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"
32 #include <com/sun/star/uno/Reference.h>
34 #include <cppuhelper/factory.hxx> // helper for factories
35 #include <com/sun/star/registry/XRegistryKey.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <i18npool/mslangid.hxx>
38 #include <tools/debug.hxx>
39 #include <unotools/processfactory.hxx>
40 #include <osl/mutex.hxx>
41 #include <unotools/pathoptions.hxx>
42 #include <unotools/lingucfg.hxx>
44 #include <rtl/string.hxx>
45 #include <rtl/ustrbuf.hxx>
46 #include "nthesimp.hxx"
47 #include <linguistic/misc.hxx>
48 #include <linguistic/lngprops.hxx>
49 #include "nthesdta.hxx"
50 #include <dictmgr.hxx>
56 // values asigned to capitalization types
57 #define CAPTYPE_UNKNOWN 0
58 #define CAPTYPE_NOCAP 1
59 #define CAPTYPE_INITCAP 2
60 #define CAPTYPE_ALLCAP 3
61 #define CAPTYPE_MIXED 4
63 // XML-header to query SPELLML support
64 #define SPELLML_SUPPORT "<?xml?>"
69 using namespace com::sun::star
;
70 using namespace com::sun::star::beans
;
71 using namespace com::sun::star::lang
;
72 using namespace com::sun::star::uno
;
73 using namespace com::sun::star::linguistic2
;
74 using namespace linguistic
;
78 ///////////////////////////////////////////////////////////////////////////
80 static uno::Reference
< XLinguServiceManager
> GetLngSvcMgr_Impl()
82 uno::Reference
< XLinguServiceManager
> xRes
;
83 uno::Reference
< XMultiServiceFactory
> xMgr
= getProcessServiceFactory();
86 xRes
= uno::Reference
< XLinguServiceManager
> ( xMgr
->createInstance(
87 OUString( RTL_CONSTASCII_USTRINGPARAM(
88 "com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY
) ;
93 Thesaurus::Thesaurus() :
94 aEvtListeners ( GetLinguMutex() )
107 Thesaurus::~Thesaurus()
111 for (int i
= 0; i
< numthes
; i
++) {
112 if (aThes
[i
]) delete aThes
[i
];
119 for (int i
= 0; i
< numthes
; i
++) {
120 if (aCharSetInfo
[i
]) delete aCharSetInfo
[i
];
121 aCharSetInfo
[i
] = NULL
;
123 delete[] aCharSetInfo
;
127 if (aTEncs
) delete[] aTEncs
;
129 if (aTLocs
) delete[] aTLocs
;
131 if (aTNames
) delete[] aTNames
;
135 pPropHelper
->RemoveAsPropListener();
139 PropertyHelper_Thes
& Thesaurus::GetPropHelper_Impl()
143 Reference
< XPropertySet
> xPropSet( GetLinguProperties(), UNO_QUERY
);
145 pPropHelper
= new PropertyHelper_Thes( (XThesaurus
*) this, xPropSet
);
146 xPropHelper
= pPropHelper
;
147 pPropHelper
->AddAsPropListener(); //! after a reference is established
153 Sequence
< Locale
> SAL_CALL
Thesaurus::getLocales()
154 throw(RuntimeException
)
156 MutexGuard
aGuard( GetLinguMutex() );
158 // this routine should return the locales supported by the installed
163 SvtLinguConfig aLinguCfg
;
165 // get list of dictionaries-to-use
166 std::list
< SvtLinguConfigDictionaryEntry
> aDics
;
167 uno::Sequence
< rtl::OUString
> aFormatList
;
168 aLinguCfg
.GetSupportedDictionaryFormatsFor( A2OU("Thesauri"),
169 A2OU("org.openoffice.lingu.new.Thesaurus"), aFormatList
);
170 sal_Int32 nLen
= aFormatList
.getLength();
171 for (sal_Int32 i
= 0; i
< nLen
; ++i
)
173 std::vector
< SvtLinguConfigDictionaryEntry
> aTmpDic(
174 aLinguCfg
.GetActiveDictionariesByFormat( aFormatList
[i
] ) );
175 aDics
.insert( aDics
.end(), aTmpDic
.begin(), aTmpDic
.end() );
178 //!! for compatibility with old dictionaries (the ones not using extensions
179 //!! or new configuration entries, but still using the dictionary.lst file)
180 //!! Get the list of old style spell checking dictionaries to use...
181 std::vector
< SvtLinguConfigDictionaryEntry
> aOldStyleDics(
182 GetOldStyleDics( "THES" ) );
184 // to prefer dictionaries with configuration entries we will only
185 // use those old style dictionaries that add a language that
186 // is not yet supported by the list od new style dictionaries
187 MergeNewStyleDicsAndOldStyleDics( aDics
, aOldStyleDics
);
189 numthes
= aDics
.size();
192 // get supported locales from the dictionaries-to-use...
194 std::set
< rtl::OUString
, lt_rtl_OUString
> aLocaleNamesSet
;
195 std::list
< SvtLinguConfigDictionaryEntry
>::const_iterator aDictIt
;
196 for (aDictIt
= aDics
.begin(); aDictIt
!= aDics
.end(); ++aDictIt
)
198 uno::Sequence
< rtl::OUString
> aLocaleNames( aDictIt
->aLocaleNames
);
199 sal_Int32 nLen2
= aLocaleNames
.getLength();
200 for (k
= 0; k
< nLen2
; ++k
)
202 aLocaleNamesSet
.insert( aLocaleNames
[k
] );
205 // ... and add them to the resulting sequence
206 aSuppLocales
.realloc( aLocaleNamesSet
.size() );
207 std::set
< rtl::OUString
, lt_rtl_OUString
>::const_iterator aItB
;
209 for (aItB
= aLocaleNamesSet
.begin(); aItB
!= aLocaleNamesSet
.end(); ++aItB
)
211 Locale
aTmp( MsLangId::convertLanguageToLocale(
212 MsLangId::convertIsoStringToLanguage( *aItB
)));
213 aSuppLocales
[k
++] = aTmp
;
216 //! For each dictionary and each locale we need a seperate entry.
217 //! If this results in more than one dictionary per locale than (for now)
218 //! it is undefined which dictionary gets used.
219 //! In the future the implementation should support using several dictionaries
222 for (aDictIt
= aDics
.begin(); aDictIt
!= aDics
.end(); ++aDictIt
)
223 numthes
= numthes
+ aDictIt
->aLocaleNames
.getLength();
225 // add dictionary information
226 aThes
= new MyThes
* [numthes
];
227 aTEncs
= new rtl_TextEncoding
[numthes
];
228 aTLocs
= new Locale
[numthes
];
229 aTNames
= new OUString
[numthes
];
230 aCharSetInfo
= new CharClass
* [numthes
];
233 for (aDictIt
= aDics
.begin(); aDictIt
!= aDics
.end(); ++aDictIt
)
235 if (aDictIt
->aLocaleNames
.getLength() > 0 &&
236 aDictIt
->aLocations
.getLength() > 0)
238 uno::Sequence
< rtl::OUString
> aLocaleNames( aDictIt
->aLocaleNames
);
239 sal_Int32 nLocales
= aLocaleNames
.getLength();
241 // currently only one language per dictionary is supported in the actual implementation...
242 // Thus here we work-around this by adding the same dictionary several times.
243 // Once for each of it's supported locales.
244 for (sal_Int32 i
= 0; i
< nLocales
; ++i
)
248 aTLocs
[k
] = MsLangId::convertLanguageToLocale(
249 MsLangId::convertIsoStringToLanguage( aDictIt
->aLocaleNames
[i
] ));
250 aCharSetInfo
[k
] = new CharClass( aTLocs
[k
] );
251 // also both files have to be in the same directory and the
252 // file names must only differ in the extension (.aff/.dic).
253 // Thus we use the first location only and strip the extension part.
254 rtl::OUString aLocation
= aDictIt
->aLocations
[0];
255 sal_Int32 nPos
= aLocation
.lastIndexOf( '.' );
256 aLocation
= aLocation
.copy( 0, nPos
);
257 aTNames
[k
] = aLocation
;
263 DBG_ASSERT( k
== numthes
, "index mismatch?" );
267 /* no dictionary found so register no dictionaries */
274 aSuppLocales
.realloc(0);
283 sal_Bool SAL_CALL
Thesaurus::hasLocale(const Locale
& rLocale
)
284 throw(RuntimeException
)
286 MutexGuard
aGuard( GetLinguMutex() );
289 if (!aSuppLocales
.getLength())
291 INT32 nLen
= aSuppLocales
.getLength();
292 for (INT32 i
= 0; i
< nLen
; ++i
)
294 const Locale
*pLocale
= aSuppLocales
.getConstArray();
295 if (rLocale
== pLocale
[i
])
305 Sequence
< Reference
< ::com::sun::star::linguistic2::XMeaning
> > SAL_CALL
306 Thesaurus::queryMeanings( const OUString
& qTerm
, const Locale
& rLocale
,
307 const PropertyValues
& rProperties
)
308 throw(IllegalArgumentException
, RuntimeException
)
310 MutexGuard
aGuard( GetLinguMutex() );
312 uno::Sequence
< Reference
< XMeaning
> > aMeanings( 1 );
313 uno::Sequence
< Reference
< XMeaning
> > noMeanings( 0 );
314 uno::Reference
< XLinguServiceManager
> xLngSvcMgr( GetLngSvcMgr_Impl() );
315 uno::Reference
< XSpellChecker1
> xSpell
;
317 OUString
rTerm(qTerm
);
318 OUString
pTerm(qTerm
);
319 sal_uInt16 ct
= CAPTYPE_UNKNOWN
;
323 INT16 nLanguage
= LocaleToLanguage( rLocale
);
325 if (nLanguage
== LANGUAGE_NONE
|| !rTerm
.getLength())
328 if (!hasLocale( rLocale
))
329 #ifdef LINGU_EXCEPTIONS
330 throw( IllegalArgumentException() );
335 if (prevTerm
== qTerm
&& prevLocale
== nLanguage
) return prevMeanings
;
337 mentry
* pmean
= NULL
;
340 PropertyHelper_Thes
&rHelper
= GetPropHelper();
341 rHelper
.SetTmpPropVals( rProperties
);
344 rtl_TextEncoding aEnc
= 0;
345 CharClass
* pCC
= NULL
;
347 // find the first thesaurus that matches the locale
348 for (int i
=0; i
< numthes
; i
++) {
349 if (rLocale
== aTLocs
[i
])
351 // open up and intialize this thesaurus if need be
354 OUString datpath
= aTNames
[i
] + A2OU(".dat");
355 OUString idxpath
= aTNames
[i
] + A2OU(".idx");
358 osl::FileBase::getSystemPathFromFileURL(datpath
,ndat
);
359 osl::FileBase::getSystemPathFromFileURL(idxpath
,nidx
);
360 OString
aTmpidx(OU2ENC(nidx
,osl_getThreadTextEncoding()));
361 OString
aTmpdat(OU2ENC(ndat
,osl_getThreadTextEncoding()));
364 // workaround for Windows specifc problem that the
365 // path length in calls to 'fopen' is limted to somewhat
366 // about 120+ characters which will usually be exceed when
367 // using dictionaries as extensions.
368 aTmpidx
= Win_GetShortPathName( nidx
);
369 aTmpdat
= Win_GetShortPathName( ndat
);
372 aThes
[i
] = new MyThes(aTmpidx
.getStr(),aTmpdat
.getStr());
374 const char * enc_string
= aThes
[i
]->get_th_encoding();
376 aTEncs
[i
] = rtl_getTextEncodingFromUnixCharset("ISO8859-1");
378 aTEncs
[i
] = rtl_getTextEncodingFromUnixCharset(enc_string
);
379 if (aTEncs
[i
] == RTL_TEXTENCODING_DONTKNOW
) {
380 if (strcmp("ISCII-DEVANAGARI", enc_string
) == 0) {
381 aTEncs
[i
] = RTL_TEXTENCODING_ISCII_DEVANAGARI
;
382 } else if (strcmp("UTF-8", enc_string
) == 0) {
383 aTEncs
[i
] = RTL_TEXTENCODING_UTF8
;
391 pCC
= aCharSetInfo
[i
];
399 // convert word to all lower case for searching
400 if (!stem
) ct
= capitalType(rTerm
, pCC
);
401 OUString
nTerm(makeLowerCase(rTerm
, pCC
));
402 OString
aTmp( OU2ENC(nTerm
, aEnc
) );
403 nmean
= pTH
->Lookup(aTmp
.getStr(),aTmp
.getLength(),&pmean
);
405 if (nmean
) aMeanings
.realloc( nmean
);
408 OUString codeTerm
= qTerm
;
409 Reference
< XSpellAlternatives
> xTmpRes2
;
412 xTmpRes2
= xSpell
->spell( A2OU("<?xml?><query type='analyze'><word>") +
413 pTerm
+ A2OU("</word></query>"), nLanguage
, rProperties
);
415 Sequence
<OUString
>seq
= xTmpRes2
->getAlternatives();
416 if (seq
.getLength() > 0) {
421 OString o
= OUStringToOString(codeTerm
, rtl_getTextEncodingFromUnixCharset("UTF-8"));
422 fprintf(stderr
, "CODETERM: %s\n", o
.pData
->buffer
);
427 for (int j
= 0; j
< nmean
; j
++) {
428 int count
= pe
->count
;
430 Sequence
< OUString
> aStr( count
);
431 OUString
*pStr
= aStr
.getArray();
433 for (int i
=0; i
< count
; i
++) {
434 OUString
sTerm(pe
->psyns
[i
],strlen(pe
->psyns
[i
]),aEnc
);
435 sal_Int32 catpos
= sTerm
.indexOf('(');
436 sal_Int32 catpos2
= 0;
440 // remove category name for affixation and casing
441 catst
= A2OU(" ") + sTerm
.copy(catpos
);
442 sTerm
= sTerm
.copy(0, catpos
);
443 sTerm
= sTerm
.trim();
445 // generate synonyms with affixes
447 Reference
< XSpellAlternatives
> xTmpRes
;
448 xTmpRes
= xSpell
->spell( A2OU("<?xml?><query type='generate'><word>") +
449 sTerm
+ A2OU("</word>") + codeTerm
+ A2OU("</query>"), nLanguage
, rProperties
);
451 Sequence
<OUString
>seq
= xTmpRes
->getAlternatives();
452 for (int k
= 0; k
< seq
.getLength(); k
++) {
453 OString o
= OUStringToOString(seq
[k
], rtl_getTextEncodingFromUnixCharset("UTF-8"));
455 if (seq
.getLength() > 0) sTerm
= seq
[0];
458 if (catpos2
) sTerm
= catst2
+ sTerm
;
460 sal_uInt16 ct1
= capitalType(sTerm
, pCC
);
461 if (CAPTYPE_MIXED
== ct1
)
467 cTerm
= makeUpperCase(sTerm
, pCC
);
470 case CAPTYPE_INITCAP
:
472 cTerm
= makeInitCap(sTerm
, pCC
);
481 OUString
aAlt( cTerm
+ catst
);
485 Meaning
* pMn
= new Meaning(rTerm
,nLanguage
,rHelper
);
487 Meaning
* pMn
= new Meaning(rTerm
,nLanguage
);
488 OUString
dTerm(pe
->defn
,strlen(pe
->defn
),aEnc
);
489 pMn
->SetMeaning(dTerm
);
490 pMn
->SetSynonyms(aStr
);
491 Reference
<XMeaning
>* pMeaning
= aMeanings
.getArray();
496 pTH
->CleanUpAfterLookup(&pmean
,nmean
);
500 prevMeanings
= aMeanings
;
501 prevLocale
= nLanguage
;
505 if (stem
|| !xLngSvcMgr
.is()) return noMeanings
;
508 xSpell
= uno::Reference
< XSpellChecker1
>( xLngSvcMgr
->getSpellChecker(), UNO_QUERY
);
509 if (!xSpell
.is() || !xSpell
->isValid( A2OU(SPELLML_SUPPORT
), nLanguage
, rProperties
)) {
512 Reference
< XSpellAlternatives
> xTmpRes
;
513 xTmpRes
= xSpell
->spell( A2OU("<?xml?><query type='stem'><word>") +
514 rTerm
+ A2OU("</word></query>"), nLanguage
, rProperties
);
516 Sequence
<OUString
>seq
= xTmpRes
->getAlternatives();
518 for (int i
= 0; i
< seq
.getLength(); i
++) {
519 OString o
= OUStringToOString(seq
[i
], rtl_getTextEncodingFromUnixCharset("UTF-8"));
520 fprintf(stderr
, "%d: %s\n", i
+ 1, o
.pData
->buffer
);
523 if (seq
.getLength() > 0) {
524 rTerm
= seq
[0]; // XXX Use only the first stem
529 // stem the last word of the synonym (for categories after affixation)
530 rTerm
= rTerm
.trim();
531 sal_Int32 pos
= rTerm
.lastIndexOf(' ');
532 if (!pos
) return noMeanings
;
533 xTmpRes
= xSpell
->spell( A2OU("<?xml?><query type='stem'><word>") +
534 rTerm
.copy(pos
+ 1) + A2OU("</word></query>"), nLanguage
, rProperties
);
536 Sequence
<OUString
>seq
= xTmpRes
->getAlternatives();
537 if (seq
.getLength() > 0) {
538 pTerm
= rTerm
.copy(pos
+ 1);
539 rTerm
= rTerm
.copy(0, pos
+ 1) + seq
[0];
541 for (int i
= 0; i
< seq
.getLength(); i
++) {
542 OString o
= OUStringToOString(seq
[i
], rtl_getTextEncodingFromUnixCharset("UTF-8"));
543 fprintf(stderr
, "%d: %s\n", i
+ 1, o
.pData
->buffer
);
556 Reference
< XInterface
> SAL_CALL
Thesaurus_CreateInstance(
557 const Reference
< XMultiServiceFactory
> & /*rSMgr*/ )
560 Reference
< XInterface
> xService
= (cppu::OWeakObject
*) new Thesaurus
;
566 Thesaurus::getServiceDisplayName( const Locale
& /*rLocale*/ )
567 throw(RuntimeException
)
569 MutexGuard
aGuard( GetLinguMutex() );
570 return A2OU( "OpenOffice.org New Thesaurus" );
575 Thesaurus::initialize( const Sequence
< Any
>& rArguments
)
576 throw(Exception
, RuntimeException
)
578 MutexGuard
aGuard( GetLinguMutex() );
582 INT32 nLen
= rArguments
.getLength();
585 Reference
< XPropertySet
> xPropSet
;
586 rArguments
.getConstArray()[0] >>= xPropSet
;
588 //! Pointer allows for access of the non-UNO functions.
589 //! And the reference to the UNO-functions while increasing
590 //! the ref-count and will implicitly free the memory
591 //! when the object is not longer used.
592 pPropHelper
= new PropertyHelper_Thes( (XThesaurus
*) this, xPropSet
);
593 xPropHelper
= pPropHelper
;
594 pPropHelper
->AddAsPropListener(); //! after a reference is established
597 DBG_ERROR( "wrong number of arguments in sequence" );
603 sal_uInt16 SAL_CALL
Thesaurus::capitalType(const OUString
& aTerm
, CharClass
* pCC
)
605 sal_Int32 tlen
= aTerm
.getLength();
606 if ((pCC
) && (tlen
)) {
609 for (USHORT tindex
= 0; tindex
< tlen
; tindex
++) {
610 if (pCC
->getCharacterType(aStr
,tindex
) &
611 ::com::sun::star::i18n::KCharacterType::UPPER
) nc
++;
614 if (nc
== 0) return (sal_uInt16
) CAPTYPE_NOCAP
;
616 if (nc
== tlen
) return (sal_uInt16
) CAPTYPE_ALLCAP
;
618 if ((nc
== 1) && (pCC
->getCharacterType(aStr
,0) &
619 ::com::sun::star::i18n::KCharacterType::UPPER
))
620 return (sal_uInt16
) CAPTYPE_INITCAP
;
622 return (sal_uInt16
) CAPTYPE_MIXED
;
624 return (sal_uInt16
) CAPTYPE_UNKNOWN
;
629 OUString SAL_CALL
Thesaurus::makeLowerCase(const OUString
& aTerm
, CharClass
* pCC
)
632 return pCC
->toLower_rtl(aTerm
, 0, aTerm
.getLength());
637 OUString SAL_CALL
Thesaurus::makeUpperCase(const OUString
& aTerm
, CharClass
* pCC
)
640 return pCC
->toUpper_rtl(aTerm
, 0, aTerm
.getLength());
645 OUString SAL_CALL
Thesaurus::makeInitCap(const OUString
& aTerm
, CharClass
* pCC
)
647 sal_Int32 tlen
= aTerm
.getLength();
648 if ((pCC
) && (tlen
)) {
649 OUString bTemp
= aTerm
.copy(0,1);
651 return ( pCC
->toUpper_rtl(bTemp
, 0, 1)
652 + pCC
->toLower_rtl(aTerm
,1,(tlen
-1)) );
654 return pCC
->toUpper_rtl(bTemp
, 0, 1);
663 throw(RuntimeException
)
665 MutexGuard
aGuard( GetLinguMutex() );
670 EventObject
aEvtObj( (XThesaurus
*) this );
671 aEvtListeners
.disposeAndClear( aEvtObj
);
677 Thesaurus::addEventListener( const Reference
< XEventListener
>& rxListener
)
678 throw(RuntimeException
)
680 MutexGuard
aGuard( GetLinguMutex() );
682 if (!bDisposing
&& rxListener
.is())
683 aEvtListeners
.addInterface( rxListener
);
688 Thesaurus::removeEventListener( const Reference
< XEventListener
>& rxListener
)
689 throw(RuntimeException
)
691 MutexGuard
aGuard( GetLinguMutex() );
693 if (!bDisposing
&& rxListener
.is())
694 aEvtListeners
.removeInterface( rxListener
);
698 ///////////////////////////////////////////////////////////////////////////
699 // Service specific part
702 OUString SAL_CALL
Thesaurus::getImplementationName()
703 throw(RuntimeException
)
705 MutexGuard
aGuard( GetLinguMutex() );
706 return getImplementationName_Static();
710 sal_Bool SAL_CALL
Thesaurus::supportsService( const OUString
& ServiceName
)
711 throw(RuntimeException
)
713 MutexGuard
aGuard( GetLinguMutex() );
715 Sequence
< OUString
> aSNL
= getSupportedServiceNames();
716 const OUString
* pArray
= aSNL
.getConstArray();
717 for( INT32 i
= 0; i
< aSNL
.getLength(); i
++ )
718 if( pArray
[i
] == ServiceName
)
724 Sequence
< OUString
> SAL_CALL
Thesaurus::getSupportedServiceNames()
725 throw(RuntimeException
)
727 MutexGuard
aGuard( GetLinguMutex() );
728 return getSupportedServiceNames_Static();
732 Sequence
< OUString
> Thesaurus::getSupportedServiceNames_Static()
735 MutexGuard
aGuard( GetLinguMutex() );
737 Sequence
< OUString
> aSNS( 1 ); // auch mehr als 1 Service moeglich
738 aSNS
.getArray()[0] = A2OU( SN_THESAURUS
);
743 sal_Bool SAL_CALL
Thesaurus_writeInfo(
744 void * /*pServiceManager*/, registry::XRegistryKey
* pRegistryKey
)
749 aImpl
+= Thesaurus::getImplementationName_Static().getStr();
750 aImpl
.AppendAscii( "/UNO/SERVICES" );
751 Reference
< registry::XRegistryKey
> xNewKey
=
752 pRegistryKey
->createKey( aImpl
);
753 Sequence
< OUString
> aServices
=
754 Thesaurus::getSupportedServiceNames_Static();
755 for( INT32 i
= 0; i
< aServices
.getLength(); i
++ )
756 xNewKey
->createKey( aServices
.getConstArray()[i
] );
767 void * SAL_CALL
Thesaurus_getFactory( const sal_Char
* pImplName
,
768 XMultiServiceFactory
* pServiceManager
, void * )
771 if ( !Thesaurus::getImplementationName_Static().compareToAscii( pImplName
) )
774 Reference
< XSingleServiceFactory
> xFactory
=
775 cppu::createOneInstanceFactory(
777 Thesaurus::getImplementationName_Static(),
778 Thesaurus_CreateInstance
,
779 Thesaurus::getSupportedServiceNames_Static());
780 // acquire, because we return an interface pointer instead of a reference
782 pRet
= xFactory
.get();
788 ///////////////////////////////////////////////////////////////////////////
791 #undef CAPTYPE_UNKNOWN
793 #undef CAPTYPE_INITCAP
794 #undef CAPTYPE_ALLCAP