1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: thesdsp.cxx,v $
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"
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
)
69 bHasLanguage
= pRef
[k
]->hasLocale( rLocale
);
75 ///////////////////////////////////////////////////////////////////////////
78 ThesaurusDispatcher::ThesaurusDispatcher()
83 ThesaurusDispatcher::~ThesaurusDispatcher()
89 void ThesaurusDispatcher::ClearSvcList()
91 // release memory for each table entry
92 ThesSvcByLangMap_t 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
);
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())
138 // search for entry with that language
139 LangSvcEntries_Thes
*pEntry
= aSvcMap
[ nLanguage
].get();
143 #ifdef LINGU_EXCEPTIONS
144 throw IllegalArgumentException();
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");
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
);
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() );
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" );
205 if (xThes
.is() && xThes
->hasLocale( rLocale
))
206 aMeanings
= xThes
->queryMeanings( aChkWord
, rLocale
, rProperties
);
208 pEntry
->nLastTriedSvcIndex
= (INT16
) 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
);
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();
237 aSvcMap
.erase( nLanguage
);
241 LangSvcEntries_Thes
*pEntry
= aSvcMap
[ nLanguage
].get();
245 pEntry
->aSvcImplNames
= rSvcImplNames
;
246 pEntry
->aSvcRefs
= Sequence
< Reference
< XThesaurus
> >( nLen
);
250 boost::shared_ptr
< LangSvcEntries_Thes
> pTmpEntry( new LangSvcEntries_Thes( rSvcImplNames
) );
251 pTmpEntry
->aSvcRefs
= Sequence
< Reference
< XThesaurus
> >( nLen
);
252 aSvcMap
[ nLanguage
] = pTmpEntry
;
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();
270 aRes
= pEntry
->aSvcImplNames
;
276 LinguDispatcher::DspType
ThesaurusDispatcher::GetDspType() const
282 ///////////////////////////////////////////////////////////////////////////