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 : :
30 : : #include "filterfactory.hxx"
31 : : #include "macros.hxx"
32 : : #include "constant.hxx"
33 : : #include "versions.hxx"
34 : :
35 : : #include <com/sun/star/lang/XInitialization.hpp>
36 : : #include <comphelper/enumhelper.hxx>
37 : : #include <comphelper/configurationhelper.hxx>
38 : : #include <rtl/ustrbuf.hxx>
39 : :
40 : :
41 : : namespace filter{
42 : : namespace config{
43 : :
44 : : namespace css = ::com::sun::star;
45 : :
46 : :
47 : : /** @short can be used to query for filters related to its application module.
48 : : */
49 : : #define BASE_QUERY_ALL "_query_all"
50 : : #define BASE_QUERY_WRITER "_query_Writer"
51 : : #define BASE_QUERY_WEB "_query_web"
52 : : #define BASE_QUERY_GLOBAL "_query_global"
53 : : #define BASE_QUERY_CHART "_query_chart"
54 : : #define BASE_QUERY_CALC "_query_calc"
55 : : #define BASE_QUERY_IMPRESS "_query_impress"
56 : : #define BASE_QUERY_DRAW "_query_draw"
57 : : #define BASE_QUERY_MATH "_query_math"
58 : :
59 : : //_______________________________________________
60 : :
61 : : /** @short define all possible parts of a filter query.
62 : :
63 : : @descr syntax: "<query>[:<param>[=<value>]]"
64 : : e.g.: "_query_writer:default_first:use_order:sort_prop=uiname"
65 : :
66 : : argument description default
67 : : -----------------------------------------------------------------------------------------------
68 : : iflags=<mask> include filters by given mask 0
69 : : eflags=<mask> exclude filters by given mask 0
70 : : sort_prop=<[name,uiname]> sort by internal name or uiname name
71 : : descending sort descending false
72 : : use_order use order flag of filters for sorting false
73 : : default_first set default filter on top of return list false
74 : : case_sensitive compare "sort_prop" case sensitive false
75 : : */
76 : : #define SEPERATOR_QUERYPARAM ((sal_Unicode)':')
77 : : #define SEPERATOR_QUERYPARAMVALUE ((sal_Unicode)'=')
78 : :
79 : : #define QUERYPARAM_IFLAGS ::rtl::OUString( "iflags" )
80 : : #define QUERYPARAM_EFLAGS ::rtl::OUString( "eflags" )
81 : : #define QUERYPARAM_SORT_PROP ::rtl::OUString( "sort_prop" )
82 : :
83 : : #define QUERYPARAM_DESCENDING ::rtl::OUString( "descending" )
84 : : #define QUERYPARAM_USE_ORDER ::rtl::OUString( "use_order" )
85 : : #define QUERYPARAM_DEFAULT_FIRST ::rtl::OUString( "default_first" )
86 : : #define QUERYPARAM_CASE_SENSITIVE ::rtl::OUString( "case_sensitive" )
87 : :
88 : : #define QUERYPARAMVALUE_SORT_PROP_NAME ::rtl::OUString( "name" )
89 : : #define QUERYPARAMVALUE_SORT_PROP_UINAME ::rtl::OUString( "uiname" )
90 : :
91 : :
92 : :
93 : 11432 : FilterFactory::FilterFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
94 : : {
95 : : BaseContainer::init(xSMGR ,
96 : : FilterFactory::impl_getImplementationName() ,
97 : : FilterFactory::impl_getSupportedServiceNames(),
98 [ + - ][ + - ]: 11432 : FilterCache::E_FILTER );
[ + - ][ + - ]
99 : 11432 : }
100 : :
101 : :
102 : :
103 : 11432 : FilterFactory::~FilterFactory()
104 : : {
105 [ - + ]: 22864 : }
106 : :
107 : :
108 : :
109 : 0 : css::uno::Reference< css::uno::XInterface > SAL_CALL FilterFactory::createInstance(const ::rtl::OUString& sFilter)
110 : : throw(css::uno::Exception ,
111 : : css::uno::RuntimeException)
112 : : {
113 [ # # ]: 0 : return createInstanceWithArguments(sFilter, css::uno::Sequence< css::uno::Any >());
114 : : }
115 : :
116 : :
117 : :
118 : 641 : css::uno::Reference< css::uno::XInterface > SAL_CALL FilterFactory::createInstanceWithArguments(const ::rtl::OUString& sFilter ,
119 : : const css::uno::Sequence< css::uno::Any >& lArguments)
120 : : throw(css::uno::Exception ,
121 : : css::uno::RuntimeException)
122 : : {
123 : : // SAFE ->
124 [ + - ]: 641 : ::osl::ResettableMutexGuard aLock(m_aLock);
125 : :
126 : 641 : ::rtl::OUString sRealFilter = sFilter;
127 : :
128 : : #ifdef _FILTER_CONFIG_MIGRATION_Q_
129 : :
130 : : /* -> TODO - HACK
131 : : check if the given filter name realy exist ...
132 : : Because our old implementation worked with an internal
133 : : type name instead of a filter name. For a small migration time
134 : : we must simulate this old feature :-( */
135 : :
136 [ + - ][ - + ]: 641 : if (!m_rCache->hasItem(FilterCache::E_FILTER, sFilter) && m_rCache->hasItem(FilterCache::E_TYPE, sFilter))
[ # # ][ # # ]
[ # # ][ - + ]
[ + - ]
137 : : {
138 : : OSL_FAIL("Who use this deprecated functionality?");
139 : : _FILTER_CONFIG_LOG_("FilterFactory::createInstanceWithArguments() ... simulate old type search functionality!\n");
140 : :
141 [ # # ]: 0 : css::uno::Sequence< css::beans::NamedValue > lQuery(1);
142 [ # # ]: 0 : lQuery[0].Name = PROPNAME_TYPE;
143 [ # # ][ # # ]: 0 : lQuery[0].Value <<= sFilter;
144 : :
145 [ # # ]: 0 : css::uno::Reference< css::container::XEnumeration > xSet = createSubSetEnumerationByProperties(lQuery);
146 [ # # ][ # # ]: 0 : while(xSet->hasMoreElements())
[ # # ]
147 : : {
148 [ # # ][ # # ]: 0 : ::comphelper::SequenceAsHashMap lHandlerProps(xSet->nextElement());
[ # # ]
149 [ # # ][ # # ]: 0 : if (!(lHandlerProps[PROPNAME_NAME] >>= sRealFilter))
150 : 0 : continue;
151 [ # # ][ # # ]: 0 : }
152 : :
153 : : // prevent outside code against NoSuchElementException!
154 : : // But dont implement such defensive strategy for our new create handling :-)
155 [ # # ][ # # ]: 0 : if (!m_rCache->hasItem(FilterCache::E_FILTER, sRealFilter))
[ # # ]
156 [ # # ][ # # ]: 0 : return css::uno::Reference< css::uno::XInterface>();
[ # # ]
157 : : }
158 : :
159 : : /* <- HACK */
160 : :
161 : : #endif // _FILTER_CONFIG_MIGRATION_Q_
162 : :
163 : : // search filter on cache
164 [ + - ][ + - ]: 641 : CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sRealFilter);
165 : 641 : ::rtl::OUString sFilterService;
166 [ + - ]: 641 : aFilter[PROPNAME_FILTERSERVICE] >>= sFilterService;
167 : :
168 : : // create service instance
169 : 641 : css::uno::Reference< css::uno::XInterface > xFilter;
170 [ + - ]: 641 : if (!sFilterService.isEmpty())
171 [ + - ][ + - ]: 641 : xFilter = m_xSMGR->createInstance(sFilterService);
[ + - ]
172 : :
173 : : // initialize filter
174 [ + - ]: 641 : css::uno::Reference< css::lang::XInitialization > xInit(xFilter, css::uno::UNO_QUERY);
175 [ + - ]: 641 : if (xInit.is())
176 : : {
177 : : // format: lInitData[0] = seq<PropertyValue>, which contains all configuration properties of this filter
178 : : // lInitData[1] = lArguments[0]
179 : : // ...
180 : : // lInitData[n] = lArguments[n-1]
181 [ + - ]: 641 : css::uno::Sequence< css::beans::PropertyValue > lConfig;
182 [ + - ]: 641 : aFilter >> lConfig;
183 : :
184 [ + - ]: 641 : ::comphelper::SequenceAsVector< css::uno::Any > stlArguments(lArguments);
185 [ + - ][ + - ]: 641 : stlArguments.insert(stlArguments.begin(), css::uno::makeAny(lConfig));
186 : :
187 [ + - ]: 641 : css::uno::Sequence< css::uno::Any > lInitData;
188 [ + - ]: 641 : stlArguments >> lInitData;
189 : :
190 [ + - ][ + - ]: 641 : xInit->initialize(lInitData);
[ + - ][ + - ]
191 : : }
192 : :
193 [ + - ][ + - ]: 641 : return xFilter;
194 : : // <- SAFE
195 : : }
196 : :
197 : :
198 : :
199 : 0 : css::uno::Sequence< ::rtl::OUString > SAL_CALL FilterFactory::getAvailableServiceNames()
200 : : throw(css::uno::RuntimeException)
201 : : {
202 : : /* Attention: Instead of getElementNames() this method have to return only filter names,
203 : : which can be created as UNO Services realy. Thats why we search for filters,
204 : : which dont have a valid value for the property "FilterService".
205 : : Of course we cant check for corrupted service names here. We can check
206 : : for empty strings only ...
207 : : */
208 [ # # ]: 0 : CacheItem lIProps;
209 [ # # ]: 0 : CacheItem lEProps;
210 [ # # ][ # # ]: 0 : lEProps[PROPNAME_FILTERSERVICE] <<= ::rtl::OUString();
211 : :
212 [ # # ]: 0 : OUStringList lUNOFilters;
213 : : try
214 : : {
215 [ # # ][ # # ]: 0 : lUNOFilters = m_rCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps, lEProps);
[ # # ]
216 : : }
217 [ # # # ]: 0 : catch(const css::uno::RuntimeException&)
218 : 0 : { throw; }
219 [ # # ]: 0 : catch(const css::uno::Exception&)
220 : 0 : { lUNOFilters.clear(); }
221 : :
222 [ # # ][ # # ]: 0 : return lUNOFilters.getAsConstList();
[ # # ]
223 : : }
224 : :
225 : :
226 : :
227 : 0 : css::uno::Reference< css::container::XEnumeration > SAL_CALL FilterFactory::createSubSetEnumerationByQuery(const ::rtl::OUString& sQuery)
228 : : throw (css::uno::RuntimeException)
229 : : {
230 : : // reject old deprecated queries ...
231 [ # # ]: 0 : if (sQuery.matchAsciiL("_filterquery_",13,0))
232 : : throw css::uno::RuntimeException(
233 : : _FILTER_CONFIG_FROM_ASCII_("Use of deprecated and now unsupported query!"),
234 [ # # ][ # # ]: 0 : static_cast< css::container::XContainerQuery* >(this));
[ # # ]
235 : :
236 : : // convert "_query_xxx:..." to "getByDocService=xxx:..."
237 : 0 : ::rtl::OUString sNewQuery(sQuery);
238 : 0 : sal_Int32 pos = sNewQuery.indexOf("_query_");
239 [ # # ]: 0 : if (pos != -1)
240 : : {
241 : : OSL_FAIL("DEPRECATED!\nPlease use new query format: 'matchByDocumentService=...'");
242 : 0 : ::rtl::OUStringBuffer sPatchedQuery(256);
243 [ # # ]: 0 : sPatchedQuery.appendAscii("matchByDocumentService=");
244 [ # # ]: 0 : sPatchedQuery.append (sNewQuery.copy(7) );
245 [ # # ]: 0 : sNewQuery = sPatchedQuery.makeStringAndClear();
246 : : }
247 : :
248 : : // analyze query and split it into its tokens
249 [ # # ]: 0 : QueryTokenizer lTokens(sNewQuery);
250 : 0 : QueryTokenizer::const_iterator pIt;
251 [ # # ]: 0 : OUStringList lEnumSet;
252 : :
253 : : // start query
254 : : // (see attention comment below!)
255 [ # # ][ # # ]: 0 : if (lTokens.valid())
256 : : {
257 : : // SAFE -> ----------------------
258 [ # # ]: 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
259 : : // May be not all filters was loaded ...
260 : : // But we need it now!
261 [ # # ]: 0 : impl_loadOnDemand();
262 [ # # ]: 0 : aLock.clear();
263 : : // <- SAFE ----------------------
264 : :
265 [ # # ][ # # ]: 0 : if (lTokens.find(QUERY_IDENTIFIER_GETPREFERREDFILTERFORTYPE) != lTokens.end())
[ # # ][ # # ]
266 : : OSL_FAIL("DEPRECATED!\nPlease use prop search at the TypeDetection container!");
267 : : else
268 [ # # ][ # # ]: 0 : if (lTokens.find(QUERY_IDENTIFIER_MATCHBYDOCUMENTSERVICE) != lTokens.end())
[ # # ][ # # ]
269 [ # # ][ # # ]: 0 : lEnumSet = impl_queryMatchByDocumentService(lTokens);
270 : : else
271 [ # # ][ # # ]: 0 : if (lTokens.find(QUERY_IDENTIFIER_GET_SORTED_FILTERLIST) != lTokens.end())
[ # # ][ # # ]
272 [ # # ][ # # ]: 0 : lEnumSet = impl_getSortedFilterList(lTokens);
[ # # ]
273 : : }
274 : :
275 : : // pack list of item names as an enum list
276 : : // Attention: Do not return empty reference for empty list!
277 : : // The outside check "hasMoreElements()" should be enough, to detect this state :-)
278 [ # # ]: 0 : css::uno::Sequence< ::rtl::OUString > lSet = lEnumSet.getAsConstList();
279 [ # # ][ # # ]: 0 : ::comphelper::OEnumerationByName* pEnum = new ::comphelper::OEnumerationByName(this, lSet);
280 [ # # ][ # # ]: 0 : return css::uno::Reference< css::container::XEnumeration >(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY);
[ # # ][ # # ]
281 : : }
282 : :
283 : :
284 : :
285 : 0 : OUStringList FilterFactory::impl_queryMatchByDocumentService(const QueryTokenizer& lTokens) const
286 : : {
287 : : // analyze query
288 : 0 : QueryTokenizer::const_iterator pIt;
289 : :
290 : 0 : ::rtl::OUString sDocumentService;
291 : 0 : sal_Int32 nIFlags = 0;
292 : 0 : sal_Int32 nEFlags = 0;
293 : :
294 [ # # ][ # # ]: 0 : pIt = lTokens.find(QUERY_IDENTIFIER_MATCHBYDOCUMENTSERVICE);
295 [ # # ]: 0 : if (pIt != lTokens.end())
296 [ # # ]: 0 : sDocumentService = pIt->second;
297 : :
298 : : #define COMP_HACK
299 : : #ifdef COMP_HACK
300 [ # # ]: 0 : if ( sDocumentService == "writer" )
301 : : {
302 : : OSL_FAIL("DEPRECATED!\nPlease use right document service for filter query!");
303 : 0 : sDocumentService = ::rtl::OUString( "com.sun.star.text.TextDocument" );
304 : : }
305 : : else
306 [ # # ]: 0 : if ( sDocumentService == "web" )
307 : : {
308 : : OSL_FAIL("DEPRECATED!\nPlease use right document service for filter query!");
309 : 0 : sDocumentService = ::rtl::OUString( "com.sun.star.text.WebDocument" );
310 : : }
311 : : else
312 [ # # ]: 0 : if ( sDocumentService == "global" )
313 : : {
314 : : OSL_FAIL("DEPRECATED!\nPlease use right document service for filter query!");
315 : 0 : sDocumentService = ::rtl::OUString( "com.sun.star.text.GlobalDocument" );
316 : : }
317 : : else
318 [ # # ]: 0 : if ( sDocumentService == "calc" )
319 : : {
320 : : OSL_FAIL("DEPRECATED!\nPlease use right document service for filter query!");
321 : 0 : sDocumentService = ::rtl::OUString( "com.sun.star.sheet.SpreadsheetDocument" );
322 : : }
323 : : else
324 [ # # ]: 0 : if ( sDocumentService == "draw" )
325 : : {
326 : : OSL_FAIL("DEPRECATED!\nPlease use right document service for filter query!");
327 : 0 : sDocumentService = ::rtl::OUString( "com.sun.star.drawing.DrawingDocument" );
328 : : }
329 : : else
330 [ # # ]: 0 : if ( sDocumentService == "impress" )
331 : : {
332 : : OSL_FAIL("DEPRECATED!\nPlease use right document service for filter query!");
333 : 0 : sDocumentService = ::rtl::OUString( "com.sun.star.presentation.PresentationDocument" );
334 : : }
335 : : else
336 [ # # ]: 0 : if ( sDocumentService == "math" )
337 : : {
338 : : OSL_FAIL("DEPRECATED!\nPlease use right document service for filter query!");
339 : 0 : sDocumentService = ::rtl::OUString( "com.sun.star.formula.FormulaProperties" );
340 : : }
341 : : #endif
342 : :
343 [ # # ][ # # ]: 0 : pIt = lTokens.find(QUERY_PARAM_IFLAGS);
344 [ # # ]: 0 : if (pIt != lTokens.end())
345 [ # # ]: 0 : nIFlags = ::rtl::OUString(pIt->second).toInt32();
346 : :
347 [ # # ][ # # ]: 0 : pIt = lTokens.find(QUERY_PARAM_EFLAGS);
348 [ # # ]: 0 : if (pIt != lTokens.end())
349 [ # # ]: 0 : nEFlags = ::rtl::OUString(pIt->second).toInt32();
350 : :
351 : : // SAFE -> ----------------------
352 [ # # ]: 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
353 : :
354 : : // search suitable filters
355 [ # # ]: 0 : FilterCache* pCache = impl_getWorkingCache();
356 [ # # ]: 0 : OUStringList lFilterNames = pCache->getItemNames(FilterCache::E_FILTER);
357 [ # # ]: 0 : OUStringList lResult ;
358 : :
359 [ # # ][ # # ]: 0 : for (OUStringList::const_iterator pName = lFilterNames.begin();
[ # # ]
360 : 0 : pName != lFilterNames.end() ;
361 : : ++pName )
362 : : {
363 : : try
364 : : {
365 : 0 : const ::rtl::OUString& sName = *pName;
366 [ # # ]: 0 : const CacheItem aFilter = pCache->getItem(FilterCache::E_FILTER, sName);
367 : 0 : CacheItem::const_iterator pProp ;
368 : :
369 : : // "matchByDocumentService=" => any filter will be addressed here
370 : : // "matchByDocumentService=all" => any filter will be addressed here
371 : : // "matchByDocumentService=com.sun.star..." => only filter matching this document service will be addressed
372 [ # # ]: 0 : ::rtl::OUString sCheckValue = aFilter.getUnpackedValueOrDefault(PROPNAME_DOCUMENTSERVICE, ::rtl::OUString());
373 [ # # ][ # # : 0 : if (
# # # # ]
374 : 0 : (!sDocumentService.isEmpty() ) &&
375 [ # # ][ # # ]: 0 : (!sDocumentService.equals(QUERY_CONSTVALUE_ALL)) &&
[ # # ]
376 : 0 : (!sCheckValue.equals(sDocumentService) )
377 : : )
378 : : {
379 : 0 : continue; // ignore filter -> try next one!
380 : : }
381 : :
382 : : // "iflags=" => not allowed
383 : : // "iflags=-1" => not allowed
384 : : // "iflags=0" => not usefull
385 : : // "iflags=283648" => only filter, which has set these flag field will be addressed
386 [ # # ]: 0 : sal_Int32 nCheckValue = aFilter.getUnpackedValueOrDefault(PROPNAME_FLAGS, (sal_Int32)0);
387 [ # # ][ # # ]: 0 : if (
388 : : (nIFlags > 0 ) &&
389 : : ((nCheckValue & nIFlags) != nIFlags)
390 : : )
391 : : {
392 : 0 : continue; // ignore filter -> try next one!
393 : : }
394 : :
395 : : // "eflags=" => not allowed
396 : : // "eflags=-1" => not allowed
397 : : // "eflags=0" => not usefull
398 : : // "eflags=283648" => only filter, which has not set these flag field will be addressed
399 [ # # ][ # # ]: 0 : if (
400 : : (nEFlags > 0 ) &&
401 : : ((nCheckValue & nEFlags) == nEFlags)
402 : : )
403 : : {
404 : 0 : continue; // ignore filter -> try next one!
405 : : }
406 : :
407 : : // OK - this filter passed all checks.
408 : : // It match the query ...
409 [ # # ][ # # ]: 0 : lResult.push_back(sName);
[ # # ][ # # ]
410 : : }
411 [ # # # ]: 0 : catch(const css::uno::RuntimeException&)
412 : 0 : { throw; }
413 [ # # ]: 0 : catch(const css::uno::Exception&)
414 : 0 : { continue; }
415 : : }
416 : :
417 [ # # ]: 0 : aLock.clear();
418 : : // <- SAFE ----------------------
419 : :
420 [ # # ]: 0 : return lResult;
421 : : }
422 : :
423 : :
424 : :
425 : : class stlcomp_removeIfMatchFlags
426 : : {
427 : : private:
428 : : FilterCache* m_pCache ;
429 : : sal_Int32 m_nFlags ;
430 : : sal_Bool m_bIFlags;
431 : :
432 : : public:
433 : 0 : stlcomp_removeIfMatchFlags(FilterCache* pCache ,
434 : : sal_Int32 nFlags ,
435 : : sal_Bool bIFlags)
436 : : : m_pCache (pCache )
437 : : , m_nFlags (nFlags )
438 : 0 : , m_bIFlags(bIFlags)
439 : 0 : {}
440 : :
441 : 0 : bool operator() (const ::rtl::OUString& sFilter) const
442 : : {
443 : : try
444 : : {
445 [ # # ]: 0 : const CacheItem aFilter = m_pCache->getItem(FilterCache::E_FILTER, sFilter);
446 [ # # ]: 0 : sal_Int32 nFlags = aFilter.getUnpackedValueOrDefault(PROPNAME_FLAGS, ((sal_Int32)0));
447 : :
448 : 0 : bool bMatch = false;
449 [ # # ]: 0 : if (m_bIFlags)
450 : : // IFlags are interpeted as ALL_FLAGS_MUST_MATCH !
451 : 0 : bMatch = ((nFlags & m_nFlags) == m_nFlags);
452 : : else
453 : : // EFlags are interpreted as ATE_LEAST_ONE_FLAG_MUST_MATCH !
454 : 0 : bMatch = !(nFlags & m_nFlags);
455 : : // We are asked for bRemove ! And bMatch = !bRemove => so bRemove = !bMatch .-)
456 [ # # ][ # # ]: 0 : return !bMatch;
457 : : }
458 : 0 : catch(const css::container::NoSuchElementException &)
459 : : {
460 : 0 : return true;
461 : : }
462 : : }
463 : : };
464 : :
465 : :
466 : :
467 : 0 : OUStringList FilterFactory::impl_getSortedFilterList(const QueryTokenizer& lTokens) const
468 : : {
469 : : // analyze the given query parameter
470 : 0 : QueryTokenizer::const_iterator pIt1;
471 : :
472 : 0 : ::rtl::OUString sModule;
473 : 0 : sal_Int32 nIFlags = -1;
474 : 0 : sal_Int32 nEFlags = -1;
475 : :
476 [ # # ][ # # ]: 0 : pIt1 = lTokens.find(QUERY_PARAM_MODULE);
477 [ # # ]: 0 : if (pIt1 != lTokens.end())
478 [ # # ]: 0 : sModule = pIt1->second;
479 [ # # ][ # # ]: 0 : pIt1 = lTokens.find(QUERY_PARAM_IFLAGS);
480 [ # # ]: 0 : if (pIt1 != lTokens.end())
481 [ # # ]: 0 : nIFlags = ::rtl::OUString(pIt1->second).toInt32();
482 [ # # ][ # # ]: 0 : pIt1 = lTokens.find(QUERY_PARAM_EFLAGS);
483 [ # # ]: 0 : if (pIt1 != lTokens.end())
484 [ # # ]: 0 : nEFlags = ::rtl::OUString(pIt1->second).toInt32();
485 : :
486 : : // simple search for filters of one specific module.
487 [ # # ]: 0 : OUStringList lFilterList;
488 [ # # ]: 0 : if (!sModule.isEmpty())
489 [ # # ][ # # ]: 0 : lFilterList = impl_getSortedFilterListForModule(sModule, nIFlags, nEFlags);
490 : : else
491 : : {
492 : : // more complex search for all filters
493 : : // We check first, which office modules are installed ...
494 [ # # ]: 0 : OUStringList lModules = impl_getListOfInstalledModules();
495 : 0 : OUStringList::const_iterator pIt2;
496 [ # # ][ # # ]: 0 : for ( pIt2 = lModules.begin();
[ # # ]
497 : 0 : pIt2 != lModules.end() ;
498 : : ++pIt2 )
499 : : {
500 : 0 : sModule = *pIt2;
501 [ # # ]: 0 : OUStringList lFilters4Module = impl_getSortedFilterListForModule(sModule, nIFlags, nEFlags);
502 : 0 : OUStringList::const_iterator pIt3;
503 [ # # ][ # # ]: 0 : for ( pIt3 = lFilters4Module.begin();
[ # # ]
504 : 0 : pIt3 != lFilters4Module.end() ;
505 : : ++pIt3 )
506 : : {
507 : 0 : const ::rtl::OUString& sFilter = *pIt3;
508 [ # # ]: 0 : lFilterList.push_back(sFilter);
509 : : }
510 : 0 : }
511 : : }
512 : :
513 : 0 : return lFilterList;
514 : : }
515 : :
516 : :
517 : :
518 : 0 : OUStringList FilterFactory::impl_getListOfInstalledModules() const
519 : : {
520 : : // SAFE -> ----------------------
521 [ # # ]: 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
522 : 0 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
523 [ # # ]: 0 : aLock.clear();
524 : : // <- SAFE ----------------------
525 : :
526 : : try
527 : : {
528 : : css::uno::Reference< css::container::XNameAccess > xModuleConfig(
529 : : ::comphelper::ConfigurationHelper::openConfig(xSMGR,
530 : : CFGPACKAGE_OOO_MODULES,
531 : : ::comphelper::ConfigurationHelper::E_READONLY),
532 [ # # ][ # # ]: 0 : css::uno::UNO_QUERY_THROW);
[ # # ]
533 [ # # ][ # # ]: 0 : OUStringList lModules(xModuleConfig->getElementNames());
[ # # ][ # # ]
534 [ # # ]: 0 : return lModules;
535 : : }
536 [ # # # ]: 0 : catch(const css::uno::RuntimeException&)
537 : 0 : { throw; }
538 [ # # ]: 0 : catch(const css::uno::Exception&)
539 : : {}
540 : :
541 [ # # ][ # # ]: 0 : return OUStringList();
542 : : }
543 : :
544 : :
545 : :
546 : 0 : OUStringList FilterFactory::impl_getSortedFilterListForModule(const ::rtl::OUString& sModule,
547 : : sal_Int32 nIFlags,
548 : : sal_Int32 nEFlags) const
549 : : {
550 [ # # ]: 0 : OUStringList lSortedFilters = impl_readSortedFilterListFromConfig(sModule);
551 : :
552 : : // get all filters for the requested module
553 [ # # ]: 0 : CacheItem lIProps;
554 [ # # ][ # # ]: 0 : lIProps[PROPNAME_DOCUMENTSERVICE] <<= sModule;
555 : :
556 : : // SAFE -> ----------------------
557 [ # # ]: 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
558 [ # # ]: 0 : FilterCache* pCache = impl_getWorkingCache();
559 [ # # ][ # # ]: 0 : OUStringList lOtherFilters = pCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps);
[ # # ]
560 [ # # ]: 0 : aLock.clear();
561 : : // <- SAFE ----------------------
562 : :
563 : : // bring "other" filters in an alphabeticly order
564 : : // It's needed below.
565 [ # # ]: 0 : ::std::sort(lOtherFilters.begin(), lOtherFilters.end());
566 : :
567 : : // merge both lists together
568 [ # # ]: 0 : OUStringList lMergedFilters = lSortedFilters;
569 : 0 : OUStringList::iterator pIt2;
570 : 0 : OUStringList::iterator pIt3;
571 [ # # ][ # # ]: 0 : for ( pIt2 = lOtherFilters.begin();
572 : 0 : pIt2 != lOtherFilters.end() ;
573 : : ++pIt2 )
574 : : {
575 : 0 : const ::rtl::OUString& rFilter = *pIt2;
576 [ # # ]: 0 : pIt3 = ::std::find(lSortedFilters.begin(), lSortedFilters.end(), rFilter);
577 [ # # ][ # # ]: 0 : if (pIt3 == lSortedFilters.end())
578 [ # # ]: 0 : lMergedFilters.push_back(rFilter);
579 : : }
580 : :
581 : : // remove all filters from this merged list, which does not fit the flag specification
582 [ # # ]: 0 : if (nIFlags != -1)
583 : : {
584 [ # # ]: 0 : pIt2 = ::std::remove_if(lMergedFilters.begin(), lMergedFilters.end(), stlcomp_removeIfMatchFlags(pCache, nIFlags, sal_True));
585 [ # # ]: 0 : lMergedFilters.erase(pIt2, lMergedFilters.end());
586 : : }
587 [ # # ]: 0 : if (nEFlags != -1)
588 : : {
589 [ # # ]: 0 : pIt2 = ::std::remove_if(lMergedFilters.begin(), lMergedFilters.end(), stlcomp_removeIfMatchFlags(pCache, nEFlags, sal_False));
590 [ # # ]: 0 : lMergedFilters.erase(pIt2, lMergedFilters.end());
591 : : }
592 : :
593 : : // sort the default filter to the front of this list
594 : : // TODO
595 : :
596 [ # # ][ # # ]: 0 : return lMergedFilters;
597 : : }
598 : :
599 : :
600 : :
601 : 0 : OUStringList FilterFactory::impl_readSortedFilterListFromConfig(const ::rtl::OUString& sModule) const
602 : : {
603 : : // SAFE -> ----------------------
604 [ # # ]: 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
605 : 0 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
606 [ # # ]: 0 : aLock.clear();
607 : : // <- SAFE ----------------------
608 : :
609 : : try
610 : : {
611 : : css::uno::Reference< css::container::XNameAccess > xUISortConfig(
612 : : ::comphelper::ConfigurationHelper::openConfig(xSMGR,
613 : : CFGPACKAGE_TD_UISORT,
614 : : ::comphelper::ConfigurationHelper::E_READONLY),
615 [ # # ][ # # ]: 0 : css::uno::UNO_QUERY_THROW);
[ # # ]
616 : :
617 : : // dont ccheck the module name here. If it does not exists, an exception is thrown and catched below.
618 : : // We return an empty list as result then.
619 : 0 : css::uno::Reference< css::container::XNameAccess > xModule;
620 [ # # ][ # # ]: 0 : xUISortConfig->getByName(sModule) >>= xModule;
[ # # ]
621 [ # # ]: 0 : if (xModule.is()) // only to be on the safe side of life if the exception was not thrown .-)
622 : : {
623 : : // Note: convertion of the returned Any to OUStringList throws
624 : : // an IllegalArgumentException if the type does not match ...
625 : : // but it resets the OUStringList to a length of 0 if the Any is empty!
626 [ # # ][ # # ]: 0 : OUStringList lSortedFilters(xModule->getByName(PROPNAME_SORTEDFILTERLIST));
[ # # ][ # # ]
627 [ # # ]: 0 : return lSortedFilters;
628 [ # # ][ # # ]: 0 : }
629 : : }
630 [ # # # ]: 0 : catch(const css::uno::RuntimeException&)
631 : 0 : { throw; }
632 [ # # ]: 0 : catch(const css::uno::Exception&)
633 : : {}
634 : :
635 [ # # ][ # # ]: 0 : return OUStringList();
636 : : }
637 : :
638 : :
639 : :
640 : 12071 : ::rtl::OUString FilterFactory::impl_getImplementationName()
641 : : {
642 : 12071 : return ::rtl::OUString( "com.sun.star.comp.filter.config.FilterFactory" );
643 : : }
644 : :
645 : :
646 : :
647 : 11559 : css::uno::Sequence< ::rtl::OUString > FilterFactory::impl_getSupportedServiceNames()
648 : : {
649 : 11559 : css::uno::Sequence< ::rtl::OUString > lServiceNames(1);
650 [ + - ]: 11559 : lServiceNames[0] = ::rtl::OUString( "com.sun.star.document.FilterFactory" );
651 : 11559 : return lServiceNames;
652 : : }
653 : :
654 : :
655 : :
656 : 11432 : css::uno::Reference< css::uno::XInterface > SAL_CALL FilterFactory::impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
657 : : {
658 [ + - ]: 11432 : FilterFactory* pNew = new FilterFactory(xSMGR);
659 [ + - ]: 11432 : return css::uno::Reference< css::uno::XInterface >(static_cast< css::lang::XMultiServiceFactory* >(pNew), css::uno::UNO_QUERY);
660 : : }
661 : :
662 : : } // namespace config
663 : : } // namespace filter
664 : :
665 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|