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