1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "filtercache.hxx"
22 #include "lateinitlistener.hxx"
24 #include "constant.hxx"
25 #include "cacheupdatelistener.hxx"
27 /*TODO see using below ... */
28 #define AS_ENABLE_FILTER_UINAMES
29 #define WORKAROUND_EXCEPTION_PROBLEM
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>
45 #include <unotools/configpaths.hxx>
46 #include <rtl/ustrbuf.hxx>
47 #include <rtl/logfile.hxx>
48 #include <rtl/uri.hxx>
49 #include <tools/urlobj.hxx>
50 #include <tools/wldcrd.hxx>
51 #include <i18nlangtag/languagetag.hxx>
53 #include <comphelper/configurationhelper.hxx>
59 FilterCache::FilterCache()
61 , m_eFillState(E_CONTAINS_NOTHING
)
63 RTL_LOGFILE_TRACE("{ (as96863) FilterCache lifetime");
68 FilterCache::~FilterCache()
70 RTL_LOGFILE_TRACE("} (as96863) FilterCache lifetime");
71 if (m_xTypesChglisteners
.is())
72 m_xTypesChglisteners
->stopListening();
73 if (m_xFiltersChgListener
.is())
74 m_xFiltersChgListener
->stopListening();
79 FilterCache
* FilterCache::clone() const
81 // SAFE -> ----------------------------------
82 ::osl::ResettableMutexGuard
aLock(m_aLock
);
84 FilterCache
* pClone
= new FilterCache();
86 // Dont copy the configuration access points here.
87 // They will be created on demand inside the cloned instance,
88 // if they are needed.
90 pClone
->m_lTypes
= m_lTypes
;
91 pClone
->m_lDetectServices
= m_lDetectServices
;
92 pClone
->m_lFilters
= m_lFilters
;
93 pClone
->m_lFrameLoaders
= m_lFrameLoaders
;
94 pClone
->m_lContentHandlers
= m_lContentHandlers
;
95 pClone
->m_lExtensions2Types
= m_lExtensions2Types
;
96 pClone
->m_lURLPattern2Types
= m_lURLPattern2Types
;
98 pClone
->m_sActLocale
= m_sActLocale
;
99 pClone
->m_sFormatName
= m_sFormatName
;
100 pClone
->m_sFormatVersion
= m_sFormatVersion
;
102 pClone
->m_eFillState
= m_eFillState
;
104 pClone
->m_lChangedTypes
= m_lChangedTypes
;
105 pClone
->m_lChangedFilters
= m_lChangedFilters
;
106 pClone
->m_lChangedDetectServices
= m_lChangedDetectServices
;
107 pClone
->m_lChangedFrameLoaders
= m_lChangedFrameLoaders
;
108 pClone
->m_lChangedContentHandlers
= m_lChangedContentHandlers
;
111 // <- SAFE ----------------------------------
116 void FilterCache::takeOver(const FilterCache
& rClone
)
118 // SAFE -> ----------------------------------
119 ::osl::ResettableMutexGuard
aLock(m_aLock
);
122 // Dont copy the configuration access points here!
123 // We must use our own ones ...
126 // Further we can ignore the uno service manager.
127 // We should already have a valid instance.
130 // Take over only changed items!
131 // Otherwise we risk the following scenario:
132 // c1) clone_1 contains changed filters
133 // c2) clone_2 container changed types
134 // c3) clone_1 take over changed filters and unchanged types
135 // c4) clone_2 take over unchanged filters(!) and changed types(!)
136 // c5) c4 overwrites c3!
138 if (rClone
.m_lChangedTypes
.size()>0)
139 m_lTypes
= rClone
.m_lTypes
;
140 if (rClone
.m_lChangedDetectServices
.size()>0)
141 m_lDetectServices
= rClone
.m_lDetectServices
;
142 if (rClone
.m_lChangedFilters
.size()>0)
143 m_lFilters
= rClone
.m_lFilters
;
144 if (rClone
.m_lChangedFrameLoaders
.size()>0)
145 m_lFrameLoaders
= rClone
.m_lFrameLoaders
;
146 if (rClone
.m_lChangedContentHandlers
.size()>0)
147 m_lContentHandlers
= rClone
.m_lContentHandlers
;
149 m_lChangedTypes
.clear();
150 m_lChangedDetectServices
.clear();
151 m_lChangedFilters
.clear();
152 m_lChangedFrameLoaders
.clear();
153 m_lChangedContentHandlers
.clear();
155 m_sActLocale
= rClone
.m_sActLocale
;
156 m_sFormatName
= rClone
.m_sFormatName
;
157 m_sFormatVersion
= rClone
.m_sFormatVersion
;
159 m_eFillState
= rClone
.m_eFillState
;
161 // renew all dependencies and optimizations
162 // Because we cant be shure, that changed filters on one clone
163 // and changed types of another clone work together.
164 // But here we can check against the lates changes ...
165 impl_validateAndOptimize();
166 // <- SAFE ----------------------------------
171 void FilterCache::load(EFillState eRequired
,
172 #if OSL_DEBUG_LEVEL > 1
178 throw(css::uno::Exception
)
180 // SAFE -> ----------------------------------
181 ::osl::ResettableMutexGuard
aLock(m_aLock
);
183 // check if required fill state is already reached ...
184 // There is nothing to do then.
185 if ((m_eFillState
& eRequired
) == eRequired
)
188 #if OSL_DEBUG_LEVEL > 1
189 if (!bByThread
&& ((eRequired
& E_CONTAINS_ALL
) == E_CONTAINS_ALL
))
191 OSL_FAIL("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!");
195 // Otherwise load the missing items.
197 // ------------------------------------------
198 // a) load some const values from configration.
199 // These values are needed there for loading
201 // Further we load some std items from the
202 // configuration so we can try to load the first
203 // office document with a minimal set of values.
204 if (m_eFillState
== E_CONTAINS_NOTHING
)
206 impl_getDirectCFGValue(CFGDIRECTKEY_OFFICELOCALE
) >>= m_sActLocale
;
207 if (m_sActLocale
.isEmpty())
209 _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify office locale => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_OFFICELOCALE
));
210 m_sActLocale
= DEFAULT_OFFICELOCALE
;
213 impl_getDirectCFGValue(CFGDIRECTKEY_FORMATNAME
) >>= m_sFormatName
;
214 if (m_sFormatName
.isEmpty())
215 impl_getDirectCFGValue(CFGDIRECTKEY_PRODUCTNAME
) >>= m_sFormatName
;
217 if (m_sFormatName
.isEmpty())
219 _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify format name => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_FORMATNAME
));
220 m_sFormatName
= DEFAULT_FORMATNAME
;
223 impl_getDirectCFGValue(CFGDIRECTKEY_FORMATVERSION
) >>= m_sFormatVersion
;
224 if (m_sFormatVersion
.isEmpty())
226 _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify format version => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_FORMATVERSION
));
227 m_sFormatVersion
= DEFAULT_FORMATVERSION
;
230 // Support the old configuration support. Read it only one times during office runtime!
231 impl_readOldFormat();
233 // enable "loadOnDemand" feature ...
234 // Create uno listener, which waits for finishing the office startup
235 // and starts a thread, which calls loadAll() at this filter cache.
236 // Note: Its not a leak to create this listener with new here.
237 // It kills itself after working!
238 /* LateInitListener* pLateInit = */ new LateInitListener(comphelper::getProcessComponentContext());
241 // ------------------------------------------
242 // b) If the required fill state was not reached
243 // but std values was already loaded ...
244 // we must load some further missing items.
245 impl_load(eRequired
);
251 sal_Bool
FilterCache::isFillState(FilterCache::EFillState eState
) const
252 throw(css::uno::Exception
)
255 ::osl::ResettableMutexGuard
aLock(m_aLock
);
256 return ((m_eFillState
& eState
) == eState
);
262 OUStringList
FilterCache::getMatchingItemsByProps( EItemType eType
,
263 const CacheItem
& lIProps
,
264 const CacheItem
& lEProps
) const
265 throw(css::uno::Exception
)
268 ::osl::ResettableMutexGuard
aLock(m_aLock
);
270 // search for right list
271 // An exception is thrown - "eType" is unknown.
272 // => rList will be valid everytimes next line is reached.
273 const CacheItemList
& rList
= impl_getItemList(eType
);
277 // search items, which provides all needed properties of set "lIProps"
278 // but not of set "lEProps"!
279 for (CacheItemList::const_iterator pIt
= rList
.begin();
283 _FILTER_CONFIG_LOG_1_("getMatchingProps for \"%s\" ...\n",
284 _FILTER_CONFIG_TO_ASCII_(pIt
->first
))
286 (pIt
->second
.haveProps(lIProps
) ) &&
287 (pIt
->second
.dontHaveProps(lEProps
))
290 lKeys
.push_back(pIt
->first
);
300 sal_Bool
FilterCache::hasItems(EItemType eType
) const
301 throw(css::uno::Exception
)
304 ::osl::ResettableMutexGuard
aLock(m_aLock
);
306 // search for right list
307 // An exception is thrown - "eType" is unknown.
308 // => rList will be valid everytimes next line is reached.
309 const CacheItemList
& rList
= impl_getItemList(eType
);
311 return !rList
.empty();
317 OUStringList
FilterCache::getItemNames(EItemType eType
) const
318 throw(css::uno::Exception
)
321 ::osl::ResettableMutexGuard
aLock(m_aLock
);
323 // search for right list
324 // An exception is thrown - "eType" is unknown.
325 // => rList will be valid everytimes next line is reached.
326 const CacheItemList
& rList
= impl_getItemList(eType
);
329 for (CacheItemList::const_iterator pIt
= rList
.begin();
333 lKeys
.push_back(pIt
->first
);
341 sal_Bool
FilterCache::hasItem( EItemType eType
,
342 const OUString
& sItem
)
343 throw(css::uno::Exception
)
346 ::osl::ResettableMutexGuard
aLock(m_aLock
);
348 // search for right list
349 // An exception is thrown - "eType" is unknown.
350 // => rList will be valid everytimes next line is reached.
351 const CacheItemList
& rList
= impl_getItemList(eType
);
353 // if item could not be found - check if it can be loaded
354 // from the underlying configuration layer. Might it was not already
355 // loaded into this FilterCache object before.
356 CacheItemList::const_iterator pIt
= rList
.find(sItem
);
357 if (pIt
!= rList
.end())
362 impl_loadItemOnDemand(eType
, sItem
);
363 // no exception => item could be loaded!
366 catch(const css::container::NoSuchElementException
&)
375 CacheItem
FilterCache::getItem( EItemType eType
,
376 const OUString
& sItem
)
377 throw(css::uno::Exception
)
380 ::osl::ResettableMutexGuard
aLock(m_aLock
);
382 // search for right list
383 // An exception is thrown if "eType" is unknown.
384 // => rList will be valid everytimes next line is reached.
385 CacheItemList
& rList
= impl_getItemList(eType
);
387 // check if item exists ...
388 CacheItemList::iterator pIt
= rList
.find(sItem
);
389 if (pIt
== rList
.end())
391 // ... or load it on demand from the
392 // underlying configuration layer.
393 // Note: NoSuchElementException is thrown automaticly here if
394 // item could not be loaded!
395 pIt
= impl_loadItemOnDemand(eType
, sItem
);
398 /* Workaround for #137955#
399 Draw types and filters are installed ... but draw was disabled during setup.
400 We must supress accessing these filters. Otherwise the office can crash.
401 Solution for the next major release: do not install those filters !
403 if (eType
== E_FILTER
)
405 CacheItem
& rFilter
= pIt
->second
;
406 OUString sDocService
;
407 rFilter
[PROPNAME_DOCUMENTSERVICE
] >>= sDocService
;
409 // In Standalone-Impress the module WriterWeb is not installed
410 // but it is there to load help pages
411 bool bIsHelpFilter
= sItem
== "writer_web_HTML_help";
413 if ( !bIsHelpFilter
&& !impl_isModuleInstalled(sDocService
) )
415 OUString
sMsg("The requested filter '" + sItem
+
416 "' exists ... but it shouldnt; because the corresponding LibreOffice module was not installed.");
417 throw css::container::NoSuchElementException(sMsg
, css::uno::Reference
< css::uno::XInterface
>());
427 void FilterCache::removeItem( EItemType eType
,
428 const OUString
& sItem
)
429 throw(css::uno::Exception
)
432 ::osl::ResettableMutexGuard
aLock(m_aLock
);
434 // search for right list
435 // An exception is thrown - "eType" is unknown.
436 // => rList will be valid everytimes next line is reached.
437 CacheItemList
& rList
= impl_getItemList(eType
);
439 CacheItemList::iterator pItem
= rList
.find(sItem
);
440 if (pItem
== rList
.end())
441 pItem
= impl_loadItemOnDemand(eType
, sItem
); // throws NoSuchELementException!
444 impl_addItem2FlushList(eType
, sItem
);
449 void FilterCache::setItem( EItemType eType
,
450 const OUString
& sItem
,
451 const CacheItem
& aValue
)
452 throw(css::uno::Exception
)
455 ::osl::ResettableMutexGuard
aLock(m_aLock
);
457 // search for right list
458 // An exception is thrown - "eType" is unknown.
459 // => rList will be valid everytimes next line is reached.
460 CacheItemList
& rList
= impl_getItemList(eType
);
462 // name must be part of the property set too ... otherwise our
463 // container query cant work correctly
464 CacheItem aItem
= aValue
;
465 aItem
[PROPNAME_NAME
] <<= sItem
;
466 aItem
.validateUINames(m_sActLocale
);
468 // remove implicit properties as e.g. FINALIZED or MANDATORY
469 // They cant be saved here and must be readed on demand later, if they are needed.
470 removeStatePropsFromItem(aItem
);
472 rList
[sItem
] = aItem
;
474 impl_addItem2FlushList(eType
, sItem
);
477 //-----------------------------------------------
478 void FilterCache::refreshItem( EItemType eType
,
479 const OUString
& sItem
)
480 throw(css::uno::Exception
)
483 ::osl::ResettableMutexGuard
aLock(m_aLock
);
484 impl_loadItemOnDemand(eType
, sItem
);
489 void FilterCache::addStatePropsToItem( EItemType eType
,
490 const OUString
& sItem
,
492 throw(css::uno::Exception
)
495 ::osl::ResettableMutexGuard
aLock(m_aLock
);
497 // Note: Opening of the configuration layer throws some exceptions
498 // if it failed. So we dont must check any reference here ...
499 css::uno::Reference
< css::container::XNameAccess
> xPackage
;
500 css::uno::Reference
< css::container::XNameAccess
> xSet
;
505 xPackage
= css::uno::Reference
< css::container::XNameAccess
>(impl_openConfig(E_PROVIDER_TYPES
), css::uno::UNO_QUERY_THROW
);
506 xPackage
->getByName(CFGSET_TYPES
) >>= xSet
;
512 xPackage
= css::uno::Reference
< css::container::XNameAccess
>(impl_openConfig(E_PROVIDER_FILTERS
), css::uno::UNO_QUERY_THROW
);
513 xPackage
->getByName(CFGSET_FILTERS
) >>= xSet
;
521 The default frame loader cant be located inside te normal set of frame loaders.
522 Its an atomic property inside the misc cfg package. So we cant retrieve the information
523 about FINALIZED and MANDATORY very easy ... :-(
524 => set it to readonly/required everytimes :-)
526 css::uno::Any aDirectValue
= impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER
);
527 OUString sDefaultFrameLoader
;
529 (aDirectValue
>>= sDefaultFrameLoader
) &&
530 (!sDefaultFrameLoader
.isEmpty() ) &&
531 (sItem
.equals(sDefaultFrameLoader
) )
534 rItem
[PROPNAME_FINALIZED
] <<= sal_True
;
535 rItem
[PROPNAME_MANDATORY
] <<= sal_True
;
540 xPackage
= css::uno::Reference
< css::container::XNameAccess
>(impl_openConfig(E_PROVIDER_OTHERS
), css::uno::UNO_QUERY_THROW
);
541 xPackage
->getByName(CFGSET_FRAMELOADERS
) >>= xSet
;
545 case E_CONTENTHANDLER
:
547 xPackage
= css::uno::Reference
< css::container::XNameAccess
>(impl_openConfig(E_PROVIDER_OTHERS
), css::uno::UNO_QUERY_THROW
);
548 xPackage
->getByName(CFGSET_CONTENTHANDLERS
) >>= xSet
;
556 css::uno::Reference
< css::beans::XProperty
> xItem
;
557 xSet
->getByName(sItem
) >>= xItem
;
558 css::beans::Property aDescription
= xItem
->getAsProperty();
560 sal_Bool bFinalized
= ((aDescription
.Attributes
& css::beans::PropertyAttribute::READONLY
) == css::beans::PropertyAttribute::READONLY
);
561 sal_Bool bMandatory
= ((aDescription
.Attributes
& css::beans::PropertyAttribute::REMOVABLE
) != css::beans::PropertyAttribute::REMOVABLE
);
563 rItem
[PROPNAME_FINALIZED
] <<= bFinalized
;
564 rItem
[PROPNAME_MANDATORY
] <<= bMandatory
;
566 catch(const css::container::NoSuchElementException
&)
568 /* Ignore exceptions for missing elements inside configuration.
569 May by the following reason exists:
570 - The item does not exists inside the new configuration package org.openoffice.TypeDetection - but
571 we got it from the old package org.openoffice.Office/TypeDetection. We dont migrate such items
572 automaticly to the new format. Because it will disturb e.g. the deinstallation of an external filter
573 package. Because such external filter can remove the old file - but not the automaticly created new one ...
575 => mark item as FINALIZED / MANDATORY, we dont support writing to the old format
577 rItem
[PROPNAME_FINALIZED
] <<= sal_True
;
578 rItem
[PROPNAME_MANDATORY
] <<= sal_True
;
586 void FilterCache::removeStatePropsFromItem(CacheItem
& rItem
)
587 throw(css::uno::Exception
)
589 CacheItem::iterator pIt
;
590 pIt
= rItem
.find(PROPNAME_FINALIZED
);
591 if (pIt
!= rItem
.end())
593 pIt
= rItem
.find(PROPNAME_MANDATORY
);
594 if (pIt
!= rItem
.end())
600 void FilterCache::flush()
601 throw(css::uno::Exception
)
604 ::osl::ResettableMutexGuard
aLock(m_aLock
);
606 // renew all dependencies and optimizations
607 impl_validateAndOptimize();
609 if (m_lChangedTypes
.size() > 0)
611 css::uno::Reference
< css::container::XNameAccess
> xConfig(impl_openConfig(E_PROVIDER_TYPES
), css::uno::UNO_QUERY_THROW
);
612 css::uno::Reference
< css::container::XNameAccess
> xSet
;
614 xConfig
->getByName(CFGSET_TYPES
) >>= xSet
;
615 impl_flushByList(xSet
, E_TYPE
, m_lTypes
, m_lChangedTypes
);
617 css::uno::Reference
< css::util::XChangesBatch
> xFlush(xConfig
, css::uno::UNO_QUERY
);
618 xFlush
->commitChanges();
621 if (m_lChangedFilters
.size() > 0)
623 css::uno::Reference
< css::container::XNameAccess
> xConfig(impl_openConfig(E_PROVIDER_FILTERS
), css::uno::UNO_QUERY_THROW
);
624 css::uno::Reference
< css::container::XNameAccess
> xSet
;
626 xConfig
->getByName(CFGSET_FILTERS
) >>= xSet
;
627 impl_flushByList(xSet
, E_FILTER
, m_lFilters
, m_lChangedFilters
);
629 css::uno::Reference
< css::util::XChangesBatch
> xFlush(xConfig
, css::uno::UNO_QUERY
);
630 xFlush
->commitChanges();
633 /*TODO FrameLoader/ContentHandler must be flushed here too ... */
638 void FilterCache::impl_flushByList(const css::uno::Reference
< css::container::XNameAccess
>& xSet
,
640 const CacheItemList
& rCache
,
641 const OUStringList
& lItems
)
642 throw(css::uno::Exception
)
644 css::uno::Reference
< css::container::XNameContainer
> xAddRemoveSet
= css::uno::Reference
< css::container::XNameContainer
> (xSet
, css::uno::UNO_QUERY
);
645 css::uno::Reference
< css::container::XNameReplace
> xReplaceeSet
= css::uno::Reference
< css::container::XNameReplace
> (xSet
, css::uno::UNO_QUERY
);
646 css::uno::Reference
< css::lang::XSingleServiceFactory
> xFactory
= css::uno::Reference
< css::lang::XSingleServiceFactory
>(xSet
, css::uno::UNO_QUERY
);
648 for (OUStringList::const_iterator pIt
= lItems
.begin();
649 pIt
!= lItems
.end() ;
652 const OUString
& sItem
= *pIt
;
653 EItemFlushState eState
= impl_specifyFlushOperation(xSet
, rCache
, sItem
);
656 case E_ITEM_REMOVED
:
658 xAddRemoveSet
->removeByName(sItem
);
664 css::uno::Reference
< css::container::XNameReplace
> xItem (xFactory
->createInstance(), css::uno::UNO_QUERY
);
666 // special case. no exception - but not a valid item => set must be finalized or mandatory!
667 // Reject flush operation by throwing an exception. At least one item couldnt be flushed.
669 throw css::uno::Exception("Cant add item. Set is finalized or mandatory!",
670 css::uno::Reference
< css::uno::XInterface
>());
672 CacheItemList::const_iterator pItem
= rCache
.find(sItem
);
673 impl_saveItem(xItem
, eType
, pItem
->second
);
674 xAddRemoveSet
->insertByName(sItem
, css::uno::makeAny(xItem
));
678 case E_ITEM_CHANGED
:
680 css::uno::Reference
< css::container::XNameReplace
> xItem
;
681 xSet
->getByName(sItem
) >>= xItem
;
683 // special case. no exception - but not a valid item => it must be finalized or mandatory!
684 // Reject flush operation by throwing an exception. At least one item couldnt be flushed.
686 throw css::uno::Exception("Cant change item. Its finalized or mandatory!",
687 css::uno::Reference
< css::uno::XInterface
>());
689 CacheItemList::const_iterator pItem
= rCache
.find(sItem
);
690 impl_saveItem(xItem
, eType
, pItem
->second
);
700 void FilterCache::detectFlatForURL(const css::util::URL
& aURL
,
701 FlatDetection
& rFlatTypes
) const
702 throw(css::uno::Exception
)
704 // extract extension from URL, so it can be used directly as key into our hash map!
705 // Note further: It must be converted to lower case, because the optimize hash
706 // (which maps extensions to types) work with lower case key strings!
707 INetURLObject
aParser (aURL
.Main
);
708 OUString sExtension
= aParser
.getExtension(INetURLObject::LAST_SEGMENT
,
710 INetURLObject::DECODE_WITH_CHARSET
);
711 sExtension
= sExtension
.toAsciiLowerCase();
713 // SAFE -> ----------------------------------
714 ::osl::ResettableMutexGuard
aLock(m_aLock
);
716 //*******************************************
717 // i) Step over all well known URL pattern
718 // and add registered types to the return list too
719 // Do it as first one - because: if a type match by a
720 // pattern a following deep detection can be supressed!
721 // Further we can stop after first match ...
722 for (CacheItemRegistration::const_iterator pPattReg
= m_lURLPattern2Types
.begin();
723 pPattReg
!= m_lURLPattern2Types
.end() ;
726 WildCard
aPatternCheck(pPattReg
->first
);
727 if (aPatternCheck
.Matches(aURL
.Main
))
729 const OUStringList
& rTypesForPattern
= pPattReg
->second
;
731 FlatDetectionInfo aInfo
;
732 aInfo
.sType
= *(rTypesForPattern
.begin());
733 aInfo
.bMatchByPattern
= sal_True
;
735 rFlatTypes
.push_back(aInfo
);
740 //*******************************************
741 // ii) search types matching to the given extension.
742 // Copy every macthing type without changing its order!
743 // Because preferred types was added as first one during
744 // loading configuration.
745 CacheItemRegistration::const_iterator pExtReg
= m_lExtensions2Types
.find(sExtension
);
746 if (pExtReg
!= m_lExtensions2Types
.end())
748 const OUStringList
& rTypesForExtension
= pExtReg
->second
;
749 for (OUStringList::const_iterator pIt
= rTypesForExtension
.begin();
750 pIt
!= rTypesForExtension
.end() ;
753 FlatDetectionInfo aInfo
;
755 aInfo
.bMatchByExtension
= sal_True
;
757 rFlatTypes
.push_back(aInfo
);
762 // <- SAFE ----------------------------------
765 const CacheItemList
& FilterCache::impl_getItemList(EItemType eType
) const
767 // SAFE -> ----------------------------------
768 ::osl::ResettableMutexGuard
aLock(m_aLock
);
772 case E_TYPE
: return m_lTypes
;
773 case E_FILTER
: return m_lFilters
;
774 case E_FRAMELOADER
: return m_lFrameLoaders
;
775 case E_CONTENTHANDLER
: return m_lContentHandlers
;
776 case E_DETECTSERVICE
: return m_lDetectServices
;
780 throw css::uno::Exception("unknown sub container requested.",
781 css::uno::Reference
< css::uno::XInterface
>());
782 // <- SAFE ----------------------------------
785 CacheItemList
& FilterCache::impl_getItemList(EItemType eType
)
787 // SAFE -> ----------------------------------
788 ::osl::ResettableMutexGuard
aLock(m_aLock
);
792 case E_TYPE
: return m_lTypes
;
793 case E_FILTER
: return m_lFilters
;
794 case E_FRAMELOADER
: return m_lFrameLoaders
;
795 case E_CONTENTHANDLER
: return m_lContentHandlers
;
796 case E_DETECTSERVICE
: return m_lDetectServices
;
800 throw css::uno::Exception("unknown sub container requested.",
801 css::uno::Reference
< css::uno::XInterface
>());
802 // <- SAFE ----------------------------------
805 css::uno::Reference
< css::uno::XInterface
> FilterCache::impl_openConfig(EConfigProvider eProvider
)
806 throw(css::uno::Exception
)
808 ::osl::ResettableMutexGuard
aLock(m_aLock
);
811 css::uno::Reference
< css::uno::XInterface
>* pConfig
= 0;
812 css::uno::Reference
< css::uno::XInterface
> xOld
;
817 case E_PROVIDER_TYPES
:
819 if (m_xConfigTypes
.is())
820 return m_xConfigTypes
;
821 sPath
= CFGPACKAGE_TD_TYPES
;
822 pConfig
= &m_xConfigTypes
;
823 sRtlLog
= "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_TYPES)";
827 case E_PROVIDER_FILTERS
:
829 if (m_xConfigFilters
.is())
830 return m_xConfigFilters
;
831 sPath
= CFGPACKAGE_TD_FILTERS
;
832 pConfig
= &m_xConfigFilters
;
833 sRtlLog
= "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_FILTERS)";
837 case E_PROVIDER_OTHERS
:
839 if (m_xConfigOthers
.is())
840 return m_xConfigOthers
;
841 sPath
= CFGPACKAGE_TD_OTHERS
;
842 pConfig
= &m_xConfigOthers
;
843 sRtlLog
= "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OTHERS)";
847 case E_PROVIDER_OLD
:
849 // This special provider is used to work with
850 // the old configuration format only. Its not cached!
851 sPath
= CFGPACKAGE_TD_OLD
;
853 sRtlLog
= "framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OLD)";
857 default : throw css::uno::Exception("These configuration node isnt supported here for open!", 0);
861 RTL_LOGFILE_CONTEXT(aLog
, sRtlLog
.getStr());
862 *pConfig
= impl_createConfigAccess(sPath
,
863 sal_False
, // bReadOnly
864 sal_True
); // bLocalesMode
868 // Start listening for changes on that configuration access.
871 case E_PROVIDER_TYPES
:
873 m_xTypesChglisteners
.set(new CacheUpdateListener(*this, *pConfig
, FilterCache::E_TYPE
));
874 m_xTypesChglisteners
->startListening();
877 case E_PROVIDER_FILTERS
:
879 m_xFiltersChgListener
.set(new CacheUpdateListener(*this, *pConfig
, FilterCache::E_FILTER
));
880 m_xFiltersChgListener
->startListening();
892 css::uno::Any
FilterCache::impl_getDirectCFGValue(const OUString
& sDirectKey
)
898 (!::utl::splitLastFromConfigurationPath(sDirectKey
, sRoot
, sKey
)) ||
899 (sRoot
.isEmpty() ) ||
902 return css::uno::Any();
904 css::uno::Reference
< css::uno::XInterface
> xCfg
= impl_createConfigAccess(sRoot
,
905 sal_True
, // bReadOnly
906 sal_False
); // bLocalesMode
908 return css::uno::Any();
910 css::uno::Reference
< css::container::XNameAccess
> xAccess(xCfg
, css::uno::UNO_QUERY
);
912 return css::uno::Any();
914 css::uno::Any aValue
;
917 aValue
= xAccess
->getByName(sKey
);
919 catch(const css::uno::RuntimeException
&)
921 #if OSL_DEBUG_LEVEL > 0
922 catch(const css::uno::Exception
& ex
)
924 catch(const css::uno::Exception
&)
927 #if OSL_DEBUG_LEVEL > 0
928 OSL_FAIL(OUStringToOString(ex
.Message
, RTL_TEXTENCODING_UTF8
).getStr());
938 css::uno::Reference
< css::uno::XInterface
> FilterCache::impl_createConfigAccess(const OUString
& sRoot
,
940 sal_Bool bLocalesMode
)
943 ::osl::ResettableMutexGuard
aLock(m_aLock
);
945 css::uno::Reference
< css::uno::XInterface
> xCfg
;
949 css::uno::Reference
< css::lang::XMultiServiceFactory
> xConfigProvider(
950 css::configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() ) );
952 ::comphelper::SequenceAsVector
< css::uno::Any
> lParams
;
953 css::beans::NamedValue aParam
;
956 aParam
.Name
= _FILTER_CONFIG_FROM_ASCII_("nodepath");
957 aParam
.Value
<<= sRoot
;
958 lParams
.push_back(css::uno::makeAny(aParam
));
960 // enable "all locales mode" ... if required
963 aParam
.Name
= _FILTER_CONFIG_FROM_ASCII_("locale");
964 aParam
.Value
<<= _FILTER_CONFIG_FROM_ASCII_("*" );
965 lParams
.push_back(css::uno::makeAny(aParam
));
970 xCfg
= xConfigProvider
->createInstanceWithArguments(SERVICE_CONFIGURATIONACCESS
, lParams
.getAsConstList());
972 xCfg
= xConfigProvider
->createInstanceWithArguments(SERVICE_CONFIGURATIONUPDATEACCESS
, lParams
.getAsConstList());
974 // If configuration could not be opened ... but factory method does not throwed an exception
975 // trigger throwing of our own CorruptedFilterConfigurationException.
976 // Let message empty. The normal exception text show enough information to the user.
978 throw css::uno::Exception(
979 _FILTER_CONFIG_FROM_ASCII_("Got NULL reference on opening configuration file ... but no exception."),
980 css::uno::Reference
< css::uno::XInterface
>());
982 catch(const css::uno::Exception
& ex
)
984 throw css::document::CorruptedFilterConfigurationException(
985 "filter configuration, caught: " + ex
.Message
,
986 css::uno::Reference
< css::uno::XInterface
>(),
996 void FilterCache::impl_validateAndOptimize()
997 throw(css::uno::Exception
)
1000 ::osl::ResettableMutexGuard
aLock(m_aLock
);
1002 RTL_LOGFILE_CONTEXT( aLog
, "framework (as96863) ::FilterCache::impl_validateAndOptimize");
1004 // First check if any filter or type could be readed
1005 // from the underlying configuration!
1006 sal_Bool bSomeTypesShouldExist
= ((m_eFillState
& E_CONTAINS_STANDARD
) == E_CONTAINS_STANDARD
);
1007 sal_Bool bAllFiltersShouldExist
= ((m_eFillState
& E_CONTAINS_FILTERS
) == E_CONTAINS_FILTERS
);
1009 #if OSL_DEBUG_LEVEL > 0
1011 sal_Int32 nWarnings
= 0;
1013 // sal_Bool bAllTypesShouldExist = ((m_eFillState & E_CONTAINS_TYPES ) == E_CONTAINS_TYPES );
1014 sal_Bool bAllLoadersShouldExist
= ((m_eFillState
& E_CONTAINS_FRAMELOADERS
) == E_CONTAINS_FRAMELOADERS
);
1015 sal_Bool bAllHandlersShouldExist
= ((m_eFillState
& E_CONTAINS_CONTENTHANDLERS
) == E_CONTAINS_CONTENTHANDLERS
);
1020 (bSomeTypesShouldExist
) &&
1021 (m_lTypes
.size() < 1 )
1024 (bAllFiltersShouldExist
) &&
1025 (m_lFilters
.size() < 1 )
1029 throw css::document::CorruptedFilterConfigurationException(
1030 "filter configuration: the list of types or filters is empty",
1031 css::uno::Reference
< css::uno::XInterface
>(),
1032 "The list of types or filters is empty." );
1035 // Create a log for all detected problems, which
1036 // occur in the next few lines.
1037 // If there are some real errors throw a RuntimException!
1038 // If there are some warnings only, show an assertion.
1039 sal_Int32 nErrors
= 0;
1040 OUStringBuffer
sLog(256);
1042 CacheItemList::iterator pIt
;
1044 for (pIt
= m_lTypes
.begin(); pIt
!= m_lTypes
.end(); ++pIt
)
1046 OUString sType
= pIt
->first
;
1047 CacheItem aType
= pIt
->second
;
1049 // create list of all known detect services / frame loader / content handler on demand
1050 // Because these information are available as type properties!
1051 OUString sDetectService
;
1052 aType
[PROPNAME_DETECTSERVICE
] >>= sDetectService
;
1053 if (!sDetectService
.isEmpty())
1054 impl_resolveItem4TypeRegistration(&m_lDetectServices
, sDetectService
, sType
);
1056 // get its registration for file Extensions AND(!) URLPattern ...
1057 // It doesnt matter if these items exists or if our
1058 // used index access create some default ones ...
1059 // only in case there is no filled set of Extensions AND
1060 // no filled set of URLPattern -> we must try to remove this invalid item
1062 css::uno::Sequence
< OUString
> lExtensions
;
1063 css::uno::Sequence
< OUString
> lURLPattern
;
1064 aType
[PROPNAME_EXTENSIONS
] >>= lExtensions
;
1065 aType
[PROPNAME_URLPATTERN
] >>= lURLPattern
;
1066 sal_Int32 ce
= lExtensions
.getLength();
1067 sal_Int32 cu
= lURLPattern
.getLength();
1069 #if OSL_DEBUG_LEVEL > 0
1071 OUString sInternalTypeNameCheck
;
1072 aType
[PROPNAME_NAME
] >>= sInternalTypeNameCheck
;
1073 if (!sInternalTypeNameCheck
.equals(sType
))
1075 sLog
.append("Warning\t:\t" "The type \"" + sType
+ "\" does support the property \"Name\" correctly.\n");
1081 sLog
.append("Warning\t:\t" "The type \"" + sType
+ "\" does not contain any URL pattern nor any extensions.\n");
1086 // create an optimized registration for this type to
1087 // its set list of extensions/url pattern. If its a "normal" type
1088 // set it at the end of this optimized list. But if its
1089 // a "Preferred" one - set it to the front of this list.
1090 // Of course multiple "Preferred" registrations can occur
1091 // (they shouldn't - but they can!) ... Ignore it. The last
1092 // preferred type is useable in the same manner then every
1094 sal_Bool bPreferred
= sal_False
;
1095 aType
[PROPNAME_PREFERRED
] >>= bPreferred
;
1097 const OUString
* pExtensions
= lExtensions
.getConstArray();
1098 for (sal_Int32 e
=0; e
<ce
; ++e
)
1100 // Note: We must be sure that address the right hash entry
1101 // does not depend from any upper/lower case problems ...
1102 OUString sNormalizedExtension
= pExtensions
[e
].toAsciiLowerCase();
1104 OUStringList
& lTypesForExtension
= m_lExtensions2Types
[sNormalizedExtension
];
1105 if (::std::find(lTypesForExtension
.begin(), lTypesForExtension
.end(), sType
) != lTypesForExtension
.end())
1109 lTypesForExtension
.insert(lTypesForExtension
.begin(), sType
);
1111 lTypesForExtension
.push_back(sType
);
1114 const OUString
* pURLPattern
= lURLPattern
.getConstArray();
1115 for (sal_Int32 u
=0; u
<cu
; ++u
)
1117 OUStringList
& lTypesForURLPattern
= m_lURLPattern2Types
[pURLPattern
[u
]];
1118 if (::std::find(lTypesForURLPattern
.begin(), lTypesForURLPattern
.end(), sType
) != lTypesForURLPattern
.end())
1122 lTypesForURLPattern
.insert(lTypesForURLPattern
.begin(), sType
);
1124 lTypesForURLPattern
.push_back(sType
);
1127 #if OSL_DEBUG_LEVEL > 0
1129 // Dont check cross references between types and filters, if
1130 // not all filters read from disk!
1131 // OK - this cache can read single filters on demand too ...
1132 // but then the fill state of this cache shouldnt be set to E_CONTAINS_FILTERS!
1133 if (!bAllFiltersShouldExist
)
1136 OUString sPrefFilter
;
1137 aType
[PROPNAME_PREFERREDFILTER
] >>= sPrefFilter
;
1138 if (sPrefFilter
.isEmpty())
1140 // OK - there is no filter for this type. But thats not an error.
1141 // May be it can be handled by a ContentHandler ...
1142 // But at this time its not guaranteed that there is any ContentHandler
1143 // or FrameLoader inside this cache ... but on disk ...
1144 sal_Bool bReferencedByLoader
= sal_True
;
1145 sal_Bool bReferencedByHandler
= sal_True
;
1146 if (bAllLoadersShouldExist
)
1147 bReferencedByLoader
= !impl_searchFrameLoaderForType(sType
).isEmpty();
1149 if (bAllHandlersShouldExist
)
1150 bReferencedByHandler
= !impl_searchContentHandlerForType(sType
).isEmpty();
1153 (!bReferencedByLoader
) &&
1154 (!bReferencedByHandler
)
1157 sLog
.append("Warning\t:\t" "The type \"" + sType
+ "\" isnt used by any filter, loader or content handler.\n");
1162 if (!sPrefFilter
.isEmpty())
1164 CacheItemList::const_iterator pIt2
= m_lFilters
.find(sPrefFilter
);
1165 if (pIt2
== m_lFilters
.end())
1167 if (bAllFiltersShouldExist
)
1169 ++nWarnings
; // preferred filters can point to a non-installed office module ! no error ... it's a warning only .-(
1170 sLog
.append("error\t:\t");
1175 sLog
.append("warning\t:\t");
1178 sLog
.append("The type \"" + sType
+ "\" points to an invalid filter \"" + sPrefFilter
+ "\".\n");
1182 CacheItem aPrefFilter
= pIt2
->second
;
1183 OUString sFilterTypeReg
;
1184 aPrefFilter
[PROPNAME_TYPE
] >>= sFilterTypeReg
;
1185 if (sFilterTypeReg
!= sType
)
1187 sLog
.append("error\t:\t" "The preferred filter \"" + sPrefFilter
+ "\" of type \"" + sType
+
1188 "is registered for another type \"" + sFilterTypeReg
+ "\".\n");
1192 sal_Int32 nFlags
= 0;
1193 aPrefFilter
[PROPNAME_FLAGS
] >>= nFlags
;
1194 if ((nFlags
& FLAGVAL_IMPORT
) != FLAGVAL_IMPORT
)
1196 sLog
.append("error\t:\t" "The preferred filter \"" + sPrefFilter
+ "\" of type \"" +
1197 sType
+ "\" is not an IMPORT filter!\n");
1201 OUString sInternalFilterNameCheck
;
1202 aPrefFilter
[PROPNAME_NAME
] >>= sInternalFilterNameCheck
;
1203 if (!sInternalFilterNameCheck
.equals(sPrefFilter
))
1205 sLog
.append("Warning\t:\t" "The filter \"" + sPrefFilter
+
1206 "\" does support the property \"Name\" correctly.\n");
1213 // create dependencies between the global default frame loader
1214 // and all types (and of course if registered filters), which
1215 // does not registered for any other loader.
1216 css::uno::Any aDirectValue
= impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER
);
1217 OUString sDefaultFrameLoader
;
1220 (!(aDirectValue
>>= sDefaultFrameLoader
)) ||
1221 (sDefaultFrameLoader
.isEmpty() )
1224 sLog
.append("error\t:\t" "There is no valid default frame loader!?\n");
1228 // a) get list of all well known types
1229 // b) step over all well known frame loader services
1230 // and remove all types from list a), which already
1231 // referenced by a loader b)
1232 OUStringList lTypes
= getItemNames(E_TYPE
);
1233 for ( pIt
= m_lFrameLoaders
.begin();
1234 pIt
!= m_lFrameLoaders
.end() ;
1237 // Note: of course the default loader must be ignored here.
1238 // Because we replace its registration later completely with all
1239 // types, which are not referenced by any other loader.
1240 // So we can avaoid our code against the complexity of a diff!
1241 OUString sLoader
= pIt
->first
;
1242 if (sLoader
.equals(sDefaultFrameLoader
))
1245 CacheItem
& rLoader
= pIt
->second
;
1246 css::uno::Any
& rTypesReg
= rLoader
[PROPNAME_TYPES
];
1247 OUStringList
lTypesReg (rTypesReg
);
1249 for (OUStringList::const_iterator pTypesReg
= lTypesReg
.begin();
1250 pTypesReg
!= lTypesReg
.end() ;
1253 OUStringList::iterator pTypeCheck
= ::std::find(lTypes
.begin(), lTypes
.end(), *pTypesReg
);
1254 if (pTypeCheck
!= lTypes
.end())
1255 lTypes
.erase(pTypeCheck
);
1259 CacheItem
& rDefaultLoader
= m_lFrameLoaders
[sDefaultFrameLoader
];
1260 rDefaultLoader
[PROPNAME_NAME
] <<= sDefaultFrameLoader
;
1261 rDefaultLoader
[PROPNAME_TYPES
] <<= lTypes
.getAsConstList();
1263 OUString sLogOut
= sLog
.makeStringAndClear();
1264 OSL_ENSURE(!nErrors
, OUStringToOString(sLogOut
,RTL_TEXTENCODING_UTF8
).getStr());
1266 throw css::document::CorruptedFilterConfigurationException(
1267 "filter configuration: " + sLogOut
,
1268 css::uno::Reference
< css::uno::XInterface
>(),
1270 OSL_ENSURE(!nWarnings
, OUStringToOString(sLogOut
,RTL_TEXTENCODING_UTF8
).getStr());
1277 void FilterCache::impl_addItem2FlushList( EItemType eType
,
1278 const OUString
& sItem
)
1279 throw(css::uno::Exception
)
1281 OUStringList
* pList
= 0;
1285 pList
= &m_lChangedTypes
;
1289 pList
= &m_lChangedFilters
;
1292 case E_FRAMELOADER
:
1293 pList
= &m_lChangedFrameLoaders
;
1296 case E_CONTENTHANDLER
:
1297 pList
= &m_lChangedContentHandlers
;
1300 case E_DETECTSERVICE
:
1301 pList
= &m_lChangedDetectServices
;
1304 default : throw css::uno::Exception("unsupported item type", 0);
1307 OUStringList::const_iterator pItem
= ::std::find(pList
->begin(), pList
->end(), sItem
);
1308 if (pItem
== pList
->end())
1309 pList
->push_back(sItem
);
1314 FilterCache::EItemFlushState
FilterCache::impl_specifyFlushOperation(const css::uno::Reference
< css::container::XNameAccess
>& xSet
,
1315 const CacheItemList
& rList
,
1316 const OUString
& sItem
)
1317 throw(css::uno::Exception
)
1319 sal_Bool bExistsInConfigLayer
= xSet
->hasByName(sItem
);
1320 sal_Bool bExistsInMemory
= (rList
.find(sItem
) != rList
.end());
1322 EItemFlushState
eState( E_ITEM_UNCHANGED
);
1324 // !? ... such situation can occur, if an item was added and(!) removed before it was flushed :-)
1325 if (!bExistsInConfigLayer
&& !bExistsInMemory
)
1326 eState
= E_ITEM_UNCHANGED
;
1327 else if (!bExistsInConfigLayer
&& bExistsInMemory
)
1328 eState
= E_ITEM_ADDED
;
1329 else if (bExistsInConfigLayer
&& bExistsInMemory
)
1330 eState
= E_ITEM_CHANGED
;
1331 else if (bExistsInConfigLayer
&& !bExistsInMemory
)
1332 eState
= E_ITEM_REMOVED
;
1339 void FilterCache::impl_resolveItem4TypeRegistration( CacheItemList
* pList
,
1340 const OUString
& sItem
,
1341 const OUString
& sType
)
1342 throw(css::uno::Exception
)
1344 CacheItem
& rItem
= (*pList
)[sItem
];
1345 // In case its a new created entry (automaticly done by the boost::unordered_map index operator!)
1346 // we must be shure, that this entry has its own name as property available.
1347 // Its needed later at our container interface!
1348 rItem
[PROPNAME_NAME
] <<= sItem
;
1350 OUStringList
lTypeRegs(rItem
[PROPNAME_TYPES
]);
1351 if (::std::find(lTypeRegs
.begin(), lTypeRegs
.end(), sType
) == lTypeRegs
.end())
1353 lTypeRegs
.push_back(sType
);
1354 rItem
[PROPNAME_TYPES
] <<= lTypeRegs
.getAsConstList();
1360 void FilterCache::impl_load(EFillState eRequiredState
)
1361 throw(css::uno::Exception
)
1364 ::osl::ResettableMutexGuard
aLock(m_aLock
);
1366 // Attention: Detect services are part of the standard set!
1367 // So there is no need to handle it separately.
1369 // ------------------------------------------
1370 // a) The standard set of config value is needed.
1372 ((eRequiredState
& E_CONTAINS_STANDARD
) == E_CONTAINS_STANDARD
) &&
1373 ((m_eFillState
& E_CONTAINS_STANDARD
) != E_CONTAINS_STANDARD
)
1376 // Attention! If config couldnt be opened successfully
1377 // and exception os thrown automaticly and must be forwarded
1379 css::uno::Reference
< css::container::XNameAccess
> xTypes(impl_openConfig(E_PROVIDER_TYPES
), css::uno::UNO_QUERY_THROW
);
1381 RTL_LOGFILE_CONTEXT( aLog
, "framework (as96863) ::FilterCache::load std");
1382 impl_loadSet(xTypes
, E_TYPE
, E_READ_STANDARD
, &m_lTypes
);
1386 // ------------------------------------------
1387 // b) We need all type information ...
1389 ((eRequiredState
& E_CONTAINS_TYPES
) == E_CONTAINS_TYPES
) &&
1390 ((m_eFillState
& E_CONTAINS_TYPES
) != E_CONTAINS_TYPES
)
1393 // Attention! If config couldnt be opened successfully
1394 // and exception os thrown automaticly and must be forwarded
1396 css::uno::Reference
< css::container::XNameAccess
> xTypes(impl_openConfig(E_PROVIDER_TYPES
), css::uno::UNO_QUERY_THROW
);
1398 RTL_LOGFILE_CONTEXT( aLog
, "framework (as96863) ::FilterCache::load all types");
1399 impl_loadSet(xTypes
, E_TYPE
, E_READ_UPDATE
, &m_lTypes
);
1403 // ------------------------------------------
1404 // c) We need all filter information ...
1406 ((eRequiredState
& E_CONTAINS_FILTERS
) == E_CONTAINS_FILTERS
) &&
1407 ((m_eFillState
& E_CONTAINS_FILTERS
) != E_CONTAINS_FILTERS
)
1410 // Attention! If config couldnt be opened successfully
1411 // and exception os thrown automaticly and must be forwarded
1413 css::uno::Reference
< css::container::XNameAccess
> xFilters(impl_openConfig(E_PROVIDER_FILTERS
), css::uno::UNO_QUERY_THROW
);
1415 RTL_LOGFILE_CONTEXT( aLog
, "framework (as96863) ::FilterCache::load all filters");
1416 impl_loadSet(xFilters
, E_FILTER
, E_READ_ALL
, &m_lFilters
);
1420 // ------------------------------------------
1421 // c) We need all frame loader information ...
1423 ((eRequiredState
& E_CONTAINS_FRAMELOADERS
) == E_CONTAINS_FRAMELOADERS
) &&
1424 ((m_eFillState
& E_CONTAINS_FRAMELOADERS
) != E_CONTAINS_FRAMELOADERS
)
1427 // Attention! If config couldnt be opened successfully
1428 // and exception os thrown automaticly and must be forwarded
1430 css::uno::Reference
< css::container::XNameAccess
> xLoaders(impl_openConfig(E_PROVIDER_OTHERS
), css::uno::UNO_QUERY_THROW
);
1432 RTL_LOGFILE_CONTEXT( aLog
, "framework (as96863) ::FilterCache::load all frame loader");
1433 impl_loadSet(xLoaders
, E_FRAMELOADER
, E_READ_ALL
, &m_lFrameLoaders
);
1437 // ------------------------------------------
1438 // d) We need all content handler information ...
1440 ((eRequiredState
& E_CONTAINS_CONTENTHANDLERS
) == E_CONTAINS_CONTENTHANDLERS
) &&
1441 ((m_eFillState
& E_CONTAINS_CONTENTHANDLERS
) != E_CONTAINS_CONTENTHANDLERS
)
1444 // Attention! If config couldnt be opened successfully
1445 // and exception os thrown automaticly and must be forwarded
1447 css::uno::Reference
< css::container::XNameAccess
> xHandlers(impl_openConfig(E_PROVIDER_OTHERS
), css::uno::UNO_QUERY_THROW
);
1449 RTL_LOGFILE_CONTEXT( aLog
, "framework (as96863) ::FilterCache::load all content handler");
1450 impl_loadSet(xHandlers
, E_CONTENTHANDLER
, E_READ_ALL
, &m_lContentHandlers
);
1454 // update fill state. Note: its a bit field, which combines different parts.
1455 m_eFillState
= (EFillState
) ((sal_Int32
)m_eFillState
| (sal_Int32
)eRequiredState
);
1458 // yes! => validate it and update optimized structures.
1459 impl_validateAndOptimize();
1466 void FilterCache::impl_loadSet(const css::uno::Reference
< css::container::XNameAccess
>& xConfig
,
1468 EReadOption eOption
,
1469 CacheItemList
* pCache
)
1470 throw(css::uno::Exception
)
1472 // get access to the right configuration set
1477 sSetName
= CFGSET_TYPES
;
1481 sSetName
= CFGSET_FILTERS
;
1484 case E_FRAMELOADER
:
1485 sSetName
= CFGSET_FRAMELOADERS
;
1488 case E_CONTENTHANDLER
:
1489 sSetName
= CFGSET_CONTENTHANDLERS
;
1494 css::uno::Reference
< css::container::XNameAccess
> xSet
;
1495 css::uno::Sequence
< OUString
> lItems
;
1499 css::uno::Any aVal
= xConfig
->getByName(sSetName
);
1500 if (!(aVal
>>= xSet
) || !xSet
.is())
1502 OUString
sMsg("Could not open configuration set \"" + sSetName
+ "\".");
1503 throw css::uno::Exception(sMsg
, css::uno::Reference
< css::uno::XInterface
>());
1505 lItems
= xSet
->getElementNames();
1507 catch(const css::uno::Exception
& ex
)
1509 throw css::document::CorruptedFilterConfigurationException(
1510 "filter configuration, caught: " + ex
.Message
,
1511 css::uno::Reference
< css::uno::XInterface
>(),
1515 // get names of all existing sub items of this set
1516 // step over it and fill internal cache structures.
1518 // But dont update optimized structures like e.g. hash
1519 // for mapping extensions to its types!
1521 const OUString
* pItems
= lItems
.getConstArray();
1522 sal_Int32 c
= lItems
.getLength();
1523 for (sal_Int32 i
=0; i
<c
; ++i
)
1525 CacheItemList::iterator pItem
= pCache
->find(pItems
[i
]);
1528 // a) read a standard set of properties only or read all
1529 case E_READ_STANDARD
:
1534 (*pCache
)[pItems
[i
]] = impl_loadItem(xSet
, eType
, pItems
[i
], eOption
);
1536 catch(const css::uno::Exception
& ex
)
1538 throw css::document::CorruptedFilterConfigurationException(
1539 "filter configuration, caught: " + ex
.Message
,
1540 css::uno::Reference
< css::uno::XInterface
>(),
1546 // b) read optional properties only!
1547 // All items must already exist inside our cache.
1548 // But they must be updated.
1549 case E_READ_UPDATE
:
1551 if (pItem
== pCache
->end())
1553 OUString
sMsg("item \"" + pItems
[i
] + "\" not found for update!");
1554 throw css::uno::Exception(sMsg
, css::uno::Reference
< css::uno::XInterface
>());
1558 CacheItem aItem
= impl_loadItem(xSet
, eType
, pItems
[i
], eOption
);
1559 pItem
->second
.update(aItem
);
1561 catch(const css::uno::Exception
& ex
)
1563 throw css::document::CorruptedFilterConfigurationException(
1564 "filter configuration, caught: " + ex
.Message
,
1565 css::uno::Reference
< css::uno::XInterface
>(),
1577 void FilterCache::impl_readPatchUINames(const css::uno::Reference
< css::container::XNameAccess
>& xNode
,
1579 throw(css::uno::Exception
)
1582 // SAFE -> ----------------------------------
1583 ::osl::ResettableMutexGuard
aLock(m_aLock
);
1584 OUString sFormatName
= m_sFormatName
;
1585 OUString sFormatVersion
= m_sFormatVersion
;
1586 OUString sActLocale
= m_sActLocale
;
1588 // <- SAFE ----------------------------------
1590 css::uno::Any aVal
= xNode
->getByName(PROPNAME_UINAME
);
1591 css::uno::Reference
< css::container::XNameAccess
> xUIName
;
1592 if (!(aVal
>>= xUIName
) && !xUIName
.is())
1595 const ::comphelper::SequenceAsVector
< OUString
> lLocales(xUIName
->getElementNames());
1596 ::comphelper::SequenceAsVector
< OUString
>::const_iterator pLocale
;
1597 ::comphelper::SequenceAsHashMap lUINames
;
1599 const char FORMATNAME_VAR
[] = "%productname%";
1600 const char FORMATVERSION_VAR
[] = "%formatversion%";
1601 // patch %PRODUCTNAME and %FORMATNAME
1602 for ( pLocale
= lLocales
.begin();
1603 pLocale
!= lLocales
.end() ;
1606 const OUString
& sLocale
= *pLocale
;
1609 xUIName
->getByName(sLocale
) >>= sValue
;
1611 // replace %productname%
1612 sal_Int32 nIndex
= sValue
.indexOf(FORMATNAME_VAR
);
1615 sValue
= sValue
.replaceAt(nIndex
, RTL_CONSTASCII_LENGTH(FORMATNAME_VAR
), sFormatName
);
1616 nIndex
= sValue
.indexOf(FORMATNAME_VAR
, nIndex
);
1618 // replace %formatversion%
1619 nIndex
= sValue
.indexOf(FORMATVERSION_VAR
);
1622 sValue
= sValue
.replaceAt(nIndex
, RTL_CONSTASCII_LENGTH(FORMATVERSION_VAR
), sFormatVersion
);
1623 nIndex
= sValue
.indexOf(FORMATVERSION_VAR
, nIndex
);
1626 lUINames
[sLocale
] <<= sValue
;
1629 aVal
<<= lUINames
.getAsConstPropertyValueList();
1630 rItem
[PROPNAME_UINAMES
] = aVal
;
1632 // find right UIName for current office locale
1633 // Use fallbacks too!
1634 pLocale
= LanguageTag::getFallback(lLocales
, sActLocale
);
1635 if (pLocale
== lLocales
.end())
1637 #if OSL_DEBUG_LEVEL > 0
1638 if ( sActLocale
== "en-US" )
1640 OUString sName
= rItem
.getUnpackedValueOrDefault(PROPNAME_NAME
, OUString());
1642 OUString
sMsg("Fallback scenario for filter or type '" + sName
+ "' and locale '" +
1643 sActLocale
+ "' failed. Please check your filter configuration.");
1645 OSL_FAIL(_FILTER_CONFIG_TO_ASCII_(sMsg
));
1650 const OUString
& sLocale
= *pLocale
;
1651 ::comphelper::SequenceAsHashMap::const_iterator pUIName
= lUINames
.find(sLocale
);
1652 if (pUIName
!= lUINames
.end())
1653 rItem
[PROPNAME_UINAME
] = pUIName
->second
;
1658 void FilterCache::impl_savePatchUINames(const css::uno::Reference
< css::container::XNameReplace
>& xNode
,
1659 const CacheItem
& rItem
)
1660 throw(css::uno::Exception
)
1662 css::uno::Reference
< css::container::XNameContainer
> xAdd (xNode
, css::uno::UNO_QUERY
);
1663 css::uno::Reference
< css::container::XNameAccess
> xCheck(xNode
, css::uno::UNO_QUERY
);
1665 css::uno::Sequence
< css::beans::PropertyValue
> lUINames
= rItem
.getUnpackedValueOrDefault(PROPNAME_UINAMES
, css::uno::Sequence
< css::beans::PropertyValue
>());
1666 sal_Int32 c
= lUINames
.getLength();
1667 const css::beans::PropertyValue
* pUINames
= lUINames
.getConstArray();
1669 for (sal_Int32 i
=0; i
<c
; ++i
)
1671 if (xCheck
->hasByName(pUINames
[i
].Name
))
1672 xNode
->replaceByName(pUINames
[i
].Name
, pUINames
[i
].Value
);
1674 xAdd
->insertByName(pUINames
[i
].Name
, pUINames
[i
].Value
);
1678 /*-----------------------------------------------
1680 clarify, how the real problem behind the
1681 wrong constructed CacheItem instance (which
1682 will force a crash during destruction)
1684 -----------------------------------------------*/
1685 CacheItem
FilterCache::impl_loadItem(const css::uno::Reference
< css::container::XNameAccess
>& xSet
,
1687 const OUString
& sItem
,
1688 EReadOption eOption
)
1689 throw(css::uno::Exception
)
1691 // try to get an API object, which points directly to the
1692 // requested item. If it fail an exception should occur and
1693 // break this operation. Of course returned API object must be
1695 css::uno::Reference
< css::container::XNameAccess
> xItem
;
1696 #ifdef WORKAROUND_EXCEPTION_PROBLEM
1700 css::uno::Any aVal
= xSet
->getByName(sItem
);
1701 if (!(aVal
>>= xItem
) || !xItem
.is())
1703 OUString
sMsg("found corrupted item \"" + sItem
+ "\".");
1704 throw css::uno::Exception(sMsg
, css::uno::Reference
< css::uno::XInterface
>());
1706 #ifdef WORKAROUND_EXCEPTION_PROBLEM
1708 catch(const css::container::NoSuchElementException
&)
1714 // The internal name of an item must(!) be part of the property
1715 // set too. Of course its already used as key into the e.g. outside
1716 // used hash map ... but some of our API methods provide
1717 // this property set as result only. But the user of this CacheItem
1718 // should know, which value the key names has :-) ITS IMPORTANT!
1720 aItem
[PROPNAME_NAME
] = css::uno::makeAny(sItem
);
1723 //---------------------------------------
1726 // read standard properties of a type
1728 (eOption
== E_READ_STANDARD
) ||
1729 (eOption
== E_READ_ALL
)
1732 aItem
[PROPNAME_PREFERREDFILTER
] = xItem
->getByName(PROPNAME_PREFERREDFILTER
);
1733 aItem
[PROPNAME_DETECTSERVICE
] = xItem
->getByName(PROPNAME_DETECTSERVICE
);
1734 aItem
[PROPNAME_URLPATTERN
] = xItem
->getByName(PROPNAME_URLPATTERN
);
1735 aItem
[PROPNAME_EXTENSIONS
] = xItem
->getByName(PROPNAME_EXTENSIONS
);
1736 aItem
[PROPNAME_PREFERRED
] = xItem
->getByName(PROPNAME_PREFERRED
);
1737 aItem
[PROPNAME_CLIPBOARDFORMAT
] = xItem
->getByName(PROPNAME_CLIPBOARDFORMAT
);
1739 // read optional properties of a type
1740 // no else here! Is an additional switch ...
1742 (eOption
== E_READ_UPDATE
) ||
1743 (eOption
== E_READ_ALL
)
1746 aItem
[PROPNAME_MEDIATYPE
] = xItem
->getByName(PROPNAME_MEDIATYPE
);
1747 impl_readPatchUINames(xItem
, aItem
);
1752 //---------------------------------------
1755 // read standard properties of a filter
1757 (eOption
== E_READ_STANDARD
) ||
1758 (eOption
== E_READ_ALL
)
1761 aItem
[PROPNAME_TYPE
] = xItem
->getByName(PROPNAME_TYPE
);
1762 aItem
[PROPNAME_FILEFORMATVERSION
] = xItem
->getByName(PROPNAME_FILEFORMATVERSION
);
1763 aItem
[PROPNAME_UICOMPONENT
] = xItem
->getByName(PROPNAME_UICOMPONENT
);
1764 aItem
[PROPNAME_FILTERSERVICE
] = xItem
->getByName(PROPNAME_FILTERSERVICE
);
1765 aItem
[PROPNAME_DOCUMENTSERVICE
] = xItem
->getByName(PROPNAME_DOCUMENTSERVICE
);
1766 aItem
[PROPNAME_EXPORTEXTENSION
] = xItem
->getByName(PROPNAME_EXPORTEXTENSION
);
1768 // special handling for flags! Convert it from a list of names to its
1769 // int representation ...
1770 css::uno::Sequence
< OUString
> lFlagNames
;
1771 if (xItem
->getByName(PROPNAME_FLAGS
) >>= lFlagNames
)
1772 aItem
[PROPNAME_FLAGS
] <<= FilterCache::impl_convertFlagNames2FlagField(lFlagNames
);
1774 // read optional properties of a filter
1775 // no else here! Is an additional switch ...
1777 (eOption
== E_READ_UPDATE
) ||
1778 (eOption
== E_READ_ALL
)
1781 aItem
[PROPNAME_USERDATA
] = xItem
->getByName(PROPNAME_USERDATA
);
1782 aItem
[PROPNAME_TEMPLATENAME
] = xItem
->getByName(PROPNAME_TEMPLATENAME
);
1783 //TODO remove it if moving of filter uinames to type uinames
1784 // will be finished realy
1785 #ifdef AS_ENABLE_FILTER_UINAMES
1786 impl_readPatchUINames(xItem
, aItem
);
1787 #endif // AS_ENABLE_FILTER_UINAMES
1792 //---------------------------------------
1793 case E_FRAMELOADER
:
1794 case E_CONTENTHANDLER
:
1796 aItem
[PROPNAME_TYPES
] = xItem
->getByName(PROPNAME_TYPES
);
1807 CacheItemList::iterator
FilterCache::impl_loadItemOnDemand( EItemType eType
,
1808 const OUString
& sItem
)
1809 throw(css::uno::Exception
)
1811 CacheItemList
* pList
= 0;
1812 css::uno::Reference
< css::uno::XInterface
> xConfig
;
1820 xConfig
= impl_openConfig(E_PROVIDER_TYPES
);
1821 sSet
= CFGSET_TYPES
;
1827 pList
= &m_lFilters
;
1828 xConfig
= impl_openConfig(E_PROVIDER_FILTERS
);
1829 sSet
= CFGSET_FILTERS
;
1833 case E_FRAMELOADER
:
1835 pList
= &m_lFrameLoaders
;
1836 xConfig
= impl_openConfig(E_PROVIDER_OTHERS
);
1837 sSet
= CFGSET_FRAMELOADERS
;
1841 case E_CONTENTHANDLER
:
1843 pList
= &m_lContentHandlers
;
1844 xConfig
= impl_openConfig(E_PROVIDER_OTHERS
);
1845 sSet
= CFGSET_CONTENTHANDLERS
;
1849 case E_DETECTSERVICE
:
1851 OSL_FAIL("Cant load detect services on demand. Who use this unsupported feature?");
1856 css::uno::Reference
< css::container::XNameAccess
> xRoot(xConfig
, css::uno::UNO_QUERY_THROW
);
1857 css::uno::Reference
< css::container::XNameAccess
> xSet
;
1858 xRoot
->getByName(sSet
) >>= xSet
;
1860 CacheItemList::iterator pItemInCache
= pList
->find(sItem
);
1861 sal_Bool bItemInConfig
= xSet
->hasByName(sItem
);
1865 (*pList
)[sItem
] = impl_loadItem(xSet
, eType
, sItem
, E_READ_ALL
);
1866 _FILTER_CONFIG_LOG_2_("impl_loadItemOnDemand(%d, \"%s\") ... OK", (int)eType
, _FILTER_CONFIG_TO_ASCII_(sItem
).getStr())
1870 if (pItemInCache
!= pList
->end())
1871 pList
->erase(pItemInCache
);
1872 // OK - this item does not exists inside configuration.
1873 // And we already updated our internal cache.
1874 // But the outside code needs this NoSuchElementException
1875 // to know, that this item does notexists.
1876 // Nobody checks the iterator!
1877 throw css::container::NoSuchElementException();
1880 return pList
->find(sItem
);
1885 void FilterCache::impl_saveItem(const css::uno::Reference
< css::container::XNameReplace
>& xItem
,
1887 const CacheItem
& aItem
)
1888 throw(css::uno::Exception
)
1890 CacheItem::const_iterator pIt
;
1893 //---------------------------------------
1896 pIt
= aItem
.find(PROPNAME_PREFERREDFILTER
);
1897 if (pIt
!= aItem
.end())
1898 xItem
->replaceByName(PROPNAME_PREFERREDFILTER
, pIt
->second
);
1899 pIt
= aItem
.find(PROPNAME_DETECTSERVICE
);
1900 if (pIt
!= aItem
.end())
1901 xItem
->replaceByName(PROPNAME_DETECTSERVICE
, pIt
->second
);
1902 pIt
= aItem
.find(PROPNAME_URLPATTERN
);
1903 if (pIt
!= aItem
.end())
1904 xItem
->replaceByName(PROPNAME_URLPATTERN
, pIt
->second
);
1905 pIt
= aItem
.find(PROPNAME_EXTENSIONS
);
1906 if (pIt
!= aItem
.end())
1907 xItem
->replaceByName(PROPNAME_EXTENSIONS
, pIt
->second
);
1908 pIt
= aItem
.find(PROPNAME_PREFERRED
);
1909 if (pIt
!= aItem
.end())
1910 xItem
->replaceByName(PROPNAME_PREFERRED
, pIt
->second
);
1911 pIt
= aItem
.find(PROPNAME_MEDIATYPE
);
1912 if (pIt
!= aItem
.end())
1913 xItem
->replaceByName(PROPNAME_MEDIATYPE
, pIt
->second
);
1914 pIt
= aItem
.find(PROPNAME_CLIPBOARDFORMAT
);
1915 if (pIt
!= aItem
.end())
1916 xItem
->replaceByName(PROPNAME_CLIPBOARDFORMAT
, pIt
->second
);
1918 css::uno::Reference
< css::container::XNameReplace
> xUIName
;
1919 xItem
->getByName(PROPNAME_UINAME
) >>= xUIName
;
1920 impl_savePatchUINames(xUIName
, aItem
);
1924 //---------------------------------------
1927 pIt
= aItem
.find(PROPNAME_TYPE
);
1928 if (pIt
!= aItem
.end())
1929 xItem
->replaceByName(PROPNAME_TYPE
, pIt
->second
);
1930 pIt
= aItem
.find(PROPNAME_FILEFORMATVERSION
);
1931 if (pIt
!= aItem
.end())
1932 xItem
->replaceByName(PROPNAME_FILEFORMATVERSION
, pIt
->second
);
1933 pIt
= aItem
.find(PROPNAME_UICOMPONENT
);
1934 if (pIt
!= aItem
.end())
1935 xItem
->replaceByName(PROPNAME_UICOMPONENT
, pIt
->second
);
1936 pIt
= aItem
.find(PROPNAME_FILTERSERVICE
);
1937 if (pIt
!= aItem
.end())
1938 xItem
->replaceByName(PROPNAME_FILTERSERVICE
, pIt
->second
);
1939 pIt
= aItem
.find(PROPNAME_DOCUMENTSERVICE
);
1940 if (pIt
!= aItem
.end())
1941 xItem
->replaceByName(PROPNAME_DOCUMENTSERVICE
, pIt
->second
);
1942 pIt
= aItem
.find(PROPNAME_USERDATA
);
1943 if (pIt
!= aItem
.end())
1944 xItem
->replaceByName(PROPNAME_USERDATA
, pIt
->second
);
1945 pIt
= aItem
.find(PROPNAME_TEMPLATENAME
);
1946 if (pIt
!= aItem
.end())
1947 xItem
->replaceByName(PROPNAME_TEMPLATENAME
, pIt
->second
);
1949 // special handling for flags! Convert it from an integer flag field back
1950 // to a list of names ...
1951 // But note: because we work directly on a reference to the cache item,
1952 // its not allowd to change the value here. We must work on a copy!
1953 pIt
= aItem
.find(PROPNAME_FLAGS
);
1954 if (pIt
!= aItem
.end())
1956 sal_Int32 nFlags
= 0;
1957 pIt
->second
>>= nFlags
;
1958 css::uno::Any aFlagNameList
;
1959 aFlagNameList
<<= FilterCache::impl_convertFlagField2FlagNames(nFlags
);
1960 xItem
->replaceByName(PROPNAME_FLAGS
, aFlagNameList
);
1963 //TODO remove it if moving of filter uinames to type uinames
1964 // will be finished realy
1965 #ifdef AS_ENABLE_FILTER_UINAMES
1966 css::uno::Reference
< css::container::XNameReplace
> xUIName
;
1967 xItem
->getByName(PROPNAME_UINAME
) >>= xUIName
;
1968 impl_savePatchUINames(xUIName
, aItem
);
1969 #endif // AS_ENABLE_FILTER_UINAMES
1973 //---------------------------------------
1974 case E_FRAMELOADER
:
1975 case E_CONTENTHANDLER
:
1977 pIt
= aItem
.find(PROPNAME_TYPES
);
1978 if (pIt
!= aItem
.end())
1979 xItem
->replaceByName(PROPNAME_TYPES
, pIt
->second
);
1986 /*-----------------------------------------------
1987 static! => no locks neccessary
1988 -----------------------------------------------*/
1989 css::uno::Sequence
< OUString
> FilterCache::impl_convertFlagField2FlagNames(sal_Int32 nFlags
)
1991 OUStringList lFlagNames
;
1993 if ((nFlags
& FLAGVAL_3RDPARTYFILTER
) == FLAGVAL_3RDPARTYFILTER
) lFlagNames
.push_back(FLAGNAME_3RDPARTYFILTER
);
1994 if ((nFlags
& FLAGVAL_ALIEN
) == FLAGVAL_ALIEN
) lFlagNames
.push_back(FLAGNAME_ALIEN
);
1995 if ((nFlags
& FLAGVAL_ASYNCHRON
) == FLAGVAL_ASYNCHRON
) lFlagNames
.push_back(FLAGNAME_ASYNCHRON
);
1996 if ((nFlags
& FLAGVAL_BROWSERPREFERRED
) == FLAGVAL_BROWSERPREFERRED
) lFlagNames
.push_back(FLAGNAME_BROWSERPREFERRED
);
1997 if ((nFlags
& FLAGVAL_CONSULTSERVICE
) == FLAGVAL_CONSULTSERVICE
) lFlagNames
.push_back(FLAGNAME_CONSULTSERVICE
);
1998 if ((nFlags
& FLAGVAL_DEFAULT
) == FLAGVAL_DEFAULT
) lFlagNames
.push_back(FLAGNAME_DEFAULT
);
1999 if ((nFlags
& FLAGVAL_ENCRYPTION
) == FLAGVAL_ENCRYPTION
) lFlagNames
.push_back(FLAGNAME_ENCRYPTION
);
2000 if ((nFlags
& FLAGVAL_EXPORT
) == FLAGVAL_EXPORT
) lFlagNames
.push_back(FLAGNAME_EXPORT
);
2001 if ((nFlags
& FLAGVAL_IMPORT
) == FLAGVAL_IMPORT
) lFlagNames
.push_back(FLAGNAME_IMPORT
);
2002 if ((nFlags
& FLAGVAL_INTERNAL
) == FLAGVAL_INTERNAL
) lFlagNames
.push_back(FLAGNAME_INTERNAL
);
2003 if ((nFlags
& FLAGVAL_NOTINCHOOSER
) == FLAGVAL_NOTINCHOOSER
) lFlagNames
.push_back(FLAGNAME_NOTINCHOOSER
);
2004 if ((nFlags
& FLAGVAL_NOTINFILEDIALOG
) == FLAGVAL_NOTINFILEDIALOG
) lFlagNames
.push_back(FLAGNAME_NOTINFILEDIALOG
);
2005 if ((nFlags
& FLAGVAL_NOTINSTALLED
) == FLAGVAL_NOTINSTALLED
) lFlagNames
.push_back(FLAGNAME_NOTINSTALLED
);
2006 if ((nFlags
& FLAGVAL_OWN
) == FLAGVAL_OWN
) lFlagNames
.push_back(FLAGNAME_OWN
);
2007 if ((nFlags
& FLAGVAL_PACKED
) == FLAGVAL_PACKED
) lFlagNames
.push_back(FLAGNAME_PACKED
);
2008 if ((nFlags
& FLAGVAL_PASSWORDTOMODIFY
) == FLAGVAL_PASSWORDTOMODIFY
) lFlagNames
.push_back(FLAGNAME_PASSWORDTOMODIFY
);
2009 if ((nFlags
& FLAGVAL_PREFERRED
) == FLAGVAL_PREFERRED
) lFlagNames
.push_back(FLAGNAME_PREFERRED
);
2010 if ((nFlags
& FLAGVAL_STARTPRESENTATION
) == FLAGVAL_STARTPRESENTATION
) lFlagNames
.push_back(FLAGNAME_STARTPRESENTATION
);
2011 if ((nFlags
& FLAGVAL_READONLY
) == FLAGVAL_READONLY
) lFlagNames
.push_back(FLAGNAME_READONLY
);
2012 if ((nFlags
& FLAGVAL_SUPPORTSSELECTION
) == FLAGVAL_SUPPORTSSELECTION
) lFlagNames
.push_back(FLAGNAME_SUPPORTSSELECTION
);
2013 if ((nFlags
& FLAGVAL_TEMPLATE
) == FLAGVAL_TEMPLATE
) lFlagNames
.push_back(FLAGNAME_TEMPLATE
);
2014 if ((nFlags
& FLAGVAL_TEMPLATEPATH
) == FLAGVAL_TEMPLATEPATH
) lFlagNames
.push_back(FLAGNAME_TEMPLATEPATH
);
2015 if ((nFlags
& FLAGVAL_USESOPTIONS
) == FLAGVAL_USESOPTIONS
) lFlagNames
.push_back(FLAGNAME_USESOPTIONS
);
2016 if ((nFlags
& FLAGVAL_COMBINED
) == FLAGVAL_COMBINED
) lFlagNames
.push_back(FLAGNAME_COMBINED
);
2018 return lFlagNames
.getAsConstList();
2021 /*-----------------------------------------------
2022 static! => no locks neccessary
2023 -----------------------------------------------*/
2024 sal_Int32
FilterCache::impl_convertFlagNames2FlagField(const css::uno::Sequence
< OUString
>& lNames
)
2026 sal_Int32 nField
= 0;
2028 const OUString
* pNames
= lNames
.getConstArray();
2029 sal_Int32 c
= lNames
.getLength();
2030 for (sal_Int32 i
=0; i
<c
; ++i
)
2032 if (pNames
[i
].equals(FLAGNAME_3RDPARTYFILTER
))
2034 nField
|= FLAGVAL_3RDPARTYFILTER
;
2037 if (pNames
[i
].equals(FLAGNAME_ALIEN
))
2039 nField
|= FLAGVAL_ALIEN
;
2042 if (pNames
[i
].equals(FLAGNAME_ASYNCHRON
))
2044 nField
|= FLAGVAL_ASYNCHRON
;
2047 if (pNames
[i
].equals(FLAGNAME_BROWSERPREFERRED
))
2049 nField
|= FLAGVAL_BROWSERPREFERRED
;
2052 if (pNames
[i
].equals(FLAGNAME_CONSULTSERVICE
))
2054 nField
|= FLAGVAL_CONSULTSERVICE
;
2057 if (pNames
[i
].equals(FLAGNAME_DEFAULT
))
2059 nField
|= FLAGVAL_DEFAULT
;
2062 if (pNames
[i
].equals(FLAGNAME_ENCRYPTION
))
2064 nField
|= FLAGVAL_ENCRYPTION
;
2067 if (pNames
[i
].equals(FLAGNAME_EXPORT
))
2069 nField
|= FLAGVAL_EXPORT
;
2072 if (pNames
[i
].equals(FLAGNAME_IMPORT
))
2074 nField
|= FLAGVAL_IMPORT
;
2077 if (pNames
[i
].equals(FLAGNAME_INTERNAL
))
2079 nField
|= FLAGVAL_INTERNAL
;
2082 if (pNames
[i
].equals(FLAGNAME_NOTINCHOOSER
))
2084 nField
|= FLAGVAL_NOTINCHOOSER
;
2087 if (pNames
[i
].equals(FLAGNAME_NOTINFILEDIALOG
))
2089 nField
|= FLAGVAL_NOTINFILEDIALOG
;
2092 if (pNames
[i
].equals(FLAGNAME_NOTINSTALLED
))
2094 nField
|= FLAGVAL_NOTINSTALLED
;
2097 if (pNames
[i
].equals(FLAGNAME_OWN
))
2099 nField
|= FLAGVAL_OWN
;
2102 if (pNames
[i
].equals(FLAGNAME_PACKED
))
2104 nField
|= FLAGVAL_PACKED
;
2107 if (pNames
[i
].equals(FLAGNAME_PASSWORDTOMODIFY
))
2109 nField
|= FLAGVAL_PASSWORDTOMODIFY
;
2112 if (pNames
[i
].equals(FLAGNAME_PREFERRED
))
2114 nField
|= FLAGVAL_PREFERRED
;
2117 if (pNames
[i
].equals(FLAGNAME_STARTPRESENTATION
))
2119 nField
|= FLAGVAL_STARTPRESENTATION
;
2122 if (pNames
[i
].equals(FLAGNAME_READONLY
))
2124 nField
|= FLAGVAL_READONLY
;
2127 if (pNames
[i
].equals(FLAGNAME_SUPPORTSSELECTION
))
2129 nField
|= FLAGVAL_SUPPORTSSELECTION
;
2132 if (pNames
[i
].equals(FLAGNAME_TEMPLATE
))
2134 nField
|= FLAGVAL_TEMPLATE
;
2137 if (pNames
[i
].equals(FLAGNAME_TEMPLATEPATH
))
2139 nField
|= FLAGVAL_TEMPLATEPATH
;
2142 if (pNames
[i
].equals(FLAGNAME_USESOPTIONS
))
2144 nField
|= FLAGVAL_USESOPTIONS
;
2147 if (pNames
[i
].equals(FLAGNAME_COMBINED
))
2149 nField
|= FLAGVAL_COMBINED
;
2159 void FilterCache::impl_interpretDataVal4Type(const OUString
& sValue
,
2167 if (sValue
.toInt32() == 1)
2168 rItem
[PROPNAME_PREFERRED
] = css::uno::makeAny(sal_True
);
2170 rItem
[PROPNAME_PREFERRED
] = css::uno::makeAny(sal_False
);
2174 case 1: rItem
[PROPNAME_MEDIATYPE
] <<= ::rtl::Uri::decode(sValue
, rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
);
2177 case 2: rItem
[PROPNAME_CLIPBOARDFORMAT
] <<= ::rtl::Uri::decode(sValue
, rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
);
2180 case 3: rItem
[PROPNAME_URLPATTERN
] <<= impl_tokenizeString(sValue
, (sal_Unicode
)';').getAsConstList();
2183 case 4: rItem
[PROPNAME_EXTENSIONS
] <<= impl_tokenizeString(sValue
, (sal_Unicode
)';').getAsConstList();
2190 void FilterCache::impl_interpretDataVal4Filter(const OUString
& sValue
,
2198 sal_Int32 nOrder
= sValue
.toInt32();
2201 OSL_FAIL("FilterCache::impl_interpretDataVal4Filter()\nCant move Order value from filter to type on demand!\n");
2202 _FILTER_CONFIG_LOG_2_("impl_interpretDataVal4Filter(%d, \"%s\") ... OK", (int)eType
, _FILTER_CONFIG_TO_ASCII_(rItem
).getStr())
2207 case 1: rItem
[PROPNAME_TYPE
] <<= ::rtl::Uri::decode(sValue
, rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
);
2210 case 2: rItem
[PROPNAME_DOCUMENTSERVICE
] <<= ::rtl::Uri::decode(sValue
, rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
);
2213 case 3: rItem
[PROPNAME_FILTERSERVICE
] <<= ::rtl::Uri::decode(sValue
, rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
);
2216 case 4: rItem
[PROPNAME_FLAGS
] <<= sValue
.toInt32();
2219 case 5: rItem
[PROPNAME_USERDATA
] <<= impl_tokenizeString(sValue
, (sal_Unicode
)';').getAsConstList();
2221 // FileFormatVersion
2222 case 6: rItem
[PROPNAME_FILEFORMATVERSION
] <<= sValue
.toInt32();
2225 case 7: rItem
[PROPNAME_TEMPLATENAME
] <<= ::rtl::Uri::decode(sValue
, rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
);
2227 // [optional!] UIComponent
2228 case 8: rItem
[PROPNAME_UICOMPONENT
] <<= ::rtl::Uri::decode(sValue
, rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
);
2233 /*-----------------------------------------------
2234 TODO work on a cache copy first, which can be flushed afterwards
2235 That would be useful to guarantee a consistent cache.
2236 -----------------------------------------------*/
2237 void FilterCache::impl_readOldFormat()
2238 throw(css::uno::Exception
)
2240 // Attention: Opening/Reading of this old configuration format has to be handled gracefully.
2241 // Its optional and shouldnt disturb our normal work!
2242 // E.g. we must check, if the package exists ...
2244 css::uno::Reference
< css::container::XNameAccess
> xCfg
;
2247 css::uno::Reference
< css::uno::XInterface
> xInt
= impl_openConfig(E_PROVIDER_OLD
);
2248 xCfg
= css::uno::Reference
< css::container::XNameAccess
>(xInt
, css::uno::UNO_QUERY_THROW
);
2250 /* corrupt filter addon ? because it's external (optional) code .. we can ignore it. Addon wont work then ...
2251 but that seams to be acceptable.
2252 see #139088# for further information
2254 catch(const css::uno::Exception
&)
2257 OUString
TYPES_SET("Types");
2259 // May be there is no type set ...
2260 if (xCfg
->hasByName(TYPES_SET
))
2262 css::uno::Reference
< css::container::XNameAccess
> xSet
;
2263 xCfg
->getByName(TYPES_SET
) >>= xSet
;
2264 const css::uno::Sequence
< OUString
> lItems
= xSet
->getElementNames();
2265 const OUString
* pItems
= lItems
.getConstArray();
2266 for (sal_Int32 i
=0; i
<lItems
.getLength(); ++i
)
2267 m_lTypes
[pItems
[i
]] = impl_readOldItem(xSet
, E_TYPE
, pItems
[i
]);
2270 OUString
FILTER_SET("Filters");
2271 // May be there is no filter set ...
2272 if (xCfg
->hasByName(FILTER_SET
))
2274 css::uno::Reference
< css::container::XNameAccess
> xSet
;
2275 xCfg
->getByName(FILTER_SET
) >>= xSet
;
2276 const css::uno::Sequence
< OUString
> lItems
= xSet
->getElementNames();
2277 const OUString
* pItems
= lItems
.getConstArray();
2278 for (sal_Int32 i
=0; i
<lItems
.getLength(); ++i
)
2279 m_lFilters
[pItems
[i
]] = impl_readOldItem(xSet
, E_FILTER
, pItems
[i
]);
2285 CacheItem
FilterCache::impl_readOldItem(const css::uno::Reference
< css::container::XNameAccess
>& xSet
,
2287 const OUString
& sItem
)
2288 throw(css::uno::Exception
)
2290 css::uno::Reference
< css::container::XNameAccess
> xItem
;
2291 xSet
->getByName(sItem
) >>= xItem
;
2293 throw css::uno::Exception("Cant read old item.", css::uno::Reference
< css::uno::XInterface
>());
2296 aItem
[PROPNAME_NAME
] <<= sItem
;
2298 // Installed flag ...
2299 // Isnt used any longer!
2302 impl_readPatchUINames(xItem
, aItem
);
2307 xItem
->getByName( "Data" ) >>= sData
;
2308 lData
= impl_tokenizeString(sData
, (sal_Unicode
)',');
2310 (sData
.isEmpty()) ||
2314 throw css::uno::Exception( "Cant read old item property DATA.", css::uno::Reference
< css::uno::XInterface
>());
2317 sal_Int32 nProp
= 0;
2318 for (OUStringList::const_iterator pProp
= lData
.begin();
2319 pProp
!= lData
.end() ;
2322 const OUString
& sProp
= *pProp
;
2326 impl_interpretDataVal4Type(sProp
, nProp
, aItem
);
2330 impl_interpretDataVal4Filter(sProp
, nProp
, aItem
);
2342 OUStringList
FilterCache::impl_tokenizeString(const OUString
& sData
,
2343 sal_Unicode cSeparator
)
2345 OUStringList lData
;
2346 sal_Int32 nToken
= 0;
2349 OUString sToken
= sData
.getToken(0, cSeparator
, nToken
);
2350 lData
.push_back(sToken
);
2356 #if OSL_DEBUG_LEVEL > 0
2359 OUString
FilterCache::impl_searchFrameLoaderForType(const OUString
& sType
) const
2361 CacheItemList::const_iterator pIt
;
2362 for ( pIt
= m_lFrameLoaders
.begin();
2363 pIt
!= m_lFrameLoaders
.end() ;
2366 const OUString
& sItem
= pIt
->first
;
2367 ::comphelper::SequenceAsHashMap
lProps(pIt
->second
);
2368 OUStringList
lTypes(lProps
[PROPNAME_TYPES
]);
2370 if (::std::find(lTypes
.begin(), lTypes
.end(), sType
) != lTypes
.end())
2379 OUString
FilterCache::impl_searchContentHandlerForType(const OUString
& sType
) const
2381 CacheItemList::const_iterator pIt
;
2382 for ( pIt
= m_lContentHandlers
.begin();
2383 pIt
!= m_lContentHandlers
.end() ;
2386 const OUString
& sItem
= pIt
->first
;
2387 ::comphelper::SequenceAsHashMap
lProps(pIt
->second
);
2388 OUStringList
lTypes(lProps
[PROPNAME_TYPES
]);
2390 if (::std::find(lTypes
.begin(), lTypes
.end(), sType
) != lTypes
.end())
2400 sal_Bool
FilterCache::impl_isModuleInstalled(const OUString
& sModule
)
2402 css::uno::Reference
< css::container::XNameAccess
> xCfg
;
2405 ::osl::ResettableMutexGuard
aLock(m_aLock
);
2406 if (! m_xModuleCfg
.is())
2408 m_xModuleCfg
= css::uno::Reference
< css::container::XNameAccess
>(
2409 ::comphelper::ConfigurationHelper::openConfig(
2410 comphelper::getProcessComponentContext(),
2411 "org.openoffice.Setup/Office/Factories",
2412 ::comphelper::ConfigurationHelper::E_READONLY
),
2413 css::uno::UNO_QUERY_THROW
);
2416 xCfg
= m_xModuleCfg
;
2421 return xCfg
->hasByName(sModule
);
2426 } // namespace config
2427 } // namespace filter
2429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */