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