xref: /AOO41X/main/unotools/source/i18n/transliterationwrapper.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_unotools.hxx"
30 
31 #include <unotools/transliterationwrapper.hxx>
32 #include <tools/debug.hxx>
33 #include <i18npool/mslangid.hxx>
34 #include <comphelper/componentfactory.hxx>
35 
36 #include <com/sun/star/uno/XInterface.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
40 
41 #define TRANSLIT_LIBRARYNAME "i18n"
42 #define TRANSLIT_SERVICENAME "com.sun.star.i18n.Transliteration"
43 
44 using namespace ::com::sun::star::lang;
45 using namespace ::com::sun::star::i18n;
46 using namespace ::com::sun::star::uno;
47 using namespace ::utl;
48 
49 TransliterationWrapper::TransliterationWrapper(
50 					const Reference< XMultiServiceFactory > & xSF,
51 					sal_uInt32 nTyp )
52 	: xSMgr( xSF ), nType( nTyp ), nLanguage( 0 ), bFirstCall( sal_True )
53 {
54 	if( xSMgr.is() )
55 	{
56 		try {
57             xTrans = Reference< XExtendedTransliteration > (
58                     xSMgr->createInstance( ::rtl::OUString(
59                             RTL_CONSTASCII_USTRINGPARAM(
60                                 TRANSLIT_SERVICENAME))), UNO_QUERY );
61 		}
62 		catch ( Exception&  )
63 		{
64 			DBG_ERRORFILE( "TransliterationWrapper: Exception caught!" );
65 		}
66 	}
67 	else
68 	{	// try to get an instance somehow
69 		DBG_ERRORFILE( "TransliterationWrapper: no service manager, trying own" );
70 		try
71 		{
72             Reference< XInterface > xI = ::comphelper::getComponentInstance(
73                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME(
74                                 TRANSLIT_LIBRARYNAME ))),
75                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
76                             TRANSLIT_SERVICENAME)));
77 			if ( xI.is() )
78 			{
79 				Any x = xI->queryInterface(
80 					::getCppuType((const Reference< XExtendedTransliteration>*)0) );
81 				x >>= xTrans ;
82 			}
83 		}
84 		catch ( Exception&  )
85 		{
86 			DBG_ERRORFILE( "getComponentInstance: Exception caught!" );
87 		}
88 	}
89 	DBG_ASSERT( xTrans.is(), "TransliterationWrapper: no Transliteraion available" );
90 }
91 
92 
93 TransliterationWrapper::~TransliterationWrapper()
94 {
95 }
96 
97 
98 String TransliterationWrapper::transliterate(
99 								const String& rStr, sal_uInt16 nLang,
100 								xub_StrLen nStart, xub_StrLen nLen,
101 								Sequence <sal_Int32>* pOffset )
102 {
103 	String sRet;
104 	if( xTrans.is() )
105 	{
106 		try
107 		{
108             loadModuleIfNeeded( nLang );
109 
110 			if ( pOffset )
111 			    sRet = xTrans->transliterate( rStr, nStart, nLen, *pOffset );
112             else
113 			    sRet = xTrans->transliterateString2String( rStr, nStart, nLen);
114 		}
115 		catch( Exception&  )
116 		{
117 			DBG_ERRORFILE( "transliterate: Exception caught!" );
118 		}
119 	}
120 	return sRet;
121 }
122 
123 
124 String TransliterationWrapper::transliterate(
125 								const String& rStr,
126 								xub_StrLen nStart, xub_StrLen nLen,
127 								Sequence <sal_Int32>* pOffset ) const
128 {
129 	String sRet( rStr );
130 	if( xTrans.is() )
131 	{
132 		try
133 		{
134 			if ( pOffset )
135 			    sRet = xTrans->transliterate( rStr, nStart, nLen, *pOffset );
136             else
137 			    sRet = xTrans->transliterateString2String( rStr, nStart, nLen);
138 		}
139 		catch( Exception&  )
140 		{
141 			DBG_ERRORFILE( "transliterate: Exception caught!" );
142 		}
143 	}
144 	return sRet;
145 }
146 
147 sal_Bool TransliterationWrapper::needLanguageForTheMode() const
148 {
149 	return TransliterationModules_UPPERCASE_LOWERCASE == nType ||
150 		   TransliterationModules_LOWERCASE_UPPERCASE == nType ||
151 		   TransliterationModules_IGNORE_CASE == nType ||
152            (sal_uInt32) TransliterationModulesExtra::SENTENCE_CASE == (sal_uInt32) nType ||
153            (sal_uInt32) TransliterationModulesExtra::TITLE_CASE    == (sal_uInt32) nType ||
154            (sal_uInt32) TransliterationModulesExtra::TOGGLE_CASE   == (sal_uInt32) nType;
155 }
156 
157 
158 void TransliterationWrapper::setLanguageLocaleImpl( sal_uInt16 nLang )
159 {
160     nLanguage = nLang;
161     if( LANGUAGE_NONE == nLanguage )
162         nLanguage = LANGUAGE_SYSTEM;
163     MsLangId::convertLanguageToLocale( nLanguage, aLocale);
164 }
165 
166 
167 void TransliterationWrapper::loadModuleIfNeeded( sal_uInt16 nLang )
168 {
169     sal_Bool bLoad = bFirstCall;
170     bFirstCall = sal_False;
171 
172     if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::SENTENCE_CASE )
173     {
174         if( bLoad )
175             loadModuleByImplName(String::CreateFromAscii("SENTENCE_CASE"), nLang);
176     }
177     else if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::TITLE_CASE )
178     {
179         if( bLoad )
180             loadModuleByImplName(String::CreateFromAscii("TITLE_CASE"), nLang);
181     }
182     else if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::TOGGLE_CASE )
183     {
184         if( bLoad )
185             loadModuleByImplName(String::CreateFromAscii("TOGGLE_CASE"), nLang);
186     }
187     else
188     {
189         if( nLanguage != nLang )
190         {
191             setLanguageLocaleImpl( nLang );
192             if( !bLoad )
193                 bLoad = needLanguageForTheMode();
194         }
195         if( bLoad )
196             loadModuleImpl();
197     }
198 }
199 
200 
201 void TransliterationWrapper::loadModuleImpl() const
202 {
203     if ( bFirstCall )
204         ((TransliterationWrapper*)this)->setLanguageLocaleImpl( LANGUAGE_SYSTEM );
205 
206     try
207     {
208         if ( xTrans.is() )
209             xTrans->loadModule( (TransliterationModules)nType, aLocale );
210     }
211     catch ( Exception& e )
212     {
213 #ifdef DBG_UTIL
214         ByteString aMsg( "loadModuleImpl: Exception caught\n" );
215         aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
216         DBG_ERRORFILE( aMsg.GetBuffer() );
217 #else
218         (void)e;
219 #endif
220     }
221 
222     bFirstCall = sal_False;
223 }
224 
225 
226 void TransliterationWrapper::loadModuleByImplName(
227         const String& rModuleName, sal_uInt16 nLang )
228 {
229     try
230     {
231         setLanguageLocaleImpl( nLang );
232         // Reset LanguageType, so the next call to loadModuleIfNeeded() forces
233         // new settings.
234         nLanguage = LANGUAGE_DONTKNOW;
235         if ( xTrans.is() )
236             xTrans->loadModuleByImplName( rModuleName, aLocale );
237     }
238     catch ( Exception& e )
239     {
240 #ifdef DBG_UTIL
241         ByteString aMsg( "loadModuleByImplName: Exception caught\n" );
242         aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
243         DBG_ERRORFILE( aMsg.GetBuffer() );
244 #else
245         (void)e;
246 #endif
247     }
248 
249     bFirstCall = sal_False;
250 }
251 
252 
253 sal_Bool TransliterationWrapper::equals(
254     const String& rStr1, sal_Int32 nPos1, sal_Int32 nCount1, sal_Int32& nMatch1,
255     const String& rStr2, sal_Int32 nPos2, sal_Int32 nCount2, sal_Int32& nMatch2 ) const
256 {
257     try
258     {
259         if( bFirstCall )
260             loadModuleImpl();
261         if ( xTrans.is() )
262             return xTrans->equals( rStr1, nPos1, nCount1, nMatch1, rStr2, nPos2, nCount2, nMatch2 );
263     }
264 	catch ( Exception& e )
265 	{
266 #ifdef DBG_UTIL
267         ByteString aMsg( "equals: Exception caught\n" );
268 		aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
269 		DBG_ERRORFILE( aMsg.GetBuffer() );
270 #else
271         (void)e;
272 #endif
273 	}
274     return sal_False;
275 }
276 
277 
278 sal_Int32 TransliterationWrapper::compareSubstring(
279     const String& rStr1, sal_Int32 nOff1, sal_Int32 nLen1,
280     const String& rStr2, sal_Int32 nOff2, sal_Int32 nLen2 ) const
281 {
282     try
283     {
284         if( bFirstCall )
285             loadModuleImpl();
286         if ( xTrans.is() )
287             return xTrans->compareSubstring( rStr1, nOff1, nLen1, rStr2, nOff2, nLen2 );
288     }
289 	catch ( Exception& e )
290 	{
291 #ifdef DBG_UTIL
292         ByteString aMsg( "compareSubstring: Exception caught\n" );
293 		aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
294 		DBG_ERRORFILE( aMsg.GetBuffer() );
295 #else
296         (void)e;
297 #endif
298 	}
299     return 0;
300 }
301 
302 
303 sal_Int32 TransliterationWrapper::compareString( const String& rStr1, const String& rStr2 ) const
304 {
305     try
306     {
307         if( bFirstCall )
308             loadModuleImpl();
309         if ( xTrans.is() )
310             return xTrans->compareString( rStr1, rStr2 );
311     }
312 	catch ( Exception& e )
313 	{
314 #ifdef DBG_UTIL
315         ByteString aMsg( "compareString: Exception caught\n" );
316 		aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 );
317 		DBG_ERRORFILE( aMsg.GetBuffer() );
318 #else
319         (void)e;
320 #endif
321 	}
322     return 0;
323 }
324 
325 
326 // --- helpers --------------------------------------------------------
327 
328 sal_Bool TransliterationWrapper::isEqual( const String& rStr1, const String& rStr2 ) const
329 {
330     sal_Int32 nMatch1, nMatch2;
331     sal_Bool bMatch = equals(
332         rStr1, 0, rStr1.Len(), nMatch1,
333         rStr2, 0, rStr2.Len(), nMatch2 );
334     return bMatch;
335 }
336 
337 
338 sal_Bool TransliterationWrapper::isMatch( const String& rStr1, const String& rStr2 ) const
339 {
340     sal_Int32 nMatch1, nMatch2;
341     equals(
342         rStr1, 0, rStr1.Len(), nMatch1,
343         rStr2, 0, rStr2.Len(), nMatch2 );
344     return (nMatch1 <= nMatch2) && (nMatch1 == rStr1.Len());
345 }
346