summaryrefslogtreecommitdiff
path: root/filter/source/config/cache
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/config/cache')
-rw-r--r--filter/source/config/cache/basecontainer.cxx638
-rw-r--r--filter/source/config/cache/basecontainer.hxx323
-rw-r--r--filter/source/config/cache/cacheitem.cxx443
-rw-r--r--filter/source/config/cache/cacheitem.hxx261
-rw-r--r--filter/source/config/cache/cacheupdatelistener.cxx246
-rw-r--r--filter/source/config/cache/cacheupdatelistener.hxx147
-rw-r--r--filter/source/config/cache/configflush.cxx168
-rw-r--r--filter/source/config/cache/configflush.hxx128
-rw-r--r--filter/source/config/cache/constant.hxx217
-rw-r--r--filter/source/config/cache/contenthandlerfactory.cxx201
-rw-r--r--filter/source/config/cache/contenthandlerfactory.hxx148
-rw-r--r--filter/source/config/cache/filtercache.cxx2536
-rw-r--r--filter/source/config/cache/filtercache.hxx1066
-rw-r--r--filter/source/config/cache/filterconfig1.component46
-rw-r--r--filter/source/config/cache/filterfactory.cxx724
-rw-r--r--filter/source/config/cache/filterfactory.hxx212
-rw-r--r--filter/source/config/cache/frameloaderfactory.cxx198
-rw-r--r--filter/source/config/cache/frameloaderfactory.hxx148
-rw-r--r--filter/source/config/cache/lateinitlistener.cxx136
-rw-r--r--filter/source/config/cache/lateinitlistener.hxx125
-rw-r--r--filter/source/config/cache/lateinitthread.cxx80
-rw-r--r--filter/source/config/cache/lateinitthread.hxx89
-rw-r--r--filter/source/config/cache/macros.hxx132
-rw-r--r--filter/source/config/cache/makefile.mk87
-rw-r--r--filter/source/config/cache/querytokenizer.cxx99
-rw-r--r--filter/source/config/cache/querytokenizer.hxx115
-rw-r--r--filter/source/config/cache/registration.cxx123
-rw-r--r--filter/source/config/cache/registration.hxx121
-rw-r--r--filter/source/config/cache/typedetection.cxx1257
-rw-r--r--filter/source/config/cache/typedetection.hxx459
-rw-r--r--filter/source/config/cache/versions.hxx36
31 files changed, 10709 insertions, 0 deletions
diff --git a/filter/source/config/cache/basecontainer.cxx b/filter/source/config/cache/basecontainer.cxx
new file mode 100644
index 000000000000..800876ce1abd
--- /dev/null
+++ b/filter/source/config/cache/basecontainer.cxx
@@ -0,0 +1,638 @@
+/*************************************************************************
+ *
+ * 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 "basecontainer.hxx"
+#include "constant.hxx"
+
+//_______________________________________________
+// includes
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/uno/Type.h>
+#include <comphelper/enumhelper.hxx>
+#include <osl/diagnose.h>
+
+//_______________________________________________
+// namespace
+
+#define LOAD_IMPLICIT
+
+namespace css = ::com::sun::star;
+
+namespace filter{
+ namespace config{
+
+//_______________________________________________
+// definitions
+
+::salhelper::SingletonRef< FilterCache >* BaseContainer::m_pPerformanceOptimizer = 0;
+
+/*-----------------------------------------------
+ 03.03.2004 11:37
+-----------------------------------------------*/
+BaseContainer::BaseContainer()
+ : BaseLock ( )
+ , m_rCache ( )
+ , m_pFlushCache(NULL )
+ , m_lListener (m_aLock)
+{
+ m_rCache->load(FilterCache::E_CONTAINS_STANDARD);
+
+ // GLOBAL SAFE (!) -> -----------------------
+ // TODO use rtl pattern to create it realy threadsafe!
+ ::osl::ResettableMutexGuard aGlobalLock(::osl::Mutex::getGlobalMutex());
+ if (!m_pPerformanceOptimizer)
+ m_pPerformanceOptimizer = new ::salhelper::SingletonRef< FilterCache >();
+ aGlobalLock.clear();
+ // <- GLOBAL SAFE (!) -----------------------
+}
+
+/*-----------------------------------------------
+ 02.07.2003 10:16
+-----------------------------------------------*/
+BaseContainer::~BaseContainer()
+{
+}
+
+/*-----------------------------------------------
+ 03.07.2003 11:16
+-----------------------------------------------*/
+void BaseContainer::init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const ::rtl::OUString& sImplementationName,
+ const css::uno::Sequence< ::rtl::OUString >& lServiceNames ,
+ FilterCache::EItemType eType )
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ m_sImplementationName = sImplementationName;
+ m_lServiceNames = lServiceNames ;
+ m_xSMGR = xSMGR ;
+ m_eType = eType ;
+ m_xRefreshBroadcaster = css::uno::Reference< css::util::XRefreshable >(
+ xSMGR->createInstance(SERVICE_FILTERCONFIGREFRESH),
+ css::uno::UNO_QUERY);
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 28.10.2003 09:04
+-----------------------------------------------*/
+void BaseContainer::impl_loadOnDemand()
+{
+#ifdef LOAD_IMPLICIT
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // A generic container needs all items of a set of our cache!
+ // Of course it can block for a while, till the cache is realy filled.
+ // Note: dont load all sets supported by the cache here!
+
+ FilterCache::EFillState eRequiredState = FilterCache::E_CONTAINS_NOTHING;
+ switch(m_eType)
+ {
+ case FilterCache::E_TYPE :
+ eRequiredState = FilterCache::E_CONTAINS_TYPES;
+ break;
+
+ case FilterCache::E_FILTER :
+ eRequiredState = FilterCache::E_CONTAINS_FILTERS;
+ break;
+
+ case FilterCache::E_DETECTSERVICE :
+ eRequiredState = FilterCache::E_CONTAINS_DETECTSERVICES;
+ break;
+
+ case FilterCache::E_FRAMELOADER :
+ eRequiredState = FilterCache::E_CONTAINS_FRAMELOADERS;
+ break;
+
+ case FilterCache::E_CONTENTHANDLER :
+ eRequiredState = FilterCache::E_CONTAINS_CONTENTHANDLERS;
+ break;
+ }
+
+ m_rCache->load(eRequiredState);
+ // <- SAFE
+#endif
+}
+
+/*-----------------------------------------------
+ 03.03.2004 12:18
+-----------------------------------------------*/
+void BaseContainer::impl_initFlushMode()
+ throw (css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ if (!m_pFlushCache)
+ m_pFlushCache = m_rCache->clone();
+ if (!m_pFlushCache)
+ throw css::uno::RuntimeException(
+ ::rtl::OUString::createFromAscii("Cant create write copy of internal used cache on demand."),
+ dynamic_cast< css::container::XNameAccess* >(this));
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 03.03.2004 12:11
+-----------------------------------------------*/
+FilterCache* BaseContainer::impl_getWorkingCache() const
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ if (m_pFlushCache)
+ return m_pFlushCache;
+ else
+ return &(*m_rCache);
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 03.07.2003 11:12
+-----------------------------------------------*/
+::rtl::OUString SAL_CALL BaseContainer::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ return m_sImplementationName;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 03.07.2003 11:14
+-----------------------------------------------*/
+sal_Bool SAL_CALL BaseContainer::supportsService(const ::rtl::OUString& sServiceName)
+ throw (css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ sal_Int32 c = m_lServiceNames.getLength();
+ const ::rtl::OUString* pNames = m_lServiceNames.getConstArray();
+ for (sal_Int32 i=0; i<c; ++i)
+ {
+ if (pNames[i].equals(sServiceName))
+ return sal_True;
+ }
+ return sal_False;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 03.07.2003 11:12
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > SAL_CALL BaseContainer::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ return m_lServiceNames;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 20.10.2003 11:39
+-----------------------------------------------*/
+void SAL_CALL BaseContainer::insertByName(const ::rtl::OUString& sItem ,
+ const css::uno::Any& aValue)
+ throw (css::lang::IllegalArgumentException ,
+ css::container::ElementExistException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ if (!sItem.getLength())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("empty value not allowed as item name."),
+ static_cast< css::container::XNameContainer* >(this),
+ 1);
+
+ CacheItem aItem;
+ try
+ {
+ aItem << aValue;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::lang::IllegalArgumentException(ex.Message, static_cast< css::container::XNameContainer* >(this), 2);
+ }
+
+ impl_loadOnDemand();
+
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // create write copy of used cache on demand ...
+ impl_initFlushMode();
+
+ FilterCache* pCache = impl_getWorkingCache();
+ if (pCache->hasItem(m_eType, sItem))
+ throw css::container::ElementExistException(::rtl::OUString(), static_cast< css::container::XNameContainer* >(this));
+ pCache->setItem(m_eType, sItem, aItem);
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 03.03.2004 11:40
+-----------------------------------------------*/
+void SAL_CALL BaseContainer::removeByName(const ::rtl::OUString& sItem)
+ throw (css::container::NoSuchElementException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ impl_loadOnDemand();
+
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // create write copy of used cache on demand ...
+ impl_initFlushMode();
+
+ FilterCache* pCache = impl_getWorkingCache();
+ pCache->removeItem(m_eType, sItem); // throw exceptions automaticly
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 03.03.2004 11:41
+-----------------------------------------------*/
+void SAL_CALL BaseContainer::replaceByName(const ::rtl::OUString& sItem ,
+ const css::uno::Any& aValue)
+ throw (css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ if (!sItem.getLength())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("empty value not allowed as item name."),
+ static_cast< css::container::XNameContainer* >(this),
+ 1);
+
+ CacheItem aItem;
+ try
+ {
+ aItem << aValue;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::lang::IllegalArgumentException(ex.Message, static_cast< css::container::XNameContainer* >(this), 2);
+ }
+
+ impl_loadOnDemand();
+
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // create write copy of used cache on demand ...
+ impl_initFlushMode();
+
+ FilterCache* pCache = impl_getWorkingCache();
+ if (!pCache->hasItem(m_eType, sItem))
+ throw css::container::NoSuchElementException(::rtl::OUString(), static_cast< css::container::XNameContainer* >(this));
+ pCache->setItem(m_eType, sItem, aItem);
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 03.03.2004 11:44
+-----------------------------------------------*/
+css::uno::Any SAL_CALL BaseContainer::getByName(const ::rtl::OUString& sItem)
+ throw (css::container::NoSuchElementException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ if (!sItem.getLength())
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString::createFromAscii("An empty item cant be part of this cache!"),
+ css::uno::Reference< css::uno::XInterface >(static_cast< css::container::XNameAccess* >(this), css::uno::UNO_QUERY));
+
+ css::uno::Any aValue;
+
+ impl_loadOnDemand();
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ CacheItem aItem;
+ try
+ {
+ FilterCache* pCache = impl_getWorkingCache();
+ aItem = pCache->getItem(m_eType, sItem);
+ pCache->addStatePropsToItem(m_eType, sItem, aItem); // add implicit props "Finalized"/"Mandatory"
+ }
+ catch(const css::container::NoSuchElementException& exNotExist)
+ {
+ throw exNotExist;
+ }
+ catch(const css::uno::Exception&)
+ {
+ // TODO invalid cache!? How should it be handled right?
+ aItem.clear();
+ }
+
+ aValue <<= aItem.getAsPackedPropertyValueList();
+ // <- SAFE
+
+ return aValue;
+}
+
+/*-----------------------------------------------
+ 03.03.2004 11:46
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > SAL_CALL BaseContainer::getElementNames()
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< ::rtl::OUString > lNames;
+
+ impl_loadOnDemand();
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ try
+ {
+ FilterCache* pCache = impl_getWorkingCache();
+ OUStringList lKeys = pCache->getItemNames(m_eType);
+ lKeys >> lNames;
+ }
+ catch(const css::uno::Exception&)
+ {
+ // invalid cache!?
+ lNames.realloc(0);
+ }
+
+ // <- SAFE
+
+ return lNames;
+}
+
+/*-----------------------------------------------
+ 03.03.2004 11:47
+-----------------------------------------------*/
+sal_Bool SAL_CALL BaseContainer::hasByName(const ::rtl::OUString& sItem)
+ throw (css::uno::RuntimeException)
+{
+ sal_Bool bHasOne = sal_False;
+
+ impl_loadOnDemand();
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ try
+ {
+ FilterCache* pCache = impl_getWorkingCache();
+ bHasOne = pCache->hasItem(m_eType, sItem);
+ }
+ catch(const css::uno::Exception&)
+ {
+ // invalid cache!?
+ bHasOne = sal_False;
+ }
+
+ // <- SAFE
+
+ return bHasOne;
+}
+
+/*-----------------------------------------------
+ 02.07.2003 10:18
+-----------------------------------------------*/
+css::uno::Type SAL_CALL BaseContainer::getElementType()
+ throw (css::uno::RuntimeException)
+{
+ // no lock neccessary - because the type of our items
+ // is fix! no internal call or member needed ...
+ return ::getCppuType(static_cast< css::uno::Sequence< css::beans::PropertyValue >* >(NULL));
+}
+
+/*-----------------------------------------------
+ 03.03.2004 11:48
+-----------------------------------------------*/
+sal_Bool SAL_CALL BaseContainer::hasElements()
+ throw (css::uno::RuntimeException)
+{
+ sal_Bool bHasSome = sal_False;
+
+ impl_loadOnDemand();
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ try
+ {
+ FilterCache* pCache = impl_getWorkingCache();
+ bHasSome = pCache->hasItems(m_eType);
+ }
+ catch(const css::uno::Exception&)
+ {
+ // invalid cache?!
+ bHasSome = sal_False;
+ }
+
+ // <- SAFE
+
+ return bHasSome;
+}
+
+/*-----------------------------------------------
+ 15.07.2003 09:21
+-----------------------------------------------*/
+css::uno::Reference< css::container::XEnumeration > SAL_CALL BaseContainer::createSubSetEnumerationByQuery(const ::rtl::OUString& /* sQuery */ )
+ throw (css::uno::RuntimeException)
+{
+ OSL_ENSURE(sal_False, "not pure virtual ... but not realy implemented .-)");
+
+ ::comphelper::OEnumerationByName* pEnum = new ::comphelper::OEnumerationByName(this, css::uno::Sequence< ::rtl::OUString >());
+ return css::uno::Reference< css::container::XEnumeration >(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY);
+}
+
+/*-----------------------------------------------
+ 15.07.2003 10:15
+-----------------------------------------------*/
+css::uno::Reference< css::container::XEnumeration > SAL_CALL BaseContainer::createSubSetEnumerationByProperties(const css::uno::Sequence< css::beans::NamedValue >& lProperties)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Reference< css::container::XEnumeration > xEnum;
+ OUStringList lKeys;
+
+ impl_loadOnDemand();
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ try
+ {
+ // convert the given properties first to our internal representation
+ CacheItem lProps;
+ lProps << lProperties;
+
+ // search the key names of all items, where its properties match
+ // the given ones in its minimum
+ FilterCache* pCache = impl_getWorkingCache();
+ lKeys = pCache->getMatchingItemsByProps(m_eType, lProps);
+ }
+ catch(const css::uno::Exception&)
+ {
+ // invalid cache, internal failure, wrong conversion ...!?
+ // doesnt matter
+ lKeys.clear();
+ }
+
+ // <- SAFE
+
+ // create a specialized enumeration helper, which
+ // provides the collected informations outside.
+ // It hold a reference to us ... and call our container interface directly.
+ // be aware of some direct callbacks if it will be created :-)
+
+ /* Note: Its not allowed to return NULL. Because an empty enumeration
+ transport the same information but make no trouble outside.
+ Further its easiear to work directly with the return value
+ instaed of checking of NULL returns! */
+
+ css::uno::Sequence< ::rtl::OUString > lSubSet;
+ lKeys >> lSubSet;
+ ::comphelper::OEnumerationByName* pEnum = new ::comphelper::OEnumerationByName(this, lSubSet);
+ return css::uno::Reference< css::container::XEnumeration >(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY);
+}
+
+/*-----------------------------------------------
+ 07.03.2004 10:48
+-----------------------------------------------*/
+void SAL_CALL BaseContainer::flush()
+ throw (css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ if (!m_pFlushCache)
+ throw css::lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii("Cant guarantee cache consistency. Special flush container does not exists!"),
+ dynamic_cast< css::container::XNameAccess* >(this),
+ css::uno::Any());
+
+ try
+ {
+ m_pFlushCache->flush();
+ // Take over all changes into the global cache and
+ // forget the clone.
+ /* TODO
+ -think about me
+ If the global cache gets this information via listener,
+ we should remove this method!
+ */
+ m_rCache->takeOver(*m_pFlushCache);
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ // Dont remove the clone. May be the outside
+ // user whish to repair it now and calls flush()
+ // later again ...
+
+ throw css::lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii("Flush rejected by internal container."),
+ dynamic_cast< css::container::XNameAccess* >(this),
+ css::uno::makeAny(ex));
+ }
+
+ delete m_pFlushCache;
+ m_pFlushCache = NULL;
+
+ css::uno::Reference< css::util::XRefreshable > xRefreshBroadcaster = m_xRefreshBroadcaster;
+
+ aLock.clear();
+ // <- SAFE
+
+ if (xRefreshBroadcaster.is())
+ xRefreshBroadcaster->refresh();
+
+ // notify listener outside the lock!
+ // The used listener helper lives if we live
+ // and is threadsafe by itself.
+ // Further its not a good idea to hold the own lock
+ // if an outside object is called :-)
+ css::lang::EventObject aSource (static_cast< css::util::XFlushable* >(this));
+ ::cppu::OInterfaceContainerHelper* pContainer = m_lListener.getContainer(::getCppuType(static_cast< css::uno::Reference< css::util::XFlushListener >* >(NULL)));
+ if (pContainer)
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ // ... this pointer can be interesting to find out, where will be called as listener
+ // Dont optimize it to a direct iterator cast :-)
+ css::util::XFlushListener* pListener = (css::util::XFlushListener*)pIterator.next();
+ pListener->flushed(aSource);
+ }
+ catch(const css::uno::Exception&)
+ {
+ // ignore any "damaged" flush listener!
+ // May its remote reference is broken ...
+ pIterator.remove();
+ }
+ }
+ }
+}
+
+/*-----------------------------------------------
+ 02.07.2003 12:16
+-----------------------------------------------*/
+void SAL_CALL BaseContainer::addFlushListener(const css::uno::Reference< css::util::XFlushListener >& xListener)
+ throw (css::uno::RuntimeException)
+{
+ // no locks neccessary
+ // used helper lives if we live and is threadsafe by itself ...
+ m_lListener.addInterface(::getCppuType(static_cast< css::uno::Reference< css::util::XFlushListener >* >(NULL)),
+ xListener );
+}
+
+/*-----------------------------------------------
+ 02.07.2003 12:18
+-----------------------------------------------*/
+void SAL_CALL BaseContainer::removeFlushListener(const css::uno::Reference< css::util::XFlushListener >& xListener)
+ throw (css::uno::RuntimeException)
+{
+ // no locks neccessary
+ // used helper lives if we live and is threadsafe by itself ...
+ m_lListener.removeInterface(::getCppuType(static_cast< css::uno::Reference< css::util::XFlushListener >* >(NULL)),
+ xListener );
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/basecontainer.hxx b/filter/source/config/cache/basecontainer.hxx
new file mode 100644
index 000000000000..e3730ce662e4
--- /dev/null
+++ b/filter/source/config/cache/basecontainer.hxx
@@ -0,0 +1,323 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef __FILTER_CONFIG_BASECONTAINER_HXX_
+#define __FILTER_CONFIG_BASECONTAINER_HXX_
+
+//_______________________________________________
+// includes
+
+#include "filtercache.hxx"
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainerQuery.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <cppuhelper/interfacecontainer.h>
+#include <salhelper/singletonref.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <rtl/ustring.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+//_______________________________________________
+// definitions
+
+//_______________________________________________
+
+/** @short implements the interface css::container::XNameContainer
+ on top of a FilterCache reference.
+
+ @descr This class can be used as base for own service implementations,
+ which must provide read/write access to the filter configuration.
+ Parameters regulate read/write access, which sub set of informations
+ should be available etc.
+
+ @attention The base class BaseLock must be the first of declared ones.
+ Otherwhise we cant be shure, that our own mutex member (which is
+ present by this base class!) was full initialized inside our own
+ ctor as first!
+ */
+class BaseContainer : public BaseLock
+ , public ::cppu::WeakImplHelper4< css::lang::XServiceInfo ,
+ css::container::XNameContainer , // => XNameReplace => XNameAccess => XElementAccess
+ css::container::XContainerQuery ,
+ css::util::XFlushable >
+{
+ //-------------------------------------------
+ // member
+
+ protected:
+
+ /** @short reference to an uno service manager, which can be used
+ to create own needed services. */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ // TODO
+ css::uno::WeakReference< css::util::XRefreshable > m_xRefreshBroadcaster;
+
+ /** @short the implementation name of our derived class, which we provide
+ at the interface XServiceInfo of our class ... */
+ ::rtl::OUString m_sImplementationName;
+
+ /** @short the list of supported uno service names of our derived class, which we provide
+ at the interface XServiceInfo of our class ... */
+ css::uno::Sequence< ::rtl::OUString > m_lServiceNames;
+
+ /** @short reference(!) to a singleton filter cache implementation,
+ which is used to work with the underlying configuration. */
+ ::salhelper::SingletonRef< FilterCache > m_rCache;
+
+ /** @short local filter cache, which is used to collect changes on the
+ filter configuration first and flush it later.
+
+ @descr Normaly this member isnt used nor initialized. Thats true,
+ if this container is used for reading only. The first write access
+ (e.g. by calling insertByName()) creates a copy of the current
+ global cache m_rCache to initialize the m_pFlushCache member.
+
+ Afterwards only the flush cache copy is used. Inside flush() this
+ copy will be removed and m_rCache can be used again.
+
+ m_pFlushCache and m_rCache must not be synchronized manually here.
+ m_rCache listen on the global configuration, where m_pFlushCache
+ write its data. m_rCache update itself automaticly.
+ */
+ FilterCache* m_pFlushCache;
+
+ /** @short specify, which sub container of the used filter cache
+ must be wrapped by this container interface. */
+ FilterCache::EItemType m_eType;
+
+ /** @short holds all listener, which are registered at this instance. */
+ ::cppu::OMultiTypeInterfaceContainerHelper m_lListener;
+
+ /** @short hold at least on filter cache instance alive and
+ prevent he office from unloading this cache if no filter
+ is currently used.*/
+ static ::salhelper::SingletonRef< FilterCache >* m_pPerformanceOptimizer;
+
+ //-------------------------------------------
+ // native interface
+
+ public:
+
+ //---------------------------------------
+ // ctor/dtor
+
+ /** @short standard ctor.
+
+ @descr Because mostly this class is used as base class for own service
+ implementations in combination with a ImplInheritanceHelper2 template ...
+ there is no way to provide some initializing data through the ctor :-(
+ This base class will be created inside its default ctor and must be
+ initialized with its needed parameters explicitly by calling: "init()".
+
+ @see init()
+ */
+ BaseContainer();
+
+ //---------------------------------------
+
+ /** @short standard dtor.
+ */
+ virtual ~BaseContainer();
+
+ //---------------------------------------
+
+ /** @short initialize this generic intsnace with some specialized values
+ from our derived object.
+
+ @descr Because an outside class must use ImplInheritanceHelper2 template to
+ use us a base class ... and there is no way to pass such initializing
+ parameters trough a required default ctor ... we must be initialized
+ by this special method. Of course this method must be called first before
+ any other interface method is used.
+
+ @param xSMGR
+ reference to the uno service manager, which created this service instance.
+
+ @param sImplementationName
+ the implementation name of our derived class, which we provide
+ at the interface XServiceInfo of our class ...
+
+ @param lServiceNames
+ the list of supported uno service names of our derived class, which we provide
+ at the interface XServiceInfo of our class ...
+
+ @param eType
+ specify, which sub container of the used filter cache
+ must be wrapped by this container interface.
+ */
+ virtual void init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const ::rtl::OUString& sImplementationName,
+ const css::uno::Sequence< ::rtl::OUString >& lServiceNames ,
+ FilterCache::EItemType eType );
+
+ //-------------------------------------------
+ // helper
+
+ protected:
+
+ //---------------------------------------
+
+ /** @short check if the underlying configuration data was already loaded
+ and do it if neccessary automaticly.
+ */
+ void impl_loadOnDemand();
+
+ //---------------------------------------
+
+ /** @short it creates the global instance m_pFilterCache, which is a copy
+ of the global instance m_rCache, and will be used to change the
+ configuration.
+
+ @descr If no exception occures, its guaranteed, that the member m_rFlushCache
+ was initialized right and can be used further.
+ */
+ void impl_initFlushMode()
+ throw (css::uno::RuntimeException);
+
+ //---------------------------------------
+
+ /** @short returns a pointer to the current used cache member.
+
+ @descr Its a point to the FilterCache instance behind m_pFlushCache
+ or m_rCache.
+
+ @note The lifetime of this pointer is restricted to the time, where
+ the mutex of this BaseContainer instance is locked.
+ Otherwhise may be the interface method flush() will destroy
+ m_pFlushCache and the here returned pointer will be invalid!
+
+ Use:
+
+ Guard aLock(m_aLock);
+ FilterCache* p = impl_getWorkingCache();
+ p->doSomething();
+ aLock.clear();
+ // after this point p cant b e guaranteed any longer!
+ */
+ FilterCache* impl_getWorkingCache() const;
+
+ //-------------------------------------------
+ // uno interface
+
+ public:
+
+ //---------------------------------------
+ // XServiceInfo
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService(const ::rtl::OUString& sServiceName)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (css::uno::RuntimeException);
+
+ //---------------------------------------
+ // XNameContainer
+
+ virtual void SAL_CALL insertByName(const ::rtl::OUString& sItem ,
+ const css::uno::Any& aValue)
+ throw (css::lang::IllegalArgumentException ,
+ css::container::ElementExistException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException );
+
+ virtual void SAL_CALL removeByName(const ::rtl::OUString& sItem)
+ throw (css::container::NoSuchElementException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException );
+
+ //---------------------------------------
+ // XNameReplace
+
+ virtual void SAL_CALL replaceByName(const ::rtl::OUString& sItem ,
+ const css::uno::Any& aValue)
+ throw (css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException );
+
+ //---------------------------------------
+ // XElementAccess
+
+ virtual css::uno::Any SAL_CALL getByName(const ::rtl::OUString& sItem)
+ throw (css::container::NoSuchElementException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException );
+
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasByName(const ::rtl::OUString& sItem)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Type SAL_CALL getElementType()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasElements()
+ throw (css::uno::RuntimeException);
+
+ //---------------------------------------
+ // XContainerQuery
+
+ // must be implemented realy by derived class ...
+ // We implement return of an empty result here only!
+ // But we show an assertion :-)
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createSubSetEnumerationByQuery(const ::rtl::OUString& sQuery)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createSubSetEnumerationByProperties(const css::uno::Sequence< css::beans::NamedValue >& lProperties)
+ throw (css::uno::RuntimeException);
+
+ //---------------------------------------
+ // XFlushable
+
+ virtual void SAL_CALL flush()
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL addFlushListener(const css::uno::Reference< css::util::XFlushListener >& xListener)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeFlushListener(const css::uno::Reference< css::util::XFlushListener >& xListener)
+ throw (css::uno::RuntimeException);
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_BASECONTAINER_HXX_
diff --git a/filter/source/config/cache/cacheitem.cxx b/filter/source/config/cache/cacheitem.cxx
new file mode 100644
index 000000000000..c752516df10f
--- /dev/null
+++ b/filter/source/config/cache/cacheitem.cxx
@@ -0,0 +1,443 @@
+/*************************************************************************
+ *
+ * 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 "cacheitem.hxx"
+#include "macros.hxx"
+#include "constant.hxx"
+
+//_______________________________________________
+// includes
+#include <com/sun/star/uno/Sequence.h>
+
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_Hpp_
+#include <com/sun/star/beans/PropertyValue.hpp>
+#endif
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+/*-----------------------------------------------
+ 04.11.2003 09:27
+-----------------------------------------------*/
+CacheItem::CacheItem()
+ : SequenceAsHashMap()
+{
+}
+
+/*-----------------------------------------------
+ 26.06.2003 11:37
+-----------------------------------------------*/
+void CacheItem::update(const CacheItem& rUpdateItem)
+{
+ for(const_iterator pItUpdate = rUpdateItem.begin();
+ pItUpdate != rUpdateItem.end() ;
+ ++pItUpdate )
+ {
+ iterator pItThis = this->find(pItUpdate->first);
+ if (pItThis == this->end())
+ (*this)[pItUpdate->first] = pItUpdate->second; // add new prop
+ else
+ pItThis->second = pItUpdate->second; // change value of existing prop
+ }
+}
+
+/*-----------------------------------------------
+ 26.11.2003 13:27
+-----------------------------------------------*/
+void CacheItem::validateUINames(const ::rtl::OUString& sActLocale)
+{
+ if (!sActLocale.getLength())
+ return;
+
+ // 1) check UINames first
+ const_iterator pUINames = find(PROPNAME_UINAMES);
+ const_iterator pUIName = find(PROPNAME_UINAME );
+
+ ::comphelper::SequenceAsHashMap lUINames;
+ if (pUINames != end())
+ lUINames << pUINames->second;
+
+ ::rtl::OUString sUIName;
+ if (pUIName != end())
+ pUIName->second >>= sUIName;
+
+ if (sUIName.getLength())
+ {
+ // 1a) set UIName inside list of UINames for current locale
+ lUINames[sActLocale] <<= sUIName;
+ }
+ else if (lUINames.size()>0)
+ {
+ // 1b) or get it from this list, if it not exist!
+ lUINames[sActLocale] >>= sUIName;
+ }
+
+ (*this)[PROPNAME_UINAMES] <<= lUINames.getAsConstPropertyValueList();
+ (*this)[PROPNAME_UINAME ] <<= sUIName;
+}
+
+/*-----------------------------------------------
+ 12.01.2004 13:32
+-----------------------------------------------*/
+css::uno::Sequence< css::beans::PropertyValue > CacheItem::getAsPackedPropertyValueList()
+{
+ sal_Int32 c = (sal_Int32)size();
+ sal_Int32 i = 0;
+
+ css::uno::Sequence< css::beans::PropertyValue > lList(c);
+ css::beans::PropertyValue* pList = lList.getArray();
+
+ for (const_iterator pProp = begin();
+ pProp != end() ;
+ ++pProp )
+ {
+ const ::rtl::OUString& rName = pProp->first;
+ const css::uno::Any& rValue = pProp->second;
+
+ if (!rValue.hasValue())
+ continue;
+
+ pList[i].Name = rName ;
+ pList[i].Value = rValue;
+ ++i;
+ }
+ lList.realloc(i);
+
+ return lList;
+}
+
+/*-----------------------------------------------
+ 17.07.2003 08:27
+-----------------------------------------------*/
+sal_Bool isSubSet(const css::uno::Any& aSubSet,
+ const css::uno::Any& aSet )
+{
+ css::uno::Type aT1 = aSubSet.getValueType();
+ css::uno::Type aT2 = aSet.getValueType();
+
+ if (!aT1.equals(aT2))
+ {
+ _FILTER_CONFIG_LOG_("isSubSet() ... types of any values are different => return FALSE\n")
+ return sal_False;
+ }
+
+ css::uno::TypeClass aTypeClass = aT1.getTypeClass();
+ switch(aTypeClass)
+ {
+ //---------------------------------------
+ case css::uno::TypeClass_BOOLEAN :
+ case css::uno::TypeClass_BYTE :
+ case css::uno::TypeClass_SHORT :
+ case css::uno::TypeClass_UNSIGNED_SHORT :
+ case css::uno::TypeClass_LONG :
+ case css::uno::TypeClass_UNSIGNED_LONG :
+ case css::uno::TypeClass_HYPER :
+ case css::uno::TypeClass_UNSIGNED_HYPER :
+ case css::uno::TypeClass_FLOAT :
+ case css::uno::TypeClass_DOUBLE :
+ {
+ sal_Bool bIs = (aSubSet == aSet);
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for atomic types => return %s\n", bIs ? "TRUE" : "FALSE")
+ return bIs;
+ }
+
+ //---------------------------------------
+ case css::uno::TypeClass_STRING :
+ {
+ ::rtl::OUString v1;
+ ::rtl::OUString v2;
+
+ if (
+ (aSubSet >>= v1) &&
+ (aSet >>= v2)
+ )
+ {
+ sal_Bool bIs = (v1.equals(v2));
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for string types => return %s\n", bIs ? "TRUE" : "FALSE")
+ return bIs;
+ }
+ }
+ break;
+
+ //---------------------------------------
+ case css::uno::TypeClass_ANY :
+ {
+ css::uno::Any v1;
+ css::uno::Any v2;
+
+ if (
+ (aSubSet >>= v1) &&
+ (aSet >>= v2)
+ )
+ {
+ sal_Bool bIs = (isSubSet(v1, v2));
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for packed any types => return %s\n", bIs ? "TRUE" : "FALSE")
+ return bIs;
+ }
+ }
+ break;
+
+ //---------------------------------------
+ case css::uno::TypeClass_STRUCT :
+ {
+ css::beans::PropertyValue p1;
+ css::beans::PropertyValue p2;
+
+ if (
+ (aSubSet >>= p1) &&
+ (aSet >>= p2)
+ )
+ {
+ sal_Bool bIs = (
+ (p1.Name.equals(p2.Name) ) &&
+ (isSubSet(p1.Value, p2.Value))
+ );
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for structured types [PropertyValue] => return %s\n", bIs ? "TRUE" : "FALSE")
+ return bIs;
+ }
+
+ css::beans::NamedValue n1;
+ css::beans::NamedValue n2;
+
+ if (
+ (aSubSet >>= n1) &&
+ (aSet >>= n2)
+ )
+ {
+ sal_Bool bIs = (
+ (n1.Name.equals(n2.Name) ) &&
+ (isSubSet(n1.Value, n2.Value))
+ );
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for structured types [NamedValue] => return %s\n", bIs ? "TRUE" : "FALSE")
+ return bIs;
+ }
+ }
+ break;
+
+ //---------------------------------------
+ case css::uno::TypeClass_SEQUENCE :
+ {
+ css::uno::Sequence< ::rtl::OUString > uno_s1;
+ css::uno::Sequence< ::rtl::OUString > uno_s2;
+
+ if (
+ (aSubSet >>= uno_s1) &&
+ (aSet >>= uno_s2)
+ )
+ {
+ OUStringList stl_s1(uno_s1);
+ OUStringList stl_s2(uno_s2);
+
+ for (OUStringList::const_iterator it1 = stl_s1.begin();
+ it1 != stl_s1.end() ;
+ ++it1 )
+ {
+ if (::std::find(stl_s2.begin(), stl_s2.end(), *it1) == stl_s2.end())
+ {
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [OUString] ... dont found \"%s\" => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(*it1))
+ return sal_False;
+ }
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [OUString] ... found \"%s\" => continue loop\n", _FILTER_CONFIG_TO_ASCII_(*it1))
+ }
+ _FILTER_CONFIG_LOG_("isSubSet() ... check for list types [OUString] => return TRUE\n")
+ return sal_True;
+ }
+
+ css::uno::Sequence< css::beans::PropertyValue > uno_p1;
+ css::uno::Sequence< css::beans::PropertyValue > uno_p2;
+
+ if (
+ (aSubSet >>= uno_p1) &&
+ (aSet >>= uno_p2)
+ )
+ {
+ ::comphelper::SequenceAsHashMap stl_p1(uno_p1);
+ ::comphelper::SequenceAsHashMap stl_p2(uno_p2);
+
+ for (::comphelper::SequenceAsHashMap::const_iterator it1 = stl_p1.begin();
+ it1 != stl_p1.end() ;
+ ++it1 )
+ {
+ ::comphelper::SequenceAsHashMap::const_iterator it2 = stl_p2.find(it1->first);
+ if (it2 == stl_p2.end())
+ {
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [PropertyValue] ... dont found \"%s\" => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
+ return sal_False;
+ }
+ if (!isSubSet(it1->second, it2->second))
+ {
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [PropertyValue] ... found \"%s\" but has different value => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
+ return sal_False;
+ }
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [PropertyValue] ... found \"%s\" with right value => continue loop\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
+ }
+ _FILTER_CONFIG_LOG_("isSubSet() ... check for list types [PropertyValue] => return TRUE\n")
+ return sal_True;
+ }
+
+ css::uno::Sequence< css::beans::NamedValue > uno_n1;
+ css::uno::Sequence< css::beans::NamedValue > uno_n2;
+
+ if (
+ (aSubSet >>= uno_n1) &&
+ (aSet >>= uno_n2)
+ )
+ {
+ ::comphelper::SequenceAsHashMap stl_n1(uno_n1);
+ ::comphelper::SequenceAsHashMap stl_n2(uno_n2);
+
+ for (::comphelper::SequenceAsHashMap::const_iterator it1 = stl_n1.begin();
+ it1 != stl_n1.end() ;
+ ++it1 )
+ {
+ ::comphelper::SequenceAsHashMap::const_iterator it2 = stl_n2.find(it1->first);
+ if (it2 == stl_n2.end())
+ {
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [NamedValue] ... dont found \"%s\" => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
+ return sal_False;
+ }
+ if (!isSubSet(it1->second, it2->second))
+ {
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [NamedValue] ... found \"%s\" but has different value => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
+ return sal_False;
+ }
+ _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [NamedValue] ... found \"%s\" with right value => continue loop\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
+ }
+ _FILTER_CONFIG_LOG_("isSubSet() ... check for list types [NamedValue] => return TRUE\n")
+ return sal_True;
+ }
+ }
+ break;
+/*
+ case css::uno::TypeClass_CHAR :
+ case css::uno::TypeClass_VOID :
+ case css::uno::TypeClass_TYPE :
+ case css::uno::TypeClass_ENUM :
+ case css::uno::TypeClass_TYPEDEF :
+ case css::uno::TypeClass_UNION :
+ case css::uno::TypeClass_EXCEPTION :
+ case css::uno::TypeClass_ARRAY :
+ case css::uno::TypeClass_INTERFACE :
+ case css::uno::TypeClass_SERVICE :
+ case css::uno::TypeClass_MODULE :
+ case css::uno::TypeClass_INTERFACE_METHOD :
+ case css::uno::TypeClass_INTERFACE_ATTRIBUTE :
+ case css::uno::TypeClass_UNKNOWN :
+ case css::uno::TypeClass_PROPERTY :
+ case css::uno::TypeClass_CONSTANT :
+ case css::uno::TypeClass_CONSTANTS :
+ case css::uno::TypeClass_SINGLETON :
+*/
+ default: break;
+ }
+
+ OSL_ENSURE(sal_False, "isSubSet() ... this point should not be reached!");
+ return sal_False;
+}
+
+/*-----------------------------------------------
+ 14.07.2003 10:24
+-----------------------------------------------*/
+sal_Bool CacheItem::haveProps(const CacheItem& lProps) const
+{
+ for (const_iterator pIt = lProps.begin();
+ pIt != lProps.end() ;
+ ++pIt )
+ {
+ // i) one required property does not exist at this item => return false
+ const_iterator pItThis = this->find(pIt->first);
+ if (pItThis == this->end())
+ {
+ _FILTER_CONFIG_LOG_1_("CacheItem::haveProps() ... dont found \"%s\" => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(pIt->first))
+ return sal_False;
+ }
+
+ // ii) one item does not have the right value => return false
+ if (!isSubSet(pIt->second, pItThis->second))
+ {
+ _FILTER_CONFIG_LOG_1_("CacheItem::haveProps() ... item \"%s\" has different value => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(pIt->first))
+ return sal_False;
+ }
+ }
+
+ // this method was not breaked before =>
+ // the given property set seems to match with our
+ // own properties in its minimum => return TRUE
+ _FILTER_CONFIG_LOG_("CacheItem::haveProps() ... => return TRUE\n")
+ return sal_True;
+}
+
+/*-----------------------------------------------
+ 14.07.2003 10:43
+-----------------------------------------------*/
+sal_Bool CacheItem::dontHaveProps(const CacheItem& lProps) const
+{
+ for (const_iterator pIt = lProps.begin();
+ pIt != lProps.end() ;
+ ++pIt )
+ {
+ // i) one item does not exists in general
+ // => continue with next one, because
+ // "excluding" means ... "dont have it".
+ // And "not exists" match to "dont have it".
+ const_iterator pItThis = this->find(pIt->first);
+ if (pItThis == this->end())
+ {
+ _FILTER_CONFIG_LOG_1_("CacheItem::dontHaveProps() ... not found \"%s\" => continue loop!\n", _FILTER_CONFIG_TO_ASCII_(pIt->first))
+ continue;
+ }
+
+ // ii) one item have the right value => return false
+ // because this item has the requested property ...
+ // But we checked for "dont have it" here.
+ if (isSubSet(pIt->second, pItThis->second))
+ {
+ _FILTER_CONFIG_LOG_1_("CacheItem::dontHaveProps() ... item \"%s\" has same value => return FALSE!\n", _FILTER_CONFIG_TO_ASCII_(pIt->first))
+ return sal_False;
+ }
+ }
+
+ // this method was not breaked before =>
+ // That means: this item has no matching property
+ // of the given set. It "dont have" it ... => return true.
+ _FILTER_CONFIG_LOG_("CacheItem::dontHaveProps() ... => return TRUE\n")
+ return sal_True;
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/cacheitem.hxx b/filter/source/config/cache/cacheitem.hxx
new file mode 100644
index 000000000000..793a5f370cf9
--- /dev/null
+++ b/filter/source/config/cache/cacheitem.hxx
@@ -0,0 +1,261 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __FILTER_CONFIG_CACHEITEM_HXX_
+#define __FILTER_CONFIG_CACHEITEM_HXX_
+
+//_______________________________________________
+// includes
+
+#include <hash_map>
+#include <deque>
+#include <list>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <comphelper/sequenceasvector.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <osl/mutex.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+/** @short Must be used as first derived base class
+ to get a full initialized mutex member,
+ which can be used during the ctor runs too!
+ */
+struct BaseLock
+{
+ public:
+
+ // must be mutable to be useable in const environments too!
+ mutable ::osl::Mutex m_aLock;
+};
+
+
+typedef ::comphelper::SequenceAsVector< ::rtl::OUString > OUStringList;
+
+//_______________________________________________
+
+/** @short represent an item of a FilterCache
+ instance.
+
+ @descr This class is not threadsafe tp perform
+ operations, which use many instances of
+ this class! Synchronizations must be done outside.
+ */
+class CacheItem : public ::comphelper::SequenceAsHashMap
+{
+ //-------------------------------------------
+ public:
+
+ //---------------------------------------
+ /** @short creates an empty item.
+ */
+ CacheItem();
+
+ //---------------------------------------
+
+ /** @short update only properties, which are given by the
+ specified rItem.
+
+ @descr Update means: - add new properties
+ - change existing values
+
+ @param rUpdateItem
+ another cache item, which contains some special
+ properties, which should by used for updating
+ this one.
+ */
+ void update(const CacheItem& rUpdateItem);
+
+ //---------------------------------------
+
+ /** @short check, if the given properties exists
+ at this item.
+
+ @descr All properties are compared in its minimum.
+ E.g: string lists => only the requested items
+ are checked. Additional existing items are ignored.
+
+ @param lProps
+ contains all properties, which must exist at this item.
+
+ @return TRUE if all given properties exists
+ at this item; FALSE otherwhise.
+ */
+ sal_Bool haveProps(const CacheItem& lProps) const;
+
+ //---------------------------------------
+
+ /** @short check, if the given properties dont exists
+ at this item.
+
+ @descr All properties are compared in its minimum.
+ E.g: string lists => only the requested items
+ are checked. Additional existing items are ignored.
+
+ @param lProps
+ contains all properties, which should not exists at this item.
+
+ @return FALSE if at least on property exists at this item(!);
+ TRUE otherwhise.
+ */
+ sal_Bool dontHaveProps(const CacheItem& lProps) const;
+
+ //---------------------------------------
+
+ /** @short check, if the given properties dont exists
+ at this item.
+
+ @descr All properties are compared in its minimum.
+ E.g: string lists => only the specified items
+ are checked. Additional existing items are ignored.
+
+ @param lProps
+ contains all properties, which should be checked.
+
+ @return TRUE if all given properties dont exists
+ at this item; FALSE otherwhise.
+ */
+ sal_Bool excludeProps(const CacheItem& lProps) const;
+
+ //---------------------------------------
+
+ /** @short because we know two UIName properties
+ (a list with all locales and the value
+ for the current locale only), we must be shure
+ that the correspond together.
+
+ @param sActLocale
+ must specify the current office locale.
+ Its needed to adress the UIName property inside
+ the list of possible ones.
+ */
+ void validateUINames(const ::rtl::OUString& sActLocale);
+
+ //---------------------------------------
+
+ /** @short convert this structure to a seq< PropertyValue >
+ and ignore all empty properties!
+
+ @descr Normaly the converter routines of the base class
+ SequenceAsHashMap do this job already.
+ But it doesnt provide a "pack" mechanism to
+ ignore properties with empty (means "void") values.
+
+ @return css::uno::Sequence< css::beans::PropertyValue >
+ as a list of all properties of this cacheitem,
+ where empty properties was removed.
+ */
+ css::uno::Sequence< css::beans::PropertyValue > getAsPackedPropertyValueList();
+};
+
+//_______________________________________________
+
+/** @short represent an item list of a FilterCache
+ instance.
+ */
+typedef ::std::hash_map< ::rtl::OUString ,
+ CacheItem ,
+ ::rtl::OUStringHash ,
+ ::std::equal_to< ::rtl::OUString > > CacheItemList;
+
+//_______________________________________________
+
+/** @short supports registration of multiple key to
+ another string information.
+
+ @descr E.g. a list of internal type names can be registered
+ to an extension. Organization as an hash makes it
+ faster then searching inside vectors.
+
+ On the other side e.g. URLPattern cant be realy adressed
+ by a hash value ... because the use wildcards. But
+ there we need key-value pairs too, which cant be provided
+ by a pur vector!
+ */
+typedef ::std::hash_map< ::rtl::OUString ,
+ OUStringList ,
+ ::rtl::OUStringHash ,
+ ::std::equal_to< ::rtl::OUString > > CacheItemRegistration;
+
+//_______________________________________________
+
+/** @short is used to collect all matching types of an URL
+ during type detection.
+
+ @descr Every type in this list is combined with an information,
+ which property matched to the given URL. The user of this
+ structure can decide then, if a deep detection should be
+ supressed e.g. if an URLPattern was used.
+ */
+struct FlatDetectionInfo
+{
+ // the internal type name
+ ::rtl::OUString sType;
+
+ // this type was found by a matching the URL extension
+ sal_Bool bMatchByExtension;
+
+ // this type was found by a matching URL Pattern
+ sal_Bool bMatchByPattern;
+
+ // the user selected this type explicitly
+ sal_Bool bPreselectedAsType;
+
+ // the user selected this type implicit by selecting a corresponding filter
+ sal_Bool bPreselectedByFilter;
+
+ // the user selected this type implicit by selecting a corresponding office module
+ sal_Bool bPreselectedByDocumentService;
+
+ FlatDetectionInfo()
+ : sType (::rtl::OUString())
+ , bMatchByExtension (sal_False )
+ , bMatchByPattern (sal_False )
+ , bPreselectedAsType (sal_False )
+ , bPreselectedByFilter (sal_False )
+ , bPreselectedByDocumentService(sal_False )
+ {}
+};
+
+typedef ::std::list< FlatDetectionInfo > FlatDetection;
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_CACHEITEM_HXX_
diff --git a/filter/source/config/cache/cacheupdatelistener.cxx b/filter/source/config/cache/cacheupdatelistener.cxx
new file mode 100644
index 000000000000..90bd89c9d864
--- /dev/null
+++ b/filter/source/config/cache/cacheupdatelistener.cxx
@@ -0,0 +1,246 @@
+/*************************************************************************
+ *
+ * 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 "cacheupdatelistener.hxx"
+#include "constant.hxx"
+
+//_______________________________________________
+// includes
+#include <com/sun/star/util/XChangesNotifier.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <salhelper/singletonref.hxx>
+#include <unotools/configpathes.hxx>
+#include <rtl/ustring.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+/*-----------------------------------------------
+ 05.03.2004 08:36
+-----------------------------------------------*/
+CacheUpdateListener::CacheUpdateListener(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::uno::XInterface >& xConfigAccess,
+ FilterCache::EItemType eConfigType )
+ : BaseLock ( )
+ , m_xSMGR (xSMGR )
+ , m_rCache ( )
+ , m_xConfig (xConfigAccess)
+ , m_eConfigType(eConfigType )
+{
+}
+
+/*-----------------------------------------------
+ 05.03.2004 08:37
+-----------------------------------------------*/
+CacheUpdateListener::~CacheUpdateListener()
+{
+}
+
+/*-----------------------------------------------
+ 07.03.2004 07:59
+-----------------------------------------------*/
+void CacheUpdateListener::startListening()
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::util::XChangesNotifier > xNotifier(m_xConfig, css::uno::UNO_QUERY);
+ aLock.clear();
+ // <- SAFE
+
+ if (!xNotifier.is())
+ return;
+
+ css::uno::Reference< css::util::XChangesListener > xThis(static_cast< css::util::XChangesListener* >(this), css::uno::UNO_QUERY_THROW);
+ xNotifier->addChangesListener(xThis);
+
+/*
+ css::uno::Reference< css::container::XContainer > xNotifier(xConfigAccess, css::uno::UNO_QUERY);
+ if (!xNotifier.is())
+ return;
+
+ css::uno::Reference< css::container::XContainerListener > xThis(static_cast< css::container::XContainerListener* >(this), css::uno::UNO_QUERY);
+ xNotifier->addContainerListener(xThis);
+*/
+}
+
+/*-----------------------------------------------
+ 07.03.2004 07:59
+-----------------------------------------------*/
+void CacheUpdateListener::stopListening()
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::util::XChangesNotifier > xNotifier(m_xConfig, css::uno::UNO_QUERY);
+ aLock.clear();
+ // <- SAFE
+
+ if (!xNotifier.is())
+ return;
+
+ css::uno::Reference< css::util::XChangesListener > xThis(static_cast< css::util::XChangesListener* >(this), css::uno::UNO_QUERY);
+ xNotifier->removeChangesListener(xThis);
+
+/*
+ css::uno::Reference< css::container::XContainer > xNotifier(xConfigAccess, css::uno::UNO_QUERY);
+ if (!xNotifier.is())
+ return;
+
+ css::uno::Reference< css::container::XContainerListener > xThis(static_cast< css::container::XContainerListener* >(this), css::uno::UNO_QUERY);
+ xNotifier->removeContainerListener(xThis);
+*/
+}
+
+/*-----------------------------------------------
+ 07.03.2004 08:17
+-----------------------------------------------*/
+void SAL_CALL CacheUpdateListener::changesOccurred(const css::util::ChangesEvent& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // disposed ?
+ if ( ! m_xConfig.is())
+ return;
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ FilterCache::EItemType eType = m_eConfigType;
+
+ aLock.clear();
+ // <- SAFE
+
+ OUStringList lChangedItems;
+ sal_Int32 c = aEvent.Changes.getLength();
+ sal_Int32 i = 0;
+
+ for (i=0; i<c; ++i)
+ {
+ const css::util::ElementChange& aChange = aEvent.Changes[i];
+
+ ::rtl::OUString sOrgPath ;
+ ::rtl::OUString sTempPath;
+
+ ::rtl::OUString sProperty;
+ ::rtl::OUString sNode ;
+ ::rtl::OUString sLocale ;
+
+ /* at least we must be able to retrieve 2 path elements
+ But sometimes the original path can contain 3 of them ... in case
+ a localized value was changed.
+ =>
+ 1) Filters/Filter["filtername"]/Property
+ 2) Filters/Filter["filtername"]/LocalizedProperty/Locale
+ */
+
+ aChange.Accessor >>= sOrgPath;
+ if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sLocale))
+ continue;
+ sOrgPath = sTempPath;
+ if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sProperty))
+ {
+ sNode = sLocale;
+ sProperty = ::rtl::OUString();
+ sLocale = ::rtl::OUString();
+ }
+ else
+ {
+ sOrgPath = sTempPath;
+ if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sNode))
+ {
+ sNode = sProperty;
+ sProperty = sLocale;
+ sLocale = ::rtl::OUString();
+ }
+ }
+
+ if ( ! sNode.getLength() )
+ continue;
+
+ OUStringList::const_iterator pIt = ::std::find(lChangedItems.begin(), lChangedItems.end(), sNode);
+ if (pIt == lChangedItems.end())
+ lChangedItems.push_back(sNode);
+ }
+
+ sal_Bool bNotifyRefresh = sal_False;
+ OUStringList::const_iterator pIt;
+ for ( pIt = lChangedItems.begin();
+ pIt != lChangedItems.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sItem = *pIt;
+ try
+ {
+ m_rCache->refreshItem(eType, sItem);
+ }
+ catch(const css::container::NoSuchElementException&)
+ {
+ // can be ignored! Because we must be aware that
+ // sItem was removed from the condfiguration and we forced an update of the cache.
+ // But we know, that the cache is up-to-date know and has thrown this exception afterwards .-)
+ }
+ // NO FLUSH! Otherwhise we start a never ending story here .-)
+ bNotifyRefresh = sal_True;
+ }
+
+ // notify sfx cache about the changed filter cache .-)
+ if (bNotifyRefresh)
+ {
+ css::uno::Reference< css::util::XRefreshable > xRefreshBroadcaster(
+ xSMGR->createInstance(SERVICE_FILTERCONFIGREFRESH),
+ css::uno::UNO_QUERY);
+ if (xRefreshBroadcaster.is())
+ xRefreshBroadcaster->refresh();
+ }
+}
+
+/*-----------------------------------------------
+ 05.03.2004 08:44
+-----------------------------------------------*/
+void SAL_CALL CacheUpdateListener::disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ if (aEvent.Source == m_xConfig)
+ m_xConfig.clear();
+ aLock.clear();
+ // <- SAFE
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/cacheupdatelistener.hxx b/filter/source/config/cache/cacheupdatelistener.hxx
new file mode 100644
index 000000000000..8e75e4304bf2
--- /dev/null
+++ b/filter/source/config/cache/cacheupdatelistener.hxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef __FILTER_CONFIG_CACHEUPDATELISTENER_HXX_
+#define __FILTER_CONFIG_CACHEUPDATELISTENER_HXX_
+
+//_______________________________________________
+// includes
+
+#include "filtercache.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/util/XChangesListener.hpp>
+#include <salhelper/singletonref.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+//_______________________________________________
+// definitions
+
+//_______________________________________________
+
+/** @short implements a listener, which will update the
+ global filter cache, if the underlying configuration
+ wa changed by other processes.
+ */
+class CacheUpdateListener : public BaseLock // must be the first one to guarantee right initialized mutex member!
+ , public ::cppu::WeakImplHelper1< css::util::XChangesListener >
+{
+ //-------------------------------------------
+ // member
+
+ private:
+
+ /** @short reference to an uno service manager, which can be used
+ to create own needed services. */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ /** @short reference to the singleton(!) filter cache implementation,
+ which should be updated by this thread. */
+ ::salhelper::SingletonRef< FilterCache > m_rCache;
+
+ /** @short holds the configuration access, where we listen alive. */
+ css::uno::Reference< css::uno::XInterface > m_xConfig;
+
+ /** @short every instance of this update listener listen on
+ a special sub set of the filter configuration.
+ So it should know, which type of configuration entry
+ it must put into the filter cache, if the configuration notifys changes ... */
+ FilterCache::EItemType m_eConfigType;
+
+ //-------------------------------------------
+ // native interface
+
+ public:
+
+ //---------------------------------------
+ // ctor/dtor
+
+ /** @short initialize new instance of this class.
+
+ @descr Listening wont be started here. It can be done
+ by calling startListening() on this instance.
+
+ @see startListening()
+
+ @param xSMGR
+ reference to a service manager, which can be used to create
+ own needed uno services.
+
+ @param xConfigAccess
+ the configuration access, where this instance should listen for changes.
+
+ @param eConfigType
+ specify the type of configuration.
+ */
+ CacheUpdateListener(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::uno::XInterface >& xConfigAccess,
+ FilterCache::EItemType eConfigType );
+
+ //---------------------------------------
+
+ /** @short standard dtor.
+ */
+ virtual ~CacheUpdateListener();
+
+ //---------------------------------------
+
+ /** @short starts listening.
+ */
+ virtual void startListening();
+
+ //---------------------------------------
+
+ /** @short stop listening.
+ */
+ virtual void stopListening();
+
+ //-------------------------------------------
+ // uno interface
+
+ public:
+
+ //---------------------------------------
+ // XChangesListener
+
+ virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent)
+ throw(css::uno::RuntimeException);
+
+ //---------------------------------------
+ // lang.XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException);
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_CACHEUPDATELISTENER_HXX_
diff --git a/filter/source/config/cache/configflush.cxx b/filter/source/config/cache/configflush.cxx
new file mode 100644
index 000000000000..e97df2a7f40d
--- /dev/null
+++ b/filter/source/config/cache/configflush.cxx
@@ -0,0 +1,168 @@
+/*************************************************************************
+ *
+ * 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 "configflush.hxx"
+#include "constant.hxx"
+
+//_______________________________________________
+// includes
+#include <osl/diagnose.h>
+
+//_______________________________________________
+// namespace
+
+namespace css = ::com::sun::star;
+
+namespace filter{
+ namespace config{
+
+//_______________________________________________
+// definitions
+
+//-----------------------------------------------
+ConfigFlush::ConfigFlush(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : BaseLock ( )
+ , m_xSMGR (xSMGR )
+ , m_lListener(m_aLock)
+{
+}
+
+//-----------------------------------------------
+ConfigFlush::~ConfigFlush()
+{
+}
+
+//-----------------------------------------------
+::rtl::OUString SAL_CALL ConfigFlush::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return impl_getImplementationName();
+ // <- SAFE
+}
+
+//-----------------------------------------------
+sal_Bool SAL_CALL ConfigFlush::supportsService(const ::rtl::OUString& sServiceName)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< ::rtl::OUString > lServiceNames = impl_getSupportedServiceNames();
+ sal_Int32 c = lServiceNames.getLength();
+ const ::rtl::OUString* pNames = lServiceNames.getConstArray();
+ for (sal_Int32 i=0; i<c; ++i)
+ {
+ if (pNames[i].equals(sServiceName))
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//-----------------------------------------------
+css::uno::Sequence< ::rtl::OUString > SAL_CALL ConfigFlush::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return impl_getSupportedServiceNames();
+}
+
+//-----------------------------------------------
+void SAL_CALL ConfigFlush::refresh()
+ throw(css::uno::RuntimeException)
+{
+ // notify listener outside the lock!
+ // The used listener helper lives if we live
+ // and is threadsafe by itself.
+ // Further its not a good idea to hold the own lock
+ // if an outside object is called :-)
+ css::lang::EventObject aSource (static_cast< css::util::XRefreshable* >(this));
+ ::cppu::OInterfaceContainerHelper* pContainer = m_lListener.getContainer(::getCppuType(static_cast< css::uno::Reference< css::util::XRefreshListener >* >(NULL)));
+ if (pContainer)
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ // ... this pointer can be interesting to find out, where will be called as listener
+ // Dont optimize it to a direct iterator cast :-)
+ css::util::XRefreshListener* pListener = (css::util::XRefreshListener*)pIterator.next();
+ pListener->refreshed(aSource);
+ }
+ catch(const css::uno::Exception&)
+ {
+ // ignore any "damaged" flush listener!
+ // May its remote reference is broken ...
+ pIterator.remove();
+ }
+ }
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL ConfigFlush::addRefreshListener(const css::uno::Reference< css::util::XRefreshListener >& xListener)
+ throw(css::uno::RuntimeException)
+{
+ // no locks neccessary
+ // used helper lives if we live and is threadsafe by itself ...
+ m_lListener.addInterface(::getCppuType(static_cast< css::uno::Reference< css::util::XRefreshListener >* >(NULL)),
+ xListener);
+}
+
+//-----------------------------------------------
+void SAL_CALL ConfigFlush::removeRefreshListener(const css::uno::Reference< css::util::XRefreshListener >& xListener)
+ throw(css::uno::RuntimeException)
+{
+ // no locks neccessary
+ // used helper lives if we live and is threadsafe by itself ...
+ m_lListener.removeInterface(::getCppuType(static_cast< css::uno::Reference< css::util::XRefreshListener >* >(NULL)),
+ xListener);
+}
+
+//-----------------------------------------------
+::rtl::OUString ConfigFlush::impl_getImplementationName()
+{
+ static ::rtl::OUString IMPLNAME = ::rtl::OUString::createFromAscii("com.sun.star.comp.filter.config.ConfigFlush");
+ return IMPLNAME;
+}
+
+//-----------------------------------------------
+css::uno::Sequence< ::rtl::OUString > ConfigFlush::impl_getSupportedServiceNames()
+{
+ css::uno::Sequence< ::rtl::OUString > lServiceNames(1);
+ lServiceNames[0] = SERVICE_FILTERCONFIGREFRESH;
+ return lServiceNames;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::uno::XInterface > ConfigFlush::impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ ConfigFlush* pNew = new ConfigFlush(xSMGR);
+ return css::uno::Reference< css::uno::XInterface >(static_cast< css::util::XRefreshable* >(pNew), css::uno::UNO_QUERY);
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/configflush.hxx b/filter/source/config/cache/configflush.hxx
new file mode 100644
index 000000000000..477d7017ca35
--- /dev/null
+++ b/filter/source/config/cache/configflush.hxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef __FILTER_CONFIG_CONFIGFLUSH_HXX_
+#define __FILTER_CONFIG_CONFIGFLUSH_HXX_
+
+//_______________________________________________
+// includes
+
+#include "cacheitem.hxx"
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/interfacecontainer.h>
+#include <cppuhelper/implbase1.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+//_______________________________________________
+// definitions
+
+//_______________________________________________
+
+/** @short supports registration of XRefreshListener
+ on the global filter configuration.
+
+ @descr Such refresh listener will be called in case the
+ type/filter configuration will be changed at runtime.
+ */
+class ConfigFlush : public BaseLock
+ , public ::cppu::WeakImplHelper1< css::util::XRefreshable >
+{
+ //-------------------------------------------
+ // member
+
+ protected:
+
+ /** @short reference to an uno service manager, which can be used
+ to create own needed services. */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ /** @short holds all listener, which are registered at this instance. */
+ ::cppu::OMultiTypeInterfaceContainerHelper m_lListener;
+
+ //-------------------------------------------
+ // native interface
+
+ public:
+
+ //---------------------------------------
+ // ctor/dtor
+
+ /** @short standard ctor.
+ */
+ ConfigFlush(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+
+ //---------------------------------------
+
+ /** @short standard dtor.
+ */
+ virtual ~ConfigFlush();
+
+ //-------------------------------------------
+ // uno interface
+
+ public:
+
+ //---------------------------------------
+ // XServiceInfo
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService(const ::rtl::OUString& sServiceName)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (css::uno::RuntimeException);
+
+ //---------------------------------------
+ // XRefreshable
+
+ virtual void SAL_CALL refresh()
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL addRefreshListener(const css::uno::Reference< css::util::XRefreshListener >& xListener)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeRefreshListener(const css::uno::Reference< css::util::XRefreshListener >& xListener)
+ throw(css::uno::RuntimeException);
+
+ //---------------------------------------
+ // interface to register/create this instance as an UNO service
+ static ::rtl::OUString impl_getImplementationName();
+ static css::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames();
+ static css::uno::Reference< css::uno::XInterface > impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_CONFIGFLUSH_HXX_
diff --git a/filter/source/config/cache/constant.hxx b/filter/source/config/cache/constant.hxx
new file mode 100644
index 000000000000..244a78864228
--- /dev/null
+++ b/filter/source/config/cache/constant.hxx
@@ -0,0 +1,217 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _FILTER_CONFIG_CONSTANT_HXX_
+#define _FILTER_CONFIG_CONSTANT_HXX_
+
+#include "macros.hxx"
+
+namespace filter { namespace config {
+extern rtl::OUString pFilterStrings[];
+} }
+#ifndef PROPNAME_IMPL_DECL
+# define PROPNAME_DECL(index, str) (pFilterStrings[(index)])
+#else
+# define PROPNAME_DECL(index, str) pFilterStrings[(index)] = _FILTER_CONFIG_FROM_ASCII_(str)
+#endif
+
+/* disable impl_loadOnDemand function of BaseContainer for certain
+ functions, where it the feature "impl_loadItemOnDemand() of class FilterCache
+ can be used instead of loadAll()!*/
+// #define LOAD_IMPLICIT
+
+//_______________________________________________
+
+/** @short used to identify a some generic item properties against the
+ configuration API and can be used at all name containers
+ (based on this filtercache) too.
+ */
+#define PROPNAME_NAME PROPNAME_DECL(0, "Name")
+
+/** @short used to identify a type item property against the
+ configuration API and can be used at all name containers
+ (based on this filtercache) too.
+ */
+#define PROPNAME_UINAME PROPNAME_DECL(1, "UIName" )
+#define PROPNAME_UINAMES PROPNAME_DECL(2, "UINames" )
+#define PROPNAME_PREFERRED PROPNAME_DECL(3, "Preferred" )
+#define PROPNAME_PREFERREDFILTER PROPNAME_DECL(4, "PreferredFilter" )
+#define PROPNAME_DETECTSERVICE PROPNAME_DECL(5, "DetectService" )
+#define PROPNAME_MEDIATYPE PROPNAME_DECL(6, "MediaType" )
+#define PROPNAME_CLIPBOARDFORMAT PROPNAME_DECL(7, "ClipboardFormat" )
+#define PROPNAME_URLPATTERN PROPNAME_DECL(8, "URLPattern" )
+#define PROPNAME_EXTENSIONS PROPNAME_DECL(9, "Extensions" )
+
+/** @short used to identify a filter item property against the
+ configuration API and can be used at all name containers
+ (based on this filtercache) too.
+ */
+#define PROPNAME_TYPE PROPNAME_DECL(10, "Type" )
+#define PROPNAME_DOCUMENTSERVICE PROPNAME_DECL(11, "DocumentService" )
+#define PROPNAME_FILTERSERVICE PROPNAME_DECL(12, "FilterService" )
+#define PROPNAME_UICOMPONENT PROPNAME_DECL(13, "UIComponent" )
+#define PROPNAME_FLAGS PROPNAME_DECL(14, "Flags" )
+#define PROPNAME_USERDATA PROPNAME_DECL(15, "UserData" )
+#define PROPNAME_TEMPLATENAME PROPNAME_DECL(16, "TemplateName" )
+#define PROPNAME_FILEFORMATVERSION PROPNAME_DECL(17, "FileFormatVersion")
+
+/** @short used to identify a frame loader or detect service item
+ property against the configuration API and can be used
+ at all name containers (based on this filtercache) too.
+ */
+#define PROPNAME_TYPES PROPNAME_DECL(18, "Types")
+
+/** @short used to identify the list of sorted filters for a specific
+ office module
+ */
+#define PROPNAME_SORTEDFILTERLIST _FILTER_CONFIG_FROM_ASCII_("SortedFilterList")
+
+/** @short implicit properties. which are used at the container interface only.
+ */
+#define PROPNAME_FINALIZED _FILTER_CONFIG_FROM_ASCII_("Finalized")
+#define PROPNAME_MANDATORY _FILTER_CONFIG_FROM_ASCII_("Mandatory")
+
+/** @short used to identify a set of items against the configuration API. */
+#define CFGSET_TYPES _FILTER_CONFIG_FROM_ASCII_("Types" )
+#define CFGSET_FILTERS _FILTER_CONFIG_FROM_ASCII_("Filters" )
+#define CFGSET_FRAMELOADERS _FILTER_CONFIG_FROM_ASCII_("FrameLoaders" )
+#define CFGSET_CONTENTHANDLERS _FILTER_CONFIG_FROM_ASCII_("ContentHandlers")
+
+/** @short used to adress some configuration keys directly.
+
+ @descr Such direct keys should be used with function
+ FilterCache::impl_getDirectCFGValue() only!
+
+ @TODO define these direct keys ...
+ */
+#define CFGDIRECTKEY_OFFICELOCALE _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.Setup/L10N/ooLocale" )
+#define CFGDIRECTKEY_DEFAULTFRAMELOADER _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.TypeDetection.Misc/Defaults/DefaultFrameLoader")
+#define CFGDIRECTKEY_OFFICELOCALE _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.Setup/L10N/ooLocale" )
+#define CFGDIRECTKEY_FORMATNAME _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.Setup/Product/ooXMLFileFormatName" )
+#define CFGDIRECTKEY_FORMATVERSION _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.Setup/Product/ooXMLFileFormatVersion" )
+#define CFGDIRECTKEY_PRODUCTNAME _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.Setup/Product/ooName" )
+
+/** @short names of filter flags, sorted in alphabetical order */
+#define FLAGNAME_3RDPARTYFILTER _FILTER_CONFIG_FROM_ASCII_("3RDPARTYFILTER" )
+#define FLAGNAME_ALIEN _FILTER_CONFIG_FROM_ASCII_("ALIEN" )
+#define FLAGNAME_ASYNCHRON _FILTER_CONFIG_FROM_ASCII_("ASYNCHRON" )
+#define FLAGNAME_BROWSERPREFERRED _FILTER_CONFIG_FROM_ASCII_("BROWSERPREFERRED" )
+#define FLAGNAME_CONSULTSERVICE _FILTER_CONFIG_FROM_ASCII_("CONSULTSERVICE" )
+#define FLAGNAME_DEFAULT _FILTER_CONFIG_FROM_ASCII_("DEFAULT" )
+#define FLAGNAME_ENCRYPTION _FILTER_CONFIG_FROM_ASCII_("ENCRYPTION" )
+#define FLAGNAME_EXPORT _FILTER_CONFIG_FROM_ASCII_("EXPORT" )
+#define FLAGNAME_IMPORT _FILTER_CONFIG_FROM_ASCII_("IMPORT" )
+#define FLAGNAME_INTERNAL _FILTER_CONFIG_FROM_ASCII_("INTERNAL" )
+#define FLAGNAME_NOTINCHOOSER _FILTER_CONFIG_FROM_ASCII_("NOTINCHOOSER" )
+#define FLAGNAME_NOTINFILEDIALOG _FILTER_CONFIG_FROM_ASCII_("NOTINFILEDIALOG" )
+#define FLAGNAME_NOTINSTALLED _FILTER_CONFIG_FROM_ASCII_("NOTINSTALLED" )
+#define FLAGNAME_OWN _FILTER_CONFIG_FROM_ASCII_("OWN" )
+#define FLAGNAME_PACKED _FILTER_CONFIG_FROM_ASCII_("PACKED" )
+#define FLAGNAME_PASSWORDTOMODIFY _FILTER_CONFIG_FROM_ASCII_("PASSWORDTOMODIFY" )
+#define FLAGNAME_PREFERRED _FILTER_CONFIG_FROM_ASCII_("PREFERRED" )
+#define FLAGNAME_READONLY _FILTER_CONFIG_FROM_ASCII_("READONLY" )
+#define FLAGNAME_SILENTEXPORT _FILTER_CONFIG_FROM_ASCII_("SILENTEXPORT" )
+#define FLAGNAME_SUPPORTSSELECTION _FILTER_CONFIG_FROM_ASCII_("SUPPORTSSELECTION")
+#define FLAGNAME_TEMPLATE _FILTER_CONFIG_FROM_ASCII_("TEMPLATE" )
+#define FLAGNAME_TEMPLATEPATH _FILTER_CONFIG_FROM_ASCII_("TEMPLATEPATH" )
+#define FLAGNAME_USESOPTIONS _FILTER_CONFIG_FROM_ASCII_("USESOPTIONS" )
+#define FLAGNAME_COMBINED _FILTER_CONFIG_FROM_ASCII_("COMBINED" )
+
+/** @short values of filter flags, sorted based on value */
+#define FLAGVAL_IMPORT 0x00000001 // 1
+#define FLAGVAL_EXPORT 0x00000002 // 2
+#define FLAGVAL_TEMPLATE 0x00000004 // 4
+#define FLAGVAL_INTERNAL 0x00000008 // 8
+#define FLAGVAL_TEMPLATEPATH 0x00000010 // 16
+#define FLAGVAL_OWN 0x00000020 // 32
+#define FLAGVAL_ALIEN 0x00000040 // 64
+#define FLAGVAL_USESOPTIONS 0x00000080 // 128
+#define FLAGVAL_DEFAULT 0x00000100 // 256
+#define FLAGVAL_SUPPORTSSELECTION 0x00000400 // 1024
+#define FLAGVAL_NOTINFILEDIALOG 0x00001000 // 4096
+#define FLAGVAL_NOTINCHOOSER 0x00002000 // 8192
+#define FLAGVAL_ASYNCHRON 0x00004000 // 16384
+#define FLAGVAL_READONLY 0x00010000 // 65536
+#define FLAGVAL_NOTINSTALLED 0x00020000 // 131072
+#define FLAGVAL_CONSULTSERVICE 0x00040000 // 262144
+#define FLAGVAL_3RDPARTYFILTER 0x00080000 // 524288
+#define FLAGVAL_PACKED 0x00100000 // 1048576
+#define FLAGVAL_SILENTEXPORT 0x00200000 // 2097152
+#define FLAGVAL_BROWSERPREFERRED 0x00400000 // 4194304
+#define FLAGVAL_COMBINED 0x00800000 // 8388608
+#define FLAGVAL_ENCRYPTION 0x01000000 // 16777216
+#define FLAGVAL_PASSWORDTOMODIFY 0x02000000 // 33554432
+#define FLAGVAL_PREFERRED 0x10000000 // 268435456
+#define FLAGVAL_ALL 0xffffffff // 4294967295
+
+/** @short uno service names of our document services
+ provided by our application modules.
+ */
+#define DOCUMENTSERVICE_WRITER _FILTER_CONFIG_FROM_ASCII_("com.sun.star.text.TextDocument" )
+#define DOCUMENTSERVICE_WRITER_WEB _FILTER_CONFIG_FROM_ASCII_("com.sun.star.text.WebDocument" )
+#define DOCUMENTSERVICE_WRITER_GLOBAL _FILTER_CONFIG_FROM_ASCII_("com.sun.star.text.GlobalDocument" )
+#define DOCUMENTSERVICE_CALC _FILTER_CONFIG_FROM_ASCII_("com.sun.star.sheet.SpreadsheetDocument" )
+#define DOCUMENTSERVICE_DRAW _FILTER_CONFIG_FROM_ASCII_("com.sun.star.drawing.DrawingDocument" )
+#define DOCUMENTSERVICE_IMPRESS _FILTER_CONFIG_FROM_ASCII_("com.sun.star.presentation.PresentationDocument")
+#define DOCUMENTSERVICE_CHART _FILTER_CONFIG_FROM_ASCII_("com.sun.star.chart2.ChartDocument" )
+#define DOCUMENTSERVICE_MATH _FILTER_CONFIG_FROM_ASCII_("com.sun.star.formula.FormulaProperties" )
+
+/** @short some uno service names.
+ */
+#define SERVICE_CONFIGURATIONPROVIDER _FILTER_CONFIG_FROM_ASCII_("com.sun.star.configuration.ConfigurationProvider" )
+#define SERVICE_CONFIGURATIONUPDATEACCESS _FILTER_CONFIG_FROM_ASCII_("com.sun.star.configuration.ConfigurationUpdateAccess" )
+#define SERVICE_CONFIGURATIONACCESS _FILTER_CONFIG_FROM_ASCII_("com.sun.star.configuration.ConfigurationAccess" )
+#define SERVICE_URLTRANSFORMER _FILTER_CONFIG_FROM_ASCII_("com.sun.star.util.URLTransformer" )
+#define SERVICE_FILTERCONFIGREFRESH _FILTER_CONFIG_FROM_ASCII_("com.sun.star.document.FilterConfigRefresh" )
+
+/** @short some configuration pathes.
+ */
+#define CFGPACKAGE_TD_TYPES _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.TypeDetection.Types" )
+#define CFGPACKAGE_TD_FILTERS _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.TypeDetection.Filter")
+#define CFGPACKAGE_TD_OTHERS _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.TypeDetection.Misc" )
+#define CFGPACKAGE_TD_UISORT _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.TypeDetection.UISort/ModuleDependendFilterOrder")
+#define CFGPACKAGE_TD_OLD _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.Office.TypeDetection")
+#define CFGPACKAGE_OOO_MODULES _FILTER_CONFIG_FROM_ASCII_("/org.openoffice.Setup/Office/Factories")
+
+/** @short some default values.
+ */
+#define DEFAULT_OFFICELOCALE _FILTER_CONFIG_FROM_ASCII_("en-US")
+#define DEFAULT_FORMATNAME _FILTER_CONFIG_FROM_ASCII_("OpenOffice")
+#define DEFAULT_FORMATVERSION _FILTER_CONFIG_FROM_ASCII_("1.0")
+
+/** @short used for the queries of the FilterFactory service.
+ */
+#define QUERY_IDENTIFIER_MATCHBYDOCUMENTSERVICE _FILTER_CONFIG_FROM_ASCII_("matchByDocumentService" )
+#define QUERY_IDENTIFIER_GETPREFERREDFILTERFORTYPE _FILTER_CONFIG_FROM_ASCII_("getDefaultFilterForType")
+#define QUERY_IDENTIFIER_GET_SORTED_FILTERLIST _FILTER_CONFIG_FROM_ASCII_("getSortedFilterList()" )
+
+#define QUERY_PARAM_IFLAGS _FILTER_CONFIG_FROM_ASCII_("iflags")
+#define QUERY_PARAM_EFLAGS _FILTER_CONFIG_FROM_ASCII_("eflags")
+#define QUERY_PARAM_MODULE _FILTER_CONFIG_FROM_ASCII_("module")
+#define QUERY_PARAM_DEFAULTFIRST _FILTER_CONFIG_FROM_ASCII_("default_first")
+#define QUERY_CONSTVALUE_ALL _FILTER_CONFIG_FROM_ASCII_("all")
+
+#endif // _FILTER_CONFIG_CONSTANT_HXX_
diff --git a/filter/source/config/cache/contenthandlerfactory.cxx b/filter/source/config/cache/contenthandlerfactory.cxx
new file mode 100644
index 000000000000..3863658d9abb
--- /dev/null
+++ b/filter/source/config/cache/contenthandlerfactory.cxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * 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 "contenthandlerfactory.hxx"
+#include "querytokenizer.hxx"
+#include "macros.hxx"
+#include "constant.hxx"
+#include "versions.hxx"
+
+//_______________________________________________
+// includes
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <comphelper/enumhelper.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+ContentHandlerFactory::ContentHandlerFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ BaseContainer::init(xSMGR ,
+ ContentHandlerFactory::impl_getImplementationName() ,
+ ContentHandlerFactory::impl_getSupportedServiceNames(),
+ FilterCache::E_CONTENTHANDLER );
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+ContentHandlerFactory::~ContentHandlerFactory()
+{
+}
+
+/*-----------------------------------------------
+ 16.07.2003 13:38
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > SAL_CALL ContentHandlerFactory::createInstance(const ::rtl::OUString& sHandler)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ return createInstanceWithArguments(sHandler, css::uno::Sequence< css::uno::Any >());
+}
+
+/*-----------------------------------------------
+ 16.07.2003 13:40
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > SAL_CALL ContentHandlerFactory::createInstanceWithArguments(const ::rtl::OUString& sHandler ,
+ const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ css::uno::Reference< css::uno::XInterface > xHandler;
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ ::rtl::OUString sRealHandler = sHandler;
+
+ #ifdef _FILTER_CONFIG_MIGRATION_Q_
+
+ /* -> TODO - HACK
+ check if the given handler name realy exist ...
+ Because our old implementation worked with an internal
+ type name instead of a handler name. For a small migration time
+ we must simulate this old feature :-( */
+
+ if (!m_rCache->hasItem(FilterCache::E_CONTENTHANDLER, sHandler) && m_rCache->hasItem(FilterCache::E_TYPE, sHandler))
+ {
+ _FILTER_CONFIG_LOG_("ContentHandlerFactory::createInstanceWithArguments() ... simulate old type search functionality!\n");
+
+ css::uno::Sequence< ::rtl::OUString > lTypes(1);
+ lTypes[0] = sHandler;
+
+ css::uno::Sequence< css::beans::NamedValue > lQuery(1);
+ lQuery[0].Name = PROPNAME_TYPES;
+ lQuery[0].Value <<= lTypes;
+
+ css::uno::Reference< css::container::XEnumeration > xSet = createSubSetEnumerationByProperties(lQuery);
+ while(xSet->hasMoreElements())
+ {
+ ::comphelper::SequenceAsHashMap lHandlerProps(xSet->nextElement());
+ if (!(lHandlerProps[PROPNAME_NAME] >>= sRealHandler))
+ continue;
+ }
+
+ // prevent outside code against NoSuchElementException!
+ // But dont implement such defensive strategy for our new create handling :-)
+ if (!m_rCache->hasItem(FilterCache::E_CONTENTHANDLER, sRealHandler))
+ return css::uno::Reference< css::uno::XInterface>();
+ }
+
+ /* <- HACK */
+
+ #endif // _FILTER_CONFIG_MIGRATION_Q_
+
+ // search handler on cache
+ CacheItem aHandler = m_rCache->getItem(FilterCache::E_CONTENTHANDLER, sRealHandler);
+
+ // create service instance
+ xHandler = m_xSMGR->createInstance(sRealHandler);
+
+ // initialize filter
+ css::uno::Reference< css::lang::XInitialization > xInit(xHandler, css::uno::UNO_QUERY);
+ if (xInit.is())
+ {
+ // format: lInitData[0] = seq<PropertyValue>, which contains all configuration properties of this handler
+ // lInitData[1] = lArguments[0]
+ // ...
+ // lInitData[n] = lArguments[n-1]
+ css::uno::Sequence< css::beans::PropertyValue > lConfig;
+ aHandler >> lConfig;
+
+ ::comphelper::SequenceAsVector< css::uno::Any > stlArguments(lArguments);
+ stlArguments.insert(stlArguments.begin(), css::uno::makeAny(lConfig));
+
+ css::uno::Sequence< css::uno::Any > lInitData;
+ stlArguments >> lInitData;
+
+ xInit->initialize(lInitData);
+ }
+
+ return xHandler;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:46
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > SAL_CALL ContentHandlerFactory::getAvailableServiceNames()
+ throw(css::uno::RuntimeException)
+{
+ // must be the same list as ((XNameAccess*)this)->getElementNames() return!
+ return getElementNames();
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+::rtl::OUString ContentHandlerFactory::impl_getImplementationName()
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.filter.config.ContentHandlerFactory");
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > ContentHandlerFactory::impl_getSupportedServiceNames()
+{
+ css::uno::Sequence< ::rtl::OUString > lServiceNames(1);
+ lServiceNames[0] = ::rtl::OUString::createFromAscii("com.sun.star.frame.ContentHandlerFactory");
+ return lServiceNames;
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > SAL_CALL ContentHandlerFactory::impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ ContentHandlerFactory* pNew = new ContentHandlerFactory(xSMGR);
+ return css::uno::Reference< css::uno::XInterface >(static_cast< css::lang::XMultiServiceFactory* >(pNew), css::uno::UNO_QUERY);
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/contenthandlerfactory.hxx b/filter/source/config/cache/contenthandlerfactory.hxx
new file mode 100644
index 000000000000..a50f91c0b61e
--- /dev/null
+++ b/filter/source/config/cache/contenthandlerfactory.hxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __FILTER_CONFIG_CONTENTHANDLERFACTORY_HXX_
+#define __FILTER_CONFIG_CONTENTHANDLERFACTORY_HXX_
+
+//_______________________________________________
+// includes
+
+#include "basecontainer.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+//_______________________________________________
+
+/** @short implements the service <type scope="com.sun.star.document">ContentHandlerFactory</type>.
+ */
+class ContentHandlerFactory : public ::cppu::ImplInheritanceHelper1< BaseContainer ,
+ css::lang::XMultiServiceFactory >
+{
+ //-------------------------------------------
+ // native interface
+
+ public:
+
+ //---------------------------------------
+ // ctor/dtor
+
+ /** @short standard ctor to connect this interface wrapper to
+ the global filter cache instance ...
+
+ @param xSMGR
+ reference to the uno service manager, which created this service instance.
+ */
+ ContentHandlerFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+
+ //---------------------------------------
+
+ /** @short standard dtor.
+ */
+ virtual ~ContentHandlerFactory();
+
+ //-------------------------------------------
+ // uno interface
+
+ public:
+
+ //---------------------------------------
+ // XMultiServiceFactory
+
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(const ::rtl::OUString& sHandler)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArguments(const ::rtl::OUString& sHandler ,
+ const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableServiceNames()
+ throw(css::uno::RuntimeException);
+
+ //-------------------------------------------
+ // static uno helper!
+
+ public:
+
+ //---------------------------------------
+
+ /** @short return the uno implementation name of this class.
+
+ @descr Because this information is used at several places
+ (and mostly an object instance of this class is not possible)
+ its implemented as a static function!
+
+ @return The fix uno implementation name of this class.
+ */
+ static ::rtl::OUString impl_getImplementationName();
+
+ //---------------------------------------
+
+ /** @short return the list of supported uno services of this class.
+
+ @descr Because this information is used at several places
+ (and mostly an object instance of this class is not possible)
+ its implemented as a static function!
+
+ @return The fix list of uno services supported by this class.
+ */
+ static css::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames();
+
+ //---------------------------------------
+
+ /** @short return a new intsnace of this class.
+
+ @descr This method is used by the uno service manager, to create
+ a new instance of this service if needed.
+
+ @param xSMGR
+ reference to the uno service manager, which require
+ this new instance. It should be passed to the new object
+ so it can be used internaly to create own needed uno resources.
+
+ @return The new instance of this service as an uno reference.
+ */
+ static css::uno::Reference< css::uno::XInterface > impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_CONTENTHANDLERFACTORY_HXX_
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
diff --git a/filter/source/config/cache/filtercache.hxx b/filter/source/config/cache/filtercache.hxx
new file mode 100644
index 000000000000..0c0e34b2783b
--- /dev/null
+++ b/filter/source/config/cache/filtercache.hxx
@@ -0,0 +1,1066 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __FILTER_CONFIG_FILTERCACHE_HXX_
+#define __FILTER_CONFIG_FILTERCACHE_HXX_
+
+//_______________________________________________
+// includes
+
+#include "cacheitem.hxx"
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/util/ChangesEvent.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Any.h>
+#include <rtl/ustring.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+//_______________________________________________
+// definitions
+
+//_______________________________________________
+
+/** @short implements a cache, which contains all
+ elements of our filter and type detection
+ configuration.
+
+ @descr The cache itself is threadsafe implemented.
+ Because it should be used as a singleton only.
+ To do so please use reference mechanism as wrapper
+ around this FilterCache class.
+
+ @attention Because we use a trick to get a full initialized
+ mutex lock during initialization time (means during
+ the constructor runs), the base class FilterCacheLock
+ must be the first of all declared one!
+ Further we make it public. So any user of this class
+ can lock us from outside too.
+ */
+class FilterCache : public BaseLock
+{
+ //-------------------------------------------
+ // public types
+
+ public:
+
+ //---------------------------------------
+
+ /** @short identify the type of a container item.
+
+ @descr Because the cache interface is a generic one
+ every group of container items must be specified.
+ */
+ enum EItemType
+ {
+ E_TYPE ,
+ E_FILTER ,
+ E_FRAMELOADER ,
+ E_CONTENTHANDLER,
+ E_DETECTSERVICE
+ };
+
+ //---------------------------------------
+
+ /** @short indicates, which items already exists inside this cache
+ and which not.
+
+ @descr This cache supports a 2-step load mechanism.
+ First only types (and only some special properties of every type!)
+ but no filters/frame loaders/content handlers will be readed.
+ That should be enough to work with this cache e.g. for loading
+ the first document. After this first document was loaded successfully,
+ a special "load-on-demand-thread" will be started to fill this cache
+ with ALL other informations, which was not readed before.
+ Thats the second step. All operations on top of this cache will be
+ blocked then.
+ */
+ enum EFillState
+ {
+ E_CONTAINS_NOTHING = 0,
+ E_CONTAINS_STANDARD = 1,
+ E_CONTAINS_TYPES = 2,
+ E_CONTAINS_FILTERS = 4,
+ E_CONTAINS_DETECTSERVICES = 8,
+ E_CONTAINS_FRAMELOADERS = 16,
+ E_CONTAINS_CONTENTHANDLERS = 32,
+ E_CONTAINS_ALL = 63 // must be a combination of all excepting E_CONTAINS_NOTHING! Please update if items will be added or removed ...
+ };
+
+ //-------------------------------------------
+ // private types
+
+ private:
+
+ //---------------------------------------
+ /** @short regulate, which properties of a configured item
+ will be readed.
+
+ @descr To perform reading of all configuration items,
+ only standard properties will be handled. At a second
+ step all optional properties will be read and added to
+ our internal structures. Of course the combination of
+ both options can be used too, to get all properties
+ at the same time.
+ */
+ enum EReadOption
+ {
+ E_READ_NOTHING = 0,
+ E_READ_STANDARD = 1,
+ E_READ_UPDATE = 2,
+ E_READ_ALL = 3
+ };
+
+ //---------------------------------------
+ /** @short indicates the state of a configuration set item.
+
+ @descr Inside method flush we check:
+ <ul>
+ <li>if the item exists inside config layer but not inside our cache => REMOVED</li>
+ <li>if the item exists inside config layer and inside our cache => CHANGED</li>
+ <li>if the item does not exists inside config layer but inside our cache => ADDED.</li>
+ </ul>
+ */
+ enum EItemFlushState
+ {
+ /// indicates an unchanged item (can occure e.g. if an item was added and(!) removed before it was flushed ...
+ E_ITEM_UNCHANGED = 0,
+ /// indicates an item, which exists inside config layer but not inside our own cache
+ E_ITEM_REMOVED = 1,
+ /// indicates an item, which exists inside config layer and inside our own cache
+ E_ITEM_CHANGED = 2,
+ /// indicates an item, which does not exists inside config layer but inside our own cache
+ E_ITEM_ADDED = 3
+ };
+
+ //---------------------------------------
+ /** TODO document me */
+ enum EConfigProvider
+ {
+ E_PROVIDER_TYPES = 0,
+ E_PROVIDER_FILTERS = 1,
+ E_PROVIDER_OTHERS = 2,
+ E_PROVIDER_OLD = 3
+ };
+
+ //-------------------------------------------
+ // member
+
+ private:
+
+ //---------------------------------------
+ /** @short reference to an uno service manager, which can be used
+ to create own needed services. */
+ mutable css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ //---------------------------------------
+ /** @short holds the used configuration provider alive, which
+ provides access to the list of types. */
+ mutable css::uno::Reference< css::uno::XInterface > m_xConfigTypes;
+
+ //---------------------------------------
+ /** @short holds the used configuration provider alive, which
+ provides access to the list of filters. */
+ mutable css::uno::Reference< css::uno::XInterface > m_xConfigFilters;
+
+ //---------------------------------------
+ /** @short holds the used configuration provider alive, which
+ provides access to the list of other values needed
+ by our type detection framework. */
+ mutable css::uno::Reference< css::uno::XInterface > m_xConfigOthers;
+
+ //---------------------------------------
+ /** @short contains all loaded types with its properties. */
+ mutable CacheItemList m_lTypes;
+
+ //---------------------------------------
+ /** @short contains all well known detect service with its properties. */
+ mutable CacheItemList m_lDetectServices;
+
+ //---------------------------------------
+ /** @short contains all loaded filters with its properties. */
+ mutable CacheItemList m_lFilters;
+
+ //---------------------------------------
+ /** @short contains all loaded frame loader with its properties. */
+ mutable CacheItemList m_lFrameLoaders;
+
+ //---------------------------------------
+ /** @short contains all loaded content handler with its properties. */
+ mutable CacheItemList m_lContentHandlers;
+
+ //---------------------------------------
+ /** @short optimize mapping of URL extensions to a type representation,
+ by using extensions as key and a list of internal
+ type names as value. */
+ mutable CacheItemRegistration m_lExtensions2Types;
+
+ //---------------------------------------
+ /** @short optimize mapping of URL pattern to a type representation,
+ by using patterns as key and a list of internal
+ type names as value. */
+ mutable CacheItemRegistration m_lURLPattern2Types;
+
+ //---------------------------------------
+ /** @short contains the current locale of the office and will be
+ used to work with localized configuration values. */
+ ::rtl::OUString m_sActLocale;
+
+ //---------------------------------------
+ /** TODO */
+ ::rtl::OUString m_sFormatName;
+
+ //---------------------------------------
+ /** TODO */
+ ::rtl::OUString m_sFormatVersion;
+
+ //---------------------------------------
+ /** @short contains status, which cache items/properties
+ was already loaded from the underlying configuration.
+
+ @descr This information can be used to detect missing
+ informations and load it on demand.
+
+ @see EFillState
+ @see load()
+ */
+ EFillState m_eFillState;
+
+ //---------------------------------------
+ /** TODO document me ... */
+ OUStringList m_lChangedTypes;
+ OUStringList m_lChangedFilters;
+ OUStringList m_lChangedDetectServices;
+ OUStringList m_lChangedFrameLoaders;
+ OUStringList m_lChangedContentHandlers;
+
+ //---------------------------------------
+ /// readonly acccess to the module configuration of OOo
+ css::uno::Reference< css::container::XNameAccess > m_xModuleCfg;
+
+ //-------------------------------------------
+ // interface
+
+ public:
+
+ //---------------------------------------
+ // ctor/dtor
+
+ /** @short standard ctor
+
+ @descr Its not allowed to do anything here ...
+ especialy is forbidden to start operations,
+ which needs a FilterCache instance too!
+ Why? Because thie FilterCache instance will be
+ used as a singleton! And if during this ctor any
+ action related to this FilterCache singleton is
+ started ... a race will be the result.
+
+ The first method after construction of a new
+ singleton reference should be "load()". There
+ a special fill state of this cache can be forced.
+ */
+ FilterCache();
+
+ //---------------------------------------
+
+ /** @short standard dtor.
+ */
+ virtual ~FilterCache();
+
+ //---------------------------------------
+
+ /** @short creates a copy of this container.
+
+ @descr Such copy can be used then to modify items (add/change/remove)
+ without the risk to damage the original container.
+ After its changed data was flushed to the configuration it can be
+ removed.
+
+ The original container will get these new data automaticly
+ because it listen for changes on the internal used configuration layer.
+ If the new data are needed immediatly inside the original container,
+ the method takeOver() can be used to copy all changes back.
+ The may be following notifications of the configuration will be superflous then.
+ But they cant be stopped ...
+
+ All internal structures will be copied here. But the internal used
+ configuration (update) access wont be copied. The cloned instance contains
+ a different one.
+
+ @note The cloned instance is created on the heap. The user of this instance
+ has to remove it later.
+ */
+ virtual FilterCache* clone() const;
+
+ //---------------------------------------
+
+ /** @short copy the cache content or rClone back to this instance.
+ */
+ virtual void takeOver(const FilterCache& rClone);
+
+ //---------------------------------------
+
+ /** @short force special fill state of this cache.
+
+ @descr This method check if all requested items/properties already
+ exists. Only missing informations will be readed.
+ Otherwhise this method does nothing!
+
+ This method must be called from every user of this cache
+ everytimes it need a filled cache. Normaly we load
+ only standard informations into this cache on startup.
+ After a few seconds we start a special thread, which
+ may fill this cache completely. But if somehwere outside
+ need a filled cache before ... it can run into trouble,
+ if this "load-on-demand" thread does not finished its work before.
+ This method "load(xxx)" synchronize such load-on-demand requests.
+
+ Of course it would be possible to supress this special load thread
+ in general and start it manualy inside this load() request.
+ The outside code decide then, if and when this cache will be filled
+ with all available informations ...
+
+ @param bByThread
+ indicates using of this method by our global "load-on-demand-thread".
+ Its an implementation detail! We use it to check, if this "load()"
+ request was forced e.g. by one of our derived service container (which need
+ it to full fill its own operations) or if it was forced by our own
+ "load-on-demand-thread", which tries to optimize our startup performance
+ and start this load() only in case the office startup was already finished!
+
+ @throw An exception if the cache could not be filled realy
+ or seems to be invalid afterwards. But there is no reaction
+ at all if this method does nothing inside, because the cache
+ is already full filled!
+ */
+ virtual void load(EFillState eRequired ,
+ sal_Bool bByThread = sal_False)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short return the current fill state of this cache.
+
+ @descr This information can be used e.g. to start
+ a search on top of this cache with a minimum on
+ informations ... and do it again, if some other
+ cache items seems to be available after calling of "loadAll()"
+ on this cache and first search does not had any valid results.
+
+ @return TRUE if the required fill state exists for this cache; FALSE
+ otherwise.
+ */
+ virtual sal_Bool isFillState(EFillState eRequired) const
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short return a list of key names for items, which match
+ the specified criteria.
+
+ @descr The returned key names can be used at another method "getItem()"
+ of this cache to get further informations about this item.
+
+ @attention Please note: because this cache can be used inside multithreaded
+ environments, such returned key name can point to an already removed
+ item! Please be aware of some "NoSuchElementExceptions" if you try to
+ call any other method of this cache in relation to this key name.
+
+ @param eType
+ specify the sub container of this cache, which should be used for
+ searching. see also EItemType.
+
+ @param lIProps
+ specify the property set, which must exist at the searched items
+ as minimum.
+
+ @param lEProps
+ specify the property set, which must not(!) exist at the searched items
+ as minimum.
+
+ @return [OUStringList]
+ a list of key names, which identify items of the queried sub container.
+ May be an empty list.
+
+ @throw [css::uno::Exception]
+ if some input parameter are wrong or the cache itself is not valid
+ any longer, because any operation before damage it.
+ */
+ virtual OUStringList getMatchingItemsByProps( EItemType eType ,
+ const CacheItem& lIProps ,
+ const CacheItem& lEProps = CacheItem()) const
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short indicates if the requested sub container
+ contains some items.
+
+ @descr We dont provide any information about the count
+ of such items. Because we dont implement any index
+ based interface! The information "we have items or not"
+ must be enough for the outside code ... till somewhere
+ give us a good reason. :-)
+
+ @param eType
+ specify the sub container of this cache, which should be used.
+ see also EItemType.
+
+ @return [sal_Bool]
+ True, if the requested sub container contains some items;
+ False otherwhise.
+
+ @throw [css::uno::Exception]
+ if some input parameter are wrong or the cache itself is not valid
+ any longer, because any operation before damage it.
+ */
+ virtual sal_Bool hasItems(EItemType eType) const
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short return a list of all key names, which represent
+ an item inside the specified sub container.
+
+ @attention Please note: because this cache can be used inside multithreaded
+ environments, such returned key names can point to some already removed
+ items! Please be aware of some "NoSuchElementExceptions" if you try to
+ call any other method of this cache in relation to this key names.
+
+ @param eType
+ specify the sub container of this cache, which should be used for
+ searching. see also EItemType.
+
+ @return [OUStringList]
+ a list of key names, which can be used to access the item properties
+ using some other methods of this cache.
+
+ @throw [css::uno::Exception]
+ if some input parameter are wrong or the cache itself is not valid
+ any longer, because any operation before damage it.
+ */
+ virtual OUStringList getItemNames(EItemType eType) const
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short check if the required item exist inside this container.
+
+ @attention This method exists to supports some UNO container interfaces
+ only. (e.g. XNameAccess.hasByName()). But inside multithreaded
+ environments there is no guarantee, that this item still exists, if
+ its realy requested e.g. by calling getItem()!
+ Be aware of some NoSuchElementExistExceptions ...
+
+ @param eType
+ specify the sub container of this cache, which should be used.
+ see also EItemType.
+
+ @param sItem
+ the key name of the requested item inside the pecified sub container.
+
+ @throw [css::uno::Exception]
+ if some input parameter are wrong or the cache itself is not valid
+ any longer, because any operation before damage it.
+ */
+ virtual sal_Bool hasItem( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short return an item, which match the specified type and name.
+
+ @descr Because this cache can be used inside multithreaded environments
+ the caller must be aware of some exceptions - especialy a "NoSuchElementExcepotion".
+ May another thread already removed the required item before ...
+
+ @param eType
+ specify the sub container of this cache, which should be used for
+ searching. see also EItemType.
+
+ @param sItem
+ specify the requested item by its key name.
+
+ @return [CacheItem]
+ the required item if it could be located ...
+ But we throw an exception if the required item does not exist!
+
+ @throw [css::container::NoSuchElementException]
+ if the required item does not still exist.
+
+ @throw [css::uno::Exception]
+ if some input parameter are wrong or the cache itself is not valid
+ any longer, because any operation before damage it.
+ */
+ virtual CacheItem getItem( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO document me ...
+ */
+ virtual void removeItem( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO document me ...
+ */
+ virtual void setItem( EItemType eType ,
+ const ::rtl::OUString& sItem ,
+ const CacheItem& aValue)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO document me ...
+ */
+ virtual void refreshItem( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short add some implicit properties to the given
+ cache item reference.
+
+ @descr Such properties can e.g. finalized or mandatory.
+ They are not persistent and not realy part of e.g. a
+ filter not. But they are attributes of a configuration
+ entry and can influence our container interface.
+
+ @attention These properties are not part of the normal CacheItem
+ returned by the method getItem(). Because getItem() is
+ used internaly too but these specialized properties
+ are needed at our container services only. So these
+ function sets are different to allow different handling.
+
+ @param eType
+ specify the sub container of this cache, which should be used for
+ searching. see also EItemType.
+
+ @param sItem
+ specify the requested item by its key name.
+
+ @param rItem
+ contains already the normal properties of this item,
+ and will be used as out parameter to add the implicit
+ attributes there.
+
+ @throw [css::uno::Exception]
+ if an internal error occured.
+ Note: If the item is missing inside the underlying configuration
+ no exception will be thrown. In such case the item is marked as
+ finalized/mandatory automaticly
+ Reason: May be the item cames from the old configuration package and
+ was not migrated to the new one. So we cant provide write access
+ to such items ...
+ */
+ virtual void addStatePropsToItem( EItemType eType,
+ const ::rtl::OUString& sItem,
+ CacheItem& rItem)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO document me
+ */
+ virtual void removeStatePropsFromItem(CacheItem& aValue)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short force writing of all changes (which was made after
+ last flush was called) back to the configuration.
+
+ @descr TODO
+
+ @throw [css::uno::Exception]
+ if the cache itself is not valid
+ any longer, because any operation before damage it.
+ */
+ virtual void flush()
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short supports a flat type detection for given URL.
+
+ @descr Because such detection works on our optimized internal
+ structures (e.g. mapping from extensions/pattern to type names),
+ it should be made inside this cache.
+
+ @param aURL
+ URL of the content, which type should be detected.
+ Its already parsed and splitted into its differnt parts,
+ like e.g.: main, jump marks etcpp.
+
+ @param rFlatTypes
+ used as [out] parameter to add all types, which match to the given
+ URL. Further an information is added for every type. It indicates, how
+ this type is related to the specified URL (means e.g. if it matches
+ by extension or URLPattern ...).
+
+ @attention Please note: because this cache can be used inside multithreaded
+ environments, such returned key names can point to some already removed
+ items! Please be aware of some "NoSuchElementExceptions" if you try to
+ call any other method of this cache in relation to this key names.
+
+ @throw [css::uno::Exception]
+ if the cache itself is not valid
+ any longer, because any operation before damage it.
+ */
+ virtual void detectFlatForURL(const css::util::URL& aURL ,
+ FlatDetection& rFlatTypes) const
+ throw(css::uno::Exception);
+
+ //-------------------------------------------
+ // private helper
+
+ private:
+
+ //---------------------------------------
+
+ /** @short return a reference to one of our internal
+ sub container, which contains items of the
+ requested type.
+
+ @param eType
+ specify, which sub container is needed outside.
+
+ @return [CacheItemList&]
+ a reference(!) to the right sub container member.
+
+ @throw [css::uno::Exception]
+ if the required list does not exist.
+ */
+ CacheItemList& impl_getItemList(EItemType eType) const
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short return a valid configuration update access
+ to the underlying configuration package, which
+ is fix for this cache.
+
+ @descr It checks first, if the internal member m_xConfig already
+ points to an open update access. If not - it opens a new one.
+ Doing so this method can be called everytimes a configuration
+ access is needed.
+
+ @param eProvider
+ specify the needed configuration provider.
+ see EConfigProvider for further informations ...
+
+ @attention If a configuration access was opened successfully
+ all neccessary listener connections will be established
+ too. So this cache will be informed about outside updates.
+ */
+ css::uno::Reference< css::uno::XInterface > impl_openConfig(EConfigProvider eProvide)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short tries to open the requested configuration root
+ using the specified modi.
+
+ @param sRoot
+ specify the configuration root, which should be opened.
+
+ @param bReadOnly
+ enable/disable write access on the returned configuration
+ object.
+
+ @param bLocalesMode
+ enable/disable special handling of localized configuratiom
+ items by the returned configuration object.
+
+ @return A valid reference, if the configuration access could be opened
+ and initialized within the requested modes successfully;
+ a NULL reference otherwhise.
+ */
+ css::uno::Reference< css::uno::XInterface > impl_createConfigAccess(const ::rtl::OUString& sRoot ,
+ sal_Bool bReadOnly ,
+ sal_Bool bLocalesMode);
+
+ //---------------------------------------
+
+ /** @short reads the specified configuration key
+ and return its value.
+
+ @descr The specified key must be an absolute configuration path,
+ which can be splitted into its package and relative path tokens.
+
+ @attention Because this function might opens a new configuration
+ read access for reading one key value only, it should
+ be used in rare cases only. Its an easy way ... but an
+ expensive one.
+
+ @param sDirectKey
+ the absolute configuration path, which should be readed.
+
+ @return [css::uno::Any]
+ the value of the requested key.
+ Can be empty if an internal error occured or if the requested
+ key does not exists!
+ */
+ css::uno::Any impl_getDirectCFGValue(const ::rtl::OUString& sDirectKey);
+
+ //---------------------------------------
+
+ /** @short load the underlying configuration into this cache.
+
+ @descr Which items should be readed can be regulate by the
+ parameter eRequiredState. That provides the possibility
+ to load standard values on startup only and update this
+ cache later on demand with all available informations.
+
+ @param eRequiredState
+ indicates, which fill state this cache should have afterwards.
+ */
+ void impl_load(EFillState eRequiredState)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short validate the whole cache and create
+ structures for optimized items access.
+
+ @descr Wrong cache items will be removed automaticly.
+ Wrong dependencies will be corrected automaticly.
+ If something could not be repaired - an exception
+ is thrown.
+ Further some optmized structures will be created.
+ E.g.: a hash to map extensions to her types.
+
+ @attention There is no exception, if the cache could be repaired
+ but contained wrong elements before!
+
+ @throw [css::uno::Exception]
+ if cache is invalid and could not be repaired.
+ */
+ void impl_validateAndOptimize()
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short register the specified item for the given type.
+
+ @descr Because detect services, frame loader or content handler
+ are not listed inside the xml configuration as seperated
+ items (they are properties of any type entry!), this method update
+ the internal lists of such items. Thats neccessary to have
+ it accessible for our container interfaces of detect, frame loader
+ and content handler services.
+
+ @param pList
+ points to a CacheItemList of this filter cache, where
+ this item registration should be updated or added.
+
+ @param sItem
+ specify the detect service, frame loader or content handler,
+ which should be registered for the given type.
+
+ @param sType
+ contains the internal type name, where the item should be registered for.
+
+ @throw [css::uno::Exception]
+ If registration failed by any reason.
+ That does not include double registrations!
+ */
+ void impl_resolveItem4TypeRegistration( CacheItemList* pList,
+ const ::rtl::OUString& sItem,
+ const ::rtl::OUString& sType)
+ throw(css::uno::Exception);
+
+ //-------------------------------------------
+ // static helper
+
+ private:
+
+ //---------------------------------------
+
+ /** @short read the specified config set into the cache.
+
+ @descr This method provides the following mechanism for reading:
+ a) read only standard properties of set items
+ b) read anything
+ c) read only optional properties and update already existing
+ items of the specified cache
+
+ @param xConfig
+ API which provides access to the required configuration set.
+
+ @param eType
+ specify the type of config item, which must be interpreted.
+ Of course this information can be used to locate the right set
+ at the given xConfig API object.
+
+ @param eOption
+ regulate reading of standard/optional or all properties.
+
+ @param pCache
+ points to the cache member, which should be filled or updated.
+
+ @throw [css::uno::Exception]
+ if an unrecoverable error occure inside this operation.
+ */
+ void impl_loadSet(const css::uno::Reference< css::container::XNameAccess >& xConfig,
+ EItemType eType ,
+ EReadOption eOption,
+ CacheItemList* pCache )
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short read the specified container item from the given configuration set.
+
+ @descr Its not added to any internal structures here. That must be done
+ outside this method.
+
+ @param xSet
+ provides access to the configuration set, which includes all items.
+
+ @param eType
+ specify, which container item type must be readed.
+
+ @param sItem
+ means the internal name, which can be used to adress the item
+ properties relativ to the given configuration set.
+
+ @param eOption
+ regulate, which properties of the requested item should be read.
+ See defintion of EReadOption for further informations.
+
+ @throw [css::uno::Exception]
+ if an unrecoverable error occure inside this operation.
+ */
+ CacheItem impl_loadItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
+ EItemType eType ,
+ const ::rtl::OUString& sItem ,
+ EReadOption eOption)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short try to load the requested item on demand from the underlying configuration
+ layer.
+
+ @descr The outside code has to be shure, that the item does not already exists
+ inside this cachse. Otherwise it will be loaded twice. This method
+ doesnt check such constellations!
+
+ @param eType
+ specify the type of config item, which must be interpreted.
+ Of course this information can be used to locate the right set
+ at the given xConfig API object.
+
+ @param sItem
+ the set node name of the requested item.
+
+ @return An iterator, which points directly to the new cached item.
+ Is a valid iterator if no exception occured here!
+ But to improve robustness - it should be checked :-)
+
+ @throw [css::container::NoSuchElementException]
+ if the item does not exists inside the configuration layer too!
+
+ @throw [css::uno::Exception]
+ if an unrecoverable error occure inside this operation.
+ */
+ CacheItemList::iterator impl_loadItemOnDemand( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO */
+ void impl_saveItem(const css::uno::Reference< css::container::XNameReplace >& xSet ,
+ EItemType eType ,
+ const CacheItem& aValue)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO */
+ void impl_addItem2FlushList( EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception);
+
+
+ //---------------------------------------
+
+ /** TODO */
+ void impl_flushByList(const css::uno::Reference< css::container::XNameAccess >& xSet ,
+ EItemType eType ,
+ const CacheItemList& rCache,
+ const OUStringList& lItems)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short specify, which save operation is neccessary for the specified item.
+
+ @desrc If an item of this cache will be added/removed or modified it will
+ be changed inside memory only first. But we save its name inside a special
+ list of changed items. If at least the method flush() is called, we use
+ this list to check if the item was changed/added or removed. This method
+ checks the exist state of the requested item inside our own cache
+ and inside the underlying configuration layer to find out, if the item
+ must be removed/added or modified inside the configuratuion layer.
+
+ @param xSet
+ points directly to the configuration set, where the item should resist
+ (if it exists!).
+
+ @param rList
+ points to our internal cache list, where the item should resist
+ (if it exists!).
+
+ @param sItem
+ the internal name of the item, which should be checked.
+
+ @return An enum value of type EItemFlushState, which indicates the needed
+ API operation for updating the underlying configuration layer.
+
+ @throws An exception if anything failed inside this operation.
+ e.g. the given configuration set was not open.
+ */
+ EItemFlushState impl_specifyFlushOperation(const css::uno::Reference< css::container::XNameAccess >& xSet ,
+ const CacheItemList& rList,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO */
+ void impl_readPatchUINames(const css::uno::Reference< css::container::XNameAccess >& xNode,
+ CacheItem& rItem)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO */
+ void impl_savePatchUINames(const css::uno::Reference< css::container::XNameReplace >& xNode,
+ const CacheItem& rItem)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO */
+ void impl_readOldFormat()
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO */
+ CacheItem impl_readOldItem(const css::uno::Reference< css::container::XNameAccess >& xSet ,
+ EItemType eType,
+ const ::rtl::OUString& sItem)
+ throw(css::uno::Exception);
+
+ //---------------------------------------
+
+ /** TODO */
+ void impl_interpretDataVal4Type(const ::rtl::OUString& sValue,
+ sal_Int32 nProp ,
+ CacheItem& rItem );
+
+ //---------------------------------------
+
+ /** TODO */
+ void impl_interpretDataVal4Filter(const ::rtl::OUString& sValue,
+ sal_Int32 nProp ,
+ CacheItem& rItem );
+
+ //---------------------------------------
+
+ /** TODO */
+ OUStringList impl_tokenizeString(const ::rtl::OUString& sData ,
+ sal_Unicode cSeperator);
+
+ //---------------------------------------
+
+#if OSL_DEBUG_LEVEL > 0
+ /** TODO */
+ ::rtl::OUString impl_searchFrameLoaderForType(const ::rtl::OUString& sType) const;
+ ::rtl::OUString impl_searchContentHandlerForType(const ::rtl::OUString& sType) const;
+#endif
+
+ //---------------------------------------
+ /** @short check if the specified OOo module is installed.
+
+ @param sModule
+ the long name of the module (e.g. "com.sun.star.text.TextDocument").
+
+ @return TRUE if the requested module is installed; FALSE otherwise.
+ */
+ sal_Bool impl_isModuleInstalled(const ::rtl::OUString& sModule);
+
+ //---------------------------------------
+
+ /** @short convert a list of flag names to its int representation.
+
+ @param lNames
+ the list of flag names.
+
+ @return [sal_Int32]
+ the converted flag field.
+ */
+ static sal_Int32 impl_convertFlagNames2FlagField(const css::uno::Sequence< ::rtl::OUString >& lNames);
+
+ //---------------------------------------
+
+ /** @short convert a flag field value to its list representation of flag names.
+
+ @param nFlags
+ the flag field value
+
+ @return [seq< string >]
+ the converted flag name list.
+ */
+ static css::uno::Sequence< ::rtl::OUString > impl_convertFlagField2FlagNames(sal_Int32 nFlags);
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_FILTERCACHE_HXX_
diff --git a/filter/source/config/cache/filterconfig1.component b/filter/source/config/cache/filterconfig1.component
new file mode 100644
index 000000000000..9d3c7c90fb31
--- /dev/null
+++ b/filter/source/config/cache/filterconfig1.component
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* 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.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.filter.config.ConfigFlush">
+ <service name="com.sun.star.document.FilterConfigRefresh"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.filter.config.ContentHandlerFactory">
+ <service name="com.sun.star.frame.ContentHandlerFactory"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.filter.config.FilterFactory">
+ <service name="com.sun.star.document.FilterFactory"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.filter.config.FrameLoaderFactory">
+ <service name="com.sun.star.frame.FrameLoaderFactory"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.filter.config.TypeDetection">
+ <service name="com.sun.star.document.TypeDetection"/>
+ </implementation>
+</component>
diff --git a/filter/source/config/cache/filterfactory.cxx b/filter/source/config/cache/filterfactory.cxx
new file mode 100644
index 000000000000..dc7869be27ca
--- /dev/null
+++ b/filter/source/config/cache/filterfactory.cxx
@@ -0,0 +1,724 @@
+/*************************************************************************
+ *
+ * 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 "filterfactory.hxx"
+#include "macros.hxx"
+#include "constant.hxx"
+#include "versions.hxx"
+
+//_______________________________________________
+// includes
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/configurationhelper.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+/** @short can be used to query for filters related to its application module.
+ */
+#define BASE_QUERY_ALL "_query_all"
+#define BASE_QUERY_WRITER "_query_Writer"
+#define BASE_QUERY_WEB "_query_web"
+#define BASE_QUERY_GLOBAL "_query_global"
+#define BASE_QUERY_CHART "_query_chart"
+#define BASE_QUERY_CALC "_query_calc"
+#define BASE_QUERY_IMPRESS "_query_impress"
+#define BASE_QUERY_DRAW "_query_draw"
+#define BASE_QUERY_MATH "_query_math"
+
+//_______________________________________________
+
+/** @short define all possible parts of a filter query.
+
+ @descr syntax: "<query>[:<param>[=<value>]]"
+ e.g.: "_query_writer:default_first:use_order:sort_prop=uiname"
+
+ argument description default
+ -----------------------------------------------------------------------------------------------
+ iflags=<mask> include filters by given mask 0
+ eflags=<mask> exclude filters by given mask 0
+ sort_prop=<[name,uiname]> sort by internal name or uiname name
+ descending sort descending false
+ use_order use order flag of filters for sorting false
+ default_first set default filter on top of return list false
+ case_sensitive compare "sort_prop" case sensitive false
+ */
+#define SEPERATOR_QUERYPARAM ((sal_Unicode)':')
+#define SEPERATOR_QUERYPARAMVALUE ((sal_Unicode)'=')
+
+#define QUERYPARAM_IFLAGS ::rtl::OUString::createFromAscii("iflags")
+#define QUERYPARAM_EFLAGS ::rtl::OUString::createFromAscii("eflags")
+#define QUERYPARAM_SORT_PROP ::rtl::OUString::createFromAscii("sort_prop")
+
+#define QUERYPARAM_DESCENDING ::rtl::OUString::createFromAscii("descending")
+#define QUERYPARAM_USE_ORDER ::rtl::OUString::createFromAscii("use_order")
+#define QUERYPARAM_DEFAULT_FIRST ::rtl::OUString::createFromAscii("default_first")
+#define QUERYPARAM_CASE_SENSITIVE ::rtl::OUString::createFromAscii("case_sensitive")
+
+#define QUERYPARAMVALUE_SORT_PROP_NAME ::rtl::OUString::createFromAscii("name")
+#define QUERYPARAMVALUE_SORT_PROP_UINAME ::rtl::OUString::createFromAscii("uiname")
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+FilterFactory::FilterFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ BaseContainer::init(xSMGR ,
+ FilterFactory::impl_getImplementationName() ,
+ FilterFactory::impl_getSupportedServiceNames(),
+ FilterCache::E_FILTER );
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+FilterFactory::~FilterFactory()
+{
+}
+
+/*-----------------------------------------------
+ 16.07.2003 13:43
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > SAL_CALL FilterFactory::createInstance(const ::rtl::OUString& sFilter)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ return createInstanceWithArguments(sFilter, css::uno::Sequence< css::uno::Any >());
+}
+
+/*-----------------------------------------------
+ 17.07.2003 08:56
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > SAL_CALL FilterFactory::createInstanceWithArguments(const ::rtl::OUString& sFilter ,
+ const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ ::rtl::OUString sRealFilter = sFilter;
+
+ #ifdef _FILTER_CONFIG_MIGRATION_Q_
+
+ /* -> TODO - HACK
+ check if the given filter name realy exist ...
+ Because our old implementation worked with an internal
+ type name instead of a filter name. For a small migration time
+ we must simulate this old feature :-( */
+
+ if (!m_rCache->hasItem(FilterCache::E_FILTER, sFilter) && m_rCache->hasItem(FilterCache::E_TYPE, sFilter))
+ {
+ OSL_ENSURE(sal_False, "Who use this deprecated functionality?");
+ _FILTER_CONFIG_LOG_("FilterFactory::createInstanceWithArguments() ... simulate old type search functionality!\n");
+
+ css::uno::Sequence< css::beans::NamedValue > lQuery(1);
+ lQuery[0].Name = PROPNAME_TYPE;
+ lQuery[0].Value <<= sFilter;
+
+ css::uno::Reference< css::container::XEnumeration > xSet = createSubSetEnumerationByProperties(lQuery);
+ while(xSet->hasMoreElements())
+ {
+ ::comphelper::SequenceAsHashMap lHandlerProps(xSet->nextElement());
+ if (!(lHandlerProps[PROPNAME_NAME] >>= sRealFilter))
+ continue;
+ }
+
+ // prevent outside code against NoSuchElementException!
+ // But dont implement such defensive strategy for our new create handling :-)
+ if (!m_rCache->hasItem(FilterCache::E_FILTER, sRealFilter))
+ return css::uno::Reference< css::uno::XInterface>();
+ }
+
+ /* <- HACK */
+
+ #endif // _FILTER_CONFIG_MIGRATION_Q_
+
+ // search filter on cache
+ CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sRealFilter);
+ ::rtl::OUString sFilterService;
+ aFilter[PROPNAME_FILTERSERVICE] >>= sFilterService;
+
+ // create service instance
+ css::uno::Reference< css::uno::XInterface > xFilter;
+ if (sFilterService.getLength())
+ xFilter = m_xSMGR->createInstance(sFilterService);
+
+ // initialize filter
+ css::uno::Reference< css::lang::XInitialization > xInit(xFilter, css::uno::UNO_QUERY);
+ if (xInit.is())
+ {
+ // format: lInitData[0] = seq<PropertyValue>, which contains all configuration properties of this filter
+ // lInitData[1] = lArguments[0]
+ // ...
+ // lInitData[n] = lArguments[n-1]
+ css::uno::Sequence< css::beans::PropertyValue > lConfig;
+ aFilter >> lConfig;
+
+ ::comphelper::SequenceAsVector< css::uno::Any > stlArguments(lArguments);
+ stlArguments.insert(stlArguments.begin(), css::uno::makeAny(lConfig));
+
+ css::uno::Sequence< css::uno::Any > lInitData;
+ stlArguments >> lInitData;
+
+ xInit->initialize(lInitData);
+ }
+
+ return xFilter;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 18.02.2004 14:21
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > SAL_CALL FilterFactory::getAvailableServiceNames()
+ throw(css::uno::RuntimeException)
+{
+ /* Attention: Instead of getElementNames() this method have to return only filter names,
+ which can be created as UNO Services realy. Thats why we search for filters,
+ which dont have a valid value for the property "FilterService".
+ Of course we cant check for corrupted service names here. We can check
+ for empty strings only ...
+ */
+ CacheItem lIProps;
+ CacheItem lEProps;
+ lEProps[PROPNAME_FILTERSERVICE] <<= ::rtl::OUString();
+
+ OUStringList lUNOFilters;
+ try
+ {
+ lUNOFilters = m_rCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps, lEProps);
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { lUNOFilters.clear(); }
+
+ return lUNOFilters.getAsConstList();
+}
+
+/*-----------------------------------------------
+ 11.03.2004 08:37
+-----------------------------------------------*/
+css::uno::Reference< css::container::XEnumeration > SAL_CALL FilterFactory::createSubSetEnumerationByQuery(const ::rtl::OUString& sQuery)
+ throw (css::uno::RuntimeException)
+{
+ // reject old deprecated queries ...
+ if (sQuery.matchAsciiL("_filterquery_",13,0))
+ throw css::uno::RuntimeException(
+ _FILTER_CONFIG_FROM_ASCII_("Use of deprecated and now unsupported query!"),
+ static_cast< css::container::XContainerQuery* >(this));
+
+ // convert "_query_xxx:..." to "getByDocService=xxx:..."
+ ::rtl::OUString sNewQuery(sQuery);
+ sal_Int32 pos = sNewQuery.indexOf(::rtl::OUString::createFromAscii("_query_"),0);
+ if (pos != -1)
+ {
+ OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use new query format: 'matchByDocumentService=...'");
+ ::rtl::OUStringBuffer sPatchedQuery(256);
+ sPatchedQuery.appendAscii("matchByDocumentService=");
+ sPatchedQuery.append (sNewQuery.copy(7) );
+ sNewQuery = sPatchedQuery.makeStringAndClear();
+ }
+
+ // analyze query and split it into its tokens
+ QueryTokenizer lTokens(sNewQuery);
+ QueryTokenizer::const_iterator pIt;
+ OUStringList lEnumSet;
+
+ // start query
+ // (see attention comment below!)
+ if (lTokens.valid())
+ {
+ // SAFE -> ----------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ // May be not all filters was loaded ...
+ // But we need it now!
+ impl_loadOnDemand();
+ aLock.clear();
+ // <- SAFE ----------------------
+
+ if (lTokens.find(QUERY_IDENTIFIER_GETPREFERREDFILTERFORTYPE) != lTokens.end())
+ OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use prop search at the TypeDetection container!");
+// lEnumSet = impl_queryGetPreferredFilterForType(lTokens);
+ else
+ if (lTokens.find(QUERY_IDENTIFIER_MATCHBYDOCUMENTSERVICE) != lTokens.end())
+ lEnumSet = impl_queryMatchByDocumentService(lTokens);
+ else
+ if (lTokens.find(QUERY_IDENTIFIER_GET_SORTED_FILTERLIST) != lTokens.end())
+ lEnumSet = impl_getSortedFilterList(lTokens);
+ }
+
+ // pack list of item names as an enum list
+ // Attention: Do not return empty reference for empty list!
+ // The outside check "hasMoreElements()" should be enough, to detect this state :-)
+// size_t c = lEnumSet.size();
+ css::uno::Sequence< ::rtl::OUString > lSet = lEnumSet.getAsConstList();
+ ::comphelper::OEnumerationByName* pEnum = new ::comphelper::OEnumerationByName(this, lSet);
+ return css::uno::Reference< css::container::XEnumeration >(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY);
+}
+/*
+ if (lEnumSet.empty())
+ {
+ //-------------------------------------------
+ // 1) getDefaultFilterForType=<internal_typename>
+
+ pIt = lTokens.find(::rtl::OUString::createFromAscii("getDefaultFilterForType"));
+ if (pIt != lTokens.end())
+ {
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // might not all types was loaded till now!
+ impl_loadOnDemand();
+
+ ::rtl::OUString sType = pIt->second;
+ FilterCache* pCache = impl_getWorkingCache();
+ if (pCache->hasItem(FilterCache::E_TYPE, sType))
+ {
+ CacheItem aType = pCache->getItem(FilterCache::E_TYPE, sType);
+ ::rtl::OUString sPreferredFilter;
+ aType[PROPNAME_PREFERREDFILTER] >>= sPreferredFilter;
+
+ if (
+ (sPreferredFilter.getLength() ) &&
+ (pCache->hasItem(FilterCache::E_FILTER, sPreferredFilter))
+ )
+ {
+ lEnumSet.push_back(sPreferredFilter);
+ }
+ }
+
+ aLock.clear();
+ // <- SAFE
+ }
+ }
+*/
+
+/*-----------------------------------------------
+ 11.03.2004 08:33
+-----------------------------------------------*/
+OUStringList FilterFactory::impl_queryMatchByDocumentService(const QueryTokenizer& lTokens) const
+{
+ // analyze query
+ QueryTokenizer::const_iterator pIt;
+
+ ::rtl::OUString sDocumentService;
+ sal_Int32 nIFlags = 0;
+ sal_Int32 nEFlags = 0;
+
+ pIt = lTokens.find(QUERY_IDENTIFIER_MATCHBYDOCUMENTSERVICE);
+ if (pIt != lTokens.end())
+ sDocumentService = pIt->second;
+
+#define COMP_HACK
+#ifdef COMP_HACK
+ if (sDocumentService.equalsAscii("writer"))
+ {
+ OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
+ sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.text.TextDocument");
+ }
+ else
+ if (sDocumentService.equalsAscii("web"))
+ {
+ OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
+ sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.text.WebDocument");
+ }
+ else
+ if (sDocumentService.equalsAscii("global"))
+ {
+ OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
+ sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.text.GlobalDocument");
+ }
+ else
+ if (sDocumentService.equalsAscii("calc"))
+ {
+ OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
+ sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument");
+ }
+ else
+ if (sDocumentService.equalsAscii("draw"))
+ {
+ OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
+ sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.drawing.DrawingDocument");
+ }
+ else
+ if (sDocumentService.equalsAscii("impress"))
+ {
+ OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
+ sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.presentation.PresentationDocument");
+ }
+ else
+ if (sDocumentService.equalsAscii("math"))
+ {
+ OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
+ sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.formula.FormulaProperties");
+ }
+#endif
+
+ pIt = lTokens.find(QUERY_PARAM_IFLAGS);
+ if (pIt != lTokens.end())
+ nIFlags = ::rtl::OUString(pIt->second).toInt32();
+
+ pIt = lTokens.find(QUERY_PARAM_EFLAGS);
+ if (pIt != lTokens.end())
+ nEFlags = ::rtl::OUString(pIt->second).toInt32();
+
+ // SAFE -> ----------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // search suitable filters
+ FilterCache* pCache = impl_getWorkingCache();
+ OUStringList lFilterNames = pCache->getItemNames(FilterCache::E_FILTER);
+ OUStringList lResult ;
+
+ for (OUStringList::const_iterator pName = lFilterNames.begin();
+ pName != lFilterNames.end() ;
+ ++pName )
+ {
+ try
+ {
+ const ::rtl::OUString& sName = *pName;
+ const CacheItem aFilter = pCache->getItem(FilterCache::E_FILTER, sName);
+ CacheItem::const_iterator pProp ;
+
+ // "matchByDocumentService=" => any filter will be adressed here
+ // "matchByDocumentService=all" => any filter will be adressed here
+ // "matchByDocumentService=com.sun.star..." => only filter matching this document service will be adressed
+ ::rtl::OUString sCheckValue = aFilter.getUnpackedValueOrDefault(PROPNAME_DOCUMENTSERVICE, ::rtl::OUString());
+ if (
+ ( sDocumentService.getLength() ) &&
+ (!sDocumentService.equals(QUERY_CONSTVALUE_ALL)) &&
+ (!sCheckValue.equals(sDocumentService) )
+ )
+ {
+ continue; // ignore filter -> try next one!
+ }
+
+ // "iflags=" => not allowed
+ // "iflags=-1" => not allowed
+ // "iflags=0" => not usefull
+ // "iflags=283648" => only filter, which has set these flag field will be adressed
+ sal_Int32 nCheckValue = aFilter.getUnpackedValueOrDefault(PROPNAME_FLAGS, (sal_Int32)0);
+ if (
+ (nIFlags > 0 ) &&
+ ((nCheckValue & nIFlags) != nIFlags)
+ )
+ {
+ continue; // ignore filter -> try next one!
+ }
+
+ // "eflags=" => not allowed
+ // "eflags=-1" => not allowed
+ // "eflags=0" => not usefull
+ // "eflags=283648" => only filter, which has not set these flag field will be adressed
+ if (
+ (nEFlags > 0 ) &&
+ ((nCheckValue & nEFlags) == nEFlags)
+ )
+ {
+ continue; // ignore filter -> try next one!
+ }
+
+ // OK - this filter passed all checks.
+ // It match the query ...
+ lResult.push_back(sName);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { continue; }
+ }
+
+ aLock.clear();
+ // <- SAFE ----------------------
+
+ return lResult;
+}
+
+/*-----------------------------------------------
+ 21.01.2005 13:39
+-----------------------------------------------*/
+class stlcomp_removeIfMatchFlags
+{
+ private:
+ FilterCache* m_pCache ;
+ sal_Int32 m_nFlags ;
+ sal_Bool m_bIFlags;
+
+ public:
+ stlcomp_removeIfMatchFlags(FilterCache* pCache ,
+ sal_Int32 nFlags ,
+ sal_Bool bIFlags)
+ : m_pCache (pCache )
+ , m_nFlags (nFlags )
+ , m_bIFlags(bIFlags)
+ {}
+
+ bool operator() (const ::rtl::OUString& sFilter) const
+ {
+ try
+ {
+ const CacheItem aFilter = m_pCache->getItem(FilterCache::E_FILTER, sFilter);
+ sal_Int32 nFlags = aFilter.getUnpackedValueOrDefault(PROPNAME_FLAGS, ((sal_Int32)0));
+
+ bool bMatch = false;
+ if (m_bIFlags)
+ // IFlags are interpeted as ALL_FLAGS_MUST_MATCH !
+ bMatch = ((nFlags & m_nFlags) == m_nFlags);
+ else
+ // EFlags are interpreted as ATE_LEAST_ONE_FLAG_MUST_MATCH !
+ bMatch = !(nFlags & m_nFlags);
+ // We are asked for bRemove ! And bMatch = !bRemove => so bRemove = !bMatch .-)
+ return !bMatch;
+ }
+ catch(css::container::NoSuchElementException)
+ {
+ return true;
+ }
+ }
+};
+
+/*-----------------------------------------------
+ 21.01.2005 13:39
+-----------------------------------------------*/
+OUStringList FilterFactory::impl_getSortedFilterList(const QueryTokenizer& lTokens) const
+{
+ // analyze the given query parameter
+ QueryTokenizer::const_iterator pIt1;
+
+ ::rtl::OUString sModule;
+ sal_Int32 nIFlags = -1;
+ sal_Int32 nEFlags = -1;
+
+ pIt1 = lTokens.find(QUERY_PARAM_MODULE);
+ if (pIt1 != lTokens.end())
+ sModule = pIt1->second;
+ pIt1 = lTokens.find(QUERY_PARAM_IFLAGS);
+ if (pIt1 != lTokens.end())
+ nIFlags = ::rtl::OUString(pIt1->second).toInt32();
+ pIt1 = lTokens.find(QUERY_PARAM_EFLAGS);
+ if (pIt1 != lTokens.end())
+ nEFlags = ::rtl::OUString(pIt1->second).toInt32();
+
+ // simple search for filters of one specific module.
+ OUStringList lFilterList;
+ if (sModule.getLength())
+ lFilterList = impl_getSortedFilterListForModule(sModule, nIFlags, nEFlags);
+ else
+ {
+ // more complex search for all filters
+ // We check first, which office modules are installed ...
+ OUStringList lModules = impl_getListOfInstalledModules();
+ OUStringList::const_iterator pIt2;
+ for ( pIt2 = lModules.begin();
+ pIt2 != lModules.end() ;
+ ++pIt2 )
+ {
+ sModule = *pIt2;
+ OUStringList lFilters4Module = impl_getSortedFilterListForModule(sModule, nIFlags, nEFlags);
+ OUStringList::const_iterator pIt3;
+ for ( pIt3 = lFilters4Module.begin();
+ pIt3 != lFilters4Module.end() ;
+ ++pIt3 )
+ {
+ const ::rtl::OUString& sFilter = *pIt3;
+ lFilterList.push_back(sFilter);
+ }
+ }
+ }
+
+ return lFilterList;
+}
+
+/*-----------------------------------------------
+ 21.01.2005 10:19
+-----------------------------------------------*/
+OUStringList FilterFactory::impl_getListOfInstalledModules() const
+{
+ // SAFE -> ----------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aLock.clear();
+ // <- SAFE ----------------------
+
+ try
+ {
+ css::uno::Reference< css::container::XNameAccess > xModuleConfig(
+ ::comphelper::ConfigurationHelper::openConfig(xSMGR,
+ CFGPACKAGE_OOO_MODULES,
+ ::comphelper::ConfigurationHelper::E_READONLY),
+ css::uno::UNO_QUERY_THROW);
+ OUStringList lModules(xModuleConfig->getElementNames());
+ return lModules;
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+
+ return OUStringList();
+}
+
+/*-----------------------------------------------
+ 21.01.2005 10:19
+-----------------------------------------------*/
+OUStringList FilterFactory::impl_getSortedFilterListForModule(const ::rtl::OUString& sModule,
+ sal_Int32 nIFlags,
+ sal_Int32 nEFlags) const
+{
+ OUStringList lSortedFilters = impl_readSortedFilterListFromConfig(sModule);
+
+ // get all filters for the requested module
+ CacheItem lIProps;
+ lIProps[PROPNAME_DOCUMENTSERVICE] <<= sModule;
+
+ // SAFE -> ----------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ FilterCache* pCache = impl_getWorkingCache();
+ OUStringList lOtherFilters = pCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps);
+ aLock.clear();
+ // <- SAFE ----------------------
+
+ // bring "other" filters in an alphabeticly order
+ // It's needed below.
+ ::std::sort(lOtherFilters.begin(), lOtherFilters.end());
+
+ // merge both lists together
+ OUStringList lMergedFilters = lSortedFilters;
+ OUStringList::iterator pIt2;
+ OUStringList::iterator pIt3;
+ for ( pIt2 = lOtherFilters.begin();
+ pIt2 != lOtherFilters.end() ;
+ ++pIt2 )
+ {
+ const ::rtl::OUString& rFilter = *pIt2;
+ pIt3 = ::std::find(lSortedFilters.begin(), lSortedFilters.end(), rFilter);
+ if (pIt3 == lSortedFilters.end())
+ lMergedFilters.push_back(rFilter);
+ }
+
+ // remove all filters from this merged list, which does not fit the flag specification
+ if (nIFlags != -1)
+ {
+ pIt2 = ::std::remove_if(lMergedFilters.begin(), lMergedFilters.end(), stlcomp_removeIfMatchFlags(pCache, nIFlags, sal_True));
+ lMergedFilters.erase(pIt2, lMergedFilters.end());
+ }
+ if (nEFlags != -1)
+ {
+ pIt2 = ::std::remove_if(lMergedFilters.begin(), lMergedFilters.end(), stlcomp_removeIfMatchFlags(pCache, nEFlags, sal_False));
+ lMergedFilters.erase(pIt2, lMergedFilters.end());
+ }
+
+ // sort the default filter to the front of this list
+ // TODO
+
+ return lMergedFilters;
+}
+
+/*-----------------------------------------------
+ 21.01.2005 10:19
+-----------------------------------------------*/
+OUStringList FilterFactory::impl_readSortedFilterListFromConfig(const ::rtl::OUString& sModule) const
+{
+ // SAFE -> ----------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aLock.clear();
+ // <- SAFE ----------------------
+
+ try
+ {
+ css::uno::Reference< css::container::XNameAccess > xUISortConfig(
+ ::comphelper::ConfigurationHelper::openConfig(xSMGR,
+ CFGPACKAGE_TD_UISORT,
+ ::comphelper::ConfigurationHelper::E_READONLY),
+ css::uno::UNO_QUERY_THROW);
+
+ // dont ccheck the module name here. If it does not exists, an exception is thrown and catched below.
+ // We return an empty list as result then.
+ css::uno::Reference< css::container::XNameAccess > xModule;
+ xUISortConfig->getByName(sModule) >>= xModule;
+ if (xModule.is()) // only to be on the safe side of life if the exception was not thrown .-)
+ {
+ // Note: convertion of the returned Any to OUStringList throws
+ // an IllegalArgumentException if the type does not match ...
+ // but it resets the OUStringList to a length of 0 if the Any is empty!
+ OUStringList lSortedFilters(xModule->getByName(PROPNAME_SORTEDFILTERLIST));
+ return lSortedFilters;
+ }
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+
+ return OUStringList();
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+::rtl::OUString FilterFactory::impl_getImplementationName()
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.filter.config.FilterFactory");
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > FilterFactory::impl_getSupportedServiceNames()
+{
+ css::uno::Sequence< ::rtl::OUString > lServiceNames(1);
+ lServiceNames[0] = ::rtl::OUString::createFromAscii("com.sun.star.document.FilterFactory");
+ return lServiceNames;
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > SAL_CALL FilterFactory::impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ FilterFactory* pNew = new FilterFactory(xSMGR);
+ return css::uno::Reference< css::uno::XInterface >(static_cast< css::lang::XMultiServiceFactory* >(pNew), css::uno::UNO_QUERY);
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/filterfactory.hxx b/filter/source/config/cache/filterfactory.hxx
new file mode 100644
index 000000000000..2f0ba31f942b
--- /dev/null
+++ b/filter/source/config/cache/filterfactory.hxx
@@ -0,0 +1,212 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __FILTER_CONFIG_FILTERFACTORY_HXX_
+#define __FILTER_CONFIG_FILTERFACTORY_HXX_
+
+//_______________________________________________
+// includes
+
+#include "basecontainer.hxx"
+#include "querytokenizer.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+//_______________________________________________
+
+/** @short implements the service <type scope="com.sun.star.document">FilterFactory</type>.
+ */
+class FilterFactory : public ::cppu::ImplInheritanceHelper1< BaseContainer ,
+ css::lang::XMultiServiceFactory >
+{
+ //-------------------------------------------
+ // native interface
+
+ public:
+
+ //---------------------------------------
+ // ctor/dtor
+
+ /** @short standard ctor to connect this interface wrapper to
+ the global filter cache instance ...
+
+ @param xSMGR
+ reference to the uno service manager, which created this service instance.
+ */
+ FilterFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+
+ //---------------------------------------
+
+ /** @short standard dtor.
+ */
+ virtual ~FilterFactory();
+
+ //-------------------------------------------
+ // uno interface
+
+ public:
+
+ //---------------------------------------
+ // XMultiServiceFactory
+
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(const ::rtl::OUString& sFilter)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArguments(const ::rtl::OUString& sFilter ,
+ const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableServiceNames()
+ throw(css::uno::RuntimeException);
+
+ //---------------------------------------
+ // XContainerQuery
+
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createSubSetEnumerationByQuery(const ::rtl::OUString& sQuery)
+ throw (css::uno::RuntimeException);
+
+ //-------------------------------------------
+ // internal helper!
+
+ private:
+
+ //---------------------------------------
+
+ /** @short implement the container string query: "matchByDocumentService=:iflags=:eflags=:..."
+
+ @param lTokens
+ the list of query tokens and its values.
+
+ @return A string list of internal filter names, including
+ all filters, which match this query.
+ */
+ OUStringList impl_queryMatchByDocumentService(const QueryTokenizer& lTokens) const;
+
+ //---------------------------------------
+
+ /** TODO document me
+ */
+ OUStringList impl_getListOfInstalledModules() const;
+
+ //---------------------------------------
+
+ /** @short implement the container string query:
+ "getSortedFilterList()[:module=<xxx>]:[iflags=<xxx>][:eflags=<xxx>]"
+
+ @param lTokens
+ the list of query tokens and its values.
+
+ @return A string list of internal filter names, including
+ all filters, which match this query.
+ */
+ OUStringList impl_getSortedFilterList(const QueryTokenizer& lTokens) const;
+
+ //---------------------------------------
+
+ /** TODO document me
+ */
+ OUStringList impl_getSortedFilterListForModule(const ::rtl::OUString& sModule,
+ sal_Int32 nIFlags,
+ sal_Int32 nEFlags) const;
+
+ //---------------------------------------
+
+ /** @short read a specialized and sorted list of filter names from
+ the configuration (matching the specified module)
+
+ @param sModule
+ the module for which the sorted list should be retrieved for.
+
+ @return A string list of internal filter names.
+ Can be empty.
+ */
+ OUStringList impl_readSortedFilterListFromConfig(const ::rtl::OUString& sModule) const;
+
+ //-------------------------------------------
+ // static uno helper!
+
+ public:
+
+ //---------------------------------------
+
+ /** @short return the uno implementation name of this class.
+
+ @descr Because this information is used at several places
+ (and mostly an object instance of this class is not possible)
+ its implemented as a static function!
+
+ @return The fix uno implementation name of this class.
+ */
+ static ::rtl::OUString impl_getImplementationName();
+
+ //---------------------------------------
+
+ /** @short return the list of supported uno services of this class.
+
+ @descr Because this information is used at several places
+ (and mostly an object instance of this class is not possible)
+ its implemented as a static function!
+
+ @return The fix list of uno services supported by this class.
+ */
+ static css::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames();
+
+ //---------------------------------------
+
+ /** @short return a new intsnace of this class.
+
+ @descr This method is used by the uno service manager, to create
+ a new instance of this service if needed.
+
+ @param xSMGR
+ reference to the uno service manager, which require
+ this new instance. It should be passed to the new object
+ so it can be used internaly to create own needed uno resources.
+
+ @return The new instance of this service as an uno reference.
+ */
+ static css::uno::Reference< css::uno::XInterface > impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_FILTERFACTORY_HXX_
diff --git a/filter/source/config/cache/frameloaderfactory.cxx b/filter/source/config/cache/frameloaderfactory.cxx
new file mode 100644
index 000000000000..3c9163899a97
--- /dev/null
+++ b/filter/source/config/cache/frameloaderfactory.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * 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 "frameloaderfactory.hxx"
+#include "macros.hxx"
+#include "constant.hxx"
+#include "versions.hxx"
+
+//_______________________________________________
+// includes
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <comphelper/enumhelper.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+FrameLoaderFactory::FrameLoaderFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ BaseContainer::init(xSMGR ,
+ FrameLoaderFactory::impl_getImplementationName() ,
+ FrameLoaderFactory::impl_getSupportedServiceNames(),
+ FilterCache::E_FRAMELOADER );
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+FrameLoaderFactory::~FrameLoaderFactory()
+{
+}
+
+/*-----------------------------------------------
+ 16.07.2003 13:37
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > SAL_CALL FrameLoaderFactory::createInstance(const ::rtl::OUString& sLoader)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ return createInstanceWithArguments(sLoader, css::uno::Sequence< css::uno::Any >());
+}
+
+/*-----------------------------------------------
+ 17.07.2003 09:00
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > SAL_CALL FrameLoaderFactory::createInstanceWithArguments(const ::rtl::OUString& sLoader ,
+ const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ ::rtl::OUString sRealLoader = sLoader;
+
+ #ifdef _FILTER_CONFIG_MIGRATION_Q_
+
+ /* -> TODO - HACK
+ check if the given loader name realy exist ...
+ Because our old implementation worked with an internal
+ type name instead of a loader name. For a small migration time
+ we must simulate this old feature :-( */
+
+ if (!m_rCache->hasItem(FilterCache::E_FRAMELOADER, sLoader) && m_rCache->hasItem(FilterCache::E_TYPE, sLoader))
+ {
+ _FILTER_CONFIG_LOG_("FrameLoaderFactory::createInstanceWithArguments() ... simulate old type search functionality!\n");
+
+ css::uno::Sequence< ::rtl::OUString > lTypes(1);
+ lTypes[0] = sLoader;
+
+ css::uno::Sequence< css::beans::NamedValue > lQuery(1);
+ lQuery[0].Name = PROPNAME_TYPES;
+ lQuery[0].Value <<= lTypes;
+
+ css::uno::Reference< css::container::XEnumeration > xSet = createSubSetEnumerationByProperties(lQuery);
+ while(xSet->hasMoreElements())
+ {
+ ::comphelper::SequenceAsHashMap lLoaderProps(xSet->nextElement());
+ if (!(lLoaderProps[PROPNAME_NAME] >>= sRealLoader))
+ continue;
+ }
+
+ // prevent outside code against NoSuchElementException!
+ // But dont implement such defensive strategy for our new create handling :-)
+ if (!m_rCache->hasItem(FilterCache::E_FRAMELOADER, sRealLoader))
+ return css::uno::Reference< css::uno::XInterface>();
+ }
+
+ /* <- HACK */
+
+ #endif // _FILTER_CONFIG_MIGRATION_Q_
+
+ // search loader on cache
+ CacheItem aLoader = m_rCache->getItem(m_eType, sRealLoader);
+
+ // create service instance
+ css::uno::Reference< css::uno::XInterface > xLoader = m_xSMGR->createInstance(sRealLoader);
+
+ // initialize filter
+ css::uno::Reference< css::lang::XInitialization > xInit(xLoader, css::uno::UNO_QUERY);
+ if (xInit.is())
+ {
+ // format: lInitData[0] = seq<PropertyValue>, which contains all configuration properties of this loader
+ // lInitData[1] = lArguments[0]
+ // ...
+ // lInitData[n] = lArguments[n-1]
+ css::uno::Sequence< css::beans::PropertyValue > lConfig;
+ aLoader >> lConfig;
+
+ ::comphelper::SequenceAsVector< css::uno::Any > stlArguments(lArguments);
+ stlArguments.insert(stlArguments.begin(), css::uno::makeAny(lConfig));
+
+ css::uno::Sequence< css::uno::Any > lInitData;
+ stlArguments >> lInitData;
+
+ xInit->initialize(lInitData);
+ }
+
+ return xLoader;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:46
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > SAL_CALL FrameLoaderFactory::getAvailableServiceNames()
+ throw(css::uno::RuntimeException)
+{
+ // must be the same list as ((XNameAccess*)this)->getElementNames() return!
+ return getElementNames();
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+::rtl::OUString FrameLoaderFactory::impl_getImplementationName()
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.filter.config.FrameLoaderFactory");
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > FrameLoaderFactory::impl_getSupportedServiceNames()
+{
+ css::uno::Sequence< ::rtl::OUString > lServiceNames(1);
+ lServiceNames[0] = ::rtl::OUString::createFromAscii("com.sun.star.frame.FrameLoaderFactory");
+ return lServiceNames;
+}
+
+/*-----------------------------------------------
+ 09.07.2003 07:43
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > SAL_CALL FrameLoaderFactory::impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ FrameLoaderFactory* pNew = new FrameLoaderFactory(xSMGR);
+ return css::uno::Reference< css::uno::XInterface >(static_cast< css::lang::XMultiServiceFactory* >(pNew), css::uno::UNO_QUERY);
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/frameloaderfactory.hxx b/filter/source/config/cache/frameloaderfactory.hxx
new file mode 100644
index 000000000000..7741f0011f38
--- /dev/null
+++ b/filter/source/config/cache/frameloaderfactory.hxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __FILTER_CONFIG_FRAMELOADERFACTORY_HXX_
+#define __FILTER_CONFIG_FRAMELOADERFACTORY_HXX_
+
+//_______________________________________________
+// includes
+
+#include "basecontainer.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+//_______________________________________________
+
+/** @short implements the service <type scope="com.sun.star.document">FrameLoaderFactory</type>.
+ */
+class FrameLoaderFactory : public ::cppu::ImplInheritanceHelper1< BaseContainer ,
+ css::lang::XMultiServiceFactory >
+{
+ //-------------------------------------------
+ // native interface
+
+ public:
+
+ //---------------------------------------
+ // ctor/dtor
+
+ /** @short standard ctor to connect this interface wrapper to
+ the global filter cache instance ...
+
+ @param xSMGR
+ reference to the uno service manager, which created this service instance.
+ */
+ FrameLoaderFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+
+ //---------------------------------------
+
+ /** @short standard dtor.
+ */
+ virtual ~FrameLoaderFactory();
+
+ //-------------------------------------------
+ // uno interface
+
+ public:
+
+ //---------------------------------------
+ // XMultiServiceFactory
+
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(const ::rtl::OUString& sLoader)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArguments(const ::rtl::OUString& sLoader ,
+ const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableServiceNames()
+ throw(css::uno::RuntimeException);
+
+ //-------------------------------------------
+ // static uno helper!
+
+ public:
+
+ //---------------------------------------
+
+ /** @short return the uno implementation name of this class.
+
+ @descr Because this information is used at several places
+ (and mostly an object instance of this class is not possible)
+ its implemented as a static function!
+
+ @return The fix uno implementation name of this class.
+ */
+ static ::rtl::OUString impl_getImplementationName();
+
+ //---------------------------------------
+
+ /** @short return the list of supported uno services of this class.
+
+ @descr Because this information is used at several places
+ (and mostly an object instance of this class is not possible)
+ its implemented as a static function!
+
+ @return The fix list of uno services supported by this class.
+ */
+ static css::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames();
+
+ //---------------------------------------
+
+ /** @short return a new intsnace of this class.
+
+ @descr This method is used by the uno service manager, to create
+ a new instance of this service if needed.
+
+ @param xSMGR
+ reference to the uno service manager, which require
+ this new instance. It should be passed to the new object
+ so it can be used internaly to create own needed uno resources.
+
+ @return The new instance of this service as an uno reference.
+ */
+ static css::uno::Reference< css::uno::XInterface > impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_FRAMELOADERFACTORY_HXX_
diff --git a/filter/source/config/cache/lateinitlistener.cxx b/filter/source/config/cache/lateinitlistener.cxx
new file mode 100644
index 000000000000..b9b090025227
--- /dev/null
+++ b/filter/source/config/cache/lateinitlistener.cxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * 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 "lateinitlistener.hxx"
+#include "lateinitthread.hxx"
+
+//_______________________________________________
+// includes
+#include <rtl/ustring.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+/*-----------------------------------------------
+ 14.08.2003 07:35
+-----------------------------------------------*/
+LateInitListener::LateInitListener(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : BaseLock( )
+ , m_xSMGR (xSMGR)
+{
+ // important to do so ...
+ // Otherwhise the temp. reference to ourselves
+ // will kill us at realeasing time!
+ osl_incrementInterlockedCount( &m_refCount );
+
+ m_xBroadcaster = css::uno::Reference< css::document::XEventBroadcaster >(
+ m_xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.GlobalEventBroadcaster")),
+ css::uno::UNO_QUERY);
+
+ m_xBroadcaster->addEventListener(static_cast< css::document::XEventListener* >(this));
+
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+/*-----------------------------------------------
+ 14.08.2003 07:25
+-----------------------------------------------*/
+LateInitListener::~LateInitListener()
+{
+}
+
+/*-----------------------------------------------
+ 14.08.2003 08:45
+-----------------------------------------------*/
+void SAL_CALL LateInitListener::notifyEvent(const css::document::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // wait for events, which indicates finished open of the first document
+ if (
+ (aEvent.EventName.equalsAscii("OnNew") ) ||
+ (aEvent.EventName.equalsAscii("OnLoad"))
+ )
+ {
+ // this thread must be started one times only ...
+ // cancel listener connection before!
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ if ( !m_xBroadcaster.is() )
+ // the beauty of multi-threading ... OnLoad can be notified synchronously or asynchronously. In particular,
+ // SFX-based documents notify it synchronously, database documents do it asynchronously.
+ // Now if multiple documents are opened "at the same time", it is well possible that we get two events from
+ // different threads, where upon the first event, we already remove ourself from m_xBroadcaster, and start
+ // the thread, nonetheless there's also a second notification "in the queue", which will arrive short
+ // thereafter.
+ // In such a case, simply ignore this second event.
+ return;
+
+ m_xBroadcaster->removeEventListener(static_cast< css::document::XEventListener* >(this));
+ m_xBroadcaster.clear();
+
+ aLock.clear();
+ // <- SAFE
+
+ LateInitThread* pThread = new LateInitThread();
+ pThread->create();
+ }
+}
+
+/*-----------------------------------------------
+ 14.08.2003 07:48
+-----------------------------------------------*/
+void SAL_CALL LateInitListener::disposing(const css::lang::EventObject& /* aEvent */ )
+ throw(css::uno::RuntimeException)
+{
+ // ???
+ // Normaly it should never be called. Because we cancel our listener connection
+ // if we got the event about finished open of the first office document.
+ // But if this method was reached, it indicates an office, which was started
+ // (might as remote script container for an external API client) but not realy used.
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ m_xBroadcaster.clear();
+ aLock.clear();
+ // <- SAFE
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/lateinitlistener.hxx b/filter/source/config/cache/lateinitlistener.hxx
new file mode 100644
index 000000000000..0ed1abf1e679
--- /dev/null
+++ b/filter/source/config/cache/lateinitlistener.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __FILTER_CONFIG_LATEINITLISTENER_HXX_
+#define __FILTER_CONFIG_LATEINITLISTENER_HXX_
+
+//_______________________________________________
+// includes
+
+#include "cacheitem.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+//_______________________________________________
+// definitions
+
+//_______________________________________________
+
+/** @short implements a listener, which will update the
+ global filter cache of an office, after zje office
+ startup was finished.
+
+ @descr To perform startup of an office, the filter cache starts
+ with a minimum set of properties only. After the first document
+ was loaded successfully a thread will be started to fill the
+ cache with all other proeprties, so it can work with the whole
+ filter configuration.
+ */
+class LateInitListener : public BaseLock // must be the first one to guarantee right initialized mutex member!
+ , public ::cppu::WeakImplHelper1< css::document::XEventListener >
+{
+ //-------------------------------------------
+ // member
+
+ private:
+
+ /** @short reference to an uno service manager, which can be used
+ to create own needed services. */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ /** @short reference to the global event broadcaster, which is usde to find
+ out, when the first office document was opened successfully. */
+ css::uno::Reference< css::document::XEventBroadcaster > m_xBroadcaster;
+
+ //-------------------------------------------
+ // native interface
+
+ public:
+
+ //---------------------------------------
+ // ctor/dtor
+
+ /** @short initialize new instance of this class.
+
+ @descr It set a reference to the global filter cache singleton,
+ which should be updated here. Further it starts listening
+ on the global event broadcaster to get the information, when
+ loading of the first document was finished.
+
+ @param xSMGR
+ reference to a service manager, which can be used to create
+ own needed uno services.
+ */
+ LateInitListener(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+
+ //---------------------------------------
+
+ /** @short standard dtor.
+ */
+ virtual ~LateInitListener();
+
+ //-------------------------------------------
+ // uno interface
+
+ public:
+
+ //---------------------------------------
+ // document.XEventListener
+
+ virtual void SAL_CALL notifyEvent(const css::document::EventObject& aEvent)
+ throw(css::uno::RuntimeException);
+
+ //---------------------------------------
+ // lang.XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException);
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_LATEINITLISTENER_HXX_
diff --git a/filter/source/config/cache/lateinitthread.cxx b/filter/source/config/cache/lateinitthread.cxx
new file mode 100644
index 000000000000..13432c30ad0f
--- /dev/null
+++ b/filter/source/config/cache/lateinitthread.cxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * 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 "lateinitthread.hxx"
+
+//_______________________________________________
+// includes
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+/*-----------------------------------------------
+ 14.08.2003 09:31
+-----------------------------------------------*/
+LateInitThread::LateInitThread()
+{
+}
+
+/*-----------------------------------------------
+ 14.08.2003 08:42
+-----------------------------------------------*/
+LateInitThread::~LateInitThread()
+{
+}
+
+/*-----------------------------------------------
+ 28.10.2003 09:30
+-----------------------------------------------*/
+void SAL_CALL LateInitThread::run()
+{
+ // sal_True => It indicates using of this method by this thread
+ // The filter cache use this information to show an assertion
+ // for "optimization failure" in case the first calli of loadAll()
+ // was not this thread ...
+
+ // Further please dont catch any exception here.
+ // May be they show the problem of a corrupted filter
+ // configuration, which is handled inside our event loop or desktop.main()!
+
+ ::salhelper::SingletonRef< FilterCache > rCache;
+ rCache->load(FilterCache::E_CONTAINS_ALL, sal_True);
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/lateinitthread.hxx b/filter/source/config/cache/lateinitthread.hxx
new file mode 100644
index 000000000000..c330394d434d
--- /dev/null
+++ b/filter/source/config/cache/lateinitthread.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __FILTER_CONFIG_LATEINITTHREAD_HXX_
+#define __FILTER_CONFIG_LATEINITTHREAD_HXX_
+
+//_______________________________________________
+// includes
+
+#include "filtercache.hxx"
+#include <salhelper/singletonref.hxx>
+#include <osl/thread.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+//_______________________________________________
+// definitions
+
+//_______________________________________________
+
+/** @short implements a thread, which will update the
+ global filter cache of an office, after its
+ startup was finished.
+
+ @descr Its started by a LateInitListener instance ...
+
+ @see LateInitListener
+
+ @attention The filter cache will be blocked during this thrad runs!
+ */
+class LateInitThread : public ::osl::Thread
+{
+ //-------------------------------------------
+ // native interface
+
+ public:
+
+ //---------------------------------------
+ // ctor/dtor
+
+ /** @short initialize new instance of this class.
+ */
+ LateInitThread();
+
+ //---------------------------------------
+
+ /** @short standard dtor.
+ */
+ virtual ~LateInitThread();
+
+ //---------------------------------------
+
+ /** @short thread function.
+ */
+ virtual void SAL_CALL run();
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_LATEINITTHREAD_HXX_
diff --git a/filter/source/config/cache/macros.hxx b/filter/source/config/cache/macros.hxx
new file mode 100644
index 000000000000..485029ead5a8
--- /dev/null
+++ b/filter/source/config/cache/macros.hxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _FILTER_CONFIG_MACROS_HXX_
+#define _FILTER_CONFIG_MACROS_HXX_
+
+//_______________________________________________
+
+#include <rtl/ustring.hxx>
+
+#ifdef _FILTER_CONFIG_FROM_ASCII_
+ #error "who already defined such macro :-("
+#endif
+
+#ifdef _FILTER_CONFIG_TO_ASCII_
+ #error "who already defined such macro :-("
+#endif
+
+/*
+//#define _FILTER_CONFIG_FROM_ASCII_(ASCII_STRING) \
+// ::rtl::OUString::createFromAscii(ASCII_STRING)
+*/
+
+#define _FILTER_CONFIG_FROM_ASCII_(ASCII_STRING) \
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ASCII_STRING))
+
+#define _FILTER_CONFIG_TO_ASCII_(UNICODE_STRING) \
+ ::rtl::OUStringToOString(UNICODE_STRING, RTL_TEXTENCODING_UTF8).getStr()
+
+#define _FILTER_CONFIG_LOG_(TEXT)
+#define _FILTER_CONFIG_LOG_1_(FORMAT, ARG1)
+#define _FILTER_CONFIG_LOG_2_(FORMAT, ARG1, ARG2)
+#define _FILTER_CONFIG_LOG_3_(FORMAT, ARG1, ARG2, ARG3)
+
+/*
+#include <rtl/ustrbuf.hxx>
+
+#include <stdio.h>
+
+//_______________________________________________
+
+ #ifdef _FILTER_CONFIG_LOG_
+ #error "who already defined such macro :-("
+ #endif
+
+ #ifdef _FILTER_CONFIG_LOG_1_
+ #error "who already defined such macro :-("
+ #endif
+
+ #ifdef _FILTER_CONFIG_LOG_2_
+ #error "who already defined such macro :-("
+ #endif
+
+ #ifdef _FILTER_CONFIG_LOG_3_
+ #error "who already defined such macro :-("
+ #endif
+
+ //-------------------------------------------
+ // @short append given text to the log file
+ //
+ // @param TEXT [const char*]
+ // contains the text, which should be logged
+ //
+ #define _FILTER_CONFIG_LOG_(TEXT) \
+ { \
+ FILE* pFile = fopen("filtercache.log", "a");\
+ fprintf(pFile, "%s", TEXT); \
+ fclose(pFile); \
+ }
+
+ //-------------------------------------------
+ // @short append given text to the log file
+ // and supports using one optional argument.
+ //
+ // @descr The syntax of FORMAT and ARG1 follows the
+ // mechanism of e.g. sprintf();
+ //
+ // @param FORMAT [const char*]
+ // specify the format of the log message
+ //
+ // @param ARGn
+ // points to any argument(s), which will be used
+ // inside the FORMAT string to replace place holder(s).
+ //
+ #define _FILTER_CONFIG_LOG_1_(FORMAT, ARG1) \
+ { \
+ FILE* pFile = fopen("filtercache.log", "a");\
+ fprintf(pFile, FORMAT, ARG1); \
+ fclose(pFile); \
+ }
+
+ #define _FILTER_CONFIG_LOG_2_(FORMAT, ARG1, ARG2) \
+ { \
+ FILE* pFile = fopen("filtercache.log", "a");\
+ fprintf(pFile, FORMAT, ARG1, ARG2); \
+ fclose(pFile); \
+ }
+
+ #define _FILTER_CONFIG_LOG_3_(FORMAT, ARG1, ARG2, ARG3) \
+ { \
+ FILE* pFile = fopen("filtercache.log", "a");\
+ fprintf(pFile, FORMAT, ARG1, ARG2, ARG3); \
+ fclose(pFile); \
+ }
+
+#endif // OSL_DEBUG_LEVEL < 2
+*/
+#endif // _FILTER_CONFIG_MACROS_HXX_
diff --git a/filter/source/config/cache/makefile.mk b/filter/source/config/cache/makefile.mk
new file mode 100644
index 000000000000..d94c81e35010
--- /dev/null
+++ b/filter/source/config/cache/makefile.mk
@@ -0,0 +1,87 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = filter
+TARGET = filterconfig
+ENABLE_EXCEPTIONS = TRUE
+VERSION = 1
+USE_DEFFILE = TRUE
+LIBTARGET = NO
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Library -----------------------------------
+
+SHL1TARGET= $(TARGET)$(VERSION)
+
+SLOFILES= \
+ $(SLO)$/configflush.obj \
+ $(SLO)$/basecontainer.obj \
+ $(SLO)$/cacheitem.obj \
+ $(SLO)$/contenthandlerfactory.obj \
+ $(SLO)$/filtercache.obj \
+ $(SLO)$/filterfactory.obj \
+ $(SLO)$/frameloaderfactory.obj \
+ $(SLO)$/lateinitlistener.obj \
+ $(SLO)$/lateinitthread.obj \
+ $(SLO)$/querytokenizer.obj \
+ $(SLO)$/registration.obj \
+ $(SLO)$/typedetection.obj \
+ $(SLO)$/cacheupdatelistener.obj
+
+SHL1OBJS= $(SLOFILES)
+
+SHL1STDLIBS= \
+ $(COMPHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(TOOLSLIB) \
+ $(UNOTOOLSLIB) \
+ $(FWELIB)
+
+DEF1NAME= $(SHL1TARGET)
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN=
+SHL1IMPLIB= i$(SHL1TARGET)
+SHL1VERSIONMAP= $(SOLARENV)/src/component.map
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/filterconfig1.component
+
+$(MISC)/filterconfig1.component .ERRREMOVE : \
+ $(SOLARENV)/bin/createcomponent.xslt filterconfig1.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt filterconfig1.component
diff --git a/filter/source/config/cache/querytokenizer.cxx b/filter/source/config/cache/querytokenizer.cxx
new file mode 100644
index 000000000000..a07a95e37d23
--- /dev/null
+++ b/filter/source/config/cache/querytokenizer.cxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * 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 "querytokenizer.hxx"
+
+//_______________________________________________
+// includes
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+//_______________________________________________
+// definitions
+
+/*-----------------------------------------------
+ 01.08.2003 10:42
+-----------------------------------------------*/
+QueryTokenizer::QueryTokenizer(const ::rtl::OUString& sQuery)
+ : m_bValid(sal_True)
+{
+ sal_Int32 token = 0;
+ while(token != -1)
+ {
+ ::rtl::OUString sToken = sQuery.getToken(0, ':', token);
+ if (sToken.getLength())
+ {
+ sal_Int32 equal = sToken.indexOf('=');
+
+ if (equal == 0)
+ m_bValid = sal_False;
+ OSL_ENSURE(m_bValid, "QueryTokenizer::QueryTokenizer()\nFound non boolean query parameter ... but its key is empty. Will be ignored!\n");
+
+ ::rtl::OUString sKey;
+ ::rtl::OUString sVal;
+
+ sKey = sToken;
+ if (equal > 0)
+ {
+ sKey = sToken.copy(0 , equal );
+ sVal = sToken.copy(equal+1, sToken.getLength()-(equal+1));
+ }
+
+ if (find(sKey) != end())
+ m_bValid = sal_False;
+ OSL_ENSURE(m_bValid, "QueryTokenizer::QueryTokenizer()\nQuery contains same param more then once. Last one wins :-)\n");
+
+ (*this)[sKey] = sVal;
+ }
+ }
+}
+
+/*-----------------------------------------------
+ 01.08.2003 10:28
+-----------------------------------------------*/
+QueryTokenizer::~QueryTokenizer()
+{
+ /*TODO*/
+}
+
+/*-----------------------------------------------
+ 01.08.2003 10:53
+-----------------------------------------------*/
+sal_Bool QueryTokenizer::valid() const
+{
+ return m_bValid;
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/querytokenizer.hxx b/filter/source/config/cache/querytokenizer.hxx
new file mode 100644
index 000000000000..0823e49f5616
--- /dev/null
+++ b/filter/source/config/cache/querytokenizer.hxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _FILTER_CONFIG_QUERYTOKENIZER_HXX_
+#define _FILTER_CONFIG_QUERYTOKENIZER_HXX_
+
+//_______________________________________________
+// includes
+
+#include <hash_map>
+#include <rtl/ustring.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+//_______________________________________________
+// definitions
+
+/** @short It can be used to split any query string (which can be used at the
+ related interface <type scope="com::sun::star::container">XContainerQuery</type>)
+ into its different tokens using a fix schema.
+
+ @descr All queries implemented of the services
+ <ul>
+ <li><type scope="com::sun::star::document">TypeDetection</type></li>
+ <li><type scope="com::sun::star::document">FilterFactory</type></li>
+ <li><type scope="com::sun::star::document">ExtendedTypeDetectionFactory</type></li>
+ <li><type scope="com::sun::star::frame">FrameLoaderFactory</type></li>
+ <li><type scope="com::sun::star::frame">ContentHandlerFactory</type></li>
+ </ul>
+ uses this schema.
+
+ @attention This class is not threadsafe implemented. Because its not neccessary.
+ But you have to make shure, that ist not used as such :-)
+ */
+class QueryTokenizer : public ::std::hash_map< ::rtl::OUString ,
+ ::rtl::OUString ,
+ ::rtl::OUStringHash ,
+ ::std::equal_to< ::rtl::OUString > >
+{
+ //-------------------------------------------
+ // member
+
+ private:
+
+ /** @short Because the given query can contain errors,
+ it should be checked outside.
+
+ TODO May its a good idea to describe the real problem
+ more detailed ...
+ */
+ sal_Bool m_bValid;
+
+ //-------------------------------------------
+ // interface
+
+ public:
+
+ /** @short create a new tokenizer instance with a
+ a new query.
+
+ @descr The given query is immidiatly analyzed
+ and seperated into its token, which can
+ be access by some specialized method later.
+
+ @param sQuery
+ the query string.
+ */
+ QueryTokenizer(const ::rtl::OUString& sQuery);
+
+ //---------------------------------------
+
+ /** @short destruct an instance of this class.
+ */
+ virtual ~QueryTokenizer();
+
+ //---------------------------------------
+
+ /** @short can be used to check if analyzing of given query
+ was successfully or not.
+ */
+ virtual sal_Bool valid() const;
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // _FILTER_CONFIG_QUERYTOKENIZER_HXX_
diff --git a/filter/source/config/cache/registration.cxx b/filter/source/config/cache/registration.cxx
new file mode 100644
index 000000000000..2be110871ee1
--- /dev/null
+++ b/filter/source/config/cache/registration.cxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * 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 "registration.hxx"
+
+//_______________________________________________
+// includes
+
+#ifdef _FILTER_CONFIG_CONSTANT_HXX_
+# error "Already included constant.hxx"
+#else
+# define PROPNAME_IMPL_DECL
+# include "constant.hxx"
+#endif
+#include <stdio.h>
+#include "typedetection.hxx"
+#include "filterfactory.hxx"
+#include "contenthandlerfactory.hxx"
+#include "frameloaderfactory.hxx"
+#include "configflush.hxx"
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+rtl::OUString pFilterStrings[19];
+static bool bInitialized = false;
+
+static void InitConstants()
+{
+ if (!bInitialized)
+ {
+ ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
+ if (!bInitialized)
+ {
+ PROPNAME_NAME;
+ PROPNAME_UINAME;
+ PROPNAME_UINAMES;
+ PROPNAME_PREFERRED;
+ PROPNAME_PREFERREDFILTER;
+ PROPNAME_DETECTSERVICE;
+ PROPNAME_MEDIATYPE;
+ PROPNAME_CLIPBOARDFORMAT;
+ PROPNAME_URLPATTERN;
+ PROPNAME_EXTENSIONS;
+ PROPNAME_TYPE;
+ PROPNAME_DOCUMENTSERVICE;
+ PROPNAME_FILTERSERVICE;
+ PROPNAME_UICOMPONENT;
+ PROPNAME_FLAGS;
+ PROPNAME_USERDATA;
+ PROPNAME_TEMPLATENAME;
+ PROPNAME_FILEFORMATVERSION;
+ PROPNAME_TYPES;
+ bInitialized = true;
+ }
+ }
+}
+
+// extern "C" component_getImplementationEnvironment()
+_COMPHELPER_COMPONENT_GETIMPLEMENTATIONENVIRONMENT
+
+// extern "C" component_getFactory()
+_COMPHELPER_COMPONENT_GETFACTORY
+(
+ { InitConstants(); },
+ _COMPHELPER_MULTIINSTANCEFACTORY( TypeDetection::impl_getImplementationName() ,
+ TypeDetection::impl_getSupportedServiceNames(),
+ TypeDetection::impl_createInstance )
+
+ _COMPHELPER_MULTIINSTANCEFACTORY( FilterFactory::impl_getImplementationName() ,
+ FilterFactory::impl_getSupportedServiceNames(),
+ FilterFactory::impl_createInstance )
+
+ _COMPHELPER_MULTIINSTANCEFACTORY( ContentHandlerFactory::impl_getImplementationName() ,
+ ContentHandlerFactory::impl_getSupportedServiceNames(),
+ ContentHandlerFactory::impl_createInstance )
+
+ _COMPHELPER_MULTIINSTANCEFACTORY( FrameLoaderFactory::impl_getImplementationName() ,
+ FrameLoaderFactory::impl_getSupportedServiceNames(),
+ FrameLoaderFactory::impl_createInstance )
+
+ _COMPHELPER_ONEINSTANCEFACTORY( ConfigFlush::impl_getImplementationName() ,
+ ConfigFlush::impl_getSupportedServiceNames(),
+ ConfigFlush::impl_createInstance )
+)
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/registration.hxx b/filter/source/config/cache/registration.hxx
new file mode 100644
index 000000000000..d664cc365abb
--- /dev/null
+++ b/filter/source/config/cache/registration.hxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __COMPHELPER_REGISTRATION_HXX_
+#define __COMPHELPER_REGISTRATION_HXX_
+
+//_______________________________________________
+// includes
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/factory.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace comphelper{
+
+//_______________________________________________
+// declaration
+
+//_______________________________________________
+
+/** TODO doc
+ */
+#define _COMPHELPER_COMPONENT_GETIMPLEMENTATIONENVIRONMENT \
+ extern "C" void SAL_CALL component_getImplementationEnvironment(const sal_Char** ppEnvironmentTypeName, \
+ uno_Environment** /* ppEnvironment */ ) \
+ { \
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; \
+ }
+
+//_______________________________________________
+
+/** TODO doc
+ */
+#define _COMPHELPER_MULTIINSTANCEFACTORY(IMPLEMENTATIONNAME, SERVICENAMES, FACTORYMETHOD) \
+ if (IMPLEMENTATIONNAME == sImplName) \
+ xFactory = ::cppu::createSingleFactory(xSMGR , \
+ IMPLEMENTATIONNAME, \
+ FACTORYMETHOD , \
+ SERVICENAMES );
+
+//_______________________________________________
+
+/** TODO doc
+ */
+#define _COMPHELPER_ONEINSTANCEFACTORY(IMPLEMENTATIONNAME, SERVICENAMES, FACTORYMETHOD) \
+ if (IMPLEMENTATIONNAME == sImplName) \
+ xFactory = ::cppu::createOneInstanceFactory(xSMGR , \
+ IMPLEMENTATIONNAME, \
+ FACTORYMETHOD , \
+ SERVICENAMES );
+
+//_______________________________________________
+
+/** TODO doc
+ */
+#define _COMPHELPER_COMPONENT_GETFACTORY(STATIC_INIT,FACTORYLIST) \
+ extern "C" void* SAL_CALL component_getFactory(const sal_Char* pImplementationName, \
+ void* pServiceManager , \
+ void* /* pRegistryKey */ ) \
+ { \
+ if ( \
+ (!pImplementationName) || \
+ (!pServiceManager ) \
+ ) \
+ return NULL; \
+ \
+ STATIC_INIT \
+ \
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = reinterpret_cast< css::lang::XMultiServiceFactory* >(pServiceManager); \
+ css::uno::Reference< css::lang::XSingleServiceFactory > xFactory ; \
+ rtl::OUString sImplName = ::rtl::OUString::createFromAscii(pImplementationName); \
+ \
+ /* This parameter will expand to: */ \
+ /* _COMPHELPER_xxxFACTORY(1) */ \
+ /* else */ \
+ /* ... */ \
+ /* else */ \
+ /* _COMPHELPER_xxxFACTORY(n) */ \
+ FACTORYLIST \
+ \
+ /* And if one of these checks was successfully => xFactory was set! */ \
+ if (xFactory.is()) \
+ { \
+ xFactory->acquire(); \
+ return xFactory.get(); \
+ } \
+ \
+ return NULL; \
+ }
+
+} // namespace comphelper
+
+#endif // #ifndef __COMPHELPER_REGISTRATION_HXX_
diff --git a/filter/source/config/cache/typedetection.cxx b/filter/source/config/cache/typedetection.cxx
new file mode 100644
index 000000000000..4fe9a1df64e6
--- /dev/null
+++ b/filter/source/config/cache/typedetection.cxx
@@ -0,0 +1,1257 @@
+/*************************************************************************
+ *
+ * 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 "typedetection.hxx"
+#include "constant.hxx"
+
+//_______________________________________________
+// includes
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+#ifndef _COM_SUN_STAR_IO_XINPUSTREAM_HPP_
+#include <com/sun/star/io/XInputStream.hpp>
+#endif
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <tools/wldcrd.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <framework/interaction.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/localfilehelper.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+// Use this switch to change the behaviour of preselection DocumentService ... (see using for further informations)
+#define IGNORE_NON_URLMATCHING_TYPES_FOR_PRESELECTION_DOCUMENTSERVICE
+
+// enable/disable special handling for CSV/TXT problem
+#define WORKAROUND_CSV_TXT_BUG_i60158
+
+/*-----------------------------------------------
+ 03.07.2003 11:25
+-----------------------------------------------*/
+TypeDetection::TypeDetection(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ BaseContainer::init(xSMGR ,
+ TypeDetection::impl_getImplementationName() ,
+ TypeDetection::impl_getSupportedServiceNames(),
+ FilterCache::E_TYPE );
+}
+
+/*-----------------------------------------------
+ 03.07.2003 10:36
+-----------------------------------------------*/
+TypeDetection::~TypeDetection()
+{
+}
+
+/*-----------------------------------------------
+ 03.11.2003 08:43
+-----------------------------------------------*/
+::rtl::OUString SAL_CALL TypeDetection::queryTypeByURL(const ::rtl::OUString& sURL)
+ throw (css::uno::RuntimeException)
+{
+ ::rtl::OUString sType;
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ css::util::URL aURL;
+ aURL.Complete = sURL;
+ css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICE_URLTRANSFORMER), css::uno::UNO_QUERY);
+ xParser->parseStrict(aURL);
+
+ // set std types as minimum requirement first!
+ // Only in case no type was found for given URL,
+ // use optional types too ...
+ FlatDetection lFlatTypes;
+ m_rCache->detectFlatForURL(aURL, lFlatTypes);
+
+ if (
+ (lFlatTypes.size() < 1 ) &&
+ (!m_rCache->isFillState(FilterCache::E_CONTAINS_TYPES))
+ )
+ {
+ m_rCache->load(FilterCache::E_CONTAINS_TYPES);
+ m_rCache->detectFlatForURL(aURL, lFlatTypes);
+ }
+
+ // first item is guaranteed as "preferred" one!
+ if (lFlatTypes.size() > 0)
+ {
+ const FlatDetectionInfo& aMatch = *(lFlatTypes.begin());
+ sType = aMatch.sType;
+ }
+
+ return sType;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 31.10.2003 09:36
+-----------------------------------------------*/
+::rtl::OUString SAL_CALL TypeDetection::queryTypeByDescriptor(css::uno::Sequence< css::beans::PropertyValue >& lDescriptor,
+ sal_Bool bAllowDeep )
+ throw (css::uno::RuntimeException)
+{
+ // make the descriptor more useable :-)
+ ::comphelper::MediaDescriptor stlDescriptor(lDescriptor);
+
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ //*******************************************
+ // parse given URL to split it into e.g. main and jump marks ...
+ ::rtl::OUString sURL = stlDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_URL(), ::rtl::OUString());
+
+#if OSL_DEBUG_LEVEL > 0
+ if (stlDescriptor.find(::rtl::OUString::createFromAscii("FileName")) != stlDescriptor.end())
+ OSL_ENSURE(sal_False, "Detect using of deprecated and already unsupported MediaDescriptor property \"FileName\"!");
+#endif
+
+ css::util::URL aURL;
+ aURL.Complete = sURL;
+ css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICE_URLTRANSFORMER), css::uno::UNO_QUERY);
+ xParser->parseStrict(aURL);
+
+ //*******************************************
+ // preselected filter, type or document service?
+ // use it as first "flat" detected type later!
+ FlatDetection lFlatTypes;
+ impl_getPreselection(aURL, stlDescriptor, lFlatTypes);
+
+ //*******************************************
+ // get all types, which match to the given descriptor
+ // That can be true by: extensions/url pattern/mime type etcpp.
+ m_rCache->detectFlatForURL(aURL, lFlatTypes);
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ ::rtl::OUString sType ;
+ ::rtl::OUString sLastChance;
+
+ try
+ {
+ //*******************************************
+ // verify every flat detected (or preselected!) type
+ // by calling its registered deep detection service.
+ // But break this loop if a type match to the given descriptor
+ // by an URL pattern(!) or if deep detection isnt allowed from
+ // outside (bAllowDeep=FALSE) or break the whole detection by
+ // throwing an exception if creation of the might needed input
+ // stream failed by e.g. an IO exception ...
+ OUStringList lUsedDetectors;
+ if (lFlatTypes.size()>0)
+ sType = impl_detectTypeFlatAndDeep(stlDescriptor, lFlatTypes, bAllowDeep, lUsedDetectors, sLastChance);
+
+ //*******************************************
+ // if no flat detected (nor preselected!) type could be
+ // verified and no error occured during creation of
+ // the might needed input stream, start detection
+ // which uses all registered deep detection services.
+ if (
+ (!sType.getLength()) &&
+ (bAllowDeep )
+ )
+ {
+ sType = impl_detectTypeDeepOnly(stlDescriptor, lUsedDetectors);
+ }
+
+ //*******************************************
+ // flat detection failed
+ // pure deep detection failed
+ // => ask might existing InteractionHandler
+ // means: ask user for it's decision
+ if (!sType.getLength())
+ sType = impl_askUserForTypeAndFilterIfAllowed(stlDescriptor);
+
+ //*******************************************
+ // no real detected type - but a might valid one.
+ // update descriptor and set last chance for return.
+ if (!sType.getLength() && sLastChance.getLength())
+ {
+ OSL_ENSURE(sal_False, "set first flat detected type without a registered deep detection service as \"last chance\" ... nevertheless some other deep detections said \"NO\". I TRY IT!");
+ sType = sLastChance;
+ }
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { sType = ::rtl::OUString(); }
+
+ //*******************************************
+ // adapt media descriptor, so it contains the right values
+ // for type/filter name/document service/ etcpp.
+ impl_checkResultsAndAddBestFilter(stlDescriptor, sType); // Attention: sType is used as IN/OUT param here and will might be changed inside this method !!!
+ impl_validateAndSetTypeOnDescriptor(stlDescriptor, sType);
+
+ stlDescriptor >> lDescriptor;
+ return sType;
+}
+
+/*-----------------------------------------------
+ 03.07.2003 10:36
+-----------------------------------------------*/
+void TypeDetection::impl_checkResultsAndAddBestFilter(::comphelper::MediaDescriptor& rDescriptor,
+ ::rtl::OUString& sType )
+{
+ // a)
+ // Dont overwrite a might preselected filter!
+ ::rtl::OUString sFilter = rDescriptor.getUnpackedValueOrDefault(
+ ::comphelper::MediaDescriptor::PROP_FILTERNAME(),
+ ::rtl::OUString());
+ if (sFilter.getLength())
+ return;
+
+ // b)
+ // check a preselected document service too.
+ // Then we have to search a suitable filter witin this module.
+ ::rtl::OUString sDocumentService = rDescriptor.getUnpackedValueOrDefault(
+ ::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE(),
+ ::rtl::OUString());
+ if (sDocumentService.getLength())
+ {
+ try
+ {
+ ::rtl::OUString sRealType = sType;
+
+ #ifdef WORKAROUND_CSV_TXT_BUG_i60158
+ // Workaround for #i60158#
+ // We do not have right filter for Text_Ascii in calc nor a suitable filter for CSV in writer.
+ // So we must overrule our detection and make the right things. Normaly we should have
+ // one type TextAscii and two filters registered for these one type.
+ // But then we loose automatic opening of CSV files in calc instead of opening these files
+ // inside writer.
+ if (
+ (sDocumentService.equalsAscii("com.sun.star.sheet.SpreadsheetDocument")) &&
+ (
+ (sRealType.equalsAscii("writer_Text" )) ||
+ (sRealType.equalsAscii("writer_Text_encoded"))
+ )
+ )
+ {
+ sRealType = ::rtl::OUString::createFromAscii("calc_Text_txt_csv_StarCalc");
+ }
+ else
+ if (
+ (sDocumentService.equalsAscii("com.sun.star.text.TextDocument")) &&
+ (sRealType.equalsAscii("calc_Text_txt_csv_StarCalc" ))
+ )
+ {
+ sRealType = ::rtl::OUString::createFromAscii("writer_Text");
+ }
+ #endif // WORKAROUND_CSV_TXT_BUG_i60158
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // Attention: For executing next lines of code, We must be shure that
+ // all filters already loaded :-(
+ // That can disturb our "load on demand feature". But we have no other chance!
+ m_rCache->load(FilterCache::E_CONTAINS_FILTERS);
+
+ CacheItem lIProps;
+ lIProps[PROPNAME_DOCUMENTSERVICE] <<= sDocumentService;
+ lIProps[PROPNAME_TYPE ] <<= sRealType;
+ OUStringList lFilters = m_rCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps);
+
+ aLock.clear();
+ // <- SAFE
+
+ for ( OUStringList::const_iterator pIt = lFilters.begin();
+ pIt != lFilters.end() && sFilter.getLength() == 0 ;
+ ++pIt )
+ {
+ // SAFE ->
+ aLock.reset();
+ try
+ {
+ CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, *pIt);
+ sal_Int32 nFlags = 0;
+ aFilter[PROPNAME_FLAGS] >>= nFlags;
+
+ if ((nFlags & FLAGVAL_IMPORT) == FLAGVAL_IMPORT)
+ sFilter = *pIt;
+ }
+ catch(const css::uno::Exception&) {}
+ aLock.clear();
+ // <- SAFE
+ }
+
+ if (sFilter.getLength() > 0)
+ {
+ rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME() ] <<= sRealType;
+ rDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
+ sType = sRealType;
+ return;
+ }
+ }
+ catch(const css::uno::Exception&)
+ {}
+ }
+
+ // c)
+ // We can use the preferred filter for the specified type.
+ // Such preferred filter points:
+ // - to the default filter of the preferred application
+ // - or to any other filter if no preferred filter was set.
+ // Note: It's an optimization only!
+ // It's not guaranteed, that such preferred filter exists.
+ sFilter = ::rtl::OUString();
+ try
+ {
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ CacheItem aType = m_rCache->getItem(FilterCache::E_TYPE, sType);
+ aType[PROPNAME_PREFERREDFILTER] >>= sFilter;
+ CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
+
+ aLock.clear();
+ // <- SAFE
+
+ // no exception => found valid type and filter => set it on the given descriptor
+ rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME() ] <<= sType ;
+ rDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
+ return;
+ }
+ catch(const css::uno::Exception&)
+ {}
+
+ // d)
+ // Search for any import(!) filter, which is registered for this type.
+ sFilter = ::rtl::OUString();
+ try
+ {
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // Attention: For executing next lines of code, We must be shure that
+ // all filters already loaded :-(
+ // That can disturb our "load on demand feature". But we have no other chance!
+ m_rCache->load(FilterCache::E_CONTAINS_FILTERS);
+
+ CacheItem lIProps;
+ lIProps[PROPNAME_TYPE] <<= sType;
+ OUStringList lFilters = m_rCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps);
+
+ aLock.clear();
+ // <- SAFE
+
+ OUStringList::const_iterator pIt;
+ for ( pIt = lFilters.begin();
+ pIt != lFilters.end() ;
+ ++pIt )
+ {
+ sFilter = *pIt;
+
+ // SAFE ->
+ aLock.reset();
+ try
+ {
+ CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
+ sal_Int32 nFlags = 0;
+ aFilter[PROPNAME_FLAGS] >>= nFlags;
+
+ if ((nFlags & FLAGVAL_IMPORT) == FLAGVAL_IMPORT)
+ break;
+ }
+ catch(const css::uno::Exception&)
+ { continue; }
+ aLock.clear();
+ // <- SAFE
+
+ sFilter = ::rtl::OUString();
+ }
+
+ if (sFilter.getLength())
+ {
+ rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME() ] <<= sType ;
+ rDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
+ return;
+ }
+ }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+/*-----------------------------------------------
+ 14.11.2003 12:06
+-----------------------------------------------*/
+sal_Bool TypeDetection::impl_getPreselectionForType(const ::rtl::OUString& sPreSelType,
+ const css::util::URL& aParsedURL ,
+ FlatDetection& rFlatTypes )
+{
+ // Can be used to supress execution of some parts of this method
+ // if its already clear that detected type is valid or not.
+ // Its neccessary to use shared code at the end, which update
+ // all return parameters constistency!
+ sal_Bool bBreakDetection = sal_False;
+
+ // Further we must know if it matches by pattern
+ // Every flat detected type by pattern wont be detected deep!
+ sal_Bool bMatchByPattern = sal_False;
+
+ // And we must know if a preselection must be preferred, because
+ // it matches by it's extension too.
+ sal_Bool bMatchByExtension = sal_False;
+
+ // If we e.g. collect all filters of a factory (be a forced factory preselection)
+ // we should preferr all filters of this factory, where the type match the given URL.
+ // All other types (which sorrespond to filters of the same factory - but dont match
+ // the URL) should be "used later" for detection and sorted at the end of our return vector
+ // rFlatTypes!
+ // => bPreferredPreselection = (matchByExtension || matchByURLPattern)
+ sal_Bool bPreferredPreselection = sal_False;
+
+ // validate type
+ ::rtl::OUString sType(sPreSelType);
+ CacheItem aType;
+ try
+ {
+ // SAFE -> --------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ aType = m_rCache->getItem(FilterCache::E_TYPE, sType);
+ aLock.clear();
+ // <- SAFE --------------------------
+ }
+ catch(const css::container::NoSuchElementException&)
+ {
+ sType = ::rtl::OUString();
+ bBreakDetection = sal_True;
+ }
+
+ if (!bBreakDetection)
+ {
+ // We cant check a preselected type for a given stream!
+ // So we must believe, that it can work ...
+ if (aParsedURL.Complete.equalsAsciiL("private:stream", 14))
+ bBreakDetection = sal_True;
+ }
+
+ if (!bBreakDetection)
+ {
+ // extract extension from URL .. to check it case-insensitive !
+ INetURLObject aParser (aParsedURL.Main);
+ ::rtl::OUString sExtension = aParser.getExtension(INetURLObject::LAST_SEGMENT ,
+ sal_True ,
+ INetURLObject::DECODE_WITH_CHARSET);
+ sExtension = sExtension.toAsciiLowerCase();
+
+ // otherwhise we must know, if it matches to the given URL realy.
+ // especialy if it matches by its extension or pattern registration.
+ OUStringList lExtensions(aType[PROPNAME_EXTENSIONS]);
+ OUStringList lURLPattern(aType[PROPNAME_URLPATTERN]);
+
+ for (OUStringList::const_iterator pIt = lExtensions.begin();
+ pIt != lExtensions.end() ;
+ ++pIt )
+ {
+ ::rtl::OUString sCheckExtension(pIt->toAsciiLowerCase());
+ if (sCheckExtension.equals(sExtension))
+ {
+ bBreakDetection = sal_True;
+ bMatchByExtension = sal_True;
+ bPreferredPreselection = sal_True;
+ break;
+ }
+ }
+
+ if (!bBreakDetection)
+ {
+ for (OUStringList::const_iterator pIt = lURLPattern.begin();
+ pIt != lURLPattern.end() ;
+ ++pIt )
+ {
+ WildCard aCheck(*pIt);
+ if (aCheck.Matches(aParsedURL.Main))
+ {
+ bBreakDetection = sal_True;
+ bMatchByPattern = sal_True;
+ bPreferredPreselection = sal_True;
+ break;
+ }
+ }
+ }
+
+ /*
+ Comment ... why the following line of code should be comened out .-)
+
+ This type does not seem to fit the requirements
+ But its an existing and well known type.
+ At least - [because may be the extension was missing :-( ]
+ we should try to detect this type deep ...
+ So we accept it here :-)
+
+ if (!bBreakDetection)
+ sType = ::rtl::OUString();
+ */
+ }
+
+ // if its a valid type - set it on all return values!
+ if (sType.getLength())
+ {
+ FlatDetectionInfo aInfo;
+ aInfo.sType = sType;
+ aInfo.bMatchByExtension = bMatchByExtension;
+ aInfo.bMatchByPattern = bMatchByPattern;
+ aInfo.bPreselectedAsType = sal_True;
+
+ if (bPreferredPreselection)
+ rFlatTypes.push_front(aInfo);
+ else
+ rFlatTypes.push_back(aInfo);
+
+ return sal_True;
+ }
+
+ // not valid!
+ return sal_False;
+}
+
+/*-----------------------------------------------
+ 14.11.2003 12:09
+-----------------------------------------------*/
+sal_Bool TypeDetection::impl_getPreselectionForFilter(const ::rtl::OUString& sPreSelFilter,
+ const css::util::URL& aParsedURL ,
+ FlatDetection& rFlatTypes )
+{
+ // Can be used to supress execution of some parts of this method
+ // if its already clear that detected filter is valid or not.
+ // Its neccessary to use shared code at the end, which update
+ // all return parameters constistency!
+ sal_Bool bBreakDetection = sal_False;
+
+ // validate filter
+ ::rtl::OUString sFilter(sPreSelFilter);
+ CacheItem aFilter;
+ try
+ {
+ // SAFE -> --------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
+ aLock.clear();
+ // <- SAFE --------------------------
+ }
+ catch(const css::container::NoSuchElementException&)
+ {
+ sFilter = ::rtl::OUString();
+ bBreakDetection = sal_True;
+ }
+
+ if (!bBreakDetection)
+ {
+ // get its type and check if it matches the given URL
+ ::rtl::OUString sType;
+ aFilter[PROPNAME_TYPE] >>= sType;
+
+ bBreakDetection = impl_getPreselectionForType(sType, aParsedURL, rFlatTypes);
+
+ // not a valid type? -> not a valid filter!
+ if (!bBreakDetection)
+ sFilter = ::rtl::OUString();
+ }
+
+ // We have to mark all retrieved preselection items as "preselected by filter"!
+ FlatDetection::iterator pIt;
+ for ( pIt = rFlatTypes.begin();
+ pIt != rFlatTypes.end() ;
+ ++pIt )
+ {
+ FlatDetectionInfo& rInfo = *pIt;
+ rInfo.bPreselectedAsType = sal_False;
+ rInfo.bPreselectedByFilter = sal_True;
+ }
+
+ if (sFilter.getLength())
+ return sal_True;
+ else
+ return sal_False;
+}
+
+/*-----------------------------------------------
+ 14.11.2003 12:11
+-----------------------------------------------*/
+sal_Bool TypeDetection::impl_getPreselectionForDocumentService(const ::rtl::OUString& sPreSelDocumentService,
+ const css::util::URL& aParsedURL ,
+ FlatDetection& rFlatTypes )
+{
+ // get all filters, which match to this doc service
+ OUStringList lFilters;
+ try
+ {
+ // SAFE -> --------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // Attention: For executing next lines of code, We must be shure that
+ // all filters already loaded :-(
+ // That can disturb our "load on demand feature". But we have no other chance!
+ m_rCache->load(FilterCache::E_CONTAINS_FILTERS);
+
+ CacheItem lIProps;
+ lIProps[PROPNAME_DOCUMENTSERVICE] <<= sPreSelDocumentService;
+ lFilters = m_rCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps);
+
+ aLock.clear();
+ // <- SAFE --------------------------
+ }
+ catch(const css::container::NoSuchElementException&)
+ {
+ lFilters.clear();
+ }
+
+ // step over all filters, and check if its registered type
+ // match the given URL.
+ // But use temp. list of "preselected types" instead of incoming rFlatTypes list!
+ // The reason behind: we must filter the getted results. And copying of stl entries
+ // is an easier job then removing it .-)
+ FlatDetection lPreselections;
+ for (OUStringList::const_iterator pFilter = lFilters.begin();
+ pFilter != lFilters.end() ;
+ ++pFilter )
+ {
+ const ::rtl::OUString sFilter = *pFilter;
+ impl_getPreselectionForFilter(sFilter, aParsedURL, lPreselections);
+ }
+
+ // We have to mark all retrieved preselection items as "preselected by document service".
+ // Further we must ignore all preselected items, which does not match the URL!
+ FlatDetection::iterator pIt;
+ for ( pIt = lPreselections.begin();
+ pIt != lPreselections.end() ;
+ ++pIt )
+ {
+ FlatDetectionInfo& rInfo = *pIt;
+
+ /*
+ #i60158#
+ Preselection by DocumentService ...
+ How many filters (and corresponding types) must be checked ?
+ All or only the list of filters/types, which match to the given URL too ?
+ There is no final decision about this currently. So we make it "configurable" .-)
+ */
+ #ifdef IGNORE_NON_URLMATCHING_TYPES_FOR_PRESELECTION_DOCUMENTSERVICE
+ if (
+ (!rInfo.bMatchByExtension) &&
+ (!rInfo.bMatchByPattern )
+ )
+ continue;
+ #endif
+
+ rInfo.bPreselectedAsType = sal_False;
+ rInfo.bPreselectedByFilter = sal_False;
+ rInfo.bPreselectedByDocumentService = sal_True ;
+ rFlatTypes.push_back(rInfo);
+ }
+
+ return sal_True;
+}
+
+/*-----------------------------------------------
+ 14.11.2003 12:21
+-----------------------------------------------*/
+void TypeDetection::impl_getPreselection(const css::util::URL& aParsedURL ,
+ ::comphelper::MediaDescriptor& rDescriptor,
+ FlatDetection& rFlatTypes )
+{
+ // done to be shure, that only valid results leave this function!
+ rFlatTypes.clear();
+
+ /* #i55122#
+ Sometimes we must detect files without or with real unknown extensions.
+ If it does not work /which can happen of course .-)/, the user tried to preselect
+ the right format. But some special dialogs (e.g. "Insert->Sheet From File")
+ add it's own preselection too.
+ So we have a combination of preselected values ...
+
+ The we should preferr the most important one - set by the user.
+ And the user normaly preselects a filter or type. The preslected
+ document service cames from the dialog.
+
+ Further it doesnt matter if the user preselected a filter or a document service.
+ A filter selection is always more explicit then a document service selection.
+ So it must be pereferred. An order between type and filter selection cant be discussed .-)
+ */
+
+ ::rtl::OUString sSelectedType = rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString());
+ if (sSelectedType.getLength())
+ impl_getPreselectionForType(sSelectedType, aParsedURL, rFlatTypes);
+
+ ::rtl::OUString sSelectedFilter = rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString());
+ if (sSelectedFilter.getLength())
+ impl_getPreselectionForFilter(sSelectedFilter, aParsedURL, rFlatTypes);
+
+ ::rtl::OUString sSelectedDoc = rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE(), ::rtl::OUString());
+ if (sSelectedDoc.getLength())
+ impl_getPreselectionForDocumentService(sSelectedDoc, aParsedURL, rFlatTypes);
+}
+
+/*-----------------------------------------------
+ 03.11.2003 09:17
+-----------------------------------------------*/
+::rtl::OUString TypeDetection::impl_detectTypeFlatAndDeep( ::comphelper::MediaDescriptor& rDescriptor ,
+ const FlatDetection& lFlatTypes ,
+ sal_Bool bAllowDeep ,
+ OUStringList& rUsedDetectors,
+ ::rtl::OUString& rLastChance )
+{
+ // reset it everytimes, so the outside code can distinguish between
+ // a set and a not set value.
+ rLastChance = ::rtl::OUString();
+ rUsedDetectors.clear();
+
+ // step over all possible types for this URL.
+ // solutions:
+ // a) no types => no detection
+ // b) deep detection not allowed => return first valid type of list (because its the preferred or the first valid one)
+ // or(!) match by URLPattern => in such case a deep detection will be supressed!
+ // c) type has no detect service => safe the first occured type without a detect service
+ // as "last chance"(!). It will be used outside of this method
+ // if no further type could be detected.
+ // It must be the first one, because it can be a preferred type.
+ // Our types list was sorted by such criteria!
+ // d) detect service return a valid result => return its decision
+ // e) detect service return an invalid result
+ // or any needed information could not be
+ // getted from the cache => ignore it, and continue with search
+
+ for (FlatDetection::const_iterator pFlatIt = lFlatTypes.begin();
+ pFlatIt != lFlatTypes.end() ;
+ ++pFlatIt )
+ {
+ const FlatDetectionInfo& aFlatTypeInfo = *pFlatIt;
+ ::rtl::OUString sFlatType = aFlatTypeInfo.sType;
+
+ if (!impl_validateAndSetTypeOnDescriptor(rDescriptor, sFlatType))
+ continue;
+
+ // b)
+ if (
+ (!bAllowDeep ) ||
+ (aFlatTypeInfo.bMatchByPattern)
+ )
+ {
+ return sFlatType;
+ }
+
+ try
+ {
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ CacheItem aType = m_rCache->getItem(FilterCache::E_TYPE, sFlatType);
+ aLock.clear();
+
+ ::rtl::OUString sDetectService;
+ aType[PROPNAME_DETECTSERVICE] >>= sDetectService;
+
+ // c)
+ if (!sDetectService.getLength())
+ {
+ // accept or not accept flat types without deep detection: that's the question :-)
+ // May be there exists some states, where we have to use our LastChance feature instead
+ // of using the flat type directly.
+ // Here the list of task ID's, which wasrelated to these lines of code:
+ // #i47159#, #i43404#, #i46494#
+
+ // a flat detected type without the chance for a deep detection ... but preselected by the user
+ // explicitly (means preselected as type or filter ... not as documentservice!)
+ // should be accepted. So the user can overrule our detection.
+ if (
+ (aFlatTypeInfo.bPreselectedAsType ) ||
+ (aFlatTypeInfo.bPreselectedByFilter)
+ )
+ return sFlatType;
+
+ // flat detected types without any registered deep detection service and not
+ // preselected by the user can be used as LAST CHANCE in case no other type could
+ // be detected. Of course only the first type without deep detector can be used.
+ // Further ones has to be ignored.
+ if (rLastChance.getLength() < 1)
+ rLastChance = sFlatType;
+
+ continue;
+ }
+
+ // dont forget to add every real asked deep detection service here.
+ // Such detectors will be ignored if may be "impl_detectTypeDeepOnly()"
+ // must be called later!
+ rUsedDetectors.push_back(sDetectService);
+ ::rtl::OUString sDeepType = impl_askDetectService(sDetectService, rDescriptor);
+
+ // d)
+ if (sDeepType.getLength())
+ return sDeepType;
+ }
+ catch(const css::container::NoSuchElementException&)
+ {}
+ // e)
+ }
+
+ return ::rtl::OUString();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 03.11.2003 09:19
+-----------------------------------------------*/
+::rtl::OUString TypeDetection::impl_detectTypeDeepOnly( ::comphelper::MediaDescriptor& rDescriptor ,
+ const OUStringList& lOutsideUsedDetectors)
+{
+ // We must know if a detect service was already used:
+ // i) in a combined flat/deep detection scenario outside or
+ // ii) in this method for a deep detection only.
+ // Reason: Such deep detection services work differently in these two modes!
+ OUStringList lInsideUsedDetectors;
+ OUStringList::const_iterator pIt;
+
+ // a)
+ // The list of "already used detect services" correspond to the list
+ // of preselected or flat detected types. But these detect services was called
+ // to check these types explicitly and return black/white ... yes/no only.
+ // Now they are called to return any possible result. But we should preferr
+ // these already used detect services against all other ones!
+ for ( pIt = lOutsideUsedDetectors.begin();
+ pIt != lOutsideUsedDetectors.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sDetectService = *pIt;
+ ::rtl::OUString sDeepType = impl_askDetectService(sDetectService, rDescriptor);
+ if (sDeepType.getLength())
+ return sDeepType;
+ lInsideUsedDetectors.push_back(sDetectService);
+ }
+
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ OUStringList lDetectors = m_rCache->getItemNames(FilterCache::E_DETECTSERVICE);
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ // b)
+ // Sometimes it would be nice to ask a special set of detect services before
+ // any other detect service is asked. E.g. by using a preselection of a DocumentService.
+ // That's needed to prevent us from asking the "wrong application module" and
+ // opening the files into the "wrong application".
+ ::rtl::OUString sPreselDocumentService = rDescriptor.getUnpackedValueOrDefault(
+ ::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE(),
+ ::rtl::OUString());
+ if (sPreselDocumentService.getLength())
+ {
+ for ( pIt = lDetectors.begin();
+ pIt != lDetectors.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sDetectService = *pIt;
+
+ OUStringList::const_iterator pAlreadyUsed = ::std::find(lInsideUsedDetectors.begin(), lInsideUsedDetectors.end(), sDetectService);
+ if (pAlreadyUsed != lInsideUsedDetectors.end())
+ continue;
+
+ // SAFE -> --------------------------------------------------------
+ aLock.reset();
+
+ CacheItem lIProps;
+ lIProps[PROPNAME_DETECTSERVICE] <<= sDetectService;
+ OUStringList lTypes = m_rCache->getMatchingItemsByProps(FilterCache::E_TYPE, lIProps);
+
+ aLock.clear();
+ // <- SAFE --------------------------------------------------------
+
+ sal_Bool bMatchDetectorToDocumentService = sal_False;
+ OUStringList::const_iterator pIt2;
+ for ( pIt2 = lTypes.begin();
+ pIt2 != lTypes.end() ;
+ ++pIt2 )
+ {
+ const ::rtl::OUString& sType = *pIt2;
+
+ try
+ {
+ // SAFE -> ----------------------------------------------------
+ aLock.reset();
+
+ CacheItem aType = m_rCache->getItem(FilterCache::E_TYPE, sType);
+ ::rtl::OUString sFilter;
+ aType[PROPNAME_PREFERREDFILTER] >>= sFilter;
+ CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
+ ::rtl::OUString sCheckDocumentService;
+ aFilter[PROPNAME_DOCUMENTSERVICE] >>= sCheckDocumentService;
+
+ aLock.clear();
+ // <- SAFE
+
+ if (sCheckDocumentService.equals(sPreselDocumentService))
+ {
+ bMatchDetectorToDocumentService = sal_True;
+ break;
+ }
+ }
+ catch(const css::uno::Exception&)
+ { continue; }
+ }
+
+ if (bMatchDetectorToDocumentService)
+ {
+ ::rtl::OUString sDeepType = impl_askDetectService(sDetectService, rDescriptor);
+ if (sDeepType.getLength())
+ return sDeepType;
+ lInsideUsedDetectors.push_back(sDetectService);
+ }
+ }
+ }
+
+ // c)
+ // Last chance. No "used detectors", no "preselected detectors" ... ask any existing detect services
+ // for this till know unknown format.
+ for ( pIt = lDetectors.begin();
+ pIt != lDetectors.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sDetectService = *pIt;
+
+ OUStringList::const_iterator pAlreadyUsed = ::std::find(lInsideUsedDetectors.begin(), lInsideUsedDetectors.end(), sDetectService);
+ if (pAlreadyUsed != lInsideUsedDetectors.end())
+ continue;
+
+ ::rtl::OUString sDeepType = impl_askDetectService(sDetectService, rDescriptor);
+ if (sDeepType.getLength())
+ return sDeepType;
+ }
+
+ return ::rtl::OUString();
+}
+
+/*-----------------------------------------------
+ 07.03.2005 11:13
+-----------------------------------------------*/
+void TypeDetection::impl_seekStreamToZero(comphelper::MediaDescriptor& rDescriptor)
+{
+ // try to seek to 0 ...
+ // But because XSeekable is an optional interface ... try it only .-)
+ css::uno::Reference< css::io::XInputStream > xStream = rDescriptor.getUnpackedValueOrDefault(
+ ::comphelper::MediaDescriptor::PROP_INPUTSTREAM(),
+ css::uno::Reference< css::io::XInputStream >());
+ css::uno::Reference< css::io::XSeekable > xSeek(xStream, css::uno::UNO_QUERY);
+ if (xSeek.is())
+ {
+ try
+ {
+ xSeek->seek(0);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+ }
+}
+
+/*-----------------------------------------------
+ 30.10.2003 15:12
+-----------------------------------------------*/
+::rtl::OUString TypeDetection::impl_askDetectService(const ::rtl::OUString& sDetectService,
+ ::comphelper::MediaDescriptor& rDescriptor )
+{
+ // Open the stream and add it to the media descriptor if this method is called for the first time.
+ // All following requests to this method will detect, that there already exists a stream .-)
+ // Attention: This method throws an exception if the stream could not be opened.
+ // It's important to break any further detection in such case.
+ // Catch it on the highest detection level only !!!
+ impl_openStream(rDescriptor);
+
+ // seek to 0 is an optional feature to be more robust against
+ // "simple implemented detect services" .-)
+ impl_seekStreamToZero(rDescriptor);
+
+ css::uno::Reference< css::document::XExtendedFilterDetection > xDetector;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR;
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ xSMGR = m_xSMGR;
+ aLock.clear();
+ // <- SAFE
+
+ // Attention! If e.g. an office module was not installed sometimes we find a
+ // registered detect service, which is referred inside the configuration ... but not realy
+ // installed. On the other side we use third party components here, which can make trouble anyway.
+ // So we should handle errors during creation of such services more gracefully .-)
+ xDetector = css::uno::Reference< css::document::XExtendedFilterDetection >(
+ xSMGR->createInstance(sDetectService),
+ css::uno::UNO_QUERY);
+
+ if ( ! xDetector.is())
+ return ::rtl::OUString();
+
+ ::rtl::OUString sDeepType;
+ try
+ {
+ // start deep detection
+ // Dont forget to convert stl descriptor to its uno representation.
+
+ /* Attention!
+ You have to use an explicit instance of this uno sequence ...
+ Because its used as an in out parameter. And in case of a temp. used object
+ we will run into memory corruptions!
+ */
+ css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
+ rDescriptor >> lDescriptor;
+ sDeepType = xDetector->detect(lDescriptor);
+ rDescriptor << lDescriptor;
+ }
+ catch(const css::uno::Exception&)
+ {
+ // We should ignore errors here.
+ // Thrown exceptions mostly will end in crash recovery ...
+ // But might be we find another deep detection service which can detect the same
+ // document without a problem .-)
+ sDeepType = ::rtl::OUString();
+ }
+
+ // seek to 0 is an optional feature to be more robust against
+ // "simple implemented detect services" .-)
+ impl_seekStreamToZero(rDescriptor);
+
+ // analyze the results
+ // a) detect service returns "" => return "" too and remove TYPE/FILTER prop from descriptor
+ // b) returned type is unknown => return "" too and remove TYPE/FILTER prop from descriptor
+ // c) returned type is valid => check TYPE/FILTER props inside descriptor and return the type
+
+ // this special helper checks for a valid type
+ // and set right values on the descriptor!
+ sal_Bool bValidType = impl_validateAndSetTypeOnDescriptor(rDescriptor, sDeepType);
+ if (bValidType)
+ return sDeepType;
+
+ return ::rtl::OUString();
+}
+
+/*-----------------------------------------------
+ 17.12.2004 13:47
+-----------------------------------------------*/
+::rtl::OUString TypeDetection::impl_askUserForTypeAndFilterIfAllowed(::comphelper::MediaDescriptor& rDescriptor)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aLock.clear();
+ // <- SAFE
+
+ css::uno::Reference< css::task::XInteractionHandler > xInteraction =
+ rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER(),
+ css::uno::Reference< css::task::XInteractionHandler >());
+
+ if (!xInteraction.is())
+ return ::rtl::OUString();
+
+ ::rtl::OUString sURL =
+ rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_URL(),
+ ::rtl::OUString());
+
+ css::uno::Reference< css::io::XInputStream > xStream =
+ rDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_INPUTSTREAM(),
+ css::uno::Reference< css::io::XInputStream >());
+
+ // Dont distrub the user for "non existing files - means empty URLs" or
+ // if we was forced to detect a stream.
+ // Reason behind: We must be shure to ask user for "unknown contents" only ...
+ // and not for "missing files". Especialy if detection is done by a stream only
+ // we cant check if the stream points to an "existing content"!
+ if (
+ (!sURL.getLength() ) || // "non existing file" ?
+ (!xStream.is() ) || // non existing file !
+ (sURL.equalsIgnoreAsciiCaseAsciiL("private:stream", 14)) // not a good idea .-)
+ )
+ return ::rtl::OUString();
+
+ try
+ {
+ // create a new request to ask user for it's decision about the usable filter
+ ::framework::RequestFilterSelect* pRequest = new ::framework::RequestFilterSelect(sURL);
+ css::uno::Reference< css::task::XInteractionRequest > xRequest(static_cast< css::task::XInteractionRequest* >(pRequest), css::uno::UNO_QUERY_THROW);
+ xInteraction->handle(xRequest);
+
+ // "Cancel" pressed? => return with error
+ if (pRequest->isAbort())
+ return ::rtl::OUString();
+
+ // "OK" pressed => verify the selected filter, get it's coressponding
+ // type and return it. (BTW: We must update the media descriptor here ...)
+ // The user selected explicitly a filter ... but normaly we are interested on
+ // a type here only. But we must be shure, that the selected filter is used
+ // too and no ambigous filter registration disturb us .-)
+
+ ::rtl::OUString sFilter = pRequest->getFilter();
+ if (!impl_validateAndSetFilterOnDescriptor(rDescriptor, sFilter))
+ return ::rtl::OUString();
+
+ ::rtl::OUString sType;
+ rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] >>= sType;
+ return sType;
+ }
+ catch(const css::uno::Exception&)
+ {}
+
+ return ::rtl::OUString();
+}
+
+/*-----------------------------------------------
+ 10.03.2004 10:30
+-----------------------------------------------*/
+void TypeDetection::impl_openStream(::comphelper::MediaDescriptor& rDescriptor)
+ throw (css::uno::Exception)
+{
+ sal_Bool bSuccess = sal_False;
+ ::rtl::OUString sURL = rDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_URL(), ::rtl::OUString() );
+ sal_Bool bRequestedReadOnly = rDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_READONLY(), sal_False );
+ if ( sURL.getLength() && ::utl::LocalFileHelper::IsLocalFile( INetURLObject( sURL ).GetMainURL( INetURLObject::NO_DECODE ) ) )
+ {
+ // OOo uses own file locking mechanics in case of local file
+ bSuccess = rDescriptor.addInputStreamOwnLock();
+ }
+ else
+ bSuccess = rDescriptor.addInputStream();
+
+ if ( !bSuccess )
+ throw css::uno::Exception(_FILTER_CONFIG_FROM_ASCII_("Could not open stream."), static_cast< css::document::XTypeDetection* >(this));
+
+ if ( !bRequestedReadOnly )
+ {
+ // The MediaDescriptor implementation adds ReadOnly argument if the file can not be opened for writing
+ // this argument should be either removed or an additional argument should be added so that application
+ // can separate the case when the user explicitly requests readonly document.
+ // The current solution is to remove it here.
+ rDescriptor.erase( ::comphelper::MediaDescriptor::PROP_READONLY() );
+ }
+}
+
+/*-----------------------------------------------
+ 04.07.2003 13:47
+-----------------------------------------------*/
+void TypeDetection::impl_removeTypeFilterFromDescriptor(::comphelper::MediaDescriptor& rDescriptor)
+{
+ ::comphelper::MediaDescriptor::iterator pItType = rDescriptor.find(::comphelper::MediaDescriptor::PROP_TYPENAME() );
+ ::comphelper::MediaDescriptor::iterator pItFilter = rDescriptor.find(::comphelper::MediaDescriptor::PROP_FILTERNAME());
+ if (pItType != rDescriptor.end())
+ rDescriptor.erase(pItType);
+ if (pItFilter != rDescriptor.end())
+ rDescriptor.erase(pItFilter);
+}
+
+/*-----------------------------------------------
+ 14.10.2003 11:15
+-----------------------------------------------*/
+sal_Bool TypeDetection::impl_validateAndSetTypeOnDescriptor( ::comphelper::MediaDescriptor& rDescriptor,
+ const ::rtl::OUString& sType )
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ if (m_rCache->hasItem(FilterCache::E_TYPE, sType))
+ {
+ rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType;
+ return sal_True;
+ }
+ aLock.clear();
+ // <- SAFE
+
+ // remove all related informations from the descriptor
+ impl_removeTypeFilterFromDescriptor(rDescriptor);
+ return sal_False;
+}
+
+/*-----------------------------------------------
+ 04.07.2003 14:01
+-----------------------------------------------*/
+sal_Bool TypeDetection::impl_validateAndSetFilterOnDescriptor( ::comphelper::MediaDescriptor& rDescriptor,
+ const ::rtl::OUString& sFilter )
+{
+ try
+ {
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sFilter);
+ ::rtl::OUString sType;
+ aFilter[PROPNAME_TYPE] >>= sType;
+ CacheItem aType = m_rCache->getItem(FilterCache::E_TYPE, sType);
+
+ aLock.clear();
+ // <- SAFE
+
+ // found valid type and filter => set it on the given descriptor
+ rDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME() ] <<= sType ;
+ rDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
+ return sal_True;
+ }
+ catch(const css::container::NoSuchElementException&){}
+
+ // remove all related informations from the descriptor
+ impl_removeTypeFilterFromDescriptor(rDescriptor);
+ return sal_False;
+}
+
+/*-----------------------------------------------
+ 03.07.2003 10:36
+-----------------------------------------------*/
+::rtl::OUString TypeDetection::impl_getImplementationName()
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.filter.config.TypeDetection");
+}
+
+/*-----------------------------------------------
+ 03.07.2003 11:27
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > TypeDetection::impl_getSupportedServiceNames()
+{
+ css::uno::Sequence< ::rtl::OUString > lServiceNames(1);
+ lServiceNames[0] = ::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection");
+ return lServiceNames;
+}
+
+/*-----------------------------------------------
+ 09.07.2003 08:02
+-----------------------------------------------*/
+css::uno::Reference< css::uno::XInterface > SAL_CALL TypeDetection::impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ TypeDetection* pNew = new TypeDetection(xSMGR);
+ return css::uno::Reference< css::uno::XInterface >(static_cast< css::document::XTypeDetection* >(pNew), css::uno::UNO_QUERY);
+}
+
+ } // namespace config
+} // namespace filter
diff --git a/filter/source/config/cache/typedetection.hxx b/filter/source/config/cache/typedetection.hxx
new file mode 100644
index 000000000000..4dbf6f07d33e
--- /dev/null
+++ b/filter/source/config/cache/typedetection.hxx
@@ -0,0 +1,459 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef __FILTER_CONFIG_TYPEDETECTION_HXX_
+#define __FILTER_CONFIG_TYPEDETECTION_HXX_
+
+//_______________________________________________
+// includes
+
+#include "basecontainer.hxx"
+#include <com/sun/star/document/XTypeDetection.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <comphelper/mediadescriptor.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace filter{
+ namespace config{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// definitions
+
+//_______________________________________________
+
+/** @short implements the service <type scope="com.sun.star.document">TypeDetection</type>.
+ */
+class TypeDetection : public ::cppu::ImplInheritanceHelper1< BaseContainer ,
+ css::document::XTypeDetection >
+{
+ //-------------------------------------------
+ // native interface
+
+ public:
+
+ //---------------------------------------
+ // ctor/dtor
+
+ /** @short standard ctor to connect this interface wrapper to
+ the global filter cache instance ...
+
+ @param xSMGR
+ reference to the uno service manager, which created this service instance.
+ */
+ TypeDetection(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+
+ //---------------------------------------
+
+ /** @short standard dtor.
+ */
+ virtual ~TypeDetection();
+
+ //-------------------------------------------
+ // private helper
+
+ private:
+
+ //---------------------------------------
+ /** TODO document me */
+ sal_Bool impl_getPreselectionForType(const ::rtl::OUString& sPreSelType,
+ const css::util::URL& aParsedURL ,
+ FlatDetection& rFlatTypes );
+
+ //---------------------------------------
+ /** TODO document me */
+ sal_Bool impl_getPreselectionForFilter(const ::rtl::OUString& sPreSelFilter,
+ const css::util::URL& aParsedURL ,
+ FlatDetection& rFlatTypes );
+
+ //---------------------------------------
+ /** TODO document me */
+ sal_Bool impl_getPreselectionForDocumentService(const ::rtl::OUString& sPreSelDocumentService,
+ const css::util::URL& aParsedURL ,
+ FlatDetection& rFlatTypes );
+
+ //---------------------------------------
+
+ /** @short check if a filter or a type was preselected inside the given
+ MediaDescriptor and validate this information.
+
+ @descr Only in case the preselected filter exists and its type registration
+ seems to be usefully, it would be used realy as valid type detection
+ result. This method doesnt make any deep detection here. It checks only
+ if the preselection match to the URL by an URLPattern.
+ This information has to be added to the given rFlatTypes list too.
+ The outside code can use it to supress a deep detection then in general.
+ Because pattern are defined as non detectable at all!
+
+ @param pDescriptor
+ provides any easy-to-use stl interface to the MediaDescriptor.
+ Note : Its content will be adapted to returned result of this method.
+ Means: The type/filter entries of it will be actualized or removed.
+
+ @param rFlatTypes
+ the preselected type (or the registered type of a preselected filter)
+ will be added here as first(!) element. Further we have to provide the
+ information, if this type match to the given URL by its URLPattern
+ registration.
+ */
+ void impl_getPreselection(const css::util::URL& aParsedURL ,
+ ::comphelper::MediaDescriptor& rDescriptor,
+ FlatDetection& rFlatTypes );
+
+ //---------------------------------------
+
+ /** @short make a combined flat/deep type detection
+
+ @descr It steps over all flat detected types (given by the parameter lFlatTypes),
+ try it and search for most suitable one.
+ The specified MediaDescriptor will be patched, so it contain
+ the right values everytime. Using of any deep detection service
+ can be enabled/disabled. And last but not least: If the results
+ wont be realy clear (because a flat detected type has no deep
+ detection service), a "sugested" type name will be returned as "rLastChance".
+ It can be used after e.g. all well known deep detection services
+ was used without getting any result. Then this "last-chance-type"
+ should be returned. Of course using of it can fail too ... but its a try :-)
+
+ As an optimization - this method collects the names of all used deep
+ detection services. This information can be usefull inside the may be
+ afterwards called method "impl_detectTypeDeepOnly()"!
+
+ @param rDescriptor
+ provides any easy-to-use stl interface to the MediaDescriptor.
+ Note : Its content will be adapted to returned result of this method.
+ Means: The type/filter entries of it will be actualized or removed from it.
+
+ @param lFlatTypes
+ a list of all flat detected types, which should be checked here.
+ No other types are allowed here!
+
+ @param rLastChance
+ the internal name of a "suggested type" ... (see before)
+ Note: it will be reseted to an empty string everytimes. So
+ a set value of "rLastChance" can be detected outside very easy.
+
+ @param rUsedDetectors
+ used as [out] parameter. It contains a list of names of all deep
+ detection services, which was used inside this method.
+ Such detectors can be ignored later if "impl_detectTypeDeepOnly()"
+ is called.
+
+ @param bAllowDeep
+ enable/disable using of a might existing deep detection service.
+
+ @return The internal name of a detected type.
+ An empty value if detection failed. .... but see rLastChance
+ for additional returns!
+ */
+ ::rtl::OUString impl_detectTypeFlatAndDeep( ::comphelper::MediaDescriptor& rDescriptor ,
+ const FlatDetection& lFlatTypes ,
+ sal_Bool bAllowDeep ,
+ OUStringList& rUsedDetectors,
+ ::rtl::OUString& rLastChance );
+
+ //---------------------------------------
+
+ /** @short make a deep type detection only
+
+ @descr It steps over all well known deep detection services
+ and check her results. The first positive result will be
+ used for return. Its more a "try and error" algorithm then
+ a real type detection and will be used if a flat detection
+ cant work realy ... e.g. if the extension of an URL is
+ missing or wrong.
+
+ @param rDescriptor
+ provides any easy-to-use stl interface to the MediaDescriptor.
+ Note : Its content will be adapted to returned result of this method.
+ Means: The type/filter entries of it will be actualized or removed from it.
+
+ @param rUsedDetectors
+ It contains a list of names of all deep detection services,
+ which was already used inside the method "impl_detectTypeFlatAndDeep()"!
+ Such detectors must be ignored here!
+
+ @return The internal name of a detected type.
+ An empty value if detection failed.
+ */
+ ::rtl::OUString impl_detectTypeDeepOnly( ::comphelper::MediaDescriptor& rDescriptor ,
+ const OUStringList& rUsedDetectors);
+
+ //---------------------------------------
+
+ /** @short seek a might existing stream to position 0.
+
+ @descr This is an optinal action to be more robust
+ in case any detect service doesnt make this seek ...
+ Normaly it's part of any called detect service or filter ...
+ but sometimes it's not done there.
+
+ @param rDescriptor
+ a stl representation of the MediaDescriptor as in/out parameter.
+ */
+ void impl_seekStreamToZero(comphelper::MediaDescriptor& rDescriptor);
+
+ //---------------------------------------
+
+ /** @short make deep type detection for a specified
+ detect service (threadsafe!).
+
+ @descr It creates the right uno service, prepare the
+ needed MediaDescriptor, call ths right interfaces,
+ and return the results.
+
+ @attention The results (means type and corresponding filter)
+ are already part of the in/out parameter pDescriptor.
+ (in case they was valid).
+
+ @param sDetectService
+ uno service name of the detect service.
+
+ @param rDescriptor
+ a stl representation of the MediaDescriptor as in/out parameter.
+ */
+ ::rtl::OUString impl_askDetectService(const ::rtl::OUString& sDetectService,
+ ::comphelper::MediaDescriptor& rDescriptor );
+
+ //---------------------------------------
+
+ /** @short try to find an interaction handler and
+ ask him to select a possible filter for
+ this unknown format.
+
+ @descr If the user select a filter, it will be used as return value
+ without further checking against the given file content!
+
+ @param rDescriptor
+ a stl representation of the MediaDescriptor as in/out parameter.
+
+ @return [string]
+ a valid type name or an empty string if user canceled interaction.
+ */
+ ::rtl::OUString impl_askUserForTypeAndFilterIfAllowed(::comphelper::MediaDescriptor& rDescriptor);
+
+ //---------------------------------------
+
+ /** @short check if an input stream is already part of the
+ given MediaDesciptor and creates a new one if neccessary.
+
+ @attention This method does further something special!
+ <ul>
+ <li>
+ If the given URL seem to be a streamable content, but creation of the stream
+ failed (might by an IOException), this method throws an exception.
+ (May be an existing interaction handler must be called here too ...)
+ The whole detection must be interrupted then and the interface method queryTypeByDescriptor()
+ must return an empty type name value.
+
+ That prevent us against multiple handling of the same error more then ones
+ (e.g. if we ask all detect services as fallback ...).
+ </li>
+ <li>
+ In case the stream already exists inside the descriptor this method does nothing.
+ </li>
+ <li>
+ In case the stream does not exists but can be created successfully, the stream will
+ be added to the descriptor.
+ </li>
+ </ul>
+
+ @param rDescriptor
+ provides any easy-to-use stl interface to the MediaDescriptor.
+ Note : Its content will be adapted to returned result of this method.
+ Means: The stream will be added to it.
+
+ @throw Any suitable exception if stream should be opened but operation was not sucessfull.
+ Note: If an interactionHandler is part of the given descriptor too, it was already used.
+ Means: let the exception pass trough the top most interface method!
+ */
+ void impl_openStream(::comphelper::MediaDescriptor& rDescriptor)
+ throw (css::uno::Exception);
+
+ //---------------------------------------
+
+ /** @short validate the specified type and its relation ships
+ and set all needed informations related to this type
+ in the specified descriptor.
+
+ @descr Related informations are: - corresponding filter
+ - media type
+ - ...
+
+ @param rDescriptor
+ provides access to the outside MediaDescriptor.
+
+ @param sType
+ the name of the type, which should be set on the descriptor.
+ Can be empty to remove any related value from the descriptor!
+
+ @return TRUE the specified type and its registrations was valid(!) and
+ could be set on the descriptor.
+ */
+ sal_Bool impl_validateAndSetTypeOnDescriptor( ::comphelper::MediaDescriptor& rDescriptor,
+ const ::rtl::OUString& sType );
+
+ //---------------------------------------
+
+ /** @short validate the specified filter and its relation ships
+ and set all needed informations related to this filter
+ in the specified descriptor.
+
+ @descr Related informations are: - corresponding type
+ - ...
+
+ @param rDescriptor
+ provides access to the outside MediaDescriptor.
+
+ @param sFilter
+ the name of the filter, which should be set on the descriptor.
+ Can be empty to remove any related value from the descriptor!
+
+ @return TRUE the specified type and its registrations was valid(!) and
+ could be set on the descriptor.
+ */
+ sal_Bool impl_validateAndSetFilterOnDescriptor( ::comphelper::MediaDescriptor& rDescriptor,
+ const ::rtl::OUString& sFilter );
+
+ //---------------------------------------
+
+ /** @short remove anythimng related to a TYPE/FILTER entry from the
+ specified MediaDescriptor.
+
+ @descr This method works together with impl_validateAndSetTypeOnDescriptor()/
+ impl_validateAndSetFilterOnDescriptor(). All informations, which can be
+ set by these two operations must be "removeable" by this method.
+
+ @param rDescriptor
+ reference to the MediaDescriptor (represented by an easy-to-use
+ stl interface!), which should be patched.
+ */
+ void impl_removeTypeFilterFromDescriptor(::comphelper::MediaDescriptor& rDescriptor);
+
+ //---------------------------------------
+
+ /** @short search the best suitable filter for the given type
+ and add it into the media descriptor.
+
+ @descr Normaly this is a type detection only ...
+ but for some special features we must overwrite our detection
+ because a file must be loaded into a special (means preselected)
+ application.
+
+ E.g. CSV/TXT format are sometimes ugly to handle .-)
+
+ Note: If the descriptor already include a filter
+ (may be selected by a FilterSelect interaction or preselected
+ by the user itself) ... we dont change that here !
+
+ @param rDescriptor
+ reference to the MediaDescriptor (represented by an easy-to-use
+ stl interface!), which should be patched.
+
+ @param sType
+ the internal type name, where we search a filter for.
+ Used as IN/OUT parameter so we can overrule the detection result for
+ types too !
+
+ @note #i60158#
+ sometimes our text ascii and our csv filter cant work together.
+ Then we overwrite our detection hardly.
+ sType param is used as out parameter then too ... and
+ rDescriptor will be changed by selecting another filter.
+ (see code)
+ */
+ void impl_checkResultsAndAddBestFilter(::comphelper::MediaDescriptor& rDescriptor,
+ ::rtl::OUString& sType );
+
+ //-------------------------------------------
+ // uno interface
+
+ public:
+
+ //---------------------------------------
+ // XTypeDetection
+
+ virtual ::rtl::OUString SAL_CALL queryTypeByURL(const ::rtl::OUString& sURL)
+ throw (css::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL queryTypeByDescriptor(css::uno::Sequence< css::beans::PropertyValue >& lDescriptor,
+ sal_Bool bAllowDeep )
+ throw (css::uno::RuntimeException);
+
+ //-------------------------------------------
+ // static uno helper!
+
+ public:
+
+ //---------------------------------------
+
+ /** @short return the uno implementation name of this class.
+
+ @descr Because this information is used at several places
+ (and mostly an object instance of this class is not possible)
+ its implemented as a static function!
+
+ @return The fix uno implementation name of this class.
+ */
+ static ::rtl::OUString impl_getImplementationName();
+
+ //---------------------------------------
+
+ /** @short return the list of supported uno services of this class.
+
+ @descr Because this information is used at several places
+ (and mostly an object instance of this class is not possible)
+ its implemented as a static function!
+
+ @return The fix list of uno services supported by this class.
+ */
+ static css::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames();
+
+ //---------------------------------------
+
+ /** @short return a new intsnace of this class.
+
+ @descr This method is used by the uno service manager, to create
+ a new instance of this service if needed.
+
+ @param xSMGR
+ reference to the uno service manager, which require
+ this new instance. It should be passed to the new object
+ so it can be used internaly to create own needed uno resources.
+
+ @return The new instance of this service as an uno reference.
+ */
+ static css::uno::Reference< css::uno::XInterface > impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+};
+
+ } // namespace config
+} // namespace filter
+
+#endif // __FILTER_CONFIG_TYPEDETECTION_HXX_
diff --git a/filter/source/config/cache/versions.hxx b/filter/source/config/cache/versions.hxx
new file mode 100644
index 000000000000..fbd92604170f
--- /dev/null
+++ b/filter/source/config/cache/versions.hxx
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _FILTER_CONFIG_VERSIONS_HXX_
+#define _FILTER_CONFIG_VERSIONS_HXX_
+
+//_______________________________________________
+
+//#define _FILTER_CONFIG_Q_ // final Q code base
+#define _FILTER_CONFIG_MIGRATION_Q_ // usefull for migration time, to support some old functionality temp. :-)
+
+#endif // _FILTER_CONFIG_VERSIONS_HXX_