summaryrefslogtreecommitdiff
path: root/lingucomponent/source/thesaurus/libnth/nthesimp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'lingucomponent/source/thesaurus/libnth/nthesimp.cxx')
-rw-r--r--lingucomponent/source/thesaurus/libnth/nthesimp.cxx795
1 files changed, 795 insertions, 0 deletions
diff --git a/lingucomponent/source/thesaurus/libnth/nthesimp.cxx b/lingucomponent/source/thesaurus/libnth/nthesimp.cxx
new file mode 100644
index 000000000000..bd6afffdbd6a
--- /dev/null
+++ b/lingucomponent/source/thesaurus/libnth/nthesimp.cxx
@@ -0,0 +1,795 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_lingucomponent.hxx"
+
+// include <stdio.h>
+#include <com/sun/star/uno/Reference.h>
+
+#include <cppuhelper/factory.hxx> // helper for factories
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <i18npool/mslangid.hxx>
+#include <tools/debug.hxx>
+#include <unotools/processfactory.hxx>
+#include <osl/mutex.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/lingucfg.hxx>
+
+#include <rtl/string.hxx>
+#include <rtl/ustrbuf.hxx>
+#include "nthesimp.hxx"
+#include <linguistic/misc.hxx>
+#include <linguistic/lngprops.hxx>
+#include "nthesdta.hxx"
+#include <dictmgr.hxx>
+
+#include <list>
+#include <set>
+#include <string.h>
+
+// values asigned to capitalization types
+#define CAPTYPE_UNKNOWN 0
+#define CAPTYPE_NOCAP 1
+#define CAPTYPE_INITCAP 2
+#define CAPTYPE_ALLCAP 3
+#define CAPTYPE_MIXED 4
+
+// XML-header to query SPELLML support
+#define SPELLML_SUPPORT "<?xml?>"
+
+using namespace utl;
+using namespace osl;
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::linguistic2;
+using namespace linguistic;
+
+
+
+///////////////////////////////////////////////////////////////////////////
+
+static uno::Reference< XLinguServiceManager > GetLngSvcMgr_Impl()
+{
+ uno::Reference< XLinguServiceManager > xRes;
+ uno::Reference< XMultiServiceFactory > xMgr = getProcessServiceFactory();
+ if (xMgr.is())
+ {
+ xRes = uno::Reference< XLinguServiceManager > ( xMgr->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY ) ;
+ }
+ return xRes;
+}
+
+Thesaurus::Thesaurus() :
+ aEvtListeners ( GetLinguMutex() )
+{
+ bDisposing = FALSE;
+ pPropHelper = NULL;
+ aThes = NULL;
+ aCharSetInfo = NULL;
+ aTEncs = NULL;
+ aTLocs = NULL;
+ aTNames = NULL;
+ numthes = 0;
+}
+
+
+Thesaurus::~Thesaurus()
+{
+
+ if (aThes) {
+ for (int i = 0; i < numthes; i++) {
+ if (aThes[i]) delete aThes[i];
+ aThes[i] = NULL;
+ }
+ delete[] aThes;
+ }
+ aThes = NULL;
+ if (aCharSetInfo) {
+ for (int i = 0; i < numthes; i++) {
+ if (aCharSetInfo[i]) delete aCharSetInfo[i];
+ aCharSetInfo[i] = NULL;
+ }
+ delete[] aCharSetInfo;
+ }
+ aCharSetInfo = NULL;
+ numthes = 0;
+ if (aTEncs) delete[] aTEncs;
+ aTEncs = NULL;
+ if (aTLocs) delete[] aTLocs;
+ aTLocs = NULL;
+ if (aTNames) delete[] aTNames;
+ aTNames = NULL;
+
+ if (pPropHelper)
+ pPropHelper->RemoveAsPropListener();
+}
+
+
+PropertyHelper_Thes & Thesaurus::GetPropHelper_Impl()
+{
+ if (!pPropHelper)
+ {
+ Reference< XPropertySet > xPropSet( GetLinguProperties(), UNO_QUERY );
+
+ pPropHelper = new PropertyHelper_Thes( (XThesaurus *) this, xPropSet );
+ xPropHelper = pPropHelper;
+ pPropHelper->AddAsPropListener(); //! after a reference is established
+ }
+ return *pPropHelper;
+}
+
+
+Sequence< Locale > SAL_CALL Thesaurus::getLocales()
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ // this routine should return the locales supported by the installed
+ // dictionaries.
+
+ if (!numthes)
+ {
+ SvtLinguConfig aLinguCfg;
+
+ // get list of dictionaries-to-use
+ std::list< SvtLinguConfigDictionaryEntry > aDics;
+ uno::Sequence< rtl::OUString > aFormatList;
+ aLinguCfg.GetSupportedDictionaryFormatsFor( A2OU("Thesauri"),
+ A2OU("org.openoffice.lingu.new.Thesaurus"), aFormatList );
+ sal_Int32 nLen = aFormatList.getLength();
+ for (sal_Int32 i = 0; i < nLen; ++i)
+ {
+ std::vector< SvtLinguConfigDictionaryEntry > aTmpDic(
+ aLinguCfg.GetActiveDictionariesByFormat( aFormatList[i] ) );
+ aDics.insert( aDics.end(), aTmpDic.begin(), aTmpDic.end() );
+ }
+
+ //!! for compatibility with old dictionaries (the ones not using extensions
+ //!! or new configuration entries, but still using the dictionary.lst file)
+ //!! Get the list of old style spell checking dictionaries to use...
+ std::vector< SvtLinguConfigDictionaryEntry > aOldStyleDics(
+ GetOldStyleDics( "THES" ) );
+
+ // to prefer dictionaries with configuration entries we will only
+ // use those old style dictionaries that add a language that
+ // is not yet supported by the list od new style dictionaries
+ MergeNewStyleDicsAndOldStyleDics( aDics, aOldStyleDics );
+
+ numthes = aDics.size();
+ if (numthes)
+ {
+ // get supported locales from the dictionaries-to-use...
+ sal_Int32 k = 0;
+ std::set< rtl::OUString, lt_rtl_OUString > aLocaleNamesSet;
+ std::list< SvtLinguConfigDictionaryEntry >::const_iterator aDictIt;
+ for (aDictIt = aDics.begin(); aDictIt != aDics.end(); ++aDictIt)
+ {
+ uno::Sequence< rtl::OUString > aLocaleNames( aDictIt->aLocaleNames );
+ sal_Int32 nLen2 = aLocaleNames.getLength();
+ for (k = 0; k < nLen2; ++k)
+ {
+ aLocaleNamesSet.insert( aLocaleNames[k] );
+ }
+ }
+ // ... and add them to the resulting sequence
+ aSuppLocales.realloc( aLocaleNamesSet.size() );
+ std::set< rtl::OUString, lt_rtl_OUString >::const_iterator aItB;
+ k = 0;
+ for (aItB = aLocaleNamesSet.begin(); aItB != aLocaleNamesSet.end(); ++aItB)
+ {
+ Locale aTmp( MsLangId::convertLanguageToLocale(
+ MsLangId::convertIsoStringToLanguage( *aItB )));
+ aSuppLocales[k++] = aTmp;
+ }
+
+ //! For each dictionary and each locale we need a seperate entry.
+ //! If this results in more than one dictionary per locale than (for now)
+ //! it is undefined which dictionary gets used.
+ //! In the future the implementation should support using several dictionaries
+ //! for one locale.
+ numthes = 0;
+ for (aDictIt = aDics.begin(); aDictIt != aDics.end(); ++aDictIt)
+ numthes = numthes + aDictIt->aLocaleNames.getLength();
+
+ // add dictionary information
+ aThes = new MyThes* [numthes];
+ aTEncs = new rtl_TextEncoding [numthes];
+ aTLocs = new Locale [numthes];
+ aTNames = new OUString [numthes];
+ aCharSetInfo = new CharClass* [numthes];
+
+ k = 0;
+ for (aDictIt = aDics.begin(); aDictIt != aDics.end(); ++aDictIt)
+ {
+ if (aDictIt->aLocaleNames.getLength() > 0 &&
+ aDictIt->aLocations.getLength() > 0)
+ {
+ uno::Sequence< rtl::OUString > aLocaleNames( aDictIt->aLocaleNames );
+ sal_Int32 nLocales = aLocaleNames.getLength();
+
+ // currently only one language per dictionary is supported in the actual implementation...
+ // Thus here we work-around this by adding the same dictionary several times.
+ // Once for each of it's supported locales.
+ for (sal_Int32 i = 0; i < nLocales; ++i)
+ {
+ aThes[k] = NULL;
+ aTEncs[k] = 0;
+ aTLocs[k] = MsLangId::convertLanguageToLocale(
+ MsLangId::convertIsoStringToLanguage( aDictIt->aLocaleNames[i] ));
+ aCharSetInfo[k] = new CharClass( aTLocs[k] );
+ // also both files have to be in the same directory and the
+ // file names must only differ in the extension (.aff/.dic).
+ // Thus we use the first location only and strip the extension part.
+ rtl::OUString aLocation = aDictIt->aLocations[0];
+ sal_Int32 nPos = aLocation.lastIndexOf( '.' );
+ aLocation = aLocation.copy( 0, nPos );
+ aTNames[k] = aLocation;
+
+ ++k;
+ }
+ }
+ }
+ DBG_ASSERT( k == numthes, "index mismatch?" );
+ }
+ else
+ {
+ /* no dictionary found so register no dictionaries */
+ numthes = 0;
+ aThes = NULL;
+ aTEncs = NULL;
+ aTLocs = NULL;
+ aTNames = NULL;
+ aCharSetInfo = NULL;
+ aSuppLocales.realloc(0);
+ }
+ }
+
+ return aSuppLocales;
+}
+
+
+
+sal_Bool SAL_CALL Thesaurus::hasLocale(const Locale& rLocale)
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ BOOL bRes = FALSE;
+ if (!aSuppLocales.getLength())
+ getLocales();
+ INT32 nLen = aSuppLocales.getLength();
+ for (INT32 i = 0; i < nLen; ++i)
+ {
+ const Locale *pLocale = aSuppLocales.getConstArray();
+ if (rLocale == pLocale[i])
+ {
+ bRes = TRUE;
+ break;
+ }
+ }
+ return bRes;
+}
+
+
+Sequence < Reference < ::com::sun::star::linguistic2::XMeaning > > SAL_CALL
+ Thesaurus::queryMeanings( const OUString& qTerm, const Locale& rLocale,
+ const PropertyValues& rProperties)
+ throw(IllegalArgumentException, RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ uno::Sequence< Reference< XMeaning > > aMeanings( 1 );
+ uno::Sequence< Reference< XMeaning > > noMeanings( 0 );
+ uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
+ uno::Reference< XSpellChecker1 > xSpell;
+
+ OUString rTerm(qTerm);
+ OUString pTerm(qTerm);
+ sal_uInt16 ct = CAPTYPE_UNKNOWN;
+ sal_Int32 stem = 0;
+ sal_Int32 stem2 = 0;
+
+ INT16 nLanguage = LocaleToLanguage( rLocale );
+
+ if (nLanguage == LANGUAGE_NONE || !rTerm.getLength())
+ return noMeanings;
+
+ if (!hasLocale( rLocale ))
+#ifdef LINGU_EXCEPTIONS
+ throw( IllegalArgumentException() );
+#else
+ return noMeanings;
+#endif
+
+ if (prevTerm == qTerm && prevLocale == nLanguage) return prevMeanings;
+
+ mentry * pmean = NULL;
+ sal_Int32 nmean = 0;
+
+ PropertyHelper_Thes &rHelper = GetPropHelper();
+ rHelper.SetTmpPropVals( rProperties );
+
+ MyThes * pTH = NULL;
+ rtl_TextEncoding aEnc = 0;
+ CharClass * pCC = NULL;
+
+ // find the first thesaurus that matches the locale
+ for (int i =0; i < numthes; i++) {
+ if (rLocale == aTLocs[i])
+ {
+ // open up and intialize this thesaurus if need be
+ if (!aThes[i])
+ {
+ OUString datpath = aTNames[i] + A2OU(".dat");
+ OUString idxpath = aTNames[i] + A2OU(".idx");
+ OUString ndat;
+ OUString nidx;
+ osl::FileBase::getSystemPathFromFileURL(datpath,ndat);
+ osl::FileBase::getSystemPathFromFileURL(idxpath,nidx);
+ OString aTmpidx(OU2ENC(nidx,osl_getThreadTextEncoding()));
+ OString aTmpdat(OU2ENC(ndat,osl_getThreadTextEncoding()));
+
+#if defined(WNT)
+ // workaround for Windows specifc problem that the
+ // path length in calls to 'fopen' is limted to somewhat
+ // about 120+ characters which will usually be exceed when
+ // using dictionaries as extensions.
+ aTmpidx = Win_GetShortPathName( nidx );
+ aTmpdat = Win_GetShortPathName( ndat );
+#endif
+
+ aThes[i] = new MyThes(aTmpidx.getStr(),aTmpdat.getStr());
+ if (aThes[i]) {
+ const char * enc_string = aThes[i]->get_th_encoding();
+ if (!enc_string) {
+ aTEncs[i] = rtl_getTextEncodingFromUnixCharset("ISO8859-1");
+ } else {
+ aTEncs[i] = rtl_getTextEncodingFromUnixCharset(enc_string);
+ if (aTEncs[i] == RTL_TEXTENCODING_DONTKNOW) {
+ if (strcmp("ISCII-DEVANAGARI", enc_string) == 0) {
+ aTEncs[i] = RTL_TEXTENCODING_ISCII_DEVANAGARI;
+ } else if (strcmp("UTF-8", enc_string) == 0) {
+ aTEncs[i] = RTL_TEXTENCODING_UTF8;
+ }
+ }
+ }
+ }
+ }
+ pTH = aThes[i];
+ aEnc = aTEncs[i];
+ pCC = aCharSetInfo[i];
+
+ if (pTH)
+ break;
+ }
+ }
+
+ while (pTH) {
+ // convert word to all lower case for searching
+ if (!stem) ct = capitalType(rTerm, pCC);
+ OUString nTerm(makeLowerCase(rTerm, pCC));
+ OString aTmp( OU2ENC(nTerm, aEnc) );
+ nmean = pTH->Lookup(aTmp.getStr(),aTmp.getLength(),&pmean);
+
+ if (nmean) aMeanings.realloc( nmean );
+
+ mentry * pe = pmean;
+ OUString codeTerm = qTerm;
+ Reference< XSpellAlternatives > xTmpRes2;
+
+ if (stem) {
+ xTmpRes2 = xSpell->spell( A2OU("<?xml?><query type='analyze'><word>") +
+ pTerm + A2OU("</word></query>"), nLanguage, rProperties );
+ if (xTmpRes2.is()) {
+ Sequence<OUString>seq = xTmpRes2->getAlternatives();
+ if (seq.getLength() > 0) {
+ codeTerm = seq[0];
+ stem2 = 1;
+ }
+#if 0
+ OString o = OUStringToOString(codeTerm, rtl_getTextEncodingFromUnixCharset("UTF-8"));
+ fprintf(stderr, "CODETERM: %s\n", o.pData->buffer);
+#endif
+ }
+ }
+
+ for (int j = 0; j < nmean; j++) {
+ int count = pe->count;
+ if (count) {
+ Sequence< OUString > aStr( count );
+ OUString *pStr = aStr.getArray();
+
+ for (int i=0; i < count; i++) {
+ OUString sTerm(pe->psyns[i],strlen(pe->psyns[i]),aEnc );
+ sal_Int32 catpos = sTerm.indexOf('(');
+ sal_Int32 catpos2 = 0;
+ OUString catst;
+ OUString catst2;
+ if (catpos > 2) {
+ // remove category name for affixation and casing
+ catst = A2OU(" ") + sTerm.copy(catpos);
+ sTerm = sTerm.copy(0, catpos);
+ sTerm = sTerm.trim();
+ }
+ // generate synonyms with affixes
+ if (stem && stem2) {
+ Reference< XSpellAlternatives > xTmpRes;
+ xTmpRes = xSpell->spell( A2OU("<?xml?><query type='generate'><word>") +
+ sTerm + A2OU("</word>") + codeTerm + A2OU("</query>"), nLanguage, rProperties );
+ if (xTmpRes.is()) {
+ Sequence<OUString>seq = xTmpRes->getAlternatives();
+ for (int k = 0; k < seq.getLength(); k++) {
+ OString o = OUStringToOString(seq[k], rtl_getTextEncodingFromUnixCharset("UTF-8"));
+ }
+ if (seq.getLength() > 0) sTerm = seq[0];
+ }
+ }
+ if (catpos2) sTerm = catst2 + sTerm;
+
+ sal_uInt16 ct1 = capitalType(sTerm, pCC);
+ if (CAPTYPE_MIXED == ct1)
+ ct = ct1;
+ OUString cTerm;
+ switch (ct) {
+ case CAPTYPE_ALLCAP:
+ {
+ cTerm = makeUpperCase(sTerm, pCC);
+ break;
+ }
+ case CAPTYPE_INITCAP:
+ {
+ cTerm = makeInitCap(sTerm, pCC);
+ break;
+ }
+ default:
+ {
+ cTerm = sTerm;
+ break;
+ }
+ }
+ OUString aAlt( cTerm + catst);
+ pStr[i] = aAlt;
+ }
+#if 0
+ Meaning * pMn = new Meaning(rTerm,nLanguage,rHelper);
+#endif
+ Meaning * pMn = new Meaning(rTerm,nLanguage);
+ OUString dTerm(pe->defn,strlen(pe->defn),aEnc );
+ pMn->SetMeaning(dTerm);
+ pMn->SetSynonyms(aStr);
+ Reference<XMeaning>* pMeaning = aMeanings.getArray();
+ pMeaning[j] = pMn;
+ }
+ pe++;
+ }
+ pTH->CleanUpAfterLookup(&pmean,nmean);
+
+ if (nmean) {
+ prevTerm = qTerm;
+ prevMeanings = aMeanings;
+ prevLocale = nLanguage;
+ return aMeanings;
+ }
+
+ if (stem || !xLngSvcMgr.is()) return noMeanings;
+ stem = 1;
+
+ xSpell = uno::Reference< XSpellChecker1 >( xLngSvcMgr->getSpellChecker(), UNO_QUERY );
+ if (!xSpell.is() || !xSpell->isValid( A2OU(SPELLML_SUPPORT), nLanguage, rProperties )) {
+ return noMeanings;
+ }
+ Reference< XSpellAlternatives > xTmpRes;
+ xTmpRes = xSpell->spell( A2OU("<?xml?><query type='stem'><word>") +
+ rTerm + A2OU("</word></query>"), nLanguage, rProperties );
+ if (xTmpRes.is()) {
+ Sequence<OUString>seq = xTmpRes->getAlternatives();
+#if 0
+ for (int i = 0; i < seq.getLength(); i++) {
+ OString o = OUStringToOString(seq[i], rtl_getTextEncodingFromUnixCharset("UTF-8"));
+ fprintf(stderr, "%d: %s\n", i + 1, o.pData->buffer);
+ }
+#endif
+ if (seq.getLength() > 0) {
+ rTerm = seq[0]; // XXX Use only the first stem
+ continue;
+ }
+ }
+
+ // stem the last word of the synonym (for categories after affixation)
+ rTerm = rTerm.trim();
+ sal_Int32 pos = rTerm.lastIndexOf(' ');
+ if (!pos) return noMeanings;
+ xTmpRes = xSpell->spell( A2OU("<?xml?><query type='stem'><word>") +
+ rTerm.copy(pos + 1) + A2OU("</word></query>"), nLanguage, rProperties );
+ if (xTmpRes.is()) {
+ Sequence<OUString>seq = xTmpRes->getAlternatives();
+ if (seq.getLength() > 0) {
+ pTerm = rTerm.copy(pos + 1);
+ rTerm = rTerm.copy(0, pos + 1) + seq[0];
+#if 0
+ for (int i = 0; i < seq.getLength(); i++) {
+ OString o = OUStringToOString(seq[i], rtl_getTextEncodingFromUnixCharset("UTF-8"));
+ fprintf(stderr, "%d: %s\n", i + 1, o.pData->buffer);
+ }
+#endif
+ continue;
+ }
+ }
+ break;
+ }
+ return noMeanings;
+}
+
+
+
+Reference< XInterface > SAL_CALL Thesaurus_CreateInstance(
+ const Reference< XMultiServiceFactory > & /*rSMgr*/ )
+ throw(Exception)
+{
+ Reference< XInterface > xService = (cppu::OWeakObject*) new Thesaurus;
+ return xService;
+}
+
+
+OUString SAL_CALL
+ Thesaurus::getServiceDisplayName( const Locale& /*rLocale*/ )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return A2OU( "OpenOffice.org New Thesaurus" );
+}
+
+
+void SAL_CALL
+ Thesaurus::initialize( const Sequence< Any >& rArguments )
+ throw(Exception, RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!pPropHelper)
+ {
+ INT32 nLen = rArguments.getLength();
+ if (1 == nLen)
+ {
+ Reference< XPropertySet > xPropSet;
+ rArguments.getConstArray()[0] >>= xPropSet;
+
+ //! Pointer allows for access of the non-UNO functions.
+ //! And the reference to the UNO-functions while increasing
+ //! the ref-count and will implicitly free the memory
+ //! when the object is not longer used.
+ pPropHelper = new PropertyHelper_Thes( (XThesaurus *) this, xPropSet );
+ xPropHelper = pPropHelper;
+ pPropHelper->AddAsPropListener(); //! after a reference is established
+ }
+ else
+ DBG_ERROR( "wrong number of arguments in sequence" );
+ }
+}
+
+
+
+sal_uInt16 SAL_CALL Thesaurus::capitalType(const OUString& aTerm, CharClass * pCC)
+{
+ sal_Int32 tlen = aTerm.getLength();
+ if ((pCC) && (tlen)) {
+ String aStr(aTerm);
+ sal_Int32 nc = 0;
+ for (USHORT tindex = 0; tindex < tlen; tindex++) {
+ if (pCC->getCharacterType(aStr,tindex) &
+ ::com::sun::star::i18n::KCharacterType::UPPER) nc++;
+ }
+
+ if (nc == 0) return (sal_uInt16) CAPTYPE_NOCAP;
+
+ if (nc == tlen) return (sal_uInt16) CAPTYPE_ALLCAP;
+
+ if ((nc == 1) && (pCC->getCharacterType(aStr,0) &
+ ::com::sun::star::i18n::KCharacterType::UPPER))
+ return (sal_uInt16) CAPTYPE_INITCAP;
+
+ return (sal_uInt16) CAPTYPE_MIXED;
+ }
+ return (sal_uInt16) CAPTYPE_UNKNOWN;
+}
+
+
+
+OUString SAL_CALL Thesaurus::makeLowerCase(const OUString& aTerm, CharClass * pCC)
+{
+ if (pCC)
+ return pCC->toLower_rtl(aTerm, 0, aTerm.getLength());
+ return aTerm;
+}
+
+
+OUString SAL_CALL Thesaurus::makeUpperCase(const OUString& aTerm, CharClass * pCC)
+{
+ if (pCC)
+ return pCC->toUpper_rtl(aTerm, 0, aTerm.getLength());
+ return aTerm;
+}
+
+
+OUString SAL_CALL Thesaurus::makeInitCap(const OUString& aTerm, CharClass * pCC)
+{
+ sal_Int32 tlen = aTerm.getLength();
+ if ((pCC) && (tlen)) {
+ OUString bTemp = aTerm.copy(0,1);
+ if (tlen > 1)
+ return ( pCC->toUpper_rtl(bTemp, 0, 1)
+ + pCC->toLower_rtl(aTerm,1,(tlen-1)) );
+
+ return pCC->toUpper_rtl(bTemp, 0, 1);
+ }
+ return aTerm;
+}
+
+
+
+void SAL_CALL
+ Thesaurus::dispose()
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bDisposing)
+ {
+ bDisposing = TRUE;
+ EventObject aEvtObj( (XThesaurus *) this );
+ aEvtListeners.disposeAndClear( aEvtObj );
+ }
+}
+
+
+void SAL_CALL
+ Thesaurus::addEventListener( const Reference< XEventListener >& rxListener )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bDisposing && rxListener.is())
+ aEvtListeners.addInterface( rxListener );
+}
+
+
+void SAL_CALL
+ Thesaurus::removeEventListener( const Reference< XEventListener >& rxListener )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bDisposing && rxListener.is())
+ aEvtListeners.removeInterface( rxListener );
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+// Service specific part
+//
+
+OUString SAL_CALL Thesaurus::getImplementationName()
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return getImplementationName_Static();
+}
+
+
+sal_Bool SAL_CALL Thesaurus::supportsService( const OUString& ServiceName )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getConstArray();
+ for( INT32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return TRUE;
+ return FALSE;
+}
+
+
+Sequence< OUString > SAL_CALL Thesaurus::getSupportedServiceNames()
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return getSupportedServiceNames_Static();
+}
+
+
+Sequence< OUString > Thesaurus::getSupportedServiceNames_Static()
+ throw()
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich
+ aSNS.getArray()[0] = A2OU( SN_THESAURUS );
+ return aSNS;
+}
+
+
+sal_Bool SAL_CALL Thesaurus_writeInfo(
+ void * /*pServiceManager*/, registry::XRegistryKey * pRegistryKey )
+{
+ try
+ {
+ String aImpl( '/' );
+ aImpl += Thesaurus::getImplementationName_Static().getStr();
+ aImpl.AppendAscii( "/UNO/SERVICES" );
+ Reference< registry::XRegistryKey > xNewKey =
+ pRegistryKey->createKey( aImpl );
+ Sequence< OUString > aServices =
+ Thesaurus::getSupportedServiceNames_Static();
+ for( INT32 i = 0; i < aServices.getLength(); i++ )
+ xNewKey->createKey( aServices.getConstArray()[i] );
+
+ return sal_True;
+ }
+ catch(Exception &)
+ {
+ return sal_False;
+ }
+}
+
+
+void * SAL_CALL Thesaurus_getFactory( const sal_Char * pImplName,
+ XMultiServiceFactory * pServiceManager, void * )
+{
+ void * pRet = 0;
+ if ( !Thesaurus::getImplementationName_Static().compareToAscii( pImplName ) )
+ {
+
+ Reference< XSingleServiceFactory > xFactory =
+ cppu::createOneInstanceFactory(
+ pServiceManager,
+ Thesaurus::getImplementationName_Static(),
+ Thesaurus_CreateInstance,
+ Thesaurus::getSupportedServiceNames_Static());
+ // acquire, because we return an interface pointer instead of a reference
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ return pRet;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+#undef CAPTYPE_UNKNOWN
+#undef CAPTYPE_NOCAP
+#undef CAPTYPE_INITCAP
+#undef CAPTYPE_ALLCAP
+#undef CAPTYPE_MIXED