LibreOffice Module linguistic (master) 1
thesdsp.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <i18nlangtag/lang.h>
22#include <tools/debug.hxx>
23#include <svl/lngmisc.hxx>
24
25#include <com/sun/star/beans/XPropertySet.hpp>
28#include <com/sun/star/uno/XComponentContext.hpp>
29#include <osl/mutex.hxx>
30#include <sal/log.hxx>
31
32#include "thesdsp.hxx"
33#include <linguistic/misc.hxx>
34
35using namespace osl;
36using namespace com::sun::star;
37using namespace com::sun::star::beans;
38using namespace com::sun::star::lang;
39using namespace com::sun::star::uno;
40using namespace com::sun::star::linguistic2;
41using namespace linguistic;
42
43
45 const Sequence< Reference< XThesaurus > > &rRefs,
46 const Locale &rLocale )
47{
48 return std::any_of(rRefs.begin(), rRefs.end(),
49 [&rLocale](const Reference<XThesaurus>& rRef) {
50 return rRef.is() && rRef->hasLocale( rLocale ); });
51}
52
53
55{
56}
57
58
60{
62}
63
64
66{
67 // release memory for each table entry
69}
70
71
72Sequence< Locale > SAL_CALL
74{
75 MutexGuard aGuard( GetLinguMutex() );
76
77 std::vector<Locale> aLocales;
78 aLocales.reserve(aSvcMap.size());
79
80 std::transform(aSvcMap.begin(), aSvcMap.end(), std::back_inserter(aLocales),
81 [](ThesSvcByLangMap_t::const_reference elem) { return LanguageTag::convertToLocale(elem.first); });
82
83 return comphelper::containerToSequence(aLocales);
84}
85
86
87sal_Bool SAL_CALL
88 ThesaurusDispatcher::hasLocale( const Locale& rLocale )
89{
90 MutexGuard aGuard( GetLinguMutex() );
91 ThesSvcByLangMap_t::const_iterator aIt( aSvcMap.find( LinguLocaleToLanguage( rLocale ) ) );
92 return aIt != aSvcMap.end();
93}
94
95
98 const OUString& rTerm, const Locale& rLocale,
99 const css::uno::Sequence< ::css::beans::PropertyValue >& rProperties )
100{
101 MutexGuard aGuard( GetLinguMutex() );
102
104
105 LanguageType nLanguage = LinguLocaleToLanguage( rLocale );
106 if (LinguIsUnspecified( nLanguage) || rTerm.isEmpty())
107 return aMeanings;
108
109 // search for entry with that language
110 ThesSvcByLangMap_t::iterator aIt( aSvcMap.find( nLanguage ) );
111 LangSvcEntries_Thes *pEntry = aIt != aSvcMap.end() ? aIt->second.get() : nullptr;
112
113 if (pEntry)
114 {
115 OUString aChkWord = rTerm.replace( SVT_HARD_SPACE, ' ' );
116 RemoveHyphens( aChkWord );
117 if (IsIgnoreControlChars( rProperties, GetPropSet() ))
118 RemoveControlChars( aChkWord );
119
120 sal_Int32 nLen = pEntry->aSvcRefs.getLength();
121 DBG_ASSERT( nLen == pEntry->aSvcImplNames.getLength(),
122 "lng : sequence length mismatch");
123 DBG_ASSERT( pEntry->nLastTriedSvcIndex < nLen,
124 "lng : index out of range");
125
126 sal_Int32 i = 0;
127
128 // try already instantiated services first
129 {
130 const Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getConstArray();
131 while (i <= pEntry->nLastTriedSvcIndex
132 && !aMeanings.hasElements())
133 {
134 if (pRef[i].is() && pRef[i]->hasLocale( rLocale ))
135 aMeanings = pRef[i]->queryMeanings( aChkWord, rLocale, rProperties );
136 ++i;
137 }
138 }
139
140 // if still no result instantiate new services and try those
141 if (!aMeanings.hasElements()
142 && pEntry->nLastTriedSvcIndex < nLen - 1)
143 {
144 const OUString *pImplNames = pEntry->aSvcImplNames.getConstArray();
145 Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getArray();
146
149
150 // build service initialization argument
151 Sequence< Any > aArgs(1);
152 aArgs.getArray()[0] <<= GetPropSet();
153
154 while (i < nLen && !aMeanings.hasElements())
155 {
156 // create specific service via it's implementation name
158 try
159 {
160 xThes.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
161 pImplNames[i], aArgs, xContext ),
162 UNO_QUERY );
163 }
164 catch (uno::Exception &)
165 {
166 SAL_WARN( "linguistic", "createInstanceWithArguments failed" );
167 }
168 pRef[i] = xThes;
169
170 if (xThes.is() && xThes->hasLocale( rLocale ))
171 aMeanings = xThes->queryMeanings( aChkWord, rLocale, rProperties );
172
173 pEntry->nLastTriedSvcIndex = static_cast<sal_Int16>(i);
174 ++i;
175 }
176
177 // if language is not supported by any of the services
178 // remove it from the list.
179 if (i == nLen && !aMeanings.hasElements())
180 {
181 if (!SvcListHasLanguage( pEntry->aSvcRefs, rLocale ))
182 aSvcMap.erase( nLanguage );
183 }
184 }
185 }
186
187 return aMeanings;
188}
189
190
191void ThesaurusDispatcher::SetServiceList( const Locale &rLocale,
192 const Sequence< OUString > &rSvcImplNames )
193{
194 MutexGuard aGuard( GetLinguMutex() );
195
196 LanguageType nLanguage = LinguLocaleToLanguage( rLocale );
197
198 sal_Int32 nLen = rSvcImplNames.getLength();
199 if (0 == nLen)
200 // remove entry
201 aSvcMap.erase( nLanguage );
202 else
203 {
204 // modify/add entry
205 LangSvcEntries_Thes *pEntry = aSvcMap[ nLanguage ].get();
206 if (pEntry)
207 {
208 pEntry->Clear();
209 pEntry->aSvcImplNames = rSvcImplNames;
211 }
212 else
213 {
214 auto pTmpEntry = std::make_shared<LangSvcEntries_Thes>( rSvcImplNames );
215 pTmpEntry->aSvcRefs = Sequence< Reference < XThesaurus > >( nLen );
216 aSvcMap[ nLanguage ] = pTmpEntry;
217 }
218 }
219}
220
221
223 ThesaurusDispatcher::GetServiceList( const Locale &rLocale ) const
224{
225 MutexGuard aGuard( GetLinguMutex() );
226
228
229 // search for entry with that language and use data from that
230 LanguageType nLanguage = LinguLocaleToLanguage( rLocale );
231 const ThesSvcByLangMap_t::const_iterator aIt( aSvcMap.find( nLanguage ) );
232 const LangSvcEntries_Thes *pEntry = aIt != aSvcMap.end() ? aIt->second.get() : nullptr;
233 if (pEntry)
234 aRes = pEntry->aSvcImplNames;
235
236 return aRes;
237}
238
239
240/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual css::uno::Sequence< css::uno::Reference< css::linguistic2::XMeaning > > SAL_CALL queryMeanings(const OUString &aTerm, const css::lang::Locale &aLocale, const css::uno::Sequence< ::css::beans::PropertyValue > &aProperties) override
Definition: thesdsp.cxx:97
virtual ~ThesaurusDispatcher() override
Definition: thesdsp.cxx:59
std::map< LanguageType, LangSvcEntries_Thes_Ptr_t > ThesSvcByLangMap_t
Definition: thesdsp.hxx:43
virtual void SetServiceList(const css::lang::Locale &rLocale, const css::uno::Sequence< OUString > &rSvcImplNames) override
Definition: thesdsp.cxx:191
virtual sal_Bool SAL_CALL hasLocale(const css::lang::Locale &aLocale) override
Definition: thesdsp.cxx:88
virtual css::uno::Sequence< css::lang::Locale > SAL_CALL getLocales() override
Definition: thesdsp.cxx:73
virtual css::uno::Sequence< OUString > GetServiceList(const css::lang::Locale &rLocale) const override
Definition: thesdsp.cxx:223
const css::uno::Reference< css::linguistic2::XLinguProperties > & GetPropSet()
Definition: thesdsp.hxx:82
ThesSvcByLangMap_t aSvcMap
Definition: thesdsp.hxx:44
#define DBG_ASSERT(sCon, aError)
#define SVT_HARD_SPACE
#define SAL_WARN(area, stream)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference< XComponentContext > getProcessComponentContext()
int i
bool LinguIsUnspecified(LanguageType nLanguage)
Checks if a LanguageType is one of the values that denote absence of language or undetermined languag...
Definition: misc.cxx:88
bool RemoveHyphens(OUString &rTxt)
bool RemoveControlChars(OUString &rTxt)
osl::Mutex & GetLinguMutex()
! multi-thread safe mutex for all platforms !!
Definition: misc.cxx:60
bool IsIgnoreControlChars(const PropertyValues &rProperties, const uno::Reference< XPropertySet > &rxProp)
Definition: misc.cxx:211
LanguageType LinguLocaleToLanguage(const css::lang::Locale &rLocale)
Convert Locale to LanguageType for legacy handling.
Definition: misc.cxx:74
css::uno::Sequence< css::uno::Reference< css::linguistic2::XThesaurus > > aSvcRefs
Definition: defs.hxx:73
css::uno::Sequence< OUString > aSvcImplNames
Definition: defs.hxx:34
void Clear()
Definition: defs.hxx:50
sal_Int16 nLastTriedSvcIndex
Definition: defs.hxx:36
static bool SvcListHasLanguage(const Sequence< Reference< XThesaurus > > &rRefs, const Locale &rLocale)
Definition: thesdsp.cxx:44
unsigned char sal_Bool