summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsb <sb@openoffice.org>2009-09-23 16:07:30 +0200
committersb <sb@openoffice.org>2009-09-23 16:07:30 +0200
commitd6688c4ca3b0f7c4fdda24f183fe60894840b6dc (patch)
tree6382529fe4923031e1254ea9cbca398e158455f7
parent5ab6b21f22098727d905bae8b9c8eb6286c8edee (diff)
#i101955# notification support, continued (still to be continued; at least no longer fails miserably now)
-rw-r--r--configmgr2/source/access.cxx313
-rw-r--r--configmgr2/source/access.hxx6
-rw-r--r--configmgr2/source/components.cxx22
-rw-r--r--configmgr2/source/components.hxx2
-rw-r--r--configmgr2/source/modifications.cxx41
-rw-r--r--configmgr2/source/modifications.hxx13
-rw-r--r--configmgr2/source/rootaccess.cxx52
-rw-r--r--configmgr2/source/rootaccess.hxx8
-rw-r--r--configmgr2/source/writemodfile.cxx202
9 files changed, 378 insertions, 281 deletions
diff --git a/configmgr2/source/access.cxx b/configmgr2/source/access.cxx
index f6aa7296f156..385e0f0d70cd 100644
--- a/configmgr2/source/access.cxx
+++ b/configmgr2/source/access.cxx
@@ -160,61 +160,100 @@ void Access::releaseChild(rtl::OUString const & name) {
}
void Access::initGlobalBroadcaster(
- Modifications const & globalModifications, Broadcaster * broadcaster)
+ Modifications const & modifications, 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)
+ //TODO: handle containerListeners_, vetoableChangeListeners_,
+ // propertiesChangeListeners_
+ for (Modifications::Children::const_iterator i(
+ modifications.children.begin());
+ i != modifications.children.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));
+ rtl::Reference< ChildAccess > child(getChild(i->first));
if (child.is()) {
- child->initGlobalBroadcaster(globalModifications, broadcaster);
+ switch (child->getNode()->kind()) {
+ case Node::KIND_LOCALIZED_PROPERTY:
+ if (Components::allLocales(getRootAccess()->getLocale())) {
+ break;
+ }
+ //TODO: filter child mods that are irrelevant for locale:
+ if (!i->second.children.empty()) {
+ PropertyChangeListeners::iterator j(
+ propertyChangeListeners_.find(i->first));
+ if (j != propertyChangeListeners_.end()) {
+ for (PropertyChangeListenersElement::iterator k(
+ j->second.begin());
+ k != j->second.end(); ++k)
+ {
+ broadcaster->addPropertyChangeNotification(
+ *k,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ j = propertyChangeListeners_.find(rtl::OUString());
+ if (j != propertyChangeListeners_.end()) {
+ for (PropertyChangeListenersElement::iterator k(
+ j->second.begin());
+ k != j->second.end(); ++k)
+ {
+ broadcaster->addPropertyChangeNotification(
+ *k,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ }
+ return;
+ case Node::KIND_LOCALIZED_VALUE:
+ if (Components::allLocales(getRootAccess()->getLocale())) {
+ return;
+ }
+ // fall through
+ case Node::KIND_PROPERTY:
+ if (i->second.children.empty()) {
+ PropertyChangeListeners::iterator j(
+ propertyChangeListeners_.find(i->first));
+ if (j != propertyChangeListeners_.end()) {
+ for (PropertyChangeListenersElement::iterator k(
+ j->second.begin());
+ k != j->second.end(); ++k)
+ {
+ //TODO: filter out adds/removes:
+ broadcaster->addPropertyChangeNotification(
+ *k,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ j = propertyChangeListeners_.find(rtl::OUString());
+ if (j != propertyChangeListeners_.end()) {
+ for (PropertyChangeListenersElement::iterator k(
+ j->second.begin());
+ k != j->second.end(); ++k)
+ {
+ //TODO: filter out adds/removes:
+ broadcaster->addPropertyChangeNotification(
+ *k,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ }
+ return;
+ default:
+ break;
+ }
+ child->initGlobalBroadcaster(i->second, broadcaster);
+ //TODO: recurse only into children w/ listeners
}
}
}
@@ -300,61 +339,100 @@ void Access::clearListeners() throw() {
}
void Access::initLocalBroadcaster(
- Modifications const & localModifications, Broadcaster * broadcaster)
+ Modifications const & modifications, 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)
+ //TODO: handle containerListeners_, vetoableChangeListeners_,
+ // propertiesChangeListeners_
+ for (Modifications::Children::const_iterator i(
+ modifications.children.begin());
+ i != modifications.children.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));
+ rtl::Reference< ChildAccess > child(getChild(i->first));
if (child.is()) {
- child->initLocalBroadcaster(localModifications, broadcaster);
+ switch (child->getNode()->kind()) {
+ case Node::KIND_LOCALIZED_PROPERTY:
+ if (Components::allLocales(getRootAccess()->getLocale())) {
+ break;
+ }
+ //TODO: filter child mods that are irrelevant for locale:
+ if (!i->second.children.empty()) {
+ PropertyChangeListeners::iterator j(
+ propertyChangeListeners_.find(i->first));
+ if (j != propertyChangeListeners_.end()) {
+ for (PropertyChangeListenersElement::iterator k(
+ j->second.begin());
+ k != j->second.end(); ++k)
+ {
+ broadcaster->addPropertyChangeNotification(
+ *k,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ j = propertyChangeListeners_.find(rtl::OUString());
+ if (j != propertyChangeListeners_.end()) {
+ for (PropertyChangeListenersElement::iterator k(
+ j->second.begin());
+ k != j->second.end(); ++k)
+ {
+ broadcaster->addPropertyChangeNotification(
+ *k,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ }
+ return;
+ case Node::KIND_LOCALIZED_VALUE:
+ if (Components::allLocales(getRootAccess()->getLocale())) {
+ return;
+ }
+ // fall through
+ case Node::KIND_PROPERTY:
+ if (i->second.children.empty()) {
+ PropertyChangeListeners::iterator j(
+ propertyChangeListeners_.find(i->first));
+ if (j != propertyChangeListeners_.end()) {
+ for (PropertyChangeListenersElement::iterator k(
+ j->second.begin());
+ k != j->second.end(); ++k)
+ {
+ //TODO: filter out adds/removes:
+ broadcaster->addPropertyChangeNotification(
+ *k,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ j = propertyChangeListeners_.find(rtl::OUString());
+ if (j != propertyChangeListeners_.end()) {
+ for (PropertyChangeListenersElement::iterator k(
+ j->second.begin());
+ k != j->second.end(); ++k)
+ {
+ //TODO: filter out adds/removes:
+ broadcaster->addPropertyChangeNotification(
+ *k,
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ }
+ return;
+ default:
+ break;
+ }
+ child->initLocalBroadcaster(i->second, broadcaster);
+ //TODO: recurse only into children w/ listeners
}
}
}
@@ -1143,6 +1221,7 @@ void Access::addPropertyChangeListener(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("null listener")),
static_cast< cppu::OWeakObject * >(this));
}
+ checkKnownProperty(aPropertyName);
if (!disposed_) {
propertyChangeListeners_[aPropertyName].insert(xListener);
return;
@@ -1164,6 +1243,7 @@ void Access::removePropertyChangeListener(
{
OSL_ASSERT(thisIs(IS_GROUP));
osl::MutexGuard g(lock);
+ checkKnownProperty(aPropertyName);
PropertyChangeListeners::iterator i(
propertyChangeListeners_.find(aPropertyName));
if (i != propertyChangeListeners_.end()) {
@@ -1193,6 +1273,7 @@ void Access::addVetoableChangeListener(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("null listener")),
static_cast< cppu::OWeakObject * >(this));
}
+ checkKnownProperty(PropertyName);
if (!disposed_) {
vetoableChangeListeners_[PropertyName].insert(aListener);
return;
@@ -1214,6 +1295,7 @@ void Access::removeVetoableChangeListener(
{
OSL_ASSERT(thisIs(IS_GROUP));
osl::MutexGuard g(lock);
+ checkKnownProperty(PropertyName);
VetoableChangeListeners::iterator i(
vetoableChangeListeners_.find(PropertyName));
if (i != vetoableChangeListeners_.end()) {
@@ -1792,6 +1874,33 @@ void Access::checkFinalized() {
}
}
+void Access::checkKnownProperty(rtl::OUString const & descriptor) {
+ if (descriptor.getLength() == 0) {
+ return;
+ }
+ rtl::Reference< ChildAccess > child(getChild(descriptor));
+ if (child.is()) {
+ switch (child->getNode()->kind()) {
+ case Node::KIND_PROPERTY:
+ return;
+ case Node::KIND_LOCALIZED_PROPERTY:
+ if (!Components::allLocales(getRootAccess()->getLocale())) {
+ return;
+ }
+ break;
+ case Node::KIND_LOCALIZED_VALUE:
+ if (Components::allLocales(getRootAccess()->getLocale())) {
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ throw css::beans::UnknownPropertyException(
+ descriptor, static_cast< cppu::OWeakObject * >(this));
+}
+
rtl::Reference< ChildAccess > Access::getFreeSetMember(
css::uno::Any const & value)
{
diff --git a/configmgr2/source/access.hxx b/configmgr2/source/access.hxx
index 06e26ff1c7bf..02a93a3d6edb 100644
--- a/configmgr2/source/access.hxx
+++ b/configmgr2/source/access.hxx
@@ -143,7 +143,7 @@ public:
virtual bool isFinalized() = 0;
virtual void initGlobalBroadcaster(
- Modifications const & localModifications, Broadcaster * broadcaster);
+ Modifications const & modifications, Broadcaster * broadcaster);
using OWeakObject::acquire;
using OWeakObject::release;
@@ -167,7 +167,7 @@ protected:
virtual void clearListeners() throw ();
virtual void initLocalBroadcaster(
- Modifications const & localModifications, Broadcaster * broadcaster);
+ Modifications const & modifications, Broadcaster * broadcaster);
virtual com::sun::star::uno::Any SAL_CALL queryInterface(
com::sun::star::uno::Type const & aType)
@@ -506,6 +506,8 @@ private:
void checkFinalized();
+ void checkKnownProperty(rtl::OUString const & descriptor);
+
rtl::Reference< ChildAccess > getFreeSetMember(
com::sun::star::uno::Any const & value);
diff --git a/configmgr2/source/components.cxx b/configmgr2/source/components.cxx
index 691d64ff535d..94db1ee70f43 100644
--- a/configmgr2/source/components.cxx
+++ b/configmgr2/source/components.cxx
@@ -48,6 +48,7 @@
#include "components.hxx"
#include "data.hxx"
+#include "modifications.hxx"
#include "node.hxx"
#include "parsemanager.hxx"
#include "rootaccess.hxx"
@@ -136,9 +137,10 @@ void Components::removeRootAccess(RootAccess * access) {
}
void Components::initGlobalBroadcaster(
- Modifications const & globalModifications,
+ Modifications const & modifications,
rtl::Reference< RootAccess > const & exclude, Broadcaster * broadcaster)
{
+ //TODO: Iterate only over roots w/ listeners:
for (WeakRootSet::iterator i(roots_.begin()); i != roots_.end(); ++i) {
rtl::Reference< RootAccess > root;
if ((*i)->acquireCounting() > 1) {
@@ -147,7 +149,23 @@ void Components::initGlobalBroadcaster(
(*i)->releaseNondeleting();
if (root.is()) {
if (root != exclude) {
- root->initGlobalBroadcaster(globalModifications, broadcaster);
+ Path path(root->getAbsolutePath());
+ Modifications const * mods = &modifications;
+ for (Path::iterator j(path.begin()); j != path.end(); ++j) {
+ Modifications::Children::const_iterator k(
+ mods->children.find(*j));
+ if (k == mods->children.end()) {
+ mods = 0;
+ break;
+ }
+ mods = &k->second;
+ }
+ //TODO: If the complete tree of which root is a part is deleted,
+ // or replaced, mods will be null, but some of the listeners
+ // from within root should probably fire nonetheless:
+ if (mods != 0) {
+ root->initGlobalBroadcaster(*mods, broadcaster);
+ }
}
}
}
diff --git a/configmgr2/source/components.hxx b/configmgr2/source/components.hxx
index 98082fb842a0..807acf827ba6 100644
--- a/configmgr2/source/components.hxx
+++ b/configmgr2/source/components.hxx
@@ -70,7 +70,7 @@ public:
void removeRootAccess(RootAccess * access);
void initGlobalBroadcaster(
- Modifications const & globalModifications,
+ Modifications const & modifications,
rtl::Reference< RootAccess > const & exclude,
Broadcaster * broadcaster);
diff --git a/configmgr2/source/modifications.cxx b/configmgr2/source/modifications.cxx
index a2ea42211b2c..4b7acd1901c9 100644
--- a/configmgr2/source/modifications.cxx
+++ b/configmgr2/source/modifications.cxx
@@ -37,37 +37,24 @@
namespace configmgr {
-namespace {
-
-bool isPrefix(Path const & prefix, Path const & path) {
- if (prefix.size() > path.size()) {
- return false;
- }
- Path::const_iterator i1(prefix.begin());
- Path::const_iterator i2(path.begin());
- while (i1 != prefix.end()) {
- if (*i1++ != *i2++) {
- return false;
- }
- }
- return true;
-}
-
-}
-
void Modifications::add(Path const & path) {
- //TODO: performance
- for (List::iterator i(list.begin()); i != list.end();) {
- if (isPrefix(*i, path)) {
- return;
- }
- if (isPrefix(path, *i)) {
- list.erase(i++);
+ Modifications * mod = this;
+ bool wasPresent = false;
+ for (Path::const_iterator i(path.begin()); i != path.end(); ++i) {
+ Children::iterator j(mod->children.find(*i));
+ if (j == mod->children.end()) {
+ if (wasPresent && mod->children.empty()) {
+ return;
+ }
+ j = mod->children.insert(Children::value_type(*i, Modifications())).
+ first;
+ wasPresent = false;
} else {
- ++i;
+ wasPresent = true;
}
+ mod = &j->second;
}
- list.push_back(path);
+ mod->children.clear();
}
}
diff --git a/configmgr2/source/modifications.hxx b/configmgr2/source/modifications.hxx
index 5a2b28e5a8be..7f7d14dba132 100644
--- a/configmgr2/source/modifications.hxx
+++ b/configmgr2/source/modifications.hxx
@@ -32,19 +32,18 @@
#include "sal/config.h"
-#include <list>
-
-#include "boost/noncopyable.hpp"
+#include <map>
#include "path.hxx"
+namespace rtl { class OUString; }
+
namespace configmgr {
-struct Modifications: private boost::noncopyable {
-public:
- typedef std::list< Path > List;
+struct Modifications {
+ typedef std::map< rtl::OUString, Modifications > Children;
- List list;
+ Children children;
void add(Path const & path);
};
diff --git a/configmgr2/source/rootaccess.cxx b/configmgr2/source/rootaccess.cxx
index 554fcf0f4f70..4dee4109d342 100644
--- a/configmgr2/source/rootaccess.cxx
+++ b/configmgr2/source/rootaccess.cxx
@@ -75,26 +75,16 @@ RootAccess::RootAccess(
pathRepresentation_(pathRepresentation), locale_(locale), update_(update)
{}
+Path RootAccess::getAbsolutePath() {
+ getNode();
+ return path_;
+}
+
void RootAccess::initGlobalBroadcaster(
- Modifications const & globalModifications, Broadcaster * broadcaster)
+ Modifications const & modifications, 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(
- css::uno::Reference< css::uno::XInterface >(
- static_cast< cppu::OWeakObject * >(this))),
- //TODO: XInterface or something else?
- css::uno::Sequence< css::util::ElementChange >()/*TODO*/));
-
- }
- Access::initGlobalBroadcaster(globalModifications, broadcaster);
+ Access::initGlobalBroadcaster(modifications, broadcaster);
+ //TODO: handle changesListeners_
}
void RootAccess::acquire() throw () {
@@ -118,11 +108,6 @@ RootAccess::~RootAccess() {
Components::singleton().removeRootAccess(this);
}
-Path RootAccess::getAbsolutePath() {
- getNode();
- return path_;
-}
-
Path RootAccess::getRelativePath() {
return Path();
}
@@ -201,25 +186,10 @@ void RootAccess::clearListeners() throw() {
}
void RootAccess::initLocalBroadcaster(
- Modifications const & localModifications, Broadcaster * broadcaster)
+ Modifications const & modifications, 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(
- css::uno::Reference< css::uno::XInterface >(
- static_cast< cppu::OWeakObject * >(this))),
- //TODO: XInterface or something else?
- css::uno::Sequence< css::util::ElementChange >()/*TODO*/));
-
- }
- Access::initLocalBroadcaster(localModifications, broadcaster);
+ Access::initLocalBroadcaster(modifications, broadcaster);
+ //TODO: handle changesListeners_
}
css::uno::Any RootAccess::queryInterface(css::uno::Type const & aType)
diff --git a/configmgr2/source/rootaccess.hxx b/configmgr2/source/rootaccess.hxx
index 250a8f194d0c..9ea568bcf104 100644
--- a/configmgr2/source/rootaccess.hxx
+++ b/configmgr2/source/rootaccess.hxx
@@ -69,8 +69,10 @@ public:
rtl::OUString const & pathRepresenation, rtl::OUString const & locale,
bool update);
+ virtual Path getAbsolutePath();
+
virtual void initGlobalBroadcaster(
- Modifications const & localModifications, Broadcaster * broadcaster);
+ Modifications const & modifications, Broadcaster * broadcaster);
virtual void SAL_CALL acquire() throw ();
@@ -83,8 +85,6 @@ public:
private:
virtual ~RootAccess();
- virtual Path getAbsolutePath();
-
virtual Path getRelativePath();
virtual rtl::OUString getRelativePathRepresentation();
@@ -107,7 +107,7 @@ private:
virtual void clearListeners() throw ();
virtual void initLocalBroadcaster(
- Modifications const & localModifications, Broadcaster * broadcaster);
+ Modifications const & modifications, Broadcaster * broadcaster);
virtual com::sun::star::uno::Any SAL_CALL queryInterface(
com::sun::star::uno::Type const & aType)
diff --git a/configmgr2/source/writemodfile.cxx b/configmgr2/source/writemodfile.cxx
index ccfee9b6f891..15b9e3e5eb6a 100644
--- a/configmgr2/source/writemodfile.cxx
+++ b/configmgr2/source/writemodfile.cxx
@@ -437,6 +437,105 @@ void writeNode(
}
}
+void writeModifications(
+ oslFileHandle handle, rtl::OUString const & grandparentPathRepresentation,
+ rtl::OUString const & parentName, rtl::Reference< Node > const & parent,
+ rtl::OUString const & nodeName, rtl::Reference< Node > const & node,
+ Modifications const & modifications)
+{
+ if (modifications.children.empty()) {
+ OSL_ASSERT(parent.is());
+ // components themselves have no parent but must have children
+ if (node.is()) {
+ writeData(handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\""));
+ writeAttributeValue(
+ handle,
+ (grandparentPathRepresentation +
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
+ Data::createSegment(parent->getTemplateName(), parentName)));
+ writeData(handle, RTL_CONSTASCII_STRINGPARAM("\">"));
+ writeNode(handle, parent, nodeName, node);
+ writeData(handle, RTL_CONSTASCII_STRINGPARAM("</item>"));
+ // It is never necessary to write the oor:mandatory attribute, as it
+ // cannot be set via the UNO API.
+ } else {
+ writeData(handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\""));
+ switch (parent->kind()) {
+ case Node::KIND_LOCALIZED_PROPERTY:
+ writeAttributeValue(handle, grandparentPathRepresentation);
+ writeData(
+ handle, RTL_CONSTASCII_STRINGPARAM("\"><prop oor:name=\""));
+ writeAttributeValue(handle, parentName);
+ writeData(
+ handle,
+ RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\"><value"));
+ if (nodeName.getLength() != 0) {
+ writeData(
+ handle, RTL_CONSTASCII_STRINGPARAM(" xml:lang=\""));
+ writeAttributeValue(handle, nodeName);
+ writeData(handle, RTL_CONSTASCII_STRINGPARAM("\""));
+ }
+ writeData(
+ handle,
+ RTL_CONSTASCII_STRINGPARAM(
+ " oor:op=\"remove\"/></prop></item>"));
+ break;
+ case Node::KIND_GROUP:
+ OSL_ASSERT(
+ dynamic_cast< GroupNode * >(parent.get())->isExtensible());
+ writeAttributeValue(
+ handle,
+ (grandparentPathRepresentation +
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
+ Data::createSegment(
+ parent->getTemplateName(), parentName)));
+ writeData(
+ handle, RTL_CONSTASCII_STRINGPARAM("\"><prop oor:name=\""));
+ writeAttributeValue(handle, nodeName);
+ writeData(
+ handle,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\" oor:op=\"remove\"/></item>"));
+ break;
+ case Node::KIND_SET:
+ writeAttributeValue(
+ handle,
+ (grandparentPathRepresentation +
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
+ Data::createSegment(
+ parent->getTemplateName(), parentName)));
+ writeData(
+ handle, RTL_CONSTASCII_STRINGPARAM("\"><node oor:name=\""));
+ writeAttributeValue(handle, nodeName);
+ writeData(
+ handle,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\" oor:op=\"remove\"/></item>"));
+ break;
+ default:
+ OSL_ASSERT(false); // this cannot happen
+ break;
+ }
+ }
+ } else {
+ rtl::OUString parentPathRep;
+ if (parent.is()) { // components themselves have no parent
+ parentPathRep = grandparentPathRepresentation +
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
+ Data::createSegment(parent->getTemplateName(), parentName);
+ }
+ OSL_ASSERT(node.is());
+ for (Modifications::Children::const_iterator i(
+ modifications.children.begin());
+ i != modifications.children.end(); ++i)
+ {
+ writeModifications(
+ handle, parentPathRep, nodeName, node, i->first,
+ node->getMember(i->first), i->second);
+ }
+ }
+}
+
}
void writeModFile(rtl::OUString const & url, Data const & data) {
@@ -475,102 +574,15 @@ 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 (Modifications::List::const_iterator j(data.modifications.list.begin());
- j != data.modifications.list.end(); ++j)
+ for (Modifications::Children::const_iterator j(
+ data.modifications.children.begin());
+ j != data.modifications.children.end(); ++j)
{
- Path::const_iterator k(j->begin());
- OSL_ASSERT(k != j->end());
- rtl::OUString parentName(*k++);
- rtl::Reference< Node > parent(
- Data::findNode(Data::NO_LAYER, data.components, parentName));
- OSL_ASSERT(parent.is() && k != j->end());
- rtl::OUString nodeName;
- rtl::Reference< Node > node;
- rtl::OUStringBuffer pathRep; // up to grandparent segment
- for (;;) {
- nodeName = *k++;
- node = parent->getMember(nodeName);
- if (k == j->end()) {
- break;
- }
- OSL_ASSERT(node.is());
- pathRep.append(sal_Unicode('/'));
- pathRep.append(
- Data::createSegment(parent->getTemplateName(), parentName));
- parent = node;
- parentName = nodeName;
- }
- if (node.is()) {
- writeData(
- tmp.handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\""));
- pathRep.append(sal_Unicode('/'));
- pathRep.append(
- Data::createSegment(parent->getTemplateName(), parentName));
- writeAttributeValue(tmp.handle, pathRep.makeStringAndClear());
- writeData(tmp.handle, RTL_CONSTASCII_STRINGPARAM("\">"));
- writeNode(tmp.handle, parent, nodeName, node);
- writeData(tmp.handle, RTL_CONSTASCII_STRINGPARAM("</item>"));
- // It is never necessary to write the oor:mandatory attribute, as it
- // cannot be set via the UNO API.
- } else {
- writeData(
- tmp.handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\""));
- switch (parent->kind()) {
- case Node::KIND_LOCALIZED_PROPERTY:
- writeAttributeValue(tmp.handle, pathRep.makeStringAndClear());
- writeData(
- tmp.handle,
- RTL_CONSTASCII_STRINGPARAM("\"><prop oor:name=\""));
- writeAttributeValue(tmp.handle, parentName);
- writeData(
- tmp.handle,
- RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\"><value"));
- if (nodeName.getLength() != 0) {
- writeData(
- tmp.handle, RTL_CONSTASCII_STRINGPARAM(" xml:lang=\""));
- writeAttributeValue(tmp.handle, nodeName);
- writeData(tmp.handle, RTL_CONSTASCII_STRINGPARAM("\""));
- }
- writeData(
- tmp.handle,
- RTL_CONSTASCII_STRINGPARAM(
- " oor:op=\"remove\"/></prop></item>"));
- break;
- case Node::KIND_GROUP:
- OSL_ASSERT(
- dynamic_cast< GroupNode * >(parent.get())->isExtensible());
- pathRep.append(sal_Unicode('/'));
- pathRep.append(
- Data::createSegment(parent->getTemplateName(), parentName));
- writeAttributeValue(tmp.handle, pathRep.makeStringAndClear());
- writeData(
- tmp.handle,
- RTL_CONSTASCII_STRINGPARAM("\"><prop oor:name=\""));
- writeAttributeValue(tmp.handle, nodeName);
- writeData(
- tmp.handle,
- RTL_CONSTASCII_STRINGPARAM(
- "\" oor:op=\"remove\"/></item>"));
- break;
- case Node::KIND_SET:
- pathRep.append(sal_Unicode('/'));
- pathRep.append(
- Data::createSegment(parent->getTemplateName(), parentName));
- writeAttributeValue(tmp.handle, pathRep.makeStringAndClear());
- writeData(
- tmp.handle,
- RTL_CONSTASCII_STRINGPARAM("\"><node oor:name=\""));
- writeAttributeValue(tmp.handle, nodeName);
- writeData(
- tmp.handle,
- RTL_CONSTASCII_STRINGPARAM(
- "\" oor:op=\"remove\"/></item>"));
- break;
- default:
- OSL_ASSERT(false); // this cannot happen
- break;
- }
- }
+ writeModifications(
+ tmp.handle, rtl::OUString(), rtl::OUString(),
+ rtl::Reference< Node >(), j->first,
+ Data::findNode(Data::NO_LAYER, data.components, j->first),
+ j->second);
}
writeData(tmp.handle, RTL_CONSTASCII_STRINGPARAM("</oor:items>"));
oslFileError e = osl_closeFile(tmp.handle);