summaryrefslogtreecommitdiff
path: root/filter/source/config/cache/basecontainer.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/config/cache/basecontainer.cxx')
-rw-r--r--filter/source/config/cache/basecontainer.cxx638
1 files changed, 638 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