merged tag ooo/DEV300_m102
[LibreOffice.git] / lingucomponent / source / languageguessing / guesslang.cxx
blobbaac0fd7e8560e18bcb7e03e2ed138f115a80cab
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_lingucomponent.hxx"
31 #include <iostream>
33 #include <tools/debug.hxx>
35 #include <sal/config.h>
36 #include <cppuhelper/factory.hxx>
37 #include <cppuhelper/implementationentry.hxx>
38 #include <cppuhelper/implbase2.hxx>
39 #include <tools/string.hxx>
41 #include <simpleguesser.hxx>
42 #include <guess.hxx>
44 //#include <cppuhelper/queryinterface.hxx> // helper for queryInterface() impl
46 //#include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/registry/XRegistryKey.hpp>
48 #include <com/sun/star/lang/XServiceInfo.hpp>
49 #include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
50 #include <unotools/pathoptions.hxx>
51 #include <unotools/localfilehelper.hxx>
52 #include <osl/thread.h>
54 using namespace ::rtl;
55 using namespace ::osl;
56 using namespace ::cppu;
57 using namespace ::com::sun::star;
58 using namespace ::com::sun::star::uno;
59 using namespace ::com::sun::star::lang;
60 using namespace ::com::sun::star::linguistic2;
62 namespace css = ::com::sun::star;
64 //==================================================================================================
66 #define A2OU(x) ::rtl::OUString::createFromAscii( x )
68 #define SERVICENAME "com.sun.star.linguistic2.LanguageGuessing"
70 #define IMPLNAME "com.sun.star.lingu2.LanguageGuessing"
72 static Sequence< OUString > getSupportedServiceNames_LangGuess_Impl()
74 Sequence<OUString> names(1);
75 names[0] = A2OU( SERVICENAME );
76 return names;
79 static OUString getImplementationName_LangGuess_Impl()
81 return A2OU( IMPLNAME );
84 static osl::Mutex & GetLangGuessMutex()
86 static osl::Mutex aMutex;
87 return aMutex;
91 class LangGuess_Impl :
92 public ::cppu::WeakImplHelper2<
93 XLanguageGuessing,
94 XServiceInfo >
96 SimpleGuesser m_aGuesser;
97 bool m_bInitialized;
98 css::uno::Reference< css::uno::XComponentContext > m_xContext;
100 LangGuess_Impl( const LangGuess_Impl & ); // not defined
101 LangGuess_Impl & operator =( const LangGuess_Impl & ); // not defined
103 virtual ~LangGuess_Impl() {}
104 void EnsureInitialized();
106 public:
107 explicit LangGuess_Impl(css::uno::Reference< css::uno::XComponentContext > const & rxContext);
109 // XServiceInfo implementation
110 virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException);
111 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
112 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException);
113 static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( );
115 // XLanguageGuessing implementation
116 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);
117 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);
118 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);
119 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getAvailableLanguages( ) throw (::com::sun::star::uno::RuntimeException);
120 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getEnabledLanguages( ) throw (::com::sun::star::uno::RuntimeException);
121 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getDisabledLanguages( ) throw (::com::sun::star::uno::RuntimeException);
123 // implementation specific
124 void SetFingerPrintsDB( const rtl::OUString &fileName ) throw (RuntimeException);
126 static const OUString & SAL_CALL getImplementationName_Static() throw();
130 //*************************************************************************
132 LangGuess_Impl::LangGuess_Impl(css::uno::Reference< css::uno::XComponentContext > const & rxContext) :
133 m_bInitialized( false ),
134 m_xContext( rxContext )
138 //*************************************************************************
140 void LangGuess_Impl::EnsureInitialized()
142 if (!m_bInitialized)
144 // set this to true at the very start to prevent loops because of
145 // implicitly called functions below
146 m_bInitialized = true;
148 // set default fingerprint path to where those get installed
149 String aPhysPath;
150 String aURL( SvtPathOptions().GetFingerprintPath() );
151 utl::LocalFileHelper::ConvertURLToPhysicalName( aURL, aPhysPath );
152 #ifdef WNT
153 aPhysPath += '\\';
154 #else
155 aPhysPath += '/';
156 #endif
158 SetFingerPrintsDB( aPhysPath );
161 // disable currently not functional languages...
163 struct LangCountry
165 const char *pLang;
166 const char *pCountry;
168 LangCountry aDisable[] =
170 {"gv", ""}, {"sco", ""}, // no lang-id available yet...
171 // {"hy", ""}, {"drt", ""}, // 0 bytes fingerprints...
172 {"zh", "CN"}, {"zh", "TW"}, {"ja", ""}, {"ko", ""}, // not yet correct functional...
173 {"ka", ""}, {"hi", ""}, {"mr", ""}, {"ne", ""},
174 {"sa", ""}, {"ta", ""}, {"th", ""},
175 {"qu", ""}, {"yi", ""}
177 sal_Int32 nNum = sizeof(aDisable) / sizeof(aDisable[0]);
178 Sequence< Locale > aDisableSeq( nNum );
179 Locale *pDisableSeq = aDisableSeq.getArray();
180 for (sal_Int32 i = 0; i < nNum; ++i)
182 Locale aLocale;
183 aLocale.Language = OUString::createFromAscii( aDisable[i].pLang );
184 aLocale.Country = OUString::createFromAscii( aDisable[i].pCountry );
185 pDisableSeq[i] = aLocale;
187 disableLanguages( aDisableSeq );
188 DBG_ASSERT( nNum == getDisabledLanguages().getLength(), "size mismatch" );
192 //*************************************************************************
194 /* TL: currently not part of the API
195 Sequence< com::sun::star::lang::Locale > SAL_CALL LangGuess_Impl::guessLanguages(
196 const rtl::OUString &rText,
197 sal_Int32 nStartPos,
198 sal_Int32 nLen )
199 throw (RuntimeException)
201 Sequence< com::sun::star::lang::Locale > aRes;
203 OString o = OUStringToOString( rText, RTL_TEXTENCODING_UTF8 );
204 vector<Guess> gs = m_aGuesser.GuessLanguage(o.pData->buffer);
206 aRes.realloc(gs.size());
208 com::sun::star::lang::Locale *pRes = aRes.getArray();
210 #ifdef DEBUG
211 std::cout << " We have " << gs.size() << " candidates" << std::endl;
212 #endif
214 for(int i = 0; i < gs.size() ; i++ ){
215 com::sun::star::lang::Locale current_aRes;
217 current_aRes.Language = A2OU( gs[i].getLanguage().c_str() );
218 current_aRes.Country = A2OU( gs[i].getCountry().c_str() );
220 pRes[i] = current_aRes;
223 return aRes;
226 //*************************************************************************
228 Locale SAL_CALL LangGuess_Impl::guessPrimaryLanguage(
229 const ::rtl::OUString& rText,
230 ::sal_Int32 nStartPos,
231 ::sal_Int32 nLen )
232 throw (lang::IllegalArgumentException, uno::RuntimeException)
234 osl::MutexGuard aGuard( GetLangGuessMutex() );
236 EnsureInitialized();
238 lang::Locale aRes;
239 if (nStartPos >=0 && nLen >= 0 && nStartPos + nLen <= rText.getLength())
241 OString o( OUStringToOString( rText.copy(nStartPos, nLen), RTL_TEXTENCODING_UTF8 ) );
242 Guess g = m_aGuesser.GuessPrimaryLanguage((char*)o.getStr());
243 aRes.Language = OUString::createFromAscii(g.GetLanguage().c_str());
244 aRes.Country = OUString::createFromAscii(g.GetCountry().c_str());
246 else
247 throw lang::IllegalArgumentException();
249 return aRes;
252 //*************************************************************************
253 #define DEFAULT_CONF_FILE_NAME "fpdb.conf"
255 void LangGuess_Impl::SetFingerPrintsDB(
256 const rtl::OUString &filePath )
257 throw (RuntimeException)
259 //! text encoding for file name / path needs to be in the same encoding the OS uses
260 OString path = OUStringToOString( filePath, osl_getThreadTextEncoding() );
261 OString conf_file_name( DEFAULT_CONF_FILE_NAME );
262 OString conf_file_path(path);
263 conf_file_path += conf_file_name;
265 //cout << "Conf file : " << conf_file_path.getStr() << " directory : " << path.getStr() << endl;
267 m_aGuesser.SetDBPath((const char*)conf_file_path.getStr(), (const char*)path.getStr());
270 //*************************************************************************
271 uno::Sequence< Locale > SAL_CALL LangGuess_Impl::getAvailableLanguages( )
272 throw (uno::RuntimeException)
274 osl::MutexGuard aGuard( GetLangGuessMutex() );
276 EnsureInitialized();
278 Sequence< com::sun::star::lang::Locale > aRes;
279 vector<Guess> gs = m_aGuesser.GetAllManagedLanguages();
280 aRes.realloc(gs.size());
282 com::sun::star::lang::Locale *pRes = aRes.getArray();
284 for(size_t i = 0; i < gs.size() ; i++ ){
285 com::sun::star::lang::Locale current_aRes;
286 current_aRes.Language = A2OU( gs[i].GetLanguage().c_str() );
287 current_aRes.Country = A2OU( gs[i].GetCountry().c_str() );
288 pRes[i] = current_aRes;
291 return aRes;
294 //*************************************************************************
295 uno::Sequence< Locale > SAL_CALL LangGuess_Impl::getEnabledLanguages( )
296 throw (uno::RuntimeException)
298 osl::MutexGuard aGuard( GetLangGuessMutex() );
300 EnsureInitialized();
302 Sequence< com::sun::star::lang::Locale > aRes;
303 vector<Guess> gs = m_aGuesser.GetAvailableLanguages();
304 aRes.realloc(gs.size());
306 com::sun::star::lang::Locale *pRes = aRes.getArray();
308 for(size_t i = 0; i < gs.size() ; i++ ){
309 com::sun::star::lang::Locale current_aRes;
310 current_aRes.Language = A2OU( gs[i].GetLanguage().c_str() );
311 current_aRes.Country = A2OU( gs[i].GetCountry().c_str() );
312 pRes[i] = current_aRes;
315 return aRes;
318 //*************************************************************************
319 uno::Sequence< Locale > SAL_CALL LangGuess_Impl::getDisabledLanguages( )
320 throw (uno::RuntimeException)
322 osl::MutexGuard aGuard( GetLangGuessMutex() );
324 EnsureInitialized();
326 Sequence< com::sun::star::lang::Locale > aRes;
327 vector<Guess> gs = m_aGuesser.GetUnavailableLanguages();
328 aRes.realloc(gs.size());
330 com::sun::star::lang::Locale *pRes = aRes.getArray();
332 for(size_t i = 0; i < gs.size() ; i++ ){
333 com::sun::star::lang::Locale current_aRes;
334 current_aRes.Language = A2OU( gs[i].GetLanguage().c_str() );
335 current_aRes.Country = A2OU( gs[i].GetCountry().c_str() );
336 pRes[i] = current_aRes;
339 return aRes;
342 //*************************************************************************
343 void SAL_CALL LangGuess_Impl::disableLanguages(
344 const uno::Sequence< Locale >& rLanguages )
345 throw (lang::IllegalArgumentException, uno::RuntimeException)
347 osl::MutexGuard aGuard( GetLangGuessMutex() );
349 EnsureInitialized();
351 sal_Int32 nLanguages = rLanguages.getLength();
352 const Locale *pLanguages = rLanguages.getConstArray();
354 for (sal_Int32 i = 0; i < nLanguages; ++i)
356 string language;
358 OString l = OUStringToOString( pLanguages[i].Language, RTL_TEXTENCODING_ASCII_US );
359 OString c = OUStringToOString( pLanguages[i].Country, RTL_TEXTENCODING_ASCII_US );
361 language += l.getStr();
362 language += "-";
363 language += c.getStr();
364 m_aGuesser.DisableLanguage(language);
368 //*************************************************************************
369 void SAL_CALL LangGuess_Impl::enableLanguages(
370 const uno::Sequence< Locale >& rLanguages )
371 throw (lang::IllegalArgumentException, uno::RuntimeException)
373 osl::MutexGuard aGuard( GetLangGuessMutex() );
375 EnsureInitialized();
377 sal_Int32 nLanguages = rLanguages.getLength();
378 const Locale *pLanguages = rLanguages.getConstArray();
380 for (sal_Int32 i = 0; i < nLanguages; ++i)
382 string language;
384 OString l = OUStringToOString( pLanguages[i].Language, RTL_TEXTENCODING_ASCII_US );
385 OString c = OUStringToOString( pLanguages[i].Country, RTL_TEXTENCODING_ASCII_US );
387 language += l.getStr();
388 language += "-";
389 language += c.getStr();
390 m_aGuesser.EnableLanguage(language);
394 //*************************************************************************
395 OUString SAL_CALL LangGuess_Impl::getImplementationName( )
396 throw(RuntimeException)
398 osl::MutexGuard aGuard( GetLangGuessMutex() );
399 return A2OU( IMPLNAME );
402 //*************************************************************************
403 sal_Bool SAL_CALL LangGuess_Impl::supportsService( const OUString& ServiceName )
404 throw(RuntimeException)
406 osl::MutexGuard aGuard( GetLangGuessMutex() );
407 Sequence< OUString > aSNL = getSupportedServiceNames();
408 const OUString * pArray = aSNL.getArray();
409 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
410 if( pArray[i] == ServiceName )
411 return sal_True;
412 return sal_False;
415 //*************************************************************************
416 Sequence<OUString> SAL_CALL LangGuess_Impl::getSupportedServiceNames( )
417 throw(RuntimeException)
419 osl::MutexGuard aGuard( GetLangGuessMutex() );
420 return getSupportedServiceNames_Static();
423 //*************************************************************************
424 Sequence<OUString> SAL_CALL LangGuess_Impl::getSupportedServiceNames_Static( )
426 OUString aName( A2OU( SERVICENAME ) );
427 return Sequence< OUString >( &aName, 1 );
430 //*************************************************************************
434 * Function to create a new component instance; is needed by factory helper implementation.
435 * @param xMgr service manager to if the components needs other component instances
437 Reference< XInterface > SAL_CALL LangGuess_Impl_create(
438 Reference< XComponentContext > const & xContext )
439 SAL_THROW( () )
441 return static_cast< ::cppu::OWeakObject * >( new LangGuess_Impl(xContext) );
444 //##################################################################################################
445 //#### EXPORTED ### functions to allow for registration and creation of the UNO component
446 //##################################################################################################
448 static struct ::cppu::ImplementationEntry s_component_entries [] =
451 LangGuess_Impl_create, getImplementationName_LangGuess_Impl,
452 getSupportedServiceNames_LangGuess_Impl,
453 ::cppu::createSingleComponentFactory,
454 0, 0
456 { 0, 0, 0, 0, 0, 0 }
459 extern "C"
462 void SAL_CALL component_getImplementationEnvironment(
463 sal_Char const ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
465 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
468 void * SAL_CALL component_getFactory(
469 sal_Char const * implName, lang::XMultiServiceFactory * xMgr,
470 registry::XRegistryKey * xRegistry )
472 return ::cppu::component_getFactoryHelper(
473 implName, xMgr, xRegistry, s_component_entries );