Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <i18npool/lang.h>
30 : : #include <tools/debug.hxx>
31 : : #include <svl/lngmisc.hxx>
32 : :
33 : : #include <cppuhelper/factory.hxx> // helper for factories
34 : : #include <com/sun/star/registry/XRegistryKey.hpp>
35 : : #include <com/sun/star/beans/XPropertySet.hpp>
36 : : #include <comphelper/processfactory.hxx>
37 : : #include <osl/mutex.hxx>
38 : :
39 : : #include "thesdsp.hxx"
40 : : #include "linguistic/lngprops.hxx"
41 : :
42 : : using namespace osl;
43 : : using namespace com::sun::star;
44 : : using namespace com::sun::star::beans;
45 : : using namespace com::sun::star::lang;
46 : : using namespace com::sun::star::uno;
47 : : using namespace com::sun::star::linguistic2;
48 : : using namespace linguistic;
49 : :
50 : : using ::rtl::OUString;
51 : :
52 : :
53 : 0 : static sal_Bool SvcListHasLanguage(
54 : : const Sequence< Reference< XThesaurus > > &rRefs,
55 : : const Locale &rLocale )
56 : : {
57 : 0 : sal_Bool bHasLanguage = sal_False;
58 : :
59 : 0 : const Reference< XThesaurus > *pRef = rRefs.getConstArray();
60 : 0 : sal_Int32 nLen = rRefs.getLength();
61 [ # # ][ # # ]: 0 : for (sal_Int32 k = 0; k < nLen && !bHasLanguage; ++k)
[ # # ]
62 : : {
63 [ # # ]: 0 : if (pRef[k].is())
64 : 0 : bHasLanguage = pRef[k]->hasLocale( rLocale );
65 : : }
66 : :
67 : 0 : return bHasLanguage;
68 : : }
69 : :
70 : :
71 : :
72 [ + - ]: 46 : ThesaurusDispatcher::ThesaurusDispatcher()
73 : : {
74 : 46 : }
75 : :
76 : :
77 : 46 : ThesaurusDispatcher::~ThesaurusDispatcher()
78 : : {
79 [ + - ]: 46 : ClearSvcList();
80 [ - + ]: 92 : }
81 : :
82 : :
83 : 46 : void ThesaurusDispatcher::ClearSvcList()
84 : : {
85 : : // release memory for each table entry
86 [ + - ]: 46 : ThesSvcByLangMap_t aTmp;
87 [ + - ]: 46 : aSvcMap.swap( aTmp );
88 : 46 : }
89 : :
90 : :
91 : : Sequence< Locale > SAL_CALL
92 : 0 : ThesaurusDispatcher::getLocales()
93 : : throw(RuntimeException)
94 : : {
95 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
96 : :
97 [ # # ]: 0 : Sequence< Locale > aLocales( static_cast< sal_Int32 >(aSvcMap.size()) );
98 [ # # ]: 0 : Locale *pLocales = aLocales.getArray();
99 : 0 : ThesSvcByLangMap_t::const_iterator aIt;
100 [ # # ]: 0 : for (aIt = aSvcMap.begin(); aIt != aSvcMap.end(); ++aIt)
101 : : {
102 [ # # ]: 0 : *pLocales++ = CreateLocale( aIt->first );
103 : : }
104 [ # # ]: 0 : return aLocales;
105 : : }
106 : :
107 : :
108 : : sal_Bool SAL_CALL
109 : 0 : ThesaurusDispatcher::hasLocale( const Locale& rLocale )
110 : : throw(RuntimeException)
111 : : {
112 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
113 [ # # ][ # # ]: 0 : ThesSvcByLangMap_t::const_iterator aIt( aSvcMap.find( LocaleToLanguage( rLocale ) ) );
114 [ # # ]: 0 : return aIt != aSvcMap.end();
115 : : }
116 : :
117 : :
118 : : Sequence< Reference< XMeaning > > SAL_CALL
119 : 0 : ThesaurusDispatcher::queryMeanings(
120 : : const OUString& rTerm, const Locale& rLocale,
121 : : const PropertyValues& rProperties )
122 : : throw(IllegalArgumentException, RuntimeException)
123 : : {
124 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
125 : :
126 [ # # ]: 0 : Sequence< Reference< XMeaning > > aMeanings;
127 : :
128 [ # # ]: 0 : sal_Int16 nLanguage = LocaleToLanguage( rLocale );
129 [ # # ][ # # ]: 0 : if (nLanguage == LANGUAGE_NONE || rTerm.isEmpty())
[ # # ]
130 : : return aMeanings;
131 : :
132 : : // search for entry with that language
133 [ # # ]: 0 : ThesSvcByLangMap_t::iterator aIt( aSvcMap.find( nLanguage ) );
134 [ # # ]: 0 : LangSvcEntries_Thes *pEntry = aIt != aSvcMap.end() ? aIt->second.get() : NULL;
135 : :
136 [ # # ]: 0 : if (!pEntry)
137 : : {
138 : : #ifdef LINGU_EXCEPTIONS
139 : : throw IllegalArgumentException();
140 : : #endif
141 : : }
142 : : else
143 : : {
144 : 0 : OUString aChkWord( rTerm );
145 : 0 : aChkWord = aChkWord.replace( SVT_HARD_SPACE, ' ' );
146 [ # # ]: 0 : RemoveHyphens( aChkWord );
147 [ # # ][ # # ]: 0 : if (IsIgnoreControlChars( rProperties, GetPropSet() ))
[ # # ]
148 [ # # ]: 0 : RemoveControlChars( aChkWord );
149 : :
150 : 0 : sal_Int32 nLen = pEntry->aSvcRefs.getLength();
151 : : DBG_ASSERT( nLen == pEntry->aSvcImplNames.getLength(),
152 : : "lng : sequence length mismatch");
153 : : DBG_ASSERT( pEntry->nLastTriedSvcIndex < nLen,
154 : : "lng : index out of range");
155 : :
156 : 0 : sal_Int32 i = 0;
157 : :
158 : : // try already instantiated services first
159 : : {
160 : 0 : const Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getConstArray();
161 [ # # # # ]: 0 : while (i <= pEntry->nLastTriedSvcIndex
[ # # ]
162 : 0 : && aMeanings.getLength() == 0)
163 : : {
164 [ # # ][ # # ]: 0 : if (pRef[i].is() && pRef[i]->hasLocale( rLocale ))
[ # # ][ # # ]
[ # # ]
165 [ # # ][ # # ]: 0 : aMeanings = pRef[i]->queryMeanings( aChkWord, rLocale, rProperties );
[ # # ][ # # ]
166 : 0 : ++i;
167 : : }
168 : : }
169 : :
170 : : // if still no result instantiate new services and try those
171 [ # # ][ # # ]: 0 : if (aMeanings.getLength() == 0
[ # # ]
172 : : && pEntry->nLastTriedSvcIndex < nLen - 1)
173 : : {
174 : 0 : const OUString *pImplNames = pEntry->aSvcImplNames.getConstArray();
175 [ # # ]: 0 : Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getArray();
176 : :
177 : : Reference< XMultiServiceFactory > xMgr(
178 [ # # ]: 0 : comphelper::getProcessServiceFactory() );
179 [ # # ]: 0 : if (xMgr.is())
180 : : {
181 : : // build service initialization argument
182 [ # # ]: 0 : Sequence< Any > aArgs(1);
183 [ # # ][ # # ]: 0 : aArgs.getArray()[0] <<= GetPropSet();
[ # # ]
184 : :
185 [ # # ][ # # ]: 0 : while (i < nLen && aMeanings.getLength() == 0)
[ # # ]
186 : : {
187 : : // create specific service via it's implementation name
188 : 0 : Reference< XThesaurus > xThes;
189 : : try
190 : : {
191 : : xThes = Reference< XThesaurus >(
192 [ # # ]: 0 : xMgr->createInstanceWithArguments(
193 [ # # ][ # # ]: 0 : pImplNames[i], aArgs ), UNO_QUERY );
[ # # ][ # # ]
194 : : }
195 [ # # ]: 0 : catch (uno::Exception &)
196 : : {
197 : : DBG_ASSERT( 0, "createInstanceWithArguments failed" );
198 : : }
199 [ # # ]: 0 : pRef[i] = xThes;
200 : :
201 [ # # ][ # # ]: 0 : if (xThes.is() && xThes->hasLocale( rLocale ))
[ # # ][ # # ]
[ # # ]
202 [ # # ][ # # ]: 0 : aMeanings = xThes->queryMeanings( aChkWord, rLocale, rProperties );
[ # # ][ # # ]
203 : :
204 : 0 : pEntry->nLastTriedSvcIndex = (sal_Int16) i;
205 : 0 : ++i;
206 : 0 : }
207 : :
208 : : // if language is not supported by any of the services
209 : : // remove it from the list.
210 [ # # ][ # # ]: 0 : if (i == nLen && aMeanings.getLength() == 0)
[ # # ]
211 : : {
212 [ # # ][ # # ]: 0 : if (!SvcListHasLanguage( pEntry->aSvcRefs, rLocale ))
213 [ # # ]: 0 : aSvcMap.erase( nLanguage );
214 [ # # ]: 0 : }
215 : 0 : }
216 : 0 : }
217 : : }
218 : :
219 [ # # ]: 0 : return aMeanings;
220 : : }
221 : :
222 : :
223 : 2160 : void ThesaurusDispatcher::SetServiceList( const Locale &rLocale,
224 : : const Sequence< OUString > &rSvcImplNames )
225 : : {
226 [ + - ][ + - ]: 2160 : MutexGuard aGuard( GetLinguMutex() );
227 : :
228 [ + - ]: 2160 : sal_Int16 nLanguage = LocaleToLanguage( rLocale );
229 : :
230 : 2160 : sal_Int32 nLen = rSvcImplNames.getLength();
231 [ - + ]: 2160 : if (0 == nLen)
232 : : // remove entry
233 [ # # ]: 0 : aSvcMap.erase( nLanguage );
234 : : else
235 : : {
236 : : // modify/add entry
237 [ + - ]: 2160 : LangSvcEntries_Thes *pEntry = aSvcMap[ nLanguage ].get();
238 [ + + ]: 2160 : if (pEntry)
239 : : {
240 [ + - ]: 90 : pEntry->Clear();
241 [ + - ]: 90 : pEntry->aSvcImplNames = rSvcImplNames;
242 [ + - ][ + - ]: 90 : pEntry->aSvcRefs = Sequence< Reference < XThesaurus > >( nLen );
[ + - ]
243 : : }
244 : : else
245 : : {
246 [ + - ][ + - ]: 2070 : boost::shared_ptr< LangSvcEntries_Thes > pTmpEntry( new LangSvcEntries_Thes( rSvcImplNames ) );
[ + - ]
247 [ + - ][ + - ]: 2070 : pTmpEntry->aSvcRefs = Sequence< Reference < XThesaurus > >( nLen );
[ + - ]
248 [ + - ][ + - ]: 2070 : aSvcMap[ nLanguage ] = pTmpEntry;
[ + - ]
249 : : }
250 [ + - ]: 2160 : }
251 : 2160 : }
252 : :
253 : :
254 : : Sequence< OUString >
255 : 0 : ThesaurusDispatcher::GetServiceList( const Locale &rLocale ) const
256 : : {
257 [ # # ][ # # ]: 0 : MutexGuard aGuard( GetLinguMutex() );
258 : :
259 [ # # ]: 0 : Sequence< OUString > aRes;
260 : :
261 : : // search for entry with that language and use data from that
262 [ # # ]: 0 : sal_Int16 nLanguage = LocaleToLanguage( rLocale );
263 : 0 : ThesaurusDispatcher *pThis = (ThesaurusDispatcher *) this;
264 [ # # ]: 0 : const ThesSvcByLangMap_t::iterator aIt( pThis->aSvcMap.find( nLanguage ) );
265 [ # # ]: 0 : const LangSvcEntries_Thes *pEntry = aIt != aSvcMap.end() ? aIt->second.get() : NULL;
266 [ # # ]: 0 : if (pEntry)
267 [ # # ]: 0 : aRes = pEntry->aSvcImplNames;
268 : :
269 [ # # ]: 0 : return aRes;
270 : : }
271 : :
272 : :
273 : 0 : LinguDispatcher::DspType ThesaurusDispatcher::GetDspType() const
274 : : {
275 : 0 : return DSP_THES;
276 : : }
277 : :
278 : :
279 : :
280 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|