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