2009-09-08 14:59:07 +02:00
|
|
|
/*************************************************************************
|
2010-02-25 15:59:15 +01:00
|
|
|
*
|
2009-09-08 14:59:07 +02:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
2010-02-25 15:59:15 +01:00
|
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
2009-09-08 14:59:07 +02:00
|
|
|
*
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
|
|
*
|
|
|
|
* This file is part of OpenOffice.org.
|
|
|
|
*
|
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
* only, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Lesser General Public License version 3 for more details
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
* for a copy of the LGPLv3 License.
|
2010-02-25 15:59:15 +01:00
|
|
|
*
|
2009-09-08 14:59:07 +02:00
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#include "precompiled_configmgr.hxx"
|
|
|
|
#include "sal/config.h"
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
#include "com/sun/star/uno/Any.hxx"
|
|
|
|
#include "com/sun/star/uno/Reference.hxx"
|
|
|
|
#include "com/sun/star/uno/RuntimeException.hpp"
|
|
|
|
#include "com/sun/star/uno/XInterface.hpp"
|
|
|
|
#include "osl/diagnose.h"
|
|
|
|
#include "rtl/ref.hxx"
|
|
|
|
#include "rtl/strbuf.hxx"
|
|
|
|
#include "rtl/string.h"
|
2009-11-10 10:30:50 +01:00
|
|
|
#include "rtl/string.hxx"
|
2009-09-08 14:59:07 +02:00
|
|
|
#include "rtl/ustring.h"
|
|
|
|
#include "rtl/ustring.hxx"
|
|
|
|
|
|
|
|
#include "data.hxx"
|
|
|
|
#include "localizedpropertynode.hxx"
|
|
|
|
#include "localizedvaluenode.hxx"
|
|
|
|
#include "groupnode.hxx"
|
2009-09-23 17:48:27 +02:00
|
|
|
#include "modifications.hxx"
|
2009-09-08 14:59:07 +02:00
|
|
|
#include "node.hxx"
|
|
|
|
#include "nodemap.hxx"
|
2009-09-22 17:15:42 +02:00
|
|
|
#include "path.hxx"
|
2009-09-08 14:59:07 +02:00
|
|
|
#include "propertynode.hxx"
|
|
|
|
#include "setnode.hxx"
|
|
|
|
#include "span.hxx"
|
|
|
|
#include "xcuparser.hxx"
|
|
|
|
#include "xmldata.hxx"
|
|
|
|
#include "xmlreader.hxx"
|
|
|
|
|
|
|
|
namespace configmgr {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
namespace css = com::sun::star;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-12-02 14:57:12 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
|
|
|
|
XcuParser::~XcuParser() {}
|
|
|
|
|
|
|
|
XmlReader::Text XcuParser::getTextMode() {
|
|
|
|
return valueParser_.getTextMode();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XcuParser::startElement(
|
2009-09-08 16:25:16 +02:00
|
|
|
XmlReader & reader, XmlReader::Namespace ns, Span const & name)
|
2009-09-08 14:59:07 +02:00
|
|
|
{
|
|
|
|
if (valueParser_.startElement(reader, ns, name)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (state_.empty()) {
|
|
|
|
if (ns == XmlReader::NAMESPACE_OOR &&
|
|
|
|
name.equals(RTL_CONSTASCII_STRINGPARAM("component-data")))
|
|
|
|
{
|
|
|
|
handleComponentData(reader);
|
|
|
|
} else if (ns == XmlReader::NAMESPACE_OOR &&
|
|
|
|
name.equals(RTL_CONSTASCII_STRINGPARAM("items")))
|
|
|
|
{
|
2009-10-14 10:12:41 +02:00
|
|
|
state_.push(State(rtl::Reference< Node >(), false));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("bad root element <")) +
|
|
|
|
xmldata::convertFromUtf8(name) +
|
|
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
} else if (state_.top().ignore) {
|
|
|
|
state_.push(state_.top());
|
|
|
|
} else if (!state_.top().node.is()) {
|
|
|
|
if (ns == XmlReader::NAMESPACE_NONE &&
|
|
|
|
name.equals(RTL_CONSTASCII_STRINGPARAM("item")))
|
|
|
|
{
|
|
|
|
handleItem(reader);
|
|
|
|
} else {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("bad items node member <")) +
|
|
|
|
xmldata::convertFromUtf8(name) +
|
|
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (state_.top().node->kind()) {
|
|
|
|
case Node::KIND_PROPERTY:
|
|
|
|
if (ns == XmlReader::NAMESPACE_NONE &&
|
|
|
|
name.equals(RTL_CONSTASCII_STRINGPARAM("value")))
|
|
|
|
{
|
|
|
|
handlePropValue(
|
|
|
|
reader,
|
|
|
|
dynamic_cast< PropertyNode * >(state_.top().node.get()));
|
|
|
|
} else {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"bad property node member <")) +
|
|
|
|
xmldata::convertFromUtf8(name) +
|
|
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Node::KIND_LOCALIZED_PROPERTY:
|
|
|
|
if (ns == XmlReader::NAMESPACE_NONE &&
|
|
|
|
name.equals(RTL_CONSTASCII_STRINGPARAM("value")))
|
|
|
|
{
|
|
|
|
handleLocpropValue(
|
|
|
|
reader,
|
|
|
|
dynamic_cast< LocalizedPropertyNode * >(
|
|
|
|
state_.top().node.get()));
|
|
|
|
} else {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"bad localized property node member <")) +
|
|
|
|
xmldata::convertFromUtf8(name) +
|
|
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Node::KIND_LOCALIZED_VALUE:
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad member <")) +
|
|
|
|
xmldata::convertFromUtf8(name) +
|
|
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
case Node::KIND_GROUP:
|
|
|
|
if (ns == XmlReader::NAMESPACE_NONE &&
|
|
|
|
name.equals(RTL_CONSTASCII_STRINGPARAM("prop")))
|
|
|
|
{
|
|
|
|
handleGroupProp(
|
|
|
|
reader,
|
|
|
|
dynamic_cast< GroupNode * >(state_.top().node.get()));
|
|
|
|
} else if (ns == XmlReader::NAMESPACE_NONE &&
|
|
|
|
name.equals(RTL_CONSTASCII_STRINGPARAM("node")))
|
|
|
|
{
|
|
|
|
handleGroupNode(reader, state_.top().node);
|
|
|
|
} else {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"bad group node member <")) +
|
|
|
|
xmldata::convertFromUtf8(name) +
|
|
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Node::KIND_SET:
|
|
|
|
if (ns == XmlReader::NAMESPACE_NONE &&
|
|
|
|
name.equals(RTL_CONSTASCII_STRINGPARAM("node")))
|
|
|
|
{
|
|
|
|
handleSetNode(
|
|
|
|
reader, dynamic_cast< SetNode * >(state_.top().node.get()));
|
|
|
|
} else {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("bad set node member <")) +
|
|
|
|
xmldata::convertFromUtf8(name) +
|
|
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-03-24 16:04:08 +01:00
|
|
|
void XcuParser::endElement(XmlReader const &) {
|
|
|
|
if (valueParser_.endElement()) {
|
2009-09-08 14:59:07 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
OSL_ASSERT(!state_.empty());
|
2009-10-14 10:12:41 +02:00
|
|
|
bool ignore = state_.top().ignore;
|
2009-09-08 14:59:07 +02:00
|
|
|
rtl::Reference< Node > insert;
|
|
|
|
rtl::OUString name;
|
|
|
|
if (state_.top().insert) {
|
|
|
|
insert = state_.top().node;
|
|
|
|
OSL_ASSERT(insert.is());
|
|
|
|
name = state_.top().name;
|
|
|
|
}
|
|
|
|
state_.pop();
|
|
|
|
if (insert.is()) {
|
|
|
|
OSL_ASSERT(!state_.empty() && state_.top().node.is());
|
|
|
|
state_.top().node->getMembers()[name] = insert;
|
|
|
|
}
|
2009-10-14 10:12:41 +02:00
|
|
|
if (!ignore && !modificationPath_.empty()) {
|
|
|
|
modificationPath_.pop_back();
|
|
|
|
// </item> will pop less than <item> pushed, but that is harmless,
|
|
|
|
// as the next <item> will reset modificationPath_
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void XcuParser::characters(Span const & text) {
|
|
|
|
valueParser_.characters(text);
|
|
|
|
}
|
|
|
|
|
2009-11-10 10:30:50 +01:00
|
|
|
XcuParser::Operation XcuParser::parseOperation(Span const & text) {
|
|
|
|
OSL_ASSERT(text.is());
|
|
|
|
if (text.equals(RTL_CONSTASCII_STRINGPARAM("modify"))) {
|
2009-09-08 14:59:07 +02:00
|
|
|
return OPERATION_MODIFY;
|
2009-11-10 10:30:50 +01:00
|
|
|
}
|
|
|
|
if (text.equals(RTL_CONSTASCII_STRINGPARAM("replace"))) {
|
2009-09-08 14:59:07 +02:00
|
|
|
return OPERATION_REPLACE;
|
2009-11-10 10:30:50 +01:00
|
|
|
}
|
|
|
|
if (text.equals(RTL_CONSTASCII_STRINGPARAM("fuse"))) {
|
2009-09-08 14:59:07 +02:00
|
|
|
return OPERATION_FUSE;
|
2009-11-10 10:30:50 +01:00
|
|
|
}
|
|
|
|
if (text.equals(RTL_CONSTASCII_STRINGPARAM("remove"))) {
|
2009-09-08 14:59:07 +02:00
|
|
|
return OPERATION_REMOVE;
|
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("invalid op ")) +
|
|
|
|
xmldata::convertFromUtf8(text)),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
|
2009-09-08 16:25:16 +02:00
|
|
|
void XcuParser::handleComponentData(XmlReader & reader) {
|
2009-11-10 10:30:50 +01:00
|
|
|
rtl::OStringBuffer buf;
|
|
|
|
buf.append('.');
|
|
|
|
bool hasPackage = false;
|
|
|
|
bool hasName = false;
|
|
|
|
Operation op = OPERATION_MODIFY;
|
|
|
|
bool finalized = false;
|
2009-09-08 14:59:07 +02:00
|
|
|
for (;;) {
|
|
|
|
XmlReader::Namespace attrNs;
|
|
|
|
Span attrLn;
|
2009-09-08 16:25:16 +02:00
|
|
|
if (!reader.nextAttribute(&attrNs, &attrLn)) {
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("package")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
if (hasPackage) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"multiple component-update package attributes"
|
|
|
|
" in ")) +
|
|
|
|
reader.getUrl()),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
hasPackage = true;
|
|
|
|
Span s(reader.getAttributeValue(false));
|
|
|
|
buf.insert(0, s.begin, s.length);
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
if (hasName) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"multiple component-update name attributes in ")) +
|
|
|
|
reader.getUrl()),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
hasName = true;
|
|
|
|
Span s(reader.getAttributeValue(false));
|
|
|
|
buf.append(s.begin, s.length);
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
op = parseOperation(reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
if (!hasPackage) {
|
2009-09-08 14:59:07 +02:00
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"no component-data package attribute in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
if (!hasName) {
|
2009-09-08 14:59:07 +02:00
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"no component-data name attribute in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
componentName_ = xmldata::convertFromUtf8(
|
|
|
|
Span(buf.getStr(), buf.getLength()));
|
|
|
|
rtl::Reference< Node > node(
|
|
|
|
Data::findNode(
|
|
|
|
valueParser_.getLayer(), data_->components, componentName_));
|
|
|
|
if (!node.is()) {
|
2010-03-18 11:17:44 +01:00
|
|
|
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()); // ignored
|
|
|
|
return;
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
switch (op) {
|
2009-09-08 14:59:07 +02:00
|
|
|
case OPERATION_MODIFY:
|
|
|
|
case OPERATION_FUSE:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"invalid operation on root node in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
int finalizedLayer = std::min(
|
2009-11-10 10:30:50 +01:00
|
|
|
finalized ? valueParser_.getLayer() : Data::NO_LAYER,
|
2009-09-08 14:59:07 +02:00
|
|
|
node->getFinalized());
|
|
|
|
node->setFinalized(finalizedLayer);
|
2009-10-14 10:12:41 +02:00
|
|
|
state_.push(State(node, finalizedLayer < valueParser_.getLayer()));
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
OSL_ASSERT(modificationPath_.empty());
|
|
|
|
modificationPath_.push_back(componentName_);
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
|
2009-09-08 16:25:16 +02:00
|
|
|
void XcuParser::handleItem(XmlReader & reader) {
|
2009-09-08 14:59:07 +02:00
|
|
|
Span attrPath;
|
|
|
|
for (;;) {
|
|
|
|
XmlReader::Namespace attrNs;
|
|
|
|
Span attrLn;
|
2009-09-08 16:25:16 +02:00
|
|
|
if (!reader.nextAttribute(&attrNs, &attrLn)) {
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("path")))
|
|
|
|
{
|
2009-09-08 16:25:16 +02:00
|
|
|
attrPath = reader.getAttributeValue(false);
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!attrPath.is()) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("missing path attribute in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2010-01-22 13:45:34 +01:00
|
|
|
rtl::OUString path(xmldata::convertFromUtf8(attrPath));
|
2009-09-08 14:59:07 +02:00
|
|
|
int finalizedLayer;
|
|
|
|
rtl::Reference< Node > node(
|
2009-09-22 17:15:42 +02:00
|
|
|
data_->resolvePathRepresentation(
|
2010-01-22 13:45:34 +01:00
|
|
|
path, &modificationPath_, &finalizedLayer));
|
2009-09-08 14:59:07 +02:00
|
|
|
if (!node.is()) {
|
2010-01-22 13:45:34 +01:00
|
|
|
OSL_TRACE(
|
2010-03-18 11:17:44 +01:00
|
|
|
"configmgr unknown item %s in %s",
|
|
|
|
rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr(),
|
|
|
|
rtl::OUStringToOString(
|
|
|
|
reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
|
2010-01-22 13:45:34 +01:00
|
|
|
state_.push(State()); // ignored
|
|
|
|
return;
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
2010-03-22 16:04:16 +01:00
|
|
|
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()); // ignored
|
|
|
|
return;
|
|
|
|
case Node::KIND_LOCALIZED_PROPERTY:
|
|
|
|
valueParser_.type_ = dynamic_cast< LocalizedPropertyNode * >(
|
|
|
|
node.get())->getStaticType();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-10-14 10:12:41 +02:00
|
|
|
OSL_ASSERT(!modificationPath_.empty());
|
|
|
|
componentName_ = modificationPath_.front();
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ == 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.clear();
|
|
|
|
}
|
|
|
|
state_.push(State(node, finalizedLayer < valueParser_.getLayer()));
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
|
2009-09-08 16:25:16 +02:00
|
|
|
void XcuParser::handlePropValue(XmlReader & reader, PropertyNode * prop) {
|
2009-11-10 10:30:50 +01:00
|
|
|
bool nil = false;
|
|
|
|
rtl::OString separator;
|
|
|
|
rtl::OUString external;
|
2009-09-08 14:59:07 +02:00
|
|
|
for (;;) {
|
|
|
|
XmlReader::Namespace attrNs;
|
|
|
|
Span attrLn;
|
2009-09-08 16:25:16 +02:00
|
|
|
if (!reader.nextAttribute(&attrNs, &attrLn)) {
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (attrNs == XmlReader::NAMESPACE_XSI &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nil")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
nil = xmldata::parseBoolean(reader.getAttributeValue(true));
|
2009-11-11 13:51:17 +01:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
|
|
|
|
{
|
|
|
|
Type type = xmldata::parseType(
|
|
|
|
reader, reader.getAttributeValue(true));
|
|
|
|
if (valueParser_.type_ != TYPE_ANY && type != valueParser_.type_) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("invalid value type in ")) +
|
|
|
|
reader.getUrl()),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
valueParser_.type_ = type;
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
Span s(reader.getAttributeValue(false));
|
|
|
|
if (s.length == 0) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"bad oor:separator attribute in ")) +
|
|
|
|
reader.getUrl()),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
separator = rtl::OString(s.begin, s.length);
|
2009-09-25 14:47:45 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("external")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
external = xmldata::convertFromUtf8(reader.getAttributeValue(true));
|
|
|
|
if (external.getLength() == 0) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"bad oor:external attribute value in ")) +
|
|
|
|
reader.getUrl()),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
if (nil) {
|
2009-09-08 14:59:07 +02:00
|
|
|
if (!prop->isNillable()) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"xsi:nil attribute for non-nillable prop in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
if (external.getLength() != 0) {
|
2009-09-25 14:47:45 +02:00
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"xsi:nil and oor:external attributes for prop in ")) +
|
|
|
|
reader.getUrl()),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
prop->setValue(valueParser_.getLayer(), css::uno::Any());
|
|
|
|
state_.push(State());
|
2009-11-10 10:30:50 +01:00
|
|
|
} else if (external.getLength() == 0) {
|
|
|
|
valueParser_.separator_ = separator;
|
|
|
|
valueParser_.start(prop);
|
|
|
|
} else {
|
2009-10-01 16:48:00 +02:00
|
|
|
prop->setExternal(valueParser_.getLayer(), external);
|
2009-09-25 14:47:45 +02:00
|
|
|
state_.push(State());
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void XcuParser::handleLocpropValue(
|
2009-09-08 16:25:16 +02:00
|
|
|
XmlReader & reader, LocalizedPropertyNode * locprop)
|
2009-09-08 14:59:07 +02:00
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
rtl::OUString name;
|
|
|
|
bool nil = false;
|
|
|
|
rtl::OString separator;
|
|
|
|
Operation op = OPERATION_FUSE;
|
2009-09-08 14:59:07 +02:00
|
|
|
for (;;) {
|
|
|
|
XmlReader::Namespace attrNs;
|
|
|
|
Span attrLn;
|
2009-09-08 16:25:16 +02:00
|
|
|
if (!reader.nextAttribute(&attrNs, &attrLn)) {
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (attrNs == XmlReader::NAMESPACE_XML &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("lang")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
name = xmldata::convertFromUtf8(reader.getAttributeValue(false));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_XSI &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nil")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
nil = xmldata::parseBoolean(reader.getAttributeValue(true));
|
2009-11-11 13:51:17 +01:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
|
|
|
|
{
|
|
|
|
Type type = xmldata::parseType(
|
|
|
|
reader, reader.getAttributeValue(true));
|
|
|
|
if (valueParser_.type_ != TYPE_ANY && type != valueParser_.type_) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("invalid value type in ")) +
|
|
|
|
reader.getUrl()),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
valueParser_.type_ = type;
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
Span s(reader.getAttributeValue(false));
|
|
|
|
if (s.length == 0) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"bad oor:separator attribute in ")) +
|
|
|
|
reader.getUrl()),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
separator = rtl::OString(s.begin, s.length);
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
op = parseOperation(reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
NodeMap::iterator i(locprop->getMembers().find(name));
|
|
|
|
if (i != locprop->getMembers().end() &&
|
|
|
|
i->second->getLayer() > valueParser_.getLayer())
|
|
|
|
{
|
|
|
|
state_.push(State()); // ignored
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (nil && !locprop->isNillable()) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"xsi:nil attribute for non-nillable prop in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
switch (op) {
|
2009-10-14 10:12:41 +02:00
|
|
|
case OPERATION_FUSE:
|
2009-09-08 14:59:07 +02:00
|
|
|
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());
|
|
|
|
} else {
|
2009-11-10 10:30:50 +01:00
|
|
|
valueParser_.separator_ = separator;
|
2009-09-08 14:59:07 +02:00
|
|
|
valueParser_.start(locprop, name);
|
|
|
|
}
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
2009-12-02 14:57:12 +01:00
|
|
|
modifications_->add(modificationPath_);
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.pop_back();
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
case OPERATION_REMOVE:
|
|
|
|
//TODO: only allow if parent.op == OPERATION_FUSE
|
|
|
|
//TODO: disallow removing when e.g. lang=""?
|
|
|
|
if (i != locprop->getMembers().end()) {
|
2009-09-16 17:01:38 +02:00
|
|
|
locprop->getMembers().erase(i);
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
state_.push(State());
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
2009-12-02 14:57:12 +01:00
|
|
|
modifications_->add(modificationPath_);
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.pop_back();
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"bad op attribute for value element in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-08 16:25:16 +02:00
|
|
|
void XcuParser::handleGroupProp(XmlReader & reader, GroupNode * group) {
|
2009-11-10 10:30:50 +01:00
|
|
|
bool hasName = false;
|
|
|
|
rtl::OUString name;
|
|
|
|
Type type = TYPE_ERROR;
|
|
|
|
Operation op = OPERATION_MODIFY;
|
|
|
|
bool finalized = false;
|
2009-09-08 14:59:07 +02:00
|
|
|
for (;;) {
|
|
|
|
XmlReader::Namespace attrNs;
|
|
|
|
Span attrLn;
|
2009-09-08 16:25:16 +02:00
|
|
|
if (!reader.nextAttribute(&attrNs, &attrLn)) {
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
hasName = true;
|
|
|
|
name = xmldata::convertFromUtf8(reader.getAttributeValue(false));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
type = xmldata::parseType(reader, reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
op = parseOperation(reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
if (!hasName) {
|
2009-09-08 14:59:07 +02:00
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("no prop name attribute in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
NodeMap::iterator i(group->getMembers().find(name));
|
|
|
|
if (i == group->getMembers().end()) {
|
|
|
|
handleUnknownGroupProp(reader, group, name, type, op, finalized);
|
|
|
|
} else {
|
|
|
|
switch (i->second->kind()) {
|
|
|
|
case Node::KIND_PROPERTY:
|
2009-09-16 17:01:38 +02:00
|
|
|
handlePlainGroupProp(reader, group, i, name, type, op, finalized);
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
case Node::KIND_LOCALIZED_PROPERTY:
|
|
|
|
handleLocalizedGroupProp(
|
|
|
|
reader,
|
|
|
|
dynamic_cast< LocalizedPropertyNode * >(i->second.get()), name,
|
|
|
|
type, op, finalized);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("inappropriate prop ")) +
|
|
|
|
name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void XcuParser::handleUnknownGroupProp(
|
2009-09-08 16:25:16 +02:00
|
|
|
XmlReader const & reader, GroupNode * group, rtl::OUString const & name,
|
2009-09-08 14:59:07 +02:00
|
|
|
Type type, Operation operation, bool finalized)
|
|
|
|
{
|
|
|
|
switch (operation) {
|
|
|
|
case OPERATION_REPLACE:
|
|
|
|
case OPERATION_FUSE:
|
2010-03-18 11:17:44 +01:00
|
|
|
if (group->isExtensible()) {
|
2009-09-08 14:59:07 +02:00
|
|
|
if (type == TYPE_ERROR) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"missing type attribute for prop ")) +
|
|
|
|
name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
valueParser_.type_ = type;
|
|
|
|
rtl::Reference< Node > prop(
|
|
|
|
new PropertyNode(
|
|
|
|
valueParser_.getLayer(), TYPE_ANY, true, css::uno::Any(),
|
|
|
|
true));
|
|
|
|
if (finalized) {
|
|
|
|
prop->setFinalized(valueParser_.getLayer());
|
|
|
|
}
|
2009-10-14 10:12:41 +02:00
|
|
|
state_.push(State(prop, name, state_.top().locked));
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
2009-12-02 14:57:12 +01:00
|
|
|
modifications_->add(modificationPath_);
|
2009-10-14 10:12:41 +02:00
|
|
|
}
|
2010-03-18 11:17:44 +01:00
|
|
|
break;
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
2010-03-18 11:17:44 +01:00
|
|
|
// fall through
|
2009-10-29 11:44:00 +01:00
|
|
|
default:
|
|
|
|
OSL_TRACE(
|
2010-03-18 11:17:44 +01:00
|
|
|
"configmgr unknown property %s in %s",
|
|
|
|
rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(),
|
|
|
|
rtl::OUStringToOString(
|
|
|
|
reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
|
2009-09-08 14:59:07 +02:00
|
|
|
state_.push(State());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void XcuParser::handlePlainGroupProp(
|
2009-09-16 17:01:38 +02:00
|
|
|
XmlReader const & reader, GroupNode * group,
|
|
|
|
NodeMap::iterator const & propertyIndex, rtl::OUString const & name,
|
|
|
|
Type type, Operation operation, bool finalized)
|
2009-09-08 14:59:07 +02:00
|
|
|
{
|
2009-09-16 17:01:38 +02:00
|
|
|
PropertyNode * property = dynamic_cast< PropertyNode * >(
|
|
|
|
propertyIndex->second.get());
|
2009-09-08 14:59:07 +02:00
|
|
|
if (property->getLayer() > valueParser_.getLayer()) {
|
|
|
|
state_.push(State()); // ignored
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int finalizedLayer = std::min(
|
|
|
|
finalized ? valueParser_.getLayer() : Data::NO_LAYER,
|
|
|
|
property->getFinalized());
|
|
|
|
property->setFinalized(finalizedLayer);
|
2009-11-11 13:51:17 +01:00
|
|
|
if (type != TYPE_ERROR && property->getStaticType() != TYPE_ANY &&
|
|
|
|
type != property->getStaticType())
|
2009-09-08 14:59:07 +02:00
|
|
|
{
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("invalid type for prop ")) +
|
|
|
|
name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-11-11 13:51:17 +01:00
|
|
|
valueParser_.type_ = type == TYPE_ERROR ? property->getStaticType() : type;
|
2009-09-08 14:59:07 +02:00
|
|
|
switch (operation) {
|
|
|
|
case OPERATION_MODIFY:
|
|
|
|
case OPERATION_REPLACE:
|
|
|
|
case OPERATION_FUSE:
|
|
|
|
state_.push(
|
|
|
|
State(
|
|
|
|
property,
|
2009-10-14 10:12:41 +02:00
|
|
|
(state_.top().locked ||
|
|
|
|
finalizedLayer < valueParser_.getLayer())));
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
2009-12-02 14:57:12 +01:00
|
|
|
modifications_->add(modificationPath_);
|
2009-10-14 10:12:41 +02:00
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
case OPERATION_REMOVE:
|
|
|
|
if (!property->isExtension()) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"invalid remove of non-extension prop ")) +
|
|
|
|
name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-09-16 17:01:38 +02:00
|
|
|
group->getMembers().erase(propertyIndex);
|
2009-09-08 14:59:07 +02:00
|
|
|
state_.push(State()); // ignore children
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
2009-12-02 14:57:12 +01:00
|
|
|
modifications_->add(modificationPath_);
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.pop_back();
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void XcuParser::handleLocalizedGroupProp(
|
2009-09-08 16:25:16 +02:00
|
|
|
XmlReader const & reader, LocalizedPropertyNode * property,
|
2009-09-08 14:59:07 +02:00
|
|
|
rtl::OUString const & name, Type type, Operation operation, bool finalized)
|
|
|
|
{
|
|
|
|
if (property->getLayer() > valueParser_.getLayer()) {
|
|
|
|
state_.push(State()); // ignored
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int finalizedLayer = std::min(
|
|
|
|
finalized ? valueParser_.getLayer() : Data::NO_LAYER,
|
|
|
|
property->getFinalized());
|
|
|
|
property->setFinalized(finalizedLayer);
|
2009-11-11 13:51:17 +01:00
|
|
|
if (type != TYPE_ERROR && property->getStaticType() != TYPE_ANY &&
|
|
|
|
type != property->getStaticType())
|
2009-09-08 14:59:07 +02:00
|
|
|
{
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("invalid type for prop ")) +
|
|
|
|
name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-11-11 13:51:17 +01:00
|
|
|
valueParser_.type_ = type == TYPE_ERROR ? property->getStaticType() : type;
|
2009-09-08 14:59:07 +02:00
|
|
|
switch (operation) {
|
|
|
|
case OPERATION_MODIFY:
|
|
|
|
case OPERATION_FUSE:
|
|
|
|
state_.push(
|
|
|
|
State(
|
|
|
|
property,
|
2009-10-14 10:12:41 +02:00
|
|
|
(state_.top().locked ||
|
|
|
|
finalizedLayer < valueParser_.getLayer())));
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
case OPERATION_REPLACE:
|
|
|
|
{
|
|
|
|
rtl::Reference< Node > replacement(
|
|
|
|
new LocalizedPropertyNode(
|
2009-11-11 13:51:17 +01:00
|
|
|
valueParser_.getLayer(), property->getStaticType(),
|
2009-09-08 14:59:07 +02:00
|
|
|
property->isNillable()));
|
|
|
|
replacement->setFinalized(property->getFinalized());
|
|
|
|
state_.push(
|
|
|
|
State(
|
|
|
|
replacement, name,
|
|
|
|
(state_.top().locked ||
|
2009-10-14 10:12:41 +02:00
|
|
|
finalizedLayer < valueParser_.getLayer())));
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
2009-12-02 14:57:12 +01:00
|
|
|
modifications_->add(modificationPath_);
|
2009-10-14 10:12:41 +02:00
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OPERATION_REMOVE:
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"invalid remove of non-extension prop ")) +
|
|
|
|
name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void XcuParser::handleGroupNode(
|
2009-09-08 16:25:16 +02:00
|
|
|
XmlReader & reader, rtl::Reference< Node > const & group)
|
2009-09-08 14:59:07 +02:00
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
bool hasName = false;
|
|
|
|
rtl::OUString name;
|
|
|
|
Operation op = OPERATION_MODIFY;
|
|
|
|
bool finalized = false;
|
2009-09-08 14:59:07 +02:00
|
|
|
for (;;) {
|
|
|
|
XmlReader::Namespace attrNs;
|
|
|
|
Span attrLn;
|
2009-09-08 16:25:16 +02:00
|
|
|
if (!reader.nextAttribute(&attrNs, &attrLn)) {
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
hasName = true;
|
|
|
|
name = xmldata::convertFromUtf8(reader.getAttributeValue(false));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
op = parseOperation(reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
if (!hasName) {
|
2009-09-08 14:59:07 +02:00
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("no node name attribute in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-10-14 10:12:41 +02:00
|
|
|
rtl::Reference< Node > child(
|
2009-09-08 14:59:07 +02:00
|
|
|
Data::findNode(valueParser_.getLayer(), group->getMembers(), name));
|
2009-10-14 10:12:41 +02:00
|
|
|
if (!child.is()) {
|
2010-03-18 11:17:44 +01:00
|
|
|
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()); // ignored
|
|
|
|
return;
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
2009-10-14 10:12:41 +02:00
|
|
|
if (op != OPERATION_MODIFY && op != OPERATION_FUSE) {
|
2009-09-08 14:59:07 +02:00
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"invalid operation on group node in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
int finalizedLayer = std::min(
|
2009-11-10 10:30:50 +01:00
|
|
|
finalized ? valueParser_.getLayer() : Data::NO_LAYER,
|
2009-10-14 10:12:41 +02:00
|
|
|
child->getFinalized());
|
|
|
|
child->setFinalized(finalizedLayer);
|
2009-09-08 14:59:07 +02:00
|
|
|
state_.push(
|
|
|
|
State(
|
2009-10-14 10:12:41 +02:00
|
|
|
child,
|
|
|
|
state_.top().locked || finalizedLayer < valueParser_.getLayer()));
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
|
2009-09-08 16:25:16 +02:00
|
|
|
void XcuParser::handleSetNode(XmlReader & reader, SetNode * set) {
|
2009-11-10 10:30:50 +01:00
|
|
|
bool hasName = false;
|
|
|
|
rtl::OUString name;
|
|
|
|
rtl::OUString component(componentName_);
|
|
|
|
bool hasNodeType = false;
|
|
|
|
rtl::OUString nodeType;
|
|
|
|
Operation op = OPERATION_MODIFY;
|
|
|
|
bool finalized = false;
|
|
|
|
bool mandatory = false;
|
2009-09-08 14:59:07 +02:00
|
|
|
for (;;) {
|
|
|
|
XmlReader::Namespace attrNs;
|
|
|
|
Span attrLn;
|
2009-09-08 16:25:16 +02:00
|
|
|
if (!reader.nextAttribute(&attrNs, &attrLn)) {
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
hasName = true;
|
|
|
|
name = xmldata::convertFromUtf8(reader.getAttributeValue(false));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
component = xmldata::convertFromUtf8(
|
|
|
|
reader.getAttributeValue(false));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
hasNodeType = true;
|
|
|
|
nodeType = xmldata::convertFromUtf8(
|
|
|
|
reader.getAttributeValue(false));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
op = parseOperation(reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
} else if (attrNs == XmlReader::NAMESPACE_OOR &&
|
|
|
|
attrLn.equals(RTL_CONSTASCII_STRINGPARAM("mandatory")))
|
|
|
|
{
|
2009-11-10 10:30:50 +01:00
|
|
|
mandatory = xmldata::parseBoolean(reader.getAttributeValue(true));
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
if (!hasName) {
|
2009-09-08 14:59:07 +02:00
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("no node name attribute in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
rtl::OUString templateName(
|
|
|
|
xmldata::parseTemplateReference(
|
2009-11-10 10:30:50 +01:00
|
|
|
component, hasNodeType, nodeType, &set->getDefaultTemplateName()));
|
2009-09-08 14:59:07 +02:00
|
|
|
if (!set->isValidTemplate(templateName)) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("set member node ")) +
|
|
|
|
name +
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(" references invalid template ")) +
|
|
|
|
templateName + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
rtl::Reference< Node > tmpl(
|
|
|
|
data_->getTemplate(valueParser_.getLayer(), templateName));
|
|
|
|
if (!tmpl.is()) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("set member node ")) +
|
|
|
|
name +
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
" references undefined template ")) +
|
|
|
|
templateName + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
reader.getUrl()),
|
2009-09-08 14:59:07 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-11-10 10:30:50 +01:00
|
|
|
int finalizedLayer = finalized ? valueParser_.getLayer() : Data::NO_LAYER;
|
|
|
|
int mandatoryLayer = mandatory ? valueParser_.getLayer() : Data::NO_LAYER;
|
2009-09-08 14:59:07 +02:00
|
|
|
NodeMap::iterator i(set->getMembers().find(name));
|
|
|
|
if (i != set->getMembers().end()) {
|
|
|
|
finalizedLayer = std::min(finalizedLayer, i->second->getFinalized());
|
|
|
|
i->second->setFinalized(finalizedLayer);
|
|
|
|
mandatoryLayer = std::min(mandatoryLayer, i->second->getMandatory());
|
|
|
|
i->second->setMandatory(mandatoryLayer);
|
|
|
|
if (i->second->getLayer() > valueParser_.getLayer()) {
|
|
|
|
state_.push(State()); // ignored
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (op) {
|
|
|
|
case OPERATION_MODIFY:
|
2009-09-16 17:01:38 +02:00
|
|
|
if (i == set->getMembers().end()) {
|
2009-10-29 11:44:00 +01:00
|
|
|
OSL_TRACE("ignoring modify of unknown set member node");
|
|
|
|
state_.push(State());
|
|
|
|
} else {
|
|
|
|
state_.push(
|
|
|
|
State(
|
|
|
|
i->second,
|
|
|
|
(state_.top().locked ||
|
|
|
|
finalizedLayer < valueParser_.getLayer())));
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-29 11:44:00 +01:00
|
|
|
modificationPath_.push_back(name);
|
|
|
|
}
|
2009-10-14 10:12:41 +02:00
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
case OPERATION_REPLACE:
|
|
|
|
if (state_.top().locked || finalizedLayer < valueParser_.getLayer()) {
|
|
|
|
state_.push(State()); // ignored
|
|
|
|
} else {
|
|
|
|
rtl::Reference< Node > member(tmpl->clone());
|
|
|
|
member->setLayer(valueParser_.getLayer());
|
|
|
|
member->setFinalized(finalizedLayer);
|
|
|
|
member->setMandatory(mandatoryLayer);
|
2009-10-14 10:12:41 +02:00
|
|
|
state_.push(State(member, name, false));
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
2009-12-02 14:57:12 +01:00
|
|
|
modifications_->add(modificationPath_);
|
2009-10-14 10:12:41 +02:00
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OPERATION_FUSE:
|
2009-09-16 17:01:38 +02:00
|
|
|
if (i == set->getMembers().end()) {
|
2009-09-08 14:59:07 +02:00
|
|
|
if (state_.top().locked || finalizedLayer < valueParser_.getLayer())
|
|
|
|
{
|
|
|
|
state_.push(State()); // ignored
|
|
|
|
} else {
|
|
|
|
rtl::Reference< Node > member(tmpl->clone());
|
|
|
|
member->setLayer(valueParser_.getLayer());
|
|
|
|
member->setFinalized(finalizedLayer);
|
|
|
|
member->setMandatory(mandatoryLayer);
|
2009-10-14 10:12:41 +02:00
|
|
|
state_.push(State(member, name, false));
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
2009-12-02 14:57:12 +01:00
|
|
|
modifications_->add(modificationPath_);
|
2009-10-14 10:12:41 +02:00
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
state_.push(
|
|
|
|
State(
|
|
|
|
i->second,
|
|
|
|
(state_.top().locked ||
|
2009-10-14 10:12:41 +02:00
|
|
|
finalizedLayer < valueParser_.getLayer())));
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OPERATION_REMOVE:
|
|
|
|
// Ignore removal of unknown members, members finalized in a lower
|
|
|
|
// layer, and members made mandatory in this or a lower layer:
|
|
|
|
if (i != set->getMembers().end() && !state_.top().locked &&
|
|
|
|
finalizedLayer >= valueParser_.getLayer() &&
|
|
|
|
mandatoryLayer > valueParser_.getLayer())
|
|
|
|
{
|
2009-09-16 17:01:38 +02:00
|
|
|
set->getMembers().erase(i);
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
state_.push(State());
|
2009-12-02 14:57:12 +01:00
|
|
|
if (modifications_ != 0) {
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.push_back(name);
|
2009-12-02 14:57:12 +01:00
|
|
|
modifications_->add(modificationPath_);
|
2009-10-14 10:12:41 +02:00
|
|
|
modificationPath_.pop_back();
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|