LCOV - code coverage report
Current view: top level - filter/source/config/cache - filtercache.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 676 958 70.6 %
Date: 2015-06-13 12:38:46 Functions: 35 43 81.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11