summaryrefslogtreecommitdiff
path: root/filter/source/config/cache/filtercache.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/config/cache/filtercache.cxx')
-rw-r--r--filter/source/config/cache/filtercache.cxx2536
1 files changed, 2536 insertions, 0 deletions
diff --git a/filter/source/config/cache/filtercache.cxx b/filter/source/config/cache/filtercache.cxx
new file mode 100644
index 000000000000..d4435e2182f1
--- /dev/null
+++ b/filter/source/config/cache/filtercache.cxx
@@ -0,0 +1,2536 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_filter.hxx"
+
+#include "filtercache.hxx"
+#include "lateinitlistener.hxx"
+#include "macros.hxx"
+#include "constant.hxx"
+#include "cacheupdatelistener.hxx"
+
+/*TODO see using below ... */
+#define AS_ENABLE_FILTER_UINAMES
+#define WORKAROUND_EXCEPTION_PROBLEM
+
+//_______________________________________________
+// includes
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XProperty.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
+#include <comphelper/sequenceasvector.hxx>
+#include <comphelper/locale.hxx>
+#include <unotools/processfactory.hxx>
+
+#ifndef _UNOTOOLS_CONFIGPATHES_HXX_
+#include <unotools/configpathes.hxx>
+#endif
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+#include <rtl/uri.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/wldcrd.hxx>
+
+#include <comphelper/configurationhelper.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+// Error message in case filter config seems to be corrupted.
+// Note: Dont tell user something about "setup -repair"!
+// Its no longer supported by using native installers ...
+static ::rtl::OUString MESSAGE_CORRUPTED_FILTERCONFIG = ::rtl::OUString::createFromAscii("The filter configuration appears to be defective. Please install the office suite again.");
+
+/*-----------------------------------------------
+ 15.03.2004 08:59
+-----------------------------------------------*/
+FilterCache::FilterCache()
+ : BaseLock ( )
+ , m_xSMGR (::comphelper::getProcessServiceFactory())
+ , m_eFillState(E_CONTAINS_NOTHING )
+{
+ RTL_LOGFILE_TRACE("{ (as96863) FilterCache lifetime");
+}
+
+/*-----------------------------------------------
+ 15.03.2004 08:59
+-----------------------------------------------*/
+FilterCache::~FilterCache()
+{
+ RTL_LOGFILE_TRACE("} (as96863) FilterCache lifetime");
+}
+
+/*-----------------------------------------------
+ 03.03.2004 11:27
+-----------------------------------------------*/
+FilterCache* FilterCache::clone() const
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ FilterCache* pClone = new FilterCache();
+
+ // Dont copy the configuration access points here.
+ // They will be created on demand inside the cloned instance,
+ // if they are needed.
+
+ pClone->m_xSMGR = m_xSMGR;
+
+ pClone->m_lTypes = m_lTypes;
+ pClone->m_lDetectServices = m_lDetectServices;
+ pClone->m_lFilters = m_lFilters;
+ pClone->m_lFrameLoaders = m_lFrameLoaders;
+ pClone->m_lContentHandlers = m_lContentHandlers;
+ pClone->m_lExtensions2Types = m_lExtensions2Types;
+ pClone->m_lURLPattern2Types = m_lURLPattern2Types;
+
+ pClone->m_sActLocale = m_sActLocale;
+ pClone->m_sFormatName = m_sFormatName;
+ pClone->m_sFormatVersion = m_sFormatVersion;
+
+ pClone->m_eFillState = m_eFillState;
+
+ pClone->m_lChangedTypes = m_lChangedTypes;
+ pClone->m_lChangedFilters = m_lChangedFilters;
+ pClone->m_lChangedDetectServices = m_lChangedDetectServices;
+ pClone->m_lChangedFrameLoaders = m_lChangedFrameLoaders;
+ pClone->m_lChangedContentHandlers = m_lChangedContentHandlers;
+
+ return pClone;
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 03.03.2004 14:39
+-----------------------------------------------*/
+void FilterCache::takeOver(const FilterCache& rClone)
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // a)
+ // Dont copy the configuration access points here!
+ // We must use our own ones ...
+
+ // b)
+ // Further we can ignore the uno service manager.
+ // We should already have a valid instance.
+
+ // c)
+ // Take over only changed items!
+ // Otherwhise we risk the following scenario:
+ // c1) clone_1 contains changed filters
+ // c2) clone_2 container changed types
+ // c3) clone_1 take over changed filters and unchanged types
+ // c4) clone_2 take over unchanged filters(!) and changed types(!)
+ // c5) c4 overwrites c3!
+
+ if (rClone.m_lChangedTypes.size()>0)
+ m_lTypes = rClone.m_lTypes;
+ if (rClone.m_lChangedDetectServices.size()>0)
+ m_lDetectServices = rClone.m_lDetectServices;
+ if (rClone.m_lChangedFilters.size()>0)
+ m_lFilters = rClone.m_lFilters;
+ if (rClone.m_lChangedFrameLoaders.size()>0)
+ m_lFrameLoaders = rClone.m_lFrameLoaders;
+ if (rClone.m_lChangedContentHandlers.size()>0)
+ m_lContentHandlers = rClone.m_lContentHandlers;
+
+ m_lChangedTypes.clear();
+ m_lChangedDetectServices.clear();
+ m_lChangedFilters.clear();
+ m_lChangedFrameLoaders.clear();
+ m_lChangedContentHandlers.clear();
+
+ m_sActLocale = rClone.m_sActLocale;
+ m_sFormatName = rClone.m_sFormatName;
+ m_sFormatVersion = rClone.m_sFormatVersion;
+
+ m_eFillState = rClone.m_eFillState;
+
+ // renew all dependencies and optimizations
+ // Because we cant be shure, that changed filters on one clone
+ // and changed types of another clone work together.
+ // But here we can check against the lates changes ...
+ impl_validateAndOptimize();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 28.10.2003 09:01
+-----------------------------------------------*/
+void FilterCache::load(EFillState eRequired,
+#if OSL_DEBUG_LEVEL > 1
+ sal_Bool bByThread
+#else
+ sal_Bool
+#endif
+)
+ throw(css::uno::Exception)
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // check if required fill state is already reached ...
+ // There is nothing to do then.
+ if ((m_eFillState & eRequired) == eRequired)
+ return;
+
+#if OSL_DEBUG_LEVEL > 1 && !defined(OS2)
+ if (
+ (!bByThread) &&
+ (
+ ((eRequired & E_CONTAINS_FILTERS) == E_CONTAINS_FILTERS) ||
+ ((eRequired & E_CONTAINS_ALL ) == E_CONTAINS_ALL )
+ )
+ )
+ {
+ OSL_ENSURE(sal_False, "Who disturb our \"fill cache on demand\" feature and force loading of ALL data during office startup? Please optimize your code, so a full filled filter cache is not realy needed here!");
+ }
+#endif
+
+ // Otherwhise load the missing items.
+
+ // ------------------------------------------
+ // a) load some const values from configration.
+ // These values are needed there for loading
+ // config items ...
+ // Further we load some std items from the
+ // configuration so we can try to load the first
+ // office document with a minimal set of values.
+ if (m_eFillState == E_CONTAINS_NOTHING)
+ {
+ impl_getDirectCFGValue(CFGDIRECTKEY_OFFICELOCALE) >>= m_sActLocale;
+ if (!m_sActLocale.getLength())
+ {
+ _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify office locale => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_OFFICELOCALE));
+ m_sActLocale = DEFAULT_OFFICELOCALE;
+ }
+
+ impl_getDirectCFGValue(CFGDIRECTKEY_FORMATNAME) >>= m_sFormatName;
+ if (!m_sFormatName.getLength())
+ impl_getDirectCFGValue(CFGDIRECTKEY_PRODUCTNAME) >>= m_sFormatName;
+
+ if (!m_sFormatName.getLength())
+ {
+ _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify format name => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_FORMATNAME));
+ m_sFormatName = DEFAULT_FORMATNAME;
+ }
+
+ impl_getDirectCFGValue(CFGDIRECTKEY_FORMATVERSION) >>= m_sFormatVersion;
+ if (!m_sFormatVersion.getLength())
+ {
+ _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify format version => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_FORMATVERSION));
+ m_sFormatVersion = DEFAULT_FORMATVERSION;
+ }
+
+ // Support the old configuration support. Read it only one times during office runtime!
+ impl_readOldFormat();
+
+ // enable "loadOnDemand" feature ...
+ // Create uno listener, which waits for finishing the office startup
+ // and starts a thread, which calls loadAll() at this filter cache.
+ // Note: Its not a leak to create this listener with new here.
+ // It kills itself after working!
+ /* LateInitListener* pLateInit = */ new LateInitListener(m_xSMGR);
+ }
+
+ // ------------------------------------------
+ // b) If the required fill state was not reached
+ // but std values was already loaded ...
+ // we must load some further missing items.
+ impl_load(eRequired);
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 28.10.2003 09:50
+-----------------------------------------------*/
+sal_Bool FilterCache::isFillState(FilterCache::EFillState eState) const
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ return ((m_eFillState & eState) == eState);
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 14.07.2003 10:45
+-----------------------------------------------*/
+OUStringList FilterCache::getMatchingItemsByProps( EItemType eType ,
+ const CacheItem& lIProps,
+ const CacheItem& lEProps) const
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // search for right list
+ // An exception is thrown �f "eType" is unknown.
+ // => rList will be valid everytimes next line is reached.
+ CacheItemList& rList = impl_getItemList(eType);
+
+ OUStringList lKeys;
+
+ // search items, which provides all needed properties of set "lIProps"
+ // but not of set "lEProps"!
+ for (CacheItemList::const_iterator pIt = rList.begin();
+ pIt != rList.end() ;
+ ++pIt )
+ {
+ _FILTER_CONFIG_LOG_1_("getMatchingProps for \"%s\" ...\n",
+ _FILTER_CONFIG_TO_ASCII_(pIt->first))
+ if (
+ (pIt->second.haveProps(lIProps) ) &&
+ (pIt->second.dontHaveProps(lEProps))
+ )
+ {
+ lKeys.push_back(pIt->first);
+ }
+ }
+
+ return lKeys;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 02.07.2003 09:32
+-----------------------------------------------*/
+sal_Bool FilterCache::hasItems(EItemType eType) const
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // search for right list
+ // An exception is thrown �f "eType" is unknown.
+ // => rList will be valid everytimes next line is reached.
+ CacheItemList& rList = impl_getItemList(eType);
+
+ return (rList.size()>0);
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 02.07.2003 11:48
+-----------------------------------------------*/
+OUStringList FilterCache::getItemNames(EItemType eType) const
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // search for right list
+ // An exception is thrown �f "eType" is unknown.
+ // => rList will be valid everytimes next line is reached.
+ CacheItemList& rList = impl_getItemList(eType);
+
+ OUStringList lKeys;
+ for (CacheItemList::const_iterator pIt = rList.begin();
+ pIt != rList.end() ;
+ ++pIt )
+ {
+ lKeys.push_back(pIt->first);
+ }
+ return lKeys;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 27.10.2003 08:37
+-----------------------------------------------*/
+sal_Bool FilterCache::hasItem( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // search for right list
+ // An exception is thrown �f "eType" is unknown.
+ // => rList will be valid everytimes next line is reached.
+ CacheItemList& rList = impl_getItemList(eType);
+
+ // if item could not be found - check if it can be loaded
+ // from the underlying configuration layer. Might it was not already
+ // loaded into this FilterCache object before.
+ CacheItemList::const_iterator pIt = rList.find(sItem);
+ if (pIt != rList.end())
+ return sal_True;
+
+ try
+ {
+ impl_loadItemOnDemand(eType, sItem);
+ // no exception => item could be loaded!
+ return sal_True;
+ }
+ catch(const css::container::NoSuchElementException&)
+ {}
+
+ return sal_False;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 17.07.2006 09:15
+-----------------------------------------------*/
+CacheItem FilterCache::getItem( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // search for right list
+ // An exception is thrown if "eType" is unknown.
+ // => rList will be valid everytimes next line is reached.
+ CacheItemList& rList = impl_getItemList(eType);
+
+ // check if item exists ...
+ CacheItemList::iterator pIt = rList.find(sItem);
+ if (pIt == rList.end())
+ {
+ // ... or load it on demand from the
+ // underlying configuration layer.
+ // Note: NoSuchElementException is thrown automaticly here if
+ // item could not be loaded!
+ pIt = impl_loadItemOnDemand(eType, sItem);
+ }
+
+ /* Workaround for #137955#
+ Draw types and filters are installed ... but draw was disabled during setup.
+ We must supress accessing these filters. Otherwise the office can crash.
+ Solution for the next major release: do not install those filters !
+ */
+ if (eType == E_FILTER)
+ {
+ CacheItem& rFilter = pIt->second;
+ ::rtl::OUString sDocService;
+ rFilter[PROPNAME_DOCUMENTSERVICE] >>= sDocService;
+
+ // --> PB 2006-10-18 #142498#
+ // In Standalone-Impress the module WriterWeb is not installed
+ // but it is there to load help pages
+ sal_Bool bIsHelpFilter = sItem.equalsAscii( "writer_web_HTML_help" );
+
+ if ( !bIsHelpFilter && !impl_isModuleInstalled(sDocService) )
+ // <--
+ {
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("The requested filter '" );
+ sMsg.append (sItem );
+ sMsg.appendAscii("' exists ... but it shouldnt; because the corresponding OOo module was not installed.");
+ throw css::container::NoSuchElementException(sMsg.makeStringAndClear(), css::uno::Reference< css::uno::XInterface >());
+ }
+ }
+
+ return pIt->second;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 03.03.2004 11:28
+-----------------------------------------------*/
+void FilterCache::removeItem( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // search for right list
+ // An exception is thrown �f "eType" is unknown.
+ // => rList will be valid everytimes next line is reached.
+ CacheItemList& rList = impl_getItemList(eType);
+
+ CacheItemList::iterator pItem = rList.find(sItem);
+ if (pItem == rList.end())
+ pItem = impl_loadItemOnDemand(eType, sItem); // throws NoSuchELementException!
+ rList.erase(pItem);
+
+ impl_addItem2FlushList(eType, sItem);
+}
+
+/*-----------------------------------------------
+ 26.11.2003 13:28
+-----------------------------------------------*/
+void FilterCache::setItem( EItemType eType ,
+ const ::rtl::OUString& sItem ,
+ const CacheItem& aValue)
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // search for right list
+ // An exception is thrown �f "eType" is unknown.
+ // => rList will be valid everytimes next line is reached.
+ CacheItemList& rList = impl_getItemList(eType);
+
+ // name must be part of the property set too ... otherwhise our
+ // container query cant work correctly
+ CacheItem aItem = aValue;
+ aItem[PROPNAME_NAME] <<= sItem;
+ aItem.validateUINames(m_sActLocale);
+
+ // remove implicit properties as e.g. FINALIZED or MANDATORY
+ // They cant be saved here and must be readed on demand later, if they are needed.
+ removeStatePropsFromItem(aItem);
+
+ rList[sItem] = aItem;
+
+ impl_addItem2FlushList(eType, sItem);
+}
+
+//-----------------------------------------------
+void FilterCache::refreshItem( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ impl_loadItemOnDemand(eType, sItem);
+}
+
+/*-----------------------------------------------
+ 27.10.2003 08:14
+-----------------------------------------------*/
+void FilterCache::addStatePropsToItem( EItemType eType,
+ const ::rtl::OUString& sItem,
+ CacheItem& rItem)
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // Note: Opening of the configuration layer throws some exceptions
+ // if it failed. So we dont must check any reference here ...
+ css::uno::Reference< css::container::XNameAccess > xPackage;
+ css::uno::Reference< css::container::XNameAccess > xSet;
+ switch(eType)
+ {
+ case E_TYPE :
+ {
+ xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY);
+ xPackage->getByName(CFGSET_TYPES) >>= xSet;
+ }
+ break;
+
+ case E_FILTER :
+ {
+ xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY);
+ xPackage->getByName(CFGSET_FILTERS) >>= xSet;
+ }
+ break;
+
+ case E_FRAMELOADER :
+ {
+ /* TODO
+ Hack -->
+ The default frame loader cant be located inside te normal set of frame loaders.
+ Its an atomic property inside the misc cfg package. So we cant retrieve the information
+ about FINALIZED and MANDATORY very easy ... :-(
+ => set it to readonly/required everytimes :-)
+ */
+ css::uno::Any aDirectValue = impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER);
+ ::rtl::OUString sDefaultFrameLoader;
+ if (
+ (aDirectValue >>= sDefaultFrameLoader) &&
+ (sDefaultFrameLoader.getLength() ) &&
+ (sItem.equals(sDefaultFrameLoader) )
+ )
+ {
+ rItem[PROPNAME_FINALIZED] <<= sal_True;
+ rItem[PROPNAME_MANDATORY] <<= sal_True;
+ return;
+ }
+ /* <-- HACK */
+
+ xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY);
+ xPackage->getByName(CFGSET_FRAMELOADERS) >>= xSet;
+ }
+ break;
+
+ case E_CONTENTHANDLER :
+ {
+ xPackage = css::uno::Reference< css::container::XNameAccess >(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY);
+ xPackage->getByName(CFGSET_CONTENTHANDLERS) >>= xSet;
+ }
+ break;
+ default: break;
+ }
+
+ try
+ {
+ css::uno::Reference< css::beans::XProperty > xItem;
+ xSet->getByName(sItem) >>= xItem;
+ css::beans::Property aDescription = xItem->getAsProperty();
+
+ sal_Bool bFinalized = ((aDescription.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY );
+ sal_Bool bMandatory = ((aDescription.Attributes & css::beans::PropertyAttribute::REMOVEABLE) != css::beans::PropertyAttribute::REMOVEABLE);
+
+ rItem[PROPNAME_FINALIZED] <<= bFinalized;
+ rItem[PROPNAME_MANDATORY] <<= bMandatory;
+ }
+ catch(const css::container::NoSuchElementException&)
+ {
+ /* Ignore exceptions for missing elements inside configuration.
+ May by the following reason exists:
+ - The item does not exists inside the new configuration package org.openoffice.TypeDetection - but
+ we got it from the old package org.openoffice.Office/TypeDetection. We dont migrate such items
+ automaticly to the new format. Because it will disturb e.g. the deinstallation of an external filter
+ package. Because such external filter can remove the old file - but not the automaticly created new one ...
+
+ => mark item as FINALIZED / MANDATORY, we dont support writing to the old format
+ */
+ rItem[PROPNAME_FINALIZED] <<= sal_True;
+ rItem[PROPNAME_MANDATORY] <<= sal_True;
+ }
+
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 05.03.2004 10:36
+-----------------------------------------------*/
+void FilterCache::removeStatePropsFromItem(CacheItem& rItem)
+ throw(css::uno::Exception)
+{
+ CacheItem::iterator pIt;
+ pIt = rItem.find(PROPNAME_FINALIZED);
+ if (pIt != rItem.end())
+ rItem.erase(pIt);
+ pIt = rItem.find(PROPNAME_MANDATORY);
+ if (pIt != rItem.end())
+ rItem.erase(pIt);
+}
+
+/*-----------------------------------------------
+ 02.07.2003 09:17
+-----------------------------------------------*/
+void FilterCache::flush()
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // renew all dependencies and optimizations
+ impl_validateAndOptimize();
+
+ if (m_lChangedTypes.size() > 0)
+ {
+ css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY);
+ css::uno::Reference< css::container::XNameAccess > xSet ;
+
+ xConfig->getByName(CFGSET_TYPES) >>= xSet;
+ impl_flushByList(xSet, E_TYPE, m_lTypes, m_lChangedTypes);
+
+ css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
+ xFlush->commitChanges();
+ }
+
+ if (m_lChangedFilters.size() > 0)
+ {
+ css::uno::Reference< css::container::XNameAccess > xConfig(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY);
+ css::uno::Reference< css::container::XNameAccess > xSet ;
+
+ xConfig->getByName(CFGSET_FILTERS) >>= xSet;
+ impl_flushByList(xSet, E_FILTER, m_lFilters, m_lChangedFilters);
+
+ css::uno::Reference< css::util::XChangesBatch > xFlush(xConfig, css::uno::UNO_QUERY);
+ xFlush->commitChanges();
+ }
+
+ /*TODO FrameLoader/ContentHandler must be flushed here too ... */
+}
+
+/*-----------------------------------------------
+ 20.10.2003 09:22
+-----------------------------------------------*/
+void FilterCache::impl_flushByList(const css::uno::Reference< css::container::XNameAccess >& xSet ,
+ EItemType eType ,
+ const CacheItemList& rCache,
+ const OUStringList& lItems)
+ throw(css::uno::Exception)
+{
+ css::uno::Reference< css::container::XNameContainer > xAddRemoveSet = css::uno::Reference< css::container::XNameContainer > (xSet, css::uno::UNO_QUERY);
+ css::uno::Reference< css::container::XNameReplace > xReplaceeSet = css::uno::Reference< css::container::XNameReplace > (xSet, css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XSingleServiceFactory > xFactory = css::uno::Reference< css::lang::XSingleServiceFactory >(xSet, css::uno::UNO_QUERY);
+
+ for (OUStringList::const_iterator pIt = lItems.begin();
+ pIt != lItems.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sItem = *pIt;
+ EItemFlushState eState = impl_specifyFlushOperation(xSet, rCache, sItem);
+ switch(eState)
+ {
+ case E_ITEM_REMOVED :
+ {
+ xAddRemoveSet->removeByName(sItem);
+ }
+ break;
+
+ case E_ITEM_ADDED :
+ {
+ css::uno::Reference< css::container::XNameReplace > xItem (xFactory->createInstance(), css::uno::UNO_QUERY);
+
+ // special case. no exception - but not a valid item => set must be finalized or mandatory!
+ // Reject flush operation by throwing an exception. At least one item couldnt be flushed.
+ if (!xItem.is())
+ throw css::uno::Exception(::rtl::OUString::createFromAscii("Cant add item. Set is finalized or mandatory!"),
+ css::uno::Reference< css::uno::XInterface >() );
+
+ CacheItemList::const_iterator pItem = rCache.find(sItem);
+ impl_saveItem(xItem, eType, pItem->second);
+ xAddRemoveSet->insertByName(sItem, css::uno::makeAny(xItem));
+ }
+ break;
+
+ case E_ITEM_CHANGED :
+ {
+ css::uno::Reference< css::container::XNameReplace > xItem;
+ xSet->getByName(sItem) >>= xItem;
+
+ // special case. no exception - but not a valid item => it must be finalized or mandatory!
+ // Reject flush operation by throwing an exception. At least one item couldnt be flushed.
+ if (!xItem.is())
+ throw css::uno::Exception(::rtl::OUString::createFromAscii("Cant change item. Its finalized or mandatory!"),
+ css::uno::Reference< css::uno::XInterface >() );
+
+ CacheItemList::const_iterator pItem = rCache.find(sItem);
+ impl_saveItem(xItem, eType, pItem->second);
+ }
+ break;
+ default: break;
+ }
+ }
+}
+
+/*-----------------------------------------------
+ 03.11.2003 08:38
+-----------------------------------------------*/
+void FilterCache::detectFlatForURL(const css::util::URL& aURL ,
+ FlatDetection& rFlatTypes) const
+ throw(css::uno::Exception)
+{
+ // extract extension from URL, so it can be used directly as key into our hash map!
+ // Note further: It must be converted to lower case, because the optimize hash
+ // (which maps extensions to types) work with lower case key strings!
+ INetURLObject aParser (aURL.Main);
+ ::rtl::OUString sExtension = aParser.getExtension(INetURLObject::LAST_SEGMENT ,
+ sal_True ,
+ INetURLObject::DECODE_WITH_CHARSET);
+ sExtension = sExtension.toAsciiLowerCase();
+
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ //*******************************************
+ // i) Step over all well known URL pattern
+ // and add registered types to the return list too
+ // Do it as first one - because: if a type match by a
+ // pattern a following deep detection can be supressed!
+ // Further we can stop after first match ...
+ for (CacheItemRegistration::const_iterator pPattReg = m_lURLPattern2Types.begin();
+ pPattReg != m_lURLPattern2Types.end() ;
+ ++pPattReg )
+ {
+ WildCard aPatternCheck(pPattReg->first);
+ if (aPatternCheck.Matches(aURL.Main))
+ {
+ const OUStringList& rTypesForPattern = pPattReg->second;
+
+ FlatDetectionInfo aInfo;
+ aInfo.sType = *(rTypesForPattern.begin());
+ aInfo.bMatchByPattern = sal_True;
+
+ rFlatTypes.push_back(aInfo);
+// return;
+ }
+ }
+
+ //*******************************************
+ // ii) search types matching to the given extension.
+ // Copy every macthing type without changing its order!
+ // Because preferred types was added as first one during
+ // loading configuration.
+ CacheItemRegistration::const_iterator pExtReg = m_lExtensions2Types.find(sExtension);
+ if (pExtReg != m_lExtensions2Types.end())
+ {
+ const OUStringList& rTypesForExtension = pExtReg->second;
+ for (OUStringList::const_iterator pIt = rTypesForExtension.begin();
+ pIt != rTypesForExtension.end() ;
+ ++pIt )
+ {
+ FlatDetectionInfo aInfo;
+ aInfo.sType = *pIt;
+ aInfo.bMatchByExtension = sal_True;
+
+ rFlatTypes.push_back(aInfo);
+ }
+ }
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 03.11.2003 08:38
+-----------------------------------------------*/
+CacheItemList& FilterCache::impl_getItemList(EItemType eType) const
+ throw(css::uno::Exception)
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ switch(eType)
+ {
+ case E_TYPE : return m_lTypes ;
+ case E_FILTER : return m_lFilters ;
+ case E_FRAMELOADER : return m_lFrameLoaders ;
+ case E_CONTENTHANDLER : return m_lContentHandlers;
+ case E_DETECTSERVICE : return m_lDetectServices ;
+
+ default : throw css::uno::Exception(::rtl::OUString::createFromAscii("unknown sub container requested."),
+ css::uno::Reference< css::uno::XInterface >() );
+ }
+
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 21.10.2003 13:20
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > FilterCache::impl_openConfig(EConfigProvider eProvider)
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ ::rtl::OUString sPath ;
+ css::uno::Reference< css::uno::XInterface >* pConfig = 0;
+ css::uno::Reference< css::uno::XInterface > xOld ;
+ ::rtl::OString sRtlLog ;
+ FilterCache::EItemType eItemType( FilterCache::E_TYPE ) ;
+ sal_Bool bStartListening = sal_False;
+
+ switch(eProvider)
+ {
+ case E_PROVIDER_TYPES :
+ {
+ if (m_xConfigTypes.is())
+ return m_xConfigTypes;
+ sPath = CFGPACKAGE_TD_TYPES;
+ pConfig = &m_xConfigTypes;
+ eItemType = FilterCache::E_TYPE;
+ bStartListening = sal_True;
+ sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_TYPES)");
+ }
+ break;
+
+ case E_PROVIDER_FILTERS :
+ {
+ if (m_xConfigFilters.is())
+ return m_xConfigFilters;
+ sPath = CFGPACKAGE_TD_FILTERS;
+ pConfig = &m_xConfigFilters;
+ eItemType = FilterCache::E_FILTER;
+ bStartListening = sal_True;
+ sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_FILTERS)");
+ }
+ break;
+
+ case E_PROVIDER_OTHERS :
+ {
+ if (m_xConfigOthers.is())
+ return m_xConfigOthers;
+ sPath = CFGPACKAGE_TD_OTHERS;
+ pConfig = &m_xConfigOthers;
+ eItemType = FilterCache::E_TYPE;
+ sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OTHERS)");
+ }
+ break;
+
+ case E_PROVIDER_OLD :
+ {
+ // This special provider is used to work with
+ // the old configuration format only. Its not cached!
+ sPath = CFGPACKAGE_TD_OLD;
+ pConfig = &xOld;
+ sRtlLog = ::rtl::OString("framework (as96863) ::FilterCache::impl_openconfig(E_PROVIDER_OLD)");
+ }
+ break;
+
+ default : throw css::uno::Exception(::rtl::OUString::createFromAscii("These configuration node isnt supported here for open!"), 0);
+ }
+
+ {
+ RTL_LOGFILE_CONTEXT(aLog, sRtlLog.getStr());
+ *pConfig = impl_createConfigAccess(sPath ,
+ sal_False, // bReadOnly
+ sal_True ); // bLocalesMode
+ }
+
+ // Start listening for changes on that configuration access.
+ // We must not control the lifetime of this listener. Itself
+ // checks, when ist time to die :-)
+ if (bStartListening)
+ {
+ CacheUpdateListener* pListener = new CacheUpdateListener(m_xSMGR, *pConfig, eItemType);
+ pListener->startListening();
+ }
+
+ return *pConfig;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 17.07.2003 10:10
+-----------------------------------------------*/
+css::uno::Any FilterCache::impl_getDirectCFGValue(const ::rtl::OUString& sDirectKey)
+{
+ ::rtl::OUString sRoot;
+ ::rtl::OUString sKey ;
+
+ if (
+ (!::utl::splitLastFromConfigurationPath(sDirectKey, sRoot, sKey)) ||
+ (!sRoot.getLength() ) ||
+ (!sKey.getLength() )
+ )
+ return css::uno::Any();
+
+ css::uno::Reference< css::uno::XInterface > xCfg = impl_createConfigAccess(sRoot ,
+ sal_True , // bReadOnly
+ sal_False); // bLocalesMode
+ if (!xCfg.is())
+ return css::uno::Any();
+
+ css::uno::Reference< css::container::XNameAccess > xAccess(xCfg, css::uno::UNO_QUERY);
+ if (!xAccess.is())
+ return css::uno::Any();
+
+ css::uno::Any aValue;
+ try
+ {
+ aValue = xAccess->getByName(sKey);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ #if OSL_DEBUG_LEVEL>0
+ catch(const css::uno::Exception& ex)
+ #else
+ catch(const css::uno::Exception&)
+ #endif
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ OSL_ENSURE(sal_False, ::rtl::OUStringToOString(ex.Message, RTL_TEXTENCODING_UTF8).getStr());
+ #endif
+ aValue.clear();
+ }
+
+ return aValue;
+}
+
+/*-----------------------------------------------
+ 17.07.2003 09:49
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > FilterCache::impl_createConfigAccess(const ::rtl::OUString& sRoot ,
+ sal_Bool bReadOnly ,
+ sal_Bool bLocalesMode)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ css::uno::Reference< css::uno::XInterface > xCfg;
+
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
+ m_xSMGR->createInstance(SERVICE_CONFIGURATIONPROVIDER), css::uno::UNO_QUERY);
+
+ if (!xConfigProvider.is())
+ return css::uno::Reference< css::uno::XInterface >();
+
+ ::comphelper::SequenceAsVector< css::uno::Any > lParams;
+ css::beans::PropertyValue aParam ;
+
+ // set root path
+ aParam.Name = _FILTER_CONFIG_FROM_ASCII_("nodepath");
+ aParam.Value <<= sRoot;
+ lParams.push_back(css::uno::makeAny(aParam));
+
+ // enable "all locales mode" ... if required
+ if (bLocalesMode)
+ {
+ aParam.Name = _FILTER_CONFIG_FROM_ASCII_("locale");
+ aParam.Value <<= _FILTER_CONFIG_FROM_ASCII_("*" );
+ lParams.push_back(css::uno::makeAny(aParam));
+ }
+
+ // open it
+ if (bReadOnly)
+ xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONACCESS, lParams.getAsConstList());
+ else
+ xCfg = xConfigProvider->createInstanceWithArguments(SERVICE_CONFIGURATIONUPDATEACCESS, lParams.getAsConstList());
+
+ // If configuration could not be opened ... but factory method does not throwed an exception
+ // trigger throwing of our own CorruptedFilterConfigurationException.
+ // Let message empty. The normal exception text show enough informations to the user.
+ if (! xCfg.is())
+ throw css::uno::Exception(
+ _FILTER_CONFIG_FROM_ASCII_("Got NULL reference on opening configuration file ... but no exception."),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::document::CorruptedFilterConfigurationException(
+ MESSAGE_CORRUPTED_FILTERCONFIG,
+ css::uno::Reference< css::uno::XInterface >(),
+ ex.Message);
+ }
+
+ return xCfg;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 24.10.2003 10:03
+-----------------------------------------------*/
+void FilterCache::impl_validateAndOptimize()
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::impl_validateAndOptimize");
+
+ // First check if any filter or type could be readed
+ // from the underlying configuration!
+ sal_Bool bSomeTypesShouldExist = ((m_eFillState & E_CONTAINS_STANDARD ) == E_CONTAINS_STANDARD );
+ sal_Bool bAllFiltersShouldExist = ((m_eFillState & E_CONTAINS_FILTERS ) == E_CONTAINS_FILTERS );
+
+#if OSL_DEBUG_LEVEL > 0
+
+ sal_Int32 nWarnings = 0;
+
+// sal_Bool bAllTypesShouldExist = ((m_eFillState & E_CONTAINS_TYPES ) == E_CONTAINS_TYPES );
+ sal_Bool bAllLoadersShouldExist = ((m_eFillState & E_CONTAINS_FRAMELOADERS ) == E_CONTAINS_FRAMELOADERS );
+ sal_Bool bAllHandlersShouldExist = ((m_eFillState & E_CONTAINS_CONTENTHANDLERS) == E_CONTAINS_CONTENTHANDLERS);
+#endif
+
+ if (
+ (
+ (bSomeTypesShouldExist) &&
+ (m_lTypes.size() < 1 )
+ ) ||
+ (
+ (bAllFiltersShouldExist) &&
+ (m_lFilters.size() < 1 )
+ )
+ )
+ {
+ throw css::document::CorruptedFilterConfigurationException(
+ MESSAGE_CORRUPTED_FILTERCONFIG,
+ css::uno::Reference< css::uno::XInterface >(),
+ ::rtl::OUString::createFromAscii("The list of types or filters is empty."));
+ }
+
+ // Create a log for all detected problems, which
+ // occure in the next feew lines.
+ // If there are some real errors throw a RuntimException!
+ // If there are some warnings only, show an assertion.
+ sal_Int32 nErrors = 0;
+ ::rtl::OUStringBuffer sLog(256);
+
+ CacheItemList::iterator pIt;
+
+ for (pIt = m_lTypes.begin(); pIt != m_lTypes.end(); ++pIt)
+ {
+ ::rtl::OUString sType = pIt->first;
+ CacheItem aType = pIt->second;
+
+ // create list of all known detect services / frame loader / content handler on demand
+ // Because these informations are available as type properties!
+ ::rtl::OUString sDetectService;
+ aType[PROPNAME_DETECTSERVICE ] >>= sDetectService;
+ if (sDetectService.getLength())
+ impl_resolveItem4TypeRegistration(&m_lDetectServices, sDetectService, sType);
+
+ // get its registration for file Extensions AND(!) URLPattern ...
+ // It doesnt matter if these items exists or if our
+ // used index access create some default ones ...
+ // only in case there is no filled set of Extensions AND
+ // no filled set of URLPattern -> we must try to remove this invalid item
+ // from this cache!
+ css::uno::Sequence< ::rtl::OUString > lExtensions;
+ css::uno::Sequence< ::rtl::OUString > lURLPattern;
+ aType[PROPNAME_EXTENSIONS] >>= lExtensions;
+ aType[PROPNAME_URLPATTERN] >>= lURLPattern;
+ sal_Int32 ce = lExtensions.getLength();
+ sal_Int32 cu = lURLPattern.getLength();
+
+#if OSL_DEBUG_LEVEL > 0
+
+ ::rtl::OUString sInternalTypeNameCheck;
+ aType[PROPNAME_NAME] >>= sInternalTypeNameCheck;
+ if (!sInternalTypeNameCheck.equals(sType))
+ {
+ sLog.appendAscii("Warning\t:\t");
+ sLog.appendAscii("The type \"" );
+ sLog.append (sType );
+ sLog.appendAscii("\" does support the property \"Name\" correctly.\n");
+ ++nWarnings;
+ }
+
+ if (!ce && !cu)
+ {
+ sLog.appendAscii("Warning\t:\t");
+ sLog.appendAscii("The type \"" );
+ sLog.append (sType );
+ sLog.appendAscii("\" does not contain any URL pattern nor any extensions.\n");
+ ++nWarnings;
+ }
+#endif
+
+ // create an optimized registration for this type to
+ // its set list of extensions/url pattern. If its a "normal" type
+ // set it at the end of this optimized list. But if its
+ // a "Preferred" one - set it to the front of this list.
+ // Of course multiple "Preferred" registrations can occure
+ // (they shouldnt - but they can!) ... Ignore it. The last
+ // preferred type is useable in the same manner then every
+ // other type!
+ sal_Bool bPreferred = sal_False;
+ aType[PROPNAME_PREFERRED] >>= bPreferred;
+
+ const ::rtl::OUString* pExtensions = lExtensions.getConstArray();
+ for (sal_Int32 e=0; e<ce; ++e)
+ {
+ // Note: We must be shure that adress the right hash entry
+ // does not depend from any upper/lower case problems ...
+ ::rtl::OUString sNormalizedExtension = pExtensions[e].toAsciiLowerCase();
+
+ OUStringList& lTypesForExtension = m_lExtensions2Types[sNormalizedExtension];
+ if (::std::find(lTypesForExtension.begin(), lTypesForExtension.end(), sType) != lTypesForExtension.end())
+ continue;
+
+ if (bPreferred)
+ lTypesForExtension.insert(lTypesForExtension.begin(), sType);
+ else
+ lTypesForExtension.push_back(sType);
+ }
+
+ const ::rtl::OUString* pURLPattern = lURLPattern.getConstArray();
+ for (sal_Int32 u=0; u<cu; ++u)
+ {
+ OUStringList& lTypesForURLPattern = m_lURLPattern2Types[pURLPattern[u]];
+ if (::std::find(lTypesForURLPattern.begin(), lTypesForURLPattern.end(), sType) != lTypesForURLPattern.end())
+ continue;
+
+ if (bPreferred)
+ lTypesForURLPattern.insert(lTypesForURLPattern.begin(), sType);
+ else
+ lTypesForURLPattern.push_back(sType);
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+
+ // Dont check cross references between types and filters, if
+ // not all filters read from disk!
+ // OK - this cache can read single filters on demand too ...
+ // but then the fill state of this cache shouldnt be set to E_CONTAINS_FILTERS!
+ if (!bAllFiltersShouldExist)
+ continue;
+
+ ::rtl::OUString sPrefFilter;
+ aType[PROPNAME_PREFERREDFILTER] >>= sPrefFilter;
+ if (!sPrefFilter.getLength())
+ {
+ // OK - there is no filter for this type. But thats not an error.
+ // May be it can be handled by a ContentHandler ...
+ // But at this time its not guaranteed that there is any ContentHandler
+ // or FrameLoader inside this cache ... but on disk ...
+ sal_Bool bReferencedByLoader = sal_True;
+ sal_Bool bReferencedByHandler = sal_True;
+ if (bAllLoadersShouldExist)
+ bReferencedByLoader = (impl_searchFrameLoaderForType(sType).getLength()!=0);
+
+ if (bAllHandlersShouldExist)
+ bReferencedByHandler = (impl_searchContentHandlerForType(sType).getLength()!=0);
+
+ if (
+ (!bReferencedByLoader ) &&
+ (!bReferencedByHandler)
+ )
+ {
+ sLog.appendAscii("Warning\t:\t" );
+ sLog.appendAscii("The type \"" );
+ sLog.append (sType );
+ sLog.appendAscii("\" isnt used by any filter, loader or content handler.\n");
+ ++nWarnings;
+ }
+ }
+
+ if (sPrefFilter.getLength())
+ {
+ CacheItemList::const_iterator pIt2 = m_lFilters.find(sPrefFilter);
+ if (pIt2 == m_lFilters.end())
+ {
+ if (bAllFiltersShouldExist)
+ {
+ ++nWarnings; // preferred filters can point to a non-installed office module ! no error ... it's a warning only .-(
+ sLog.appendAscii("error\t:\t");
+ }
+ else
+ {
+ ++nWarnings;
+ sLog.appendAscii("warning\t:\t");
+ }
+
+ sLog.appendAscii("The type \"" );
+ sLog.append (sType );
+ sLog.appendAscii("\" points to an invalid filter \"");
+ sLog.append (sPrefFilter );
+ sLog.appendAscii("\".\n" );
+
+ continue;
+ }
+
+ CacheItem aPrefFilter = pIt2->second;
+ ::rtl::OUString sFilterTypeReg;
+ aPrefFilter[PROPNAME_TYPE] >>= sFilterTypeReg;
+ if (sFilterTypeReg != sType)
+ {
+ sLog.appendAscii("error\t:\t" );
+ sLog.appendAscii("The preferred filter \"" );
+ sLog.append (sPrefFilter );
+ sLog.appendAscii("\" of type \"" );
+ sLog.append (sType );
+ sLog.appendAscii("is registered for another type \"");
+ sLog.append (sFilterTypeReg );
+ sLog.appendAscii("\".\n" );
+ ++nErrors;
+ }
+
+ sal_Int32 nFlags = 0;
+ aPrefFilter[PROPNAME_FLAGS] >>= nFlags;
+ if ((nFlags & FLAGVAL_IMPORT) != FLAGVAL_IMPORT)
+ {
+ sLog.appendAscii("error\t:\t" );
+ sLog.appendAscii("The preferred filter \"" );
+ sLog.append (sPrefFilter );
+ sLog.appendAscii("\" of type \"" );
+ sLog.append (sType );
+ sLog.appendAscii("\" is not an IMPORT filter!\n");
+ ++nErrors;
+ }
+
+ ::rtl::OUString sInternalFilterNameCheck;
+ aPrefFilter[PROPNAME_NAME] >>= sInternalFilterNameCheck;
+ if (!sInternalFilterNameCheck.equals(sPrefFilter))
+ {
+ sLog.appendAscii("Warning\t:\t" );
+ sLog.appendAscii("The filter \"" );
+ sLog.append (sPrefFilter );
+ sLog.appendAscii("\" does support the property \"Name\" correctly.\n");
+ ++nWarnings;
+ }
+ }
+#endif
+ }
+
+ // create dependencies between the global default frame loader
+ // and all types (and of course if registered filters), which
+ // does not registered for any other loader.
+ css::uno::Any aDirectValue = impl_getDirectCFGValue(CFGDIRECTKEY_DEFAULTFRAMELOADER);
+ ::rtl::OUString sDefaultFrameLoader;
+
+ if (
+ (!(aDirectValue >>= sDefaultFrameLoader)) ||
+ (!sDefaultFrameLoader.getLength() )
+ )
+ {
+ sLog.appendAscii("error\t:\t" );
+ sLog.appendAscii("There is no valid default frame loader!?\n");
+ ++nErrors;
+ }
+
+ // a) get list of all well known types
+ // b) step over all well known frame loader services
+ // and remove all types from list a), which already
+ // referenced by a loader b)
+ OUStringList lTypes = getItemNames(E_TYPE);
+ for ( pIt = m_lFrameLoaders.begin();
+ pIt != m_lFrameLoaders.end() ;
+ ++pIt )
+ {
+ // Note: of course the default loader must be ignored here.
+ // Because we replace its registration later completly with all
+ // types, which are not referenced by any other loader.
+ // So we can avaoid our code against the complexity of a diff!
+ ::rtl::OUString sLoader = pIt->first;
+ if (sLoader.equals(sDefaultFrameLoader))
+ continue;
+
+ CacheItem& rLoader = pIt->second;
+ css::uno::Any& rTypesReg = rLoader[PROPNAME_TYPES];
+ OUStringList lTypesReg (rTypesReg);
+
+ for (OUStringList::const_iterator pTypesReg = lTypesReg.begin();
+ pTypesReg != lTypesReg.end() ;
+ ++pTypesReg )
+ {
+ OUStringList::iterator pTypeCheck = ::std::find(lTypes.begin(), lTypes.end(), *pTypesReg);
+ if (pTypeCheck != lTypes.end())
+ lTypes.erase(pTypeCheck);
+ }
+ }
+
+ CacheItem& rDefaultLoader = m_lFrameLoaders[sDefaultFrameLoader];
+ rDefaultLoader[PROPNAME_NAME ] <<= sDefaultFrameLoader;
+ rDefaultLoader[PROPNAME_TYPES] <<= lTypes.getAsConstList();
+
+ ::rtl::OUString sLogOut = sLog.makeStringAndClear();
+ OSL_ENSURE(!nErrors, ::rtl::OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
+ if (nErrors>0)
+ throw css::document::CorruptedFilterConfigurationException(
+ MESSAGE_CORRUPTED_FILTERCONFIG,
+ css::uno::Reference< css::uno::XInterface >(),
+ sLogOut);
+ OSL_ENSURE(!nWarnings, ::rtl::OUStringToOString(sLogOut,RTL_TEXTENCODING_UTF8).getStr());
+
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 20.10.2003 08:15
+-----------------------------------------------*/
+void FilterCache::impl_addItem2FlushList( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception)
+{
+ OUStringList* pList = 0;
+ switch(eType)
+ {
+ case E_TYPE :
+ pList = &m_lChangedTypes;
+ break;
+
+ case E_FILTER :
+ pList = &m_lChangedFilters;
+ break;
+
+ case E_FRAMELOADER :
+ pList = &m_lChangedFrameLoaders;
+ break;
+
+ case E_CONTENTHANDLER :
+ pList = &m_lChangedContentHandlers;
+ break;
+
+ case E_DETECTSERVICE :
+ pList = &m_lChangedDetectServices;
+ break;
+
+ default : throw css::uno::Exception(::rtl::OUString::createFromAscii("unsupported item type"), 0);
+ }
+
+ OUStringList::const_iterator pItem = ::std::find(pList->begin(), pList->end(), sItem);
+ if (pItem == pList->end())
+ pList->push_back(sItem);
+}
+
+/*-----------------------------------------------
+ 20.10.2003 08:49
+-----------------------------------------------*/
+FilterCache::EItemFlushState FilterCache::impl_specifyFlushOperation(const css::uno::Reference< css::container::XNameAccess >& xSet ,
+ const CacheItemList& rList,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception)
+{
+ sal_Bool bExistsInConfigLayer = xSet->hasByName(sItem);
+ sal_Bool bExistsInMemory = (rList.find(sItem) != rList.end());
+
+ EItemFlushState eState( E_ITEM_UNCHANGED );
+
+ // !? ... such situation can occure, if an item was added and(!) removed before it was flushed :-)
+ if (!bExistsInConfigLayer && !bExistsInMemory)
+ eState = E_ITEM_UNCHANGED;
+ else
+ if (!bExistsInConfigLayer && bExistsInMemory)
+ eState = E_ITEM_ADDED;
+ else
+ if (bExistsInConfigLayer && bExistsInMemory)
+ eState = E_ITEM_CHANGED;
+ else
+ if (bExistsInConfigLayer && !bExistsInMemory)
+ eState = E_ITEM_REMOVED;
+
+ return eState;
+}
+
+/*-----------------------------------------------
+ 14.10.2003 09:26
+-----------------------------------------------*/
+void FilterCache::impl_resolveItem4TypeRegistration( CacheItemList* pList,
+ const ::rtl::OUString& sItem,
+ const ::rtl::OUString& sType)
+ throw(css::uno::Exception)
+{
+ CacheItem& rItem = (*pList)[sItem];
+ // In case its a new created entry (automaticly done by the hash_map index operator!)
+ // we must be shure, that this entry has its own name as property available.
+ // Its needed later at our container interface!
+ rItem[PROPNAME_NAME] <<= sItem;
+
+ OUStringList lTypeRegs(rItem[PROPNAME_TYPES]);
+ if (::std::find(lTypeRegs.begin(), lTypeRegs.end(), sType) == lTypeRegs.end())
+ {
+ lTypeRegs.push_back(sType);
+ rItem[PROPNAME_TYPES] <<= lTypeRegs.getAsConstList();
+ }
+}
+
+/*-----------------------------------------------
+ 28.10.2003 09:18
+-----------------------------------------------*/
+void FilterCache::impl_load(EFillState eRequiredState)
+ throw(css::uno::Exception)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // Attention: Detect services are part of the standard set!
+ // So there is no need to handle it seperatly.
+
+ // ------------------------------------------
+ // a) The standard set of config value is needed.
+ if (
+ ((eRequiredState & E_CONTAINS_STANDARD) == E_CONTAINS_STANDARD) &&
+ ((m_eFillState & E_CONTAINS_STANDARD) != E_CONTAINS_STANDARD)
+ )
+ {
+ // Attention! If config couldnt be opened successfully
+ // and exception os thrown automaticly and must be forwarded
+ // to our calli ...
+ css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY);
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load std");
+ impl_loadSet(xTypes, E_TYPE, E_READ_STANDARD, &m_lTypes);
+ }
+ }
+
+ // ------------------------------------------
+ // b) We need all type informations ...
+ if (
+ ((eRequiredState & E_CONTAINS_TYPES) == E_CONTAINS_TYPES) &&
+ ((m_eFillState & E_CONTAINS_TYPES) != E_CONTAINS_TYPES)
+ )
+ {
+ // Attention! If config couldnt be opened successfully
+ // and exception os thrown automaticly and must be forwarded
+ // to our calli ...
+ css::uno::Reference< css::container::XNameAccess > xTypes(impl_openConfig(E_PROVIDER_TYPES), css::uno::UNO_QUERY);
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all types");
+ impl_loadSet(xTypes, E_TYPE, E_READ_UPDATE, &m_lTypes);
+ }
+ }
+
+ // ------------------------------------------
+ // c) We need all filter informations ...
+ if (
+ ((eRequiredState & E_CONTAINS_FILTERS) == E_CONTAINS_FILTERS) &&
+ ((m_eFillState & E_CONTAINS_FILTERS) != E_CONTAINS_FILTERS)
+ )
+ {
+ // Attention! If config couldnt be opened successfully
+ // and exception os thrown automaticly and must be forwarded
+ // to our calli ...
+ css::uno::Reference< css::container::XNameAccess > xFilters(impl_openConfig(E_PROVIDER_FILTERS), css::uno::UNO_QUERY);
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all filters");
+ impl_loadSet(xFilters, E_FILTER, E_READ_ALL, &m_lFilters);
+ }
+ }
+
+ // ------------------------------------------
+ // c) We need all frame loader informations ...
+ if (
+ ((eRequiredState & E_CONTAINS_FRAMELOADERS) == E_CONTAINS_FRAMELOADERS) &&
+ ((m_eFillState & E_CONTAINS_FRAMELOADERS) != E_CONTAINS_FRAMELOADERS)
+ )
+ {
+ // Attention! If config couldnt be opened successfully
+ // and exception os thrown automaticly and must be forwarded
+ // to our calli ...
+ css::uno::Reference< css::container::XNameAccess > xLoaders(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY);
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all frame loader");
+ impl_loadSet(xLoaders, E_FRAMELOADER, E_READ_ALL, &m_lFrameLoaders);
+ }
+ }
+
+ // ------------------------------------------
+ // d) We need all content handler informations ...
+ if (
+ ((eRequiredState & E_CONTAINS_CONTENTHANDLERS) == E_CONTAINS_CONTENTHANDLERS) &&
+ ((m_eFillState & E_CONTAINS_CONTENTHANDLERS) != E_CONTAINS_CONTENTHANDLERS)
+ )
+ {
+ // Attention! If config couldnt be opened successfully
+ // and exception os thrown automaticly and must be forwarded
+ // to our calli ...
+ css::uno::Reference< css::container::XNameAccess > xHandlers(impl_openConfig(E_PROVIDER_OTHERS), css::uno::UNO_QUERY);
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::FilterCache::load all content handler");
+ impl_loadSet(xHandlers, E_CONTENTHANDLER, E_READ_ALL, &m_lContentHandlers);
+ }
+ }
+
+ // update fill state. Note: its a bit field, which combines different parts.
+ m_eFillState = (EFillState) ((sal_Int32)m_eFillState | (sal_Int32)eRequiredState);
+
+ // any data readed?
+ // yes! => validate it and update optimized structures.
+ impl_validateAndOptimize();
+
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 22.09.2003 14:27
+-----------------------------------------------*/
+void FilterCache::impl_loadSet(const css::uno::Reference< css::container::XNameAccess >& xConfig,
+ EItemType eType ,
+ EReadOption eOption,
+ CacheItemList* pCache )
+ throw(css::uno::Exception)
+{
+ // get access to the right configuration set
+ ::rtl::OUString sSetName;
+ switch(eType)
+ {
+ case E_TYPE :
+ sSetName = CFGSET_TYPES;
+ break;
+
+ case E_FILTER :
+ sSetName = CFGSET_FILTERS;
+ break;
+
+ case E_FRAMELOADER :
+ sSetName = CFGSET_FRAMELOADERS;
+ break;
+
+ case E_CONTENTHANDLER :
+ sSetName = CFGSET_CONTENTHANDLERS;
+ break;
+ default: break;
+ }
+
+ css::uno::Reference< css::container::XNameAccess > xSet;
+ css::uno::Sequence< ::rtl::OUString > lItems;
+
+ try
+ {
+ css::uno::Any aVal = xConfig->getByName(sSetName);
+ if (!(aVal >>= xSet) || !xSet.is())
+ {
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("Could not open configuration set \"");
+ sMsg.append (sSetName );
+ sMsg.appendAscii("\"." );
+ throw css::uno::Exception(
+ sMsg.makeStringAndClear(),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ lItems = xSet->getElementNames();
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::document::CorruptedFilterConfigurationException(
+ MESSAGE_CORRUPTED_FILTERCONFIG,
+ css::uno::Reference< css::uno::XInterface >(),
+ ex.Message);
+ }
+
+ // get names of all existing sub items of this set
+ // step over it and fill internal cache structures.
+
+ // But dont update optimized structures like e.g. hash
+ // for mapping extensions to its types!
+
+ const ::rtl::OUString* pItems = lItems.getConstArray();
+ sal_Int32 c = lItems.getLength();
+ for (sal_Int32 i=0; i<c; ++i)
+ {
+ CacheItemList::iterator pItem = pCache->find(pItems[i]);
+ switch(eOption)
+ {
+ // a) read a standard set of properties only or read all
+ case E_READ_STANDARD :
+ case E_READ_ALL :
+ {
+ try
+ {
+ (*pCache)[pItems[i]] = impl_loadItem(xSet, eType, pItems[i], eOption);
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::document::CorruptedFilterConfigurationException(
+ MESSAGE_CORRUPTED_FILTERCONFIG,
+ css::uno::Reference< css::uno::XInterface >(),
+ ex.Message);
+ }
+ }
+ break;
+
+ // b) read optional properties only!
+ // All items must already exist inside our cache.
+ // But they must be updated.
+ case E_READ_UPDATE :
+ {
+ if (pItem == pCache->end())
+ {
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("item \"" );
+ sMsg.append (pItems[i] );
+ sMsg.appendAscii("\" not found for update!");
+ throw css::uno::Exception(sMsg.makeStringAndClear() ,
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ try
+ {
+ CacheItem aItem = impl_loadItem(xSet, eType, pItems[i], eOption);
+ pItem->second.update(aItem);
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::document::CorruptedFilterConfigurationException(
+ MESSAGE_CORRUPTED_FILTERCONFIG,
+ css::uno::Reference< css::uno::XInterface >(),
+ ex.Message);
+ }
+ }
+ break;
+ default: break;
+ }
+ }
+}
+
+/*-----------------------------------------------
+ 26.11.2003 12:49
+-----------------------------------------------*/
+void FilterCache::impl_readPatchUINames(const css::uno::Reference< css::container::XNameAccess >& xNode,
+ CacheItem& rItem)
+ throw(css::uno::Exception)
+{
+ static ::rtl::OUString FORMATNAME_VAR = ::rtl::OUString::createFromAscii("%productname%" );
+ static ::rtl::OUString FORMATVERSION_VAR = ::rtl::OUString::createFromAscii("%formatversion%");
+
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ ::rtl::OUString sFormatName = m_sFormatName ;
+ ::rtl::OUString sFormatVersion = m_sFormatVersion;
+ ::rtl::OUString sActLocale = m_sActLocale ;
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ css::uno::Any aVal = xNode->getByName(PROPNAME_UINAME);
+ css::uno::Reference< css::container::XNameAccess > xUIName;
+ if (!(aVal >>= xUIName) && !xUIName.is())
+ return;
+
+ const ::comphelper::SequenceAsVector< ::rtl::OUString > lLocales(xUIName->getElementNames());
+ ::comphelper::SequenceAsVector< ::rtl::OUString >::const_iterator pLocale ;
+ ::comphelper::SequenceAsHashMap lUINames;
+
+ // patch %PRODUCTNAME and %FORMATNAME
+ for ( pLocale = lLocales.begin();
+ pLocale != lLocales.end() ;
+ ++pLocale )
+ {
+ const ::rtl::OUString& sLocale = *pLocale;
+
+ ::rtl::OUString sValue;
+ xUIName->getByName(sLocale) >>= sValue;
+
+ // replace %productname%
+ sal_Int32 nIndex = sValue.indexOf(FORMATNAME_VAR);
+ while(nIndex != -1)
+ {
+ sValue = sValue.replaceAt(nIndex, FORMATNAME_VAR.getLength(), sFormatName);
+ nIndex = sValue.indexOf(FORMATNAME_VAR, nIndex);
+ }
+ // replace %formatversion%
+ nIndex = sValue.indexOf(FORMATVERSION_VAR);
+ while(nIndex != -1)
+ {
+ sValue = sValue.replaceAt(nIndex, FORMATVERSION_VAR.getLength(), sFormatVersion);
+ nIndex = sValue.indexOf(FORMATVERSION_VAR, nIndex);
+ }
+
+ lUINames[sLocale] <<= sValue;
+ }
+
+ aVal <<= lUINames.getAsConstPropertyValueList();
+ rItem[PROPNAME_UINAMES] = aVal;
+
+ // find right UIName for current office locale
+ // Use fallbacks too!
+ pLocale = ::comphelper::Locale::getFallback(lLocales, sActLocale);
+ if (pLocale == lLocales.end())
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ ::rtl::OUString sName = rItem.getUnpackedValueOrDefault(PROPNAME_NAME, ::rtl::OUString());
+
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("Fallback scenario for filter or type '" );
+ sMsg.append (sName );
+ sMsg.appendAscii("' and locale '" );
+ sMsg.append (sActLocale );
+ sMsg.appendAscii("' failed. Please check your filter configuration.");
+
+ OSL_ENSURE(sal_False, _FILTER_CONFIG_TO_ASCII_(sMsg.makeStringAndClear()));
+ #endif
+ return;
+ }
+
+ const ::rtl::OUString& sLocale = *pLocale;
+ ::comphelper::SequenceAsHashMap::const_iterator pUIName = lUINames.find(sLocale);
+ if (pUIName != lUINames.end())
+ rItem[PROPNAME_UINAME] = pUIName->second;
+}
+
+/*-----------------------------------------------
+ 26.11.2003 12:56
+-----------------------------------------------*/
+void FilterCache::impl_savePatchUINames(const css::uno::Reference< css::container::XNameReplace >& xNode,
+ const CacheItem& rItem)
+ throw(css::uno::Exception)
+{
+ css::uno::Reference< css::container::XNameContainer > xAdd (xNode, css::uno::UNO_QUERY);
+ css::uno::Reference< css::container::XNameAccess > xCheck(xNode, css::uno::UNO_QUERY);
+
+ css::uno::Sequence< css::beans::PropertyValue > lUINames = rItem.getUnpackedValueOrDefault(PROPNAME_UINAMES, css::uno::Sequence< css::beans::PropertyValue >());
+ sal_Int32 c = lUINames.getLength();
+ const css::beans::PropertyValue* pUINames = lUINames.getConstArray();
+
+ for (sal_Int32 i=0; i<c; ++i)
+ {
+ if (xCheck->hasByName(pUINames[i].Name))
+ xNode->replaceByName(pUINames[i].Name, pUINames[i].Value);
+ else
+ xAdd->insertByName(pUINames[i].Name, pUINames[i].Value);
+ }
+}
+
+/*-----------------------------------------------
+ 29.10.2003 13:17
+ TODO
+ clarify, how the real problem behind the
+ wrong constructed CacheItem instance (which
+ will force a crash during destruction)
+ can be solved ...
+-----------------------------------------------*/
+CacheItem FilterCache::impl_loadItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
+ EItemType eType ,
+ const ::rtl::OUString& sItem ,
+ EReadOption eOption)
+ throw(css::uno::Exception)
+{
+ // try to get an API object, which points directly to the
+ // requested item. If it fail an exception should occure and
+ // break this operation. Of course returned API object must be
+ // checked too.
+ css::uno::Reference< css::container::XNameAccess > xItem;
+ #ifdef WORKAROUND_EXCEPTION_PROBLEM
+ try
+ {
+ #endif
+ css::uno::Any aVal = xSet->getByName(sItem);
+ if (!(aVal >>= xItem) || !xItem.is())
+ {
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("found corrupted item \"");
+ sMsg.append (sItem );
+ sMsg.appendAscii("\"." );
+ throw css::uno::Exception(sMsg.makeStringAndClear() ,
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ #ifdef WORKAROUND_EXCEPTION_PROBLEM
+ }
+ catch(const css::container::NoSuchElementException&)
+ {
+ throw;
+ }
+ #endif
+
+ // The internal name of an item must(!) be part of the property
+ // set too. Of course its already used as key into the e.g. outside
+ // used hash map ... but some of our API methods provide
+ // this property set as result only. But the user of this CacheItem
+ // should know, which value the key names has :-) ITS IMPORTANT!
+ CacheItem aItem;
+ aItem[PROPNAME_NAME] = css::uno::makeAny(sItem);
+ switch(eType)
+ {
+ //---------------------------------------
+ case E_TYPE :
+ {
+ // read standard properties of a type
+ if (
+ (eOption == E_READ_STANDARD) ||
+ (eOption == E_READ_ALL )
+ )
+ {
+ aItem[PROPNAME_PREFERREDFILTER] = xItem->getByName(PROPNAME_PREFERREDFILTER);
+ aItem[PROPNAME_DETECTSERVICE ] = xItem->getByName(PROPNAME_DETECTSERVICE );
+ aItem[PROPNAME_URLPATTERN ] = xItem->getByName(PROPNAME_URLPATTERN );
+ aItem[PROPNAME_EXTENSIONS ] = xItem->getByName(PROPNAME_EXTENSIONS );
+ aItem[PROPNAME_PREFERRED ] = xItem->getByName(PROPNAME_PREFERRED );
+ aItem[PROPNAME_CLIPBOARDFORMAT] = xItem->getByName(PROPNAME_CLIPBOARDFORMAT);
+ }
+ // read optional properties of a type
+ // no else here! Is an additional switch ...
+ if (
+ (eOption == E_READ_UPDATE) ||
+ (eOption == E_READ_ALL )
+ )
+ {
+ aItem[PROPNAME_MEDIATYPE ] = xItem->getByName(PROPNAME_MEDIATYPE );
+ impl_readPatchUINames(xItem, aItem);
+ }
+ }
+ break;
+
+ //---------------------------------------
+ case E_FILTER :
+ {
+ // read standard properties of a filter
+ if (
+ (eOption == E_READ_STANDARD) ||
+ (eOption == E_READ_ALL )
+ )
+ {
+ aItem[PROPNAME_TYPE ] = xItem->getByName(PROPNAME_TYPE );
+ aItem[PROPNAME_FILEFORMATVERSION] = xItem->getByName(PROPNAME_FILEFORMATVERSION);
+ aItem[PROPNAME_UICOMPONENT ] = xItem->getByName(PROPNAME_UICOMPONENT );
+ aItem[PROPNAME_FILTERSERVICE ] = xItem->getByName(PROPNAME_FILTERSERVICE );
+ aItem[PROPNAME_DOCUMENTSERVICE ] = xItem->getByName(PROPNAME_DOCUMENTSERVICE );
+
+ // special handling for flags! Convert it from a list of names to its
+ // int representation ...
+ css::uno::Sequence< ::rtl::OUString > lFlagNames;
+ if (xItem->getByName(PROPNAME_FLAGS) >>= lFlagNames)
+ aItem[PROPNAME_FLAGS] <<= FilterCache::impl_convertFlagNames2FlagField(lFlagNames);
+ }
+ // read optional properties of a filter
+ // no else here! Is an additional switch ...
+ if (
+ (eOption == E_READ_UPDATE) ||
+ (eOption == E_READ_ALL )
+ )
+ {
+ aItem[PROPNAME_USERDATA ] = xItem->getByName(PROPNAME_USERDATA );
+ aItem[PROPNAME_TEMPLATENAME] = xItem->getByName(PROPNAME_TEMPLATENAME);
+//TODO remove it if moving of filter uinames to type uinames
+// will be finished realy
+#ifdef AS_ENABLE_FILTER_UINAMES
+ impl_readPatchUINames(xItem, aItem);
+#endif // AS_ENABLE_FILTER_UINAMES
+ }
+ }
+ break;
+
+ //---------------------------------------
+ case E_FRAMELOADER :
+ case E_CONTENTHANDLER :
+ {
+ aItem[PROPNAME_TYPES] = xItem->getByName(PROPNAME_TYPES);
+ }
+ break;
+ default: break;
+ }
+
+ return aItem;
+}
+
+/*-----------------------------------------------
+ 27.10.2003 08:47
+-----------------------------------------------*/
+CacheItemList::iterator FilterCache::impl_loadItemOnDemand( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception)
+{
+ CacheItemList* pList = 0;
+ css::uno::Reference< css::uno::XInterface > xConfig ;
+ ::rtl::OUString sSet ;
+
+ switch(eType)
+ {
+ case E_TYPE :
+ {
+ pList = &m_lTypes;
+ xConfig = impl_openConfig(E_PROVIDER_TYPES);
+ sSet = CFGSET_TYPES;
+ }
+ break;
+
+ case E_FILTER :
+ {
+ pList = &m_lFilters;
+ xConfig = impl_openConfig(E_PROVIDER_FILTERS);
+ sSet = CFGSET_FILTERS;
+ }
+ break;
+
+ case E_FRAMELOADER :
+ {
+ pList = &m_lFrameLoaders;
+ xConfig = impl_openConfig(E_PROVIDER_OTHERS);
+ sSet = CFGSET_FRAMELOADERS;
+ }
+ break;
+
+ case E_CONTENTHANDLER :
+ {
+ pList = &m_lContentHandlers;
+ xConfig = impl_openConfig(E_PROVIDER_OTHERS);
+ sSet = CFGSET_CONTENTHANDLERS;
+ }
+ break;
+
+ case E_DETECTSERVICE :
+ {
+ OSL_ENSURE(sal_False, "Cant load detect services on demand. Who use this unsupported feature?");
+ }
+ break;
+ }
+
+ css::uno::Reference< css::container::XNameAccess > xRoot(xConfig, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::container::XNameAccess > xSet ;
+ xRoot->getByName(sSet) >>= xSet;
+
+ CacheItemList::iterator pItemInCache = pList->find(sItem);
+ sal_Bool bItemInConfig = xSet->hasByName(sItem);
+
+ if (bItemInConfig)
+ {
+ CacheItem aItem;
+ CacheItem::iterator pDbgTest = aItem.find(PROPNAME_NAME);
+ aItem = impl_loadItem(xSet, eType, sItem, E_READ_ALL);
+ (*pList)[sItem] = aItem;
+ _FILTER_CONFIG_LOG_2_("impl_loadItemOnDemand(%d, \"%s\") ... OK", (int)eType, _FILTER_CONFIG_TO_ASCII_(sItem).getStr())
+ }
+ else
+ {
+ if (pItemInCache != pList->end())
+ pList->erase(pItemInCache);
+ // OK - this item does not exists inside configuration.
+ // And we already updated our internal cache.
+ // But the outside code needs this NoSuchElementException
+ // to know, that this item does notexists.
+ // Nobody checks the iterator!
+ throw css::container::NoSuchElementException();
+ }
+
+ return pList->find(sItem);
+}
+
+/*-----------------------------------------------
+ 20.10.2003 09:38
+-----------------------------------------------*/
+void FilterCache::impl_saveItem(const css::uno::Reference< css::container::XNameReplace >& xItem,
+ EItemType eType,
+ const CacheItem& aItem)
+ throw(css::uno::Exception)
+{
+ CacheItem::const_iterator pIt;
+ switch(eType)
+ {
+ //---------------------------------------
+ case E_TYPE :
+ {
+ pIt = aItem.find(PROPNAME_PREFERREDFILTER);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_PREFERREDFILTER, pIt->second);
+ pIt = aItem.find(PROPNAME_DETECTSERVICE);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_DETECTSERVICE, pIt->second);
+ pIt = aItem.find(PROPNAME_URLPATTERN);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_URLPATTERN, pIt->second);
+ pIt = aItem.find(PROPNAME_EXTENSIONS);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_EXTENSIONS, pIt->second);
+ pIt = aItem.find(PROPNAME_PREFERRED);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_PREFERRED, pIt->second);
+ pIt = aItem.find(PROPNAME_MEDIATYPE);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_MEDIATYPE, pIt->second);
+ pIt = aItem.find(PROPNAME_CLIPBOARDFORMAT);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_CLIPBOARDFORMAT, pIt->second);
+
+ css::uno::Reference< css::container::XNameReplace > xUIName;
+ xItem->getByName(PROPNAME_UINAME) >>= xUIName;
+ impl_savePatchUINames(xUIName, aItem);
+ }
+ break;
+
+ //---------------------------------------
+ case E_FILTER :
+ {
+ pIt = aItem.find(PROPNAME_TYPE);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_TYPE, pIt->second);
+ pIt = aItem.find(PROPNAME_FILEFORMATVERSION);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_FILEFORMATVERSION, pIt->second);
+ pIt = aItem.find(PROPNAME_UICOMPONENT);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_UICOMPONENT, pIt->second);
+ pIt = aItem.find(PROPNAME_FILTERSERVICE);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_FILTERSERVICE, pIt->second);
+ pIt = aItem.find(PROPNAME_DOCUMENTSERVICE);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_DOCUMENTSERVICE, pIt->second);
+ pIt = aItem.find(PROPNAME_USERDATA);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_USERDATA, pIt->second);
+ pIt = aItem.find(PROPNAME_TEMPLATENAME);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_TEMPLATENAME, pIt->second);
+
+ // special handling for flags! Convert it from an integer flag field back
+ // to a list of names ...
+ // But note: because we work directly on a reference to the cache item,
+ // its not allowd to change the value here. We must work on a copy!
+ sal_Int32 nFlags = 0;
+ pIt = aItem.find(PROPNAME_FLAGS);
+ if (pIt != aItem.end())
+ {
+ pIt->second >>= nFlags;
+ css::uno::Any aFlagNameList;
+ aFlagNameList <<= FilterCache::impl_convertFlagField2FlagNames(nFlags);
+ xItem->replaceByName(PROPNAME_FLAGS, aFlagNameList);
+ }
+
+//TODO remove it if moving of filter uinames to type uinames
+// will be finished realy
+#ifdef AS_ENABLE_FILTER_UINAMES
+ css::uno::Reference< css::container::XNameReplace > xUIName;
+ xItem->getByName(PROPNAME_UINAME) >>= xUIName;
+ impl_savePatchUINames(xUIName, aItem);
+#endif // AS_ENABLE_FILTER_UINAMES
+ }
+ break;
+
+ //---------------------------------------
+ case E_FRAMELOADER :
+ case E_CONTENTHANDLER :
+ {
+ pIt = aItem.find(PROPNAME_TYPES);
+ if (pIt != aItem.end())
+ xItem->replaceByName(PROPNAME_TYPES, pIt->second);
+ }
+ break;
+ default: break;
+ }
+}
+
+/*-----------------------------------------------
+ 20.10.2003 09:45
+ static! => no locks neccessary
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > FilterCache::impl_convertFlagField2FlagNames(sal_Int32 nFlags)
+{
+ OUStringList lFlagNames;
+
+ if ((nFlags & FLAGVAL_3RDPARTYFILTER ) == FLAGVAL_3RDPARTYFILTER ) lFlagNames.push_back(FLAGNAME_3RDPARTYFILTER );
+ if ((nFlags & FLAGVAL_ALIEN ) == FLAGVAL_ALIEN ) lFlagNames.push_back(FLAGNAME_ALIEN );
+ if ((nFlags & FLAGVAL_ASYNCHRON ) == FLAGVAL_ASYNCHRON ) lFlagNames.push_back(FLAGNAME_ASYNCHRON );
+ if ((nFlags & FLAGVAL_BROWSERPREFERRED ) == FLAGVAL_BROWSERPREFERRED ) lFlagNames.push_back(FLAGNAME_BROWSERPREFERRED );
+ if ((nFlags & FLAGVAL_CONSULTSERVICE ) == FLAGVAL_CONSULTSERVICE ) lFlagNames.push_back(FLAGNAME_CONSULTSERVICE );
+ if ((nFlags & FLAGVAL_DEFAULT ) == FLAGVAL_DEFAULT ) lFlagNames.push_back(FLAGNAME_DEFAULT );
+ if ((nFlags & FLAGVAL_ENCRYPTION ) == FLAGVAL_ENCRYPTION ) lFlagNames.push_back(FLAGNAME_ENCRYPTION );
+ if ((nFlags & FLAGVAL_EXPORT ) == FLAGVAL_EXPORT ) lFlagNames.push_back(FLAGNAME_EXPORT );
+ if ((nFlags & FLAGVAL_IMPORT ) == FLAGVAL_IMPORT ) lFlagNames.push_back(FLAGNAME_IMPORT );
+ if ((nFlags & FLAGVAL_INTERNAL ) == FLAGVAL_INTERNAL ) lFlagNames.push_back(FLAGNAME_INTERNAL );
+ if ((nFlags & FLAGVAL_NOTINCHOOSER ) == FLAGVAL_NOTINCHOOSER ) lFlagNames.push_back(FLAGNAME_NOTINCHOOSER );
+ if ((nFlags & FLAGVAL_NOTINFILEDIALOG ) == FLAGVAL_NOTINFILEDIALOG ) lFlagNames.push_back(FLAGNAME_NOTINFILEDIALOG );
+ if ((nFlags & FLAGVAL_NOTINSTALLED ) == FLAGVAL_NOTINSTALLED ) lFlagNames.push_back(FLAGNAME_NOTINSTALLED );
+ if ((nFlags & FLAGVAL_OWN ) == FLAGVAL_OWN ) lFlagNames.push_back(FLAGNAME_OWN );
+ if ((nFlags & FLAGVAL_PACKED ) == FLAGVAL_PACKED ) lFlagNames.push_back(FLAGNAME_PACKED );
+ if ((nFlags & FLAGVAL_PASSWORDTOMODIFY ) == FLAGVAL_PASSWORDTOMODIFY ) lFlagNames.push_back(FLAGNAME_PASSWORDTOMODIFY );
+ if ((nFlags & FLAGVAL_PREFERRED ) == FLAGVAL_PREFERRED ) lFlagNames.push_back(FLAGNAME_PREFERRED );
+ if ((nFlags & FLAGVAL_READONLY ) == FLAGVAL_READONLY ) lFlagNames.push_back(FLAGNAME_READONLY );
+ if ((nFlags & FLAGVAL_SILENTEXPORT ) == FLAGVAL_SILENTEXPORT ) lFlagNames.push_back(FLAGNAME_SILENTEXPORT );
+ if ((nFlags & FLAGVAL_SUPPORTSSELECTION) == FLAGVAL_SUPPORTSSELECTION) lFlagNames.push_back(FLAGNAME_SUPPORTSSELECTION);
+ if ((nFlags & FLAGVAL_TEMPLATE ) == FLAGVAL_TEMPLATE ) lFlagNames.push_back(FLAGNAME_TEMPLATE );
+ if ((nFlags & FLAGVAL_TEMPLATEPATH ) == FLAGVAL_TEMPLATEPATH ) lFlagNames.push_back(FLAGNAME_TEMPLATEPATH );
+ if ((nFlags & FLAGVAL_USESOPTIONS ) == FLAGVAL_USESOPTIONS ) lFlagNames.push_back(FLAGNAME_USESOPTIONS );
+ if ((nFlags & FLAGVAL_COMBINED ) == FLAGVAL_COMBINED ) lFlagNames.push_back(FLAGNAME_COMBINED );
+
+ return lFlagNames.getAsConstList();
+}
+
+/*-----------------------------------------------
+ 27.06.2003 09:26
+ static! => no locks neccessary
+-----------------------------------------------*/
+sal_Int32 FilterCache::impl_convertFlagNames2FlagField(const css::uno::Sequence< ::rtl::OUString >& lNames)
+{
+ sal_Int32 nField = 0;
+
+ const ::rtl::OUString* pNames = lNames.getConstArray();
+ sal_Int32 c = lNames.getLength();
+ for (sal_Int32 i=0; i<c; ++i)
+ {
+ if (pNames[i].equals(FLAGNAME_3RDPARTYFILTER))
+ {
+ nField |= FLAGVAL_3RDPARTYFILTER;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_ALIEN))
+ {
+ nField |= FLAGVAL_ALIEN;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_ASYNCHRON))
+ {
+ nField |= FLAGVAL_ASYNCHRON;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_BROWSERPREFERRED))
+ {
+ nField |= FLAGVAL_BROWSERPREFERRED;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_CONSULTSERVICE))
+ {
+ nField |= FLAGVAL_CONSULTSERVICE;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_DEFAULT))
+ {
+ nField |= FLAGVAL_DEFAULT;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_ENCRYPTION))
+ {
+ nField |= FLAGVAL_ENCRYPTION;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_EXPORT))
+ {
+ nField |= FLAGVAL_EXPORT;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_IMPORT))
+ {
+ nField |= FLAGVAL_IMPORT;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_INTERNAL))
+ {
+ nField |= FLAGVAL_INTERNAL;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_NOTINCHOOSER))
+ {
+ nField |= FLAGVAL_NOTINCHOOSER;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_NOTINFILEDIALOG))
+ {
+ nField |= FLAGVAL_NOTINFILEDIALOG;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_NOTINSTALLED))
+ {
+ nField |= FLAGVAL_NOTINSTALLED;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_OWN))
+ {
+ nField |= FLAGVAL_OWN;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_PACKED))
+ {
+ nField |= FLAGVAL_PACKED;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_PASSWORDTOMODIFY))
+ {
+ nField |= FLAGVAL_PASSWORDTOMODIFY;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_PREFERRED))
+ {
+ nField |= FLAGVAL_PREFERRED;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_READONLY))
+ {
+ nField |= FLAGVAL_READONLY;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_SILENTEXPORT))
+ {
+ nField |= FLAGVAL_SILENTEXPORT;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_SUPPORTSSELECTION))
+ {
+ nField |= FLAGVAL_SUPPORTSSELECTION;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_TEMPLATE))
+ {
+ nField |= FLAGVAL_TEMPLATE;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_TEMPLATEPATH))
+ {
+ nField |= FLAGVAL_TEMPLATEPATH;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_USESOPTIONS))
+ {
+ nField |= FLAGVAL_USESOPTIONS;
+ continue;
+ }
+ if (pNames[i].equals(FLAGNAME_COMBINED))
+ {
+ nField |= FLAGVAL_COMBINED;
+ continue;
+ }
+ }
+
+ return nField;
+}
+
+/*-----------------------------------------------
+ 12.02.2004 08:40
+-----------------------------------------------*/
+void FilterCache::impl_interpretDataVal4Type(const ::rtl::OUString& sValue,
+ sal_Int32 nProp ,
+ CacheItem& rItem )
+{
+ switch(nProp)
+ {
+ // Preferred
+ case 0: {
+ if (sValue.toInt32() == 1)
+ rItem[PROPNAME_PREFERRED] = css::uno::makeAny(sal_True);
+ else
+ rItem[PROPNAME_PREFERRED] = css::uno::makeAny(sal_False);
+ }
+ break;
+ // MediaType
+ case 1: rItem[PROPNAME_MEDIATYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
+ break;
+ // ClipboardFormat
+ case 2: rItem[PROPNAME_CLIPBOARDFORMAT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
+ break;
+ // URLPattern
+ case 3: rItem[PROPNAME_URLPATTERN] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
+ break;
+ // Extensions
+ case 4: rItem[PROPNAME_EXTENSIONS] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
+ break;
+ }
+}
+
+/*-----------------------------------------------
+ 12.02.2004 08:50
+-----------------------------------------------*/
+void FilterCache::impl_interpretDataVal4Filter(const ::rtl::OUString& sValue,
+ sal_Int32 nProp ,
+ CacheItem& rItem )
+{
+ switch(nProp)
+ {
+ // Order
+ case 0: {
+ sal_Int32 nOrder = sValue.toInt32();
+ if (nOrder > 0)
+ {
+ OSL_ENSURE(sal_False, "FilterCache::impl_interpretDataVal4Filter()\nCant move Order value from filter to type on demand!\n");
+ _FILTER_CONFIG_LOG_2_("impl_interpretDataVal4Filter(%d, \"%s\") ... OK", (int)eType, _FILTER_CONFIG_TO_ASCII_(rItem).getStr())
+ }
+ }
+ break;
+ // Type
+ case 1: rItem[PROPNAME_TYPE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
+ break;
+ // DocumentService
+ case 2: rItem[PROPNAME_DOCUMENTSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
+ break;
+ // FilterService
+ case 3: rItem[PROPNAME_FILTERSERVICE] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
+ break;
+ // Flags
+ case 4: rItem[PROPNAME_FLAGS] <<= sValue.toInt32();
+ break;
+ // UserData
+ case 5: rItem[PROPNAME_USERDATA] <<= impl_tokenizeString(sValue, (sal_Unicode)';').getAsConstList();
+ break;
+ // FileFormatVersion
+ case 6: rItem[PROPNAME_FILEFORMATVERSION] <<= sValue.toInt32();
+ break;
+ // TemplateName
+ case 7: rItem[PROPNAME_TEMPLATENAME] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
+ break;
+ // [optional!] UIComponent
+ case 8: rItem[PROPNAME_UICOMPONENT] <<= ::rtl::Uri::decode(sValue, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
+ break;
+ }
+}
+
+/*-----------------------------------------------
+ 12.02.2004 08:30
+ TODO work on a cache copy first, which can be flushed afterwards
+ That would be usefully to gurantee a consistent cache.
+-----------------------------------------------*/
+void FilterCache::impl_readOldFormat()
+ throw(css::uno::Exception)
+{
+ static ::rtl::OUString TYPES_SET = ::rtl::OUString::createFromAscii("Types" );
+ static ::rtl::OUString FILTER_SET = ::rtl::OUString::createFromAscii("Filters");
+
+ // Attention: Opening/Reading of this old configuration format has to be handled gracefully.
+ // Its optional and shouldnt disturb our normal work!
+ // E.g. we must check, if the package exists ...
+
+ css::uno::Reference< css::container::XNameAccess > xCfg;
+ try
+ {
+ css::uno::Reference< css::uno::XInterface > xInt = impl_openConfig(E_PROVIDER_OLD);
+ xCfg = css::uno::Reference< css::container::XNameAccess >(xInt, css::uno::UNO_QUERY_THROW);
+ }
+ /* corrupt filter addon ? because it's external (optional) code .. we can ignore it. Addon wont work then ...
+ but that seams to be acceptable.
+ see #139088# for further informations
+ */
+ catch(const css::uno::Exception&)
+ { return; }
+
+ // May be there is no type set ...
+ if (xCfg->hasByName(TYPES_SET))
+ {
+ css::uno::Reference< css::container::XNameAccess > xSet;
+ xCfg->getByName(TYPES_SET) >>= xSet;
+ const css::uno::Sequence< ::rtl::OUString > lItems = xSet->getElementNames();
+ const ::rtl::OUString* pItems = lItems.getConstArray();
+ for (sal_Int32 i=0; i<lItems.getLength(); ++i)
+ m_lTypes[pItems[i]] = impl_readOldItem(xSet, E_TYPE, pItems[i]);
+ }
+
+ // May be there is no filter set ...
+ if (xCfg->hasByName(FILTER_SET))
+ {
+ css::uno::Reference< css::container::XNameAccess > xSet;
+ xCfg->getByName(FILTER_SET) >>= xSet;
+ const css::uno::Sequence< ::rtl::OUString > lItems = xSet->getElementNames();
+ const ::rtl::OUString* pItems = lItems.getConstArray();
+ for (sal_Int32 i=0; i<lItems.getLength(); ++i)
+ m_lFilters[pItems[i]] = impl_readOldItem(xSet, E_FILTER, pItems[i]);
+ }
+}
+
+/*-----------------------------------------------
+ 12.02.2004 08:30
+-----------------------------------------------*/
+CacheItem FilterCache::impl_readOldItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
+ EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception)
+{
+ css::uno::Reference< css::container::XNameAccess > xItem;
+ xSet->getByName(sItem) >>= xItem;
+ if (!xItem.is())
+ throw css::uno::Exception(
+ ::rtl::OUString::createFromAscii("Cant read old item."),
+ css::uno::Reference< css::uno::XInterface >());
+
+ CacheItem aItem;
+ aItem[PROPNAME_NAME] <<= sItem;
+
+ // Installed flag ...
+ // Isnt used any longer!
+
+ // UIName
+ impl_readPatchUINames(xItem, aItem);
+
+ // Data
+ ::rtl::OUString sData;
+ OUStringList lData;
+ xItem->getByName(::rtl::OUString::createFromAscii("Data")) >>= sData;
+ lData = impl_tokenizeString(sData, (sal_Unicode)',');
+ if (
+ (!sData.getLength()) ||
+ (lData.size()<1 )
+ )
+ {
+ throw css::uno::Exception(
+ ::rtl::OUString::createFromAscii("Cant read old item property DATA."),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+
+ sal_Int32 nProp = 0;
+ for (OUStringList::const_iterator pProp = lData.begin();
+ pProp != lData.end() ;
+ ++pProp )
+ {
+ const ::rtl::OUString& sProp = *pProp;
+ switch(eType)
+ {
+ case E_TYPE :
+ impl_interpretDataVal4Type(sProp, nProp, aItem);
+ break;
+
+ case E_FILTER :
+ impl_interpretDataVal4Filter(sProp, nProp, aItem);
+ break;
+ default: break;
+ }
+ ++nProp;
+ }
+
+ return aItem;
+}
+
+/*-----------------------------------------------
+ 12.02.2004 08:15
+-----------------------------------------------*/
+OUStringList FilterCache::impl_tokenizeString(const ::rtl::OUString& sData ,
+ sal_Unicode cSeperator)
+{
+ OUStringList lData ;
+ sal_Int32 nToken = 0;
+ do
+ {
+ ::rtl::OUString sToken = sData.getToken(0, cSeperator, nToken);
+ lData.push_back(sToken);
+ }
+ while(nToken >= 0);
+ return lData;
+}
+
+#if OSL_DEBUG_LEVEL > 0
+/*-----------------------------------------------*/
+::rtl::OUString FilterCache::impl_searchFrameLoaderForType(const ::rtl::OUString& sType) const
+{
+ CacheItemList::const_iterator pIt;
+ for ( pIt = m_lFrameLoaders.begin();
+ pIt != m_lFrameLoaders.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sItem = pIt->first;
+ ::comphelper::SequenceAsHashMap lProps(pIt->second);
+ OUStringList lTypes(lProps[PROPNAME_TYPES]);
+
+ if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
+ return sItem;
+ }
+
+ return ::rtl::OUString();
+}
+
+/*-----------------------------------------------*/
+::rtl::OUString FilterCache::impl_searchContentHandlerForType(const ::rtl::OUString& sType) const
+{
+ CacheItemList::const_iterator pIt;
+ for ( pIt = m_lContentHandlers.begin();
+ pIt != m_lContentHandlers.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sItem = pIt->first;
+ ::comphelper::SequenceAsHashMap lProps(pIt->second);
+ OUStringList lTypes(lProps[PROPNAME_TYPES]);
+
+ if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
+ return sItem;
+ }
+
+ return ::rtl::OUString();
+}
+#endif
+
+/*-----------------------------------------------*/
+sal_Bool FilterCache::impl_isModuleInstalled(const ::rtl::OUString& sModule)
+{
+ css::uno::Reference< css::container::XNameAccess > xCfg;
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ if (! m_xModuleCfg.is())
+ {
+ m_xModuleCfg = css::uno::Reference< css::container::XNameAccess >(
+ ::comphelper::ConfigurationHelper::openConfig(
+ m_xSMGR,
+ ::rtl::OUString::createFromAscii("org.openoffice.Setup/Office/Factories"),
+ ::comphelper::ConfigurationHelper::E_READONLY),
+ css::uno::UNO_QUERY_THROW);
+ }
+
+ xCfg = m_xModuleCfg;
+ aLock.clear();
+ // <- SAFE
+
+ if (xCfg.is())
+ return xCfg->hasByName(sModule);
+
+ return sal_False;
+}
+
+ } // namespace config
+} // namespace filter