Update ooo320-m1
[ooovba.git] / linguistic / source / thesdsp.cxx
blob9ba9f9f9ce7bd036c3c0fb8672f25a4e926e81df
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: thesdsp.cxx,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_linguistic.hxx"
33 #include <i18npool/lang.h>
34 #include <tools/debug.hxx>
35 #include <svtools/lngmisc.hxx>
37 #include <cppuhelper/factory.hxx> // helper for factories
38 #include <com/sun/star/registry/XRegistryKey.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <unotools/processfactory.hxx>
41 #include <osl/mutex.hxx>
43 #include "thesdsp.hxx"
44 #include "lngprops.hxx"
46 using namespace utl;
47 using namespace osl;
48 using namespace rtl;
49 using namespace com::sun::star;
50 using namespace com::sun::star::beans;
51 using namespace com::sun::star::lang;
52 using namespace com::sun::star::uno;
53 using namespace com::sun::star::linguistic2;
54 using namespace linguistic;
56 ///////////////////////////////////////////////////////////////////////////
58 static BOOL SvcListHasLanguage(
59 const Sequence< Reference< XThesaurus > > &rRefs,
60 const Locale &rLocale )
62 BOOL bHasLanguage = FALSE;
64 const Reference< XThesaurus > *pRef = rRefs.getConstArray();
65 INT32 nLen = rRefs.getLength();
66 for (INT32 k = 0; k < nLen && !bHasLanguage; ++k)
68 if (pRef[k].is())
69 bHasLanguage = pRef[k]->hasLocale( rLocale );
72 return bHasLanguage;
75 ///////////////////////////////////////////////////////////////////////////
78 ThesaurusDispatcher::ThesaurusDispatcher()
83 ThesaurusDispatcher::~ThesaurusDispatcher()
85 ClearSvcList();
89 void ThesaurusDispatcher::ClearSvcList()
91 // release memory for each table entry
92 ThesSvcByLangMap_t aTmp;
93 aSvcMap.swap( aTmp );
97 Sequence< Locale > SAL_CALL
98 ThesaurusDispatcher::getLocales()
99 throw(RuntimeException)
101 MutexGuard aGuard( GetLinguMutex() );
103 Sequence< Locale > aLocales( static_cast< sal_Int32 >(aSvcMap.size()) );
104 Locale *pLocales = aLocales.getArray();
105 ThesSvcByLangMap_t::const_iterator aIt;
106 for (aIt = aSvcMap.begin(); aIt != aSvcMap.end(); ++aIt)
108 *pLocales++ = CreateLocale( aIt->first );
110 return aLocales;
114 sal_Bool SAL_CALL
115 ThesaurusDispatcher::hasLocale( const Locale& rLocale )
116 throw(RuntimeException)
118 MutexGuard aGuard( GetLinguMutex() );
119 ThesSvcByLangMap_t::const_iterator aIt( aSvcMap.find( LocaleToLanguage( rLocale ) ) );
120 return aIt != aSvcMap.end();
124 Sequence< Reference< XMeaning > > SAL_CALL
125 ThesaurusDispatcher::queryMeanings(
126 const OUString& rTerm, const Locale& rLocale,
127 const PropertyValues& rProperties )
128 throw(IllegalArgumentException, RuntimeException)
130 MutexGuard aGuard( GetLinguMutex() );
132 Sequence< Reference< XMeaning > > aMeanings;
134 INT16 nLanguage = LocaleToLanguage( rLocale );
135 if (nLanguage == LANGUAGE_NONE || !rTerm.getLength())
136 return aMeanings;
138 // search for entry with that language
139 LangSvcEntries_Thes *pEntry = aSvcMap[ nLanguage ].get();
141 if (!pEntry)
143 #ifdef LINGU_EXCEPTIONS
144 throw IllegalArgumentException();
145 #endif
147 else
149 OUString aChkWord( rTerm );
150 aChkWord = aChkWord.replace( SVT_HARD_SPACE, ' ' );
151 RemoveHyphens( aChkWord );
152 if (IsIgnoreControlChars( rProperties, GetPropSet() ))
153 RemoveControlChars( aChkWord );
155 INT32 nLen = pEntry->aSvcRefs.getLength();
156 DBG_ASSERT( nLen == pEntry->aSvcImplNames.getLength(),
157 "lng : sequence length mismatch");
158 DBG_ASSERT( pEntry->nLastTriedSvcIndex < nLen,
159 "lng : index out of range");
161 INT32 i = 0;
163 // try already instantiated services first
165 const Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getConstArray();
166 while (i <= pEntry->nLastTriedSvcIndex
167 && aMeanings.getLength() == 0)
169 if (pRef[i].is() && pRef[i]->hasLocale( rLocale ))
170 aMeanings = pRef[i]->queryMeanings( aChkWord, rLocale, rProperties );
171 ++i;
175 // if still no result instantiate new services and try those
176 if (aMeanings.getLength() == 0
177 && pEntry->nLastTriedSvcIndex < nLen - 1)
179 const OUString *pImplNames = pEntry->aSvcImplNames.getConstArray();
180 Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getArray();
182 Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() );
183 if (xMgr.is())
185 // build service initialization argument
186 Sequence< Any > aArgs(1);
187 aArgs.getArray()[0] <<= GetPropSet();
189 while (i < nLen && aMeanings.getLength() == 0)
191 // create specific service via it's implementation name
192 Reference< XThesaurus > xThes;
195 xThes = Reference< XThesaurus >(
196 xMgr->createInstanceWithArguments(
197 pImplNames[i], aArgs ), UNO_QUERY );
199 catch (uno::Exception &)
201 DBG_ASSERT( 0, "createInstanceWithArguments failed" );
203 pRef[i] = xThes;
205 if (xThes.is() && xThes->hasLocale( rLocale ))
206 aMeanings = xThes->queryMeanings( aChkWord, rLocale, rProperties );
208 pEntry->nLastTriedSvcIndex = (INT16) i;
209 ++i;
212 // if language is not supported by any of the services
213 // remove it from the list.
214 if (i == nLen && aMeanings.getLength() == 0)
216 if (!SvcListHasLanguage( pEntry->aSvcRefs, rLocale ))
217 aSvcMap.erase( nLanguage );
223 return aMeanings;
227 void ThesaurusDispatcher::SetServiceList( const Locale &rLocale,
228 const Sequence< OUString > &rSvcImplNames )
230 MutexGuard aGuard( GetLinguMutex() );
232 INT16 nLanguage = LocaleToLanguage( rLocale );
234 INT32 nLen = rSvcImplNames.getLength();
235 if (0 == nLen)
236 // remove entry
237 aSvcMap.erase( nLanguage );
238 else
240 // modify/add entry
241 LangSvcEntries_Thes *pEntry = aSvcMap[ nLanguage ].get();
242 if (pEntry)
244 pEntry->Clear();
245 pEntry->aSvcImplNames = rSvcImplNames;
246 pEntry->aSvcRefs = Sequence< Reference < XThesaurus > >( nLen );
248 else
250 boost::shared_ptr< LangSvcEntries_Thes > pTmpEntry( new LangSvcEntries_Thes( rSvcImplNames ) );
251 pTmpEntry->aSvcRefs = Sequence< Reference < XThesaurus > >( nLen );
252 aSvcMap[ nLanguage ] = pTmpEntry;
258 Sequence< OUString >
259 ThesaurusDispatcher::GetServiceList( const Locale &rLocale ) const
261 MutexGuard aGuard( GetLinguMutex() );
263 Sequence< OUString > aRes;
265 // search for entry with that language and use data from that
266 INT16 nLanguage = LocaleToLanguage( rLocale );
267 ThesaurusDispatcher *pThis = (ThesaurusDispatcher *) this;
268 const LangSvcEntries_Thes *pEntry = pThis->aSvcMap[ nLanguage ].get();
269 if (pEntry)
270 aRes = pEntry->aSvcImplNames;
272 return aRes;
276 LinguDispatcher::DspType ThesaurusDispatcher::GetDspType() const
278 return DSP_THES;
282 ///////////////////////////////////////////////////////////////////////////