Update ooo320-m1
[ooovba.git] / lingucomponent / source / languageguessing / guesslang.cxx
blob6ab5df3c899da4b7e8eae6ffdf9e8c7970933e94
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: guesslang.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_lingucomponent.hxx"
34 #include <iostream>
36 #include <tools/debug.hxx>
38 #include <sal/config.h>
39 #include <cppuhelper/factory.hxx>
40 #include <cppuhelper/implementationentry.hxx>
41 #include <cppuhelper/implbase2.hxx>
42 #include <tools/string.hxx>
44 #include <simpleguesser.hxx>
45 #include <guess.hxx>
47 //#include <cppuhelper/queryinterface.hxx> // helper for queryInterface() impl
49 //#include <com/sun/star/lang/XMultiServiceFactory.hpp>
50 #include <com/sun/star/registry/XRegistryKey.hpp>
51 #include <com/sun/star/lang/XServiceInfo.hpp>
52 #include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
53 #include <svtools/pathoptions.hxx>
54 #include <unotools/localfilehelper.hxx>
55 #include <osl/thread.h>
57 using namespace ::rtl;
58 using namespace ::osl;
59 using namespace ::cppu;
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::lang;
63 using namespace ::com::sun::star::linguistic2;
65 namespace css = ::com::sun::star;
67 //==================================================================================================
69 #define A2OU(x) ::rtl::OUString::createFromAscii( x )
71 #define SERVICENAME "com.sun.star.linguistic2.LanguageGuessing"
73 #define IMPLNAME "com.sun.star.lingu2.LanguageGuessing"
75 static Sequence< OUString > getSupportedServiceNames_LangGuess_Impl()
77 Sequence<OUString> names(1);
78 names[0] = A2OU( SERVICENAME );
79 return names;
82 static OUString getImplementationName_LangGuess_Impl()
84 return A2OU( IMPLNAME );
87 static osl::Mutex & GetLangGuessMutex()
89 static osl::Mutex aMutex;
90 return aMutex;
94 class LangGuess_Impl :
95 public ::cppu::WeakImplHelper2<
96 XLanguageGuessing,
97 XServiceInfo >
99 SimpleGuesser m_aGuesser;
100 bool m_bInitialized;
101 css::uno::Reference< css::uno::XComponentContext > m_xContext;
103 LangGuess_Impl( const LangGuess_Impl & ); // not defined
104 LangGuess_Impl & operator =( const LangGuess_Impl & ); // not defined
106 virtual ~LangGuess_Impl() {}
107 void EnsureInitialized();
109 public:
110 explicit LangGuess_Impl(css::uno::Reference< css::uno::XComponentContext > const & rxContext);
112 // XServiceInfo implementation
113 virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException);
114 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
115 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException);
116 static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( );
118 // XLanguageGuessing implementation
119 virtual ::com::sun::star::lang::Locale SAL_CALL guessPrimaryLanguage( const ::rtl::OUString& aText, ::sal_Int32 nStartPos, ::sal_Int32 nLen ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
120 virtual void SAL_CALL disableLanguages( const ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale >& aLanguages ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
121 virtual void SAL_CALL enableLanguages( const ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale >& aLanguages ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
122 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getAvailableLanguages( ) throw (::com::sun::star::uno::RuntimeException);
123 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getEnabledLanguages( ) throw (::com::sun::star::uno::RuntimeException);
124 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getDisabledLanguages( ) throw (::com::sun::star::uno::RuntimeException);
126 // implementation specific
127 void SetFingerPrintsDB( const rtl::OUString &fileName ) throw (RuntimeException);
129 static const OUString & SAL_CALL getImplementationName_Static() throw();
133 //*************************************************************************
135 LangGuess_Impl::LangGuess_Impl(css::uno::Reference< css::uno::XComponentContext > const & rxContext) :
136 m_bInitialized( false ),
137 m_xContext( rxContext )
141 //*************************************************************************
143 void LangGuess_Impl::EnsureInitialized()
145 if (!m_bInitialized)
147 // set this to true at the very start to prevent loops because of
148 // implicitly called functions below
149 m_bInitialized = true;
151 // set default fingerprint path to where those get installed
152 String aPhysPath;
153 String aURL( SvtPathOptions().GetFingerprintPath() );
154 utl::LocalFileHelper::ConvertURLToPhysicalName( aURL, aPhysPath );
155 #ifdef WNT
156 aPhysPath += '\\';
157 #else
158 aPhysPath += '/';
159 #endif
161 SetFingerPrintsDB( aPhysPath );
164 // disable currently not functional languages...
166 struct LangCountry
168 const char *pLang;
169 const char *pCountry;
171 LangCountry aDisable[] =
173 {"gv", ""}, {"sco", ""}, // no lang-id available yet...
174 // {"hy", ""}, {"drt", ""}, // 0 bytes fingerprints...
175 {"zh", "CN"}, {"zh", "TW"}, {"ja", ""}, {"ko", ""}, // not yet correct functional...
176 {"ka", ""}, {"hi", ""}, {"mr", ""}, {"ne", ""},
177 {"sa", ""}, {"ta", ""}, {"th", ""},
178 {"qu", ""}, {"yi", ""}
180 sal_Int32 nNum = sizeof(aDisable) / sizeof(aDisable[0]);
181 Sequence< Locale > aDisableSeq( nNum );
182 Locale *pDisableSeq = aDisableSeq.getArray();
183 for (sal_Int32 i = 0; i < nNum; ++i)
185 Locale aLocale;
186 aLocale.Language = OUString::createFromAscii( aDisable[i].pLang );
187 aLocale.Country = OUString::createFromAscii( aDisable[i].pCountry );
188 pDisableSeq[i] = aLocale;
190 disableLanguages( aDisableSeq );
191 DBG_ASSERT( nNum == getDisabledLanguages().getLength(), "size mismatch" );
195 //*************************************************************************
197 /* TL: currently not part of the API
198 Sequence< com::sun::star::lang::Locale > SAL_CALL LangGuess_Impl::guessLanguages(
199 const rtl::OUString &rText,
200 sal_Int32 nStartPos,
201 sal_Int32 nLen )
202 throw (RuntimeException)
204 Sequence< com::sun::star::lang::Locale > aRes;
206 OString o = OUStringToOString( rText, RTL_TEXTENCODING_UTF8 );
207 vector<Guess> gs = m_aGuesser.GuessLanguage(o.pData->buffer);
209 aRes.realloc(gs.size());
211 com::sun::star::lang::Locale *pRes = aRes.getArray();
213 #ifdef DEBUG
214 std::cout << " We have " << gs.size() << " candidates" << std::endl;
215 #endif
217 for(int i = 0; i < gs.size() ; i++ ){
218 com::sun::star::lang::Locale current_aRes;
220 current_aRes.Language = A2OU( gs[i].getLanguage().c_str() );
221 current_aRes.Country = A2OU( gs[i].getCountry().c_str() );
223 pRes[i] = current_aRes;
226 return aRes;
229 //*************************************************************************
231 Locale SAL_CALL LangGuess_Impl::guessPrimaryLanguage(
232 const ::rtl::OUString& rText,
233 ::sal_Int32 nStartPos,
234 ::sal_Int32 nLen )
235 throw (lang::IllegalArgumentException, uno::RuntimeException)
237 osl::MutexGuard aGuard( GetLangGuessMutex() );
239 EnsureInitialized();
241 lang::Locale aRes;
242 if (nStartPos >=0 && nLen >= 0 && nStartPos + nLen <= rText.getLength())
244 OString o( OUStringToOString( rText.copy(nStartPos, nLen), RTL_TEXTENCODING_UTF8 ) );
245 Guess g = m_aGuesser.GuessPrimaryLanguage((char*)o.getStr());
246 aRes.Language = OUString::createFromAscii(g.GetLanguage().c_str());
247 aRes.Country = OUString::createFromAscii(g.GetCountry().c_str());
249 else
250 throw lang::IllegalArgumentException();
252 return aRes;
255 //*************************************************************************
256 #define DEFAULT_CONF_FILE_NAME "fpdb.conf"
258 void LangGuess_Impl::SetFingerPrintsDB(
259 const rtl::OUString &filePath )
260 throw (RuntimeException)
262 //! text encoding for file name / path needs to be in the same encoding the OS uses
263 OString path = OUStringToOString( filePath, osl_getThreadTextEncoding() );
264 OString conf_file_name( DEFAULT_CONF_FILE_NAME );
265 OString conf_file_path(path);
266 conf_file_path += conf_file_name;
268 //cout << "Conf file : " << conf_file_path.getStr() << " directory : " << path.getStr() << endl;
270 m_aGuesser.SetDBPath((const char*)conf_file_path.getStr(), (const char*)path.getStr());
273 //*************************************************************************
274 uno::Sequence< Locale > SAL_CALL LangGuess_Impl::getAvailableLanguages( )
275 throw (uno::RuntimeException)
277 osl::MutexGuard aGuard( GetLangGuessMutex() );
279 EnsureInitialized();
281 Sequence< com::sun::star::lang::Locale > aRes;
282 vector<Guess> gs = m_aGuesser.GetAllManagedLanguages();
283 aRes.realloc(gs.size());
285 com::sun::star::lang::Locale *pRes = aRes.getArray();
287 for(size_t i = 0; i < gs.size() ; i++ ){
288 com::sun::star::lang::Locale current_aRes;
289 current_aRes.Language = A2OU( gs[i].GetLanguage().c_str() );
290 current_aRes.Country = A2OU( gs[i].GetCountry().c_str() );
291 pRes[i] = current_aRes;
294 return aRes;
297 //*************************************************************************
298 uno::Sequence< Locale > SAL_CALL LangGuess_Impl::getEnabledLanguages( )
299 throw (uno::RuntimeException)
301 osl::MutexGuard aGuard( GetLangGuessMutex() );
303 EnsureInitialized();
305 Sequence< com::sun::star::lang::Locale > aRes;
306 vector<Guess> gs = m_aGuesser.GetAvailableLanguages();
307 aRes.realloc(gs.size());
309 com::sun::star::lang::Locale *pRes = aRes.getArray();
311 for(size_t i = 0; i < gs.size() ; i++ ){
312 com::sun::star::lang::Locale current_aRes;
313 current_aRes.Language = A2OU( gs[i].GetLanguage().c_str() );
314 current_aRes.Country = A2OU( gs[i].GetCountry().c_str() );
315 pRes[i] = current_aRes;
318 return aRes;
321 //*************************************************************************
322 uno::Sequence< Locale > SAL_CALL LangGuess_Impl::getDisabledLanguages( )
323 throw (uno::RuntimeException)
325 osl::MutexGuard aGuard( GetLangGuessMutex() );
327 EnsureInitialized();
329 Sequence< com::sun::star::lang::Locale > aRes;
330 vector<Guess> gs = m_aGuesser.GetUnavailableLanguages();
331 aRes.realloc(gs.size());
333 com::sun::star::lang::Locale *pRes = aRes.getArray();
335 for(size_t i = 0; i < gs.size() ; i++ ){
336 com::sun::star::lang::Locale current_aRes;
337 current_aRes.Language = A2OU( gs[i].GetLanguage().c_str() );
338 current_aRes.Country = A2OU( gs[i].GetCountry().c_str() );
339 pRes[i] = current_aRes;
342 return aRes;
345 //*************************************************************************
346 void SAL_CALL LangGuess_Impl::disableLanguages(
347 const uno::Sequence< Locale >& rLanguages )
348 throw (lang::IllegalArgumentException, uno::RuntimeException)
350 osl::MutexGuard aGuard( GetLangGuessMutex() );
352 EnsureInitialized();
354 sal_Int32 nLanguages = rLanguages.getLength();
355 const Locale *pLanguages = rLanguages.getConstArray();
357 for (sal_Int32 i = 0; i < nLanguages; ++i)
359 string language;
361 OString l = OUStringToOString( pLanguages[i].Language, RTL_TEXTENCODING_ASCII_US );
362 OString c = OUStringToOString( pLanguages[i].Country, RTL_TEXTENCODING_ASCII_US );
364 language += l.getStr();
365 language += "-";
366 language += c.getStr();
367 m_aGuesser.DisableLanguage(language);
371 //*************************************************************************
372 void SAL_CALL LangGuess_Impl::enableLanguages(
373 const uno::Sequence< Locale >& rLanguages )
374 throw (lang::IllegalArgumentException, uno::RuntimeException)
376 osl::MutexGuard aGuard( GetLangGuessMutex() );
378 EnsureInitialized();
380 sal_Int32 nLanguages = rLanguages.getLength();
381 const Locale *pLanguages = rLanguages.getConstArray();
383 for (sal_Int32 i = 0; i < nLanguages; ++i)
385 string language;
387 OString l = OUStringToOString( pLanguages[i].Language, RTL_TEXTENCODING_ASCII_US );
388 OString c = OUStringToOString( pLanguages[i].Country, RTL_TEXTENCODING_ASCII_US );
390 language += l.getStr();
391 language += "-";
392 language += c.getStr();
393 m_aGuesser.EnableLanguage(language);
397 //*************************************************************************
398 OUString SAL_CALL LangGuess_Impl::getImplementationName( )
399 throw(RuntimeException)
401 osl::MutexGuard aGuard( GetLangGuessMutex() );
402 return A2OU( IMPLNAME );
405 //*************************************************************************
406 sal_Bool SAL_CALL LangGuess_Impl::supportsService( const OUString& ServiceName )
407 throw(RuntimeException)
409 osl::MutexGuard aGuard( GetLangGuessMutex() );
410 Sequence< OUString > aSNL = getSupportedServiceNames();
411 const OUString * pArray = aSNL.getArray();
412 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
413 if( pArray[i] == ServiceName )
414 return sal_True;
415 return sal_False;
418 //*************************************************************************
419 Sequence<OUString> SAL_CALL LangGuess_Impl::getSupportedServiceNames( )
420 throw(RuntimeException)
422 osl::MutexGuard aGuard( GetLangGuessMutex() );
423 return getSupportedServiceNames_Static();
426 //*************************************************************************
427 Sequence<OUString> SAL_CALL LangGuess_Impl::getSupportedServiceNames_Static( )
429 OUString aName( A2OU( SERVICENAME ) );
430 return Sequence< OUString >( &aName, 1 );
433 //*************************************************************************
437 * Function to create a new component instance; is needed by factory helper implementation.
438 * @param xMgr service manager to if the components needs other component instances
440 Reference< XInterface > SAL_CALL LangGuess_Impl_create(
441 Reference< XComponentContext > const & xContext )
442 SAL_THROW( () )
444 return static_cast< ::cppu::OWeakObject * >( new LangGuess_Impl(xContext) );
447 //##################################################################################################
448 //#### EXPORTED ### functions to allow for registration and creation of the UNO component
449 //##################################################################################################
451 static struct ::cppu::ImplementationEntry s_component_entries [] =
454 LangGuess_Impl_create, getImplementationName_LangGuess_Impl,
455 getSupportedServiceNames_LangGuess_Impl,
456 ::cppu::createSingleComponentFactory,
457 0, 0
459 { 0, 0, 0, 0, 0, 0 }
462 extern "C"
465 void SAL_CALL component_getImplementationEnvironment(
466 sal_Char const ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
468 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
471 sal_Bool SAL_CALL component_writeInfo(
472 XMultiServiceFactory * xMgr, registry::XRegistryKey * xRegistry )
474 return ::cppu::component_writeInfoHelper(
475 xMgr, xRegistry, s_component_entries );
478 void * SAL_CALL component_getFactory(
479 sal_Char const * implName, lang::XMultiServiceFactory * xMgr,
480 registry::XRegistryKey * xRegistry )
482 return ::cppu::component_getFactoryHelper(
483 implName, xMgr, xRegistry, s_component_entries );