summaryrefslogtreecommitdiff
path: root/configmgr/source/xcsparser.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'configmgr/source/xcsparser.cxx')
-rw-r--r--configmgr/source/xcsparser.cxx93
1 files changed, 82 insertions, 11 deletions
diff --git a/configmgr/source/xcsparser.cxx b/configmgr/source/xcsparser.cxx
index 15141844a2..12e64ebbe1 100644
--- a/configmgr/source/xcsparser.cxx
+++ b/configmgr/source/xcsparser.cxx
@@ -60,9 +60,66 @@ namespace {
namespace css = com::sun::star;
+// Conservatively merge a template or component (and its recursive parts) into
+// an existing instance:
+void merge(
+ rtl::Reference< Node > const & original,
+ rtl::Reference< Node > const & update)
+{
+ OSL_ASSERT(
+ original.is() && update.is() && original->kind() == update->kind() &&
+ update->getFinalized() == Data::NO_LAYER);
+ if (update->getLayer() >= original->getLayer() &&
+ update->getLayer() <= original->getFinalized())
+ {
+ switch (original->kind()) {
+ case Node::KIND_PROPERTY:
+ case Node::KIND_LOCALIZED_PROPERTY:
+ case Node::KIND_LOCALIZED_VALUE:
+ break; //TODO: merge certain parts?
+ case Node::KIND_GROUP:
+ if (dynamic_cast< GroupNode * >(original.get())->isExtensible()) {
+ for (NodeMap::iterator i2(update->getMembers().begin());
+ i2 != update->getMembers().end(); ++i2)
+ {
+ NodeMap::iterator i1(
+ original->getMembers().find(i2->first));
+ if (i1 == original->getMembers().end()) {
+ if (i2->second->kind() == Node::KIND_PROPERTY) {
+ original->getMembers().insert(*i2);
+ }
+ } else if (i2->second->kind() == i1->second->kind()) {
+ merge(i1->second, i2->second);
+ }
+ }
+ }
+ break;
+ case Node::KIND_SET:
+ for (NodeMap::iterator i2(update->getMembers().begin());
+ i2 != update->getMembers().end(); ++i2)
+ {
+ NodeMap::iterator i1(original->getMembers().find(i2->first));
+ if (i1 == original->getMembers().end()) {
+ if (dynamic_cast< SetNode * >(original.get())->
+ isValidTemplate(i2->second->getTemplateName()))
+ {
+ original->getMembers().insert(*i2);
+ }
+ } else if (i2->second->kind() == i1->second->kind() &&
+ (i2->second->getTemplateName() ==
+ i1->second->getTemplateName()))
+ {
+ merge(i1->second, i2->second);
+ }
+ }
+ break;
+ }
+ }
}
-XcsParser::XcsParser(int layer, Data * data):
+}
+
+XcsParser::XcsParser(int layer, Data & data):
valueParser_(layer), data_(data), state_(STATE_START)
{}
@@ -209,7 +266,7 @@ bool XcsParser::startElement(
}
void XcsParser::endElement(XmlReader const & reader) {
- if (valueParser_.endElement(reader)) {
+ if (valueParser_.endElement()) {
return;
}
if (ignoring_ > 0) {
@@ -218,15 +275,30 @@ void XcsParser::endElement(XmlReader const & reader) {
Element top(elements_.top());
elements_.pop();
if (top.node.is()) {
- NodeMap * map;
if (elements_.empty()) {
switch (state_) {
case STATE_TEMPLATES:
- map = &data_->templates;
+ {
+ NodeMap::iterator i(data_.templates.find(top.name));
+ if (i == data_.templates.end()) {
+ data_.templates.insert(
+ NodeMap::value_type(top.name, top.node));
+ } else {
+ merge(i->second, top.node);
+ }
+ }
break;
case STATE_COMPONENT:
- map = &data_->components;
- state_ = STATE_COMPONENT_DONE;
+ {
+ NodeMap::iterator i(data_.components.find(top.name));
+ if (i == data_.components.end()) {
+ data_.components.insert(
+ NodeMap::value_type(top.name, top.node));
+ } else {
+ merge(i->second, top.node);
+ }
+ state_ = STATE_COMPONENT_DONE;
+ }
break;
default:
OSL_ASSERT(false);
@@ -235,10 +307,9 @@ void XcsParser::endElement(XmlReader const & reader) {
RTL_CONSTASCII_USTRINGPARAM("this cannot happen")),
css::uno::Reference< css::uno::XInterface >());
}
- } else {
- map = &elements_.top().node->getMembers();
- }
- if (!map->insert(NodeMap::value_type(top.name, top.node)).second) {
+ } 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 +
@@ -372,7 +443,7 @@ void XcsParser::handleNodeRef(XmlReader & reader) {
css::uno::Reference< css::uno::XInterface >());
}
rtl::Reference< Node > tmpl(
- data_->getTemplate(
+ data_.getTemplate(
valueParser_.getLayer(),
xmldata::parseTemplateReference(
component, hasNodeType, nodeType, 0)));