summaryrefslogtreecommitdiff
path: root/configmgr
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2011-12-13 12:37:00 +0100
committerStephan Bergmann <sbergman@redhat.com>2011-12-13 12:50:34 +0100
commitbcdea3b379637a98e5bbc304078149ca6c2b6e03 (patch)
treea3803df980a54ab1a03c740c3114a54ca7d12f27 /configmgr
parentddf1cf333174777e7923aa0d6126daf2c8645fed (diff)
Simplified, type-safe C++ configuration access.
* New offapi com.sun.star.configuration entities to access the complete configuration read-only or read/write... * ...configmgr adapted to support those new services/singletons... * ...new unotools/configuration.hxx is the type-safe C++ plumbing on top of that... * ...officecfg now generates C++ headers to access all the properties and sets given in the .xcs files... * ...and svl's asiancfg.cxx exemplarily makes use of the new officecfg/Office/Common.hxx to access the configuration. * There is still TODOs: For one, see those listed in officecfg/registry/cppheader.xsl. For another, at least a notification mechanism for the new read-only configuration access and the C++ wrapper is missing.
Diffstat (limited to 'configmgr')
-rw-r--r--configmgr/source/access.cxx1432
-rw-r--r--configmgr/source/access.hxx136
-rw-r--r--configmgr/source/components.cxx6
-rwxr-xr-xconfigmgr/source/configmgr.component6
-rw-r--r--configmgr/source/data.cxx18
-rw-r--r--configmgr/source/data.hxx4
-rw-r--r--configmgr/source/groupnode.cxx4
-rw-r--r--configmgr/source/groupnode.hxx2
-rw-r--r--configmgr/source/localizedpropertynode.cxx4
-rw-r--r--configmgr/source/localizedpropertynode.hxx2
-rw-r--r--configmgr/source/makefile.mk3
-rw-r--r--configmgr/source/node.cxx22
-rw-r--r--configmgr/source/node.hxx5
-rw-r--r--configmgr/source/readonlyaccess.cxx126
-rw-r--r--configmgr/source/readonlyaccess.hxx61
-rw-r--r--configmgr/source/readwriteaccess.cxx151
-rw-r--r--configmgr/source/readwriteaccess.hxx61
-rw-r--r--configmgr/source/rootaccess.cxx179
-rw-r--r--configmgr/source/rootaccess.hxx40
-rw-r--r--configmgr/source/rootnode.cxx66
-rw-r--r--configmgr/source/rootnode.hxx65
-rw-r--r--configmgr/source/services.cxx10
-rw-r--r--configmgr/source/setnode.cxx4
-rw-r--r--configmgr/source/setnode.hxx2
-rw-r--r--configmgr/source/valueparser.cxx9
-rw-r--r--configmgr/source/writemodfile.cxx7
-rw-r--r--configmgr/source/xcsparser.cxx46
-rw-r--r--configmgr/source/xcuparser.cxx48
28 files changed, 1590 insertions, 929 deletions
diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx
index dab5e21c62fd..c34a8acc08be 100644
--- a/configmgr/source/access.cxx
+++ b/configmgr/source/access.cxx
@@ -54,6 +54,7 @@
#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/XHierarchicalNameReplace.hpp"
#include "com/sun/star/container/XNameAccess.hpp"
#include "com/sun/star/container/XNameContainer.hpp"
#include "com/sun/star/container/XNamed.hpp"
@@ -163,689 +164,6 @@ void Access::initBroadcaster(
initBroadcasterAndChanges(modifications, broadcaster, 0);
}
-Access::Access(Components & components):
- components_(components), disposed_(false)
-{
- lock_ = lock();
-}
-
-Access::~Access() {}
-
-void Access::initDisposeBroadcaster(Broadcaster * broadcaster) {
- 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::clearListeners() throw() {
- disposeListeners_.clear();
- containerListeners_.clear();
- propertyChangeListeners_.clear();
- vetoableChangeListeners_.clear();
- propertiesChangeListeners_.clear();
- //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->clearListeners();
- }
- }
-}
-
-css::uno::Any Access::queryInterface(css::uno::Type const & aType)
- throw (css::uno::RuntimeException)
-{
- css::uno::Any res(OWeakObject::queryInterface(aType));
- if (res.hasValue()) {
- 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())
- {
- 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;
-}
-
-Components & Access::getComponents() const {
- return components_;
-}
-
-void Access::checkLocalizedPropertyAccess() {
- if (getNode()->kind() == Node::KIND_LOCALIZED_PROPERTY &&
- !Components::allLocales(getRootAccess()->getLocale()))
- {
- throw css::uno::RuntimeException(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM(
- "configmgr Access to specialized LocalizedPropertyNode")),
- static_cast< cppu::OWeakObject * >(this));
- }
-}
-
-rtl::Reference< Node > Access::getParentNode() {
- rtl::Reference< Access > parent(getParentAccess());
- return parent.is() ? parent->getNode() : rtl::Reference< Node >();
-}
-
-rtl::Reference< ChildAccess > Access::getChild(rtl::OUString const & name) {
- ModifiedChildren::iterator i(modifiedChildren_.find(name));
- return i == modifiedChildren_.end()
- ? getUnmodifiedChild(name) : getModifiedChild(i);
-}
-
-std::vector< rtl::Reference< ChildAccess > > Access::getAllChildren() {
- std::vector< rtl::Reference< ChildAccess > > vec;
- NodeMap & members = getNode()->getMembers();
- for (NodeMap::iterator i(members.begin()); i != members.end(); ++i) {
- if (modifiedChildren_.find(i->first) == modifiedChildren_.end()) {
- vec.push_back(getUnmodifiedChild(i->first));
- assert(vec.back().is());
- }
- }
- for (ModifiedChildren::iterator i(modifiedChildren_.begin());
- i != modifiedChildren_.end(); ++i)
- {
- rtl::Reference< ChildAccess > child(getModifiedChild(i));
- if (child.is()) {
- vec.push_back(child);
- }
- }
- return vec;
-}
-
-void Access::checkValue(css::uno::Any const & value, Type type, bool nillable) {
- bool ok;
- switch (type) {
- case TYPE_NIL:
- assert(false);
- // fall through (cannot happen)
- case TYPE_ERROR:
- ok = false;
- break;
- case TYPE_ANY:
- switch (getDynamicType(value)) {
- case TYPE_ANY:
- assert(false);
- // fall through (cannot happen)
- case TYPE_ERROR:
- ok = false;
- break;
- case TYPE_NIL:
- ok = nillable;
- break;
- default:
- ok = true;
- break;
- }
- break;
- default:
- ok = value.hasValue() ? value.isExtractableTo(mapType(type)) : nillable;
- break;
- }
- if (!ok) {
- throw css::lang::IllegalArgumentException(
- rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM(
- "configmgr inappropriate property value")),
- static_cast< cppu::OWeakObject * >(this), -1);
- }
-}
-
-void Access::insertLocalizedValueChild(
- rtl::OUString const & name, css::uno::Any const & value,
- Modifications * localModifications)
-{
- assert(localModifications != 0);
- LocalizedPropertyNode * locprop = dynamic_cast< LocalizedPropertyNode * >(
- getNode().get());
- checkValue(value, locprop->getStaticType(), locprop->isNillable());
- rtl::Reference< ChildAccess > child(
- new ChildAccess(
- components_, getRootAccess(), this, name,
- new LocalizedValueNode(Data::NO_LAYER, value)));
- markChildAsModified(child);
- localModifications->add(child->getRelativePath());
-}
-
-void Access::reportChildChanges(
- std::vector< css::util::ElementChange > * changes)
-{
- assert(changes != 0);
- for (ModifiedChildren::iterator i(modifiedChildren_.begin());
- i != modifiedChildren_.end(); ++i)
- {
- rtl::Reference< ChildAccess > child(getModifiedChild(i));
- if (child.is()) {
- child->reportChildChanges(changes);
- changes->push_back(css::util::ElementChange());
- //TODO: changed value and/or inserted node
- } else {
- changes->push_back(css::util::ElementChange()); //TODO: removed node
- }
- }
-}
-
-void Access::commitChildChanges(
- bool valid, Modifications * globalModifications)
-{
- 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, 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
- // children); clarify what exactly should happen here for
- // directly inserted children
- }
- NodeMap & members = getNode()->getMembers();
- NodeMap::iterator j(members.find(i->first));
- if (child.is()) {
- // Inserted:
- if (j != members.end()) {
- childValid = childValid &&
- j->second->getFinalized() == Data::NO_LAYER;
- if (childValid) {
- child->getNode()->setMandatory(j->second->getMandatory());
- }
- }
- if (childValid) {
- members[i->first] = child->getNode();
- }
- } else {
- // Removed:
- childValid = childValid && j != members.end() &&
- j->second->getFinalized() == Data::NO_LAYER &&
- j->second->getMandatory() == Data::NO_LAYER;
- if (childValid) {
- members.erase(j);
- }
- }
- if (childValid && i->second.directlyModified) {
- Path path(getAbsolutePath());
- path.push_back(i->first);
- components_.addModification(path);
- globalModifications->add(path);
- }
- i->second.child->committed();
- modifiedChildren_.erase(i);
- }
-}
-
-void Access::initBroadcasterAndChanges(
- Modifications::Node const & modifications, Broadcaster * broadcaster,
- std::vector< css::util::ElementChange > * allChanges)
-{
- assert(broadcaster != 0);
- comphelper::SequenceAsVector< css::beans::PropertyChangeEvent > propChanges;
- bool collectPropChanges = !propertiesChangeListeners_.empty();
- for (Modifications::Node::Children::const_iterator i(
- modifications.children.begin());
- i != modifications.children.end(); ++i)
- {
- rtl::Reference< ChildAccess > child(getChild(i->first));
- if (child.is()) {
- switch (child->getNode()->kind()) {
- case Node::KIND_LOCALIZED_PROPERTY:
- if (!i->second.children.empty()) {
- if (Components::allLocales(getRootAccess()->getLocale())) {
- child->initBroadcasterAndChanges(
- i->second, broadcaster, allChanges);
- //TODO: if allChanges==0, recurse only into children
- // w/ listeners
- } else {
- //TODO: filter child mods that are irrelevant for
- // locale:
- for (ContainerListeners::iterator j(
- containerListeners_.begin());
- j != containerListeners_.end(); ++j)
- {
- broadcaster->
- addContainerElementReplacedNotification(
- *j,
- css::container::ContainerEvent(
- static_cast< cppu::OWeakObject * >(
- this),
- css::uno::makeAny(i->first),
- css::uno::Any(), css::uno::Any()));
- //TODO: non-void Element, ReplacedElement
- }
- 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()));
- }
- }
- if (allChanges != 0) {
- allChanges->push_back(
- css::util::ElementChange(
- css::uno::makeAny(
- child->getRelativePathRepresentation()),
- css::uno::Any(), css::uno::Any()));
- //TODO: non-void Element, ReplacedElement
- }
- if (collectPropChanges) {
- propChanges.push_back(
- css::beans::PropertyChangeEvent(
- static_cast< cppu::OWeakObject * >(this),
- i->first, false, -1, css::uno::Any(),
- css::uno::Any()));
- }
- }
- }
- // else: spurious Modifications::Node not representing a change
- break;
- case Node::KIND_LOCALIZED_VALUE:
- assert(Components::allLocales(getRootAccess()->getLocale()));
- for (ContainerListeners::iterator j(
- containerListeners_.begin());
- j != containerListeners_.end(); ++j)
- {
- broadcaster->addContainerElementReplacedNotification(
- *j,
- css::container::ContainerEvent(
- static_cast< cppu::OWeakObject * >(this),
- css::uno::makeAny(i->first), child->asValue(),
- css::uno::Any()));
- //TODO: distinguish add/modify; non-void ReplacedElement
- }
- if (allChanges != 0) {
- allChanges->push_back(
- css::util::ElementChange(
- css::uno::makeAny(
- child->getRelativePathRepresentation()),
- child->asValue(), css::uno::Any()));
- //TODO: non-void ReplacedElement
- }
- assert(!collectPropChanges);
- break;
- case Node::KIND_PROPERTY:
- {
- for (ContainerListeners::iterator j(
- containerListeners_.begin());
- j != containerListeners_.end(); ++j)
- {
- broadcaster->addContainerElementReplacedNotification(
- *j,
- css::container::ContainerEvent(
- static_cast< cppu::OWeakObject * >(this),
- css::uno::makeAny(i->first), child->asValue(),
- css::uno::Any()));
- //TODO: distinguish add/remove/modify; non-void
- // ReplacedElement
- }
- 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()));
- }
- }
- if (allChanges != 0) {
- allChanges->push_back(
- css::util::ElementChange(
- css::uno::makeAny(
- child->getRelativePathRepresentation()),
- child->asValue(), css::uno::Any()));
- //TODO: non-void ReplacedElement
- }
- if (collectPropChanges) {
- propChanges.push_back(
- css::beans::PropertyChangeEvent(
- static_cast< cppu::OWeakObject * >(this),
- i->first, false, -1, css::uno::Any(),
- css::uno::Any()));
- }
- }
- break;
- case Node::KIND_GROUP:
- case Node::KIND_SET:
- if (i->second.children.empty()) {
- if (child->getNode()->getTemplateName().getLength() != 0) {
- for (ContainerListeners::iterator j(
- containerListeners_.begin());
- j != containerListeners_.end(); ++j)
- {
- broadcaster->
- addContainerElementInsertedNotification(
- *j,
- css::container::ContainerEvent(
- static_cast< cppu::OWeakObject * >(
- this),
- css::uno::makeAny(i->first),
- child->asValue(), css::uno::Any()));
- }
- if (allChanges != 0) {
- allChanges->push_back(
- css::util::ElementChange(
- css::uno::makeAny(
- child->getRelativePathRepresentation()),
- css::uno::Any(), css::uno::Any()));
- //TODO: non-void Element, ReplacedElement
- }
- }
- // else: spurious Modifications::Node not representing a
- // change
- } else {
- child->initBroadcasterAndChanges(
- i->second, broadcaster, allChanges);
- //TODO: if allChanges==0, recurse only into children w/
- // listeners
- }
- break;
- }
- } else {
- switch (getNode()->kind()) {
- case Node::KIND_LOCALIZED_PROPERTY:
- // Removed localized property value:
- assert(Components::allLocales(getRootAccess()->getLocale()));
- for (ContainerListeners::iterator j(
- containerListeners_.begin());
- j != containerListeners_.end(); ++j)
- {
- broadcaster->addContainerElementRemovedNotification(
- *j,
- css::container::ContainerEvent(
- static_cast< cppu::OWeakObject * >(this),
- css::uno::makeAny(i->first), css::uno::Any(),
- css::uno::Any()));
- //TODO: non-void ReplacedElement
- }
- if (allChanges != 0) {
- rtl::OUStringBuffer path(getRelativePathRepresentation());
- if (path.getLength() != 0) {
- path.append(sal_Unicode('/'));
- }
- path.append(
- Data::createSegment(
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")),
- i->first));
- allChanges->push_back(
- css::util::ElementChange(
- css::uno::makeAny(path.makeStringAndClear()),
- css::uno::Any(), css::uno::Any()));
- //TODO: non-void ReplacedElement
- }
- assert(!collectPropChanges);
- break;
- case Node::KIND_GROUP:
- {
- // Removed (non-localized) extension property:
- for (ContainerListeners::iterator j(
- containerListeners_.begin());
- j != containerListeners_.end(); ++j)
- {
- broadcaster->addContainerElementRemovedNotification(
- *j,
- css::container::ContainerEvent(
- static_cast< cppu::OWeakObject * >(this),
- css::uno::makeAny(i->first), css::uno::Any(),
- css::uno::Any()));
- //TODO: non-void ReplacedElement
- }
- 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()));
- }
- }
- if (allChanges != 0) {
- rtl::OUStringBuffer path(
- getRelativePathRepresentation());
- if (path.getLength() != 0) {
- path.append(sal_Unicode('/'));
- }
- path.append(i->first);
- allChanges->push_back(
- css::util::ElementChange(
- css::uno::makeAny(path.makeStringAndClear()),
- css::uno::Any(), css::uno::Any()));
- //TODO: non-void ReplacedElement
- }
- if (collectPropChanges) {
- propChanges.push_back(
- css::beans::PropertyChangeEvent(
- static_cast< cppu::OWeakObject * >(this),
- i->first, false, -1, css::uno::Any(),
- css::uno::Any()));
- }
- }
- break;
- case Node::KIND_SET:
- // Removed set member:
- if (i->second.children.empty()) {
- for (ContainerListeners::iterator j(
- containerListeners_.begin());
- j != containerListeners_.end(); ++j)
- {
- broadcaster->addContainerElementRemovedNotification(
- *j,
- css::container::ContainerEvent(
- static_cast< cppu::OWeakObject * >(this),
- css::uno::makeAny(i->first),
- css::uno::Any(), css::uno::Any()));
- //TODO: non-void ReplacedElement
- }
- if (allChanges != 0) {
- rtl::OUStringBuffer path(
- getRelativePathRepresentation());
- if (path.getLength() != 0) {
- path.append(sal_Unicode('/'));
- }
- path.append(
- Data::createSegment(
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")),
- i->first));
- allChanges->push_back(
- css::util::ElementChange(
- css::uno::makeAny(path.makeStringAndClear()),
- css::uno::Any(), css::uno::Any()));
- //TODO: non-void ReplacedElement
- }
- }
- // else: spurious Modifications::Node not representing a change
- break;
- default:
- assert(false); // this cannot happen
- break;
- }
- }
- }
- if (!propChanges.empty()) {
- css::uno::Sequence< css::beans::PropertyChangeEvent > seq(
- propChanges.getAsConstList());
- for (PropertiesChangeListeners::iterator i(
- propertiesChangeListeners_.begin());
- i != propertiesChangeListeners_.end(); ++i)
- {
- broadcaster->addPropertiesChangeNotification(*i, seq);
- }
- }
-}
-
-bool Access::isDisposed() const {
- return disposed_;
-}
-
-Access::ModifiedChild::ModifiedChild() {}
-
-Access::ModifiedChild::ModifiedChild(
- rtl::Reference< ChildAccess > const & theChild, bool theDirectlyModified):
- child(theChild), directlyModified(theDirectlyModified)
-{}
-
css::uno::Sequence< css::uno::Type > Access::getTypes()
throw (css::uno::RuntimeException)
{
@@ -858,8 +176,6 @@ css::uno::Sequence< css::uno::Type > Access::getTypes()
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());
@@ -880,6 +196,8 @@ css::uno::Sequence< css::uno::Type > Access::getTypes()
}
if (getRootAccess()->isUpdate()) {
types.push_back(cppu::UnoType< css::container::XNameReplace >::get());
+ types.push_back(
+ cppu::UnoType< css::container::XHierarchicalNameReplace >::get());
if (getNode()->kind() != Node::KIND_GROUP ||
dynamic_cast< GroupNode * >(getNode().get())->isExtensible())
{
@@ -890,6 +208,9 @@ css::uno::Sequence< css::uno::Type > Access::getTypes()
types.push_back(
cppu::UnoType< css::lang::XSingleServiceFactory >::get());
}
+ } else {
+ types.push_back(
+ cppu::UnoType< css::container::XHierarchicalNameAccess >::get());
}
addTypes(&types);
return types.getAsConstList();
@@ -1148,6 +469,57 @@ sal_Bool Access::hasByHierarchicalName(rtl::OUString const & aName)
return getSubChild(aName).is();
}
+void Access::replaceByHierarchicalName(
+ rtl::OUString const & aName, css::uno::Any const & aElement)
+ throw (
+ css::lang::IllegalArgumentException,
+ css::container::NoSuchElementException,
+ css::lang::WrappedTargetException, css::uno::RuntimeException)
+{
+ //TODO: Actually support sets and combine with replaceByName:
+ assert(thisIs(IS_UPDATE));
+ Broadcaster bc;
+ {
+ osl::MutexGuard g(*lock_);
+ checkLocalizedPropertyAccess();
+ rtl::Reference< ChildAccess > child(getSubChild(aName));
+ if (!child.is()) {
+ throw css::container::NoSuchElementException(
+ aName, static_cast< cppu::OWeakObject * >(this));
+ }
+ child->checkFinalized();
+ rtl::Reference< Node > parent(child->getParentNode());
+ assert(parent.is());
+ Modifications localMods;
+ switch (parent->kind()) {
+ case Node::KIND_LOCALIZED_PROPERTY:
+ case Node::KIND_GROUP:
+ child->setProperty(aElement, &localMods);
+ break;
+ case Node::KIND_SET:
+ throw css::lang::IllegalArgumentException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "configmgr::Access::replaceByHierarchicalName does not"
+ " currently support set members")),
+ static_cast< cppu::OWeakObject * >(this), 0);
+ case Node::KIND_ROOT:
+ throw css::lang::IllegalArgumentException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "configmgr::Access::replaceByHierarchicalName does not"
+ " allow changing component "))
+ + aName),
+ static_cast< cppu::OWeakObject * >(this), 0);
+ default:
+ assert(false); // this cannot happen
+ break;
+ }
+ getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc);
+ }
+ bc.send();
+}
+
void Access::addContainerListener(
css::uno::Reference< css::container::XContainerListener > const & xListener)
throw (css::uno::RuntimeException)
@@ -1957,6 +1329,696 @@ css::uno::Reference< css::uno::XInterface > Access::createInstanceWithArguments(
return createInstance();
}
+Access::Access(Components & components):
+ components_(components), disposed_(false)
+{
+ lock_ = lock();
+}
+
+Access::~Access() {}
+
+void Access::initDisposeBroadcaster(Broadcaster * broadcaster) {
+ 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::clearListeners() throw() {
+ disposeListeners_.clear();
+ containerListeners_.clear();
+ propertyChangeListeners_.clear();
+ vetoableChangeListeners_.clear();
+ propertiesChangeListeners_.clear();
+ //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->clearListeners();
+ }
+ }
+}
+
+css::uno::Any Access::queryInterface(css::uno::Type const & aType)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Any res(OWeakObject::queryInterface(aType));
+ if (res.hasValue()) {
+ 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),
+ static_cast< css::container::XHierarchicalNameReplace * >(this));
+ if (res.hasValue()) {
+ return res;
+ }
+ if (getNode()->kind() != Node::KIND_GROUP ||
+ dynamic_cast< GroupNode * >(getNode().get())->isExtensible())
+ {
+ 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;
+}
+
+Components & Access::getComponents() const {
+ return components_;
+}
+
+void Access::checkLocalizedPropertyAccess() {
+ if (getNode()->kind() == Node::KIND_LOCALIZED_PROPERTY &&
+ !Components::allLocales(getRootAccess()->getLocale()))
+ {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "configmgr Access to specialized LocalizedPropertyNode")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+}
+
+rtl::Reference< Node > Access::getParentNode() {
+ rtl::Reference< Access > parent(getParentAccess());
+ return parent.is() ? parent->getNode() : rtl::Reference< Node >();
+}
+
+rtl::Reference< ChildAccess > Access::getChild(rtl::OUString const & name) {
+ ModifiedChildren::iterator i(modifiedChildren_.find(name));
+ return i == modifiedChildren_.end()
+ ? getUnmodifiedChild(name) : getModifiedChild(i);
+}
+
+std::vector< rtl::Reference< ChildAccess > > Access::getAllChildren() {
+ std::vector< rtl::Reference< ChildAccess > > vec;
+ NodeMap const & members = getNode()->getMembers();
+ for (NodeMap::const_iterator i(members.begin()); i != members.end(); ++i) {
+ if (modifiedChildren_.find(i->first) == modifiedChildren_.end()) {
+ vec.push_back(getUnmodifiedChild(i->first));
+ assert(vec.back().is());
+ }
+ }
+ for (ModifiedChildren::iterator i(modifiedChildren_.begin());
+ i != modifiedChildren_.end(); ++i)
+ {
+ rtl::Reference< ChildAccess > child(getModifiedChild(i));
+ if (child.is()) {
+ vec.push_back(child);
+ }
+ }
+ return vec;
+}
+
+void Access::checkValue(css::uno::Any const & value, Type type, bool nillable) {
+ bool ok;
+ switch (type) {
+ case TYPE_NIL:
+ assert(false);
+ // fall through (cannot happen)
+ case TYPE_ERROR:
+ ok = false;
+ break;
+ case TYPE_ANY:
+ switch (getDynamicType(value)) {
+ case TYPE_ANY:
+ assert(false);
+ // fall through (cannot happen)
+ case TYPE_ERROR:
+ ok = false;
+ break;
+ case TYPE_NIL:
+ ok = nillable;
+ break;
+ default:
+ ok = true;
+ break;
+ }
+ break;
+ default:
+ ok = value.hasValue() ? value.isExtractableTo(mapType(type)) : nillable;
+ break;
+ }
+ if (!ok) {
+ throw css::lang::IllegalArgumentException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "configmgr inappropriate property value")),
+ static_cast< cppu::OWeakObject * >(this), -1);
+ }
+}
+
+void Access::insertLocalizedValueChild(
+ rtl::OUString const & name, css::uno::Any const & value,
+ Modifications * localModifications)
+{
+ assert(localModifications != 0);
+ LocalizedPropertyNode * locprop = dynamic_cast< LocalizedPropertyNode * >(
+ getNode().get());
+ checkValue(value, locprop->getStaticType(), locprop->isNillable());
+ rtl::Reference< ChildAccess > child(
+ new ChildAccess(
+ components_, getRootAccess(), this, name,
+ new LocalizedValueNode(Data::NO_LAYER, value)));
+ markChildAsModified(child);
+ localModifications->add(child->getRelativePath());
+}
+
+void Access::reportChildChanges(
+ std::vector< css::util::ElementChange > * changes)
+{
+ assert(changes != 0);
+ for (ModifiedChildren::iterator i(modifiedChildren_.begin());
+ i != modifiedChildren_.end(); ++i)
+ {
+ rtl::Reference< ChildAccess > child(getModifiedChild(i));
+ if (child.is()) {
+ child->reportChildChanges(changes);
+ changes->push_back(css::util::ElementChange());
+ //TODO: changed value and/or inserted node
+ } else {
+ changes->push_back(css::util::ElementChange()); //TODO: removed node
+ }
+ }
+}
+
+void Access::commitChildChanges(
+ bool valid, Modifications * globalModifications)
+{
+ 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, 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
+ // children); clarify what exactly should happen here for
+ // directly inserted children
+ }
+ NodeMap * members = getNode()->getMemberMap();
+ if (members != 0) {
+ NodeMap::const_iterator j(members->find(i->first));
+ if (child.is()) {
+ // Inserted:
+ if (j != members->end()) {
+ childValid = childValid &&
+ j->second->getFinalized() == Data::NO_LAYER;
+ if (childValid) {
+ child->getNode()->setMandatory(
+ j->second->getMandatory());
+ }
+ }
+ if (childValid) {
+ (*members)[i->first] = child->getNode();
+ }
+ } else {
+ // Removed:
+ childValid = childValid && j != members->end() &&
+ j->second->getFinalized() == Data::NO_LAYER &&
+ j->second->getMandatory() == Data::NO_LAYER;
+ if (childValid) {
+ members->erase(j);
+ }
+ }
+ }
+ if (childValid && i->second.directlyModified) {
+ Path path(getAbsolutePath());
+ path.push_back(i->first);
+ components_.addModification(path);
+ globalModifications->add(path);
+ }
+ i->second.child->committed();
+ modifiedChildren_.erase(i);
+ }
+}
+
+void Access::initBroadcasterAndChanges(
+ Modifications::Node const & modifications, Broadcaster * broadcaster,
+ std::vector< css::util::ElementChange > * allChanges)
+{
+ assert(broadcaster != 0);
+ comphelper::SequenceAsVector< css::beans::PropertyChangeEvent > propChanges;
+ bool collectPropChanges = !propertiesChangeListeners_.empty();
+ for (Modifications::Node::Children::const_iterator i(
+ modifications.children.begin());
+ i != modifications.children.end(); ++i)
+ {
+ rtl::Reference< ChildAccess > child(getChild(i->first));
+ if (child.is()) {
+ switch (child->getNode()->kind()) {
+ case Node::KIND_LOCALIZED_PROPERTY:
+ if (!i->second.children.empty()) {
+ if (Components::allLocales(getRootAccess()->getLocale())) {
+ child->initBroadcasterAndChanges(
+ i->second, broadcaster, allChanges);
+ //TODO: if allChanges==0, recurse only into children
+ // w/ listeners
+ } else {
+ //TODO: filter child mods that are irrelevant for
+ // locale:
+ for (ContainerListeners::iterator j(
+ containerListeners_.begin());
+ j != containerListeners_.end(); ++j)
+ {
+ broadcaster->
+ addContainerElementReplacedNotification(
+ *j,
+ css::container::ContainerEvent(
+ static_cast< cppu::OWeakObject * >(
+ this),
+ css::uno::makeAny(i->first),
+ css::uno::Any(), css::uno::Any()));
+ //TODO: non-void Element, ReplacedElement
+ }
+ 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()));
+ }
+ }
+ if (allChanges != 0) {
+ allChanges->push_back(
+ css::util::ElementChange(
+ css::uno::makeAny(
+ child->getRelativePathRepresentation()),
+ css::uno::Any(), css::uno::Any()));
+ //TODO: non-void Element, ReplacedElement
+ }
+ if (collectPropChanges) {
+ propChanges.push_back(
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ }
+ // else: spurious Modifications::Node not representing a change
+ break;
+ case Node::KIND_LOCALIZED_VALUE:
+ assert(Components::allLocales(getRootAccess()->getLocale()));
+ for (ContainerListeners::iterator j(
+ containerListeners_.begin());
+ j != containerListeners_.end(); ++j)
+ {
+ broadcaster->addContainerElementReplacedNotification(
+ *j,
+ css::container::ContainerEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ css::uno::makeAny(i->first), child->asValue(),
+ css::uno::Any()));
+ //TODO: distinguish add/modify; non-void ReplacedElement
+ }
+ if (allChanges != 0) {
+ allChanges->push_back(
+ css::util::ElementChange(
+ css::uno::makeAny(
+ child->getRelativePathRepresentation()),
+ child->asValue(), css::uno::Any()));
+ //TODO: non-void ReplacedElement
+ }
+ assert(!collectPropChanges);
+ break;
+ case Node::KIND_PROPERTY:
+ {
+ for (ContainerListeners::iterator j(
+ containerListeners_.begin());
+ j != containerListeners_.end(); ++j)
+ {
+ broadcaster->addContainerElementReplacedNotification(
+ *j,
+ css::container::ContainerEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ css::uno::makeAny(i->first), child->asValue(),
+ css::uno::Any()));
+ //TODO: distinguish add/remove/modify; non-void
+ // ReplacedElement
+ }
+ 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()));
+ }
+ }
+ if (allChanges != 0) {
+ allChanges->push_back(
+ css::util::ElementChange(
+ css::uno::makeAny(
+ child->getRelativePathRepresentation()),
+ child->asValue(), css::uno::Any()));
+ //TODO: non-void ReplacedElement
+ }
+ if (collectPropChanges) {
+ propChanges.push_back(
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ break;
+ case Node::KIND_GROUP:
+ case Node::KIND_SET:
+ if (i->second.children.empty()) {
+ if (child->getNode()->getTemplateName().getLength() != 0) {
+ for (ContainerListeners::iterator j(
+ containerListeners_.begin());
+ j != containerListeners_.end(); ++j)
+ {
+ broadcaster->
+ addContainerElementInsertedNotification(
+ *j,
+ css::container::ContainerEvent(
+ static_cast< cppu::OWeakObject * >(
+ this),
+ css::uno::makeAny(i->first),
+ child->asValue(), css::uno::Any()));
+ }
+ if (allChanges != 0) {
+ allChanges->push_back(
+ css::util::ElementChange(
+ css::uno::makeAny(
+ child->getRelativePathRepresentation()),
+ css::uno::Any(), css::uno::Any()));
+ //TODO: non-void Element, ReplacedElement
+ }
+ }
+ // else: spurious Modifications::Node not representing a
+ // change
+ } else {
+ child->initBroadcasterAndChanges(
+ i->second, broadcaster, allChanges);
+ //TODO: if allChanges==0, recurse only into children w/
+ // listeners
+ }
+ break;
+ case Node::KIND_ROOT:
+ assert(false); // this cannot happen
+ break;
+ }
+ } else {
+ switch (getNode()->kind()) {
+ case Node::KIND_LOCALIZED_PROPERTY:
+ // Removed localized property value:
+ assert(Components::allLocales(getRootAccess()->getLocale()));
+ for (ContainerListeners::iterator j(
+ containerListeners_.begin());
+ j != containerListeners_.end(); ++j)
+ {
+ broadcaster->addContainerElementRemovedNotification(
+ *j,
+ css::container::ContainerEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ css::uno::makeAny(i->first), css::uno::Any(),
+ css::uno::Any()));
+ //TODO: non-void ReplacedElement
+ }
+ if (allChanges != 0) {
+ rtl::OUStringBuffer path(getRelativePathRepresentation());
+ if (path.getLength() != 0) {
+ path.append(sal_Unicode('/'));
+ }
+ path.append(
+ Data::createSegment(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")),
+ i->first));
+ allChanges->push_back(
+ css::util::ElementChange(
+ css::uno::makeAny(path.makeStringAndClear()),
+ css::uno::Any(), css::uno::Any()));
+ //TODO: non-void ReplacedElement
+ }
+ assert(!collectPropChanges);
+ break;
+ case Node::KIND_GROUP:
+ {
+ // Removed (non-localized) extension property:
+ for (ContainerListeners::iterator j(
+ containerListeners_.begin());
+ j != containerListeners_.end(); ++j)
+ {
+ broadcaster->addContainerElementRemovedNotification(
+ *j,
+ css::container::ContainerEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ css::uno::makeAny(i->first), css::uno::Any(),
+ css::uno::Any()));
+ //TODO: non-void ReplacedElement
+ }
+ 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()));
+ }
+ }
+ if (allChanges != 0) {
+ rtl::OUStringBuffer path(
+ getRelativePathRepresentation());
+ if (path.getLength() != 0) {
+ path.append(sal_Unicode('/'));
+ }
+ path.append(i->first);
+ allChanges->push_back(
+ css::util::ElementChange(
+ css::uno::makeAny(path.makeStringAndClear()),
+ css::uno::Any(), css::uno::Any()));
+ //TODO: non-void ReplacedElement
+ }
+ if (collectPropChanges) {
+ propChanges.push_back(
+ css::beans::PropertyChangeEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ i->first, false, -1, css::uno::Any(),
+ css::uno::Any()));
+ }
+ }
+ break;
+ case Node::KIND_SET:
+ // Removed set member:
+ if (i->second.children.empty()) {
+ for (ContainerListeners::iterator j(
+ containerListeners_.begin());
+ j != containerListeners_.end(); ++j)
+ {
+ broadcaster->addContainerElementRemovedNotification(
+ *j,
+ css::container::ContainerEvent(
+ static_cast< cppu::OWeakObject * >(this),
+ css::uno::makeAny(i->first),
+ css::uno::Any(), css::uno::Any()));
+ //TODO: non-void ReplacedElement
+ }
+ if (allChanges != 0) {
+ rtl::OUStringBuffer path(
+ getRelativePathRepresentation());
+ if (path.getLength() != 0) {
+ path.append(sal_Unicode('/'));
+ }
+ path.append(
+ Data::createSegment(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")),
+ i->first));
+ allChanges->push_back(
+ css::util::ElementChange(
+ css::uno::makeAny(path.makeStringAndClear()),
+ css::uno::Any(), css::uno::Any()));
+ //TODO: non-void ReplacedElement
+ }
+ }
+ // else: spurious Modifications::Node not representing a change
+ break;
+ default:
+ assert(false); // this cannot happen
+ break;
+ }
+ }
+ }
+ if (!propChanges.empty()) {
+ css::uno::Sequence< css::beans::PropertyChangeEvent > seq(
+ propChanges.getAsConstList());
+ for (PropertiesChangeListeners::iterator i(
+ propertiesChangeListeners_.begin());
+ i != propertiesChangeListeners_.end(); ++i)
+ {
+ broadcaster->addPropertiesChangeNotification(*i, seq);
+ }
+ }
+}
+
+bool Access::isDisposed() const {
+ return disposed_;
+}
+
+Access::ModifiedChild::ModifiedChild() {}
+
+Access::ModifiedChild::ModifiedChild(
+ rtl::Reference< ChildAccess > const & theChild, bool theDirectlyModified):
+ child(theChild), directlyModified(theDirectlyModified)
+{}
+
rtl::Reference< ChildAccess > Access::getModifiedChild(
ModifiedChildren::iterator const & childIterator)
{
diff --git a/configmgr/source/access.hxx b/configmgr/source/access.hxx
index d2409cbb2f1d..6401df3f8344 100644
--- a/configmgr/source/access.hxx
+++ b/configmgr/source/access.hxx
@@ -51,7 +51,7 @@
#include "com/sun/star/container/NoSuchElementException.hpp"
#include "com/sun/star/container/XContainer.hpp"
#include "com/sun/star/container/XHierarchicalName.hpp"
-#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/container/XHierarchicalNameReplace.hpp"
#include "com/sun/star/container/XNameContainer.hpp"
#include "com/sun/star/container/XNamed.hpp"
#include "com/sun/star/lang/IllegalArgumentException.hpp"
@@ -106,7 +106,7 @@ 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::XHierarchicalNameReplace,
public com::sun::star::container::XContainer,
public com::sun::star::beans::XExactName,
public com::sun::star::beans::XPropertySetInfo,
@@ -146,68 +146,6 @@ public:
using OWeakObject::acquire;
using OWeakObject::release;
-protected:
- Access(Components & components);
-
- virtual ~Access();
-
- virtual rtl::OUString getNameInternal() = 0;
- virtual rtl::Reference< RootAccess > getRootAccess() = 0;
- virtual rtl::Reference< Access > getParentAccess() = 0;
-
- virtual void addTypes(std::vector< com::sun::star::uno::Type > * types)
- const = 0;
-
- virtual void addSupportedServiceNames(
- std::vector< rtl::OUString > * services) = 0;
-
- virtual void initDisposeBroadcaster(Broadcaster * broadcaster);
- virtual void clearListeners() throw ();
-
- virtual com::sun::star::uno::Any SAL_CALL queryInterface(
- com::sun::star::uno::Type const & aType)
- throw (com::sun::star::uno::RuntimeException);
-
- Components & getComponents() const;
-
- void checkLocalizedPropertyAccess();
-
- rtl::Reference< Node > getParentNode();
- rtl::Reference< ChildAccess > getChild(rtl::OUString const & name);
- std::vector< rtl::Reference< ChildAccess > > getAllChildren();
-
- void checkValue(
- com::sun::star::uno::Any const & value, Type type, bool nillable);
-
- void insertLocalizedValueChild(
- rtl::OUString const & name, com::sun::star::uno::Any const & value,
- Modifications * localModifications);
-
- void reportChildChanges(
- std::vector< com::sun::star::util::ElementChange > * changes);
-
- void commitChildChanges(bool valid, Modifications * globalModifications);
-
- void initBroadcasterAndChanges(
- Modifications::Node const & modifications, Broadcaster * broadcaster,
- std::vector< com::sun::star::util::ElementChange > * changes);
-
- bool isDisposed() const;
-
-private:
- struct ModifiedChild {
- rtl::Reference< ChildAccess > child;
- bool directlyModified;
-
- ModifiedChild();
-
- ModifiedChild(
- rtl::Reference< ChildAccess > const & theChild,
- bool theDirectlyModified);
- };
-
- 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);
@@ -264,6 +202,14 @@ private:
virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
throw (com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL replaceByHierarchicalName(
+ rtl::OUString const & aName, com::sun::star::uno::Any const & aElement)
+ throw (
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::container::NoSuchElementException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
virtual void SAL_CALL addContainerListener(
com::sun::star::uno::Reference<
com::sun::star::container::XContainerListener > const & xListener)
@@ -491,6 +437,68 @@ private:
com::sun::star::uno::Exception,
com::sun::star::uno::RuntimeException);
+protected:
+ Access(Components & components);
+
+ virtual ~Access();
+
+ virtual rtl::OUString getNameInternal() = 0;
+ virtual rtl::Reference< RootAccess > getRootAccess() = 0;
+ virtual rtl::Reference< Access > getParentAccess() = 0;
+
+ virtual void addTypes(std::vector< com::sun::star::uno::Type > * types)
+ const = 0;
+
+ virtual void addSupportedServiceNames(
+ std::vector< rtl::OUString > * services) = 0;
+
+ virtual void initDisposeBroadcaster(Broadcaster * broadcaster);
+ virtual void clearListeners() throw ();
+
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface(
+ com::sun::star::uno::Type const & aType)
+ throw (com::sun::star::uno::RuntimeException);
+
+ Components & getComponents() const;
+
+ void checkLocalizedPropertyAccess();
+
+ rtl::Reference< Node > getParentNode();
+ rtl::Reference< ChildAccess > getChild(rtl::OUString const & name);
+ std::vector< rtl::Reference< ChildAccess > > getAllChildren();
+
+ void checkValue(
+ com::sun::star::uno::Any const & value, Type type, bool nillable);
+
+ void insertLocalizedValueChild(
+ rtl::OUString const & name, com::sun::star::uno::Any const & value,
+ Modifications * localModifications);
+
+ void reportChildChanges(
+ std::vector< com::sun::star::util::ElementChange > * changes);
+
+ void commitChildChanges(bool valid, Modifications * globalModifications);
+
+ void initBroadcasterAndChanges(
+ Modifications::Node const & modifications, Broadcaster * broadcaster,
+ std::vector< com::sun::star::util::ElementChange > * changes);
+
+ bool isDisposed() const;
+
+private:
+ struct ModifiedChild {
+ rtl::Reference< ChildAccess > child;
+ bool directlyModified;
+
+ ModifiedChild();
+
+ ModifiedChild(
+ rtl::Reference< ChildAccess > const & theChild,
+ bool theDirectlyModified);
+ };
+
+ typedef std::map< rtl::OUString, ModifiedChild > ModifiedChildren;
+
rtl::Reference< ChildAccess > getModifiedChild(
ModifiedChildren::iterator const & childIterator);
diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx
index 48d555e3236e..56c597593395 100644
--- a/configmgr/source/components.cxx
+++ b/configmgr/source/components.cxx
@@ -137,7 +137,7 @@ bool canRemoveFromLayer(int layer, rtl::Reference< Node > const & node) {
switch (node->kind()) {
case Node::KIND_LOCALIZED_PROPERTY:
case Node::KIND_GROUP:
- for (NodeMap::iterator i(node->getMembers().begin());
+ for (NodeMap::const_iterator i(node->getMembers().begin());
i != node->getMembers().end(); ++i)
{
if (!canRemoveFromLayer(layer, i->second)) {
@@ -402,7 +402,9 @@ void Components::removeExtensionXcuFile(
node->kind() == Node::KIND_GROUP ||
node->kind() == Node::KIND_SET);
if (canRemoveFromLayer(item->layer, node)) {
- parent->getMembers().erase(i->back());
+ NodeMap * members = parent->getMemberMap();
+ assert(members != 0);
+ members->erase(i->back());
data_.modifications.remove(*i);
modifications->add(*i);
}
diff --git a/configmgr/source/configmgr.component b/configmgr/source/configmgr.component
index 6ed51257005d..9ad4c79eed0b 100755
--- a/configmgr/source/configmgr.component
+++ b/configmgr/source/configmgr.component
@@ -38,6 +38,12 @@
<service name="com.sun.star.configuration.DefaultProvider"/>
<singleton name="com.sun.star.configuration.theDefaultProvider"/>
</implementation>
+ <implementation name="com.sun.star.comp.configuration.ReadOnlyAccess">
+ <singleton name="com.sun.star.configuration.ReadOnlyAccess"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.configuration.ReadWriteAccess">
+ <service name="com.sun.star.configuration.ReadWriteAccess"/>
+ </implementation>
<implementation name="com.sun.star.comp.configuration.Update">
<service name="com.sun.star.configuration.Update_Service"/>
<singleton name="com.sun.star.configuration.Update"/>
diff --git a/configmgr/source/data.cxx b/configmgr/source/data.cxx
index 0fdc1e5eba92..fcc42e97cecc 100644
--- a/configmgr/source/data.cxx
+++ b/configmgr/source/data.cxx
@@ -48,6 +48,7 @@
#include "groupnode.hxx"
#include "node.hxx"
#include "nodemap.hxx"
+#include "rootnode.hxx"
#include "setnode.hxx"
namespace configmgr {
@@ -207,6 +208,8 @@ rtl::Reference< Node > Data::findNode(
? rtl::Reference< Node >() : i->second;
}
+Data::Data(): root_(new RootNode(components)) {}
+
rtl::Reference< Node > Data::resolvePathRepresentation(
rtl::OUString const & pathRepresentation,
rtl::OUString * canonicRepresentation, Path * path, int * finalizedLayer)
@@ -218,6 +221,18 @@ rtl::Reference< Node > Data::resolvePathRepresentation(
pathRepresentation),
css::uno::Reference< css::uno::XInterface >());
}
+ if (path != 0) {
+ path->clear();
+ }
+ if (pathRepresentation.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("/"))) {
+ if (canonicRepresentation != 0) {
+ *canonicRepresentation = pathRepresentation;
+ }
+ if (finalizedLayer != 0) {
+ *finalizedLayer = NO_LAYER;
+ }
+ return root_;
+ }
rtl::OUString seg;
bool setElement;
rtl::OUString templateName;
@@ -231,9 +246,6 @@ rtl::Reference< Node > Data::resolvePathRepresentation(
}
NodeMap::const_iterator i(components.find(seg));
rtl::OUStringBuffer canonic;
- if (path != 0) {
- path->clear();
- }
rtl::Reference< Node > parent;
int finalized = NO_LAYER;
for (rtl::Reference< Node > p(i == components.end() ? 0 : i->second);;) {
diff --git a/configmgr/source/data.hxx b/configmgr/source/data.hxx
index f60ecfa1e807..64980eef4056 100644
--- a/configmgr/source/data.hxx
+++ b/configmgr/source/data.hxx
@@ -81,6 +81,8 @@ struct Data: private boost::noncopyable {
static rtl::Reference< Node > findNode(
int layer, NodeMap const & map, rtl::OUString const & name);
+ Data();
+
rtl::Reference< Node > resolvePathRepresentation(
rtl::OUString const & pathRepresentation,
rtl::OUString * canonicRepresenation, Path * path, int * finalizedLayer)
@@ -99,6 +101,8 @@ private:
typedef std::map< rtl::OUString, rtl::Reference< ExtensionXcu > >
ExtensionXcuAdditions;
+ rtl::Reference< Node > root_;
+
ExtensionXcuAdditions extensionXcuAdditions_;
};
diff --git a/configmgr/source/groupnode.cxx b/configmgr/source/groupnode.cxx
index 5591acbe606d..09658567b4c3 100644
--- a/configmgr/source/groupnode.cxx
+++ b/configmgr/source/groupnode.cxx
@@ -48,8 +48,8 @@ rtl::Reference< Node > GroupNode::clone(bool keepTemplateName) const {
return new GroupNode(*this, keepTemplateName);
}
-NodeMap & GroupNode::getMembers() {
- return members_;
+NodeMap * GroupNode::getMemberMap() {
+ return &members_;
}
rtl::OUString GroupNode::getTemplateName() const {
diff --git a/configmgr/source/groupnode.hxx b/configmgr/source/groupnode.hxx
index 02f1679998a2..1d14a9293a6b 100644
--- a/configmgr/source/groupnode.hxx
+++ b/configmgr/source/groupnode.hxx
@@ -45,7 +45,7 @@ public:
virtual rtl::Reference< Node > clone(bool keepTemplateName) const;
- virtual NodeMap & getMembers();
+ virtual NodeMap * getMemberMap();
virtual rtl::OUString getTemplateName() const;
diff --git a/configmgr/source/localizedpropertynode.cxx b/configmgr/source/localizedpropertynode.cxx
index 270485835228..196e57f6a6f9 100644
--- a/configmgr/source/localizedpropertynode.cxx
+++ b/configmgr/source/localizedpropertynode.cxx
@@ -55,8 +55,8 @@ rtl::Reference< Node > LocalizedPropertyNode::clone(bool) const {
return new LocalizedPropertyNode(*this);
}
-NodeMap & LocalizedPropertyNode::getMembers() {
- return members_;
+NodeMap * LocalizedPropertyNode::getMemberMap() {
+ return &members_;
}
Type LocalizedPropertyNode::getStaticType() const {
diff --git a/configmgr/source/localizedpropertynode.hxx b/configmgr/source/localizedpropertynode.hxx
index bbe934e36bcd..b49f375c43c2 100644
--- a/configmgr/source/localizedpropertynode.hxx
+++ b/configmgr/source/localizedpropertynode.hxx
@@ -50,7 +50,7 @@ public:
virtual rtl::Reference< Node > clone(bool keepTemplateName) const;
- virtual NodeMap & getMembers();
+ virtual NodeMap * getMemberMap();
Type getStaticType() const;
diff --git a/configmgr/source/makefile.mk b/configmgr/source/makefile.mk
index e75af0dde734..f52b4f4c0af0 100644
--- a/configmgr/source/makefile.mk
+++ b/configmgr/source/makefile.mk
@@ -55,7 +55,10 @@ SLOFILES = \
$(SLO)/parsemanager.obj \
$(SLO)/partial.obj \
$(SLO)/propertynode.obj \
+ $(SLO)/readonlyaccess.obj \
+ $(SLO)/readwriteaccess.obj \
$(SLO)/rootaccess.obj \
+ $(SLO)/rootnode.obj \
$(SLO)/services.obj \
$(SLO)/setnode.obj \
$(SLO)/type.obj \
diff --git a/configmgr/source/node.cxx b/configmgr/source/node.cxx
index 892cdaa622fd..b6480820aedc 100644
--- a/configmgr/source/node.cxx
+++ b/configmgr/source/node.cxx
@@ -30,11 +30,7 @@
#include <cassert>
-#include "com/sun/star/uno/Reference.hxx"
-#include "com/sun/star/uno/RuntimeException.hpp"
-#include "com/sun/star/uno/XInterface.hpp"
#include "rtl/ref.hxx"
-#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "data.hxx"
@@ -43,17 +39,15 @@
namespace configmgr {
-namespace {
-
-namespace css = com::sun::star;
-
+NodeMap const & Node::getMembers() const {
+ NodeMap * members = const_cast< Node * >(this)->getMemberMap();
+ assert(members != 0);
+ return *members;
}
-NodeMap & Node::getMembers() {
+NodeMap * Node::getMemberMap() {
assert(false);
- throw css::uno::RuntimeException(
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("this cannot happen")),
- css::uno::Reference< css::uno::XInterface >());
+ return 0;
}
rtl::OUString Node::getTemplateName() const {
@@ -87,8 +81,8 @@ int Node::getFinalized() const {
}
rtl::Reference< Node > Node::getMember(rtl::OUString const & name) {
- NodeMap & members = getMembers();
- NodeMap::iterator i(members.find(name));
+ NodeMap const & members = getMembers();
+ NodeMap::const_iterator i(members.find(name));
return i == members.end() ? rtl::Reference< Node >() : i->second;
}
diff --git a/configmgr/source/node.hxx b/configmgr/source/node.hxx
index 932d11cf3744..01aef18c7a6a 100644
--- a/configmgr/source/node.hxx
+++ b/configmgr/source/node.hxx
@@ -44,13 +44,14 @@ class Node: public salhelper::SimpleReferenceObject {
public:
enum Kind {
KIND_PROPERTY, KIND_LOCALIZED_PROPERTY, KIND_LOCALIZED_VALUE,
- KIND_GROUP, KIND_SET };
+ KIND_GROUP, KIND_SET, KIND_ROOT };
virtual Kind kind() const = 0;
virtual rtl::Reference< Node > clone(bool keepTemplateName) const = 0;
- virtual NodeMap & getMembers();
+ virtual NodeMap const & getMembers() const;
+ virtual NodeMap * getMemberMap();
virtual rtl::OUString getTemplateName() const;
virtual void setMandatory(int layer);
diff --git a/configmgr/source/readonlyaccess.cxx b/configmgr/source/readonlyaccess.cxx
new file mode 100644
index 000000000000..d9ab2dccd837
--- /dev/null
+++ b/configmgr/source/readonlyaccess.cxx
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
+ * (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#include "sal/config.h"
+
+#include "boost/noncopyable.hpp"
+#include "cppuhelper/implbase2.hxx"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/container/NoSuchElementException.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#include "components.hxx"
+#include "lock.hxx"
+#include "readonlyaccess.hxx"
+#include "rootaccess.hxx"
+
+namespace configmgr { namespace read_only_access {
+
+namespace {
+
+namespace css = com::sun::star;
+
+class Service:
+ public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::container::XHierarchicalNameAccess >,
+ private boost::noncopyable
+{
+public:
+ Service(css::uno::Reference< css::uno::XComponentContext > const & context);
+
+private:
+ virtual ~Service() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return read_only_access::getImplementationName(); }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const &)
+ throw (css::uno::RuntimeException)
+ { return false; }
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return read_only_access::getSupportedServiceNames(); }
+
+ virtual css::uno::Any SAL_CALL getByHierarchicalName(
+ rtl::OUString const & aName)
+ throw (
+ css::container::NoSuchElementException, css::uno::RuntimeException)
+ { return root_->getByHierarchicalName(aName); }
+
+ virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
+ throw (css::uno::RuntimeException)
+ { return root_->hasByHierarchicalName(aName); }
+
+ rtl::Reference< RootAccess > root_;
+};
+
+Service::Service(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+{
+ osl::MutexGuard guard(*lock());
+ Components & components = Components::getSingleton(context);
+ root_ = new RootAccess(
+ components, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), false);
+ components.addRootAccess(root_);
+}
+
+}
+
+css::uno::Reference< css::uno::XInterface > create(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+{
+ return static_cast< cppu::OWeakObject * >(new Service(context));
+}
+
+rtl::OUString getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.configuration.ReadOnlyAccess"));
+}
+
+css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
+ return css::uno::Sequence< rtl::OUString >();
+}
+
+} }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/configmgr/source/readonlyaccess.hxx b/configmgr/source/readonlyaccess.hxx
new file mode 100644
index 000000000000..9549789469b4
--- /dev/null
+++ b/configmgr/source/readonlyaccess.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
+ * (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef INCLUDED_CONFIGMGR_SOURCE_READONLYACCESS_HXX
+#define INCLUDED_CONFIGMGR_SOURCE_READONLYACCESS_HXX
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ class XInterface;
+ }
+} } }
+namespace rtl { class OUString; }
+
+namespace configmgr { namespace read_only_access {
+
+com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL
+create(
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+ const &);
+
+rtl::OUString SAL_CALL getImplementationName();
+
+com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+getSupportedServiceNames();
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/configmgr/source/readwriteaccess.cxx b/configmgr/source/readwriteaccess.cxx
new file mode 100644
index 000000000000..0e4415fd44ed
--- /dev/null
+++ b/configmgr/source/readwriteaccess.cxx
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
+ * (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#include "sal/config.h"
+
+#include "boost/noncopyable.hpp"
+#include "cppuhelper/implbase2.hxx"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/container/NoSuchElementException.hpp"
+#include "com/sun/star/configuration/XReadWriteAccess.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/util/ChangesSet.hpp"
+#include "rtl/ref.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#include "components.hxx"
+#include "lock.hxx"
+#include "readwriteaccess.hxx"
+#include "rootaccess.hxx"
+
+namespace configmgr { namespace read_write_access {
+
+namespace {
+
+namespace css = com::sun::star;
+
+class Service:
+ public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::configuration::XReadWriteAccess >,
+ private boost::noncopyable
+{
+public:
+ Service(css::uno::Reference< css::uno::XComponentContext > const & context);
+
+private:
+ virtual ~Service() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return read_write_access::getImplementationName(); }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const &)
+ throw (css::uno::RuntimeException)
+ { return false; }
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return read_write_access::getSupportedServiceNames(); }
+
+ virtual css::uno::Any SAL_CALL getByHierarchicalName(
+ rtl::OUString const & aName)
+ throw (
+ css::container::NoSuchElementException, css::uno::RuntimeException)
+ { return root_->getByHierarchicalName(aName); }
+
+ virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
+ throw (css::uno::RuntimeException)
+ { return root_->hasByHierarchicalName(aName); }
+
+ virtual void SAL_CALL replaceByHierarchicalName(
+ rtl::OUString const & aName, css::uno::Any const & aElement)
+ throw (
+ css::lang::IllegalArgumentException,
+ css::container::NoSuchElementException,
+ css::lang::WrappedTargetException, css::uno::RuntimeException)
+ { root_->replaceByHierarchicalName(aName, aElement); }
+
+ virtual void SAL_CALL commitChanges()
+ throw (css::lang::WrappedTargetException, css::uno::RuntimeException)
+ { root_->commitChanges(); }
+
+ virtual sal_Bool SAL_CALL hasPendingChanges()
+ throw (css::uno::RuntimeException)
+ { return root_->hasPendingChanges(); }
+
+ virtual css::util::ChangesSet SAL_CALL getPendingChanges()
+ throw (css::uno::RuntimeException)
+ { return root_->getPendingChanges(); }
+
+ rtl::Reference< RootAccess > root_;
+};
+
+Service::Service(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+{
+ osl::MutexGuard guard(*lock());
+ Components & components = Components::getSingleton(context);
+ root_ = new RootAccess(
+ components, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), true);
+ components.addRootAccess(root_);
+}
+
+}
+
+css::uno::Reference< css::uno::XInterface > create(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+{
+ return static_cast< cppu::OWeakObject * >(new Service(context));
+}
+
+rtl::OUString getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.configuration.ReadWriteAccess"));
+}
+
+css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
+ rtl::OUString name(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ReadWriteAccess"));
+ return css::uno::Sequence< rtl::OUString >(&name, 1);
+}
+
+} }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/configmgr/source/readwriteaccess.hxx b/configmgr/source/readwriteaccess.hxx
new file mode 100644
index 000000000000..b559b2a51f9f
--- /dev/null
+++ b/configmgr/source/readwriteaccess.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
+ * (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef INCLUDED_CONFIGMGR_SOURCE_READWRITEACCESS_HXX
+#define INCLUDED_CONFIGMGR_SOURCE_READWRITEACCESS_HXX
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ class XInterface;
+ }
+} } }
+namespace rtl { class OUString; }
+
+namespace configmgr { namespace read_write_access {
+
+com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL
+create(
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+ const &);
+
+rtl::OUString SAL_CALL getImplementationName();
+
+com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+getSupportedServiceNames();
+
+} }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/configmgr/source/rootaccess.cxx b/configmgr/source/rootaccess.cxx
index fc1fe39e8073..03ee3b88e29a 100644
--- a/configmgr/source/rootaccess.cxx
+++ b/configmgr/source/rootaccess.cxx
@@ -133,6 +133,91 @@ void RootAccess::setAlive(bool b) {
alive_ = b;
}
+void RootAccess::addChangesListener(
+ css::uno::Reference< css::util::XChangesListener > const & aListener)
+ throw (css::uno::RuntimeException)
+{
+ assert(thisIs(IS_ANY));
+ {
+ 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 &) {}
+}
+
+void RootAccess::removeChangesListener(
+ css::uno::Reference< css::util::XChangesListener > const & aListener)
+ throw (css::uno::RuntimeException)
+{
+ assert(thisIs(IS_ANY));
+ osl::MutexGuard g(*lock_);
+ checkLocalizedPropertyAccess();
+ ChangesListeners::iterator i(changesListeners_.find(aListener));
+ if (i != changesListeners_.end()) {
+ changesListeners_.erase(i);
+ }
+}
+
+void RootAccess::commitChanges()
+ throw (css::lang::WrappedTargetException, css::uno::RuntimeException)
+{
+ assert(thisIs(IS_UPDATE));
+ if (!alive_)
+ {
+ return;
+ }
+ Broadcaster bc;
+ {
+ osl::MutexGuard g(*lock_);
+
+ checkLocalizedPropertyAccess();
+ int finalizedLayer;
+ Modifications globalMods;
+ commitChildChanges(
+ ((getComponents().resolvePathRepresentation(
+ pathRepresentation_, 0, 0, &finalizedLayer)
+ == node_) &&
+ finalizedLayer == Data::NO_LAYER),
+ &globalMods);
+ getComponents().writeModifications();
+ getComponents().initGlobalBroadcaster(globalMods, this, &bc);
+ }
+ bc.send();
+}
+
+sal_Bool RootAccess::hasPendingChanges() throw (css::uno::RuntimeException) {
+ assert(thisIs(IS_UPDATE));
+ osl::MutexGuard g(*lock_);
+ checkLocalizedPropertyAccess();
+ //TODO: Optimize:
+ std::vector< css::util::ElementChange > changes;
+ reportChildChanges(&changes);
+ return !changes.empty();
+}
+
+css::util::ChangesSet RootAccess::getPendingChanges()
+ throw (css::uno::RuntimeException)
+{
+ assert(thisIs(IS_UPDATE));
+ osl::MutexGuard g(*lock_);
+ checkLocalizedPropertyAccess();
+ comphelper::SequenceAsVector< css::util::ElementChange > changes;
+ reportChildChanges(&changes);
+ return changes.getAsConstList();
+}
+
RootAccess::~RootAccess()
{
osl::MutexGuard g(*lock_);
@@ -166,8 +251,10 @@ rtl::Reference< Node > RootAccess::getNode() {
// RuntimeException.Context is left null here
}
pathRepresentation_ = canonic;
- assert(!path_.empty());
- name_ = path_.back();
+ assert(!path_.empty() || node_->kind() == Node::KIND_ROOT);
+ if (!path_.empty()) {
+ name_ = path_.back();
+ }
finalized_ = finalizedLayer != Data::NO_LAYER;
}
return node_;
@@ -252,97 +339,13 @@ css::uno::Any RootAccess::queryInterface(css::uno::Type const & aType)
return res;
}
-void RootAccess::addChangesListener(
- css::uno::Reference< css::util::XChangesListener > const & aListener)
+rtl::OUString RootAccess::getImplementationName()
throw (css::uno::RuntimeException)
{
assert(thisIs(IS_ANY));
- {
- 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 &) {}
-}
-
-void RootAccess::removeChangesListener(
- css::uno::Reference< css::util::XChangesListener > const & aListener)
- throw (css::uno::RuntimeException)
-{
- assert(thisIs(IS_ANY));
- osl::MutexGuard g(*lock_);
- checkLocalizedPropertyAccess();
- ChangesListeners::iterator i(changesListeners_.find(aListener));
- if (i != changesListeners_.end()) {
- changesListeners_.erase(i);
- }
-}
-
-void RootAccess::commitChanges()
- throw (css::lang::WrappedTargetException, css::uno::RuntimeException)
-{
- assert(thisIs(IS_UPDATE));
- if (!alive_)
- {
- return;
- }
- Broadcaster bc;
- {
- osl::MutexGuard g(*lock_);
-
- checkLocalizedPropertyAccess();
- int finalizedLayer;
- Modifications globalMods;
- commitChildChanges(
- ((getComponents().resolvePathRepresentation(
- pathRepresentation_, 0, 0, &finalizedLayer)
- == node_) &&
- finalizedLayer == Data::NO_LAYER),
- &globalMods);
- getComponents().writeModifications();
- getComponents().initGlobalBroadcaster(globalMods, this, &bc);
- }
- bc.send();
-}
-
-sal_Bool RootAccess::hasPendingChanges() throw (css::uno::RuntimeException) {
- assert(thisIs(IS_UPDATE));
- osl::MutexGuard g(*lock_);
- checkLocalizedPropertyAccess();
- //TODO: Optimize:
- std::vector< css::util::ElementChange > changes;
- reportChildChanges(&changes);
- return !changes.empty();
-}
-
-css::util::ChangesSet RootAccess::getPendingChanges()
- throw (css::uno::RuntimeException)
-{
- assert(thisIs(IS_UPDATE));
- osl::MutexGuard g(*lock_);
- checkLocalizedPropertyAccess();
- comphelper::SequenceAsVector< css::util::ElementChange > changes;
- reportChildChanges(&changes);
- return changes.getAsConstList();
-}
-
-rtl::OUString RootAccess::getImplementationName() throw (css::uno::RuntimeException)
-{
- assert(thisIs(IS_ANY));
osl::MutexGuard g(*lock_);
checkLocalizedPropertyAccess();
- return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "configmgr.RootAccess" ) );
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("configmgr.RootAccess"));
}
}
diff --git a/configmgr/source/rootaccess.hxx b/configmgr/source/rootaccess.hxx
index 1290519b5d99..3b9ab7bbfa94 100644
--- a/configmgr/source/rootaccess.hxx
+++ b/configmgr/source/rootaccess.hxx
@@ -88,9 +88,25 @@ public:
void setAlive(bool b);
-protected:
+ virtual void SAL_CALL addChangesListener(
+ com::sun::star::uno::Reference< com::sun::star::util::XChangesListener >
+ const & aListener)
+ throw (com::sun::star::uno::RuntimeException);
- virtual rtl::OUString SAL_CALL getImplementationName()
+ virtual void SAL_CALL removeChangesListener(
+ com::sun::star::uno::Reference< com::sun::star::util::XChangesListener >
+ const & aListener)
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL commitChanges()
+ throw (
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasPendingChanges()
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::util::ChangesSet SAL_CALL getPendingChanges()
throw (com::sun::star::uno::RuntimeException);
private:
@@ -124,25 +140,7 @@ private:
com::sun::star::uno::Type const & aType)
throw (com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL addChangesListener(
- com::sun::star::uno::Reference< com::sun::star::util::XChangesListener >
- const & aListener)
- throw (com::sun::star::uno::RuntimeException);
-
- virtual void SAL_CALL removeChangesListener(
- com::sun::star::uno::Reference< com::sun::star::util::XChangesListener >
- const & aListener)
- throw (com::sun::star::uno::RuntimeException);
-
- virtual void SAL_CALL commitChanges()
- throw (
- com::sun::star::lang::WrappedTargetException,
- com::sun::star::uno::RuntimeException);
-
- virtual sal_Bool SAL_CALL hasPendingChanges()
- throw (com::sun::star::uno::RuntimeException);
-
- virtual com::sun::star::util::ChangesSet SAL_CALL getPendingChanges()
+ virtual rtl::OUString SAL_CALL getImplementationName()
throw (com::sun::star::uno::RuntimeException);
typedef
diff --git a/configmgr/source/rootnode.cxx b/configmgr/source/rootnode.cxx
new file mode 100644
index 000000000000..3188ea1228dc
--- /dev/null
+++ b/configmgr/source/rootnode.cxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
+ * (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#include "sal/config.h"
+
+#include "rtl/ref.hxx"
+
+#include "data.hxx"
+#include "node.hxx"
+#include "nodemap.hxx"
+#include "rootnode.hxx"
+
+namespace configmgr {
+
+RootNode::RootNode(NodeMap const & members):
+ Node(Data::NO_LAYER), members_(members)
+{}
+
+RootNode::~RootNode() {}
+
+Node::Kind RootNode::kind() const {
+ return KIND_ROOT;
+}
+
+rtl::Reference< Node > RootNode::clone(bool) const {
+ assert(false); // this cannot happen
+ return rtl::Reference< Node >();
+}
+
+NodeMap const & RootNode::getMembers() const {
+ return members_;
+}
+
+NodeMap * RootNode::getMemberMap() {
+ return 0;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/configmgr/source/rootnode.hxx b/configmgr/source/rootnode.hxx
new file mode 100644
index 000000000000..97244e470737
--- /dev/null
+++ b/configmgr/source/rootnode.hxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
+ * (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef INCLUDED_CONFIGMGR_SOURCE_ROOTNODE_HXX
+#define INCLUDED_CONFIGMGR_SOURCE_ROOTNODE_HXX
+
+#include "sal/config.h"
+
+#include "rtl/ref.hxx"
+
+#include "node.hxx"
+#include "nodemap.hxx"
+
+namespace configmgr {
+
+class RootNode: public Node {
+public:
+ RootNode(NodeMap const & members);
+
+private:
+ RootNode(RootNode const & other);
+
+ virtual ~RootNode();
+
+ virtual Kind kind() const;
+
+ virtual rtl::Reference< Node > clone(bool keepTemplateName) const;
+
+ virtual NodeMap const & getMembers() const;
+ virtual NodeMap * getMemberMap();
+
+ NodeMap const & members_;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/configmgr/source/services.cxx b/configmgr/source/services.cxx
index 365c50c0e064..5c58eb719ac2 100644
--- a/configmgr/source/services.cxx
+++ b/configmgr/source/services.cxx
@@ -42,6 +42,8 @@
#include "configurationprovider.hxx"
#include "configurationregistry.hxx"
#include "defaultprovider.hxx"
+#include "readonlyaccess.hxx"
+#include "readwriteaccess.hxx"
#include "update.hxx"
namespace {
@@ -68,6 +70,14 @@ static cppu::ImplementationEntry const services[] = {
&configmgr::configuration_registry::getImplementationName,
&configmgr::configuration_registry::getSupportedServiceNames,
&cppu::createSingleComponentFactory, 0, 0 },
+ { &configmgr::read_only_access::create,
+ &configmgr::read_only_access::getImplementationName,
+ &configmgr::read_only_access::getSupportedServiceNames,
+ &cppu::createSingleComponentFactory, 0, 0 },
+ { &configmgr::read_write_access::create,
+ &configmgr::read_write_access::getImplementationName,
+ &configmgr::read_write_access::getSupportedServiceNames,
+ &cppu::createSingleComponentFactory, 0, 0 },
{ &configmgr::update::create, &configmgr::update::getImplementationName,
&configmgr::update::getSupportedServiceNames,
&cppu::createSingleComponentFactory, 0, 0 },
diff --git a/configmgr/source/setnode.cxx b/configmgr/source/setnode.cxx
index e2a8b2c888eb..214885fff66f 100644
--- a/configmgr/source/setnode.cxx
+++ b/configmgr/source/setnode.cxx
@@ -73,8 +73,8 @@ rtl::Reference< Node > SetNode::clone(bool keepTemplateName) const {
return new SetNode(*this, keepTemplateName);
}
-NodeMap & SetNode::getMembers() {
- return members_;
+NodeMap * SetNode::getMemberMap() {
+ return &members_;
}
rtl::OUString SetNode::getTemplateName() const {
diff --git a/configmgr/source/setnode.hxx b/configmgr/source/setnode.hxx
index 00bcab2a55a1..59bd2587a5ab 100644
--- a/configmgr/source/setnode.hxx
+++ b/configmgr/source/setnode.hxx
@@ -49,7 +49,7 @@ public:
virtual rtl::Reference< Node > clone(bool keepTemplateName) const;
- virtual NodeMap & getMembers();
+ virtual NodeMap * getMemberMap();
virtual rtl::OUString getTemplateName() const;
diff --git a/configmgr/source/valueparser.cxx b/configmgr/source/valueparser.cxx
index a98aae6ccf03..105d9ef323b8 100644
--- a/configmgr/source/valueparser.cxx
+++ b/configmgr/source/valueparser.cxx
@@ -413,10 +413,11 @@ bool ValueParser::endElement() {
break;
case Node::KIND_LOCALIZED_PROPERTY:
{
- NodeMap::iterator i(
- node_->getMembers().find(localizedName_));
- if (i == node_->getMembers().end()) {
- node_->getMembers().insert(
+ NodeMap * members = node_->getMemberMap();
+ assert(members != 0);
+ NodeMap::iterator i(members->find(localizedName_));
+ if (i == members->end()) {
+ members->insert(
NodeMap::value_type(
localizedName_,
new LocalizedValueNode(layer_, value)));
diff --git a/configmgr/source/writemodfile.cxx b/configmgr/source/writemodfile.cxx
index 1bae01ab88c5..eb896fffbf34 100644
--- a/configmgr/source/writemodfile.cxx
+++ b/configmgr/source/writemodfile.cxx
@@ -395,7 +395,7 @@ void writeNode(
writeData(handle, RTL_CONSTASCII_STRINGPARAM("<prop oor:name=\""));
writeAttributeValue(handle, name);
writeData(handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\">"));
- for (NodeMap::iterator i(node->getMembers().begin());
+ for (NodeMap::const_iterator i(node->getMembers().begin());
i != node->getMembers().end(); ++i)
{
writeNode(components, handle, node, i->first, i->second);
@@ -443,13 +443,16 @@ void writeNode(
handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"replace"));
}
writeData(handle, RTL_CONSTASCII_STRINGPARAM("\">"));
- for (NodeMap::iterator i(node->getMembers().begin());
+ for (NodeMap::const_iterator i(node->getMembers().begin());
i != node->getMembers().end(); ++i)
{
writeNode(components, handle, node, i->first, i->second);
}
writeData(handle, RTL_CONSTASCII_STRINGPARAM("</node>"));
break;
+ case Node::KIND_ROOT:
+ assert(false); // this cannot happen
+ break;
}
}
diff --git a/configmgr/source/xcsparser.cxx b/configmgr/source/xcsparser.cxx
index 95d994327b85..66f3f2891713 100644
--- a/configmgr/source/xcsparser.cxx
+++ b/configmgr/source/xcsparser.cxx
@@ -79,16 +79,18 @@ void merge(
case Node::KIND_LOCALIZED_VALUE:
break; //TODO: merge certain parts?
case Node::KIND_GROUP:
- for (NodeMap::iterator i2(update->getMembers().begin());
+ for (NodeMap::const_iterator i2(update->getMembers().begin());
i2 != update->getMembers().end(); ++i2)
{
- NodeMap::iterator i1(original->getMembers().find(i2->first));
- if (i1 == original->getMembers().end()) {
+ NodeMap * members = original->getMemberMap();
+ assert(members != 0);
+ NodeMap::iterator i1(members->find(i2->first));
+ if (i1 == members->end()) {
if (i2->second->kind() == Node::KIND_PROPERTY &&
dynamic_cast< GroupNode * >(
original.get())->isExtensible())
{
- original->getMembers().insert(*i2);
+ members->insert(*i2);
}
} else if (i2->second->kind() == i1->second->kind()) {
merge(i1->second, i2->second);
@@ -96,15 +98,17 @@ void merge(
}
break;
case Node::KIND_SET:
- for (NodeMap::iterator i2(update->getMembers().begin());
+ for (NodeMap::const_iterator i2(update->getMembers().begin());
i2 != update->getMembers().end(); ++i2)
{
- NodeMap::iterator i1(original->getMembers().find(i2->first));
- if (i1 == original->getMembers().end()) {
+ NodeMap * members = original->getMemberMap();
+ assert(members != 0);
+ NodeMap::iterator i1(members->find(i2->first));
+ if (i1 == members->end()) {
if (dynamic_cast< SetNode * >(original.get())->
isValidTemplate(i2->second->getTemplateName()))
{
- original->getMembers().insert(*i2);
+ members->insert(*i2);
}
} else if (i2->second->kind() == i1->second->kind() &&
(i2->second->getTemplateName() ==
@@ -114,6 +118,9 @@ void merge(
}
}
break;
+ case Node::KIND_ROOT:
+ assert(false); // this cannot happen
+ break;
}
}
}
@@ -308,15 +315,20 @@ void XcsParser::endElement(xmlreader::XmlReader const & reader) {
RTL_CONSTASCII_USTRINGPARAM("this cannot happen")),
css::uno::Reference< css::uno::XInterface >());
}
- } else if (!elements_.top().node->getMembers().insert(
- NodeMap::value_type(top.name, top.node)).second)
- {
- throw css::uno::RuntimeException(
- (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("duplicate ")) +
- top.name +
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
- reader.getUrl()),
- css::uno::Reference< css::uno::XInterface >());
+ } else {
+ NodeMap * members = elements_.top().node->getMemberMap();
+ assert(members != 0);
+ if (!members->insert(NodeMap::value_type(top.name, top.node)).
+ second)
+ {
+ throw css::uno::RuntimeException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("duplicate ")) +
+ top.name +
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
+ reader.getUrl()),
+ css::uno::Reference< css::uno::XInterface >());
+ }
}
}
} else {
diff --git a/configmgr/source/xcuparser.cxx b/configmgr/source/xcuparser.cxx
index 764cf8ce36f3..b05fe0e7e3c5 100644
--- a/configmgr/source/xcuparser.cxx
+++ b/configmgr/source/xcuparser.cxx
@@ -218,6 +218,9 @@ bool XcuParser::startElement(
css::uno::Reference< css::uno::XInterface >());
}
break;
+ case Node::KIND_ROOT:
+ assert(false); // this cannot happen
+ break;
}
}
return true;
@@ -239,7 +242,9 @@ void XcuParser::endElement(xmlreader::XmlReader const &) {
state_.pop();
if (insert.is()) {
assert(!state_.empty() && state_.top().node.is());
- state_.top().node->getMembers()[name] = insert;
+ NodeMap * members = state_.top().node->getMemberMap();
+ assert(members != 0);
+ (*members)[name] = insert;
}
if (pop && !path_.empty()) {
path_.pop_back();
@@ -590,9 +595,10 @@ void XcuParser::handleLocpropValue(
return;
}
}
- NodeMap::iterator i(locprop->getMembers().find(name));
- if (i != locprop->getMembers().end() &&
- i->second->getLayer() > valueParser_.getLayer())
+ NodeMap * members = locprop->getMemberMap();
+ assert(members != 0);
+ NodeMap::iterator i(members->find(name));
+ if (i != members->end() && i->second->getLayer() > valueParser_.getLayer())
{
state_.push(State(true)); // ignored
return;
@@ -610,8 +616,8 @@ void XcuParser::handleLocpropValue(
{
bool pop = false;
if (nil) {
- if (i == locprop->getMembers().end()) {
- locprop->getMembers()[name] = new LocalizedValueNode(
+ if (i == members->end()) {
+ (*members)[name] = new LocalizedValueNode(
valueParser_.getLayer(), css::uno::Any());
} else {
dynamic_cast< LocalizedValueNode * >(
@@ -635,8 +641,8 @@ void XcuParser::handleLocpropValue(
case OPERATION_REMOVE:
//TODO: only allow if parent.op == OPERATION_FUSE
//TODO: disallow removing when e.g. lang=""?
- if (i != locprop->getMembers().end()) {
- locprop->getMembers().erase(i);
+ if (i != members->end()) {
+ members->erase(i);
}
state_.push(State(true));
recordModification(false);
@@ -702,8 +708,10 @@ void XcuParser::handleGroupProp(
return;
}
}
- NodeMap::iterator i(group->getMembers().find(name));
- if (i == group->getMembers().end()) {
+ NodeMap * members = group->getMemberMap();
+ assert(members != 0);
+ NodeMap::iterator i(members->find(name));
+ if (i == members->end()) {
handleUnknownGroupProp(reader, group, name, type, op, finalized);
} else {
switch (i->second->kind()) {
@@ -814,7 +822,9 @@ void XcuParser::handlePlainGroupProp(
reader.getUrl()),
css::uno::Reference< css::uno::XInterface >());
}
- group->getMembers().erase(propertyIndex);
+ NodeMap * members = group->getMemberMap();
+ assert(members != 0);
+ members->erase(propertyIndex);
state_.push(State(true)); // ignore children
recordModification(false);
break;
@@ -1035,8 +1045,10 @@ void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) {
}
int finalizedLayer = finalized ? valueParser_.getLayer() : Data::NO_LAYER;
int mandatoryLayer = mandatory ? valueParser_.getLayer() : Data::NO_LAYER;
- NodeMap::iterator i(set->getMembers().find(name));
- if (i != set->getMembers().end()) {
+ NodeMap * members = set->getMemberMap();
+ assert(members != 0);
+ NodeMap::iterator i(members->find(name));
+ if (i != members->end()) {
finalizedLayer = std::min(finalizedLayer, i->second->getFinalized());
i->second->setFinalized(finalizedLayer);
mandatoryLayer = std::min(mandatoryLayer, i->second->getMandatory());
@@ -1048,7 +1060,7 @@ void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) {
}
switch (op) {
case OPERATION_MODIFY:
- if (i == set->getMembers().end()) {
+ if (i == members->end()) {
SAL_WARN(
"configmgr",
"ignoring modify of unknown set member node \"" << name
@@ -1071,11 +1083,11 @@ void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) {
member->setFinalized(finalizedLayer);
member->setMandatory(mandatoryLayer);
state_.push(State(member, name, false));
- recordModification(i == set->getMembers().end());
+ recordModification(i == members->end());
}
break;
case OPERATION_FUSE:
- if (i == set->getMembers().end()) {
+ if (i == members->end()) {
if (state_.top().locked || finalizedLayer < valueParser_.getLayer())
{
state_.push(State(true)); // ignored
@@ -1102,13 +1114,13 @@ void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) {
// forget about user-layer removals that no longer remove anything
// (so that paired additions/removals in the user layer do not grow
// registrymodifications.xcu unbounded):
- bool known = i != set->getMembers().end();
+ bool known = i != members->end();
if (known && !state_.top().locked &&
finalizedLayer >= valueParser_.getLayer() &&
(mandatoryLayer == Data::NO_LAYER ||
mandatoryLayer > valueParser_.getLayer()))
{
- set->getMembers().erase(i);
+ members->erase(i);
}
state_.push(State(true));
if (known) {