LCOV - code coverage report
Current view: top level - filter/source/config/cache - filtercache.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 676 957 70.6 %
Date: 2014-11-03 Functions: 35 43 81.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10