summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsb <sb@openoffice.org>2009-09-22 10:36:09 +0200
committersb <sb@openoffice.org>2009-09-22 10:36:09 +0200
commitec826ada913dcbe494f07055683538f525d80418 (patch)
tree62e2ed3f3c71179e161ea6d2314a000d401cbe58
parentb5ba31ba01639a189a0c7077b763a2c3dd02a347 (diff)
#i101955# rudimentary notification support, continued (to be continued; known to not work correctly yet)
-rw-r--r--configmgr2/qa/unit/test.cxx2
-rw-r--r--configmgr2/source/access.cxx583
-rw-r--r--configmgr2/source/access.hxx133
-rw-r--r--configmgr2/source/broadcaster.cxx179
-rw-r--r--configmgr2/source/broadcaster.hxx131
-rw-r--r--configmgr2/source/childaccess.cxx33
-rw-r--r--configmgr2/source/childaccess.hxx20
-rw-r--r--configmgr2/source/components.cxx11
-rw-r--r--configmgr2/source/rootaccess.cxx117
-rw-r--r--configmgr2/source/rootaccess.hxx35
10 files changed, 1031 insertions, 213 deletions
diff --git a/configmgr2/qa/unit/test.cxx b/configmgr2/qa/unit/test.cxx
index 9ce74cf8093c..d7fa8eed753f 100644
--- a/configmgr2/qa/unit/test.cxx
+++ b/configmgr2/qa/unit/test.cxx
@@ -297,7 +297,7 @@ void RecursiveTest::disposing(css::lang::EventObject const & Source)
properties_.clear();
}
-void RecursiveTest::propertyChange(css::beans::PropertyChangeEvent const &)
+void RecursiveTest::propertyChange(css::beans::PropertyChangeEvent const & evt)
throw (css::uno::RuntimeException)
{
CPPUNIT_ASSERT(
diff --git a/configmgr2/source/access.cxx b/configmgr2/source/access.cxx
index 190037db67f1..aef585f7d2a9 100644
--- a/configmgr2/source/access.cxx
+++ b/configmgr2/source/access.cxx
@@ -37,15 +37,37 @@
#include "com/sun/star/beans/PropertyChangeEvent.hpp"
#include "com/sun/star/beans/PropertyVetoException.hpp"
#include "com/sun/star/beans/UnknownPropertyException.hpp"
+#include "com/sun/star/beans/XExactName.hpp"
+#include "com/sun/star/beans/XHierarchicalPropertySet.hpp"
+#include "com/sun/star/beans/XHierarchicalPropertySetInfo.hpp"
+#include "com/sun/star/beans/XMultiHierarchicalPropertySet.hpp"
+#include "com/sun/star/beans/XMultiPropertySet.hpp"
#include "com/sun/star/beans/XPropertiesChangeListener.hpp"
+#include "com/sun/star/beans/XProperty.hpp"
#include "com/sun/star/beans/XPropertyChangeListener.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
#include "com/sun/star/beans/XPropertySetInfo.hpp"
#include "com/sun/star/beans/XVetoableChangeListener.hpp"
+#include "com/sun/star/container/ContainerEvent.hpp"
#include "com/sun/star/container/NoSuchElementException.hpp"
+#include "com/sun/star/container/XContainer.hpp"
#include "com/sun/star/container/XContainerListener.hpp"
+#include "com/sun/star/container/XElementAccess.hpp"
+#include "com/sun/star/container/XHierarchicalName.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/container/XNameContainer.hpp"
+#include "com/sun/star/container/XNamed.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/EventObject.hpp"
#include "com/sun/star/lang/IllegalArgumentException.hpp"
#include "com/sun/star/lang/NoSupportException.hpp"
#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/lang/XEventListener.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/lang/XTypeProvider.hpp"
#include "com/sun/star/lang/XUnoTunnel.hpp"
#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Reference.hxx"
@@ -54,12 +76,14 @@
#include "com/sun/star/uno/Type.hxx"
#include "com/sun/star/uno/TypeClass.hpp"
#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uno/XWeak.hpp"
#include "com/sun/star/util/ElementChange.hpp"
#include "comphelper/sequenceasvector.hxx"
#include "cppu/unotype.hxx"
-#include "cppuhelper/interfacecontainer.hxx"
+#include "cppuhelper/queryinterface.hxx"
#include "cppuhelper/weak.hxx"
#include "osl/diagnose.h"
+#include "osl/interlck.h"
#include "osl/mutex.hxx"
#include "rtl/ref.hxx"
#include "rtl/ustrbuf.hxx"
@@ -92,6 +116,14 @@ namespace css = com::sun::star;
}
+oslInterlockedCount Access::acquireCounting() {
+ return osl_incrementInterlockedCount(&m_refCount);
+}
+
+void Access::releaseNondeleting() {
+ osl_decrementInterlockedCount(&m_refCount);
+}
+
bool Access::isValue() {
rtl::Reference< Node > p(getNode());
switch (p->kind()) {
@@ -130,22 +162,52 @@ void Access::initGlobalBroadcaster(
Modifications const & globalModifications, Broadcaster * broadcaster)
{
OSL_ASSERT(broadcaster != 0);
- cppu::OInterfaceContainerHelper * cont = rBHelper.getContainer(
- cppu::UnoType< css::beans::XPropertyChangeListener >::get());
- if (cont != 0) {
- css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > els(
- cont->getElements()); //TODO: performance
- for (sal_Int32 i = 0; i < els.getLength(); ++i) {
- //TODO: only for matching modifications
- broadcaster->addPropertyChange(
- css::uno::Reference< css::beans::XPropertyChangeListener >(
- els[i], css::uno::UNO_QUERY_THROW),
+ //TODO: only for matching modifications:
+ for (ContainerListeners::iterator i(containerListeners_.begin());
+ i != containerListeners_.end(); ++i)
+ {
+ broadcaster->addContainerNotification(
+ *i,
+ css::container::ContainerEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ css::uno::Any()/*TODO*/, css::uno::Any()/*TODO*/,
+ css::uno::Any()/*TODO*/));
+ }
+ for (PropertyChangeListeners::iterator i(propertyChangeListeners_.begin());
+ i != propertyChangeListeners_.end(); ++i)
+ {
+ for (PropertyChangeListenersElement::iterator j(i->second.begin());
+ j != i->second.end(); ++j)
+ {
+ broadcaster->addPropertyChangeNotification(
+ *j,
css::beans::PropertyChangeEvent(
static_cast< cppu::OWeakObject * >(this), getNameInternal(),
false, -1, css::uno::Any(), css::uno::Any()));
}
}
- //TODO: iterate over children w/ listeners (incl. unmodified ones)
+ for (VetoableChangeListeners::iterator i(vetoableChangeListeners_.begin());
+ i != vetoableChangeListeners_.end(); ++i)
+ {
+ for (VetoableChangeListenersElement::iterator j(i->second.begin());
+ j != i->second.end(); ++j)
+ {
+ broadcaster->addVetoableChangeNotification(
+ *j,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this), getNameInternal(),
+ false, -1, css::uno::Any(), css::uno::Any()));
+ }
+ }
+ for (PropertiesChangeListeners::iterator i(
+ propertiesChangeListeners_.begin());
+ i != propertiesChangeListeners_.end(); ++i)
+ {
+ broadcaster->addPropertiesChangeNotification(
+ *i,
+ css::uno::Sequence< css::beans::PropertyChangeEvent >()/*TODO*/);
+ }
+ //TODO: iterate over children w/ listeners (incl. unmodified ones):
for (ModifiedChildren::iterator i(modifiedChildren_.begin());
i != modifiedChildren_.end(); ++i)
{
@@ -156,66 +218,182 @@ void Access::initGlobalBroadcaster(
}
}
-Access::Access(): AccessBase(lock) {}
+Access::Access(): disposed_(false) {}
Access::~Access() {}
+void Access::initDisposeBroadcaster(Broadcaster * broadcaster) {
+ OSL_ASSERT(broadcaster != 0);
+ for (DisposeListeners::iterator i(disposeListeners_.begin());
+ i != disposeListeners_.end(); ++i)
+ {
+ broadcaster->addDisposeNotification(
+ *i,
+ css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
+ }
+ for (ContainerListeners::iterator i(containerListeners_.begin());
+ i != containerListeners_.end(); ++i)
+ {
+ broadcaster->addDisposeNotification(
+ i->get(),
+ css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
+ }
+ for (PropertyChangeListeners::iterator i(propertyChangeListeners_.begin());
+ i != propertyChangeListeners_.end(); ++i)
+ {
+ for (PropertyChangeListenersElement::iterator j(i->second.begin());
+ j != i->second.end(); ++j)
+ {
+ broadcaster->addDisposeNotification(
+ j->get(),
+ css::lang::EventObject(
+ static_cast< cppu::OWeakObject * >(this)));
+ }
+ }
+ for (VetoableChangeListeners::iterator i(vetoableChangeListeners_.begin());
+ i != vetoableChangeListeners_.end(); ++i)
+ {
+ for (VetoableChangeListenersElement::iterator j(i->second.begin());
+ j != i->second.end(); ++j)
+ {
+ broadcaster->addDisposeNotification(
+ j->get(),
+ css::lang::EventObject(
+ static_cast< cppu::OWeakObject * >(this)));
+ }
+ }
+ for (PropertiesChangeListeners::iterator i(
+ propertiesChangeListeners_.begin());
+ i != propertiesChangeListeners_.end(); ++i)
+ {
+ broadcaster->addDisposeNotification(
+ i->get(),
+ css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
+ }
+ //TODO: iterate over children w/ listeners (incl. unmodified ones):
+ for (ModifiedChildren::iterator i(modifiedChildren_.begin());
+ i != modifiedChildren_.end(); ++i)
+ {
+ rtl::Reference< ChildAccess > child(getModifiedChild(i));
+ if (child.is()) {
+ child->initDisposeBroadcaster(broadcaster);
+ }
+ }
+}
+
+void Access::initLocalBroadcaster(
+ Modifications const & localModifications, Broadcaster * broadcaster)
+{
+ OSL_ASSERT(broadcaster != 0);
+ //TODO: only for matching modifications:
+ for (ContainerListeners::iterator i(containerListeners_.begin());
+ i != containerListeners_.end(); ++i)
+ {
+ broadcaster->addContainerNotification(
+ *i,
+ css::container::ContainerEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ css::uno::Any()/*TODO*/, css::uno::Any()/*TODO*/,
+ css::uno::Any()/*TODO*/));
+ }
+ for (PropertyChangeListeners::iterator i(propertyChangeListeners_.begin());
+ i != propertyChangeListeners_.end(); ++i)
+ {
+ for (PropertyChangeListenersElement::iterator j(i->second.begin());
+ j != i->second.end(); ++j)
+ {
+ broadcaster->addPropertyChangeNotification(
+ *j,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this), getNameInternal(),
+ false, -1, css::uno::Any(), css::uno::Any()));
+ }
+ }
+ for (VetoableChangeListeners::iterator i(vetoableChangeListeners_.begin());
+ i != vetoableChangeListeners_.end(); ++i)
+ {
+ for (VetoableChangeListenersElement::iterator j(i->second.begin());
+ j != i->second.end(); ++j)
+ {
+ broadcaster->addVetoableChangeNotification(
+ *j,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this), getNameInternal(),
+ false, -1, css::uno::Any(), css::uno::Any()));
+ }
+ }
+ for (PropertiesChangeListeners::iterator i(
+ propertiesChangeListeners_.begin());
+ i != propertiesChangeListeners_.end(); ++i)
+ {
+ broadcaster->addPropertiesChangeNotification(
+ *i,
+ css::uno::Sequence< css::beans::PropertyChangeEvent >()/*TODO*/);
+ }
+ //TODO: iterate over children w/ listeners (incl. unmodified ones):
+ for (ModifiedChildren::iterator i(modifiedChildren_.begin());
+ i != modifiedChildren_.end(); ++i)
+ {
+ rtl::Reference< ChildAccess > child(getModifiedChild(i));
+ if (child.is()) {
+ child->initLocalBroadcaster(localModifications, broadcaster);
+ }
+ }
+}
+
css::uno::Any Access::queryInterface(css::uno::Type const & aType)
throw (css::uno::RuntimeException)
{
- OSL_ASSERT(thisIs(IS_ANY));
- osl::MutexGuard g(lock);
- checkLocalizedPropertyAccess();
- css::uno::Any res(AccessBase::queryInterface(aType));
+ css::uno::Any res(OWeakObject::queryInterface(aType));
if (res.hasValue()) {
- if (aType.getTypeName().equalsAsciiL(
- RTL_CONSTASCII_STRINGPARAM("com.sun.beans.XPropertySetInfo")) ||
- aType.getTypeName().equalsAsciiL(
- RTL_CONSTASCII_STRINGPARAM("com.sun.beans.XPropertySet")) ||
- aType.getTypeName().equalsAsciiL(
- RTL_CONSTASCII_STRINGPARAM(
- "com.sun.beans.XMultiPropertySet")) ||
- aType.getTypeName().equalsAsciiL(
- RTL_CONSTASCII_STRINGPARAM(
- "com.sun.beans.XHierarchicalPropertySet")) ||
- aType.getTypeName().equalsAsciiL(
- RTL_CONSTASCII_STRINGPARAM(
- "com.sun.beans.XMultiHierarchicalPropertySet")) ||
- aType.getTypeName().equalsAsciiL(
- RTL_CONSTASCII_STRINGPARAM(
- "com.sun.beans.XHierarchicalPropertySetInfo")))
- {
- if (getNode()->kind() != Node::KIND_GROUP) {
- res.clear();
- }
- } else if (aType.getTypeName().equalsAsciiL(
- RTL_CONSTASCII_STRINGPARAM(
- "com.sun.star.container.XNameReplace")))
- {
- if (!getRootAccess()->isUpdate()) {
- res.clear();
- }
- } else if (aType.getTypeName().equalsAsciiL(
- RTL_CONSTASCII_STRINGPARAM(
- "com.sun.star.container.XNameContainer")))
- {
- if ((getNode()->kind() == Node::KIND_GROUP &&
- !dynamic_cast< GroupNode * >(
- getNode().get())->isExtensible()) ||
- !getRootAccess()->isUpdate())
- {
- res.clear();
- }
- } else if (aType.getTypeName().equalsAsciiL(
- RTL_CONSTASCII_STRINGPARAM(
- "com.sun.star.lang.XSingleServiceFactory")))
+ return res;
+ }
+ res = cppu::queryInterface(
+ aType, static_cast< css::lang::XTypeProvider * >(this),
+ static_cast< css::lang::XServiceInfo * >(this),
+ static_cast< css::lang::XComponent * >(this),
+ static_cast< css::container::XHierarchicalNameAccess * >(this),
+ static_cast< css::container::XContainer * >(this),
+ static_cast< css::beans::XExactName * >(this),
+ static_cast< css::container::XHierarchicalName * >(this),
+ static_cast< css::container::XNamed * >(this),
+ static_cast< css::beans::XProperty * >(this),
+ static_cast< css::container::XElementAccess * >(this),
+ static_cast< css::container::XNameAccess * >(this));
+ if (res.hasValue()) {
+ return res;
+ }
+ if (getNode()->kind() == Node::KIND_GROUP) {
+ res = cppu::queryInterface(
+ aType, static_cast< css::beans::XPropertySetInfo * >(this),
+ static_cast< css::beans::XPropertySet * >(this),
+ static_cast< css::beans::XMultiPropertySet * >(this),
+ static_cast< css::beans::XHierarchicalPropertySet * >(this),
+ static_cast< css::beans::XMultiHierarchicalPropertySet * >(this),
+ static_cast< css::beans::XHierarchicalPropertySetInfo * >(this));
+ if (res.hasValue()) {
+ return res;
+ }
+ }
+ if (getRootAccess()->isUpdate()) {
+ res = cppu::queryInterface(
+ aType, static_cast< css::container::XNameReplace * >(this));
+ if (res.hasValue()) {
+ return res;
+ }
+ if (getNode()->kind() != Node::KIND_GROUP ||
+ dynamic_cast< GroupNode * >(getNode().get())->isExtensible())
{
- if (getNode()->kind() != Node::KIND_SET ||
- !getRootAccess()->isUpdate())
- {
- res.clear();
+ res = cppu::queryInterface(
+ aType, static_cast< css::container::XNameContainer * >(this));
+ if (res.hasValue()) {
+ return res;
}
}
+ if (getNode()->kind() == Node::KIND_SET) {
+ res = cppu::queryInterface(
+ aType, static_cast< css::lang::XSingleServiceFactory * >(this));
+ }
}
return res;
}
@@ -386,6 +564,10 @@ void Access::commitChildChanges(
}
}
+bool Access::isDisposed() const {
+ return disposed_;
+}
+
Access::ModifiedChild::ModifiedChild() {}
Access::ModifiedChild::ModifiedChild(
@@ -393,6 +575,63 @@ Access::ModifiedChild::ModifiedChild(
child(theChild), directlyModified(theDirectlyModified)
{}
+css::uno::Sequence< css::uno::Type > Access::getTypes()
+ throw (css::uno::RuntimeException)
+{
+ OSL_ASSERT(thisIs(IS_ANY));
+ osl::MutexGuard g(lock);
+ checkLocalizedPropertyAccess();
+ comphelper::SequenceAsVector< css::uno::Type > types;
+ types.push_back(cppu::UnoType< css::uno::XInterface >::get());
+ types.push_back(cppu::UnoType< css::uno::XWeak >::get());
+ types.push_back(cppu::UnoType< css::lang::XTypeProvider >::get());
+ types.push_back(cppu::UnoType< css::lang::XServiceInfo >::get());
+ types.push_back(cppu::UnoType< css::lang::XComponent >::get());
+ types.push_back(
+ cppu::UnoType< css::container::XHierarchicalNameAccess >::get());
+ types.push_back(cppu::UnoType< css::container::XContainer >::get());
+ types.push_back(cppu::UnoType< css::beans::XExactName >::get());
+ types.push_back(cppu::UnoType< css::container::XHierarchicalName >::get());
+ types.push_back(cppu::UnoType< css::container::XNamed >::get());
+ types.push_back(cppu::UnoType< css::beans::XProperty >::get());
+ types.push_back(cppu::UnoType< css::container::XElementAccess >::get());
+ types.push_back(cppu::UnoType< css::container::XNameAccess >::get());
+ if (getNode()->kind() == Node::KIND_GROUP) {
+ types.push_back(cppu::UnoType< css::beans::XPropertySetInfo >::get());
+ types.push_back(cppu::UnoType< css::beans::XPropertySet >::get());
+ types.push_back(cppu::UnoType< css::beans::XMultiPropertySet >::get());
+ types.push_back(
+ cppu::UnoType< css::beans::XHierarchicalPropertySet >::get());
+ types.push_back(
+ cppu::UnoType< css::beans::XMultiHierarchicalPropertySet >::get());
+ types.push_back(
+ cppu::UnoType< css::beans::XHierarchicalPropertySetInfo >::get());
+ }
+ if (getRootAccess()->isUpdate()) {
+ types.push_back(cppu::UnoType< css::container::XNameReplace >::get());
+ if (getNode()->kind() != Node::KIND_GROUP ||
+ dynamic_cast< GroupNode * >(getNode().get())->isExtensible())
+ {
+ types.push_back(
+ cppu::UnoType< css::container::XNameContainer >::get());
+ }
+ if (getNode()->kind() == Node::KIND_SET) {
+ types.push_back(
+ cppu::UnoType< css::lang::XSingleServiceFactory >::get());
+ }
+ }
+ return types.getAsConstList();
+}
+
+css::uno::Sequence< sal_Int8 > Access::getImplementationId()
+ throw (css::uno::RuntimeException)
+{
+ OSL_ASSERT(thisIs(IS_ANY));
+ osl::MutexGuard g(lock);
+ checkLocalizedPropertyAccess();
+ return css::uno::Sequence< sal_Int8 >();
+}
+
rtl::OUString Access::getImplementationName() throw (css::uno::RuntimeException)
{
OSL_ASSERT(thisIs(IS_ANY));
@@ -484,6 +723,65 @@ css::uno::Sequence< rtl::OUString > Access::getSupportedServiceNames()
return services.getAsConstList();
}
+void Access::dispose() throw (css::uno::RuntimeException) {
+ OSL_ASSERT(thisIs(IS_ANY));
+ Broadcaster bc;
+ {
+ osl::MutexGuard g(lock);
+ checkLocalizedPropertyAccess();
+ if (getParentAccess().is()) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "configmgr dispose inappropriate Access")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ if (disposed_) {
+ return;
+ }
+ initDisposeBroadcaster(&bc);
+ disposed_ = true;
+ }
+ bc.send();
+}
+
+void Access::addEventListener(
+ css::uno::Reference< css::lang::XEventListener > const & xListener)
+ throw (css::uno::RuntimeException)
+{
+ OSL_ASSERT(thisIs(IS_ANY));
+ {
+ osl::MutexGuard g(lock);
+ checkLocalizedPropertyAccess();
+ if (!xListener.is()) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("null listener")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ if (!disposed_) {
+ disposeListeners_.insert(xListener);
+ return;
+ }
+ }
+ try {
+ xListener->disposing(
+ css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
+ } catch (css::lang::DisposedException &) {}
+}
+
+void Access::removeEventListener(
+ css::uno::Reference< css::lang::XEventListener > const & aListener)
+ throw (css::uno::RuntimeException)
+{
+ OSL_ASSERT(thisIs(IS_ANY));
+ osl::MutexGuard g(lock);
+ checkLocalizedPropertyAccess();
+ DisposeListeners::iterator i(disposeListeners_.find(aListener));
+ if (i != disposeListeners_.end()) {
+ disposeListeners_.erase(i);
+ }
+}
+
css::uno::Type Access::getElementType() throw (css::uno::RuntimeException) {
OSL_ASSERT(thisIs(IS_ANY));
osl::MutexGuard g(lock);
@@ -585,10 +883,23 @@ void Access::addContainerListener(
throw (css::uno::RuntimeException)
{
OSL_ASSERT(thisIs(IS_ANY));
- osl::MutexGuard g(lock);
- checkLocalizedPropertyAccess();
- rBHelper.addListener(
- cppu::UnoType< css::container::XContainerListener >::get(), xListener);
+ {
+ osl::MutexGuard g(lock);
+ checkLocalizedPropertyAccess();
+ if (!xListener.is()) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("null listener")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ if (!disposed_) {
+ containerListeners_.insert(xListener);
+ return;
+ }
+ }
+ try {
+ xListener->disposing(
+ css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
+ } catch (css::lang::DisposedException &) {}
}
void Access::removeContainerListener(
@@ -598,8 +909,10 @@ void Access::removeContainerListener(
OSL_ASSERT(thisIs(IS_ANY));
osl::MutexGuard g(lock);
checkLocalizedPropertyAccess();
- rBHelper.removeListener(
- cppu::UnoType< css::container::XContainerListener >::get(), xListener);
+ ContainerListeners::iterator i(containerListeners_.find(xListener));
+ if (i != containerListeners_.end()) {
+ containerListeners_.erase(i);
+ }
}
rtl::OUString Access::getExactName(rtl::OUString const & aApproximateName)
@@ -799,7 +1112,7 @@ css::uno::Any Access::getPropertyValue(rtl::OUString const & PropertyName)
}
void Access::addPropertyChangeListener(
- rtl::OUString const & /*aPropertyName*/, //TODO
+ rtl::OUString const & aPropertyName,
css::uno::Reference< css::beans::XPropertyChangeListener > const &
xListener)
throw (
@@ -807,12 +1120,26 @@ void Access::addPropertyChangeListener(
css::uno::RuntimeException)
{
OSL_ASSERT(thisIs(IS_GROUP));
- rBHelper.addListener(
- cppu::UnoType< css::beans::XPropertyChangeListener >::get(), xListener);
+ {
+ osl::MutexGuard g(lock);
+ if (!xListener.is()) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("null listener")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ if (!disposed_) {
+ propertyChangeListeners_[aPropertyName].insert(xListener);
+ return;
+ }
+ }
+ try {
+ xListener->disposing(
+ css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
+ } catch (css::lang::DisposedException &) {}
}
void Access::removePropertyChangeListener(
- rtl::OUString const & /*aPropertyName*/, //TODO
+ rtl::OUString const & aPropertyName,
css::uno::Reference< css::beans::XPropertyChangeListener > const &
aListener)
throw (
@@ -820,12 +1147,22 @@ void Access::removePropertyChangeListener(
css::uno::RuntimeException)
{
OSL_ASSERT(thisIs(IS_GROUP));
- rBHelper.removeListener(
- cppu::UnoType< css::beans::XPropertyChangeListener >::get(), aListener);
+ osl::MutexGuard g(lock);
+ PropertyChangeListeners::iterator i(
+ propertyChangeListeners_.find(aPropertyName));
+ if (i != propertyChangeListeners_.end()) {
+ PropertyChangeListenersElement::iterator j(i->second.find(aListener));
+ if (j != i->second.end()) {
+ i->second.erase(j);
+ if (i->second.empty()) {
+ propertyChangeListeners_.erase(i);
+ }
+ }
+ }
}
void Access::addVetoableChangeListener(
- rtl::OUString const & /*PropertyName*/, //TODO
+ rtl::OUString const & PropertyName,
css::uno::Reference< css::beans::XVetoableChangeListener > const &
aListener)
throw (
@@ -833,12 +1170,26 @@ void Access::addVetoableChangeListener(
css::uno::RuntimeException)
{
OSL_ASSERT(thisIs(IS_GROUP));
- rBHelper.addListener(
- cppu::UnoType< css::beans::XVetoableChangeListener >::get(), aListener);
+ {
+ osl::MutexGuard g(lock);
+ if (!aListener.is()) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("null listener")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ if (!disposed_) {
+ vetoableChangeListeners_[PropertyName].insert(aListener);
+ return;
+ }
+ }
+ try {
+ aListener->disposing(
+ css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
+ } catch (css::lang::DisposedException &) {}
}
void Access::removeVetoableChangeListener(
- rtl::OUString const & /*PropertyName*/, //TODO
+ rtl::OUString const & PropertyName,
css::uno::Reference< css::beans::XVetoableChangeListener > const &
aListener)
throw (
@@ -846,8 +1197,18 @@ void Access::removeVetoableChangeListener(
css::uno::RuntimeException)
{
OSL_ASSERT(thisIs(IS_GROUP));
- rBHelper.removeListener(
- cppu::UnoType< css::beans::XVetoableChangeListener >::get(), aListener);
+ osl::MutexGuard g(lock);
+ VetoableChangeListeners::iterator i(
+ vetoableChangeListeners_.find(PropertyName));
+ if (i != vetoableChangeListeners_.end()) {
+ VetoableChangeListenersElement::iterator j(i->second.find(aListener));
+ if (j != i->second.end()) {
+ i->second.erase(j);
+ if (i->second.empty()) {
+ vetoableChangeListeners_.erase(i);
+ }
+ }
+ }
}
void Access::setPropertyValues(
@@ -915,9 +1276,22 @@ void Access::addPropertiesChangeListener(
throw (css::uno::RuntimeException)
{
OSL_ASSERT(thisIs(IS_GROUP));
- rBHelper.addListener(
- cppu::UnoType< css::beans::XPropertiesChangeListener >::get(),
- xListener);
+ {
+ osl::MutexGuard g(lock);
+ if (!xListener.is()) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("null listener")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ if (!disposed_) {
+ propertiesChangeListeners_.insert(xListener);
+ return;
+ }
+ }
+ try {
+ xListener->disposing(
+ css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
+ } catch (css::lang::DisposedException &) {}
}
void Access::removePropertiesChangeListener(
@@ -926,9 +1300,12 @@ void Access::removePropertiesChangeListener(
throw (css::uno::RuntimeException)
{
OSL_ASSERT(thisIs(IS_GROUP));
- rBHelper.removeListener(
- cppu::UnoType< css::beans::XPropertiesChangeListener >::get(),
- xListener);
+ osl::MutexGuard g(lock);
+ PropertiesChangeListeners::iterator i(
+ propertiesChangeListeners_.find(xListener));
+ if (i != propertiesChangeListeners_.end()) {
+ propertiesChangeListeners_.erase(i);
+ }
}
void Access::firePropertiesChangeEvent(
@@ -1099,7 +1476,7 @@ void Access::replaceByName(
css::container::NoSuchElementException,
css::lang::WrappedTargetException, css::uno::RuntimeException)
{
- OSL_ASSERT(thisIs(IS_ANY|IS_UPDATE));
+ OSL_ASSERT(thisIs(IS_UPDATE));
Broadcaster bc;
{
osl::MutexGuard g(lock);
@@ -1323,7 +1700,7 @@ rtl::Reference< ChildAccess > Access::getSubChild(rtl::OUString const & path) {
}
bool Access::setChildProperty(
- rtl::OUString const & name, com::sun::star::uno::Any const & value)
+ rtl::OUString const & name, css::uno::Any const & value)
{
rtl::Reference< ChildAccess > child(getChild(name));
if (!child.is()) {
@@ -1443,36 +1820,6 @@ rtl::Reference< Access > Access::getNotificationRoot() {
}
}
-void Access::initLocalBroadcaster(
- Modifications const & localModifications, Broadcaster * broadcaster)
-{
- OSL_ASSERT(broadcaster != 0);
- cppu::OInterfaceContainerHelper * cont = rBHelper.getContainer(
- cppu::UnoType< css::beans::XPropertyChangeListener >::get());
- if (cont != 0) {
- css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > els(
- cont->getElements()); //TODO: performance
- for (sal_Int32 i = 0; i < els.getLength(); ++i) {
- //TODO: only for matching modifications
- broadcaster->addPropertyChange(
- css::uno::Reference< css::beans::XPropertyChangeListener >(
- els[i], css::uno::UNO_QUERY_THROW),
- css::beans::PropertyChangeEvent(
- static_cast< cppu::OWeakObject * >(this), getNameInternal(),
- false, -1, css::uno::Any(), css::uno::Any()));
- }
- }
- //TODO: iterate over children w/ listeners (incl. unmodified ones)
- for (ModifiedChildren::iterator i(modifiedChildren_.begin());
- i != modifiedChildren_.end(); ++i)
- {
- rtl::Reference< ChildAccess > child(getModifiedChild(i));
- if (child.is()) {
- child->initLocalBroadcaster(localModifications, broadcaster);
- }
- }
-}
-
#if OSL_DEBUG_LEVEL > 0
bool Access::thisIs(int what) {
osl::MutexGuard g(lock);
diff --git a/configmgr2/source/access.hxx b/configmgr2/source/access.hxx
index c2369dea531a..3e286b909a79 100644
--- a/configmgr2/source/access.hxx
+++ b/configmgr2/source/access.hxx
@@ -33,6 +33,7 @@
#include "sal/config.h"
#include <map>
+#include <set>
#include <vector>
#include "boost/noncopyable.hpp"
@@ -56,24 +57,21 @@
#include "com/sun/star/lang/IllegalArgumentException.hpp"
#include "com/sun/star/lang/NoSupportException.hpp"
#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XTypeProvider.hpp"
#include "com/sun/star/lang/XSingleServiceFactory.hpp"
#include "com/sun/star/uno/Exception.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/interlck.h"
#include "rtl/ref.hxx"
#include "sal/types.h"
#include "type.hxx"
-#if !defined INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_15
-#define INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_15
-#define COMPHELPER_IMPLBASE_INTERFACE_NUMBER 15
-#include "comphelper/implbase_var.hxx"
-#undef COMPHELPER_IMPLBASE_INTERFACE_NUMBER
-#endif
-
namespace com { namespace sun { namespace star {
namespace beans {
class XHierarchicalPropertySetInfo;
@@ -83,6 +81,7 @@ namespace com { namespace sun { namespace star {
struct Property;
}
namespace container { class XContainerListener; }
+ namespace lang { class XEventListener; }
namespace uno {
class Any;
class Type;
@@ -101,27 +100,31 @@ class Node;
class RootAccess;
struct Modifications;
-typedef
- comphelper::WeakComponentImplHelper15<
- com::sun::star::lang::XServiceInfo,
- com::sun::star::container::XHierarchicalNameAccess,
- com::sun::star::container::XContainer,
- com::sun::star::beans::XExactName,
- com::sun::star::beans::XPropertySetInfo,
- com::sun::star::container::XHierarchicalName,
- com::sun::star::container::XNamed,
- com::sun::star::beans::XProperty,
- com::sun::star::beans::XPropertySet,
- com::sun::star::beans::XMultiPropertySet,
- com::sun::star::beans::XHierarchicalPropertySet,
- com::sun::star::beans::XMultiHierarchicalPropertySet,
- com::sun::star::beans::XHierarchicalPropertySetInfo,
- com::sun::star::container::XNameContainer,
- com::sun::star::lang::XSingleServiceFactory >
- AccessBase;
-
-class Access: public AccessBase, private boost::noncopyable {
+class Access:
+ public cppu::OWeakObject, public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::lang::XComponent,
+ public com::sun::star::container::XHierarchicalNameAccess,
+ public com::sun::star::container::XContainer,
+ public com::sun::star::beans::XExactName,
+ public com::sun::star::beans::XPropertySetInfo,
+ public com::sun::star::container::XHierarchicalName,
+ public com::sun::star::container::XNamed,
+ public com::sun::star::beans::XProperty,
+ public com::sun::star::beans::XPropertySet,
+ public com::sun::star::beans::XMultiPropertySet,
+ public com::sun::star::beans::XHierarchicalPropertySet,
+ public com::sun::star::beans::XMultiHierarchicalPropertySet,
+ public com::sun::star::beans::XHierarchicalPropertySetInfo,
+ public com::sun::star::container::XNameContainer,
+ public com::sun::star::lang::XSingleServiceFactory,
+ private boost::noncopyable
+{
public:
+ oslInterlockedCount acquireCounting();
+
+ void releaseNondeleting();
+
bool isValue();
void markChildAsModified(rtl::Reference< ChildAccess > const & child);
@@ -136,9 +139,12 @@ public:
virtual bool isFinalized() = 0;
- void initGlobalBroadcaster(
+ virtual void initGlobalBroadcaster(
Modifications const & localModifications, Broadcaster * broadcaster);
+ using OWeakObject::acquire;
+ using OWeakObject::release;
+
protected:
Access();
@@ -153,6 +159,11 @@ protected:
virtual void addSupportedServiceNames(
std::vector< rtl::OUString > * services) = 0;
+ virtual void initDisposeBroadcaster(Broadcaster * broadcaster);
+
+ virtual void initLocalBroadcaster(
+ Modifications const & localModifications, Broadcaster * broadcaster);
+
virtual com::sun::star::uno::Any SAL_CALL queryInterface(
com::sun::star::uno::Type const & aType)
throw (com::sun::star::uno::RuntimeException);
@@ -176,6 +187,8 @@ protected:
void commitChildChanges(bool valid, Modifications * globalModifications);
+ bool isDisposed() const;
+
private:
struct ModifiedChild {
rtl::Reference< ChildAccess > child;
@@ -190,6 +203,12 @@ private:
typedef std::map< rtl::OUString, ModifiedChild > ModifiedChildren;
+ virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL
+ getTypes() throw (com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getImplementationId() throw (com::sun::star::uno::RuntimeException);
+
virtual rtl::OUString SAL_CALL getImplementationName()
throw (com::sun::star::uno::RuntimeException);
@@ -199,6 +218,19 @@ private:
virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
getSupportedServiceNames() throw (com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL dispose()
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL addEventListener(
+ com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >
+ const & xListener)
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL removeEventListener(
+ com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >
+ const & aListener)
+ throw (com::sun::star::uno::RuntimeException);
+
virtual com::sun::star::uno::Type SAL_CALL getElementType()
throw (com::sun::star::uno::RuntimeException);
@@ -474,13 +506,52 @@ private:
rtl::Reference< Access > getNotificationRoot();
- void initLocalBroadcaster(
- Modifications const & localModifications, Broadcaster * broadcaster);
-
typedef std::map< rtl::OUString, ChildAccess * > WeakChildMap;
+ typedef
+ std::multiset<
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener > >
+ DisposeListeners;
+
+ typedef
+ std::multiset<
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XContainerListener > >
+ ContainerListeners;
+
+ typedef
+ std::multiset<
+ com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertyChangeListener > >
+ PropertyChangeListenersElement;
+
+ typedef std::map< rtl::OUString, PropertyChangeListenersElement >
+ PropertyChangeListeners;
+
+ typedef
+ std::multiset<
+ com::sun::star::uno::Reference<
+ com::sun::star::beans::XVetoableChangeListener > >
+ VetoableChangeListenersElement;
+
+ typedef std::map< rtl::OUString, VetoableChangeListenersElement >
+ VetoableChangeListeners;
+
+ typedef
+ std::multiset<
+ com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertiesChangeListener > >
+ PropertiesChangeListeners;
+
ModifiedChildren modifiedChildren_;
WeakChildMap cachedChildren_;
+ DisposeListeners disposeListeners_;
+ ContainerListeners containerListeners_;
+ PropertyChangeListeners propertyChangeListeners_;
+ VetoableChangeListeners vetoableChangeListeners_;
+ PropertiesChangeListeners propertiesChangeListeners_;
+ bool disposed_;
#if OSL_DEBUG_LEVEL > 0
protected:
diff --git a/configmgr2/source/broadcaster.cxx b/configmgr2/source/broadcaster.cxx
index 58f89af69272..a5ff3b7c18ca 100644
--- a/configmgr2/source/broadcaster.cxx
+++ b/configmgr2/source/broadcaster.cxx
@@ -30,9 +30,21 @@
#include "precompiled_configmgr.hxx"
#include "sal/config.h"
+#include "com/sun/star/beans/PropertyVetoException.hpp"
+#include "com/sun/star/beans/XPropertiesChangeListener.hpp"
#include "com/sun/star/beans/XPropertyChangeListener.hpp"
+#include "com/sun/star/beans/XVetoableChangeListener.hpp"
+#include "com/sun/star/container/XContainerListener.hpp"
#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/XEventListener.hpp"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/util/XChangesListener.hpp"
#include "osl/diagnose.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
#include "broadcaster.hxx"
@@ -44,27 +56,174 @@ namespace css = com::sun::star;
}
-void Broadcaster::addPropertyChange(
+void Broadcaster::addDisposeNotification(
+ css::uno::Reference< css::lang::XEventListener > const & listener,
+ css::lang::EventObject const & event)
+{
+ disposeNotifications_.push_back(DisposeNotification(listener, event));
+}
+
+void Broadcaster::addContainerNotification(
+ css::uno::Reference< css::container::XContainerListener > const & listener,
+ css::container::ContainerEvent const & event)
+{
+ containerNotifications_.push_back(ContainerNotification(listener, event));
+}
+
+void Broadcaster::addPropertyChangeNotification(
css::uno::Reference< css::beans::XPropertyChangeListener > const & listener,
- com::sun::star::beans::PropertyChangeEvent const & event)
+ css::beans::PropertyChangeEvent const & event)
+{
+ propertyChangeNotifications_.push_back(
+ PropertyChangeNotification(listener, event));
+}
+
+void Broadcaster::addVetoableChangeNotification(
+ css::uno::Reference< css::beans::XVetoableChangeListener > const & listener,
+ css::beans::PropertyChangeEvent const & event)
{
- propertyChanges_.push_back(PropertyChange(listener, event));
+ vetoableChangeNotifications_.push_back(
+ VetoableChangeNotification(listener, event));
+}
+
+void Broadcaster::addPropertiesChangeNotification(
+ css::uno::Reference< css::beans::XPropertiesChangeListener > const &
+ listener,
+ css::uno::Sequence< css::beans::PropertyChangeEvent > const & event)
+{
+ propertiesChangeNotifications_.push_back(
+ PropertiesChangeNotification(listener, event));
+}
+
+void Broadcaster::addChangesNotification(
+ css::uno::Reference< css::util::XChangesListener > const & listener,
+ css::util::ChangesEvent const & event)
+{
+ changesNotifications_.push_back(ChangesNotification(listener, event));
}
void Broadcaster::send() {
- for (PropertyChanges::iterator i(propertyChanges_.begin());
- i != propertyChanges_.end(); ++i)
+ bool exception = false;
+ for (DisposeNotifications::iterator i(disposeNotifications_.begin());
+ i != disposeNotifications_.end(); ++i) {
+ try {
+ i->listener->disposing(i->event);
+ } catch (css::lang::DisposedException &) {
+ } catch (css::uno::Exception &) {
+ exception = true;
+ }
+ }
+ for (ContainerNotifications::iterator i(containerNotifications_.begin());
+ i != containerNotifications_.end(); ++i)
+ {
+ try {
+ i->listener->elementReplaced(i->event);
+ //TODO: elementInserted/Removed/Replaced
+ } catch (css::lang::DisposedException &) {
+ } catch (css::uno::Exception &) {
+ exception = true;
+ }
+ }
+ for (PropertyChangeNotifications::iterator i(
+ propertyChangeNotifications_.begin());
+ i != propertyChangeNotifications_.end(); ++i)
{
try {
i->listener->propertyChange(i->event);
- } catch (css::lang::DisposedException &) {}
+ } catch (css::lang::DisposedException &) {
+ } catch (css::uno::Exception &) {
+ exception = true;
+ }
+ }
+ for (VetoableChangeNotifications::iterator i(
+ vetoableChangeNotifications_.begin());
+ i != vetoableChangeNotifications_.end(); ++i)
+ {
+ try {
+ i->listener->vetoableChange(i->event);
+ } catch (css::lang::DisposedException &) {
+ } catch (css::beans::PropertyVetoException &) {
+ //TODO
+ } catch (css::uno::Exception &) {
+ exception = true;
+ }
+ }
+ for (PropertiesChangeNotifications::iterator i(
+ propertiesChangeNotifications_.begin());
+ i != propertiesChangeNotifications_.end(); ++i)
+ {
+ try {
+ i->listener->propertiesChange(i->event);
+ } catch (css::lang::DisposedException &) {
+ } catch (css::uno::Exception &) {
+ exception = true;
+ }
+ }
+ for (ChangesNotifications::iterator i(changesNotifications_.begin());
+ i != changesNotifications_.end(); ++i) {
+ try {
+ i->listener->changesOccurred(i->event);
+ } catch (css::lang::DisposedException &) {
+ } catch (css::uno::Exception &) {
+ exception = true;
+ }
+ }
+ if (exception) { //TODO
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "configmgr exceptions during listener notification")),
+ css::uno::Reference< css::uno::XInterface >());
}
}
-Broadcaster::PropertyChange::PropertyChange(
- com::sun::star::uno::Reference<
- com::sun::star::beans::XPropertyChangeListener > const & theListener,
- com::sun::star::beans::PropertyChangeEvent const & theEvent):
+Broadcaster::DisposeNotification::DisposeNotification(
+ css::uno::Reference< css::lang::XEventListener > const & theListener,
+ css::lang::EventObject const & theEvent):
+ listener(theListener), event(theEvent)
+{
+ OSL_ASSERT(theListener.is());
+}
+
+Broadcaster::ContainerNotification::ContainerNotification(
+ css::uno::Reference< css::container::XContainerListener > const &
+ theListener,
+ css::container::ContainerEvent const & theEvent):
+ listener(theListener), event(theEvent)
+{
+ OSL_ASSERT(theListener.is());
+}
+
+Broadcaster::PropertyChangeNotification::PropertyChangeNotification(
+ css::uno::Reference< css::beans::XPropertyChangeListener > const &
+ theListener,
+ css::beans::PropertyChangeEvent const & theEvent):
+ listener(theListener), event(theEvent)
+{
+ OSL_ASSERT(theListener.is());
+}
+
+Broadcaster::VetoableChangeNotification::VetoableChangeNotification(
+ css::uno::Reference< css::beans::XVetoableChangeListener > const &
+ theListener,
+ css::beans::PropertyChangeEvent const & theEvent):
+ listener(theListener), event(theEvent)
+{
+ OSL_ASSERT(theListener.is());
+}
+
+Broadcaster::PropertiesChangeNotification::PropertiesChangeNotification(
+ css::uno::Reference< css::beans::XPropertiesChangeListener > const &
+ theListener,
+ css::uno::Sequence< css::beans::PropertyChangeEvent > const & theEvent):
+ listener(theListener), event(theEvent)
+{
+ OSL_ASSERT(theListener.is());
+}
+
+Broadcaster::ChangesNotification::ChangesNotification(
+ css::uno::Reference< css::util::XChangesListener > const & theListener,
+ css::util::ChangesEvent const & theEvent):
listener(theListener), event(theEvent)
{
OSL_ASSERT(theListener.is());
diff --git a/configmgr2/source/broadcaster.hxx b/configmgr2/source/broadcaster.hxx
index 824def8500b7..00697977e077 100644
--- a/configmgr2/source/broadcaster.hxx
+++ b/configmgr2/source/broadcaster.hxx
@@ -36,12 +36,23 @@
#include "boost/noncopyable.hpp"
#include "com/sun/star/beans/PropertyChangeEvent.hpp"
+#include "com/sun/star/container/ContainerEvent.hpp"
+#include "com/sun/star/lang/EventObject.hpp"
#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/util/ChangesEvent.hpp"
#include "rtl/ref.hxx"
-namespace com { namespace sun { namespace star { namespace beans {
- class XPropertyChangeListener;
-} } } }
+namespace com { namespace sun { namespace star {
+ namespace beans {
+ class XPropertiesChangeListener;
+ class XPropertyChangeListener;
+ class XVetoableChangeListener;
+ }
+ namespace container { class XContainerListener; }
+ namespace lang { class XEventListener; }
+ namespace util { class XChangesListener; }
+} } }
namespace configmgr {
@@ -49,29 +60,133 @@ class Access;
class Broadcaster: private boost::noncopyable {
public:
- void addPropertyChange(
+ void addDisposeNotification(
+ com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >
+ const & listener,
+ com::sun::star::lang::EventObject const & event);
+
+ void addContainerNotification(
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XContainerListener > const & listener,
+ com::sun::star::container::ContainerEvent const & event);
+
+ void addPropertyChangeNotification(
com::sun::star::uno::Reference<
com::sun::star::beans::XPropertyChangeListener > const & listener,
com::sun::star::beans::PropertyChangeEvent const & event);
+ void addVetoableChangeNotification(
+ com::sun::star::uno::Reference<
+ com::sun::star::beans::XVetoableChangeListener > const & listener,
+ com::sun::star::beans::PropertyChangeEvent const & event);
+
+ void addPropertiesChangeNotification(
+ com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertiesChangeListener > const & listener,
+ com::sun::star::uno::Sequence<
+ com::sun::star::beans::PropertyChangeEvent > const & event);
+
+ void addChangesNotification(
+ com::sun::star::uno::Reference< com::sun::star::util::XChangesListener >
+ const & listener,
+ com::sun::star::util::ChangesEvent const & event);
+
void send();
private:
- struct PropertyChange {
+ struct DisposeNotification {
+ com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >
+ listener;
+ com::sun::star::lang::EventObject event;
+
+ DisposeNotification(
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener > const & theListener,
+ com::sun::star::lang::EventObject const & theEvent);
+ };
+
+ struct ContainerNotification {
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XContainerListener > listener;
+ com::sun::star::container::ContainerEvent event;
+
+ ContainerNotification(
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XContainerListener > const &
+ theListener,
+ com::sun::star::container::ContainerEvent const & theEvent);
+ };
+
+ struct PropertyChangeNotification {
com::sun::star::uno::Reference<
com::sun::star::beans::XPropertyChangeListener > listener;
com::sun::star::beans::PropertyChangeEvent event;
- PropertyChange(
+ PropertyChangeNotification(
com::sun::star::uno::Reference<
com::sun::star::beans::XPropertyChangeListener > const &
theListener,
com::sun::star::beans::PropertyChangeEvent const & theEvent);
};
- typedef std::vector< PropertyChange > PropertyChanges;
+ struct VetoableChangeNotification {
+ com::sun::star::uno::Reference<
+ com::sun::star::beans::XVetoableChangeListener > listener;
+ com::sun::star::beans::PropertyChangeEvent event;
+
+ VetoableChangeNotification(
+ com::sun::star::uno::Reference<
+ com::sun::star::beans::XVetoableChangeListener > const &
+ theListener,
+ com::sun::star::beans::PropertyChangeEvent const & theEvent);
+ };
+
+ struct PropertiesChangeNotification {
+ com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertiesChangeListener > listener;
+ com::sun::star::uno::Sequence<
+ com::sun::star::beans::PropertyChangeEvent > event;
+
+ PropertiesChangeNotification(
+ com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertiesChangeListener > const &
+ theListener,
+ com::sun::star::uno::Sequence<
+ com::sun::star::beans::PropertyChangeEvent > const & theEvent);
+ };
+
+ struct ChangesNotification {
+ com::sun::star::uno::Reference< com::sun::star::util::XChangesListener >
+ listener;
+ com::sun::star::util::ChangesEvent event;
+
+ ChangesNotification(
+ com::sun::star::uno::Reference<
+ com::sun::star::util::XChangesListener > const & theListener,
+ com::sun::star::util::ChangesEvent const & theEvent);
+ };
+
+ typedef std::vector< DisposeNotification > DisposeNotifications;
+
+ typedef std::vector< ContainerNotification > ContainerNotifications;
+
+ typedef std::vector< PropertyChangeNotification >
+ PropertyChangeNotifications;
+
+ typedef std::vector< VetoableChangeNotification >
+ VetoableChangeNotifications;
+
+ typedef std::vector< PropertiesChangeNotification >
+ PropertiesChangeNotifications;
+
+ typedef std::vector< ChangesNotification > ChangesNotifications;
- PropertyChanges propertyChanges_;
+ DisposeNotifications disposeNotifications_;
+ ContainerNotifications containerNotifications_;
+ PropertyChangeNotifications propertyChangeNotifications_;
+ VetoableChangeNotifications vetoableChangeNotifications_;
+ PropertiesChangeNotifications propertiesChangeNotifications_;
+ ChangesNotifications changesNotifications_;
};
}
diff --git a/configmgr2/source/childaccess.cxx b/configmgr2/source/childaccess.cxx
index cd912338143a..9937ea0b87a6 100644
--- a/configmgr2/source/childaccess.cxx
+++ b/configmgr2/source/childaccess.cxx
@@ -38,10 +38,9 @@
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/XInterface.hpp"
-#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/queryinterface.hxx"
#include "cppuhelper/weak.hxx"
#include "osl/diagnose.h"
-#include "osl/interlck.h"
#include "osl/mutex.hxx"
#include "rtl/ref.hxx"
#include "rtl/string.h"
@@ -144,6 +143,14 @@ rtl::Reference< Access > ChildAccess::getParentAccess() {
return parent_;
}
+void ChildAccess::acquire() throw () {
+ Access::acquire();
+}
+
+void ChildAccess::release() throw () {
+ Access::release();
+}
+
css::uno::Reference< css::uno::XInterface > ChildAccess::getParent()
throw (css::uno::RuntimeException)
{
@@ -175,14 +182,6 @@ sal_Int64 ChildAccess::getSomething(
? reinterpret_cast< sal_Int64 >(this) : 0;
}
-oslInterlockedCount ChildAccess::acquireCounting() {
- return osl_incrementInterlockedCount(&m_refCount);
-}
-
-void ChildAccess::releaseNondeleting() {
- osl_decrementInterlockedCount(&m_refCount);
-}
-
void ChildAccess::bind(
rtl::Reference< RootAccess > const & root,
rtl::Reference< Access > const & parent, rtl::OUString const & name)
@@ -344,4 +343,18 @@ void ChildAccess::addSupportedServiceNames(
"com.sun.star.configuration.SetElement")));
}
+css::uno::Any ChildAccess::queryInterface(css::uno::Type const & aType)
+ throw (css::uno::RuntimeException)
+{
+ OSL_ASSERT(thisIs(IS_ANY));
+ osl::MutexGuard g(lock);
+ checkLocalizedPropertyAccess();
+ css::uno::Any res(Access::queryInterface(aType));
+ return res.hasValue()
+ ? res
+ : cppu::queryInterface(
+ aType, static_cast< css::container::XChild * >(this),
+ static_cast< css::lang::XUnoTunnel * >(this));
+}
+
}
diff --git a/configmgr2/source/childaccess.hxx b/configmgr2/source/childaccess.hxx
index b97086b66032..cd5f1ead3421 100644
--- a/configmgr2/source/childaccess.hxx
+++ b/configmgr2/source/childaccess.hxx
@@ -41,8 +41,6 @@
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
-#include "cppuhelper/implbase2.hxx"
-#include "osl/interlck.h"
#include "rtl/ref.hxx"
#include "sal/types.h"
@@ -50,6 +48,7 @@
namespace com { namespace sun { namespace star { namespace uno {
class Any;
+ class Type;
class XInterface;
} } } }
@@ -60,9 +59,8 @@ class RootAccess;
struct Modifications;
class ChildAccess:
- public cppu::ImplInheritanceHelper2<
- Access, com::sun::star::container::XChild,
- com::sun::star::lang::XUnoTunnel >
+ public Access, public com::sun::star::container::XChild,
+ public com::sun::star::lang::XUnoTunnel
{
public:
static com::sun::star::uno::Sequence< sal_Int8 > getTunnelId();
@@ -90,6 +88,10 @@ public:
virtual rtl::Reference< Access > getParentAccess();
+ virtual void SAL_CALL acquire() throw ();
+
+ virtual void SAL_CALL release() throw ();
+
virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface >
SAL_CALL getParent()
throw (com::sun::star::uno::RuntimeException);
@@ -105,10 +107,6 @@ public:
com::sun::star::uno::Sequence< sal_Int8 > const & aIdentifier)
throw (com::sun::star::uno::RuntimeException);
- oslInterlockedCount acquireCounting();
-
- void releaseNondeleting();
-
void bind(
rtl::Reference< RootAccess > const & root,
rtl::Reference< Access > const & parent, rtl::OUString const & name)
@@ -136,6 +134,10 @@ private:
virtual void addSupportedServiceNames(
std::vector< rtl::OUString > * services);
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface(
+ com::sun::star::uno::Type const & aType)
+ throw (com::sun::star::uno::RuntimeException);
+
rtl::Reference< RootAccess > root_;
rtl::Reference< Access > parent_; // null iff free node
rtl::OUString name_;
diff --git a/configmgr2/source/components.cxx b/configmgr2/source/components.cxx
index 7b58aa5abdf4..67728113b60e 100644
--- a/configmgr2/source/components.cxx
+++ b/configmgr2/source/components.cxx
@@ -140,8 +140,15 @@ void Components::initGlobalBroadcaster(
rtl::Reference< RootAccess > const & exclude, Broadcaster * broadcaster)
{
for (WeakRootSet::iterator i(roots_.begin()); i != roots_.end(); ++i) {
- if (*i != exclude.get()) {
- (*i)->initGlobalBroadcaster(globalModifications, broadcaster);
+ rtl::Reference< RootAccess > root;
+ if ((*i)->acquireCounting() > 1) {
+ root.set(*i); // must not throw
+ }
+ (*i)->releaseNondeleting();
+ if (root.is()) {
+ if (root != exclude) {
+ root->initGlobalBroadcaster(globalModifications, broadcaster);
+ }
}
}
}
diff --git a/configmgr2/source/rootaccess.cxx b/configmgr2/source/rootaccess.cxx
index 59ecbefb914a..96d4a2949055 100644
--- a/configmgr2/source/rootaccess.cxx
+++ b/configmgr2/source/rootaccess.cxx
@@ -32,13 +32,17 @@
#include <vector>
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/EventObject.hpp"
#include "com/sun/star/lang/WrappedTargetException.hpp"
#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/util/ChangesEvent.hpp"
#include "com/sun/star/util/ChangesSet.hpp"
#include "com/sun/star/util/ElementChange.hpp"
#include "com/sun/star/util/XChangesListener.hpp"
#include "comphelper/sequenceasvector.hxx"
#include "cppu/unotype.hxx"
+#include "cppuhelper/queryinterface.hxx"
#include "cppuhelper/weak.hxx"
#include "osl/diagnose.h"
#include "osl/mutex.hxx"
@@ -67,6 +71,34 @@ RootAccess::RootAccess(
path_(path), locale_(locale), update_(update)
{}
+void RootAccess::initGlobalBroadcaster(
+ Modifications const & globalModifications, Broadcaster * broadcaster)
+{
+ OSL_ASSERT(broadcaster != 0);
+ //TODO: only for matching modifications:
+ for (ChangesListeners::iterator i(changesListeners_.begin());
+ i != changesListeners_.end(); ++i)
+ {
+ broadcaster->addChangesNotification(
+ *i,
+ css::util::ChangesEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ css::uno::makeAny(*static_cast< cppu::OWeakObject * >(this)),
+ //TODO: XInterface or something else?
+ css::uno::Sequence< css::util::ElementChange >()/*TODO*/));
+
+ }
+ Access::initGlobalBroadcaster(globalModifications, broadcaster);
+}
+
+void RootAccess::acquire() throw () {
+ Access::acquire();
+}
+
+void RootAccess::release() throw () {
+ Access::release();
+}
+
rtl::OUString RootAccess::getLocale() const {
return locale_;
}
@@ -139,19 +171,56 @@ void RootAccess::addSupportedServiceNames(
}
}
+void RootAccess::initDisposeBroadcaster(Broadcaster * broadcaster) {
+ OSL_ASSERT(broadcaster != 0);
+ for (ChangesListeners::iterator i(changesListeners_.begin());
+ i != changesListeners_.end(); ++i)
+ {
+ broadcaster->addDisposeNotification(
+ i->get(),
+ css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
+ }
+ Access::initDisposeBroadcaster(broadcaster);
+}
+
+void RootAccess::initLocalBroadcaster(
+ Modifications const & localModifications, Broadcaster * broadcaster)
+{
+ OSL_ASSERT(broadcaster != 0);
+ //TODO: only for matching modifications:
+ for (ChangesListeners::iterator i(changesListeners_.begin());
+ i != changesListeners_.end(); ++i)
+ {
+ broadcaster->addChangesNotification(
+ *i,
+ css::util::ChangesEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ css::uno::makeAny(*static_cast< cppu::OWeakObject * >(this)),
+ //TODO: XInterface or something else?
+ css::uno::Sequence< css::util::ElementChange >()/*TODO*/));
+
+ }
+ Access::initLocalBroadcaster(localModifications, broadcaster);
+}
+
css::uno::Any RootAccess::queryInterface(css::uno::Type const & aType)
throw (css::uno::RuntimeException)
{
OSL_ASSERT(thisIs(IS_ANY));
osl::MutexGuard g(lock);
checkLocalizedPropertyAccess();
- css::uno::Any res(RootAccessBase::queryInterface(aType));
- if (res.hasValue() &&
- aType.getTypeName().equalsAsciiL(
- RTL_CONSTASCII_STRINGPARAM("com.sun.star.util.XChangesBatch")) &&
- !update_)
- {
- res.clear();
+ css::uno::Any res(Access::queryInterface(aType));
+ if (res.hasValue()) {
+ return res;
+ }
+ res = cppu::queryInterface(
+ aType, static_cast< css::util::XChangesNotifier * >(this));
+ if (res.hasValue()) {
+ return res;
+ }
+ if (!res.hasValue() && update_) {
+ res = cppu::queryInterface(
+ aType, static_cast< css::util::XChangesBatch * >(this));
}
return res;
}
@@ -161,10 +230,24 @@ void RootAccess::addChangesListener(
throw (css::uno::RuntimeException)
{
OSL_ASSERT(thisIs(IS_ANY));
- osl::MutexGuard g(lock);
- checkLocalizedPropertyAccess();
- rBHelper.addListener(
- cppu::UnoType< css::util::XChangesListener >::get(), aListener);
+ {
+ osl::MutexGuard g(lock);
+ checkLocalizedPropertyAccess();
+ if (!aListener.is()) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("null listener")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ if (!isDisposed()) {
+ changesListeners_.insert(aListener);
+ return;
+ }
+ }
+ try {
+ aListener->disposing(
+ css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
+ } catch (css::lang::DisposedException &) {}
+ //TODO: actually fire changes events through Broadcaster::send
}
void RootAccess::removeChangesListener(
@@ -174,14 +257,16 @@ void RootAccess::removeChangesListener(
OSL_ASSERT(thisIs(IS_ANY));
osl::MutexGuard g(lock);
checkLocalizedPropertyAccess();
- rBHelper.removeListener(
- cppu::UnoType< css::util::XChangesListener >::get(), aListener);
+ ChangesListeners::iterator i(changesListeners_.find(aListener));
+ if (i != changesListeners_.end()) {
+ changesListeners_.erase(i);
+ }
}
void RootAccess::commitChanges()
throw (css::lang::WrappedTargetException, css::uno::RuntimeException)
{
- OSL_ASSERT(thisIs(IS_ANY|IS_UPDATE));
+ OSL_ASSERT(thisIs(IS_UPDATE));
Broadcaster bc;
{
osl::MutexGuard g(lock);
@@ -200,7 +285,7 @@ void RootAccess::commitChanges()
}
sal_Bool RootAccess::hasPendingChanges() throw (css::uno::RuntimeException) {
- OSL_ASSERT(thisIs(IS_ANY|IS_UPDATE));
+ OSL_ASSERT(thisIs(IS_UPDATE));
osl::MutexGuard g(lock);
checkLocalizedPropertyAccess();
//TODO: Optimize:
@@ -212,7 +297,7 @@ sal_Bool RootAccess::hasPendingChanges() throw (css::uno::RuntimeException) {
css::util::ChangesSet RootAccess::getPendingChanges()
throw (css::uno::RuntimeException)
{
- OSL_ASSERT(thisIs(IS_ANY|IS_UPDATE));
+ OSL_ASSERT(thisIs(IS_UPDATE));
osl::MutexGuard g(lock);
checkLocalizedPropertyAccess();
comphelper::SequenceAsVector< css::util::ElementChange > changes;
diff --git a/configmgr2/source/rootaccess.hxx b/configmgr2/source/rootaccess.hxx
index ea67ff2aa2de..3cf8e0620f5c 100644
--- a/configmgr2/source/rootaccess.hxx
+++ b/configmgr2/source/rootaccess.hxx
@@ -32,12 +32,13 @@
#include "sal/config.h"
+#include <set>
+
#include "com/sun/star/lang/WrappedTargetException.hpp"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/util/ChangesSet.hpp"
#include "com/sun/star/util/XChangesBatch.hpp"
#include "com/sun/star/util/XChangesNotifier.hpp"
-#include "cppuhelper/implbase2.hxx"
#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
@@ -54,19 +55,25 @@ namespace com { namespace sun { namespace star {
namespace configmgr {
+class Broadcaster;
class Node;
+struct Modifications;
-typedef
- cppu::ImplInheritanceHelper2<
- Access, com::sun::star::util::XChangesNotifier,
- com::sun::star::util::XChangesBatch >
- RootAccessBase;
-
-class RootAccess: public RootAccessBase {
+class RootAccess:
+ public Access, public com::sun::star::util::XChangesNotifier,
+ public com::sun::star::util::XChangesBatch
+{
public:
RootAccess(
rtl::OUString const & path, rtl::OUString const & locale, bool update);
+ virtual void initGlobalBroadcaster(
+ Modifications const & localModifications, Broadcaster * broadcaster);
+
+ virtual void SAL_CALL acquire() throw ();
+
+ virtual void SAL_CALL release() throw ();
+
rtl::OUString getLocale() const;
bool isUpdate() const;
@@ -91,6 +98,11 @@ private:
virtual void addSupportedServiceNames(
std::vector< rtl::OUString > * services);
+ virtual void initDisposeBroadcaster(Broadcaster * broadcaster);
+
+ virtual void initLocalBroadcaster(
+ Modifications const & localModifications, Broadcaster * broadcaster);
+
virtual com::sun::star::uno::Any SAL_CALL queryInterface(
com::sun::star::uno::Type const & aType)
throw (com::sun::star::uno::RuntimeException);
@@ -116,12 +128,19 @@ private:
virtual com::sun::star::util::ChangesSet SAL_CALL getPendingChanges()
throw (com::sun::star::uno::RuntimeException);
+ typedef
+ std::multiset<
+ com::sun::star::uno::Reference<
+ com::sun::star::util::XChangesListener > >
+ ChangesListeners;
+
rtl::OUString path_;
rtl::OUString locale_;
bool update_;
bool finalized_;
rtl::Reference< Node > node_;
rtl::OUString name_;
+ ChangesListeners changesListeners_;
};
}