office-gobmx/lingucomponent/source/thesaurus/libnth/nthesimp.cxx

798 lines
27 KiB
C++

/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: nthesimp.cxx,v $
* $Revision: 1.15.6.4 $
*
* 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