| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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_sProductName = m_sProductName; |
| pClone->m_sOOoXMLFormatName = m_sOOoXMLFormatName; |
| pClone->m_sOOoXMLFormatVersion = m_sOOoXMLFormatVersion; |
| |
| 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_sProductName = rClone.m_sProductName; |
| m_sOOoXMLFormatName = rClone.m_sOOoXMLFormatName; |
| m_sOOoXMLFormatVersion = rClone.m_sOOoXMLFormatVersion; |
| |
| 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_PRODUCTNAME) >>= m_sProductName; |
| |
| impl_getDirectCFGValue(CFGDIRECTKEY_FORMATNAME) >>= m_sOOoXMLFormatName; |
| if (!m_sOOoXMLFormatName.getLength()) |
| { |
| _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify format name => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_FORMATNAME)); |
| m_sOOoXMLFormatName = DEFAULT_FORMATNAME; |
| } |
| |
| impl_getDirectCFGValue(CFGDIRECTKEY_FORMATVERSION) >>= m_sOOoXMLFormatVersion; |
| if (!m_sOOoXMLFormatVersion.getLength()) |
| { |
| _FILTER_CONFIG_LOG_1_("FilterCache::ctor() ... could not specify format version => use default \"%s\"\n", _FILTER_CONFIG_TO_ASCII_(DEFAULT_FORMATVERSION)); |
| m_sOOoXMLFormatVersion = 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 PRODUCTNAME_VAR = ::rtl::OUString::createFromAscii("%productname%"); |
| static ::rtl::OUString FORMATNAME_VAR = ::rtl::OUString::createFromAscii("%oooxmlformatname%" ); |
| static ::rtl::OUString FORMATVERSION_VAR = ::rtl::OUString::createFromAscii("%oooxmlformatversion%"); |
| |
| // SAFE -> ---------------------------------- |
| ::osl::ResettableMutexGuard aLock(m_aLock); |
| ::rtl::OUString sProductName = m_sProductName; |
| ::rtl::OUString sFormatName = m_sOOoXMLFormatName; |
| ::rtl::OUString sFormatVersion = m_sOOoXMLFormatVersion; |
| ::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%, %oooxmlformatname% and %oooxmlformatversion% |
| 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(PRODUCTNAME_VAR); |
| while(nIndex != -1) |
| { |
| sValue = sValue.replaceAt(nIndex, PRODUCTNAME_VAR.getLength(), sProductName); |
| nIndex = sValue.indexOf(PRODUCTNAME_VAR, nIndex); |
| } |
| // replace %oooxmlformatname% |
| nIndex = sValue.indexOf(FORMATNAME_VAR); |
| while(nIndex != -1) |
| { |
| sValue = sValue.replaceAt(nIndex, FORMATNAME_VAR.getLength(), sFormatName); |
| nIndex = sValue.indexOf(FORMATNAME_VAR, nIndex); |
| } |
| // replace %oooxmlformatversion% |
| 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_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_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 |