Line data Source code
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 :
21 : #include "filtercache.hxx"
22 : #include "lateinitlistener.hxx"
23 : #include "macros.hxx"
24 : #include "constant.hxx"
25 : #include "cacheupdatelistener.hxx"
26 :
27 : /*TODO see using below ... */
28 : #define AS_ENABLE_FILTER_UINAMES
29 : #define WORKAROUND_EXCEPTION_PROBLEM
30 :
31 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
32 : #include <com/sun/star/util/XChangesBatch.hpp>
33 : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
34 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35 : #include <com/sun/star/beans/NamedValue.hpp>
36 : #include <com/sun/star/beans/XPropertySet.hpp>
37 : #include <com/sun/star/beans/XProperty.hpp>
38 : #include <com/sun/star/beans/PropertyValue.hpp>
39 : #include <com/sun/star/beans/Property.hpp>
40 : #include <com/sun/star/beans/PropertyAttribute.hpp>
41 : #include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
42 : #include <comphelper/sequenceasvector.hxx>
43 : #include <comphelper/processfactory.hxx>
44 :
45 : #include <unotools/configpaths.hxx>
46 : #include <rtl/ustrbuf.hxx>
47 : #include <rtl/uri.hxx>
48 : #include <tools/urlobj.hxx>
49 : #include <tools/wldcrd.hxx>
50 : #include <i18nlangtag/languagetag.hxx>
51 :
52 : #include <officecfg/Setup.hxx>
53 :
54 :
55 : namespace filter{
56 : namespace config{
57 :
58 76 : FilterCache::FilterCache()
59 : : BaseLock ( )
60 76 : , m_eFillState(E_CONTAINS_NOTHING )
61 : {
62 : SAL_INFO( "filter.config", "{ (as96863) FilterCache lifetime");
63 76 : }
64 :
65 :
66 :
67 228 : FilterCache::~FilterCache()
68 : {
69 : SAL_INFO( "filter.config", "} (as96863) FilterCache lifetime");
70 76 : if (m_xTypesChglisteners.is())
71 75 : m_xTypesChglisteners->stopListening();
72 76 : if (m_xFiltersChgListener.is())
73 74 : m_xFiltersChgListener->stopListening();
74 152 : }
75 :
76 :
77 :
78 1 : FilterCache* FilterCache::clone() const
79 : {
80 : // SAFE -> ----------------------------------
81 1 : ::osl::ResettableMutexGuard aLock(m_aLock);
82 :
83 1 : FilterCache* pClone = new FilterCache();
84 :
85 : // Dont copy the configuration access points here.
86 : // They will be created on demand inside the cloned instance,
87 : // if they are needed.
88 :
89 1 : pClone->m_lTypes = m_lTypes;
90 1 : pClone->m_lDetectServices = m_lDetectServices;
91 1 : pClone->m_lFilters = m_lFilters;
92 1 : pClone->m_lFrameLoaders = m_lFrameLoaders;
93 1 : pClone->m_lContentHandlers = m_lContentHandlers;
94 1 : pClone->m_lExtensions2Types = m_lExtensions2Types;
95 1 : pClone->m_lURLPattern2Types = m_lURLPattern2Types;
96 :
97 1 : pClone->m_sActLocale = m_sActLocale;
98 :
99 1 : pClone->m_eFillState = m_eFillState;
100 :
101 1 : pClone->m_lChangedTypes = m_lChangedTypes;
102 1 : pClone->m_lChangedFilters = m_lChangedFilters;
103 1 : pClone->m_lChangedDetectServices = m_lChangedDetectServices;
104 1 : pClone->m_lChangedFrameLoaders = m_lChangedFrameLoaders;
105 1 : pClone->m_lChangedContentHandlers = m_lChangedContentHandlers;
106 :
107 1 : return pClone;
108 : // <- SAFE ----------------------------------
109 : }
110 :
111 :
112 :
113 1 : void FilterCache::takeOver(const FilterCache& rClone)
114 : {
115 : // SAFE -> ----------------------------------
116 1 : ::osl::ResettableMutexGuard aLock(m_aLock);
117 :
118 : // a)
119 : // Dont copy the configuration access points here!
120 : // We must use our own ones ...
121 :
122 : // b)
123 : // Further we can ignore the uno service manager.
124 : // We should already have a valid instance.
125 :
126 : // c)
127 : // Take over only changed items!
128 : // Otherwise we risk the following scenario:
129 : // c1) clone_1 contains changed filters
130 : // c2) clone_2 container changed types
131 : // c3) clone_1 take over changed filters and unchanged types
132 : // c4) clone_2 take over unchanged filters(!) and changed types(!)
133 : // c5) c4 overwrites c3!
134 :
135 1 : if (rClone.m_lChangedTypes.size()>0)
136 0 : m_lTypes = rClone.m_lTypes;
137 1 : if (rClone.m_lChangedDetectServices.size()>0)
138 0 : m_lDetectServices = rClone.m_lDetectServices;
139 1 : if (rClone.m_lChangedFilters.size()>0)
140 1 : m_lFilters = rClone.m_lFilters;
141 1 : if (rClone.m_lChangedFrameLoaders.size()>0)
142 0 : m_lFrameLoaders = rClone.m_lFrameLoaders;
143 1 : if (rClone.m_lChangedContentHandlers.size()>0)
144 0 : m_lContentHandlers = rClone.m_lContentHandlers;
145 :
146 1 : m_lChangedTypes.clear();
147 1 : m_lChangedDetectServices.clear();
148 1 : m_lChangedFilters.clear();
149 1 : m_lChangedFrameLoaders.clear();
150 1 : m_lChangedContentHandlers.clear();
151 :
152 1 : m_sActLocale = rClone.m_sActLocale;
153 :
154 1 : m_eFillState = rClone.m_eFillState;
155 :
156 : // renew all dependencies and optimizations
157 : // Because we cant be shure, that changed filters on one clone
158 : // and changed types of another clone work together.
159 : // But here we can check against the lates changes ...
160 1 : impl_validateAndOptimize();
161 : // <- SAFE ----------------------------------
162 1 : }
163 :
164 :
165 :
166 131709 : void FilterCache::load(EFillState eRequired,
167 : #if OSL_DEBUG_LEVEL > 1
168 : sal_Bool bByThread
169 : #else
170 : sal_Bool
171 : #endif
172 : )
173 : throw(css::uno::Exception)
174 : {
175 : // SAFE -> ----------------------------------
176 131709 : ::osl::ResettableMutexGuard aLock(m_aLock);
177 :
178 : // check if required fill state is already reached ...
179 : // There is nothing to do then.
180 131709 : if ((m_eFillState & eRequired) == eRequired)
181 263083 : return;
182 :
183 : #if OSL_DEBUG_LEVEL > 1
184 : if (!bByThread && ((eRequired & E_CONTAINS_ALL) == E_CONTAINS_ALL))
185 : {
186 : SAL_WARN( "filter.config", "Who disturb our \"fill cache on demand\" feature and force loading of ALL data during office startup? Please optimize your code, so a full filled filter cache is not really needed here!");
187 : }
188 : #endif
189 :
190 : // Otherwise load the missing items.
191 :
192 :
193 : // a) load some const values from configration.
194 : // These values are needed there for loading
195 : // config items ...
196 : // Further we load some std items from the
197 : // configuration so we can try to load the first
198 : // office document with a minimal set of values.
199 335 : if (m_eFillState == E_CONTAINS_NOTHING)
200 : {
201 75 : impl_getDirectCFGValue(CFGDIRECTKEY_OFFICELOCALE) >>= m_sActLocale;
202 75 : if (m_sActLocale.isEmpty())
203 : {
204 : _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify office locale => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_OFFICELOCALE));
205 11 : m_sActLocale = DEFAULT_OFFICELOCALE;
206 : }
207 :
208 : // Support the old configuration support. Read it only one times during office runtime!
209 75 : impl_readOldFormat();
210 :
211 : // enable "loadOnDemand" feature ...
212 : // Create uno listener, which waits for finishing the office startup
213 : // and starts a thread, which calls loadAll() at this filter cache.
214 : // Note: Its not a leak to create this listener with new here.
215 : // It kills itself after working!
216 75 : /* LateInitListener* pLateInit = */ new LateInitListener(comphelper::getProcessComponentContext());
217 : }
218 :
219 :
220 : // b) If the required fill state was not reached
221 : // but std values was already loaded ...
222 : // we must load some further missing items.
223 335 : impl_load(eRequired);
224 : // <- SAFE
225 : }
226 :
227 :
228 :
229 13418 : sal_Bool FilterCache::isFillState(FilterCache::EFillState eState) const
230 : throw(css::uno::Exception)
231 : {
232 : // SAFE ->
233 13418 : ::osl::ResettableMutexGuard aLock(m_aLock);
234 13418 : return ((m_eFillState & eState) == eState);
235 : // <- SAFE
236 : }
237 :
238 :
239 :
240 37160 : OUStringList FilterCache::getMatchingItemsByProps( EItemType eType ,
241 : const CacheItem& lIProps,
242 : const CacheItem& lEProps) const
243 : throw(css::uno::Exception)
244 : {
245 : // SAFE ->
246 37160 : ::osl::ResettableMutexGuard aLock(m_aLock);
247 :
248 : // search for right list
249 : // An exception is thrown - "eType" is unknown.
250 : // => rList will be valid everytimes next line is reached.
251 37160 : const CacheItemList& rList = impl_getItemList(eType);
252 :
253 37160 : OUStringList lKeys;
254 :
255 : // search items, which provides all needed properties of set "lIProps"
256 : // but not of set "lEProps"!
257 4640700 : for (CacheItemList::const_iterator pIt = rList.begin();
258 3093800 : pIt != rList.end() ;
259 : ++pIt )
260 : {
261 : _FILTER_CONFIG_LOG_1_("getMatchingProps for \"%s\" ...\n",
262 : _FILTER_CONFIG_TO_ASCII_(pIt->first))
263 1509740 : if (
264 1603948 : (pIt->second.haveProps(lIProps) ) &&
265 94208 : (pIt->second.dontHaveProps(lEProps))
266 : )
267 : {
268 94208 : lKeys.push_back(pIt->first);
269 : }
270 : }
271 :
272 37160 : return lKeys;
273 : // <- SAFE
274 : }
275 :
276 :
277 :
278 3 : sal_Bool FilterCache::hasItems(EItemType eType) const
279 : throw(css::uno::Exception)
280 : {
281 : // SAFE ->
282 3 : ::osl::ResettableMutexGuard aLock(m_aLock);
283 :
284 : // search for right list
285 : // An exception is thrown - "eType" is unknown.
286 : // => rList will be valid everytimes next line is reached.
287 3 : const CacheItemList& rList = impl_getItemList(eType);
288 :
289 3 : return !rList.empty();
290 : // <- SAFE
291 : }
292 :
293 :
294 :
295 2438 : OUStringList FilterCache::getItemNames(EItemType eType) const
296 : throw(css::uno::Exception)
297 : {
298 : // SAFE ->
299 2438 : ::osl::ResettableMutexGuard aLock(m_aLock);
300 :
301 : // search for right list
302 : // An exception is thrown - "eType" is unknown.
303 : // => rList will be valid everytimes next line is reached.
304 2438 : const CacheItemList& rList = impl_getItemList(eType);
305 :
306 2438 : OUStringList lKeys;
307 1610760 : for (CacheItemList::const_iterator pIt = rList.begin();
308 1073840 : pIt != rList.end() ;
309 : ++pIt )
310 : {
311 534482 : lKeys.push_back(pIt->first);
312 : }
313 2438 : return lKeys;
314 : // <- SAFE
315 : }
316 :
317 :
318 :
319 31515 : sal_Bool FilterCache::hasItem( EItemType eType,
320 : const OUString& sItem)
321 : throw(css::uno::Exception)
322 : {
323 : // SAFE ->
324 31515 : ::osl::ResettableMutexGuard aLock(m_aLock);
325 :
326 : // search for right list
327 : // An exception is thrown - "eType" is unknown.
328 : // => rList will be valid everytimes next line is reached.
329 31515 : const CacheItemList& rList = impl_getItemList(eType);
330 :
331 : // if item could not be found - check if it can be loaded
332 : // from the underlying configuration layer. Might it was not already
333 : // loaded into this FilterCache object before.
334 31515 : CacheItemList::const_iterator pIt = rList.find(sItem);
335 31515 : if (pIt != rList.end())
336 30348 : return sal_True;
337 :
338 : try
339 : {
340 1167 : impl_loadItemOnDemand(eType, sItem);
341 : // no exception => item could be loaded!
342 0 : return sal_True;
343 : }
344 1167 : catch(const css::container::NoSuchElementException&)
345 : {}
346 :
347 32682 : return sal_False;
348 : // <- SAFE
349 : }
350 :
351 :
352 :
353 693481 : CacheItem FilterCache::getItem( EItemType eType,
354 : const OUString& sItem)
355 : throw(css::uno::Exception)
356 : {
357 : // SAFE ->
358 693481 : ::osl::ResettableMutexGuard aLock(m_aLock);
359 :
360 : // search for right list
361 : // An exception is thrown if "eType" is unknown.
362 : // => rList will be valid everytimes next line is reached.
363 693481 : CacheItemList& rList = impl_getItemList(eType);
364 :
365 : // check if item exists ...
366 693481 : CacheItemList::iterator pIt = rList.find(sItem);
367 693481 : if (pIt == rList.end())
368 : {
369 : // ... or load it on demand from the
370 : // underlying configuration layer.
371 : // Note: NoSuchElementException is thrown automaticly here if
372 : // item could not be loaded!
373 17 : pIt = impl_loadItemOnDemand(eType, sItem);
374 : }
375 :
376 : /* Workaround for #137955#
377 : Draw types and filters are installed ... but draw was disabled during setup.
378 : We must supress accessing these filters. Otherwise the office can crash.
379 : Solution for the next major release: do not install those filters !
380 : */
381 693464 : if (eType == E_FILTER)
382 : {
383 576200 : CacheItem& rFilter = pIt->second;
384 576200 : OUString sDocService;
385 576200 : rFilter[PROPNAME_DOCUMENTSERVICE] >>= sDocService;
386 :
387 : // In Standalone-Impress the module WriterWeb is not installed
388 : // but it is there to load help pages
389 576200 : bool bIsHelpFilter = sItem == "writer_web_HTML_help";
390 :
391 576200 : if ( !bIsHelpFilter && !impl_isModuleInstalled(sDocService) )
392 : {
393 0 : OUString sMsg("The requested filter '" + sItem +
394 0 : "' exists ... but it should not; because the corresponding LibreOffice module was not installed.");
395 0 : throw css::container::NoSuchElementException(sMsg, css::uno::Reference< css::uno::XInterface >());
396 576200 : }
397 : }
398 :
399 693481 : return pIt->second;
400 : // <- SAFE
401 : }
402 :
403 :
404 :
405 2 : void FilterCache::removeItem( EItemType eType,
406 : const OUString& sItem)
407 : throw(css::uno::Exception)
408 : {
409 : // SAFE ->
410 2 : ::osl::ResettableMutexGuard aLock(m_aLock);
411 :
412 : // search for right list
413 : // An exception is thrown - "eType" is unknown.
414 : // => rList will be valid everytimes next line is reached.
415 2 : CacheItemList& rList = impl_getItemList(eType);
416 :
417 2 : CacheItemList::iterator pItem = rList.find(sItem);
418 2 : if (pItem == rList.end())
419 1 : pItem = impl_loadItemOnDemand(eType, sItem); // throws NoSuchELementException!
420 1 : rList.erase(pItem);
421 :
422 2 : impl_addItem2FlushList(eType, sItem);
423 1 : }
424 :
425 :
426 :
427 1 : void FilterCache::setItem( EItemType eType ,
428 : const OUString& sItem ,
429 : const CacheItem& aValue)
430 : throw(css::uno::Exception)
431 : {
432 : // SAFE ->
433 1 : ::osl::ResettableMutexGuard aLock(m_aLock);
434 :
435 : // search for right list
436 : // An exception is thrown - "eType" is unknown.
437 : // => rList will be valid everytimes next line is reached.
438 1 : CacheItemList& rList = impl_getItemList(eType);
439 :
440 : // name must be part of the property set too ... otherwise our
441 : // container query cant work correctly
442 2 : CacheItem aItem = aValue;
443 1 : aItem[PROPNAME_NAME] <<= sItem;
444 1 : aItem.validateUINames(m_sActLocale);
445 :
446 : // remove implicit properties as e.g. FINALIZED or MANDATORY
447 : // They cant be saved here and must be readed on demand later, if they are needed.
448 1 : removeStatePropsFromItem(aItem);
449 :
450 1 : rList[sItem] = aItem;
451 :
452 2 : impl_addItem2FlushList(eType, sItem);
453 1 : }
454 :
455 :
456 0 : void FilterCache::refreshItem( EItemType eType,
457 : const OUString& sItem)
458 : throw(css::uno::Exception)
459 : {
460 : // SAFE ->
461 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
462 0 : impl_loadItemOnDemand(eType, sItem);
463 0 : }
464 :
465 :
466 :
467 20362 : void FilterCache::addStatePropsToItem( EItemType eType,
468 : const OUString& sItem,
469 : CacheItem& rItem)
470 : throw(css::uno::Exception)
471 : {
472 : // SAFE ->
473 20362 : ::osl::ResettableMutexGuard aLock(m_aLock);
474 :
475 : // Note: Opening of the configuration layer throws some exceptions
476 : // if it failed. So we dont must check any reference here ...
477 38683 : css::uno::Reference< css::container::XNameAccess > xPackage;
478 38683 : css::uno::Reference< css::container::XNameAccess > xSet;
479 20362 : switch(eType)
480 : {
481 : case E_TYPE :
482 : {
483 6486 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
484 6486 : xPackage->getByName(CFGSET_TYPES) >>= xSet;
485 : }
486 6486 : break;
487 :
488 : case E_FILTER :
489 : {
490 11808 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
491 11808 : xPackage->getByName(CFGSET_FILTERS) >>= xSet;
492 : }
493 11808 : break;
494 :
495 : case E_FRAMELOADER :
496 : {
497 : /* TODO
498 : Hack -->
499 : The default frame loader cant be located inside te normal set of frame loaders.
500 : Its an atomic property inside the misc cfg package. So we cant retrieve the information
501 : about FINALIZED and MANDATORY very easy ... :-(
502 : => set it to readonly/required everytimes :-)
503 : */
504 2066 : css::uno::Any aDirectValue = impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER);
505 2091 : OUString sDefaultFrameLoader;
506 2066 : if (
507 4132 : (aDirectValue >>= sDefaultFrameLoader) &&
508 4132 : (!sDefaultFrameLoader.isEmpty() ) &&
509 2066 : (sItem.equals(sDefaultFrameLoader) )
510 : )
511 : {
512 2041 : rItem[PROPNAME_FINALIZED] <<= sal_True;
513 2041 : rItem[PROPNAME_MANDATORY] <<= sal_True;
514 22403 : return;
515 : }
516 : /* <-- HACK */
517 :
518 25 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
519 50 : xPackage->getByName(CFGSET_FRAMELOADERS) >>= xSet;
520 : }
521 25 : break;
522 :
523 : case E_CONTENTHANDLER :
524 : {
525 2 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
526 2 : xPackage->getByName(CFGSET_CONTENTHANDLERS) >>= xSet;
527 : }
528 2 : break;
529 0 : default: break;
530 : }
531 :
532 : try
533 : {
534 18321 : css::uno::Reference< css::beans::XProperty > xItem;
535 18321 : xSet->getByName(sItem) >>= xItem;
536 36642 : css::beans::Property aDescription = xItem->getAsProperty();
537 :
538 18321 : sal_Bool bFinalized = ((aDescription.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY );
539 18321 : sal_Bool bMandatory = ((aDescription.Attributes & css::beans::PropertyAttribute::REMOVABLE) != css::beans::PropertyAttribute::REMOVABLE);
540 :
541 18321 : rItem[PROPNAME_FINALIZED] <<= bFinalized;
542 36642 : rItem[PROPNAME_MANDATORY] <<= bMandatory;
543 : }
544 0 : catch(const css::container::NoSuchElementException&)
545 : {
546 : /* Ignore exceptions for missing elements inside configuration.
547 : May by the following reason exists:
548 : - The item does not exists inside the new configuration package org.openoffice.TypeDetection - but
549 : we got it from the old package org.openoffice.Office/TypeDetection. We dont migrate such items
550 : automaticly to the new format. Because it will disturb e.g. the deinstallation of an external filter
551 : package. Because such external filter can remove the old file - but not the automaticly created new one ...
552 :
553 : => mark item as FINALIZED / MANDATORY, we dont support writing to the old format
554 : */
555 0 : rItem[PROPNAME_FINALIZED] <<= sal_True;
556 0 : rItem[PROPNAME_MANDATORY] <<= sal_True;
557 18321 : }
558 :
559 : // <- SAFE
560 : }
561 :
562 :
563 :
564 1 : void FilterCache::removeStatePropsFromItem(CacheItem& rItem)
565 : throw(css::uno::Exception)
566 : {
567 1 : CacheItem::iterator pIt;
568 1 : pIt = rItem.find(PROPNAME_FINALIZED);
569 1 : if (pIt != rItem.end())
570 1 : rItem.erase(pIt);
571 1 : pIt = rItem.find(PROPNAME_MANDATORY);
572 1 : if (pIt != rItem.end())
573 1 : rItem.erase(pIt);
574 1 : }
575 :
576 :
577 :
578 1 : void FilterCache::flush()
579 : throw(css::uno::Exception)
580 : {
581 : // SAFE ->
582 1 : ::osl::ResettableMutexGuard aLock(m_aLock);
583 :
584 : // renew all dependencies and optimizations
585 1 : impl_validateAndOptimize();
586 :
587 1 : if (m_lChangedTypes.size() > 0)
588 : {
589 0 : css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
590 0 : css::uno::Reference< css::container::XNameAccess > xSet ;
591 :
592 0 : xConfig->getByName(CFGSET_TYPES) >>= xSet;
593 0 : impl_flushByList(xSet, E_TYPE, m_lTypes, m_lChangedTypes);
594 :
595 0 : css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
596 0 : xFlush->commitChanges();
597 : }
598 :
599 1 : if (m_lChangedFilters.size() > 0)
600 : {
601 1 : css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
602 2 : css::uno::Reference< css::container::XNameAccess > xSet ;
603 :
604 1 : xConfig->getByName(CFGSET_FILTERS) >>= xSet;
605 1 : impl_flushByList(xSet, E_FILTER, m_lFilters, m_lChangedFilters);
606 :
607 2 : css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
608 2 : xFlush->commitChanges();
609 1 : }
610 :
611 : /*TODO FrameLoader/ContentHandler must be flushed here too ... */
612 1 : }
613 :
614 :
615 :
616 1 : void FilterCache::impl_flushByList(const css::uno::Reference< css::container::XNameAccess >& xSet ,
617 : EItemType eType ,
618 : const CacheItemList& rCache,
619 : const OUStringList& lItems)
620 : throw(css::uno::Exception)
621 : {
622 1 : css::uno::Reference< css::container::XNameContainer > xAddRemoveSet = css::uno::Reference< css::container::XNameContainer > (xSet, css::uno::UNO_QUERY);
623 2 : css::uno::Reference< css::container::XNameReplace > xReplaceeSet = css::uno::Reference< css::container::XNameReplace > (xSet, css::uno::UNO_QUERY);
624 2 : css::uno::Reference< css::lang::XSingleServiceFactory > xFactory = css::uno::Reference< css::lang::XSingleServiceFactory >(xSet, css::uno::UNO_QUERY);
625 :
626 6 : for (OUStringList::const_iterator pIt = lItems.begin();
627 4 : pIt != lItems.end() ;
628 : ++pIt )
629 : {
630 1 : const OUString& sItem = *pIt;
631 1 : EItemFlushState eState = impl_specifyFlushOperation(xSet, rCache, sItem);
632 1 : switch(eState)
633 : {
634 : case E_ITEM_REMOVED :
635 : {
636 0 : xAddRemoveSet->removeByName(sItem);
637 : }
638 0 : break;
639 :
640 : case E_ITEM_ADDED :
641 : {
642 0 : css::uno::Reference< css::container::XNameReplace > xItem (xFactory->createInstance(), css::uno::UNO_QUERY);
643 :
644 : // special case. no exception - but not a valid item => set must be finalized or mandatory!
645 : // Reject flush operation by throwing an exception. At least one item couldnt be flushed.
646 0 : if (!xItem.is())
647 : throw css::uno::Exception("Cant add item. Set is finalized or mandatory!",
648 0 : css::uno::Reference< css::uno::XInterface >());
649 :
650 0 : CacheItemList::const_iterator pItem = rCache.find(sItem);
651 0 : impl_saveItem(xItem, eType, pItem->second);
652 0 : xAddRemoveSet->insertByName(sItem, css::uno::makeAny(xItem));
653 : }
654 0 : break;
655 :
656 : case E_ITEM_CHANGED :
657 : {
658 0 : css::uno::Reference< css::container::XNameReplace > xItem;
659 0 : xSet->getByName(sItem) >>= xItem;
660 :
661 : // special case. no exception - but not a valid item => it must be finalized or mandatory!
662 : // Reject flush operation by throwing an exception. At least one item couldnt be flushed.
663 0 : if (!xItem.is())
664 : throw css::uno::Exception("Cant change item. Its finalized or mandatory!",
665 0 : css::uno::Reference< css::uno::XInterface >());
666 :
667 0 : CacheItemList::const_iterator pItem = rCache.find(sItem);
668 0 : impl_saveItem(xItem, eType, pItem->second);
669 : }
670 0 : break;
671 1 : default: break;
672 : }
673 1 : }
674 1 : }
675 :
676 :
677 :
678 16542 : void FilterCache::detectFlatForURL(const css::util::URL& aURL ,
679 : FlatDetection& rFlatTypes) const
680 : throw(css::uno::Exception)
681 : {
682 : // extract extension from URL, so it can be used directly as key into our hash map!
683 : // Note further: It must be converted to lower case, because the optimize hash
684 : // (which maps extensions to types) work with lower case key strings!
685 16542 : INetURLObject aParser (aURL.Main);
686 : OUString sExtension = aParser.getExtension(INetURLObject::LAST_SEGMENT ,
687 : true ,
688 33084 : INetURLObject::DECODE_WITH_CHARSET);
689 16542 : sExtension = sExtension.toAsciiLowerCase();
690 :
691 : // SAFE -> ----------------------------------
692 33084 : ::osl::ResettableMutexGuard aLock(m_aLock);
693 :
694 :
695 : // i) Step over all well known URL pattern
696 : // and add registered types to the return list too
697 : // Do it as first one - because: if a type match by a
698 : // pattern a following deep detection can be supressed!
699 : // Further we can stop after first match ...
700 694764 : for (CacheItemRegistration::const_iterator pPattReg = m_lURLPattern2Types.begin();
701 463176 : pPattReg != m_lURLPattern2Types.end() ;
702 : ++pPattReg )
703 : {
704 215046 : WildCard aPatternCheck(pPattReg->first);
705 215046 : if (aPatternCheck.Matches(aURL.Main))
706 : {
707 665 : const OUStringList& rTypesForPattern = pPattReg->second;
708 :
709 665 : FlatDetectionInfo aInfo;
710 665 : aInfo.sType = *(rTypesForPattern.begin());
711 665 : aInfo.bMatchByPattern = true;
712 :
713 665 : rFlatTypes.push_back(aInfo);
714 : // return;
715 : }
716 215046 : }
717 :
718 :
719 : // ii) search types matching to the given extension.
720 : // Copy every macthing type without changing its order!
721 : // Because preferred types was added as first one during
722 : // loading configuration.
723 16542 : CacheItemRegistration::const_iterator pExtReg = m_lExtensions2Types.find(sExtension);
724 16542 : if (pExtReg != m_lExtensions2Types.end())
725 : {
726 2098 : const OUStringList& rTypesForExtension = pExtReg->second;
727 18852 : for (OUStringList::const_iterator pIt = rTypesForExtension.begin();
728 12568 : pIt != rTypesForExtension.end() ;
729 : ++pIt )
730 : {
731 4186 : FlatDetectionInfo aInfo;
732 4186 : aInfo.sType = *pIt;
733 4186 : aInfo.bMatchByExtension = true;
734 :
735 4186 : rFlatTypes.push_back(aInfo);
736 4186 : }
737 : }
738 :
739 33084 : aLock.clear();
740 : // <- SAFE ----------------------------------
741 16542 : }
742 :
743 39601 : const CacheItemList& FilterCache::impl_getItemList(EItemType eType) const
744 : {
745 : // SAFE -> ----------------------------------
746 39601 : ::osl::ResettableMutexGuard aLock(m_aLock);
747 :
748 39601 : switch(eType)
749 : {
750 4141 : case E_TYPE : return m_lTypes ;
751 5502 : case E_FILTER : return m_lFilters ;
752 16533 : case E_FRAMELOADER : return m_lFrameLoaders ;
753 13425 : case E_CONTENTHANDLER : return m_lContentHandlers;
754 0 : case E_DETECTSERVICE : return m_lDetectServices ;
755 :
756 : }
757 :
758 : throw css::uno::Exception("unknown sub container requested.",
759 0 : css::uno::Reference< css::uno::XInterface >());
760 : // <- SAFE ----------------------------------
761 : }
762 :
763 724999 : CacheItemList& FilterCache::impl_getItemList(EItemType eType)
764 : {
765 : // SAFE -> ----------------------------------
766 724999 : ::osl::ResettableMutexGuard aLock(m_aLock);
767 :
768 724999 : switch(eType)
769 : {
770 139395 : case E_TYPE : return m_lTypes ;
771 579388 : case E_FILTER : return m_lFilters ;
772 6207 : case E_FRAMELOADER : return m_lFrameLoaders ;
773 9 : case E_CONTENTHANDLER : return m_lContentHandlers;
774 0 : case E_DETECTSERVICE : return m_lDetectServices ;
775 :
776 : }
777 :
778 : throw css::uno::Exception("unknown sub container requested.",
779 0 : css::uno::Reference< css::uno::XInterface >());
780 : // <- SAFE ----------------------------------
781 : }
782 :
783 19916 : css::uno::Reference< css::uno::XInterface > FilterCache::impl_openConfig(EConfigProvider eProvider)
784 : throw(css::uno::Exception)
785 : {
786 19916 : ::osl::ResettableMutexGuard aLock(m_aLock);
787 :
788 39832 : OUString sPath ;
789 19916 : css::uno::Reference< css::uno::XInterface >* pConfig = 0;
790 39832 : css::uno::Reference< css::uno::XInterface > xOld ;
791 39832 : OString sRtlLog ;
792 :
793 19916 : switch(eProvider)
794 : {
795 : case E_PROVIDER_TYPES :
796 : {
797 7794 : if (m_xConfigTypes.is())
798 7719 : return m_xConfigTypes;
799 75 : sPath = CFGPACKAGE_TD_TYPES;
800 75 : pConfig = &m_xConfigTypes;
801 75 : sRtlLog = "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_TYPES)";
802 : }
803 75 : break;
804 :
805 : case E_PROVIDER_FILTERS :
806 : {
807 11901 : if (m_xConfigFilters.is())
808 11827 : return m_xConfigFilters;
809 74 : sPath = CFGPACKAGE_TD_FILTERS;
810 74 : pConfig = &m_xConfigFilters;
811 74 : sRtlLog = "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_FILTERS)";
812 : }
813 74 : break;
814 :
815 : case E_PROVIDER_OTHERS :
816 : {
817 146 : if (m_xConfigOthers.is())
818 78 : return m_xConfigOthers;
819 68 : sPath = CFGPACKAGE_TD_OTHERS;
820 68 : pConfig = &m_xConfigOthers;
821 68 : sRtlLog = "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OTHERS)";
822 : }
823 68 : break;
824 :
825 : case E_PROVIDER_OLD :
826 : {
827 : // This special provider is used to work with
828 : // the old configuration format only. Its not cached!
829 75 : sPath = CFGPACKAGE_TD_OLD;
830 75 : pConfig = &xOld;
831 75 : sRtlLog = "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OLD)";
832 : }
833 75 : break;
834 :
835 0 : default : throw css::uno::Exception("These configuration node isnt supported here for open!", 0);
836 : }
837 :
838 : {
839 : SAL_INFO( "filter.config", "" << sRtlLog.getStr());
840 584 : *pConfig = impl_createConfigAccess(sPath ,
841 : sal_False, // bReadOnly
842 292 : sal_True ); // bLocalesMode
843 : }
844 :
845 :
846 : // Start listening for changes on that configuration access.
847 292 : switch(eProvider)
848 : {
849 : case E_PROVIDER_TYPES:
850 : {
851 75 : m_xTypesChglisteners.set(new CacheUpdateListener(*this, *pConfig, FilterCache::E_TYPE));
852 75 : m_xTypesChglisteners->startListening();
853 : }
854 75 : break;
855 : case E_PROVIDER_FILTERS:
856 : {
857 74 : m_xFiltersChgListener.set(new CacheUpdateListener(*this, *pConfig, FilterCache::E_FILTER));
858 74 : m_xFiltersChgListener->startListening();
859 : }
860 74 : break;
861 : default:
862 143 : break;
863 : }
864 :
865 20208 : return *pConfig;
866 : }
867 :
868 :
869 :
870 2478 : css::uno::Any FilterCache::impl_getDirectCFGValue(const OUString& sDirectKey)
871 : {
872 2478 : OUString sRoot;
873 4956 : OUString sKey ;
874 :
875 2478 : if (
876 4956 : (!::utl::splitLastFromConfigurationPath(sDirectKey, sRoot, sKey)) ||
877 4956 : (sRoot.isEmpty() ) ||
878 2478 : (sKey.isEmpty() )
879 : )
880 0 : return css::uno::Any();
881 :
882 : css::uno::Reference< css::uno::XInterface > xCfg = impl_createConfigAccess(sRoot ,
883 : sal_True , // bReadOnly
884 4956 : sal_False); // bLocalesMode
885 2478 : if (!xCfg.is())
886 0 : return css::uno::Any();
887 :
888 4956 : css::uno::Reference< css::container::XNameAccess > xAccess(xCfg, css::uno::UNO_QUERY);
889 2478 : if (!xAccess.is())
890 0 : return css::uno::Any();
891 :
892 4956 : css::uno::Any aValue;
893 : try
894 : {
895 2478 : aValue = xAccess->getByName(sKey);
896 : }
897 0 : catch(const css::uno::RuntimeException&)
898 0 : { throw; }
899 : #if OSL_DEBUG_LEVEL > 0
900 : catch(const css::uno::Exception& ex)
901 : #else
902 0 : catch(const css::uno::Exception&)
903 : #endif
904 : {
905 : #if OSL_DEBUG_LEVEL > 0
906 : OSL_FAIL(OUStringToOString(ex.Message, RTL_TEXTENCODING_UTF8).getStr());
907 : #endif
908 0 : aValue.clear();
909 : }
910 :
911 4956 : return aValue;
912 : }
913 :
914 :
915 :
916 2770 : css::uno::Reference< css::uno::XInterface > FilterCache::impl_createConfigAccess(const OUString& sRoot ,
917 : sal_Bool bReadOnly ,
918 : sal_Bool bLocalesMode)
919 : {
920 : // SAFE ->
921 2770 : ::osl::ResettableMutexGuard aLock(m_aLock);
922 :
923 2770 : css::uno::Reference< css::uno::XInterface > xCfg;
924 :
925 : try
926 : {
927 : css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
928 2770 : css::configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() ) );
929 :
930 5540 : ::comphelper::SequenceAsVector< css::uno::Any > lParams;
931 5540 : css::beans::NamedValue aParam;
932 :
933 : // set root path
934 2770 : aParam.Name = _FILTER_CONFIG_FROM_ASCII_("nodepath");
935 2770 : aParam.Value <<= sRoot;
936 2770 : lParams.push_back(css::uno::makeAny(aParam));
937 :
938 : // enable "all locales mode" ... if required
939 2770 : if (bLocalesMode)
940 : {
941 292 : aParam.Name = _FILTER_CONFIG_FROM_ASCII_("locale");
942 292 : aParam.Value <<= _FILTER_CONFIG_FROM_ASCII_("*" );
943 292 : lParams.push_back(css::uno::makeAny(aParam));
944 : }
945 :
946 : // open it
947 2770 : if (bReadOnly)
948 2478 : xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONACCESS, lParams.getAsConstList());
949 : else
950 292 : xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONUPDATEACCESS, lParams.getAsConstList());
951 :
952 : // If configuration could not be opened ... but factory method does not throwed an exception
953 : // trigger throwing of our own CorruptedFilterConfigurationException.
954 : // Let message empty. The normal exception text show enough information to the user.
955 2770 : if (! xCfg.is())
956 : throw css::uno::Exception(
957 : _FILTER_CONFIG_FROM_ASCII_("Got NULL reference on opening configuration file ... but no exception."),
958 2770 : css::uno::Reference< css::uno::XInterface >());
959 : }
960 0 : catch(const css::uno::Exception& ex)
961 : {
962 : throw css::document::CorruptedFilterConfigurationException(
963 0 : "filter configuration, caught: " + ex.Message,
964 : css::uno::Reference< css::uno::XInterface >(),
965 0 : ex.Message);
966 : }
967 :
968 2770 : return xCfg;
969 : // <- SAFE
970 : }
971 :
972 :
973 :
974 337 : void FilterCache::impl_validateAndOptimize()
975 : throw(css::uno::Exception)
976 : {
977 : // SAFE ->
978 337 : ::osl::ResettableMutexGuard aLock(m_aLock);
979 :
980 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::impl_validateAndOptimize");
981 :
982 : // First check if any filter or type could be readed
983 : // from the underlying configuration!
984 337 : sal_Bool bSomeTypesShouldExist = ((m_eFillState & E_CONTAINS_STANDARD ) == E_CONTAINS_STANDARD );
985 337 : sal_Bool bAllFiltersShouldExist = ((m_eFillState & E_CONTAINS_FILTERS ) == E_CONTAINS_FILTERS );
986 :
987 : #if OSL_DEBUG_LEVEL > 0
988 :
989 : sal_Int32 nWarnings = 0;
990 :
991 : // sal_Bool bAllTypesShouldExist = ((m_eFillState & E_CONTAINS_TYPES ) == E_CONTAINS_TYPES );
992 : sal_Bool bAllLoadersShouldExist = ((m_eFillState & E_CONTAINS_FRAMELOADERS ) == E_CONTAINS_FRAMELOADERS );
993 : sal_Bool bAllHandlersShouldExist = ((m_eFillState & E_CONTAINS_CONTENTHANDLERS) == E_CONTAINS_CONTENTHANDLERS);
994 : #endif
995 :
996 337 : if (
997 : (
998 337 : (bSomeTypesShouldExist) &&
999 337 : (m_lTypes.size() < 1 )
1000 674 : ) ||
1001 : (
1002 225 : (bAllFiltersShouldExist) &&
1003 225 : (m_lFilters.size() < 1 )
1004 : )
1005 : )
1006 : {
1007 : throw css::document::CorruptedFilterConfigurationException(
1008 : "filter configuration: the list of types or filters is empty",
1009 : css::uno::Reference< css::uno::XInterface >(),
1010 0 : "The list of types or filters is empty." );
1011 : }
1012 :
1013 : // Create a log for all detected problems, which
1014 : // occur in the next few lines.
1015 : // If there are some real errors throw a RuntimException!
1016 : // If there are some warnings only, show an assertion.
1017 337 : sal_Int32 nErrors = 0;
1018 674 : OUStringBuffer sLog(256);
1019 :
1020 337 : CacheItemList::iterator pIt;
1021 :
1022 55268 : for (pIt = m_lTypes.begin(); pIt != m_lTypes.end(); ++pIt)
1023 : {
1024 54931 : OUString sType = pIt->first;
1025 109862 : CacheItem aType = pIt->second;
1026 :
1027 : // create list of all known detect services / frame loader / content handler on demand
1028 : // Because these information are available as type properties!
1029 109862 : OUString sDetectService;
1030 54931 : aType[PROPNAME_DETECTSERVICE ] >>= sDetectService;
1031 54931 : if (!sDetectService.isEmpty())
1032 51898 : impl_resolveItem4TypeRegistration(&m_lDetectServices, sDetectService, sType);
1033 :
1034 : // get its registration for file Extensions AND(!) URLPattern ...
1035 : // It doesn't matter if these items exists or if our
1036 : // used index access create some default ones ...
1037 : // only in case there is no filled set of Extensions AND
1038 : // no filled set of URLPattern -> we must try to remove this invalid item
1039 : // from this cache!
1040 109862 : css::uno::Sequence< OUString > lExtensions;
1041 109862 : css::uno::Sequence< OUString > lURLPattern;
1042 54931 : aType[PROPNAME_EXTENSIONS] >>= lExtensions;
1043 54931 : aType[PROPNAME_URLPATTERN] >>= lURLPattern;
1044 54931 : sal_Int32 ce = lExtensions.getLength();
1045 54931 : sal_Int32 cu = lURLPattern.getLength();
1046 :
1047 : #if OSL_DEBUG_LEVEL > 0
1048 :
1049 : OUString sInternalTypeNameCheck;
1050 : aType[PROPNAME_NAME] >>= sInternalTypeNameCheck;
1051 : if (!sInternalTypeNameCheck.equals(sType))
1052 : {
1053 : sLog.append("Warning\t:\t" "The type \"" + sType + "\" does support the property \"Name\" correctly.\n");
1054 : ++nWarnings;
1055 : }
1056 :
1057 : if (!ce && !cu)
1058 : {
1059 : sLog.append("Warning\t:\t" "The type \"" + sType + "\" does not contain any URL pattern nor any extensions.\n");
1060 : ++nWarnings;
1061 : }
1062 : #endif
1063 :
1064 : // create an optimized registration for this type to
1065 : // its set list of extensions/url pattern. If it's a "normal" type
1066 : // set it at the end of this optimized list. But if its
1067 : // a "Preferred" one - set it to the front of this list.
1068 : // Of course multiple "Preferred" registrations can occur
1069 : // (they shouldn't - but they can!) ... Ignore it. The last
1070 : // preferred type is useable in the same manner then every
1071 : // other type!
1072 54931 : sal_Bool bPreferred = sal_False;
1073 54931 : aType[PROPNAME_PREFERRED] >>= bPreferred;
1074 :
1075 54931 : const OUString* pExtensions = lExtensions.getConstArray();
1076 136822 : for (sal_Int32 e=0; e<ce; ++e)
1077 : {
1078 : // Note: We must be sure that address the right hash entry
1079 : // does not depend from any upper/lower case problems ...
1080 81891 : OUString sNormalizedExtension = pExtensions[e].toAsciiLowerCase();
1081 :
1082 81891 : OUStringList& lTypesForExtension = m_lExtensions2Types[sNormalizedExtension];
1083 81891 : if (::std::find(lTypesForExtension.begin(), lTypesForExtension.end(), sType) != lTypesForExtension.end())
1084 63741 : continue;
1085 :
1086 18150 : if (bPreferred)
1087 7425 : lTypesForExtension.insert(lTypesForExtension.begin(), sType);
1088 : else
1089 10725 : lTypesForExtension.push_back(sType);
1090 18150 : }
1091 :
1092 54931 : const OUString* pURLPattern = lURLPattern.getConstArray();
1093 59312 : for (sal_Int32 u=0; u<cu; ++u)
1094 : {
1095 4381 : OUStringList& lTypesForURLPattern = m_lURLPattern2Types[pURLPattern[u]];
1096 4381 : if (::std::find(lTypesForURLPattern.begin(), lTypesForURLPattern.end(), sType) != lTypesForURLPattern.end())
1097 3406 : continue;
1098 :
1099 975 : if (bPreferred)
1100 0 : lTypesForURLPattern.insert(lTypesForURLPattern.begin(), sType);
1101 : else
1102 975 : lTypesForURLPattern.push_back(sType);
1103 : }
1104 :
1105 : #if OSL_DEBUG_LEVEL > 0
1106 :
1107 : // Dont check cross references between types and filters, if
1108 : // not all filters read from disk!
1109 : // OK - this cache can read single filters on demand too ...
1110 : // but then the fill state of this cache should not be set to E_CONTAINS_FILTERS!
1111 : if (!bAllFiltersShouldExist)
1112 : continue;
1113 :
1114 : OUString sPrefFilter;
1115 : aType[PROPNAME_PREFERREDFILTER] >>= sPrefFilter;
1116 : if (sPrefFilter.isEmpty())
1117 : {
1118 : // OK - there is no filter for this type. But thats not an error.
1119 : // May be it can be handled by a ContentHandler ...
1120 : // But at this time its not guaranteed that there is any ContentHandler
1121 : // or FrameLoader inside this cache ... but on disk ...
1122 : sal_Bool bReferencedByLoader = sal_True;
1123 : sal_Bool bReferencedByHandler = sal_True;
1124 : if (bAllLoadersShouldExist)
1125 : bReferencedByLoader = !impl_searchFrameLoaderForType(sType).isEmpty();
1126 :
1127 : if (bAllHandlersShouldExist)
1128 : bReferencedByHandler = !impl_searchContentHandlerForType(sType).isEmpty();
1129 :
1130 : if (
1131 : (!bReferencedByLoader ) &&
1132 : (!bReferencedByHandler)
1133 : )
1134 : {
1135 : sLog.append("Warning\t:\t" "The type \"" + sType + "\" isnt used by any filter, loader or content handler.\n");
1136 : ++nWarnings;
1137 : }
1138 : }
1139 :
1140 : if (!sPrefFilter.isEmpty())
1141 : {
1142 : CacheItemList::const_iterator pIt2 = m_lFilters.find(sPrefFilter);
1143 : if (pIt2 == m_lFilters.end())
1144 : {
1145 : if (bAllFiltersShouldExist)
1146 : {
1147 : ++nWarnings; // preferred filters can point to a non-installed office module ! no error ... it's a warning only .-(
1148 : sLog.append("error\t:\t");
1149 : }
1150 : else
1151 : {
1152 : ++nWarnings;
1153 : sLog.append("warning\t:\t");
1154 : }
1155 :
1156 : sLog.append("The type \"" + sType + "\" points to an invalid filter \"" + sPrefFilter + "\".\n");
1157 : continue;
1158 : }
1159 :
1160 : CacheItem aPrefFilter = pIt2->second;
1161 : OUString sFilterTypeReg;
1162 : aPrefFilter[PROPNAME_TYPE] >>= sFilterTypeReg;
1163 : if (sFilterTypeReg != sType)
1164 : {
1165 : sLog.append("error\t:\t" "The preferred filter \""
1166 : + sPrefFilter + "\" of type \"" + sType +
1167 : "\" is registered for another type \"" + sFilterTypeReg +
1168 : "\".\n");
1169 : ++nErrors;
1170 : }
1171 :
1172 : sal_Int32 nFlags = 0;
1173 : aPrefFilter[PROPNAME_FLAGS] >>= nFlags;
1174 : if ((nFlags & FLAGVAL_IMPORT) != FLAGVAL_IMPORT)
1175 : {
1176 : sLog.append("error\t:\t" "The preferred filter \"" + sPrefFilter + "\" of type \"" +
1177 : sType + "\" is not an IMPORT filter!\n");
1178 : ++nErrors;
1179 : }
1180 :
1181 : OUString sInternalFilterNameCheck;
1182 : aPrefFilter[PROPNAME_NAME] >>= sInternalFilterNameCheck;
1183 : if (!sInternalFilterNameCheck.equals(sPrefFilter))
1184 : {
1185 : sLog.append("Warning\t:\t" "The filter \"" + sPrefFilter +
1186 : "\" does support the property \"Name\" correctly.\n");
1187 : ++nWarnings;
1188 : }
1189 : }
1190 : #endif
1191 54931 : }
1192 :
1193 : // create dependencies between the global default frame loader
1194 : // and all types (and of course if registered filters), which
1195 : // does not registered for any other loader.
1196 674 : css::uno::Any aDirectValue = impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER);
1197 674 : OUString sDefaultFrameLoader;
1198 :
1199 337 : if (
1200 674 : (!(aDirectValue >>= sDefaultFrameLoader)) ||
1201 337 : (sDefaultFrameLoader.isEmpty() )
1202 : )
1203 : {
1204 0 : sLog.append("error\t:\t" "There is no valid default frame loader!?\n");
1205 0 : ++nErrors;
1206 : }
1207 :
1208 : // a) get list of all well known types
1209 : // b) step over all well known frame loader services
1210 : // and remove all types from list a), which already
1211 : // referenced by a loader b)
1212 674 : OUStringList lTypes = getItemNames(E_TYPE);
1213 4377 : for ( pIt = m_lFrameLoaders.begin();
1214 2918 : pIt != m_lFrameLoaders.end() ;
1215 : ++pIt )
1216 : {
1217 : // Note: of course the default loader must be ignored here.
1218 : // Because we replace its registration later completely with all
1219 : // types, which are not referenced by any other loader.
1220 : // So we can avaoid our code against the complexity of a diff!
1221 1122 : OUString sLoader = pIt->first;
1222 1122 : if (sLoader.equals(sDefaultFrameLoader))
1223 262 : continue;
1224 :
1225 860 : CacheItem& rLoader = pIt->second;
1226 860 : css::uno::Any& rTypesReg = rLoader[PROPNAME_TYPES];
1227 1720 : OUStringList lTypesReg (rTypesReg);
1228 :
1229 7740 : for (OUStringList::const_iterator pTypesReg = lTypesReg.begin();
1230 5160 : pTypesReg != lTypesReg.end() ;
1231 : ++pTypesReg )
1232 : {
1233 1720 : OUStringList::iterator pTypeCheck = ::std::find(lTypes.begin(), lTypes.end(), *pTypesReg);
1234 1720 : if (pTypeCheck != lTypes.end())
1235 1075 : lTypes.erase(pTypeCheck);
1236 : }
1237 860 : }
1238 :
1239 337 : CacheItem& rDefaultLoader = m_lFrameLoaders[sDefaultFrameLoader];
1240 337 : rDefaultLoader[PROPNAME_NAME ] <<= sDefaultFrameLoader;
1241 337 : rDefaultLoader[PROPNAME_TYPES] <<= lTypes.getAsConstList();
1242 :
1243 674 : OUString sLogOut = sLog.makeStringAndClear();
1244 : OSL_ENSURE(!nErrors, OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
1245 337 : if (nErrors>0)
1246 : throw css::document::CorruptedFilterConfigurationException(
1247 0 : "filter configuration: " + sLogOut,
1248 : css::uno::Reference< css::uno::XInterface >(),
1249 0 : sLogOut);
1250 337 : OSL_ENSURE(!nWarnings, OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
1251 :
1252 : // <- SAFE
1253 337 : }
1254 :
1255 :
1256 :
1257 2 : void FilterCache::impl_addItem2FlushList( EItemType eType,
1258 : const OUString& sItem)
1259 : throw(css::uno::Exception)
1260 : {
1261 2 : OUStringList* pList = 0;
1262 2 : switch(eType)
1263 : {
1264 : case E_TYPE :
1265 0 : pList = &m_lChangedTypes;
1266 0 : break;
1267 :
1268 : case E_FILTER :
1269 2 : pList = &m_lChangedFilters;
1270 2 : break;
1271 :
1272 : case E_FRAMELOADER :
1273 0 : pList = &m_lChangedFrameLoaders;
1274 0 : break;
1275 :
1276 : case E_CONTENTHANDLER :
1277 0 : pList = &m_lChangedContentHandlers;
1278 0 : break;
1279 :
1280 : case E_DETECTSERVICE :
1281 0 : pList = &m_lChangedDetectServices;
1282 0 : break;
1283 :
1284 0 : default : throw css::uno::Exception("unsupported item type", 0);
1285 : }
1286 :
1287 2 : OUStringList::const_iterator pItem = ::std::find(pList->begin(), pList->end(), sItem);
1288 2 : if (pItem == pList->end())
1289 1 : pList->push_back(sItem);
1290 2 : }
1291 :
1292 :
1293 :
1294 1 : FilterCache::EItemFlushState FilterCache::impl_specifyFlushOperation(const css::uno::Reference< css::container::XNameAccess >& xSet ,
1295 : const CacheItemList& rList,
1296 : const OUString& sItem)
1297 : throw(css::uno::Exception)
1298 : {
1299 1 : sal_Bool bExistsInConfigLayer = xSet->hasByName(sItem);
1300 1 : sal_Bool bExistsInMemory = (rList.find(sItem) != rList.end());
1301 :
1302 1 : EItemFlushState eState( E_ITEM_UNCHANGED );
1303 :
1304 : // !? ... such situation can occur, if an item was added and(!) removed before it was flushed :-)
1305 1 : if (!bExistsInConfigLayer && !bExistsInMemory)
1306 1 : eState = E_ITEM_UNCHANGED;
1307 0 : else if (!bExistsInConfigLayer && bExistsInMemory)
1308 0 : eState = E_ITEM_ADDED;
1309 0 : else if (bExistsInConfigLayer && bExistsInMemory)
1310 0 : eState = E_ITEM_CHANGED;
1311 0 : else if (bExistsInConfigLayer && !bExistsInMemory)
1312 0 : eState = E_ITEM_REMOVED;
1313 :
1314 1 : return eState;
1315 : }
1316 :
1317 :
1318 :
1319 51898 : void FilterCache::impl_resolveItem4TypeRegistration( CacheItemList* pList,
1320 : const OUString& sItem,
1321 : const OUString& sType)
1322 : throw(css::uno::Exception)
1323 : {
1324 51898 : CacheItem& rItem = (*pList)[sItem];
1325 : // In case it's a new created entry (automaticly done by the boost::unordered_map index operator!)
1326 : // we must be shure, that this entry has its own name as property available.
1327 : // Its needed later at our container interface!
1328 51898 : rItem[PROPNAME_NAME] <<= sItem;
1329 :
1330 51898 : OUStringList lTypeRegs(rItem[PROPNAME_TYPES]);
1331 51898 : if (::std::find(lTypeRegs.begin(), lTypeRegs.end(), sType) == lTypeRegs.end())
1332 : {
1333 11550 : lTypeRegs.push_back(sType);
1334 11550 : rItem[PROPNAME_TYPES] <<= lTypeRegs.getAsConstList();
1335 51898 : }
1336 51898 : }
1337 :
1338 :
1339 :
1340 335 : void FilterCache::impl_load(EFillState eRequiredState)
1341 : throw(css::uno::Exception)
1342 : {
1343 : // SAFE ->
1344 335 : ::osl::ResettableMutexGuard aLock(m_aLock);
1345 :
1346 : // Attention: Detect services are part of the standard set!
1347 : // So there is no need to handle it separately.
1348 :
1349 :
1350 : // a) The standard set of config value is needed.
1351 335 : if (
1352 443 : ((eRequiredState & E_CONTAINS_STANDARD) == E_CONTAINS_STANDARD) &&
1353 108 : ((m_eFillState & E_CONTAINS_STANDARD) != E_CONTAINS_STANDARD)
1354 : )
1355 : {
1356 : // Attention! If config couldnt be opened successfully
1357 : // and exception os thrown automaticly and must be forwarded
1358 : // to our calli ...
1359 75 : css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
1360 : {
1361 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::load std");
1362 75 : impl_loadSet(xTypes, E_TYPE, E_READ_STANDARD, &m_lTypes);
1363 75 : }
1364 : }
1365 :
1366 :
1367 : // b) We need all type information ...
1368 335 : if (
1369 437 : ((eRequiredState & E_CONTAINS_TYPES) == E_CONTAINS_TYPES) &&
1370 102 : ((m_eFillState & E_CONTAINS_TYPES) != E_CONTAINS_TYPES)
1371 : )
1372 : {
1373 : // Attention! If config couldnt be opened successfully
1374 : // and exception os thrown automaticly and must be forwarded
1375 : // to our calli ...
1376 71 : css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
1377 : {
1378 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::load all types");
1379 71 : impl_loadSet(xTypes, E_TYPE, E_READ_UPDATE, &m_lTypes);
1380 71 : }
1381 : }
1382 :
1383 :
1384 : // c) We need all filter information ...
1385 335 : if (
1386 441 : ((eRequiredState & E_CONTAINS_FILTERS) == E_CONTAINS_FILTERS) &&
1387 106 : ((m_eFillState & E_CONTAINS_FILTERS) != E_CONTAINS_FILTERS)
1388 : )
1389 : {
1390 : // Attention! If config couldnt be opened successfully
1391 : // and exception os thrown automaticly and must be forwarded
1392 : // to our calli ...
1393 73 : css::uno::Reference< css::container::XNameAccess > xFilters(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
1394 : {
1395 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::load all filters");
1396 73 : impl_loadSet(xFilters, E_FILTER, E_READ_ALL, &m_lFilters);
1397 73 : }
1398 : }
1399 :
1400 :
1401 : // c) We need all frame loader information ...
1402 335 : if (
1403 436 : ((eRequiredState & E_CONTAINS_FRAMELOADERS) == E_CONTAINS_FRAMELOADERS) &&
1404 101 : ((m_eFillState & E_CONTAINS_FRAMELOADERS) != E_CONTAINS_FRAMELOADERS)
1405 : )
1406 : {
1407 : // Attention! If config couldnt be opened successfully
1408 : // and exception os thrown automaticly and must be forwarded
1409 : // to our calli ...
1410 68 : css::uno::Reference< css::container::XNameAccess > xLoaders(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
1411 : {
1412 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::load all frame loader");
1413 68 : impl_loadSet(xLoaders, E_FRAMELOADER, E_READ_ALL, &m_lFrameLoaders);
1414 68 : }
1415 : }
1416 :
1417 :
1418 : // d) We need all content handler information ...
1419 335 : if (
1420 385 : ((eRequiredState & E_CONTAINS_CONTENTHANDLERS) == E_CONTAINS_CONTENTHANDLERS) &&
1421 50 : ((m_eFillState & E_CONTAINS_CONTENTHANDLERS) != E_CONTAINS_CONTENTHANDLERS)
1422 : )
1423 : {
1424 : // Attention! If config couldnt be opened successfully
1425 : // and exception os thrown automaticly and must be forwarded
1426 : // to our calli ...
1427 47 : css::uno::Reference< css::container::XNameAccess > xHandlers(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
1428 : {
1429 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::load all content handler");
1430 47 : impl_loadSet(xHandlers, E_CONTENTHANDLER, E_READ_ALL, &m_lContentHandlers);
1431 47 : }
1432 : }
1433 :
1434 : // update fill state. Note: it's a bit field, which combines different parts.
1435 335 : m_eFillState = (EFillState) ((sal_Int32)m_eFillState | (sal_Int32)eRequiredState);
1436 :
1437 : // any data readed?
1438 : // yes! => validate it and update optimized structures.
1439 335 : impl_validateAndOptimize();
1440 :
1441 : // <- SAFE
1442 335 : }
1443 :
1444 :
1445 :
1446 334 : void FilterCache::impl_loadSet(const css::uno::Reference< css::container::XNameAccess >& xConfig,
1447 : EItemType eType ,
1448 : EReadOption eOption,
1449 : CacheItemList* pCache )
1450 : throw(css::uno::Exception)
1451 : {
1452 : // get access to the right configuration set
1453 334 : OUString sSetName;
1454 334 : switch(eType)
1455 : {
1456 : case E_TYPE :
1457 146 : sSetName = CFGSET_TYPES;
1458 146 : break;
1459 :
1460 : case E_FILTER :
1461 73 : sSetName = CFGSET_FILTERS;
1462 73 : break;
1463 :
1464 : case E_FRAMELOADER :
1465 68 : sSetName = CFGSET_FRAMELOADERS;
1466 68 : break;
1467 :
1468 : case E_CONTENTHANDLER :
1469 47 : sSetName = CFGSET_CONTENTHANDLERS;
1470 47 : break;
1471 0 : default: break;
1472 : }
1473 :
1474 334 : css::uno::Reference< css::container::XNameAccess > xSet;
1475 668 : css::uno::Sequence< OUString > lItems;
1476 :
1477 : try
1478 : {
1479 334 : css::uno::Any aVal = xConfig->getByName(sSetName);
1480 334 : if (!(aVal >>= xSet) || !xSet.is())
1481 : {
1482 0 : OUString sMsg("Could not open configuration set \"" + sSetName + "\".");
1483 0 : throw css::uno::Exception(sMsg, css::uno::Reference< css::uno::XInterface >());
1484 : }
1485 334 : lItems = xSet->getElementNames();
1486 : }
1487 0 : catch(const css::uno::Exception& ex)
1488 : {
1489 : throw css::document::CorruptedFilterConfigurationException(
1490 0 : "filter configuration, caught: " + ex.Message,
1491 : css::uno::Reference< css::uno::XInterface >(),
1492 0 : ex.Message);
1493 : }
1494 :
1495 : // get names of all existing sub items of this set
1496 : // step over it and fill internal cache structures.
1497 :
1498 : // But dont update optimized structures like e.g. hash
1499 : // for mapping extensions to its types!
1500 :
1501 334 : const OUString* pItems = lItems.getConstArray();
1502 334 : sal_Int32 c = lItems.getLength();
1503 41215 : for (sal_Int32 i=0; i<c; ++i)
1504 : {
1505 40881 : CacheItemList::iterator pItem = pCache->find(pItems[i]);
1506 40881 : switch(eOption)
1507 : {
1508 : // a) read a standard set of properties only or read all
1509 : case E_READ_STANDARD :
1510 : case E_READ_ALL :
1511 : {
1512 : try
1513 : {
1514 29308 : (*pCache)[pItems[i]] = impl_loadItem(xSet, eType, pItems[i], eOption);
1515 : }
1516 0 : catch(const css::uno::Exception& ex)
1517 : {
1518 : throw css::document::CorruptedFilterConfigurationException(
1519 0 : "filter configuration, caught: " + ex.Message,
1520 : css::uno::Reference< css::uno::XInterface >(),
1521 0 : ex.Message);
1522 : }
1523 : }
1524 29308 : break;
1525 :
1526 : // b) read optional properties only!
1527 : // All items must already exist inside our cache.
1528 : // But they must be updated.
1529 : case E_READ_UPDATE :
1530 : {
1531 11573 : if (pItem == pCache->end())
1532 : {
1533 0 : OUString sMsg("item \"" + pItems[i] + "\" not found for update!");
1534 0 : throw css::uno::Exception(sMsg, css::uno::Reference< css::uno::XInterface >());
1535 : }
1536 : try
1537 : {
1538 11573 : CacheItem aItem = impl_loadItem(xSet, eType, pItems[i], eOption);
1539 11573 : pItem->second.update(aItem);
1540 : }
1541 0 : catch(const css::uno::Exception& ex)
1542 : {
1543 : throw css::document::CorruptedFilterConfigurationException(
1544 0 : "filter configuration, caught: " + ex.Message,
1545 : css::uno::Reference< css::uno::XInterface >(),
1546 0 : ex.Message);
1547 : }
1548 : }
1549 11573 : break;
1550 0 : default: break;
1551 : }
1552 334 : }
1553 334 : }
1554 :
1555 :
1556 :
1557 28290 : void FilterCache::impl_readPatchUINames(const css::uno::Reference< css::container::XNameAccess >& xNode,
1558 : CacheItem& rItem)
1559 : throw(css::uno::Exception)
1560 : {
1561 :
1562 : // SAFE -> ----------------------------------
1563 28290 : ::osl::ResettableMutexGuard aLock(m_aLock);
1564 53940 : OUString sActLocale = m_sActLocale ;
1565 28290 : aLock.clear();
1566 : // <- SAFE ----------------------------------
1567 :
1568 53940 : css::uno::Any aVal = xNode->getByName(PROPNAME_UINAME);
1569 53940 : css::uno::Reference< css::container::XNameAccess > xUIName;
1570 28290 : if (!(aVal >>= xUIName) && !xUIName.is())
1571 0 : return;
1572 :
1573 53940 : const ::comphelper::SequenceAsVector< OUString > lLocales(xUIName->getElementNames());
1574 28290 : ::comphelper::SequenceAsVector< OUString >::const_iterator pLocale ;
1575 53940 : ::comphelper::SequenceAsHashMap lUINames;
1576 :
1577 161820 : for ( pLocale = lLocales.begin();
1578 107880 : pLocale != lLocales.end() ;
1579 : ++pLocale )
1580 : {
1581 25650 : const OUString& sLocale = *pLocale;
1582 :
1583 25650 : OUString sValue;
1584 25650 : xUIName->getByName(sLocale) >>= sValue;
1585 :
1586 25650 : lUINames[sLocale] <<= sValue;
1587 25650 : }
1588 :
1589 28290 : aVal <<= lUINames.getAsConstPropertyValueList();
1590 28290 : rItem[PROPNAME_UINAMES] = aVal;
1591 :
1592 : // find right UIName for current office locale
1593 : // Use fallbacks too!
1594 28290 : pLocale = LanguageTag::getFallback(lLocales, sActLocale);
1595 28290 : if (pLocale == lLocales.end())
1596 : {
1597 : #if OSL_DEBUG_LEVEL > 0
1598 : if ( sActLocale == "en-US" )
1599 : return;
1600 : OUString sName = rItem.getUnpackedValueOrDefault(PROPNAME_NAME, OUString());
1601 :
1602 : OUString sMsg("Fallback scenario for filter or type '" + sName + "' and locale '" +
1603 : sActLocale + "' failed. Please check your filter configuration.");
1604 :
1605 : OSL_FAIL(_FILTER_CONFIG_TO_ASCII_(sMsg));
1606 : #endif
1607 2640 : return;
1608 : }
1609 :
1610 25650 : const OUString& sLocale = *pLocale;
1611 25650 : ::comphelper::SequenceAsHashMap::const_iterator pUIName = lUINames.find(sLocale);
1612 25650 : if (pUIName != lUINames.end())
1613 51300 : rItem[PROPNAME_UINAME] = pUIName->second;
1614 : }
1615 :
1616 :
1617 :
1618 0 : void FilterCache::impl_savePatchUINames(const css::uno::Reference< css::container::XNameReplace >& xNode,
1619 : const CacheItem& rItem)
1620 : throw(css::uno::Exception)
1621 : {
1622 0 : css::uno::Reference< css::container::XNameContainer > xAdd (xNode, css::uno::UNO_QUERY);
1623 0 : css::uno::Reference< css::container::XNameAccess > xCheck(xNode, css::uno::UNO_QUERY);
1624 :
1625 0 : css::uno::Sequence< css::beans::PropertyValue > lUINames = rItem.getUnpackedValueOrDefault(PROPNAME_UINAMES, css::uno::Sequence< css::beans::PropertyValue >());
1626 0 : sal_Int32 c = lUINames.getLength();
1627 0 : const css::beans::PropertyValue* pUINames = lUINames.getConstArray();
1628 :
1629 0 : for (sal_Int32 i=0; i<c; ++i)
1630 : {
1631 0 : if (xCheck->hasByName(pUINames[i].Name))
1632 0 : xNode->replaceByName(pUINames[i].Name, pUINames[i].Value);
1633 : else
1634 0 : xAdd->insertByName(pUINames[i].Name, pUINames[i].Value);
1635 0 : }
1636 0 : }
1637 :
1638 : /*-----------------------------------------------
1639 : TODO
1640 : clarify, how the real problem behind the
1641 : wrong constructed CacheItem instance (which
1642 : will force a crash during destruction)
1643 : can be solved ...
1644 : -----------------------------------------------*/
1645 40881 : CacheItem FilterCache::impl_loadItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
1646 : EItemType eType ,
1647 : const OUString& sItem ,
1648 : EReadOption eOption)
1649 : throw(css::uno::Exception)
1650 : {
1651 : // try to get an API object, which points directly to the
1652 : // requested item. If it fail an exception should occur and
1653 : // break this operation. Of course returned API object must be
1654 : // checked too.
1655 40881 : css::uno::Reference< css::container::XNameAccess > xItem;
1656 : #ifdef WORKAROUND_EXCEPTION_PROBLEM
1657 : try
1658 : {
1659 : #endif
1660 40881 : css::uno::Any aVal = xSet->getByName(sItem);
1661 40881 : if (!(aVal >>= xItem) || !xItem.is())
1662 : {
1663 0 : OUString sMsg("found corrupted item \"" + sItem + "\".");
1664 0 : throw css::uno::Exception(sMsg, css::uno::Reference< css::uno::XInterface >());
1665 40881 : }
1666 : #ifdef WORKAROUND_EXCEPTION_PROBLEM
1667 : }
1668 0 : catch(const css::container::NoSuchElementException&)
1669 : {
1670 0 : throw;
1671 : }
1672 : #endif
1673 :
1674 : // The internal name of an item must(!) be part of the property
1675 : // set too. Of course its already used as key into the e.g. outside
1676 : // used hash map ... but some of our API methods provide
1677 : // this property set as result only. But the user of this CacheItem
1678 : // should know, which value the key names has :-) ITS IMPORTANT!
1679 40881 : CacheItem aItem;
1680 40881 : aItem[PROPNAME_NAME] = css::uno::makeAny(sItem);
1681 40881 : switch(eType)
1682 : {
1683 :
1684 : case E_TYPE :
1685 : {
1686 : // read standard properties of a type
1687 23798 : if (
1688 11573 : (eOption == E_READ_STANDARD) ||
1689 : (eOption == E_READ_ALL )
1690 : )
1691 : {
1692 12225 : aItem[PROPNAME_PREFERREDFILTER] = xItem->getByName(PROPNAME_PREFERREDFILTER);
1693 12225 : aItem[PROPNAME_DETECTSERVICE ] = xItem->getByName(PROPNAME_DETECTSERVICE );
1694 12225 : aItem[PROPNAME_URLPATTERN ] = xItem->getByName(PROPNAME_URLPATTERN );
1695 12225 : aItem[PROPNAME_EXTENSIONS ] = xItem->getByName(PROPNAME_EXTENSIONS );
1696 12225 : aItem[PROPNAME_PREFERRED ] = xItem->getByName(PROPNAME_PREFERRED );
1697 12225 : aItem[PROPNAME_CLIPBOARDFORMAT] = xItem->getByName(PROPNAME_CLIPBOARDFORMAT);
1698 : }
1699 : // read optional properties of a type
1700 : // no else here! Is an additional switch ...
1701 23798 : if (
1702 12225 : (eOption == E_READ_UPDATE) ||
1703 : (eOption == E_READ_ALL )
1704 : )
1705 : {
1706 11573 : aItem[PROPNAME_MEDIATYPE ] = xItem->getByName(PROPNAME_MEDIATYPE );
1707 11573 : impl_readPatchUINames(xItem, aItem);
1708 : }
1709 : }
1710 23798 : break;
1711 :
1712 :
1713 : case E_FILTER :
1714 : {
1715 : // read standard properties of a filter
1716 16717 : if (
1717 16717 : (eOption == E_READ_STANDARD) ||
1718 : (eOption == E_READ_ALL )
1719 : )
1720 : {
1721 16717 : aItem[PROPNAME_TYPE ] = xItem->getByName(PROPNAME_TYPE );
1722 16717 : aItem[PROPNAME_FILEFORMATVERSION] = xItem->getByName(PROPNAME_FILEFORMATVERSION);
1723 16717 : aItem[PROPNAME_UICOMPONENT ] = xItem->getByName(PROPNAME_UICOMPONENT );
1724 16717 : aItem[PROPNAME_FILTERSERVICE ] = xItem->getByName(PROPNAME_FILTERSERVICE );
1725 16717 : aItem[PROPNAME_DOCUMENTSERVICE ] = xItem->getByName(PROPNAME_DOCUMENTSERVICE );
1726 16717 : aItem[PROPNAME_EXPORTEXTENSION ] = xItem->getByName(PROPNAME_EXPORTEXTENSION );
1727 :
1728 : // special handling for flags! Convert it from a list of names to its
1729 : // int representation ...
1730 16717 : css::uno::Sequence< OUString > lFlagNames;
1731 16717 : if (xItem->getByName(PROPNAME_FLAGS) >>= lFlagNames)
1732 16717 : aItem[PROPNAME_FLAGS] <<= FilterCache::impl_convertFlagNames2FlagField(lFlagNames);
1733 : }
1734 : // read optional properties of a filter
1735 : // no else here! Is an additional switch ...
1736 16717 : if (
1737 16717 : (eOption == E_READ_UPDATE) ||
1738 : (eOption == E_READ_ALL )
1739 : )
1740 : {
1741 16717 : aItem[PROPNAME_USERDATA ] = xItem->getByName(PROPNAME_USERDATA );
1742 16717 : aItem[PROPNAME_TEMPLATENAME] = xItem->getByName(PROPNAME_TEMPLATENAME);
1743 : //TODO remove it if moving of filter uinames to type uinames
1744 : // will be finished really
1745 : #ifdef AS_ENABLE_FILTER_UINAMES
1746 16717 : impl_readPatchUINames(xItem, aItem);
1747 : #endif // AS_ENABLE_FILTER_UINAMES
1748 : }
1749 : }
1750 16717 : break;
1751 :
1752 :
1753 : case E_FRAMELOADER :
1754 : case E_CONTENTHANDLER :
1755 : {
1756 366 : aItem[PROPNAME_TYPES] = xItem->getByName(PROPNAME_TYPES);
1757 : }
1758 366 : break;
1759 0 : default: break;
1760 : }
1761 :
1762 40881 : return aItem;
1763 : }
1764 :
1765 :
1766 :
1767 1185 : CacheItemList::iterator FilterCache::impl_loadItemOnDemand( EItemType eType,
1768 : const OUString& sItem)
1769 : throw(css::uno::Exception)
1770 : {
1771 1185 : CacheItemList* pList = 0;
1772 1185 : css::uno::Reference< css::uno::XInterface > xConfig ;
1773 2370 : OUString sSet ;
1774 :
1775 1185 : switch(eType)
1776 : {
1777 : case E_TYPE :
1778 : {
1779 1162 : pList = &m_lTypes;
1780 1162 : xConfig = impl_openConfig(E_PROVIDER_TYPES);
1781 1162 : sSet = CFGSET_TYPES;
1782 : }
1783 1162 : break;
1784 :
1785 : case E_FILTER :
1786 : {
1787 19 : pList = &m_lFilters;
1788 19 : xConfig = impl_openConfig(E_PROVIDER_FILTERS);
1789 19 : sSet = CFGSET_FILTERS;
1790 : }
1791 19 : break;
1792 :
1793 : case E_FRAMELOADER :
1794 : {
1795 2 : pList = &m_lFrameLoaders;
1796 2 : xConfig = impl_openConfig(E_PROVIDER_OTHERS);
1797 2 : sSet = CFGSET_FRAMELOADERS;
1798 : }
1799 2 : break;
1800 :
1801 : case E_CONTENTHANDLER :
1802 : {
1803 2 : pList = &m_lContentHandlers;
1804 2 : xConfig = impl_openConfig(E_PROVIDER_OTHERS);
1805 2 : sSet = CFGSET_CONTENTHANDLERS;
1806 : }
1807 2 : break;
1808 :
1809 : case E_DETECTSERVICE :
1810 : {
1811 : SAL_WARN( "filter.config", "Cant load detect services on demand. Who use this unsupported feature?");
1812 : }
1813 0 : break;
1814 : }
1815 :
1816 1185 : if (!pList)
1817 0 : throw css::container::NoSuchElementException();
1818 :
1819 1185 : css::uno::Reference< css::container::XNameAccess > xRoot(xConfig, css::uno::UNO_QUERY_THROW);
1820 2370 : css::uno::Reference< css::container::XNameAccess > xSet ;
1821 1185 : xRoot->getByName(sSet) >>= xSet;
1822 :
1823 1185 : CacheItemList::iterator pItemInCache = pList->find(sItem);
1824 1185 : sal_Bool bItemInConfig = xSet->hasByName(sItem);
1825 :
1826 1185 : if (bItemInConfig)
1827 : {
1828 0 : (*pList)[sItem] = impl_loadItem(xSet, eType, sItem, E_READ_ALL);
1829 : _FILTER_CONFIG_LOG_2_("impl_loadItemOnDemand(%d, \"%s\") ... OK", (int)eType, _FILTER_CONFIG_TO_ASCII_(sItem).getStr())
1830 : }
1831 : else
1832 : {
1833 1185 : if (pItemInCache != pList->end())
1834 0 : pList->erase(pItemInCache);
1835 : // OK - this item does not exists inside configuration.
1836 : // And we already updated our internal cache.
1837 : // But the outside code needs this NoSuchElementException
1838 : // to know, that this item does notexists.
1839 : // Nobody checks the iterator!
1840 1185 : throw css::container::NoSuchElementException();
1841 : }
1842 :
1843 2370 : return pList->find(sItem);
1844 : }
1845 :
1846 :
1847 :
1848 0 : void FilterCache::impl_saveItem(const css::uno::Reference< css::container::XNameReplace >& xItem,
1849 : EItemType eType,
1850 : const CacheItem& aItem)
1851 : throw(css::uno::Exception)
1852 : {
1853 0 : CacheItem::const_iterator pIt;
1854 0 : switch(eType)
1855 : {
1856 :
1857 : case E_TYPE :
1858 : {
1859 0 : pIt = aItem.find(PROPNAME_PREFERREDFILTER);
1860 0 : if (pIt != aItem.end())
1861 0 : xItem->replaceByName(PROPNAME_PREFERREDFILTER, pIt->second);
1862 0 : pIt = aItem.find(PROPNAME_DETECTSERVICE);
1863 0 : if (pIt != aItem.end())
1864 0 : xItem->replaceByName(PROPNAME_DETECTSERVICE, pIt->second);
1865 0 : pIt = aItem.find(PROPNAME_URLPATTERN);
1866 0 : if (pIt != aItem.end())
1867 0 : xItem->replaceByName(PROPNAME_URLPATTERN, pIt->second);
1868 0 : pIt = aItem.find(PROPNAME_EXTENSIONS);
1869 0 : if (pIt != aItem.end())
1870 0 : xItem->replaceByName(PROPNAME_EXTENSIONS, pIt->second);
1871 0 : pIt = aItem.find(PROPNAME_PREFERRED);
1872 0 : if (pIt != aItem.end())
1873 0 : xItem->replaceByName(PROPNAME_PREFERRED, pIt->second);
1874 0 : pIt = aItem.find(PROPNAME_MEDIATYPE);
1875 0 : if (pIt != aItem.end())
1876 0 : xItem->replaceByName(PROPNAME_MEDIATYPE, pIt->second);
1877 0 : pIt = aItem.find(PROPNAME_CLIPBOARDFORMAT);
1878 0 : if (pIt != aItem.end())
1879 0 : xItem->replaceByName(PROPNAME_CLIPBOARDFORMAT, pIt->second);
1880 :
1881 0 : css::uno::Reference< css::container::XNameReplace > xUIName;
1882 0 : xItem->getByName(PROPNAME_UINAME) >>= xUIName;
1883 0 : impl_savePatchUINames(xUIName, aItem);
1884 : }
1885 0 : break;
1886 :
1887 :
1888 : case E_FILTER :
1889 : {
1890 0 : pIt = aItem.find(PROPNAME_TYPE);
1891 0 : if (pIt != aItem.end())
1892 0 : xItem->replaceByName(PROPNAME_TYPE, pIt->second);
1893 0 : pIt = aItem.find(PROPNAME_FILEFORMATVERSION);
1894 0 : if (pIt != aItem.end())
1895 0 : xItem->replaceByName(PROPNAME_FILEFORMATVERSION, pIt->second);
1896 0 : pIt = aItem.find(PROPNAME_UICOMPONENT);
1897 0 : if (pIt != aItem.end())
1898 0 : xItem->replaceByName(PROPNAME_UICOMPONENT, pIt->second);
1899 0 : pIt = aItem.find(PROPNAME_FILTERSERVICE);
1900 0 : if (pIt != aItem.end())
1901 0 : xItem->replaceByName(PROPNAME_FILTERSERVICE, pIt->second);
1902 0 : pIt = aItem.find(PROPNAME_DOCUMENTSERVICE);
1903 0 : if (pIt != aItem.end())
1904 0 : xItem->replaceByName(PROPNAME_DOCUMENTSERVICE, pIt->second);
1905 0 : pIt = aItem.find(PROPNAME_USERDATA);
1906 0 : if (pIt != aItem.end())
1907 0 : xItem->replaceByName(PROPNAME_USERDATA, pIt->second);
1908 0 : pIt = aItem.find(PROPNAME_TEMPLATENAME);
1909 0 : if (pIt != aItem.end())
1910 0 : xItem->replaceByName(PROPNAME_TEMPLATENAME, pIt->second);
1911 :
1912 : // special handling for flags! Convert it from an integer flag field back
1913 : // to a list of names ...
1914 : // But note: because we work directly on a reference to the cache item,
1915 : // its not allowd to change the value here. We must work on a copy!
1916 0 : pIt = aItem.find(PROPNAME_FLAGS);
1917 0 : if (pIt != aItem.end())
1918 : {
1919 0 : sal_Int32 nFlags = 0;
1920 0 : pIt->second >>= nFlags;
1921 0 : css::uno::Any aFlagNameList;
1922 0 : aFlagNameList <<= FilterCache::impl_convertFlagField2FlagNames(nFlags);
1923 0 : xItem->replaceByName(PROPNAME_FLAGS, aFlagNameList);
1924 : }
1925 :
1926 : //TODO remove it if moving of filter uinames to type uinames
1927 : // will be finished really
1928 : #ifdef AS_ENABLE_FILTER_UINAMES
1929 0 : css::uno::Reference< css::container::XNameReplace > xUIName;
1930 0 : xItem->getByName(PROPNAME_UINAME) >>= xUIName;
1931 0 : impl_savePatchUINames(xUIName, aItem);
1932 : #endif // AS_ENABLE_FILTER_UINAMES
1933 : }
1934 0 : break;
1935 :
1936 :
1937 : case E_FRAMELOADER :
1938 : case E_CONTENTHANDLER :
1939 : {
1940 0 : pIt = aItem.find(PROPNAME_TYPES);
1941 0 : if (pIt != aItem.end())
1942 0 : xItem->replaceByName(PROPNAME_TYPES, pIt->second);
1943 : }
1944 0 : break;
1945 0 : default: break;
1946 : }
1947 0 : }
1948 :
1949 : /*-----------------------------------------------
1950 : static! => no locks necessary
1951 : -----------------------------------------------*/
1952 0 : css::uno::Sequence< OUString > FilterCache::impl_convertFlagField2FlagNames(sal_Int32 nFlags)
1953 : {
1954 0 : OUStringList lFlagNames;
1955 :
1956 0 : if ((nFlags & FLAGVAL_3RDPARTYFILTER ) == FLAGVAL_3RDPARTYFILTER ) lFlagNames.push_back(FLAGNAME_3RDPARTYFILTER );
1957 0 : if ((nFlags & FLAGVAL_ALIEN ) == FLAGVAL_ALIEN ) lFlagNames.push_back(FLAGNAME_ALIEN );
1958 0 : if ((nFlags & FLAGVAL_ASYNCHRON ) == FLAGVAL_ASYNCHRON ) lFlagNames.push_back(FLAGNAME_ASYNCHRON );
1959 0 : if ((nFlags & FLAGVAL_BROWSERPREFERRED ) == FLAGVAL_BROWSERPREFERRED ) lFlagNames.push_back(FLAGNAME_BROWSERPREFERRED );
1960 0 : if ((nFlags & FLAGVAL_CONSULTSERVICE ) == FLAGVAL_CONSULTSERVICE ) lFlagNames.push_back(FLAGNAME_CONSULTSERVICE );
1961 0 : if ((nFlags & FLAGVAL_DEFAULT ) == FLAGVAL_DEFAULT ) lFlagNames.push_back(FLAGNAME_DEFAULT );
1962 0 : if ((nFlags & FLAGVAL_ENCRYPTION ) == FLAGVAL_ENCRYPTION ) lFlagNames.push_back(FLAGNAME_ENCRYPTION );
1963 0 : if ((nFlags & FLAGVAL_EXPORT ) == FLAGVAL_EXPORT ) lFlagNames.push_back(FLAGNAME_EXPORT );
1964 0 : if ((nFlags & FLAGVAL_IMPORT ) == FLAGVAL_IMPORT ) lFlagNames.push_back(FLAGNAME_IMPORT );
1965 0 : if ((nFlags & FLAGVAL_INTERNAL ) == FLAGVAL_INTERNAL ) lFlagNames.push_back(FLAGNAME_INTERNAL );
1966 0 : if ((nFlags & FLAGVAL_NOTINCHOOSER ) == FLAGVAL_NOTINCHOOSER ) lFlagNames.push_back(FLAGNAME_NOTINCHOOSER );
1967 0 : if ((nFlags & FLAGVAL_NOTINFILEDIALOG ) == FLAGVAL_NOTINFILEDIALOG ) lFlagNames.push_back(FLAGNAME_NOTINFILEDIALOG );
1968 0 : if ((nFlags & FLAGVAL_NOTINSTALLED ) == FLAGVAL_NOTINSTALLED ) lFlagNames.push_back(FLAGNAME_NOTINSTALLED );
1969 0 : if ((nFlags & FLAGVAL_OWN ) == FLAGVAL_OWN ) lFlagNames.push_back(FLAGNAME_OWN );
1970 0 : if ((nFlags & FLAGVAL_PACKED ) == FLAGVAL_PACKED ) lFlagNames.push_back(FLAGNAME_PACKED );
1971 0 : if ((nFlags & FLAGVAL_PASSWORDTOMODIFY ) == FLAGVAL_PASSWORDTOMODIFY ) lFlagNames.push_back(FLAGNAME_PASSWORDTOMODIFY );
1972 0 : if ((nFlags & FLAGVAL_PREFERRED ) == FLAGVAL_PREFERRED ) lFlagNames.push_back(FLAGNAME_PREFERRED );
1973 0 : if ((nFlags & FLAGVAL_STARTPRESENTATION) == FLAGVAL_STARTPRESENTATION) lFlagNames.push_back(FLAGNAME_STARTPRESENTATION);
1974 0 : if ((nFlags & FLAGVAL_READONLY ) == FLAGVAL_READONLY ) lFlagNames.push_back(FLAGNAME_READONLY );
1975 0 : if ((nFlags & FLAGVAL_SUPPORTSSELECTION) == FLAGVAL_SUPPORTSSELECTION) lFlagNames.push_back(FLAGNAME_SUPPORTSSELECTION);
1976 0 : if ((nFlags & FLAGVAL_TEMPLATE ) == FLAGVAL_TEMPLATE ) lFlagNames.push_back(FLAGNAME_TEMPLATE );
1977 0 : if ((nFlags & FLAGVAL_TEMPLATEPATH ) == FLAGVAL_TEMPLATEPATH ) lFlagNames.push_back(FLAGNAME_TEMPLATEPATH );
1978 0 : if ((nFlags & FLAGVAL_USESOPTIONS ) == FLAGVAL_USESOPTIONS ) lFlagNames.push_back(FLAGNAME_USESOPTIONS );
1979 0 : if ((nFlags & FLAGVAL_COMBINED ) == FLAGVAL_COMBINED ) lFlagNames.push_back(FLAGNAME_COMBINED );
1980 :
1981 0 : return lFlagNames.getAsConstList();
1982 : }
1983 :
1984 : /*-----------------------------------------------
1985 : static! => no locks necessary
1986 : -----------------------------------------------*/
1987 16717 : sal_Int32 FilterCache::impl_convertFlagNames2FlagField(const css::uno::Sequence< OUString >& lNames)
1988 : {
1989 16717 : sal_Int32 nField = 0;
1990 :
1991 16717 : const OUString* pNames = lNames.getConstArray();
1992 16717 : sal_Int32 c = lNames.getLength();
1993 85556 : for (sal_Int32 i=0; i<c; ++i)
1994 : {
1995 68839 : if (pNames[i].equals(FLAGNAME_3RDPARTYFILTER))
1996 : {
1997 7227 : nField |= FLAGVAL_3RDPARTYFILTER;
1998 7227 : continue;
1999 : }
2000 61612 : if (pNames[i].equals(FLAGNAME_ALIEN))
2001 : {
2002 14892 : nField |= FLAGVAL_ALIEN;
2003 14892 : continue;
2004 : }
2005 46720 : if (pNames[i].equals(FLAGNAME_ASYNCHRON))
2006 : {
2007 292 : nField |= FLAGVAL_ASYNCHRON;
2008 292 : continue;
2009 : }
2010 46428 : if (pNames[i].equals(FLAGNAME_BROWSERPREFERRED))
2011 : {
2012 0 : nField |= FLAGVAL_BROWSERPREFERRED;
2013 0 : continue;
2014 : }
2015 46428 : if (pNames[i].equals(FLAGNAME_CONSULTSERVICE))
2016 : {
2017 0 : nField |= FLAGVAL_CONSULTSERVICE;
2018 0 : continue;
2019 : }
2020 46428 : if (pNames[i].equals(FLAGNAME_DEFAULT))
2021 : {
2022 730 : nField |= FLAGVAL_DEFAULT;
2023 730 : continue;
2024 : }
2025 45698 : if (pNames[i].equals(FLAGNAME_ENCRYPTION))
2026 : {
2027 3139 : nField |= FLAGVAL_ENCRYPTION;
2028 3139 : continue;
2029 : }
2030 42559 : if (pNames[i].equals(FLAGNAME_EXPORT))
2031 : {
2032 8322 : nField |= FLAGVAL_EXPORT;
2033 8322 : continue;
2034 : }
2035 34237 : if (pNames[i].equals(FLAGNAME_IMPORT))
2036 : {
2037 12483 : nField |= FLAGVAL_IMPORT;
2038 12483 : continue;
2039 : }
2040 21754 : if (pNames[i].equals(FLAGNAME_INTERNAL))
2041 : {
2042 73 : nField |= FLAGVAL_INTERNAL;
2043 73 : continue;
2044 : }
2045 21681 : if (pNames[i].equals(FLAGNAME_NOTINCHOOSER))
2046 : {
2047 730 : nField |= FLAGVAL_NOTINCHOOSER;
2048 730 : continue;
2049 : }
2050 20951 : if (pNames[i].equals(FLAGNAME_NOTINFILEDIALOG))
2051 : {
2052 657 : nField |= FLAGVAL_NOTINFILEDIALOG;
2053 657 : continue;
2054 : }
2055 20294 : if (pNames[i].equals(FLAGNAME_NOTINSTALLED))
2056 : {
2057 0 : nField |= FLAGVAL_NOTINSTALLED;
2058 0 : continue;
2059 : }
2060 20294 : if (pNames[i].equals(FLAGNAME_OWN))
2061 : {
2062 2409 : nField |= FLAGVAL_OWN;
2063 2409 : continue;
2064 : }
2065 17885 : if (pNames[i].equals(FLAGNAME_PACKED))
2066 : {
2067 0 : nField |= FLAGVAL_PACKED;
2068 0 : continue;
2069 : }
2070 17885 : if (pNames[i].equals(FLAGNAME_PASSWORDTOMODIFY))
2071 : {
2072 1460 : nField |= FLAGVAL_PASSWORDTOMODIFY;
2073 1460 : continue;
2074 : }
2075 16425 : if (pNames[i].equals(FLAGNAME_PREFERRED))
2076 : {
2077 5402 : nField |= FLAGVAL_PREFERRED;
2078 5402 : continue;
2079 : }
2080 11023 : if (pNames[i].equals(FLAGNAME_STARTPRESENTATION))
2081 : {
2082 219 : nField |= FLAGVAL_STARTPRESENTATION;
2083 219 : continue;
2084 : }
2085 10804 : if (pNames[i].equals(FLAGNAME_READONLY))
2086 : {
2087 73 : nField |= FLAGVAL_READONLY;
2088 73 : continue;
2089 : }
2090 10731 : if (pNames[i].equals(FLAGNAME_SUPPORTSSELECTION))
2091 : {
2092 2336 : nField |= FLAGVAL_SUPPORTSSELECTION;
2093 2336 : continue;
2094 : }
2095 8395 : if (pNames[i].equals(FLAGNAME_TEMPLATE))
2096 : {
2097 3066 : nField |= FLAGVAL_TEMPLATE;
2098 3066 : continue;
2099 : }
2100 5329 : if (pNames[i].equals(FLAGNAME_TEMPLATEPATH))
2101 : {
2102 1679 : nField |= FLAGVAL_TEMPLATEPATH;
2103 1679 : continue;
2104 : }
2105 3650 : if (pNames[i].equals(FLAGNAME_USESOPTIONS))
2106 : {
2107 3504 : nField |= FLAGVAL_USESOPTIONS;
2108 3504 : continue;
2109 : }
2110 146 : if (pNames[i].equals(FLAGNAME_COMBINED))
2111 : {
2112 0 : nField |= FLAGVAL_COMBINED;
2113 0 : continue;
2114 : }
2115 : }
2116 :
2117 16717 : return nField;
2118 : }
2119 :
2120 :
2121 :
2122 0 : void FilterCache::impl_interpretDataVal4Type(const OUString& sValue,
2123 : sal_Int32 nProp ,
2124 : CacheItem& rItem )
2125 : {
2126 0 : switch(nProp)
2127 : {
2128 : // Preferred
2129 : case 0: {
2130 0 : if (sValue.toInt32() == 1)
2131 0 : rItem[PROPNAME_PREFERRED] = css::uno::makeAny(sal_True);
2132 : else
2133 0 : rItem[PROPNAME_PREFERRED] = css::uno::makeAny(sal_False);
2134 : }
2135 0 : break;
2136 : // MediaType
2137 0 : case 1: rItem[PROPNAME_MEDIATYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2138 0 : break;
2139 : // ClipboardFormat
2140 0 : case 2: rItem[PROPNAME_CLIPBOARDFORMAT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2141 0 : break;
2142 : // URLPattern
2143 0 : case 3: rItem[PROPNAME_URLPATTERN] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2144 0 : break;
2145 : // Extensions
2146 0 : case 4: rItem[PROPNAME_EXTENSIONS] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2147 0 : break;
2148 : }
2149 0 : }
2150 :
2151 :
2152 :
2153 0 : void FilterCache::impl_interpretDataVal4Filter(const OUString& sValue,
2154 : sal_Int32 nProp ,
2155 : CacheItem& rItem )
2156 : {
2157 0 : switch(nProp)
2158 : {
2159 : // Order
2160 : case 0: {
2161 0 : sal_Int32 nOrder = sValue.toInt32();
2162 0 : if (nOrder > 0)
2163 : {
2164 : SAL_WARN( "filter.config", "FilterCache::impl_interpretDataVal4Filter()\nCant move Order value from filter to type on demand!");
2165 : _FILTER_CONFIG_LOG_2_("impl_interpretDataVal4Filter(%d, \"%s\") ... OK", (int)eType, _FILTER_CONFIG_TO_ASCII_(rItem).getStr())
2166 : }
2167 : }
2168 0 : break;
2169 : // Type
2170 0 : case 1: rItem[PROPNAME_TYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2171 0 : break;
2172 : // DocumentService
2173 0 : case 2: rItem[PROPNAME_DOCUMENTSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2174 0 : break;
2175 : // FilterService
2176 0 : case 3: rItem[PROPNAME_FILTERSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2177 0 : break;
2178 : // Flags
2179 0 : case 4: rItem[PROPNAME_FLAGS] <<= sValue.toInt32();
2180 0 : break;
2181 : // UserData
2182 0 : case 5: rItem[PROPNAME_USERDATA] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2183 0 : break;
2184 : // FileFormatVersion
2185 0 : case 6: rItem[PROPNAME_FILEFORMATVERSION] <<= sValue.toInt32();
2186 0 : break;
2187 : // TemplateName
2188 0 : case 7: rItem[PROPNAME_TEMPLATENAME] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2189 0 : break;
2190 : // [optional!] UIComponent
2191 0 : case 8: rItem[PROPNAME_UICOMPONENT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2192 0 : break;
2193 : }
2194 0 : }
2195 :
2196 : /*-----------------------------------------------
2197 : TODO work on a cache copy first, which can be flushed afterwards
2198 : That would be useful to guarantee a consistent cache.
2199 : -----------------------------------------------*/
2200 75 : void FilterCache::impl_readOldFormat()
2201 : throw(css::uno::Exception)
2202 : {
2203 : // Attention: Opening/Reading of this old configuration format has to be handled gracefully.
2204 : // Its optional and should not disturb our normal work!
2205 : // E.g. we must check, if the package exists ...
2206 :
2207 75 : css::uno::Reference< css::container::XNameAccess > xCfg;
2208 : try
2209 : {
2210 75 : css::uno::Reference< css::uno::XInterface > xInt = impl_openConfig(E_PROVIDER_OLD);
2211 75 : xCfg = css::uno::Reference< css::container::XNameAccess >(xInt, css::uno::UNO_QUERY_THROW);
2212 : }
2213 : /* corrupt filter addon ? because it's external (optional) code .. we can ignore it. Addon wont work then ...
2214 : but that seems to be acceptable.
2215 : see #139088# for further information
2216 : */
2217 0 : catch(const css::uno::Exception&)
2218 75 : { return; }
2219 :
2220 150 : OUString TYPES_SET("Types");
2221 :
2222 : // May be there is no type set ...
2223 75 : if (xCfg->hasByName(TYPES_SET))
2224 : {
2225 75 : css::uno::Reference< css::container::XNameAccess > xSet;
2226 75 : xCfg->getByName(TYPES_SET) >>= xSet;
2227 150 : const css::uno::Sequence< OUString > lItems = xSet->getElementNames();
2228 75 : const OUString* pItems = lItems.getConstArray();
2229 75 : for (sal_Int32 i=0; i<lItems.getLength(); ++i)
2230 75 : m_lTypes[pItems[i]] = impl_readOldItem(xSet, E_TYPE, pItems[i]);
2231 : }
2232 :
2233 150 : OUString FILTER_SET("Filters");
2234 : // May be there is no filter set ...
2235 75 : if (xCfg->hasByName(FILTER_SET))
2236 : {
2237 75 : css::uno::Reference< css::container::XNameAccess > xSet;
2238 75 : xCfg->getByName(FILTER_SET) >>= xSet;
2239 150 : const css::uno::Sequence< OUString > lItems = xSet->getElementNames();
2240 75 : const OUString* pItems = lItems.getConstArray();
2241 75 : for (sal_Int32 i=0; i<lItems.getLength(); ++i)
2242 75 : m_lFilters[pItems[i]] = impl_readOldItem(xSet, E_FILTER, pItems[i]);
2243 75 : }
2244 : }
2245 :
2246 :
2247 :
2248 0 : CacheItem FilterCache::impl_readOldItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
2249 : EItemType eType,
2250 : const OUString& sItem)
2251 : throw(css::uno::Exception)
2252 : {
2253 0 : css::uno::Reference< css::container::XNameAccess > xItem;
2254 0 : xSet->getByName(sItem) >>= xItem;
2255 0 : if (!xItem.is())
2256 0 : throw css::uno::Exception("Cant read old item.", css::uno::Reference< css::uno::XInterface >());
2257 :
2258 0 : CacheItem aItem;
2259 0 : aItem[PROPNAME_NAME] <<= sItem;
2260 :
2261 : // Installed flag ...
2262 : // Isnt used any longer!
2263 :
2264 : // UIName
2265 0 : impl_readPatchUINames(xItem, aItem);
2266 :
2267 : // Data
2268 0 : OUString sData;
2269 0 : OUStringList lData;
2270 0 : xItem->getByName( "Data" ) >>= sData;
2271 0 : lData = impl_tokenizeString(sData, (sal_Unicode)',');
2272 0 : if (
2273 0 : (sData.isEmpty()) ||
2274 0 : (lData.size()<1 )
2275 : )
2276 : {
2277 0 : throw css::uno::Exception( "Cant read old item property DATA.", css::uno::Reference< css::uno::XInterface >());
2278 : }
2279 :
2280 0 : sal_Int32 nProp = 0;
2281 0 : for (OUStringList::const_iterator pProp = lData.begin();
2282 0 : pProp != lData.end() ;
2283 : ++pProp )
2284 : {
2285 0 : const OUString& sProp = *pProp;
2286 0 : switch(eType)
2287 : {
2288 : case E_TYPE :
2289 0 : impl_interpretDataVal4Type(sProp, nProp, aItem);
2290 0 : break;
2291 :
2292 : case E_FILTER :
2293 0 : impl_interpretDataVal4Filter(sProp, nProp, aItem);
2294 0 : break;
2295 0 : default: break;
2296 : }
2297 0 : ++nProp;
2298 : }
2299 :
2300 0 : return aItem;
2301 : }
2302 :
2303 :
2304 :
2305 0 : OUStringList FilterCache::impl_tokenizeString(const OUString& sData ,
2306 : sal_Unicode cSeparator)
2307 : {
2308 0 : OUStringList lData ;
2309 0 : sal_Int32 nToken = 0;
2310 0 : do
2311 : {
2312 0 : OUString sToken = sData.getToken(0, cSeparator, nToken);
2313 0 : lData.push_back(sToken);
2314 : }
2315 0 : while(nToken >= 0);
2316 0 : return lData;
2317 : }
2318 :
2319 : #if OSL_DEBUG_LEVEL > 0
2320 :
2321 :
2322 : OUString FilterCache::impl_searchFrameLoaderForType(const OUString& sType) const
2323 : {
2324 : CacheItemList::const_iterator pIt;
2325 : for ( pIt = m_lFrameLoaders.begin();
2326 : pIt != m_lFrameLoaders.end() ;
2327 : ++pIt )
2328 : {
2329 : const OUString& sItem = pIt->first;
2330 : ::comphelper::SequenceAsHashMap lProps(pIt->second);
2331 : OUStringList lTypes(lProps[PROPNAME_TYPES]);
2332 :
2333 : if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
2334 : return sItem;
2335 : }
2336 :
2337 : return OUString();
2338 : }
2339 :
2340 :
2341 :
2342 : OUString FilterCache::impl_searchContentHandlerForType(const OUString& sType) const
2343 : {
2344 : CacheItemList::const_iterator pIt;
2345 : for ( pIt = m_lContentHandlers.begin();
2346 : pIt != m_lContentHandlers.end() ;
2347 : ++pIt )
2348 : {
2349 : const OUString& sItem = pIt->first;
2350 : ::comphelper::SequenceAsHashMap lProps(pIt->second);
2351 : OUStringList lTypes(lProps[PROPNAME_TYPES]);
2352 :
2353 : if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
2354 : return sItem;
2355 : }
2356 :
2357 : return OUString();
2358 : }
2359 : #endif
2360 :
2361 :
2362 :
2363 574110 : sal_Bool FilterCache::impl_isModuleInstalled(const OUString& sModule)
2364 : {
2365 574110 : css::uno::Reference< css::container::XNameAccess > xCfg;
2366 :
2367 : // SAFE ->
2368 1148220 : ::osl::ResettableMutexGuard aLock(m_aLock);
2369 574110 : if (! m_xModuleCfg.is())
2370 : {
2371 73 : m_xModuleCfg = officecfg::Setup::Office::Factories::get();
2372 : }
2373 :
2374 574110 : xCfg = m_xModuleCfg;
2375 574110 : aLock.clear();
2376 : // <- SAFE
2377 :
2378 574110 : if (xCfg.is())
2379 574110 : return xCfg->hasByName(sModule);
2380 :
2381 574110 : return sal_False;
2382 : }
2383 :
2384 : } // namespace config
2385 : } // namespace filter
2386 :
2387 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|