summaryrefslogtreecommitdiff
path: root/configmgr/source/xcuparser.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'configmgr/source/xcuparser.cxx')
-rw-r--r--configmgr/source/xcuparser.cxx305
1 files changed, 170 insertions, 135 deletions
diff --git a/configmgr/source/xcuparser.cxx b/configmgr/source/xcuparser.cxx
index 220168c627..77b0f747f3 100644
--- a/configmgr/source/xcuparser.cxx
+++ b/configmgr/source/xcuparser.cxx
@@ -49,6 +49,7 @@
#include "modifications.hxx"
#include "node.hxx"
#include "nodemap.hxx"
+#include "partial.hxx"
#include "path.hxx"
#include "propertynode.hxx"
#include "setnode.hxx"
@@ -65,14 +66,15 @@ namespace css = com::sun::star;
}
-XcuParser::XcuParser(int layer, Data * data, Modifications * modifications):
- valueParser_(layer), data_(data), modifications_(modifications)
-{
- if (layer == Data::NO_LAYER) {
- OSL_ASSERT(modifications_ == 0);
- modifications_ = &data_->modifications;
- }
-}
+XcuParser::XcuParser(
+ int layer, Data & data, Partial const * partial,
+ Modifications * broadcastModifications):
+ valueParser_(layer), data_(data),
+ partial_(partial), broadcastModifications_(broadcastModifications),
+ recordModifications_(layer == Data::NO_LAYER),
+ trackPath_(
+ partial_ != 0 || broadcastModifications_ != 0 || recordModifications_)
+{}
XcuParser::~XcuParser() {}
@@ -105,7 +107,7 @@ bool XcuParser::startElement(
css::uno::Reference< css::uno::XInterface >());
}
} else if (state_.top().ignore) {
- state_.push(state_.top());
+ state_.push(State(false));
} else if (!state_.top().node.is()) {
if (ns == XmlReader::NAMESPACE_NONE &&
name.equals(RTL_CONSTASCII_STRINGPARAM("item")))
@@ -209,12 +211,12 @@ bool XcuParser::startElement(
return true;
}
-void XcuParser::endElement(XmlReader const & reader) {
- if (valueParser_.endElement(reader)) {
+void XcuParser::endElement(XmlReader const &) {
+ if (valueParser_.endElement()) {
return;
}
OSL_ASSERT(!state_.empty());
- bool ignore = state_.top().ignore;
+ bool pop = state_.top().pop;
rtl::Reference< Node > insert;
rtl::OUString name;
if (state_.top().insert) {
@@ -227,10 +229,10 @@ void XcuParser::endElement(XmlReader const & reader) {
OSL_ASSERT(!state_.empty() && state_.top().node.is());
state_.top().node->getMembers()[name] = insert;
}
- if (!ignore && !modificationPath_.empty()) {
- modificationPath_.pop_back();
+ if (pop && !path_.empty()) {
+ path_.pop_back();
// </item> will pop less than <item> pushed, but that is harmless,
- // as the next <item> will reset modificationPath_
+ // as the next <item> will reset path_
}
}
@@ -328,16 +330,27 @@ void XcuParser::handleComponentData(XmlReader & reader) {
}
componentName_ = xmldata::convertFromUtf8(
Span(buf.getStr(), buf.getLength()));
+ if (trackPath_) {
+ OSL_ASSERT(path_.empty());
+ path_.push_back(componentName_);
+ if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
+ {
+ state_.push(State(true)); // ignored
+ return;
+ }
+ }
rtl::Reference< Node > node(
Data::findNode(
- valueParser_.getLayer(), data_->components, componentName_));
+ valueParser_.getLayer(), data_.components, componentName_));
if (!node.is()) {
- throw css::uno::RuntimeException(
- (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown component ")) +
- componentName_ +
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
- reader.getUrl()),
- css::uno::Reference< css::uno::XInterface >());
+ OSL_TRACE(
+ "configmgr unknown component %s in %s",
+ rtl::OUStringToOString(
+ componentName_, RTL_TEXTENCODING_UTF8).getStr(),
+ rtl::OUStringToOString(
+ reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
+ state_.push(State(true)); // ignored
+ return;
}
switch (op) {
case OPERATION_MODIFY:
@@ -356,10 +369,6 @@ void XcuParser::handleComponentData(XmlReader & reader) {
node->getFinalized());
node->setFinalized(finalizedLayer);
state_.push(State(node, finalizedLayer < valueParser_.getLayer()));
- if (modifications_ != 0) {
- OSL_ASSERT(modificationPath_.empty());
- modificationPath_.push_back(componentName_);
- }
}
void XcuParser::handleItem(XmlReader & reader) {
@@ -386,27 +395,43 @@ void XcuParser::handleItem(XmlReader & reader) {
rtl::OUString path(xmldata::convertFromUtf8(attrPath));
int finalizedLayer;
rtl::Reference< Node > node(
- data_->resolvePathRepresentation(
- path, &modificationPath_, &finalizedLayer));
+ data_.resolvePathRepresentation(path, &path_, &finalizedLayer));
if (!node.is()) {
- //TODO: Within Components::parseModificationLayer (but only there) it
- // can rightly happen that data is read that does not match a schema
- // (that no schema exists, or that the schema specifies a different
- // type), namely if the schema was brought along by an extension that
- // has been removed or replaced; instead of taking care of that at all
- // the relevant places, as a hack, only "top-level" <item>s (that only
- // appear in modification layer data) with unknown path are filtered out
- // here.
OSL_TRACE(
- "configmgr unknown <item path=\"%s\">",
- rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr());
- state_.push(State()); // ignored
+ "configmgr unknown item %s in %s",
+ rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr(),
+ rtl::OUStringToOString(
+ reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
+ state_.push(State(true)); // ignored
return;
}
- OSL_ASSERT(!modificationPath_.empty());
- componentName_ = modificationPath_.front();
- if (modifications_ == 0) {
- modificationPath_.clear();
+ OSL_ASSERT(!path_.empty());
+ componentName_ = path_.front();
+ if (trackPath_) {
+ if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
+ {
+ state_.push(State(true)); // ignored
+ return;
+ }
+ } else {
+ path_.clear();
+ }
+ switch (node->kind()) {
+ case Node::KIND_PROPERTY:
+ case Node::KIND_LOCALIZED_VALUE:
+ OSL_TRACE(
+ "configmgr item of bad type %s in %s",
+ rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr(),
+ rtl::OUStringToOString(
+ reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
+ state_.push(State(true)); // ignored
+ return;
+ case Node::KIND_LOCALIZED_PROPERTY:
+ valueParser_.type_ = dynamic_cast< LocalizedPropertyNode * >(
+ node.get())->getStaticType();
+ break;
+ default:
+ break;
}
state_.push(State(node, finalizedLayer < valueParser_.getLayer()));
}
@@ -483,13 +508,13 @@ void XcuParser::handlePropValue(XmlReader & reader, PropertyNode * prop) {
css::uno::Reference< css::uno::XInterface >());
}
prop->setValue(valueParser_.getLayer(), css::uno::Any());
- state_.push(State());
+ state_.push(State(false));
} else if (external.getLength() == 0) {
valueParser_.separator_ = separator;
valueParser_.start(prop);
} else {
prop->setExternal(valueParser_.getLayer(), external);
- state_.push(State());
+ state_.push(State(false));
}
}
@@ -546,11 +571,20 @@ void XcuParser::handleLocpropValue(
op = parseOperation(reader.getAttributeValue(true));
}
}
+ if (trackPath_) {
+ path_.push_back(name);
+ if (partial_ != 0 &&
+ partial_->contains(path_) != Partial::CONTAINS_NODE)
+ {
+ state_.push(State(true)); // ignored
+ return;
+ }
+ }
NodeMap::iterator i(locprop->getMembers().find(name));
if (i != locprop->getMembers().end() &&
i->second->getLayer() > valueParser_.getLayer())
{
- state_.push(State()); // ignored
+ state_.push(State(true)); // ignored
return;
}
if (nil && !locprop->isNillable()) {
@@ -563,23 +597,29 @@ void XcuParser::handleLocpropValue(
}
switch (op) {
case OPERATION_FUSE:
- if (nil) {
- if (i == locprop->getMembers().end()) {
- locprop->getMembers()[name] = new LocalizedValueNode(
- valueParser_.getLayer(), css::uno::Any());
+ {
+ bool pop = false;
+ if (nil) {
+ if (i == locprop->getMembers().end()) {
+ locprop->getMembers()[name] = new LocalizedValueNode(
+ valueParser_.getLayer(), css::uno::Any());
+ } else {
+ dynamic_cast< LocalizedValueNode * >(
+ i->second.get())->setValue(
+ valueParser_.getLayer(), css::uno::Any());
+ }
+ state_.push(State(true));
} else {
- dynamic_cast< LocalizedValueNode * >(i->second.get())->setValue(
- valueParser_.getLayer(), css::uno::Any());
+ valueParser_.separator_ = separator;
+ valueParser_.start(locprop, name);
+ pop = true;
+ }
+ if (trackPath_) {
+ recordModification();
+ if (pop) {
+ path_.pop_back();
+ }
}
- state_.push(State());
- } else {
- valueParser_.separator_ = separator;
- valueParser_.start(locprop, name);
- }
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- modifications_->add(modificationPath_);
- modificationPath_.pop_back();
}
break;
case OPERATION_REMOVE:
@@ -588,12 +628,8 @@ void XcuParser::handleLocpropValue(
if (i != locprop->getMembers().end()) {
locprop->getMembers().erase(i);
}
- state_.push(State());
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- modifications_->add(modificationPath_);
- modificationPath_.pop_back();
- }
+ state_.push(State(true));
+ recordModification();
break;
default:
throw css::uno::RuntimeException(
@@ -643,6 +679,17 @@ void XcuParser::handleGroupProp(XmlReader & reader, GroupNode * group) {
reader.getUrl()),
css::uno::Reference< css::uno::XInterface >());
}
+ if (trackPath_) {
+ path_.push_back(name);
+ //TODO: This ignores locprop values for which specific include paths
+ // exist (i.e., for which contains(locprop path) = CONTAINS_SUBNODES):
+ if (partial_ != 0 &&
+ partial_->contains(path_) != Partial::CONTAINS_NODE)
+ {
+ state_.push(State(true)); // ignored
+ return;
+ }
+ }
NodeMap::iterator i(group->getMembers().find(name));
if (i == group->getMembers().end()) {
handleUnknownGroupProp(reader, group, name, type, op, finalized);
@@ -672,17 +719,10 @@ void XcuParser::handleUnknownGroupProp(
XmlReader const & reader, GroupNode * group, rtl::OUString const & name,
Type type, Operation operation, bool finalized)
{
- if (!group->isExtensible()) {
- throw css::uno::RuntimeException(
- (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown prop ")) +
- name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
- reader.getUrl()),
- css::uno::Reference< css::uno::XInterface >());
- }
switch (operation) {
case OPERATION_REPLACE:
case OPERATION_FUSE:
- {
+ if (group->isExtensible()) {
if (type == TYPE_ERROR) {
throw css::uno::RuntimeException(
(rtl::OUString(
@@ -701,17 +741,17 @@ void XcuParser::handleUnknownGroupProp(
prop->setFinalized(valueParser_.getLayer());
}
state_.push(State(prop, name, state_.top().locked));
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- modifications_->add(modificationPath_);
- }
+ recordModification();
+ break;
}
- break;
+ // fall through
default:
OSL_TRACE(
- "ignoring modify or remove of unknown (presumably extension)"
- " property");
- state_.push(State());
+ "configmgr unknown property %s in %s",
+ rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(),
+ rtl::OUStringToOString(
+ reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
+ state_.push(State(true)); // ignored
break;
}
}
@@ -724,7 +764,7 @@ void XcuParser::handlePlainGroupProp(
PropertyNode * property = dynamic_cast< PropertyNode * >(
propertyIndex->second.get());
if (property->getLayer() > valueParser_.getLayer()) {
- state_.push(State()); // ignored
+ state_.push(State(true)); // ignored
return;
}
int finalizedLayer = std::min(
@@ -751,10 +791,7 @@ void XcuParser::handlePlainGroupProp(
property,
(state_.top().locked ||
finalizedLayer < valueParser_.getLayer())));
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- modifications_->add(modificationPath_);
- }
+ recordModification();
break;
case OPERATION_REMOVE:
if (!property->isExtension()) {
@@ -767,12 +804,8 @@ void XcuParser::handlePlainGroupProp(
css::uno::Reference< css::uno::XInterface >());
}
group->getMembers().erase(propertyIndex);
- state_.push(State()); // ignore children
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- modifications_->add(modificationPath_);
- modificationPath_.pop_back();
- }
+ state_.push(State(true)); // ignore children
+ recordModification();
break;
}
}
@@ -782,7 +815,7 @@ void XcuParser::handleLocalizedGroupProp(
rtl::OUString const & name, Type type, Operation operation, bool finalized)
{
if (property->getLayer() > valueParser_.getLayer()) {
- state_.push(State()); // ignored
+ state_.push(State(true)); // ignored
return;
}
int finalizedLayer = std::min(
@@ -808,9 +841,6 @@ void XcuParser::handleLocalizedGroupProp(
property,
(state_.top().locked ||
finalizedLayer < valueParser_.getLayer())));
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- }
break;
case OPERATION_REPLACE:
{
@@ -824,10 +854,7 @@ void XcuParser::handleLocalizedGroupProp(
replacement, name,
(state_.top().locked ||
finalizedLayer < valueParser_.getLayer())));
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- modifications_->add(modificationPath_);
- }
+ recordModification();
}
break;
case OPERATION_REMOVE:
@@ -876,14 +903,24 @@ void XcuParser::handleGroupNode(
reader.getUrl()),
css::uno::Reference< css::uno::XInterface >());
}
+ if (trackPath_) {
+ path_.push_back(name);
+ if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
+ {
+ state_.push(State(true)); // ignored
+ return;
+ }
+ }
rtl::Reference< Node > child(
Data::findNode(valueParser_.getLayer(), group->getMembers(), name));
if (!child.is()) {
- throw css::uno::RuntimeException(
- (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown node ")) +
- name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
- reader.getUrl()),
- css::uno::Reference< css::uno::XInterface >());
+ OSL_TRACE(
+ "configmgr unknown node %s in %s",
+ rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(),
+ rtl::OUStringToOString(
+ reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
+ state_.push(State(true)); // ignored
+ return;
}
if (op != OPERATION_MODIFY && op != OPERATION_FUSE) {
throw css::uno::RuntimeException(
@@ -901,9 +938,6 @@ void XcuParser::handleGroupNode(
State(
child,
state_.top().locked || finalizedLayer < valueParser_.getLayer()));
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- }
}
void XcuParser::handleSetNode(XmlReader & reader, SetNode * set) {
@@ -958,6 +992,14 @@ void XcuParser::handleSetNode(XmlReader & reader, SetNode * set) {
reader.getUrl()),
css::uno::Reference< css::uno::XInterface >());
}
+ if (trackPath_) {
+ path_.push_back(name);
+ if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
+ {
+ state_.push(State(true)); // ignored
+ return;
+ }
+ }
rtl::OUString templateName(
xmldata::parseTemplateReference(
component, hasNodeType, nodeType, &set->getDefaultTemplateName()));
@@ -972,7 +1014,7 @@ void XcuParser::handleSetNode(XmlReader & reader, SetNode * set) {
css::uno::Reference< css::uno::XInterface >());
}
rtl::Reference< Node > tmpl(
- data_->getTemplate(valueParser_.getLayer(), templateName));
+ data_.getTemplate(valueParser_.getLayer(), templateName));
if (!tmpl.is()) {
throw css::uno::RuntimeException(
(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("set member node ")) +
@@ -993,7 +1035,7 @@ void XcuParser::handleSetNode(XmlReader & reader, SetNode * set) {
mandatoryLayer = std::min(mandatoryLayer, i->second->getMandatory());
i->second->setMandatory(mandatoryLayer);
if (i->second->getLayer() > valueParser_.getLayer()) {
- state_.push(State()); // ignored
+ state_.push(State(true)); // ignored
return;
}
}
@@ -1001,48 +1043,39 @@ void XcuParser::handleSetNode(XmlReader & reader, SetNode * set) {
case OPERATION_MODIFY:
if (i == set->getMembers().end()) {
OSL_TRACE("ignoring modify of unknown set member node");
- state_.push(State());
+ state_.push(State(true)); // ignored
} else {
state_.push(
State(
i->second,
(state_.top().locked ||
finalizedLayer < valueParser_.getLayer())));
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- }
}
break;
case OPERATION_REPLACE:
if (state_.top().locked || finalizedLayer < valueParser_.getLayer()) {
- state_.push(State()); // ignored
+ state_.push(State(true)); // ignored
} else {
rtl::Reference< Node > member(tmpl->clone());
member->setLayer(valueParser_.getLayer());
member->setFinalized(finalizedLayer);
member->setMandatory(mandatoryLayer);
state_.push(State(member, name, false));
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- modifications_->add(modificationPath_);
- }
+ recordModification();
}
break;
case OPERATION_FUSE:
if (i == set->getMembers().end()) {
if (state_.top().locked || finalizedLayer < valueParser_.getLayer())
{
- state_.push(State()); // ignored
+ state_.push(State(true)); // ignored
} else {
rtl::Reference< Node > member(tmpl->clone());
member->setLayer(valueParser_.getLayer());
member->setFinalized(finalizedLayer);
member->setMandatory(mandatoryLayer);
state_.push(State(member, name, false));
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- modifications_->add(modificationPath_);
- }
+ recordModification();
}
} else {
state_.push(
@@ -1050,9 +1083,6 @@ void XcuParser::handleSetNode(XmlReader & reader, SetNode * set) {
i->second,
(state_.top().locked ||
finalizedLayer < valueParser_.getLayer())));
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- }
}
break;
case OPERATION_REMOVE:
@@ -1064,14 +1094,19 @@ void XcuParser::handleSetNode(XmlReader & reader, SetNode * set) {
{
set->getMembers().erase(i);
}
- state_.push(State());
- if (modifications_ != 0) {
- modificationPath_.push_back(name);
- modifications_->add(modificationPath_);
- modificationPath_.pop_back();
- }
+ state_.push(State(true));
+ recordModification();
break;
}
}
+void XcuParser::recordModification() {
+ if (broadcastModifications_ != 0) {
+ broadcastModifications_->add(path_);
+ }
+ if (recordModifications_) {
+ data_.modifications.add(path_);
+ }
+}
+
}