diff options
author | sb <sb@openoffice.org> | 2009-09-21 13:14:11 +0200 |
---|---|---|
committer | sb <sb@openoffice.org> | 2009-09-21 13:14:11 +0200 |
commit | b5ba31ba01639a189a0c7077b763a2c3dd02a347 (patch) | |
tree | f882b1bb2c32f5e0bee52e74fe3e8a70073c46b9 | |
parent | 07efdd981d2da9de49b4887949c5cd6205335a44 (diff) |
#i101955# rudimentary notification support (to be continued; known to not work correctly yet)
-rw-r--r-- | configmgr2/qa/unit/test.cxx | 5 | ||||
-rw-r--r-- | configmgr2/source/access.cxx | 162 | ||||
-rw-r--r-- | configmgr2/source/access.hxx | 12 | ||||
-rw-r--r-- | configmgr2/source/broadcaster.cxx | 73 | ||||
-rw-r--r-- | configmgr2/source/broadcaster.hxx | 79 | ||||
-rw-r--r-- | configmgr2/source/childaccess.cxx | 20 | ||||
-rw-r--r-- | configmgr2/source/childaccess.hxx | 7 | ||||
-rw-r--r-- | configmgr2/source/components.cxx | 22 | ||||
-rw-r--r-- | configmgr2/source/components.hxx | 17 | ||||
-rw-r--r-- | configmgr2/source/configurationprovider.cxx | 2 | ||||
-rw-r--r-- | configmgr2/source/data.cxx | 22 | ||||
-rw-r--r-- | configmgr2/source/data.hxx | 6 | ||||
-rw-r--r-- | configmgr2/source/makefile.mk | 2 | ||||
-rw-r--r-- | configmgr2/source/modifications.cxx | 63 | ||||
-rw-r--r-- | configmgr2/source/modifications.hxx | 54 | ||||
-rw-r--r-- | configmgr2/source/rootaccess.cxx | 29 | ||||
-rw-r--r-- | configmgr2/source/writemodfile.cxx | 5 | ||||
-rw-r--r-- | configmgr2/source/xcuparser.cxx | 4 |
18 files changed, 496 insertions, 88 deletions
diff --git a/configmgr2/qa/unit/test.cxx b/configmgr2/qa/unit/test.cxx index 0cb1a8d0940b..9ce74cf8093c 100644 --- a/configmgr2/qa/unit/test.cxx +++ b/configmgr2/qa/unit/test.cxx @@ -281,7 +281,7 @@ void RecursiveTest::test() { properties_->addPropertyChangeListener( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Label")), this); step(); - //TODO: CPPUNIT_ASSERT(count_ == 0); + CPPUNIT_ASSERT(count_ == 0); css::uno::Reference< css::lang::XComponent >( properties_, css::uno::UNO_QUERY_THROW)->dispose(); } @@ -300,6 +300,9 @@ void RecursiveTest::disposing(css::lang::EventObject const & Source) void RecursiveTest::propertyChange(css::beans::PropertyChangeEvent const &) throw (css::uno::RuntimeException) { + CPPUNIT_ASSERT( + evt.Source == properties_ && + evt.PropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Label"))); if (count_ > 0) { --count_; step(); diff --git a/configmgr2/source/access.cxx b/configmgr2/source/access.cxx index 2e501b43417e..190037db67f1 100644 --- a/configmgr2/source/access.cxx +++ b/configmgr2/source/access.cxx @@ -57,7 +57,7 @@ #include "com/sun/star/util/ElementChange.hpp" #include "comphelper/sequenceasvector.hxx" #include "cppu/unotype.hxx" -#include "cppuhelper/exc_hlp.hxx" +#include "cppuhelper/interfacecontainer.hxx" #include "cppuhelper/weak.hxx" #include "osl/diagnose.h" #include "osl/mutex.hxx" @@ -68,6 +68,7 @@ #include "sal/types.h" #include "access.hxx" +#include "broadcaster.hxx" #include "childaccess.hxx" #include "components.hxx" #include "data.hxx" @@ -75,6 +76,7 @@ #include "localizedpropertynode.hxx" #include "localizedvaluenode.hxx" #include "lock.hxx" +#include "modifications.hxx" #include "node.hxx" #include "nodemap.hxx" #include "propertynode.hxx" @@ -124,6 +126,36 @@ void Access::releaseChild(rtl::OUString const & name) { cachedChildren_.erase(name); } +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), + 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->initGlobalBroadcaster(globalModifications, broadcaster); + } + } +} + Access::Access(): AccessBase(lock) {} Access::~Access() {} @@ -300,14 +332,17 @@ void Access::reportChildChanges( } } -void Access::commitChildChanges(bool valid) { +void Access::commitChildChanges( + bool valid, Modifications * globalModifications) +{ + OSL_ASSERT(globalModifications != 0); while (!modifiedChildren_.empty()) { bool childValid = valid; ModifiedChildren::iterator i(modifiedChildren_.begin()); rtl::Reference< ChildAccess > child(getModifiedChild(i)); if (child.is()) { childValid = childValid && !child->isFinalized(); - child->commitChanges(childValid); + child->commitChanges(childValid, globalModifications); //TODO: currently, this is called here for directly inserted // children as well as for children whose sub-children were // modified (and should never be called for directly removed @@ -338,17 +373,26 @@ void Access::commitChildChanges(bool valid) { } } if (childValid && i->second.directlyModified) { - Components::singleton().addModification( + rtl::OUString path( getAbsolutePath() + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) + Data::createSegment( i->second.child->getNode()->getTemplateName(), i->first)); + Components::singleton().addModification(path); + globalModifications->add(path); } i->second.child->committed(); modifiedChildren_.erase(i); } } +Access::ModifiedChild::ModifiedChild() {} + +Access::ModifiedChild::ModifiedChild( + rtl::Reference< ChildAccess > const & theChild, bool theDirectlyModified): + child(theChild), directlyModified(theDirectlyModified) +{} + rtl::OUString Access::getImplementationName() throw (css::uno::RuntimeException) { OSL_ASSERT(thisIs(IS_ANY)); @@ -897,6 +941,7 @@ void Access::firePropertiesChangeEvent( css::uno::Sequence< css::beans::PropertyChangeEvent > events( aPropertyNames.getLength()); for (sal_Int32 i = 0; i < events.getLength(); ++i) { + events[i].Source = static_cast< cppu::OWeakObject * >(this); events[i].PropertyName = aPropertyNames[i]; events[i].Further = false; events[i].PropertyHandle = -1; @@ -935,7 +980,8 @@ void Access::setHierarchicalPropertyValue( static_cast< cppu::OWeakObject * >(this)); } child->checkFinalized(); - child->setProperty(aValue); + Modifications localMods; //TODO: use + child->setProperty(aValue, &localMods); } css::uno::Any Access::getHierarchicalPropertyValue( @@ -992,7 +1038,8 @@ void Access::setHierarchicalPropertyValues( static_cast< cppu::OWeakObject * >(this), -1); } child->checkFinalized(); - child->setProperty(Values[i]); + Modifications localMods; //TODO: use + child->setProperty(Values[i], &localMods); } } @@ -1053,33 +1100,40 @@ void Access::replaceByName( css::lang::WrappedTargetException, css::uno::RuntimeException) { OSL_ASSERT(thisIs(IS_ANY|IS_UPDATE)); - osl::MutexGuard g(lock); - checkLocalizedPropertyAccess(); - rtl::Reference< ChildAccess > child(getChild(aName)); - if (!child.is()) { - throw css::container::NoSuchElementException( - aName, static_cast< cppu::OWeakObject * >(this)); - } - child->checkFinalized(); - switch (getNode()->kind()) { - case Node::KIND_LOCALIZED_PROPERTY: - case Node::KIND_GROUP: - child->setProperty(aElement); - break; - case Node::KIND_SET: - { - rtl::Reference< ChildAccess > freeAcc(getFreeSetMember(aElement)); - rtl::Reference< RootAccess > root(getRootAccess()); - child->unbind(); // must not throw - freeAcc->bind(root, this, aName); // must not throw - markChildAsModified(freeAcc); //TODO: must not throw - //TODO notify change + Broadcaster bc; + { + osl::MutexGuard g(lock); + checkLocalizedPropertyAccess(); + rtl::Reference< ChildAccess > child(getChild(aName)); + if (!child.is()) { + throw css::container::NoSuchElementException( + aName, static_cast< cppu::OWeakObject * >(this)); } - break; - default: - OSL_ASSERT(false); // this cannot happen - break; + child->checkFinalized(); + Modifications localMods; + switch (getNode()->kind()) { + case Node::KIND_LOCALIZED_PROPERTY: + case Node::KIND_GROUP: + child->setProperty(aElement, &localMods); + break; + case Node::KIND_SET: + { + rtl::Reference< ChildAccess > freeAcc( + getFreeSetMember(aElement)); + rtl::Reference< RootAccess > root(getRootAccess()); + child->unbind(); // must not throw + freeAcc->bind(root, this, aName); // must not throw + markChildAsModified(freeAcc); //TODO: must not throw + //TODO notify change + } + break; + default: + OSL_ASSERT(false); // this cannot happen + break; + } + getNotificationRoot()->initLocalBroadcaster(localMods, &bc); } + bc.send(); } void Access::insertByName( @@ -1276,7 +1330,8 @@ bool Access::setChildProperty( return false; } child->checkFinalized(); - child->setProperty(value); + Modifications localMods; //TODO: use + child->setProperty(value, &localMods); return true; } @@ -1378,12 +1433,45 @@ rtl::Reference< ChildAccess > Access::getFreeSetMember( return freeAcc; } -Access::ModifiedChild::ModifiedChild() {} +rtl::Reference< Access > Access::getNotificationRoot() { + for (rtl::Reference< Access > p(this);;) { + rtl::Reference< Access > parent(p->getParentAccess()); + if (!parent.is()) { + return p; + } + p = parent; + } +} -Access::ModifiedChild::ModifiedChild( - rtl::Reference< ChildAccess > const & theChild, bool theDirectlyModified): - child(theChild), directlyModified(theDirectlyModified) -{} +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) { diff --git a/configmgr2/source/access.hxx b/configmgr2/source/access.hxx index 1daed272450d..c2369dea531a 100644 --- a/configmgr2/source/access.hxx +++ b/configmgr2/source/access.hxx @@ -94,10 +94,12 @@ namespace rtl { class OUString; } namespace configmgr { +class Broadcaster; class Change; class ChildAccess; class Node; class RootAccess; +struct Modifications; typedef comphelper::WeakComponentImplHelper15< @@ -134,6 +136,9 @@ public: virtual bool isFinalized() = 0; + void initGlobalBroadcaster( + Modifications const & localModifications, Broadcaster * broadcaster); + protected: Access(); @@ -169,7 +174,7 @@ protected: void reportChildChanges( std::vector< com::sun::star::util::ElementChange > * changes); - void commitChildChanges(bool valid); + void commitChildChanges(bool valid, Modifications * globalModifications); private: struct ModifiedChild { @@ -467,6 +472,11 @@ private: rtl::Reference< ChildAccess > getFreeSetMember( com::sun::star::uno::Any const & value); + rtl::Reference< Access > getNotificationRoot(); + + void initLocalBroadcaster( + Modifications const & localModifications, Broadcaster * broadcaster); + typedef std::map< rtl::OUString, ChildAccess * > WeakChildMap; ModifiedChildren modifiedChildren_; diff --git a/configmgr2/source/broadcaster.cxx b/configmgr2/source/broadcaster.cxx new file mode 100644 index 000000000000..58f89af69272 --- /dev/null +++ b/configmgr2/source/broadcaster.cxx @@ -0,0 +1,73 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* $RCSfile: code,v $ +* +* $Revision: 1.4 $ +* +* 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. +************************************************************************/ + +#include "precompiled_configmgr.hxx" +#include "sal/config.h" + +#include "com/sun/star/beans/XPropertyChangeListener.hpp" +#include "com/sun/star/lang/DisposedException.hpp" +#include "osl/diagnose.hxx" + +#include "broadcaster.hxx" + +namespace configmgr { + +namespace { + +namespace css = com::sun::star; + +} + +void Broadcaster::addPropertyChange( + css::uno::Reference< css::beans::XPropertyChangeListener > const & listener, + com::sun::star::beans::PropertyChangeEvent const & event) +{ + propertyChanges_.push_back(PropertyChange(listener, event)); +} + +void Broadcaster::send() { + for (PropertyChanges::iterator i(propertyChanges_.begin()); + i != propertyChanges_.end(); ++i) + { + try { + i->listener->propertyChange(i->event); + } catch (css::lang::DisposedException &) {} + } +} + +Broadcaster::PropertyChange::PropertyChange( + com::sun::star::uno::Reference< + com::sun::star::beans::XPropertyChangeListener > const & theListener, + com::sun::star::beans::PropertyChangeEvent const & theEvent): + listener(theListener), event(theEvent) +{ + OSL_ASSERT(theListener.is()); +} + +} diff --git a/configmgr2/source/broadcaster.hxx b/configmgr2/source/broadcaster.hxx new file mode 100644 index 000000000000..824def8500b7 --- /dev/null +++ b/configmgr2/source/broadcaster.hxx @@ -0,0 +1,79 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* $RCSfile: code,v $ +* +* $Revision: 1.4 $ +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +#ifndef INCLUDED_CONFIGMGR_SOURCE_BROADCASTER_HXX +#define INCLUDED_CONFIGMGR_SOURCE_BROADCASTER_HXX + +#include "sal/config.h" + +#include <vector> + +#include "boost/noncopyable.hpp" +#include "com/sun/star/beans/PropertyChangeEvent.hpp" +#include "com/sun/star/uno/Reference.hxx" +#include "rtl/ref.hxx" + +namespace com { namespace sun { namespace star { namespace beans { + class XPropertyChangeListener; +} } } } + +namespace configmgr { + +class Access; + +class Broadcaster: private boost::noncopyable { +public: + void addPropertyChange( + com::sun::star::uno::Reference< + com::sun::star::beans::XPropertyChangeListener > const & listener, + com::sun::star::beans::PropertyChangeEvent const & event); + + void send(); + +private: + struct PropertyChange { + com::sun::star::uno::Reference< + com::sun::star::beans::XPropertyChangeListener > listener; + com::sun::star::beans::PropertyChangeEvent event; + + PropertyChange( + com::sun::star::uno::Reference< + com::sun::star::beans::XPropertyChangeListener > const & + theListener, + com::sun::star::beans::PropertyChangeEvent const & theEvent); + }; + + typedef std::vector< PropertyChange > PropertyChanges; + + PropertyChanges propertyChanges_; +}; + +} + +#endif diff --git a/configmgr2/source/childaccess.cxx b/configmgr2/source/childaccess.cxx index 4dc0e2e126c4..cd912338143a 100644 --- a/configmgr2/source/childaccess.cxx +++ b/configmgr2/source/childaccess.cxx @@ -59,6 +59,7 @@ #include "localizedpropertynode.hxx" #include "localizedvaluenode.hxx" #include "lock.hxx" +#include "modifications.hxx" #include "node.hxx" #include "propertynode.hxx" #include "rootaccess.hxx" @@ -209,7 +210,10 @@ void ChildAccess::setNode(rtl::Reference< Node > const & node) { node_ = node; } -void ChildAccess::setProperty(css::uno::Any const & value) { +void ChildAccess::setProperty( + css::uno::Any const & value, Modifications * localModifications) +{ + OSL_ASSERT(localModifications != 0); Type type = TYPE_ERROR; bool nillable = false; switch (node_->kind()) { @@ -226,7 +230,7 @@ void ChildAccess::setProperty(css::uno::Any const & value) { if (!Components::allLocales(locale)) { rtl::Reference< ChildAccess > child(getChild(locale)); if (child.is()) { - child->setProperty(value); + child->setProperty(value, localModifications); } else { insertLocalizedValueChild(locale, value); } @@ -248,7 +252,7 @@ void ChildAccess::setProperty(css::uno::Any const & value) { checkValue(value, type, nillable); getParentAccess()->markChildAsModified(this); changedValue_.reset(new css::uno::Any(value)); - //TODO notify change + localModifications->add(getRelativePath()); } css::uno::Any ChildAccess::asValue() { @@ -294,10 +298,14 @@ css::uno::Any ChildAccess::asValue() { static_cast< cppu::OWeakObject * >(this))); } -void ChildAccess::commitChanges(bool valid) { - commitChildChanges(valid); +void ChildAccess::commitChanges(bool valid, Modifications * globalModifications) +{ + OSL_ASSERT(globalModifications != 0); + commitChildChanges(valid, globalModifications); if (valid && changedValue_.get() != 0) { - Components::singleton().addModification(getAbsolutePath()); + rtl::OUString path(getAbsolutePath()); + Components::singleton().addModification(path); + globalModifications->add(path); switch (node_->kind()) { case Node::KIND_PROPERTY: dynamic_cast< PropertyNode * >(node_.get())->setValue( diff --git a/configmgr2/source/childaccess.hxx b/configmgr2/source/childaccess.hxx index f3b7fecff072..b97086b66032 100644 --- a/configmgr2/source/childaccess.hxx +++ b/configmgr2/source/childaccess.hxx @@ -57,6 +57,7 @@ namespace configmgr { class Node; class RootAccess; +struct Modifications; class ChildAccess: public cppu::ImplInheritanceHelper2< @@ -121,11 +122,13 @@ public: void setNode(rtl::Reference< Node > const & node); - void setProperty(com::sun::star::uno::Any const & value); + void setProperty( + com::sun::star::uno::Any const & value, + Modifications * localModifications); com::sun::star::uno::Any asValue(); - void commitChanges(bool valid); + void commitChanges(bool valid, Modifications * globalModifications); private: virtual ~ChildAccess(); diff --git a/configmgr2/source/components.cxx b/configmgr2/source/components.cxx index e90ffea65d0e..7b58aa5abdf4 100644 --- a/configmgr2/source/components.cxx +++ b/configmgr2/source/components.cxx @@ -50,6 +50,7 @@ #include "data.hxx" #include "node.hxx" #include "parsemanager.hxx" +#include "rootaccess.hxx" #include "writemodfile.hxx" #include "xcdparser.hxx" #include "xcuparser.hxx" @@ -126,8 +127,27 @@ rtl::Reference< Node > Components::getTemplate( return data_.getTemplate(layer, fullName); } +void Components::addRootAccess(rtl::Reference< RootAccess > const & access) { + roots_.insert(access.get()); +} + +void Components::removeRootAccess(RootAccess * access) { + roots_.erase(access); +} + +void Components::initGlobalBroadcaster( + Modifications const & globalModifications, + 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); + } + } +} + void Components::addModification(rtl::OUString const & path) { - data_.addModification(path); + data_.modifications.add(path); } void Components::writeModifications() { diff --git a/configmgr2/source/components.hxx b/configmgr2/source/components.hxx index 1b467021de66..36c1df7d6598 100644 --- a/configmgr2/source/components.hxx +++ b/configmgr2/source/components.hxx @@ -32,6 +32,8 @@ #include "sal/config.h" +#include <set> + #include "boost/noncopyable.hpp" #include "rtl/ref.hxx" @@ -44,7 +46,10 @@ namespace rtl { namespace configmgr { +class Broadcaster; class Node; +class RootAccess; +struct Modifications; class Components: private boost::noncopyable { public: @@ -59,6 +64,15 @@ public: rtl::Reference< Node > getTemplate( int layer, rtl::OUString const & fullName) const; + void addRootAccess(rtl::Reference< RootAccess > const & access); + + void removeRootAccess(RootAccess * access); + + void initGlobalBroadcaster( + Modifications const & globalModifications, + rtl::Reference< RootAccess > const & exclude, + Broadcaster * broadcaster); + void addModification(rtl::OUString const & path); void writeModifications(); @@ -95,7 +109,10 @@ private: void parseModificationLayer(); + typedef std::set< RootAccess * > WeakRootSet; + Data data_; + WeakRootSet roots_; }; } diff --git a/configmgr2/source/configurationprovider.cxx b/configmgr2/source/configurationprovider.cxx index 3a9a5ca45857..1d3f056e5605 100644 --- a/configmgr2/source/configurationprovider.cxx +++ b/configmgr2/source/configurationprovider.cxx @@ -67,6 +67,7 @@ #include "rtl/ustring.h" #include "rtl/ustring.hxx" +#include "components.hxx" #include "configurationprovider.hxx" #include "lock.hxx" #include "rootaccess.hxx" @@ -281,6 +282,7 @@ Service::createInstanceWithArguments( nodepath), static_cast< cppu::OWeakObject * >(this)); } + Components::singleton().addRootAccess(root); return static_cast< cppu::OWeakObject * >(root.get()); } diff --git a/configmgr2/source/data.cxx b/configmgr2/source/data.cxx index 7e329ddfcbcf..c53d81b04b08 100644 --- a/configmgr2/source/data.cxx +++ b/configmgr2/source/data.cxx @@ -54,11 +54,6 @@ namespace { namespace css = com::sun::star; -bool isPrefix(rtl::OUString const & prefix, rtl::OUString const & path) { - return prefix.getLength() < path.getLength() && path.match(prefix) && - path[prefix.getLength()] == '/'; -} - bool decode( rtl::OUString const & encoded, sal_Int32 begin, sal_Int32 end, rtl::OUString * decoded) @@ -321,21 +316,4 @@ rtl::Reference< Node > Data::getTemplate( return findNode(layer, templates, fullName); } -void Data::addModification(rtl::OUString const & path) { - //TODO - for (Modifications::iterator i(modifications.begin()); - i != modifications.end();) - { - if (path == *i || isPrefix(*i, path)) { - return; - } - if (isPrefix(path, *i)) { - modifications.erase(i++); - } else { - ++i; - } - } - modifications.push_back(path); -} - } diff --git a/configmgr2/source/data.hxx b/configmgr2/source/data.hxx index f944a4293097..c2b28281ac6e 100644 --- a/configmgr2/source/data.hxx +++ b/configmgr2/source/data.hxx @@ -33,12 +33,12 @@ #include "sal/config.h" #include <climits> -#include <list> #include "boost/noncopyable.hpp" #include "rtl/ref.hxx" #include "sal/types.h" +#include "modifications.hxx" #include "nodemap.hxx" namespace rtl { class OUString; } @@ -48,8 +48,6 @@ namespace configmgr { class Node; struct Data: private boost::noncopyable { - typedef std::list< rtl::OUString > Modifications; - enum { NO_LAYER = INT_MAX }; NodeMap templates; @@ -81,8 +79,6 @@ struct Data: private boost::noncopyable { rtl::Reference< Node > getTemplate( int layer, rtl::OUString const & fullName) const; - - void addModification(rtl::OUString const & path); }; } diff --git a/configmgr2/source/makefile.mk b/configmgr2/source/makefile.mk index 7606c0a9bc72..38a412394028 100644 --- a/configmgr2/source/makefile.mk +++ b/configmgr2/source/makefile.mk @@ -40,6 +40,7 @@ CDEFS += -DOOO_DLLIMPLEMENTATION_CONFIGMGR SLOFILES = \ $(SLO)/access.obj \ + $(SLO)/broadcaster.obj \ $(SLO)/childaccess.obj \ $(SLO)/components.obj \ $(SLO)/configurationprovider.obj \ @@ -49,6 +50,7 @@ SLOFILES = \ $(SLO)/localizedpropertynode.obj \ $(SLO)/localizedvaluenode.obj \ $(SLO)/lock.obj \ + $(SLO)/modifications.obj \ $(SLO)/node.obj \ $(SLO)/nodemap.obj \ $(SLO)/pad.obj \ diff --git a/configmgr2/source/modifications.cxx b/configmgr2/source/modifications.cxx new file mode 100644 index 000000000000..157ccf35fe82 --- /dev/null +++ b/configmgr2/source/modifications.cxx @@ -0,0 +1,63 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* $RCSfile: code,v $ +* +* $Revision: 1.4 $ +* +* 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. +************************************************************************/ + +#include "precompiled_configmgr.hxx" +#include "sal/config.h" + +#include "rtl/ustring.hxx" + +#include "modifications.hxx" + +namespace configmgr { + +namespace { + +bool isPrefix(rtl::OUString const & prefix, rtl::OUString const & path) { + return prefix.getLength() < path.getLength() && path.match(prefix) && + path[prefix.getLength()] == '/'; +} + +} + +void Modifications::add(rtl::OUString const & path) { + //TODO: performance + for (List::iterator i(list.begin()); i != list.end();) { + if (path == *i || isPrefix(*i, path)) { + return; + } + if (isPrefix(path, *i)) { + list.erase(i++); + } else { + ++i; + } + } + list.push_back(path); +} + +} diff --git a/configmgr2/source/modifications.hxx b/configmgr2/source/modifications.hxx new file mode 100644 index 000000000000..37f811b9ce6f --- /dev/null +++ b/configmgr2/source/modifications.hxx @@ -0,0 +1,54 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* $RCSfile: code,v $ +* +* $Revision: 1.4 $ +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +#ifndef INCLUDED_CONFIGMGR_SOURCE_MODIFICATIONS_HXX +#define INCLUDED_CONFIGMGR_SOURCE_MODIFICATIONS_HXX + +#include "sal/config.h" + +#include <list> + +#include "boost/noncopyable.hpp" + +namespace rtl { class OUString; } + +namespace configmgr { + +struct Modifications: private boost::noncopyable { +public: + typedef std::list< rtl::OUString > List; + + List list; + + void add(rtl::OUString const & path); +}; + +} + +#endif diff --git a/configmgr2/source/rootaccess.cxx b/configmgr2/source/rootaccess.cxx index 7591ad23847b..59ecbefb914a 100644 --- a/configmgr2/source/rootaccess.cxx +++ b/configmgr2/source/rootaccess.cxx @@ -46,6 +46,7 @@ #include "rtl/ustring.h" #include "rtl/ustring.hxx" +#include "broadcaster.hxx" #include "childaccess.hxx" #include "components.hxx" #include "data.hxx" @@ -74,7 +75,10 @@ bool RootAccess::isUpdate() const { return update_; } -RootAccess::~RootAccess() {} +RootAccess::~RootAccess() { + osl::MutexGuard g(lock); + Components::singleton().removeRootAccess(this); +} rtl::OUString RootAccess::getAbsolutePath() { getNode(); @@ -178,14 +182,21 @@ void RootAccess::commitChanges() throw (css::lang::WrappedTargetException, css::uno::RuntimeException) { OSL_ASSERT(thisIs(IS_ANY|IS_UPDATE)); - osl::MutexGuard g(lock); - checkLocalizedPropertyAccess(); - int finalizedLayer; - commitChildChanges( - (Components::singleton().resolvePath(path_, 0, 0, &finalizedLayer) - == node_) && - finalizedLayer == Data::NO_LAYER); - Components::singleton().writeModifications(); + Broadcaster bc; + { + osl::MutexGuard g(lock); + checkLocalizedPropertyAccess(); + int finalizedLayer; + Modifications globalMods; + commitChildChanges( + ((Components::singleton().resolvePath(path_, 0, 0, &finalizedLayer) + == node_) && + finalizedLayer == Data::NO_LAYER), + &globalMods); + Components::singleton().writeModifications(); + Components::singleton().initGlobalBroadcaster(globalMods, this, &bc); + } + bc.send(); } sal_Bool RootAccess::hasPendingChanges() throw (css::uno::RuntimeException) { diff --git a/configmgr2/source/writemodfile.cxx b/configmgr2/source/writemodfile.cxx index bd5a802bd4cd..960fa3479858 100644 --- a/configmgr2/source/writemodfile.cxx +++ b/configmgr2/source/writemodfile.cxx @@ -51,6 +51,7 @@ #include "groupnode.hxx" #include "localizedpropertynode.hxx" #include "localizedvaluenode.hxx" +#include "modifications.hxx" #include "node.hxx" #include "nodemap.hxx" #include "propertynode.hxx" @@ -473,8 +474,8 @@ void writeModFile(rtl::OUString const & url, Data const & data) { //TODO: Do not write back information about those removed items that did not // come from the .xcs/.xcu files, anyway (but had been added dynamically // instead): - for (Data::Modifications::const_iterator j(data.modifications.begin()); - j != data.modifications.end(); ++j) + for (Modifications::List::const_iterator j(data.modifications.list.begin()); + j != data.modifications.list.end(); ++j) { rtl::OUString name; rtl::OUString parentPath(Data::parseLastSegment(*j, &name)); diff --git a/configmgr2/source/xcuparser.cxx b/configmgr2/source/xcuparser.cxx index ca50bd7a01c1..2821d51eeb7a 100644 --- a/configmgr2/source/xcuparser.cxx +++ b/configmgr2/source/xcuparser.cxx @@ -525,7 +525,7 @@ void XcuParser::handleGroupProp(XmlReader & reader, GroupNode * group) { } rtl::OUString name(xmldata::convertFromUtf8(attrName)); if (state_.top().record) { - data_->addModification(pathPrefix_ + name); + data_->modifications.add(pathPrefix_ + name); } Type type = xmldata::parseType(reader, attrType); if (type == TYPE_ANY) { @@ -842,7 +842,7 @@ void XcuParser::handleSetNode(XmlReader & reader, SetNode * set) { attrComponent, attrNodeType, componentName_, &set->getDefaultTemplateName())); if (state_.top().record) { - data_->addModification( + data_->modifications.add( pathPrefix_ + Data::createSegment(templateName, name)); } if (!set->isValidTemplate(templateName)) { |