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