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/sequenceasvector.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 182 : FilterCache::FilterCache()
60 : : BaseLock ( )
61 182 : , m_eFillState(E_CONTAINS_NOTHING )
62 : {
63 182 : int i = 0;
64 1820 : OUString sStandardProps[9];
65 :
66 182 : sStandardProps[i++] = PROPNAME_USERDATA;
67 182 : sStandardProps[i++] = PROPNAME_TEMPLATENAME;
68 : // E_READ_UPDATE only above
69 182 : sStandardProps[i++] = PROPNAME_TYPE;
70 182 : sStandardProps[i++] = PROPNAME_FILEFORMATVERSION;
71 182 : sStandardProps[i++] = PROPNAME_UICOMPONENT;
72 182 : sStandardProps[i++] = PROPNAME_FILTERSERVICE;
73 182 : sStandardProps[i++] = PROPNAME_DOCUMENTSERVICE;
74 182 : sStandardProps[i++] = PROPNAME_EXPORTEXTENSION;
75 182 : sStandardProps[i++] = PROPNAME_FLAGS; // must be last.
76 : assert(i == SAL_N_ELEMENTS(sStandardProps));
77 :
78 : // E_READ_NOTHING -> creative nothingness.
79 364 : m_aStandardProps[E_READ_STANDARD] =
80 182 : css::uno::Sequence< OUString >(sStandardProps + 2, 7);
81 364 : m_aStandardProps[E_READ_UPDATE] =
82 182 : css::uno::Sequence< OUString >(sStandardProps, 2);
83 364 : m_aStandardProps[E_READ_ALL] =
84 : css::uno::Sequence< OUString >(sStandardProps,
85 182 : SAL_N_ELEMENTS(sStandardProps));
86 :
87 182 : i = 0;
88 364 : OUString sTypeProps[7];
89 182 : sTypeProps[i++] = PROPNAME_MEDIATYPE;
90 : // E_READ_UPDATE only above
91 182 : sTypeProps[i++] = PROPNAME_PREFERREDFILTER;
92 182 : sTypeProps[i++] = PROPNAME_DETECTSERVICE;
93 182 : sTypeProps[i++] = PROPNAME_URLPATTERN;
94 182 : sTypeProps[i++] = PROPNAME_EXTENSIONS;
95 182 : sTypeProps[i++] = PROPNAME_PREFERRED;
96 182 : sTypeProps[i++] = PROPNAME_CLIPBOARDFORMAT;
97 : assert(i == SAL_N_ELEMENTS(sTypeProps));
98 :
99 : // E_READ_NOTHING -> more creative nothingness.
100 364 : m_aTypeProps[E_READ_STANDARD] =
101 182 : css::uno::Sequence< OUString >(sTypeProps + 1, 6);
102 364 : m_aTypeProps[E_READ_UPDATE] =
103 182 : css::uno::Sequence< OUString >(sTypeProps, 1);
104 364 : m_aTypeProps[E_READ_ALL] =
105 : css::uno::Sequence< OUString >(sTypeProps,
106 2002 : SAL_N_ELEMENTS(sTypeProps));
107 182 : }
108 :
109 :
110 546 : FilterCache::~FilterCache()
111 : {
112 182 : if (m_xTypesChglisteners.is())
113 180 : m_xTypesChglisteners->stopListening();
114 182 : if (m_xFiltersChgListener.is())
115 176 : m_xFiltersChgListener->stopListening();
116 364 : }
117 :
118 :
119 :
120 2 : FilterCache* FilterCache::clone() const
121 : {
122 : // SAFE -> ----------------------------------
123 2 : ::osl::ResettableMutexGuard aLock(m_aLock);
124 :
125 2 : 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 2 : pClone->m_lTypes = m_lTypes;
132 2 : pClone->m_lFilters = m_lFilters;
133 2 : pClone->m_lFrameLoaders = m_lFrameLoaders;
134 2 : pClone->m_lContentHandlers = m_lContentHandlers;
135 2 : pClone->m_lExtensions2Types = m_lExtensions2Types;
136 2 : pClone->m_lURLPattern2Types = m_lURLPattern2Types;
137 :
138 2 : pClone->m_sActLocale = m_sActLocale;
139 :
140 2 : pClone->m_eFillState = m_eFillState;
141 :
142 2 : pClone->m_lChangedTypes = m_lChangedTypes;
143 2 : pClone->m_lChangedFilters = m_lChangedFilters;
144 2 : pClone->m_lChangedFrameLoaders = m_lChangedFrameLoaders;
145 2 : pClone->m_lChangedContentHandlers = m_lChangedContentHandlers;
146 :
147 2 : return pClone;
148 : // <- SAFE ----------------------------------
149 : }
150 :
151 :
152 :
153 2 : void FilterCache::takeOver(const FilterCache& rClone)
154 : {
155 : // SAFE -> ----------------------------------
156 2 : ::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 2 : if (rClone.m_lChangedTypes.size()>0)
176 0 : m_lTypes = rClone.m_lTypes;
177 2 : if (rClone.m_lChangedFilters.size()>0)
178 2 : m_lFilters = rClone.m_lFilters;
179 2 : if (rClone.m_lChangedFrameLoaders.size()>0)
180 0 : m_lFrameLoaders = rClone.m_lFrameLoaders;
181 2 : if (rClone.m_lChangedContentHandlers.size()>0)
182 0 : m_lContentHandlers = rClone.m_lContentHandlers;
183 :
184 2 : m_lChangedTypes.clear();
185 2 : m_lChangedFilters.clear();
186 2 : m_lChangedFrameLoaders.clear();
187 2 : m_lChangedContentHandlers.clear();
188 :
189 2 : m_sActLocale = rClone.m_sActLocale;
190 :
191 2 : 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 2 : impl_validateAndOptimize();
198 : // <- SAFE ----------------------------------
199 2 : }
200 :
201 :
202 :
203 370844 : void FilterCache::load(EFillState eRequired)
204 : throw(css::uno::Exception)
205 : {
206 : // SAFE -> ----------------------------------
207 370844 : ::osl::ResettableMutexGuard aLock(m_aLock);
208 :
209 : // check if required fill state is already reached ...
210 : // There is nothing to do then.
211 370844 : if ((m_eFillState & eRequired) == eRequired)
212 740952 : 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 736 : if (m_eFillState == E_CONTAINS_NOTHING)
224 : {
225 180 : impl_getDirectCFGValue(CFGDIRECTKEY_OFFICELOCALE) >>= m_sActLocale;
226 180 : 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 26 : m_sActLocale = DEFAULT_OFFICELOCALE;
230 : }
231 :
232 : // Support the old configuration support. Read it only one times during office runtime!
233 180 : 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 736 : impl_load(eRequired);
241 : // <- SAFE
242 : }
243 :
244 :
245 :
246 39290 : bool FilterCache::isFillState(FilterCache::EFillState eState) const
247 : throw(css::uno::Exception)
248 : {
249 : // SAFE ->
250 39290 : ::osl::ResettableMutexGuard aLock(m_aLock);
251 39290 : return ((m_eFillState & eState) == eState);
252 : // <- SAFE
253 : }
254 :
255 :
256 :
257 101816 : OUStringList FilterCache::getMatchingItemsByProps( EItemType eType ,
258 : const CacheItem& lIProps,
259 : const CacheItem& lEProps) const
260 : throw(css::uno::Exception)
261 : {
262 : // SAFE ->
263 101816 : ::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 101816 : const CacheItemList& rList = impl_getItemList(eType);
269 :
270 101816 : OUStringList lKeys;
271 :
272 : // search items, which provides all needed properties of set "lIProps"
273 : // but not of set "lEProps"!
274 11234994 : for (CacheItemList::const_iterator pIt = rList.begin();
275 7489996 : pIt != rList.end() ;
276 : ++pIt )
277 : {
278 : _FILTER_CONFIG_LOG_1_("getMatchingProps for \"%s\" ...\n",
279 : _FILTER_CONFIG_TO_ASCII_(pIt->first))
280 3643182 : if (
281 3923750 : (pIt->second.haveProps(lIProps) ) &&
282 280568 : (pIt->second.dontHaveProps(lEProps))
283 : )
284 : {
285 280568 : lKeys.push_back(pIt->first);
286 : }
287 : }
288 :
289 101816 : return lKeys;
290 : // <- SAFE
291 : }
292 :
293 :
294 :
295 6 : bool FilterCache::hasItems(EItemType eType) const
296 : throw(css::uno::Exception)
297 : {
298 : // SAFE ->
299 6 : ::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 6 : const CacheItemList& rList = impl_getItemList(eType);
305 :
306 6 : return !rList.empty();
307 : // <- SAFE
308 : }
309 :
310 :
311 :
312 6360 : OUStringList FilterCache::getItemNames(EItemType eType) const
313 : throw(css::uno::Exception)
314 : {
315 : // SAFE ->
316 6360 : ::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 6360 : const CacheItemList& rList = impl_getItemList(eType);
322 :
323 6360 : OUStringList lKeys;
324 4595574 : for (CacheItemList::const_iterator pIt = rList.begin();
325 3063716 : pIt != rList.end() ;
326 : ++pIt )
327 : {
328 1525498 : lKeys.push_back(pIt->first);
329 : }
330 6360 : return lKeys;
331 : // <- SAFE
332 : }
333 :
334 :
335 :
336 113542 : bool FilterCache::hasItem( EItemType eType,
337 : const OUString& sItem)
338 : throw(css::uno::Exception)
339 : {
340 : // SAFE ->
341 113542 : ::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 113542 : 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 113542 : CacheItemList::const_iterator pIt = rList.find(sItem);
352 113542 : if (pIt != rList.end())
353 106008 : return true;
354 :
355 : try
356 : {
357 7534 : impl_loadItemOnDemand(eType, sItem);
358 : // no exception => item could be loaded!
359 0 : return true;
360 : }
361 7534 : catch(const css::container::NoSuchElementException&)
362 : {}
363 :
364 121076 : return false;
365 : // <- SAFE
366 : }
367 :
368 :
369 :
370 2043352 : CacheItem FilterCache::getItem( EItemType eType,
371 : const OUString& sItem)
372 : throw(css::uno::Exception)
373 : {
374 : // SAFE ->
375 2043352 : ::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 2043352 : CacheItemList& rList = impl_getItemList(eType);
381 :
382 : // check if item exists ...
383 2043352 : CacheItemList::iterator pIt = rList.find(sItem);
384 2043352 : 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 52 : 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 2043300 : if (eType == E_FILTER)
399 : {
400 1683910 : CacheItem& rFilter = pIt->second;
401 1683910 : OUString sDocService;
402 1683910 : 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 1683910 : bool bIsHelpFilter = sItem == "writer_web_HTML_help";
407 :
408 1683910 : 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 1683910 : }
414 : }
415 :
416 2043352 : return pIt->second;
417 : // <- SAFE
418 : }
419 :
420 :
421 :
422 4 : void FilterCache::removeItem( EItemType eType,
423 : const OUString& sItem)
424 : throw(css::uno::Exception)
425 : {
426 : // SAFE ->
427 4 : ::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 4 : CacheItemList& rList = impl_getItemList(eType);
433 :
434 4 : CacheItemList::iterator pItem = rList.find(sItem);
435 4 : if (pItem == rList.end())
436 2 : pItem = impl_loadItemOnDemand(eType, sItem); // throws NoSuchELementException!
437 2 : rList.erase(pItem);
438 :
439 4 : impl_addItem2FlushList(eType, sItem);
440 2 : }
441 :
442 :
443 :
444 2 : void FilterCache::setItem( EItemType eType ,
445 : const OUString& sItem ,
446 : const CacheItem& aValue)
447 : throw(css::uno::Exception, std::exception)
448 : {
449 : // SAFE ->
450 2 : ::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 2 : 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 4 : CacheItem aItem = aValue;
460 2 : aItem[PROPNAME_NAME] <<= sItem;
461 2 : 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 2 : removeStatePropsFromItem(aItem);
466 :
467 2 : rList[sItem] = aItem;
468 :
469 4 : impl_addItem2FlushList(eType, sItem);
470 2 : }
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 38704 : void FilterCache::addStatePropsToItem( EItemType eType,
485 : const OUString& sItem,
486 : CacheItem& rItem)
487 : throw(css::uno::Exception)
488 : {
489 : // SAFE ->
490 38704 : ::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 71932 : css::uno::Reference< css::container::XNameAccess > xPackage;
495 71932 : css::uno::Reference< css::container::XNameAccess > xSet;
496 38704 : switch(eType)
497 : {
498 : case E_TYPE :
499 : {
500 6356 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
501 6356 : xPackage->getByName(CFGSET_TYPES) >>= xSet;
502 : }
503 6356 : break;
504 :
505 : case E_FILTER :
506 : {
507 26812 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
508 26812 : xPackage->getByName(CFGSET_FILTERS) >>= xSet;
509 : }
510 26812 : 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 5532 : css::uno::Any aDirectValue = impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER);
522 5588 : OUString sDefaultFrameLoader;
523 5532 : if (
524 11064 : (aDirectValue >>= sDefaultFrameLoader) &&
525 11064 : (!sDefaultFrameLoader.isEmpty() ) &&
526 5532 : (sItem.equals(sDefaultFrameLoader) )
527 : )
528 : {
529 5476 : rItem[PROPNAME_FINALIZED] <<= sal_True;
530 5476 : rItem[PROPNAME_MANDATORY] <<= sal_True;
531 44180 : return;
532 : }
533 : /* <-- HACK */
534 :
535 56 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
536 112 : xPackage->getByName(CFGSET_FRAMELOADERS) >>= xSet;
537 : }
538 56 : break;
539 :
540 : case E_CONTENTHANDLER :
541 : {
542 4 : xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
543 4 : xPackage->getByName(CFGSET_CONTENTHANDLERS) >>= xSet;
544 : }
545 4 : break;
546 0 : default: break;
547 : }
548 :
549 : try
550 : {
551 33228 : css::uno::Reference< css::beans::XProperty > xItem;
552 33228 : xSet->getByName(sItem) >>= xItem;
553 66456 : css::beans::Property aDescription = xItem->getAsProperty();
554 :
555 33228 : bool bFinalized = ((aDescription.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY );
556 33228 : bool bMandatory = ((aDescription.Attributes & css::beans::PropertyAttribute::REMOVABLE) != css::beans::PropertyAttribute::REMOVABLE);
557 :
558 33228 : rItem[PROPNAME_FINALIZED] <<= bFinalized;
559 66456 : 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 33228 : }
575 :
576 : // <- SAFE
577 : }
578 :
579 :
580 :
581 2 : void FilterCache::removeStatePropsFromItem(CacheItem& rItem)
582 : throw(css::uno::Exception)
583 : {
584 2 : CacheItem::iterator pIt;
585 2 : pIt = rItem.find(PROPNAME_FINALIZED);
586 2 : if (pIt != rItem.end())
587 2 : rItem.erase(pIt);
588 2 : pIt = rItem.find(PROPNAME_MANDATORY);
589 2 : if (pIt != rItem.end())
590 2 : rItem.erase(pIt);
591 2 : }
592 :
593 :
594 :
595 2 : void FilterCache::flush()
596 : throw(css::uno::Exception)
597 : {
598 : // SAFE ->
599 2 : ::osl::ResettableMutexGuard aLock(m_aLock);
600 :
601 : // renew all dependencies and optimizations
602 2 : impl_validateAndOptimize();
603 :
604 2 : 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 2 : if (m_lChangedFilters.size() > 0)
617 : {
618 2 : css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
619 4 : css::uno::Reference< css::container::XNameAccess > xSet ;
620 :
621 2 : xConfig->getByName(CFGSET_FILTERS) >>= xSet;
622 2 : impl_flushByList(xSet, E_FILTER, m_lFilters, m_lChangedFilters);
623 :
624 4 : css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
625 4 : xFlush->commitChanges();
626 2 : }
627 :
628 : /*TODO FrameLoader/ContentHandler must be flushed here too ... */
629 2 : }
630 :
631 :
632 :
633 2 : 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 2 : css::uno::Reference< css::container::XNameContainer > xAddRemoveSet = css::uno::Reference< css::container::XNameContainer > (xSet, css::uno::UNO_QUERY);
640 4 : css::uno::Reference< css::container::XNameReplace > xReplaceeSet = css::uno::Reference< css::container::XNameReplace > (xSet, css::uno::UNO_QUERY);
641 4 : css::uno::Reference< css::lang::XSingleServiceFactory > xFactory = css::uno::Reference< css::lang::XSingleServiceFactory >(xSet, css::uno::UNO_QUERY);
642 :
643 12 : for (OUStringList::const_iterator pIt = lItems.begin();
644 8 : pIt != lItems.end() ;
645 : ++pIt )
646 : {
647 2 : const OUString& sItem = *pIt;
648 2 : EItemFlushState eState = impl_specifyFlushOperation(xSet, rCache, sItem);
649 2 : 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("Cant 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("Cant 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 2 : default: break;
689 : }
690 2 : }
691 2 : }
692 :
693 :
694 :
695 47924 : 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 47924 : INetURLObject aParser (aURL.Main);
703 : OUString sExtension = aParser.getExtension(INetURLObject::LAST_SEGMENT ,
704 : true ,
705 95848 : INetURLObject::DECODE_WITH_CHARSET);
706 47924 : sExtension = sExtension.toAsciiLowerCase();
707 :
708 : // SAFE -> ----------------------------------
709 95848 : ::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 2012808 : for (CacheItemRegistration::const_iterator pPattReg = m_lURLPattern2Types.begin();
718 1341872 : pPattReg != m_lURLPattern2Types.end() ;
719 : ++pPattReg )
720 : {
721 623012 : WildCard aPatternCheck(pPattReg->first);
722 623012 : if (aPatternCheck.Matches(aURL.Main))
723 : {
724 1476 : const OUStringList& rTypesForPattern = pPattReg->second;
725 :
726 1476 : FlatDetectionInfo aInfo;
727 1476 : aInfo.sType = *(rTypesForPattern.begin());
728 1476 : aInfo.bMatchByPattern = true;
729 :
730 1476 : rFlatTypes.push_back(aInfo);
731 : // return;
732 : }
733 623012 : }
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 47924 : CacheItemRegistration::const_iterator pExtReg = m_lExtensions2Types.find(sExtension);
741 47924 : if (pExtReg != m_lExtensions2Types.end())
742 : {
743 6080 : const OUStringList& rTypesForExtension = pExtReg->second;
744 54996 : for (OUStringList::const_iterator pIt = rTypesForExtension.begin();
745 36664 : pIt != rTypesForExtension.end() ;
746 : ++pIt )
747 : {
748 12252 : FlatDetectionInfo aInfo;
749 12252 : aInfo.sType = *pIt;
750 12252 : aInfo.bMatchByExtension = true;
751 :
752 12252 : rFlatTypes.push_back(aInfo);
753 12252 : }
754 : }
755 :
756 95848 : aLock.clear();
757 : // <- SAFE ----------------------------------
758 47924 : }
759 :
760 108182 : const CacheItemList& FilterCache::impl_getItemList(EItemType eType) const
761 : {
762 : // SAFE -> ----------------------------------
763 108182 : ::osl::ResettableMutexGuard aLock(m_aLock);
764 :
765 108182 : switch(eType)
766 : {
767 5624 : case E_TYPE : return m_lTypes ;
768 15412 : case E_FILTER : return m_lFilters ;
769 47842 : case E_FRAMELOADER : return m_lFrameLoaders ;
770 39304 : case E_CONTENTHANDLER : return m_lContentHandlers;
771 :
772 : }
773 :
774 : throw css::uno::Exception("unknown sub container requested.",
775 0 : css::uno::Reference< css::uno::XInterface >());
776 : // <- SAFE ----------------------------------
777 : }
778 :
779 2156900 : CacheItemList& FilterCache::impl_getItemList(EItemType eType)
780 : {
781 : // SAFE -> ----------------------------------
782 2156900 : ::osl::ResettableMutexGuard aLock(m_aLock);
783 :
784 2156900 : switch(eType)
785 : {
786 446808 : case E_TYPE : return m_lTypes ;
787 1693460 : case E_FILTER : return m_lFilters ;
788 16614 : case E_FRAMELOADER : return m_lFrameLoaders ;
789 18 : case E_CONTENTHANDLER : return m_lContentHandlers;
790 :
791 : }
792 :
793 : throw css::uno::Exception("unknown sub container requested.",
794 0 : css::uno::Reference< css::uno::XInterface >());
795 : // <- SAFE ----------------------------------
796 : }
797 :
798 41734 : css::uno::Reference< css::uno::XInterface > FilterCache::impl_openConfig(EConfigProvider eProvider)
799 : throw(css::uno::Exception)
800 : {
801 41734 : ::osl::ResettableMutexGuard aLock(m_aLock);
802 :
803 83468 : OUString sPath ;
804 41734 : css::uno::Reference< css::uno::XInterface >* pConfig = 0;
805 83468 : css::uno::Reference< css::uno::XInterface > xOld ;
806 83468 : OString sRtlLog ;
807 :
808 41734 : switch(eProvider)
809 : {
810 : case E_PROVIDER_TYPES :
811 : {
812 14228 : if (m_xConfigTypes.is())
813 14048 : return m_xConfigTypes;
814 180 : sPath = CFGPACKAGE_TD_TYPES;
815 180 : pConfig = &m_xConfigTypes;
816 180 : sRtlLog = "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_TYPES)";
817 : }
818 180 : break;
819 :
820 : case E_PROVIDER_FILTERS :
821 : {
822 27044 : if (m_xConfigFilters.is())
823 26868 : return m_xConfigFilters;
824 176 : sPath = CFGPACKAGE_TD_FILTERS;
825 176 : pConfig = &m_xConfigFilters;
826 176 : sRtlLog = "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_FILTERS)";
827 : }
828 176 : break;
829 :
830 : case E_PROVIDER_OTHERS :
831 : {
832 282 : if (m_xConfigOthers.is())
833 122 : return m_xConfigOthers;
834 160 : sPath = CFGPACKAGE_TD_OTHERS;
835 160 : pConfig = &m_xConfigOthers;
836 160 : sRtlLog = "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OTHERS)";
837 : }
838 160 : 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 180 : sPath = CFGPACKAGE_TD_OLD;
845 180 : pConfig = &xOld;
846 180 : sRtlLog = "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OLD)";
847 : }
848 180 : break;
849 :
850 0 : default : throw css::uno::Exception("These configuration node isnt supported here for open!", 0);
851 : }
852 :
853 : {
854 : SAL_INFO( "filter.config", "" << sRtlLog.getStr());
855 1392 : *pConfig = impl_createConfigAccess(sPath ,
856 : false, // bReadOnly
857 696 : true ); // bLocalesMode
858 : }
859 :
860 :
861 : // Start listening for changes on that configuration access.
862 696 : switch(eProvider)
863 : {
864 : case E_PROVIDER_TYPES:
865 : {
866 180 : m_xTypesChglisteners.set(new CacheUpdateListener(*this, *pConfig, FilterCache::E_TYPE));
867 180 : m_xTypesChglisteners->startListening();
868 : }
869 180 : break;
870 : case E_PROVIDER_FILTERS:
871 : {
872 176 : m_xFiltersChgListener.set(new CacheUpdateListener(*this, *pConfig, FilterCache::E_FILTER));
873 176 : m_xFiltersChgListener->startListening();
874 : }
875 176 : break;
876 : default:
877 340 : break;
878 : }
879 :
880 42430 : return *pConfig;
881 : }
882 :
883 :
884 :
885 6452 : css::uno::Any FilterCache::impl_getDirectCFGValue(const OUString& sDirectKey)
886 : {
887 6452 : OUString sRoot;
888 12904 : OUString sKey ;
889 :
890 6452 : if (
891 12904 : (!::utl::splitLastFromConfigurationPath(sDirectKey, sRoot, sKey)) ||
892 12904 : (sRoot.isEmpty() ) ||
893 6452 : (sKey.isEmpty() )
894 : )
895 0 : return css::uno::Any();
896 :
897 : css::uno::Reference< css::uno::XInterface > xCfg = impl_createConfigAccess(sRoot ,
898 : true , // bReadOnly
899 12904 : false); // bLocalesMode
900 6452 : if (!xCfg.is())
901 0 : return css::uno::Any();
902 :
903 12904 : css::uno::Reference< css::container::XNameAccess > xAccess(xCfg, css::uno::UNO_QUERY);
904 6452 : if (!xAccess.is())
905 0 : return css::uno::Any();
906 :
907 12904 : css::uno::Any aValue;
908 : try
909 : {
910 6452 : aValue = xAccess->getByName(sKey);
911 : }
912 0 : catch(const css::uno::RuntimeException&)
913 0 : { throw; }
914 : #if OSL_DEBUG_LEVEL > 0
915 : catch(const css::uno::Exception& ex)
916 : #else
917 0 : catch(const css::uno::Exception&)
918 : #endif
919 : {
920 : #if OSL_DEBUG_LEVEL > 0
921 : OSL_FAIL(OUStringToOString(ex.Message, RTL_TEXTENCODING_UTF8).getStr());
922 : #endif
923 0 : aValue.clear();
924 : }
925 :
926 12904 : return aValue;
927 : }
928 :
929 :
930 :
931 7148 : css::uno::Reference< css::uno::XInterface > FilterCache::impl_createConfigAccess(const OUString& sRoot ,
932 : bool bReadOnly ,
933 : bool bLocalesMode)
934 : {
935 : // SAFE ->
936 7148 : ::osl::ResettableMutexGuard aLock(m_aLock);
937 :
938 7148 : css::uno::Reference< css::uno::XInterface > xCfg;
939 :
940 : try
941 : {
942 : css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
943 7148 : css::configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() ) );
944 :
945 14296 : ::comphelper::SequenceAsVector< css::uno::Any > lParams;
946 14296 : css::beans::NamedValue aParam;
947 :
948 : // set root path
949 7148 : aParam.Name = "nodepath";
950 7148 : aParam.Value <<= sRoot;
951 7148 : lParams.push_back(css::uno::makeAny(aParam));
952 :
953 : // enable "all locales mode" ... if required
954 7148 : if (bLocalesMode)
955 : {
956 696 : aParam.Name = "locale";
957 696 : aParam.Value <<= OUString("*");
958 696 : lParams.push_back(css::uno::makeAny(aParam));
959 : }
960 :
961 : // open it
962 7148 : if (bReadOnly)
963 6452 : xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONACCESS, lParams.getAsConstList());
964 : else
965 696 : xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONUPDATEACCESS, lParams.getAsConstList());
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 7148 : if (! xCfg.is())
971 : throw css::uno::Exception(
972 : "Got NULL reference on opening configuration file ... but no exception.",
973 7148 : 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 7148 : return xCfg;
984 : // <- SAFE
985 : }
986 :
987 :
988 :
989 740 : void FilterCache::impl_validateAndOptimize()
990 : throw(css::uno::Exception)
991 : {
992 : // SAFE ->
993 740 : ::osl::ResettableMutexGuard aLock(m_aLock);
994 :
995 : // First check if any filter or type could be readed
996 : // from the underlying configuration!
997 740 : bool bSomeTypesShouldExist = ((m_eFillState & E_CONTAINS_STANDARD ) == E_CONTAINS_STANDARD );
998 740 : 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 740 : if (
1010 : (
1011 740 : (bSomeTypesShouldExist) &&
1012 740 : (m_lTypes.size() < 1 )
1013 1480 : ) ||
1014 : (
1015 464 : (bAllFiltersShouldExist) &&
1016 464 : (m_lFilters.size() < 1 )
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 740 : sal_Int32 nErrors = 0;
1031 1480 : OUStringBuffer sLog(256);
1032 :
1033 740 : CacheItemList::iterator pIt;
1034 :
1035 136160 : for (pIt = m_lTypes.begin(); pIt != m_lTypes.end(); ++pIt)
1036 : {
1037 135420 : OUString sType = pIt->first;
1038 270840 : 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 270840 : css::uno::Sequence< OUString > lExtensions;
1047 270840 : css::uno::Sequence< OUString > lURLPattern;
1048 135420 : aType[PROPNAME_EXTENSIONS] >>= lExtensions;
1049 135420 : aType[PROPNAME_URLPATTERN] >>= lURLPattern;
1050 135420 : sal_Int32 ce = lExtensions.getLength();
1051 135420 : 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 135420 : bool bPreferred = false;
1079 135420 : aType[PROPNAME_PREFERRED] >>= bPreferred;
1080 :
1081 135420 : const OUString* pExtensions = lExtensions.getConstArray();
1082 333000 : 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 197580 : OUString sNormalizedExtension = pExtensions[e].toAsciiLowerCase();
1087 :
1088 197580 : OUStringList& lTypesForExtension = m_lExtensions2Types[sNormalizedExtension];
1089 197580 : if (::std::find(lTypesForExtension.begin(), lTypesForExtension.end(), sType) != lTypesForExtension.end())
1090 149700 : continue;
1091 :
1092 47880 : if (bPreferred)
1093 24120 : lTypesForExtension.insert(lTypesForExtension.begin(), sType);
1094 : else
1095 23760 : lTypesForExtension.push_back(sType);
1096 47880 : }
1097 :
1098 135420 : const OUString* pURLPattern = lURLPattern.getConstArray();
1099 145780 : for (sal_Int32 u=0; u<cu; ++u)
1100 : {
1101 10360 : OUStringList& lTypesForURLPattern = m_lURLPattern2Types[pURLPattern[u]];
1102 10360 : if (::std::find(lTypesForURLPattern.begin(), lTypesForURLPattern.end(), sType) != lTypesForURLPattern.end())
1103 7840 : continue;
1104 :
1105 2520 : if (bPreferred)
1106 1440 : lTypesForURLPattern.insert(lTypesForURLPattern.begin(), sType);
1107 : else
1108 1080 : 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 + "\" isnt 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 135420 : }
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 1480 : css::uno::Any aDirectValue = impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER);
1203 1480 : OUString sDefaultFrameLoader;
1204 :
1205 740 : if (
1206 1480 : (!(aDirectValue >>= sDefaultFrameLoader)) ||
1207 740 : (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 1480 : OUStringList lTypes = getItemNames(E_TYPE);
1219 9396 : for ( pIt = m_lFrameLoaders.begin();
1220 6264 : 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 2392 : OUString sLoader = pIt->first;
1228 2392 : if (sLoader.equals(sDefaultFrameLoader))
1229 560 : continue;
1230 :
1231 1832 : CacheItem& rLoader = pIt->second;
1232 1832 : css::uno::Any& rTypesReg = rLoader[PROPNAME_TYPES];
1233 3664 : OUStringList lTypesReg (rTypesReg);
1234 :
1235 16488 : for (OUStringList::const_iterator pTypesReg = lTypesReg.begin();
1236 10992 : pTypesReg != lTypesReg.end() ;
1237 : ++pTypesReg )
1238 : {
1239 3664 : OUStringList::iterator pTypeCheck = ::std::find(lTypes.begin(), lTypes.end(), *pTypesReg);
1240 3664 : if (pTypeCheck != lTypes.end())
1241 2290 : lTypes.erase(pTypeCheck);
1242 : }
1243 1832 : }
1244 :
1245 740 : CacheItem& rDefaultLoader = m_lFrameLoaders[sDefaultFrameLoader];
1246 740 : rDefaultLoader[PROPNAME_NAME ] <<= sDefaultFrameLoader;
1247 740 : rDefaultLoader[PROPNAME_TYPES] <<= lTypes.getAsConstList();
1248 :
1249 1480 : OUString sLogOut = sLog.makeStringAndClear();
1250 : OSL_ENSURE(!nErrors, OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
1251 740 : if (nErrors>0)
1252 : throw css::document::CorruptedFilterConfigurationException(
1253 0 : "filter configuration: " + sLogOut,
1254 : css::uno::Reference< css::uno::XInterface >(),
1255 0 : sLogOut);
1256 740 : OSL_ENSURE(!nWarnings, OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
1257 :
1258 : // <- SAFE
1259 740 : }
1260 :
1261 :
1262 :
1263 4 : void FilterCache::impl_addItem2FlushList( EItemType eType,
1264 : const OUString& sItem)
1265 : throw(css::uno::Exception)
1266 : {
1267 4 : OUStringList* pList = 0;
1268 4 : switch(eType)
1269 : {
1270 : case E_TYPE :
1271 0 : pList = &m_lChangedTypes;
1272 0 : break;
1273 :
1274 : case E_FILTER :
1275 4 : pList = &m_lChangedFilters;
1276 4 : break;
1277 :
1278 : case E_FRAMELOADER :
1279 0 : pList = &m_lChangedFrameLoaders;
1280 0 : break;
1281 :
1282 : case E_CONTENTHANDLER :
1283 0 : pList = &m_lChangedContentHandlers;
1284 0 : break;
1285 :
1286 0 : default : throw css::uno::Exception("unsupported item type", 0);
1287 : }
1288 :
1289 4 : OUStringList::const_iterator pItem = ::std::find(pList->begin(), pList->end(), sItem);
1290 4 : if (pItem == pList->end())
1291 2 : pList->push_back(sItem);
1292 4 : }
1293 :
1294 :
1295 :
1296 2 : FilterCache::EItemFlushState FilterCache::impl_specifyFlushOperation(const css::uno::Reference< css::container::XNameAccess >& xSet ,
1297 : const CacheItemList& rList,
1298 : const OUString& sItem)
1299 : throw(css::uno::Exception)
1300 : {
1301 2 : bool bExistsInConfigLayer = xSet->hasByName(sItem);
1302 2 : bool bExistsInMemory = (rList.find(sItem) != rList.end());
1303 :
1304 2 : EItemFlushState eState( E_ITEM_UNCHANGED );
1305 :
1306 : // !? ... such situation can occur, if an item was added and(!) removed before it was flushed :-)
1307 2 : if (!bExistsInConfigLayer && !bExistsInMemory)
1308 2 : eState = E_ITEM_UNCHANGED;
1309 0 : else if (!bExistsInConfigLayer && bExistsInMemory)
1310 0 : eState = E_ITEM_ADDED;
1311 0 : else if (bExistsInConfigLayer && bExistsInMemory)
1312 0 : eState = E_ITEM_CHANGED;
1313 0 : else if (bExistsInConfigLayer && !bExistsInMemory)
1314 0 : eState = E_ITEM_REMOVED;
1315 :
1316 2 : return eState;
1317 : }
1318 :
1319 736 : void FilterCache::impl_load(EFillState eRequiredState)
1320 : throw(css::uno::Exception)
1321 : {
1322 : // SAFE ->
1323 736 : ::osl::ResettableMutexGuard aLock(m_aLock);
1324 :
1325 : // Attention: Detect services are part of the standard set!
1326 : // So there is no need to handle it separately.
1327 :
1328 :
1329 : // a) The standard set of config value is needed.
1330 736 : if (
1331 916 : ((eRequiredState & E_CONTAINS_STANDARD) == E_CONTAINS_STANDARD) &&
1332 180 : ((m_eFillState & E_CONTAINS_STANDARD) != E_CONTAINS_STANDARD)
1333 : )
1334 : {
1335 : // Attention! If config couldnt be opened successfully
1336 : // and exception os thrown automatically and must be forwarded
1337 : // to our calli ...
1338 180 : css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
1339 : {
1340 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::load std");
1341 180 : impl_loadSet(xTypes, E_TYPE, E_READ_STANDARD, &m_lTypes);
1342 180 : }
1343 : }
1344 :
1345 :
1346 : // b) We need all type information ...
1347 736 : if (
1348 904 : ((eRequiredState & E_CONTAINS_TYPES) == E_CONTAINS_TYPES) &&
1349 168 : ((m_eFillState & E_CONTAINS_TYPES) != E_CONTAINS_TYPES)
1350 : )
1351 : {
1352 : // Attention! If config couldnt be opened successfully
1353 : // and exception os thrown automatically and must be forwarded
1354 : // to our calli ...
1355 168 : css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY_THROW);
1356 : {
1357 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::load all types");
1358 168 : impl_loadSet(xTypes, E_TYPE, E_READ_UPDATE, &m_lTypes);
1359 168 : }
1360 : }
1361 :
1362 :
1363 : // c) We need all filter information ...
1364 736 : if (
1365 910 : ((eRequiredState & E_CONTAINS_FILTERS) == E_CONTAINS_FILTERS) &&
1366 174 : ((m_eFillState & E_CONTAINS_FILTERS) != E_CONTAINS_FILTERS)
1367 : )
1368 : {
1369 : // Attention! If config couldnt be opened successfully
1370 : // and exception os thrown automatically and must be forwarded
1371 : // to our calli ...
1372 174 : css::uno::Reference< css::container::XNameAccess > xFilters(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY_THROW);
1373 : {
1374 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::load all filters");
1375 174 : impl_loadSet(xFilters, E_FILTER, E_READ_ALL, &m_lFilters);
1376 174 : }
1377 : }
1378 :
1379 :
1380 : // c) We need all frame loader information ...
1381 736 : if (
1382 896 : ((eRequiredState & E_CONTAINS_FRAMELOADERS) == E_CONTAINS_FRAMELOADERS) &&
1383 160 : ((m_eFillState & E_CONTAINS_FRAMELOADERS) != E_CONTAINS_FRAMELOADERS)
1384 : )
1385 : {
1386 : // Attention! If config couldnt be opened successfully
1387 : // and exception os thrown automatically and must be forwarded
1388 : // to our calli ...
1389 160 : css::uno::Reference< css::container::XNameAccess > xLoaders(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
1390 : {
1391 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::load all frame loader");
1392 160 : impl_loadSet(xLoaders, E_FRAMELOADER, E_READ_ALL, &m_lFrameLoaders);
1393 160 : }
1394 : }
1395 :
1396 :
1397 : // d) We need all content handler information ...
1398 736 : if (
1399 790 : ((eRequiredState & E_CONTAINS_CONTENTHANDLERS) == E_CONTAINS_CONTENTHANDLERS) &&
1400 54 : ((m_eFillState & E_CONTAINS_CONTENTHANDLERS) != E_CONTAINS_CONTENTHANDLERS)
1401 : )
1402 : {
1403 : // Attention! If config couldnt be opened successfully
1404 : // and exception os thrown automatically and must be forwarded
1405 : // to our calli ...
1406 54 : css::uno::Reference< css::container::XNameAccess > xHandlers(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY_THROW);
1407 : {
1408 : SAL_INFO( "filter.config", "framework (as96863) ::FilterCache::load all content handler");
1409 54 : impl_loadSet(xHandlers, E_CONTENTHANDLER, E_READ_ALL, &m_lContentHandlers);
1410 54 : }
1411 : }
1412 :
1413 : // update fill state. Note: it's a bit field, which combines different parts.
1414 736 : m_eFillState = (EFillState) ((sal_Int32)m_eFillState | (sal_Int32)eRequiredState);
1415 :
1416 : // any data readed?
1417 : // yes! => validate it and update optimized structures.
1418 736 : impl_validateAndOptimize();
1419 :
1420 : // <- SAFE
1421 736 : }
1422 :
1423 :
1424 :
1425 736 : void FilterCache::impl_loadSet(const css::uno::Reference< css::container::XNameAccess >& xConfig,
1426 : EItemType eType ,
1427 : EReadOption eOption,
1428 : CacheItemList* pCache )
1429 : throw(css::uno::Exception)
1430 : {
1431 : // get access to the right configuration set
1432 736 : OUString sSetName;
1433 736 : switch(eType)
1434 : {
1435 : case E_TYPE :
1436 348 : sSetName = CFGSET_TYPES;
1437 348 : break;
1438 :
1439 : case E_FILTER :
1440 174 : sSetName = CFGSET_FILTERS;
1441 174 : break;
1442 :
1443 : case E_FRAMELOADER :
1444 160 : sSetName = CFGSET_FRAMELOADERS;
1445 160 : break;
1446 :
1447 : case E_CONTENTHANDLER :
1448 54 : sSetName = CFGSET_CONTENTHANDLERS;
1449 54 : break;
1450 0 : default: break;
1451 : }
1452 :
1453 736 : css::uno::Reference< css::container::XNameAccess > xSet;
1454 1472 : css::uno::Sequence< OUString > lItems;
1455 :
1456 : try
1457 : {
1458 736 : css::uno::Any aVal = xConfig->getByName(sSetName);
1459 736 : if (!(aVal >>= xSet) || !xSet.is())
1460 : {
1461 0 : OUString sMsg("Could not open configuration set \"" + sSetName + "\".");
1462 0 : throw css::uno::Exception(sMsg, css::uno::Reference< css::uno::XInterface >());
1463 : }
1464 736 : lItems = xSet->getElementNames();
1465 : }
1466 0 : catch(const css::uno::Exception& ex)
1467 : {
1468 : throw css::document::CorruptedFilterConfigurationException(
1469 0 : "filter configuration, caught: " + ex.Message,
1470 : css::uno::Reference< css::uno::XInterface >(),
1471 0 : ex.Message);
1472 : }
1473 :
1474 : // get names of all existing sub items of this set
1475 : // step over it and fill internal cache structures.
1476 :
1477 : // But dont update optimized structures like e.g. hash
1478 : // for mapping extensions to its types!
1479 :
1480 736 : const OUString* pItems = lItems.getConstArray();
1481 736 : sal_Int32 c = lItems.getLength();
1482 108320 : for (sal_Int32 i=0; i<c; ++i)
1483 : {
1484 107584 : CacheItemList::iterator pItem = pCache->find(pItems[i]);
1485 107584 : switch(eOption)
1486 : {
1487 : // a) read a standard set of properties only or read all
1488 : case E_READ_STANDARD :
1489 : case E_READ_ALL :
1490 : {
1491 : try
1492 : {
1493 76840 : (*pCache)[pItems[i]] = impl_loadItem(xSet, eType, pItems[i], eOption);
1494 : }
1495 0 : catch(const css::uno::Exception& ex)
1496 : {
1497 : throw css::document::CorruptedFilterConfigurationException(
1498 0 : "filter configuration, caught: " + ex.Message,
1499 : css::uno::Reference< css::uno::XInterface >(),
1500 0 : ex.Message);
1501 : }
1502 : }
1503 76840 : break;
1504 :
1505 : // b) read optional properties only!
1506 : // All items must already exist inside our cache.
1507 : // But they must be updated.
1508 : case E_READ_UPDATE :
1509 : {
1510 30744 : if (pItem == pCache->end())
1511 : {
1512 0 : OUString sMsg("item \"" + pItems[i] + "\" not found for update!");
1513 0 : throw css::uno::Exception(sMsg, css::uno::Reference< css::uno::XInterface >());
1514 : }
1515 : try
1516 : {
1517 30744 : CacheItem aItem = impl_loadItem(xSet, eType, pItems[i], eOption);
1518 30744 : pItem->second.update(aItem);
1519 : }
1520 0 : catch(const css::uno::Exception& ex)
1521 : {
1522 : throw css::document::CorruptedFilterConfigurationException(
1523 0 : "filter configuration, caught: " + ex.Message,
1524 : css::uno::Reference< css::uno::XInterface >(),
1525 0 : ex.Message);
1526 : }
1527 : }
1528 30744 : break;
1529 0 : default: break;
1530 : }
1531 736 : }
1532 736 : }
1533 :
1534 :
1535 :
1536 73896 : void FilterCache::impl_readPatchUINames(const css::uno::Reference< css::container::XNameAccess >& xNode,
1537 : CacheItem& rItem)
1538 : throw(css::uno::Exception)
1539 : {
1540 :
1541 : // SAFE -> ----------------------------------
1542 73896 : ::osl::ResettableMutexGuard aLock(m_aLock);
1543 140838 : OUString sActLocale = m_sActLocale ;
1544 73896 : aLock.clear();
1545 : // <- SAFE ----------------------------------
1546 :
1547 140838 : css::uno::Any aVal = xNode->getByName(PROPNAME_UINAME);
1548 140838 : css::uno::Reference< css::container::XNameAccess > xUIName;
1549 73896 : if (!(aVal >>= xUIName) && !xUIName.is())
1550 0 : return;
1551 :
1552 140838 : const ::comphelper::SequenceAsVector< OUString > lLocales(xUIName->getElementNames());
1553 73896 : ::comphelper::SequenceAsVector< OUString >::const_iterator pLocale ;
1554 140838 : ::comphelper::SequenceAsHashMap lUINames;
1555 :
1556 422514 : for ( pLocale = lLocales.begin();
1557 281676 : pLocale != lLocales.end() ;
1558 : ++pLocale )
1559 : {
1560 66942 : const OUString& sLocale = *pLocale;
1561 :
1562 66942 : OUString sValue;
1563 66942 : xUIName->getByName(sLocale) >>= sValue;
1564 :
1565 66942 : lUINames[sLocale] <<= sValue;
1566 66942 : }
1567 :
1568 73896 : aVal <<= lUINames.getAsConstPropertyValueList();
1569 73896 : rItem[PROPNAME_UINAMES] = aVal;
1570 :
1571 : // find right UIName for current office locale
1572 : // Use fallbacks too!
1573 73896 : pLocale = LanguageTag::getFallback(lLocales, sActLocale);
1574 73896 : if (pLocale == lLocales.end())
1575 : {
1576 : #if OSL_DEBUG_LEVEL > 0
1577 : if ( sActLocale == "en-US" )
1578 : return;
1579 : OUString sName = rItem.getUnpackedValueOrDefault(PROPNAME_NAME, OUString());
1580 :
1581 : OUString sMsg("Fallback scenario for filter or type '" + sName + "' and locale '" +
1582 : sActLocale + "' failed. Please check your filter configuration.");
1583 :
1584 : OSL_FAIL(_FILTER_CONFIG_TO_ASCII_(sMsg));
1585 : #endif
1586 6954 : return;
1587 : }
1588 :
1589 66942 : const OUString& sLocale = *pLocale;
1590 66942 : ::comphelper::SequenceAsHashMap::const_iterator pUIName = lUINames.find(sLocale);
1591 66942 : if (pUIName != lUINames.end())
1592 133884 : rItem[PROPNAME_UINAME] = pUIName->second;
1593 : }
1594 :
1595 :
1596 :
1597 0 : void FilterCache::impl_savePatchUINames(const css::uno::Reference< css::container::XNameReplace >& xNode,
1598 : const CacheItem& rItem)
1599 : throw(css::uno::Exception)
1600 : {
1601 0 : css::uno::Reference< css::container::XNameContainer > xAdd (xNode, css::uno::UNO_QUERY);
1602 0 : css::uno::Reference< css::container::XNameAccess > xCheck(xNode, css::uno::UNO_QUERY);
1603 :
1604 0 : css::uno::Sequence< css::beans::PropertyValue > lUINames = rItem.getUnpackedValueOrDefault(PROPNAME_UINAMES, css::uno::Sequence< css::beans::PropertyValue >());
1605 0 : sal_Int32 c = lUINames.getLength();
1606 0 : const css::beans::PropertyValue* pUINames = lUINames.getConstArray();
1607 :
1608 0 : for (sal_Int32 i=0; i<c; ++i)
1609 : {
1610 0 : if (xCheck->hasByName(pUINames[i].Name))
1611 0 : xNode->replaceByName(pUINames[i].Name, pUINames[i].Value);
1612 : else
1613 0 : xAdd->insertByName(pUINames[i].Name, pUINames[i].Value);
1614 0 : }
1615 0 : }
1616 :
1617 : /*-----------------------------------------------
1618 : TODO
1619 : clarify, how the real problem behind the
1620 : wrong constructed CacheItem instance (which
1621 : will force a crash during destruction)
1622 : can be solved ...
1623 : -----------------------------------------------*/
1624 107584 : CacheItem FilterCache::impl_loadItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
1625 : EItemType eType ,
1626 : const OUString& sItem ,
1627 : EReadOption eOption)
1628 : throw(css::uno::Exception)
1629 : {
1630 : // try to get an API object, which points directly to the
1631 : // requested item. If it fail an exception should occur and
1632 : // break this operation. Of course returned API object must be
1633 : // checked too.
1634 107584 : css::uno::Reference< css::container::XNameAccess > xItem;
1635 : #ifdef WORKAROUND_EXCEPTION_PROBLEM
1636 : try
1637 : {
1638 : #endif
1639 107584 : css::uno::Any aVal = xSet->getByName(sItem);
1640 107584 : if (!(aVal >>= xItem) || !xItem.is())
1641 : {
1642 0 : OUString sMsg("found corrupted item \"" + sItem + "\".");
1643 0 : throw css::uno::Exception(sMsg, css::uno::Reference< css::uno::XInterface >());
1644 107584 : }
1645 : #ifdef WORKAROUND_EXCEPTION_PROBLEM
1646 : }
1647 0 : catch(const css::container::NoSuchElementException&)
1648 : {
1649 0 : throw;
1650 : }
1651 : #endif
1652 :
1653 : // set too. Of course its already used as key into the e.g. outside
1654 : // used hash map ... but some of our API methods provide
1655 : // this property set as result only. But the user of this CacheItem
1656 : // should know, which value the key names has :-) ITS IMPORTANT!
1657 107584 : CacheItem aItem;
1658 107584 : aItem[PROPNAME_NAME] = css::uno::makeAny(sItem);
1659 107584 : switch(eType)
1660 : {
1661 : case E_TYPE :
1662 : {
1663 : assert(eOption >= 0 && eOption <= E_READ_ALL);
1664 63684 : css::uno::Sequence< OUString > &rNames = m_aTypeProps[eOption];
1665 :
1666 : // read standard properties of a filter
1667 63684 : if (rNames.getLength() > 0)
1668 : {
1669 : css::uno::Reference< css::beans::XMultiPropertySet >
1670 63684 : xPropSet( xItem, css::uno::UNO_QUERY_THROW);
1671 127368 : css::uno::Sequence< css::uno::Any > aValues;
1672 63684 : aValues = xPropSet->getPropertyValues(rNames);
1673 :
1674 292068 : for (sal_Int32 i = 0; i < aValues.getLength(); i++)
1675 292068 : aItem[rNames[i]] = aValues[i];
1676 : }
1677 :
1678 : // read optional properties of a type
1679 : // no else here! Is an additional switch ...
1680 63684 : if (eOption == E_READ_UPDATE || eOption == E_READ_ALL)
1681 30744 : impl_readPatchUINames(xItem, aItem);
1682 : }
1683 63684 : break;
1684 :
1685 :
1686 : case E_FILTER :
1687 : {
1688 : assert(eOption >= 0 && eOption <= E_READ_ALL);
1689 43152 : css::uno::Sequence< OUString > &rNames = m_aStandardProps[eOption];
1690 :
1691 : // read standard properties of a filter
1692 43152 : if (rNames.getLength() > 0)
1693 : {
1694 : css::uno::Reference< css::beans::XMultiPropertySet >
1695 43152 : xPropSet( xItem, css::uno::UNO_QUERY_THROW);
1696 86304 : css::uno::Sequence< css::uno::Any > aValues;
1697 43152 : aValues = xPropSet->getPropertyValues(rNames);
1698 :
1699 431520 : for (sal_Int32 i = 0; i < rNames.getLength(); i++)
1700 : {
1701 388368 : OUString &rPropName = rNames[i];
1702 388368 : if (i != rNames.getLength() - 1 || rPropName != PROPNAME_FLAGS)
1703 345216 : aItem[rPropName] = aValues[i];
1704 : else
1705 : {
1706 : assert(rPropName == PROPNAME_FLAGS);
1707 : // special handling for flags! Convert it from a list of names to its
1708 : // int representation ...
1709 43152 : css::uno::Sequence< OUString > lFlagNames;
1710 43152 : if (aValues[i] >>= lFlagNames)
1711 43152 : aItem[rPropName] <<= FilterCache::impl_convertFlagNames2FlagField(lFlagNames);
1712 : }
1713 43152 : }
1714 : }
1715 : //TODO remove it if moving of filter uinames to type uinames
1716 : // will be finished really
1717 : #ifdef AS_ENABLE_FILTER_UINAMES
1718 43152 : if (eOption == E_READ_UPDATE || eOption == E_READ_ALL)
1719 43152 : impl_readPatchUINames(xItem, aItem);
1720 : #endif // AS_ENABLE_FILTER_UINAMES
1721 : }
1722 43152 : break;
1723 :
1724 : case E_FRAMELOADER :
1725 : case E_CONTENTHANDLER :
1726 748 : aItem[PROPNAME_TYPES] = xItem->getByName(PROPNAME_TYPES);
1727 748 : break;
1728 0 : default: break;
1729 : }
1730 :
1731 107584 : return aItem;
1732 : }
1733 :
1734 :
1735 :
1736 7588 : CacheItemList::iterator FilterCache::impl_loadItemOnDemand( EItemType eType,
1737 : const OUString& sItem)
1738 : throw(css::uno::Exception)
1739 : {
1740 7588 : CacheItemList* pList = 0;
1741 7588 : css::uno::Reference< css::uno::XInterface > xConfig ;
1742 15176 : OUString sSet ;
1743 :
1744 7588 : switch(eType)
1745 : {
1746 : case E_TYPE :
1747 : {
1748 7524 : pList = &m_lTypes;
1749 7524 : xConfig = impl_openConfig(E_PROVIDER_TYPES);
1750 7524 : sSet = CFGSET_TYPES;
1751 : }
1752 7524 : break;
1753 :
1754 : case E_FILTER :
1755 : {
1756 56 : pList = &m_lFilters;
1757 56 : xConfig = impl_openConfig(E_PROVIDER_FILTERS);
1758 56 : sSet = CFGSET_FILTERS;
1759 : }
1760 56 : break;
1761 :
1762 : case E_FRAMELOADER :
1763 : {
1764 4 : pList = &m_lFrameLoaders;
1765 4 : xConfig = impl_openConfig(E_PROVIDER_OTHERS);
1766 4 : sSet = CFGSET_FRAMELOADERS;
1767 : }
1768 4 : break;
1769 :
1770 : case E_CONTENTHANDLER :
1771 : {
1772 4 : pList = &m_lContentHandlers;
1773 4 : xConfig = impl_openConfig(E_PROVIDER_OTHERS);
1774 4 : sSet = CFGSET_CONTENTHANDLERS;
1775 : }
1776 4 : break;
1777 : }
1778 :
1779 7588 : if (!pList)
1780 0 : throw css::container::NoSuchElementException();
1781 :
1782 7588 : css::uno::Reference< css::container::XNameAccess > xRoot(xConfig, css::uno::UNO_QUERY_THROW);
1783 15176 : css::uno::Reference< css::container::XNameAccess > xSet ;
1784 7588 : xRoot->getByName(sSet) >>= xSet;
1785 :
1786 7588 : CacheItemList::iterator pItemInCache = pList->find(sItem);
1787 7588 : bool bItemInConfig = xSet->hasByName(sItem);
1788 :
1789 7588 : if (bItemInConfig)
1790 : {
1791 0 : (*pList)[sItem] = impl_loadItem(xSet, eType, sItem, E_READ_ALL);
1792 : _FILTER_CONFIG_LOG_2_("impl_loadItemOnDemand(%d, \"%s\") ... OK", (int)eType, _FILTER_CONFIG_TO_ASCII_(sItem).getStr())
1793 : }
1794 : else
1795 : {
1796 7588 : if (pItemInCache != pList->end())
1797 0 : pList->erase(pItemInCache);
1798 : // OK - this item does not exists inside configuration.
1799 : // And we already updated our internal cache.
1800 : // But the outside code needs this NoSuchElementException
1801 : // to know, that this item does notexists.
1802 : // Nobody checks the iterator!
1803 7588 : throw css::container::NoSuchElementException();
1804 : }
1805 :
1806 15176 : return pList->find(sItem);
1807 : }
1808 :
1809 :
1810 :
1811 0 : void FilterCache::impl_saveItem(const css::uno::Reference< css::container::XNameReplace >& xItem,
1812 : EItemType eType,
1813 : const CacheItem& aItem)
1814 : throw(css::uno::Exception)
1815 : {
1816 0 : CacheItem::const_iterator pIt;
1817 0 : switch(eType)
1818 : {
1819 :
1820 : case E_TYPE :
1821 : {
1822 0 : pIt = aItem.find(PROPNAME_PREFERREDFILTER);
1823 0 : if (pIt != aItem.end())
1824 0 : xItem->replaceByName(PROPNAME_PREFERREDFILTER, pIt->second);
1825 0 : pIt = aItem.find(PROPNAME_DETECTSERVICE);
1826 0 : if (pIt != aItem.end())
1827 0 : xItem->replaceByName(PROPNAME_DETECTSERVICE, pIt->second);
1828 0 : pIt = aItem.find(PROPNAME_URLPATTERN);
1829 0 : if (pIt != aItem.end())
1830 0 : xItem->replaceByName(PROPNAME_URLPATTERN, pIt->second);
1831 0 : pIt = aItem.find(PROPNAME_EXTENSIONS);
1832 0 : if (pIt != aItem.end())
1833 0 : xItem->replaceByName(PROPNAME_EXTENSIONS, pIt->second);
1834 0 : pIt = aItem.find(PROPNAME_PREFERRED);
1835 0 : if (pIt != aItem.end())
1836 0 : xItem->replaceByName(PROPNAME_PREFERRED, pIt->second);
1837 0 : pIt = aItem.find(PROPNAME_MEDIATYPE);
1838 0 : if (pIt != aItem.end())
1839 0 : xItem->replaceByName(PROPNAME_MEDIATYPE, pIt->second);
1840 0 : pIt = aItem.find(PROPNAME_CLIPBOARDFORMAT);
1841 0 : if (pIt != aItem.end())
1842 0 : xItem->replaceByName(PROPNAME_CLIPBOARDFORMAT, pIt->second);
1843 :
1844 0 : css::uno::Reference< css::container::XNameReplace > xUIName;
1845 0 : xItem->getByName(PROPNAME_UINAME) >>= xUIName;
1846 0 : impl_savePatchUINames(xUIName, aItem);
1847 : }
1848 0 : break;
1849 :
1850 :
1851 : case E_FILTER :
1852 : {
1853 0 : pIt = aItem.find(PROPNAME_TYPE);
1854 0 : if (pIt != aItem.end())
1855 0 : xItem->replaceByName(PROPNAME_TYPE, pIt->second);
1856 0 : pIt = aItem.find(PROPNAME_FILEFORMATVERSION);
1857 0 : if (pIt != aItem.end())
1858 0 : xItem->replaceByName(PROPNAME_FILEFORMATVERSION, pIt->second);
1859 0 : pIt = aItem.find(PROPNAME_UICOMPONENT);
1860 0 : if (pIt != aItem.end())
1861 0 : xItem->replaceByName(PROPNAME_UICOMPONENT, pIt->second);
1862 0 : pIt = aItem.find(PROPNAME_FILTERSERVICE);
1863 0 : if (pIt != aItem.end())
1864 0 : xItem->replaceByName(PROPNAME_FILTERSERVICE, pIt->second);
1865 0 : pIt = aItem.find(PROPNAME_DOCUMENTSERVICE);
1866 0 : if (pIt != aItem.end())
1867 0 : xItem->replaceByName(PROPNAME_DOCUMENTSERVICE, pIt->second);
1868 0 : pIt = aItem.find(PROPNAME_USERDATA);
1869 0 : if (pIt != aItem.end())
1870 0 : xItem->replaceByName(PROPNAME_USERDATA, pIt->second);
1871 0 : pIt = aItem.find(PROPNAME_TEMPLATENAME);
1872 0 : if (pIt != aItem.end())
1873 0 : xItem->replaceByName(PROPNAME_TEMPLATENAME, pIt->second);
1874 :
1875 : // special handling for flags! Convert it from an integer flag field back
1876 : // to a list of names ...
1877 : // But note: because we work directly on a reference to the cache item,
1878 : // its not allowd to change the value here. We must work on a copy!
1879 0 : pIt = aItem.find(PROPNAME_FLAGS);
1880 0 : if (pIt != aItem.end())
1881 : {
1882 0 : sal_Int32 nFlags = 0;
1883 0 : pIt->second >>= nFlags;
1884 0 : css::uno::Any aFlagNameList;
1885 0 : aFlagNameList <<= FilterCache::impl_convertFlagField2FlagNames(nFlags);
1886 0 : xItem->replaceByName(PROPNAME_FLAGS, aFlagNameList);
1887 : }
1888 :
1889 : //TODO remove it if moving of filter uinames to type uinames
1890 : // will be finished really
1891 : #ifdef AS_ENABLE_FILTER_UINAMES
1892 0 : css::uno::Reference< css::container::XNameReplace > xUIName;
1893 0 : xItem->getByName(PROPNAME_UINAME) >>= xUIName;
1894 0 : impl_savePatchUINames(xUIName, aItem);
1895 : #endif // AS_ENABLE_FILTER_UINAMES
1896 : }
1897 0 : break;
1898 :
1899 :
1900 : case E_FRAMELOADER :
1901 : case E_CONTENTHANDLER :
1902 : {
1903 0 : pIt = aItem.find(PROPNAME_TYPES);
1904 0 : if (pIt != aItem.end())
1905 0 : xItem->replaceByName(PROPNAME_TYPES, pIt->second);
1906 : }
1907 0 : break;
1908 0 : default: break;
1909 : }
1910 0 : }
1911 :
1912 : /*-----------------------------------------------
1913 : static! => no locks necessary
1914 : -----------------------------------------------*/
1915 0 : css::uno::Sequence< OUString > FilterCache::impl_convertFlagField2FlagNames(sal_Int32 nFlags)
1916 : {
1917 0 : OUStringList lFlagNames;
1918 :
1919 0 : if ((nFlags & FLAGVAL_3RDPARTYFILTER ) == FLAGVAL_3RDPARTYFILTER ) lFlagNames.push_back(FLAGNAME_3RDPARTYFILTER );
1920 0 : if ((nFlags & FLAGVAL_ALIEN ) == FLAGVAL_ALIEN ) lFlagNames.push_back(FLAGNAME_ALIEN );
1921 0 : if ((nFlags & FLAGVAL_ASYNCHRON ) == FLAGVAL_ASYNCHRON ) lFlagNames.push_back(FLAGNAME_ASYNCHRON );
1922 0 : if ((nFlags & FLAGVAL_BROWSERPREFERRED ) == FLAGVAL_BROWSERPREFERRED ) lFlagNames.push_back(FLAGNAME_BROWSERPREFERRED );
1923 0 : if ((nFlags & FLAGVAL_CONSULTSERVICE ) == FLAGVAL_CONSULTSERVICE ) lFlagNames.push_back(FLAGNAME_CONSULTSERVICE );
1924 0 : if ((nFlags & FLAGVAL_DEFAULT ) == FLAGVAL_DEFAULT ) lFlagNames.push_back(FLAGNAME_DEFAULT );
1925 0 : if ((nFlags & FLAGVAL_ENCRYPTION ) == FLAGVAL_ENCRYPTION ) lFlagNames.push_back(FLAGNAME_ENCRYPTION );
1926 0 : if ((nFlags & FLAGVAL_EXPORT ) == FLAGVAL_EXPORT ) lFlagNames.push_back(FLAGNAME_EXPORT );
1927 0 : if ((nFlags & FLAGVAL_IMPORT ) == FLAGVAL_IMPORT ) lFlagNames.push_back(FLAGNAME_IMPORT );
1928 0 : if ((nFlags & FLAGVAL_INTERNAL ) == FLAGVAL_INTERNAL ) lFlagNames.push_back(FLAGNAME_INTERNAL );
1929 0 : if ((nFlags & FLAGVAL_NOTINCHOOSER ) == FLAGVAL_NOTINCHOOSER ) lFlagNames.push_back(FLAGNAME_NOTINCHOOSER );
1930 0 : if ((nFlags & FLAGVAL_NOTINFILEDIALOG ) == FLAGVAL_NOTINFILEDIALOG ) lFlagNames.push_back(FLAGNAME_NOTINFILEDIALOG );
1931 0 : if ((nFlags & FLAGVAL_NOTINSTALLED ) == FLAGVAL_NOTINSTALLED ) lFlagNames.push_back(FLAGNAME_NOTINSTALLED );
1932 0 : if ((nFlags & FLAGVAL_OWN ) == FLAGVAL_OWN ) lFlagNames.push_back(FLAGNAME_OWN );
1933 0 : if ((nFlags & FLAGVAL_PACKED ) == FLAGVAL_PACKED ) lFlagNames.push_back(FLAGNAME_PACKED );
1934 0 : if ((nFlags & FLAGVAL_PASSWORDTOMODIFY ) == FLAGVAL_PASSWORDTOMODIFY ) lFlagNames.push_back(FLAGNAME_PASSWORDTOMODIFY );
1935 0 : if ((nFlags & FLAGVAL_PREFERRED ) == FLAGVAL_PREFERRED ) lFlagNames.push_back(FLAGNAME_PREFERRED );
1936 0 : if ((nFlags & FLAGVAL_STARTPRESENTATION) == FLAGVAL_STARTPRESENTATION) lFlagNames.push_back(FLAGNAME_STARTPRESENTATION);
1937 0 : if ((nFlags & FLAGVAL_READONLY ) == FLAGVAL_READONLY ) lFlagNames.push_back(FLAGNAME_READONLY );
1938 0 : if ((nFlags & FLAGVAL_SUPPORTSSELECTION) == FLAGVAL_SUPPORTSSELECTION) lFlagNames.push_back(FLAGNAME_SUPPORTSSELECTION);
1939 0 : if ((nFlags & FLAGVAL_TEMPLATE ) == FLAGVAL_TEMPLATE ) lFlagNames.push_back(FLAGNAME_TEMPLATE );
1940 0 : if ((nFlags & FLAGVAL_TEMPLATEPATH ) == FLAGVAL_TEMPLATEPATH ) lFlagNames.push_back(FLAGNAME_TEMPLATEPATH );
1941 0 : if ((nFlags & FLAGVAL_USESOPTIONS ) == FLAGVAL_USESOPTIONS ) lFlagNames.push_back(FLAGNAME_USESOPTIONS );
1942 0 : if ((nFlags & FLAGVAL_COMBINED ) == FLAGVAL_COMBINED ) lFlagNames.push_back(FLAGNAME_COMBINED );
1943 :
1944 0 : return lFlagNames.getAsConstList();
1945 : }
1946 :
1947 : /*-----------------------------------------------
1948 : static! => no locks necessary
1949 : -----------------------------------------------*/
1950 43152 : sal_Int32 FilterCache::impl_convertFlagNames2FlagField(const css::uno::Sequence< OUString >& lNames)
1951 : {
1952 43152 : sal_Int32 nField = 0;
1953 :
1954 43152 : const OUString* pNames = lNames.getConstArray();
1955 43152 : sal_Int32 c = lNames.getLength();
1956 224808 : for (sal_Int32 i=0; i<c; ++i)
1957 : {
1958 181656 : if (pNames[i] == FLAGNAME_3RDPARTYFILTER)
1959 : {
1960 20358 : nField |= FLAGVAL_3RDPARTYFILTER;
1961 20358 : continue;
1962 : }
1963 161298 : if (pNames[i] == FLAGNAME_ALIEN)
1964 : {
1965 38628 : nField |= FLAGVAL_ALIEN;
1966 38628 : continue;
1967 : }
1968 122670 : if (pNames[i] == FLAGNAME_ASYNCHRON)
1969 : {
1970 696 : nField |= FLAGVAL_ASYNCHRON;
1971 696 : continue;
1972 : }
1973 121974 : if (pNames[i] == FLAGNAME_BROWSERPREFERRED)
1974 : {
1975 0 : nField |= FLAGVAL_BROWSERPREFERRED;
1976 0 : continue;
1977 : }
1978 121974 : if (pNames[i] == FLAGNAME_CONSULTSERVICE)
1979 : {
1980 0 : nField |= FLAGVAL_CONSULTSERVICE;
1981 0 : continue;
1982 : }
1983 121974 : if (pNames[i] == FLAGNAME_DEFAULT)
1984 : {
1985 1740 : nField |= FLAGVAL_DEFAULT;
1986 1740 : continue;
1987 : }
1988 120234 : if (pNames[i] == FLAGNAME_ENCRYPTION)
1989 : {
1990 7656 : nField |= FLAGVAL_ENCRYPTION;
1991 7656 : continue;
1992 : }
1993 112578 : if (pNames[i] == FLAGNAME_EXPORT)
1994 : {
1995 20010 : nField |= FLAGVAL_EXPORT;
1996 20010 : continue;
1997 : }
1998 92568 : if (pNames[i] == FLAGNAME_IMPORT)
1999 : {
2000 33060 : nField |= FLAGVAL_IMPORT;
2001 33060 : continue;
2002 : }
2003 59508 : if (pNames[i] == FLAGNAME_INTERNAL)
2004 : {
2005 174 : nField |= FLAGVAL_INTERNAL;
2006 174 : continue;
2007 : }
2008 59334 : if (pNames[i] == FLAGNAME_NOTINCHOOSER)
2009 : {
2010 1740 : nField |= FLAGVAL_NOTINCHOOSER;
2011 1740 : continue;
2012 : }
2013 57594 : if (pNames[i] == FLAGNAME_NOTINFILEDIALOG)
2014 : {
2015 1566 : nField |= FLAGVAL_NOTINFILEDIALOG;
2016 1566 : continue;
2017 : }
2018 56028 : if (pNames[i] == FLAGNAME_NOTINSTALLED)
2019 : {
2020 0 : nField |= FLAGVAL_NOTINSTALLED;
2021 0 : continue;
2022 : }
2023 56028 : if (pNames[i] == FLAGNAME_OWN)
2024 : {
2025 5916 : nField |= FLAGVAL_OWN;
2026 5916 : continue;
2027 : }
2028 50112 : if (pNames[i] == FLAGNAME_PACKED)
2029 : {
2030 0 : nField |= FLAGVAL_PACKED;
2031 0 : continue;
2032 : }
2033 50112 : if (pNames[i] == FLAGNAME_PASSWORDTOMODIFY)
2034 : {
2035 4524 : nField |= FLAGVAL_PASSWORDTOMODIFY;
2036 4524 : continue;
2037 : }
2038 45588 : if (pNames[i] == FLAGNAME_PREFERRED)
2039 : {
2040 15834 : nField |= FLAGVAL_PREFERRED;
2041 15834 : continue;
2042 : }
2043 29754 : if (pNames[i] == FLAGNAME_STARTPRESENTATION)
2044 : {
2045 522 : nField |= FLAGVAL_STARTPRESENTATION;
2046 522 : continue;
2047 : }
2048 29232 : if (pNames[i] == FLAGNAME_READONLY)
2049 : {
2050 174 : nField |= FLAGVAL_READONLY;
2051 174 : continue;
2052 : }
2053 29058 : if (pNames[i] == FLAGNAME_SUPPORTSSELECTION)
2054 : {
2055 5568 : nField |= FLAGVAL_SUPPORTSSELECTION;
2056 5568 : continue;
2057 : }
2058 23490 : if (pNames[i] == FLAGNAME_TEMPLATE)
2059 : {
2060 7482 : nField |= FLAGVAL_TEMPLATE;
2061 7482 : continue;
2062 : }
2063 16008 : if (pNames[i] == FLAGNAME_TEMPLATEPATH)
2064 : {
2065 4176 : nField |= FLAGVAL_TEMPLATEPATH;
2066 4176 : continue;
2067 : }
2068 11832 : if (pNames[i] == FLAGNAME_USESOPTIONS)
2069 : {
2070 11484 : nField |= FLAGVAL_USESOPTIONS;
2071 11484 : continue;
2072 : }
2073 348 : if (pNames[i] == FLAGNAME_COMBINED)
2074 : {
2075 0 : nField |= FLAGVAL_COMBINED;
2076 0 : continue;
2077 : }
2078 : }
2079 :
2080 43152 : return nField;
2081 : }
2082 :
2083 :
2084 :
2085 0 : void FilterCache::impl_interpretDataVal4Type(const OUString& sValue,
2086 : sal_Int32 nProp ,
2087 : CacheItem& rItem )
2088 : {
2089 0 : switch(nProp)
2090 : {
2091 : // Preferred
2092 : case 0: {
2093 0 : if (sValue.toInt32() == 1)
2094 0 : rItem[PROPNAME_PREFERRED] = css::uno::makeAny(sal_True);
2095 : else
2096 0 : rItem[PROPNAME_PREFERRED] = css::uno::makeAny(sal_False);
2097 : }
2098 0 : break;
2099 : // MediaType
2100 0 : case 1: rItem[PROPNAME_MEDIATYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2101 0 : break;
2102 : // ClipboardFormat
2103 0 : case 2: rItem[PROPNAME_CLIPBOARDFORMAT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2104 0 : break;
2105 : // URLPattern
2106 0 : case 3: rItem[PROPNAME_URLPATTERN] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2107 0 : break;
2108 : // Extensions
2109 0 : case 4: rItem[PROPNAME_EXTENSIONS] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2110 0 : break;
2111 : }
2112 0 : }
2113 :
2114 :
2115 :
2116 0 : void FilterCache::impl_interpretDataVal4Filter(const OUString& sValue,
2117 : sal_Int32 nProp ,
2118 : CacheItem& rItem )
2119 : {
2120 0 : switch(nProp)
2121 : {
2122 : // Order
2123 : case 0: {
2124 0 : sal_Int32 nOrder = sValue.toInt32();
2125 0 : if (nOrder > 0)
2126 : {
2127 : SAL_WARN( "filter.config", "FilterCache::impl_interpretDataVal4Filter()\nCant move Order value from filter to type on demand!");
2128 : _FILTER_CONFIG_LOG_2_("impl_interpretDataVal4Filter(%d, \"%s\") ... OK", (int)eType, _FILTER_CONFIG_TO_ASCII_(rItem).getStr())
2129 : }
2130 : }
2131 0 : break;
2132 : // Type
2133 0 : case 1: rItem[PROPNAME_TYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2134 0 : break;
2135 : // DocumentService
2136 0 : case 2: rItem[PROPNAME_DOCUMENTSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2137 0 : break;
2138 : // FilterService
2139 0 : case 3: rItem[PROPNAME_FILTERSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2140 0 : break;
2141 : // Flags
2142 0 : case 4: rItem[PROPNAME_FLAGS] <<= sValue.toInt32();
2143 0 : break;
2144 : // UserData
2145 0 : case 5: rItem[PROPNAME_USERDATA] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
2146 0 : break;
2147 : // FileFormatVersion
2148 0 : case 6: rItem[PROPNAME_FILEFORMATVERSION] <<= sValue.toInt32();
2149 0 : break;
2150 : // TemplateName
2151 0 : case 7: rItem[PROPNAME_TEMPLATENAME] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2152 0 : break;
2153 : // [optional!] UIComponent
2154 0 : case 8: rItem[PROPNAME_UICOMPONENT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
2155 0 : break;
2156 : }
2157 0 : }
2158 :
2159 : /*-----------------------------------------------
2160 : TODO work on a cache copy first, which can be flushed afterwards
2161 : That would be useful to guarantee a consistent cache.
2162 : -----------------------------------------------*/
2163 180 : void FilterCache::impl_readOldFormat()
2164 : throw(css::uno::Exception)
2165 : {
2166 : // Attention: Opening/Reading of this old configuration format has to be handled gracefully.
2167 : // Its optional and should not disturb our normal work!
2168 : // E.g. we must check, if the package exists ...
2169 :
2170 180 : css::uno::Reference< css::container::XNameAccess > xCfg;
2171 : try
2172 : {
2173 180 : css::uno::Reference< css::uno::XInterface > xInt = impl_openConfig(E_PROVIDER_OLD);
2174 180 : xCfg = css::uno::Reference< css::container::XNameAccess >(xInt, css::uno::UNO_QUERY_THROW);
2175 : }
2176 : /* corrupt filter addon ? because it's external (optional) code .. we can ignore it. Addon wont work then ...
2177 : but that seems to be acceptable.
2178 : see #139088# for further information
2179 : */
2180 0 : catch(const css::uno::Exception&)
2181 180 : { return; }
2182 :
2183 360 : OUString TYPES_SET("Types");
2184 :
2185 : // May be there is no type set ...
2186 180 : if (xCfg->hasByName(TYPES_SET))
2187 : {
2188 180 : css::uno::Reference< css::container::XNameAccess > xSet;
2189 180 : xCfg->getByName(TYPES_SET) >>= xSet;
2190 360 : const css::uno::Sequence< OUString > lItems = xSet->getElementNames();
2191 180 : const OUString* pItems = lItems.getConstArray();
2192 180 : for (sal_Int32 i=0; i<lItems.getLength(); ++i)
2193 180 : m_lTypes[pItems[i]] = impl_readOldItem(xSet, E_TYPE, pItems[i]);
2194 : }
2195 :
2196 360 : OUString FILTER_SET("Filters");
2197 : // May be there is no filter set ...
2198 180 : if (xCfg->hasByName(FILTER_SET))
2199 : {
2200 180 : css::uno::Reference< css::container::XNameAccess > xSet;
2201 180 : xCfg->getByName(FILTER_SET) >>= xSet;
2202 360 : const css::uno::Sequence< OUString > lItems = xSet->getElementNames();
2203 180 : const OUString* pItems = lItems.getConstArray();
2204 180 : for (sal_Int32 i=0; i<lItems.getLength(); ++i)
2205 180 : m_lFilters[pItems[i]] = impl_readOldItem(xSet, E_FILTER, pItems[i]);
2206 180 : }
2207 : }
2208 :
2209 :
2210 :
2211 0 : CacheItem FilterCache::impl_readOldItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
2212 : EItemType eType,
2213 : const OUString& sItem)
2214 : throw(css::uno::Exception)
2215 : {
2216 0 : css::uno::Reference< css::container::XNameAccess > xItem;
2217 0 : xSet->getByName(sItem) >>= xItem;
2218 0 : if (!xItem.is())
2219 0 : throw css::uno::Exception("Cant read old item.", css::uno::Reference< css::uno::XInterface >());
2220 :
2221 0 : CacheItem aItem;
2222 0 : aItem[PROPNAME_NAME] <<= sItem;
2223 :
2224 : // Installed flag ...
2225 : // Isn't used any longer!
2226 :
2227 : // UIName
2228 0 : impl_readPatchUINames(xItem, aItem);
2229 :
2230 : // Data
2231 0 : OUString sData;
2232 0 : OUStringList lData;
2233 0 : xItem->getByName( "Data" ) >>= sData;
2234 0 : lData = impl_tokenizeString(sData, (sal_Unicode)',');
2235 0 : if (
2236 0 : (sData.isEmpty()) ||
2237 0 : (lData.size()<1 )
2238 : )
2239 : {
2240 0 : throw css::uno::Exception( "Cant read old item property DATA.", css::uno::Reference< css::uno::XInterface >());
2241 : }
2242 :
2243 0 : sal_Int32 nProp = 0;
2244 0 : for (OUStringList::const_iterator pProp = lData.begin();
2245 0 : pProp != lData.end() ;
2246 : ++pProp )
2247 : {
2248 0 : const OUString& sProp = *pProp;
2249 0 : switch(eType)
2250 : {
2251 : case E_TYPE :
2252 0 : impl_interpretDataVal4Type(sProp, nProp, aItem);
2253 0 : break;
2254 :
2255 : case E_FILTER :
2256 0 : impl_interpretDataVal4Filter(sProp, nProp, aItem);
2257 0 : break;
2258 0 : default: break;
2259 : }
2260 0 : ++nProp;
2261 : }
2262 :
2263 0 : return aItem;
2264 : }
2265 :
2266 :
2267 :
2268 0 : OUStringList FilterCache::impl_tokenizeString(const OUString& sData ,
2269 : sal_Unicode cSeparator)
2270 : {
2271 0 : OUStringList lData ;
2272 0 : sal_Int32 nToken = 0;
2273 0 : do
2274 : {
2275 0 : OUString sToken = sData.getToken(0, cSeparator, nToken);
2276 0 : lData.push_back(sToken);
2277 : }
2278 0 : while(nToken >= 0);
2279 0 : return lData;
2280 : }
2281 :
2282 : #if OSL_DEBUG_LEVEL > 0
2283 :
2284 :
2285 : OUString FilterCache::impl_searchFrameLoaderForType(const OUString& sType) const
2286 : {
2287 : CacheItemList::const_iterator pIt;
2288 : for ( pIt = m_lFrameLoaders.begin();
2289 : pIt != m_lFrameLoaders.end() ;
2290 : ++pIt )
2291 : {
2292 : const OUString& sItem = pIt->first;
2293 : ::comphelper::SequenceAsHashMap lProps(pIt->second);
2294 : OUStringList lTypes(lProps[PROPNAME_TYPES]);
2295 :
2296 : if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
2297 : return sItem;
2298 : }
2299 :
2300 : return OUString();
2301 : }
2302 :
2303 :
2304 :
2305 : OUString FilterCache::impl_searchContentHandlerForType(const OUString& sType) const
2306 : {
2307 : CacheItemList::const_iterator pIt;
2308 : for ( pIt = m_lContentHandlers.begin();
2309 : pIt != m_lContentHandlers.end() ;
2310 : ++pIt )
2311 : {
2312 : const OUString& sItem = pIt->first;
2313 : ::comphelper::SequenceAsHashMap lProps(pIt->second);
2314 : OUStringList lTypes(lProps[PROPNAME_TYPES]);
2315 : if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
2316 : return sItem;
2317 : }
2318 :
2319 : return OUString();
2320 : }
2321 : #endif
2322 :
2323 :
2324 :
2325 1678316 : bool FilterCache::impl_isModuleInstalled(const OUString& sModule)
2326 : {
2327 1678316 : css::uno::Reference< css::container::XNameAccess > xCfg;
2328 :
2329 : // SAFE ->
2330 3356632 : ::osl::ResettableMutexGuard aLock(m_aLock);
2331 1678316 : if (! m_xModuleCfg.is())
2332 : {
2333 174 : m_xModuleCfg = officecfg::Setup::Office::Factories::get();
2334 : }
2335 :
2336 1678316 : xCfg = m_xModuleCfg;
2337 1678316 : aLock.clear();
2338 : // <- SAFE
2339 :
2340 1678316 : if (xCfg.is())
2341 1678316 : return xCfg->hasByName(sModule);
2342 :
2343 1678316 : return false;
2344 : }
2345 :
2346 : } // namespace config
2347 : } // namespace filter
2348 :
2349 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|