diff options
Diffstat (limited to 'framework/source/fwi/classes/propertysethelper.cxx')
-rw-r--r-- | framework/source/fwi/classes/propertysethelper.cxx | 450 |
1 files changed, 450 insertions, 0 deletions
diff --git a/framework/source/fwi/classes/propertysethelper.cxx b/framework/source/fwi/classes/propertysethelper.cxx new file mode 100644 index 000000000000..2e41106a9ceb --- /dev/null +++ b/framework/source/fwi/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 |