summaryrefslogtreecommitdiff
path: root/framework/source/classes/propertysethelper.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source/classes/propertysethelper.cxx')
-rw-r--r--framework/source/classes/propertysethelper.cxx450
1 files changed, 450 insertions, 0 deletions
diff --git a/framework/source/classes/propertysethelper.cxx b/framework/source/classes/propertysethelper.cxx
new file mode 100644
index 000000000000..2e41106a9ceb
--- /dev/null
+++ b/framework/source/classes/propertysethelper.cxx
@@ -0,0 +1,450 @@
+/*************************************************************************
+ *
+ * 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_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+
+#include <classes/propertysethelper.hxx>
+#include <threadhelp/transactionguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+
+//_________________________________________________________________________________________________________________
+// other includes
+
+//_________________________________________________________________________________________________________________
+// namespace
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+
+//-----------------------------------------------------------------------------
+PropertySetHelper::PropertySetHelper(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ LockHelper* pExternalLock ,
+ TransactionManager* pExternalTransactionManager ,
+ sal_Bool bReleaseLockOnCall )
+ : m_xSMGR (xSMGR )
+ , m_lSimpleChangeListener(pExternalLock->getShareableOslMutex())
+ , m_lVetoChangeListener (pExternalLock->getShareableOslMutex())
+ , m_bReleaseLockOnCall (bReleaseLockOnCall )
+ , m_rLock (*pExternalLock )
+ , m_rTransactionManager (*pExternalTransactionManager )
+{
+}
+
+//-----------------------------------------------------------------------------
+PropertySetHelper::~PropertySetHelper()
+{
+}
+
+//-----------------------------------------------------------------------------
+void PropertySetHelper::impl_setPropertyChangeBroadcaster(const css::uno::Reference< css::uno::XInterface >& xBroadcaster)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+ m_xBroadcaster = xBroadcaster;
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_addPropertyInfo(const css::beans::Property& aProperty)
+ throw(css::beans::PropertyExistException,
+ css::uno::Exception )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(aProperty.Name);
+ if (pIt != m_lProps.end())
+ throw css::beans::PropertyExistException();
+
+ m_lProps[aProperty.Name] = aProperty;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_removePropertyInfo(const ::rtl::OUString& sProperty)
+ throw(css::beans::UnknownPropertyException,
+ css::uno::Exception )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ m_lProps.erase(pIt);
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_enablePropertySet()
+{
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_disablePropertySet()
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ css::uno::Reference< css::uno::XInterface > xThis(static_cast< css::beans::XPropertySet* >(this), css::uno::UNO_QUERY);
+ css::lang::EventObject aEvent(xThis);
+
+ m_lSimpleChangeListener.disposeAndClear(aEvent);
+ m_lVetoChangeListener.disposeAndClear(aEvent);
+ m_lProps.free();
+
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool PropertySetHelper::impl_existsVeto(const css::beans::PropertyChangeEvent& aEvent)
+{
+ /* Dont use the lock here!
+ The used helper is threadsafe and it lives for the whole lifetime of
+ our own object.
+ */
+ ::cppu::OInterfaceContainerHelper* pVetoListener = m_lVetoChangeListener.getContainer(aEvent.PropertyName);
+ if (! pVetoListener)
+ return sal_False;
+
+ ::cppu::OInterfaceIteratorHelper pListener(*pVetoListener);
+ while (pListener.hasMoreElements())
+ {
+ try
+ {
+ css::uno::Reference< css::beans::XVetoableChangeListener > xListener(
+ ((css::beans::XVetoableChangeListener*)pListener.next()),
+ css::uno::UNO_QUERY_THROW);
+ xListener->vetoableChange(aEvent);
+ }
+ catch(const css::uno::RuntimeException&)
+ { pListener.remove(); }
+ catch(const css::beans::PropertyVetoException&)
+ { return sal_True; }
+ }
+
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+void PropertySetHelper::impl_notifyChangeListener(const css::beans::PropertyChangeEvent& aEvent)
+{
+ /* Dont use the lock here!
+ The used helper is threadsafe and it lives for the whole lifetime of
+ our own object.
+ */
+ ::cppu::OInterfaceContainerHelper* pSimpleListener = m_lSimpleChangeListener.getContainer(aEvent.PropertyName);
+ if (! pSimpleListener)
+ return;
+
+ ::cppu::OInterfaceIteratorHelper pListener(*pSimpleListener);
+ while (pListener.hasMoreElements())
+ {
+ try
+ {
+ css::uno::Reference< css::beans::XPropertyChangeListener > xListener(
+ ((css::beans::XVetoableChangeListener*)pListener.next()),
+ css::uno::UNO_QUERY_THROW);
+ xListener->propertyChange(aEvent);
+ }
+ catch(const css::uno::RuntimeException&)
+ { pListener.remove(); }
+ }
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PropertySetHelper::getPropertySetInfo()
+ throw(css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ css::uno::Reference< css::beans::XPropertySetInfo > xInfo(static_cast< css::beans::XPropertySetInfo* >(this), css::uno::UNO_QUERY_THROW);
+ return xInfo;
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::setPropertyValue(const ::rtl::OUString& sProperty,
+ const css::uno::Any& aValue )
+ throw(css::beans::UnknownPropertyException,
+ css::beans::PropertyVetoException ,
+ css::lang::IllegalArgumentException ,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ // TODO look for e.g. readonly props and reject setProp() call!
+
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ css::beans::Property aPropInfo = pIt->second;
+
+ sal_Bool bLocked = sal_True;
+ if (m_bReleaseLockOnCall)
+ {
+ aWriteLock.unlock();
+ bLocked = sal_False;
+ // <- SAFE
+ }
+
+ css::uno::Any aCurrentValue = impl_getPropertyValue(aPropInfo.Name, aPropInfo.Handle);
+
+ if (! bLocked)
+ {
+ // SAFE ->
+ aWriteLock.lock();
+ bLocked = sal_True;
+ }
+
+ sal_Bool bWillBeChanged = (aCurrentValue != aValue);
+ if (! bWillBeChanged)
+ return;
+
+ css::beans::PropertyChangeEvent aEvent;
+ aEvent.PropertyName = aPropInfo.Name;
+ aEvent.Further = sal_False;
+ aEvent.PropertyHandle = aPropInfo.Handle;
+ aEvent.OldValue = aCurrentValue;
+ aEvent.NewValue = aValue;
+ aEvent.Source = css::uno::Reference< css::uno::XInterface >(m_xBroadcaster.get(), css::uno::UNO_QUERY);
+
+ if (m_bReleaseLockOnCall)
+ {
+ aWriteLock.unlock();
+ bLocked = sal_False;
+ // <- SAFE
+ }
+
+ if (impl_existsVeto(aEvent))
+ throw css::beans::PropertyVetoException();
+
+ impl_setPropertyValue(aPropInfo.Name, aPropInfo.Handle, aValue);
+
+ impl_notifyChangeListener(aEvent);
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Any SAL_CALL PropertySetHelper::getPropertyValue(const ::rtl::OUString& sProperty)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ css::beans::Property aPropInfo = pIt->second;
+
+ sal_Bool bLocked = sal_True;
+ if (m_bReleaseLockOnCall)
+ {
+ aReadLock.unlock();
+ bLocked = sal_False;
+ // <- SAFE
+ }
+
+ return impl_getPropertyValue(aPropInfo.Name, aPropInfo.Handle);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::addPropertyChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lSimpleChangeListener.addInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::removePropertyChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lSimpleChangeListener.removeInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::addVetoableChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lVetoChangeListener.addInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::removeVetoableChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lVetoChangeListener.removeInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Sequence< css::beans::Property > SAL_CALL PropertySetHelper::getProperties()
+ throw(css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ sal_Int32 c = (sal_Int32)m_lProps.size();
+ css::uno::Sequence< css::beans::Property > lProps(c);
+ PropertySetHelper::TPropInfoHash::const_iterator pIt ;
+
+ for ( pIt = m_lProps.begin();
+ pIt != m_lProps.end() ;
+ ++pIt )
+ {
+ lProps[--c] = pIt->second;
+ }
+
+ return lProps;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+css::beans::Property SAL_CALL PropertySetHelper::getPropertyByName(const ::rtl::OUString& sName)
+ throw(css::beans::UnknownPropertyException,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sName);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ return pIt->second;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL PropertySetHelper::hasPropertyByName(const ::rtl::OUString& sName)
+ throw(css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::iterator pIt = m_lProps.find(sName);
+ sal_Bool bExist = (pIt != m_lProps.end());
+
+ return bExist;
+ // <- SAFE
+}
+
+} // namespace framework