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