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

Generated by: LCOV version 1.10