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"
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>
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
);
79 static OUString
getImplementationName_LangGuess_Impl()
81 return A2OU( IMPLNAME
);
84 static osl::Mutex
& GetLangGuessMutex()
86 static osl::Mutex aMutex
;
91 class LangGuess_Impl
:
92 public ::cppu::WeakImplHelper2
<
96 SimpleGuesser m_aGuesser
;
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();
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()
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
150 String
aURL( SvtPathOptions().GetFingerprintPath() );
151 utl::LocalFileHelper::ConvertURLToPhysicalName( aURL
, aPhysPath
);
158 SetFingerPrintsDB( aPhysPath
);
161 // disable currently not functional languages...
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
)
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,
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();
211 std::cout << " We have " << gs.size() << " candidates" << std::endl;
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;
226 //*************************************************************************
228 Locale SAL_CALL
LangGuess_Impl::guessPrimaryLanguage(
229 const ::rtl::OUString
& rText
,
230 ::sal_Int32 nStartPos
,
232 throw (lang::IllegalArgumentException
, uno::RuntimeException
)
234 osl::MutexGuard
aGuard( GetLangGuessMutex() );
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());
247 throw lang::IllegalArgumentException();
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() );
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
;
294 //*************************************************************************
295 uno::Sequence
< Locale
> SAL_CALL
LangGuess_Impl::getEnabledLanguages( )
296 throw (uno::RuntimeException
)
298 osl::MutexGuard
aGuard( GetLangGuessMutex() );
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
;
318 //*************************************************************************
319 uno::Sequence
< Locale
> SAL_CALL
LangGuess_Impl::getDisabledLanguages( )
320 throw (uno::RuntimeException
)
322 osl::MutexGuard
aGuard( GetLangGuessMutex() );
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
;
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() );
351 sal_Int32 nLanguages
= rLanguages
.getLength();
352 const Locale
*pLanguages
= rLanguages
.getConstArray();
354 for (sal_Int32 i
= 0; i
< nLanguages
; ++i
)
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();
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() );
377 sal_Int32 nLanguages
= rLanguages
.getLength();
378 const Locale
*pLanguages
= rLanguages
.getConstArray();
380 for (sal_Int32 i
= 0; i
< nLanguages
; ++i
)
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();
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
)
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
)
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
,
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
);