diff options
Diffstat (limited to 'lingucomponent/source/thesaurus/libnth/nthesimp.cxx')
-rw-r--r-- | lingucomponent/source/thesaurus/libnth/nthesimp.cxx | 695 |
1 files changed, 695 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..3e5d3fffd1ee --- /dev/null +++ b/lingucomponent/source/thesaurus/libnth/nthesimp.cxx @@ -0,0 +1,695 @@ +/************************************************************************* + * + * $RCSfile: nthesimp.cxx,v $ + * (modified version of sspellimp.cxx) + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2004-02-04 13:00:19 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// include <stdio.h> + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_ +#include <com/sun/star/uno/Reference.h> +#endif + +#include <cppuhelper/factory.hxx> // helper for factories +#include <com/sun/star/registry/XRegistryKey.hpp> + +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include <com/sun/star/beans/XPropertySet.hpp> +#endif +#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT +#include <tools/debug.hxx> +#endif +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ +#include <unotools/processfactory.hxx> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX +#include <svtools/pathoptions.hxx> +#endif + +#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 <csutil.hxx> + +// 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 + + + +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; + + + +/////////////////////////////////////////////////////////////////////////// + +BOOL operator == ( const Locale &rL1, const Locale &rL2 ) +{ + return rL1.Language == rL2.Language && + rL1.Country == rL2.Country && + rL1.Variant == rL2.Variant; +} + +///////////////////////////////////////////////////////////////////////// + + +Thesaurus::Thesaurus() : + aEvtListeners ( GetLinguMutex() ) +{ + bDisposing = FALSE; + pPropHelper = NULL; + aThes = NULL; + aCharSetInfo = NULL; + aTEncs = NULL; + aTLocs = NULL; + aTNames = NULL; + numthes = 0; +} + + +Thesaurus::~Thesaurus() +{ + + for (int i = 0; i < numthes; i++) { + if (aThes[i]) delete aThes[i]; + aThes[i] = NULL; + if (aCharSetInfo[i]) delete aCharSetInfo[i]; + aCharSetInfo[i] = NULL; + } + if (aThes) delete[] aThes; + aThes = NULL; + if (aCharSetInfo) delete[] aCharSetInfo; + aCharSetInfo = NULL; + if (aTEncs) delete[] aTEncs; + aTEncs = NULL; + if (aTLocs) delete[] aTLocs; + aTLocs = NULL; + if (aTNames) delete[] aTNames; + aTNames = NULL; + numthes = 0; + + 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() ); + + dictentry * spthes; // shared thesaurus list entry pointer + dictentry * upthes; // shared thesaurus list entry pointer + SvtPathOptions aPathOpt; + int numusr; // number of user dictionary entries + int numshr = 0; // number of shared dictionary entries + + if (!numthes) { + + // invoke a dictionary manager to get the user dictionary list + OUString usrlst = aPathOpt.GetUserDictionaryPath() + A2OU("/dictionary.lst"); + OUString ulst; + osl::FileBase::getSystemPathFromFileURL(usrlst,ulst); + OString uTmp(OU2ENC(ulst, osl_getThreadTextEncoding())); + DictMgr* udMgr = new DictMgr(uTmp.getStr(),"THES"); + numusr = 0; + if (udMgr) + numusr = udMgr->get_list(&upthes); + + // invoke a dictionary manager to get the shared thesaurus list + OUString shrlst = aPathOpt.GetLinguisticPath() + A2OU("/ooo/dictionary.lst"); + OUString slst; + osl::FileBase::getSystemPathFromFileURL(shrlst,slst); + OString sTmp(OU2ENC(slst, osl_getThreadTextEncoding())); + DictMgr* sdMgr = new DictMgr(sTmp.getStr(),"THES"); + if (sdMgr) + numshr = sdMgr->get_list(&spthes); + + + // we really should merge these and remove duplicates but since + // users can name their dictionaries anything they want it would + // be impossible to know if a real duplication exists unless we + // add some unique key to each dictionary + numthes = numshr + numusr; + + if (numthes) { + aThes = new MyThes* [numthes]; + aTEncs = new rtl_TextEncoding [numthes]; + aTLocs = new Locale [numthes]; + aTNames = new OUString [numthes]; + aCharSetInfo = new CharClass* [numthes]; + aSuppLocales.realloc(numthes); + Locale * pLocale = aSuppLocales.getArray(); + int numlocs = 0; + int newloc; + int i,j; + int k = 0; + + //first add the user dictionaries + for (i = 0; i < numusr; i++) { + Locale nLoc( A2OU(upthes->lang), A2OU(upthes->region), OUString() ); + newloc = 1; + for (j = 0; j < numlocs; j++) { + if (nLoc == pLocale[j]) newloc = 0; + } + if (newloc) { + pLocale[numlocs] = nLoc; + numlocs++; + } + aTLocs[k] = nLoc; + aThes[k] = NULL; + aTEncs[k] = 0; + + aTNames[k] = aPathOpt.GetUserDictionaryPath() + A2OU("/") + A2OU(upthes->filename); + aCharSetInfo[k] = new CharClass(nLoc); + k++; + upthes++; + } + + // now add the shared thesauri + for (i = 0; i < numshr; i++) { + Locale nLoc( A2OU(spthes->lang), A2OU(spthes->region), OUString() ); + newloc = 1; + for (j = 0; j < numlocs; j++) { + if (nLoc == pLocale[j]) newloc = 0; + } + if (newloc) { + pLocale[numlocs] = nLoc; + numlocs++; + } + aTLocs[k] = nLoc; + aThes[k] = NULL; + aTEncs[k] = 0; + aTNames[k] = aPathOpt.GetLinguisticPath() + A2OU("/ooo/") + A2OU(spthes->filename); + aCharSetInfo[k] = new CharClass(nLoc); + k++; + spthes++; + } + + aSuppLocales.realloc(numlocs); + + } else { + // no dictionary.lst so don't register any + numthes = 0; + aThes = NULL; + aTEncs = NULL; + aTLocs = NULL; + aTNames = NULL; + aSuppLocales.realloc(0); + aCharSetInfo = NULL; + } + + /* de-allocation of memory is handled inside the DictMgr */ + upthes = NULL; + if (udMgr) { + delete udMgr; + udMgr = NULL; + } + spthes = NULL; + if (sdMgr) { + delete sdMgr; + sdMgr = NULL; + } + + } + + 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& rTerm, const Locale& rLocale, + const PropertyValues& rProperties) + throw(IllegalArgumentException, RuntimeException) +{ + MutexGuard aGuard( GetLinguMutex() ); + + uno::Sequence< Reference< XMeaning > > aMeanings( 1 ); + uno::Sequence< Reference< XMeaning > > noMeanings( 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 + + 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())); + 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(enc_string); + } else { + aTEncs[i] = rtl_getTextEncodingFromUnixCharset("ISO8859-1"); + } + } + } + pTH = aThes[i]; + aEnc = aTEncs[i]; + pCC = aCharSetInfo[i]; + } + } + + if (pTH) { + // convert word to all lower case for searching + sal_uInt16 ct = CAPTYPE_UNKNOWN; + 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; + 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 ); + 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 ); + 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) { + return aMeanings; + } + 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 (sal_Int32 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 |