1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski #include "precompiled_configmgr.hxx"
25*b1cdbd2cSJim Jagielski #include "sal/config.h"
26*b1cdbd2cSJim Jagielski
27*b1cdbd2cSJim Jagielski #include <algorithm>
28*b1cdbd2cSJim Jagielski
29*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/Any.hxx"
30*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/Reference.hxx"
31*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/RuntimeException.hpp"
32*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/XInterface.hpp"
33*b1cdbd2cSJim Jagielski #include "osl/diagnose.h"
34*b1cdbd2cSJim Jagielski #include "rtl/ref.hxx"
35*b1cdbd2cSJim Jagielski #include "rtl/strbuf.hxx"
36*b1cdbd2cSJim Jagielski #include "rtl/string.h"
37*b1cdbd2cSJim Jagielski #include "rtl/string.hxx"
38*b1cdbd2cSJim Jagielski #include "rtl/ustring.h"
39*b1cdbd2cSJim Jagielski #include "rtl/ustring.hxx"
40*b1cdbd2cSJim Jagielski #include "xmlreader/span.hxx"
41*b1cdbd2cSJim Jagielski #include "xmlreader/xmlreader.hxx"
42*b1cdbd2cSJim Jagielski
43*b1cdbd2cSJim Jagielski #include "data.hxx"
44*b1cdbd2cSJim Jagielski #include "localizedpropertynode.hxx"
45*b1cdbd2cSJim Jagielski #include "localizedvaluenode.hxx"
46*b1cdbd2cSJim Jagielski #include "groupnode.hxx"
47*b1cdbd2cSJim Jagielski #include "modifications.hxx"
48*b1cdbd2cSJim Jagielski #include "node.hxx"
49*b1cdbd2cSJim Jagielski #include "nodemap.hxx"
50*b1cdbd2cSJim Jagielski #include "parsemanager.hxx"
51*b1cdbd2cSJim Jagielski #include "partial.hxx"
52*b1cdbd2cSJim Jagielski #include "path.hxx"
53*b1cdbd2cSJim Jagielski #include "propertynode.hxx"
54*b1cdbd2cSJim Jagielski #include "setnode.hxx"
55*b1cdbd2cSJim Jagielski #include "xcuparser.hxx"
56*b1cdbd2cSJim Jagielski #include "xmldata.hxx"
57*b1cdbd2cSJim Jagielski
58*b1cdbd2cSJim Jagielski namespace configmgr {
59*b1cdbd2cSJim Jagielski
60*b1cdbd2cSJim Jagielski namespace {
61*b1cdbd2cSJim Jagielski
62*b1cdbd2cSJim Jagielski namespace css = com::sun::star;
63*b1cdbd2cSJim Jagielski
64*b1cdbd2cSJim Jagielski }
65*b1cdbd2cSJim Jagielski
XcuParser(int layer,Data & data,Partial const * partial,Modifications * broadcastModifications,Additions * additions)66*b1cdbd2cSJim Jagielski XcuParser::XcuParser(
67*b1cdbd2cSJim Jagielski int layer, Data & data, Partial const * partial,
68*b1cdbd2cSJim Jagielski Modifications * broadcastModifications, Additions * additions):
69*b1cdbd2cSJim Jagielski valueParser_(layer), data_(data),
70*b1cdbd2cSJim Jagielski partial_(partial), broadcastModifications_(broadcastModifications),
71*b1cdbd2cSJim Jagielski additions_(additions), recordModifications_(layer == Data::NO_LAYER),
72*b1cdbd2cSJim Jagielski trackPath_(
73*b1cdbd2cSJim Jagielski partial_ != 0 || broadcastModifications_ != 0 || additions_ != 0 ||
74*b1cdbd2cSJim Jagielski recordModifications_)
75*b1cdbd2cSJim Jagielski {}
76*b1cdbd2cSJim Jagielski
~XcuParser()77*b1cdbd2cSJim Jagielski XcuParser::~XcuParser() {}
78*b1cdbd2cSJim Jagielski
getTextMode()79*b1cdbd2cSJim Jagielski xmlreader::XmlReader::Text XcuParser::getTextMode() {
80*b1cdbd2cSJim Jagielski return valueParser_.getTextMode();
81*b1cdbd2cSJim Jagielski }
82*b1cdbd2cSJim Jagielski
startElement(xmlreader::XmlReader & reader,int nsId,xmlreader::Span const & name)83*b1cdbd2cSJim Jagielski bool XcuParser::startElement(
84*b1cdbd2cSJim Jagielski xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
85*b1cdbd2cSJim Jagielski {
86*b1cdbd2cSJim Jagielski if (valueParser_.startElement(reader, nsId, name)) {
87*b1cdbd2cSJim Jagielski return true;
88*b1cdbd2cSJim Jagielski }
89*b1cdbd2cSJim Jagielski if (state_.empty()) {
90*b1cdbd2cSJim Jagielski if (nsId == ParseManager::NAMESPACE_OOR &&
91*b1cdbd2cSJim Jagielski name.equals(RTL_CONSTASCII_STRINGPARAM("component-data")))
92*b1cdbd2cSJim Jagielski {
93*b1cdbd2cSJim Jagielski handleComponentData(reader);
94*b1cdbd2cSJim Jagielski } else if (nsId == ParseManager::NAMESPACE_OOR &&
95*b1cdbd2cSJim Jagielski name.equals(RTL_CONSTASCII_STRINGPARAM("items")))
96*b1cdbd2cSJim Jagielski {
97*b1cdbd2cSJim Jagielski state_.push(State(rtl::Reference< Node >(), false));
98*b1cdbd2cSJim Jagielski } else {
99*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
100*b1cdbd2cSJim Jagielski (rtl::OUString(
101*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("bad root element <")) +
102*b1cdbd2cSJim Jagielski name.convertFromUtf8() +
103*b1cdbd2cSJim Jagielski rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
104*b1cdbd2cSJim Jagielski reader.getUrl()),
105*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
106*b1cdbd2cSJim Jagielski }
107*b1cdbd2cSJim Jagielski } else if (state_.top().ignore) {
108*b1cdbd2cSJim Jagielski state_.push(State(false));
109*b1cdbd2cSJim Jagielski } else if (!state_.top().node.is()) {
110*b1cdbd2cSJim Jagielski if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
111*b1cdbd2cSJim Jagielski name.equals(RTL_CONSTASCII_STRINGPARAM("item")))
112*b1cdbd2cSJim Jagielski {
113*b1cdbd2cSJim Jagielski handleItem(reader);
114*b1cdbd2cSJim Jagielski } else {
115*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
116*b1cdbd2cSJim Jagielski (rtl::OUString(
117*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("bad items node member <")) +
118*b1cdbd2cSJim Jagielski name.convertFromUtf8() +
119*b1cdbd2cSJim Jagielski rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
120*b1cdbd2cSJim Jagielski reader.getUrl()),
121*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
122*b1cdbd2cSJim Jagielski }
123*b1cdbd2cSJim Jagielski } else {
124*b1cdbd2cSJim Jagielski switch (state_.top().node->kind()) {
125*b1cdbd2cSJim Jagielski case Node::KIND_PROPERTY:
126*b1cdbd2cSJim Jagielski if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
127*b1cdbd2cSJim Jagielski name.equals(RTL_CONSTASCII_STRINGPARAM("value")))
128*b1cdbd2cSJim Jagielski {
129*b1cdbd2cSJim Jagielski handlePropValue(
130*b1cdbd2cSJim Jagielski reader,
131*b1cdbd2cSJim Jagielski dynamic_cast< PropertyNode * >(state_.top().node.get()));
132*b1cdbd2cSJim Jagielski } else {
133*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
134*b1cdbd2cSJim Jagielski (rtl::OUString(
135*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
136*b1cdbd2cSJim Jagielski "bad property node member <")) +
137*b1cdbd2cSJim Jagielski name.convertFromUtf8() +
138*b1cdbd2cSJim Jagielski rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
139*b1cdbd2cSJim Jagielski reader.getUrl()),
140*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
141*b1cdbd2cSJim Jagielski }
142*b1cdbd2cSJim Jagielski break;
143*b1cdbd2cSJim Jagielski case Node::KIND_LOCALIZED_PROPERTY:
144*b1cdbd2cSJim Jagielski if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
145*b1cdbd2cSJim Jagielski name.equals(RTL_CONSTASCII_STRINGPARAM("value")))
146*b1cdbd2cSJim Jagielski {
147*b1cdbd2cSJim Jagielski handleLocpropValue(
148*b1cdbd2cSJim Jagielski reader,
149*b1cdbd2cSJim Jagielski dynamic_cast< LocalizedPropertyNode * >(
150*b1cdbd2cSJim Jagielski state_.top().node.get()));
151*b1cdbd2cSJim Jagielski } else {
152*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
153*b1cdbd2cSJim Jagielski (rtl::OUString(
154*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
155*b1cdbd2cSJim Jagielski "bad localized property node member <")) +
156*b1cdbd2cSJim Jagielski name.convertFromUtf8() +
157*b1cdbd2cSJim Jagielski rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
158*b1cdbd2cSJim Jagielski reader.getUrl()),
159*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
160*b1cdbd2cSJim Jagielski }
161*b1cdbd2cSJim Jagielski break;
162*b1cdbd2cSJim Jagielski case Node::KIND_LOCALIZED_VALUE:
163*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
164*b1cdbd2cSJim Jagielski (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad member <")) +
165*b1cdbd2cSJim Jagielski name.convertFromUtf8() +
166*b1cdbd2cSJim Jagielski rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
167*b1cdbd2cSJim Jagielski reader.getUrl()),
168*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
169*b1cdbd2cSJim Jagielski case Node::KIND_GROUP:
170*b1cdbd2cSJim Jagielski if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
171*b1cdbd2cSJim Jagielski name.equals(RTL_CONSTASCII_STRINGPARAM("prop")))
172*b1cdbd2cSJim Jagielski {
173*b1cdbd2cSJim Jagielski handleGroupProp(
174*b1cdbd2cSJim Jagielski reader,
175*b1cdbd2cSJim Jagielski dynamic_cast< GroupNode * >(state_.top().node.get()));
176*b1cdbd2cSJim Jagielski } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
177*b1cdbd2cSJim Jagielski name.equals(RTL_CONSTASCII_STRINGPARAM("node")))
178*b1cdbd2cSJim Jagielski {
179*b1cdbd2cSJim Jagielski handleGroupNode(reader, state_.top().node);
180*b1cdbd2cSJim Jagielski } else {
181*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
182*b1cdbd2cSJim Jagielski (rtl::OUString(
183*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
184*b1cdbd2cSJim Jagielski "bad group node member <")) +
185*b1cdbd2cSJim Jagielski name.convertFromUtf8() +
186*b1cdbd2cSJim Jagielski rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
187*b1cdbd2cSJim Jagielski reader.getUrl()),
188*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
189*b1cdbd2cSJim Jagielski }
190*b1cdbd2cSJim Jagielski break;
191*b1cdbd2cSJim Jagielski case Node::KIND_SET:
192*b1cdbd2cSJim Jagielski if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
193*b1cdbd2cSJim Jagielski name.equals(RTL_CONSTASCII_STRINGPARAM("node")))
194*b1cdbd2cSJim Jagielski {
195*b1cdbd2cSJim Jagielski handleSetNode(
196*b1cdbd2cSJim Jagielski reader, dynamic_cast< SetNode * >(state_.top().node.get()));
197*b1cdbd2cSJim Jagielski } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
198*b1cdbd2cSJim Jagielski name.equals(RTL_CONSTASCII_STRINGPARAM("prop")))
199*b1cdbd2cSJim Jagielski {
200*b1cdbd2cSJim Jagielski OSL_TRACE(
201*b1cdbd2cSJim Jagielski "configmgr bad set node <prop> member in %s",
202*b1cdbd2cSJim Jagielski rtl::OUStringToOString(
203*b1cdbd2cSJim Jagielski reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
204*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
205*b1cdbd2cSJim Jagielski } else {
206*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
207*b1cdbd2cSJim Jagielski (rtl::OUString(
208*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("bad set node member <")) +
209*b1cdbd2cSJim Jagielski name.convertFromUtf8() +
210*b1cdbd2cSJim Jagielski rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
211*b1cdbd2cSJim Jagielski reader.getUrl()),
212*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
213*b1cdbd2cSJim Jagielski }
214*b1cdbd2cSJim Jagielski break;
215*b1cdbd2cSJim Jagielski }
216*b1cdbd2cSJim Jagielski }
217*b1cdbd2cSJim Jagielski return true;
218*b1cdbd2cSJim Jagielski }
219*b1cdbd2cSJim Jagielski
endElement(xmlreader::XmlReader const &)220*b1cdbd2cSJim Jagielski void XcuParser::endElement(xmlreader::XmlReader const &) {
221*b1cdbd2cSJim Jagielski if (valueParser_.endElement()) {
222*b1cdbd2cSJim Jagielski return;
223*b1cdbd2cSJim Jagielski }
224*b1cdbd2cSJim Jagielski OSL_ASSERT(!state_.empty());
225*b1cdbd2cSJim Jagielski bool pop = state_.top().pop;
226*b1cdbd2cSJim Jagielski rtl::Reference< Node > insert;
227*b1cdbd2cSJim Jagielski rtl::OUString name;
228*b1cdbd2cSJim Jagielski if (state_.top().insert) {
229*b1cdbd2cSJim Jagielski insert = state_.top().node;
230*b1cdbd2cSJim Jagielski OSL_ASSERT(insert.is());
231*b1cdbd2cSJim Jagielski name = state_.top().name;
232*b1cdbd2cSJim Jagielski }
233*b1cdbd2cSJim Jagielski state_.pop();
234*b1cdbd2cSJim Jagielski if (insert.is()) {
235*b1cdbd2cSJim Jagielski OSL_ASSERT(!state_.empty() && state_.top().node.is());
236*b1cdbd2cSJim Jagielski state_.top().node->getMembers()[name] = insert;
237*b1cdbd2cSJim Jagielski }
238*b1cdbd2cSJim Jagielski if (pop && !path_.empty()) {
239*b1cdbd2cSJim Jagielski path_.pop_back();
240*b1cdbd2cSJim Jagielski // </item> will pop less than <item> pushed, but that is harmless,
241*b1cdbd2cSJim Jagielski // as the next <item> will reset path_
242*b1cdbd2cSJim Jagielski }
243*b1cdbd2cSJim Jagielski }
244*b1cdbd2cSJim Jagielski
characters(xmlreader::Span const & text)245*b1cdbd2cSJim Jagielski void XcuParser::characters(xmlreader::Span const & text) {
246*b1cdbd2cSJim Jagielski valueParser_.characters(text);
247*b1cdbd2cSJim Jagielski }
248*b1cdbd2cSJim Jagielski
parseOperation(xmlreader::Span const & text)249*b1cdbd2cSJim Jagielski XcuParser::Operation XcuParser::parseOperation(xmlreader::Span const & text) {
250*b1cdbd2cSJim Jagielski OSL_ASSERT(text.is());
251*b1cdbd2cSJim Jagielski if (text.equals(RTL_CONSTASCII_STRINGPARAM("modify"))) {
252*b1cdbd2cSJim Jagielski return OPERATION_MODIFY;
253*b1cdbd2cSJim Jagielski }
254*b1cdbd2cSJim Jagielski if (text.equals(RTL_CONSTASCII_STRINGPARAM("replace"))) {
255*b1cdbd2cSJim Jagielski return OPERATION_REPLACE;
256*b1cdbd2cSJim Jagielski }
257*b1cdbd2cSJim Jagielski if (text.equals(RTL_CONSTASCII_STRINGPARAM("fuse"))) {
258*b1cdbd2cSJim Jagielski return OPERATION_FUSE;
259*b1cdbd2cSJim Jagielski }
260*b1cdbd2cSJim Jagielski if (text.equals(RTL_CONSTASCII_STRINGPARAM("remove"))) {
261*b1cdbd2cSJim Jagielski return OPERATION_REMOVE;
262*b1cdbd2cSJim Jagielski }
263*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
264*b1cdbd2cSJim Jagielski (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("invalid op ")) +
265*b1cdbd2cSJim Jagielski text.convertFromUtf8()),
266*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
267*b1cdbd2cSJim Jagielski }
268*b1cdbd2cSJim Jagielski
handleComponentData(xmlreader::XmlReader & reader)269*b1cdbd2cSJim Jagielski void XcuParser::handleComponentData(xmlreader::XmlReader & reader) {
270*b1cdbd2cSJim Jagielski rtl::OStringBuffer buf;
271*b1cdbd2cSJim Jagielski buf.append('.');
272*b1cdbd2cSJim Jagielski bool hasPackage = false;
273*b1cdbd2cSJim Jagielski bool hasName = false;
274*b1cdbd2cSJim Jagielski Operation op = OPERATION_MODIFY;
275*b1cdbd2cSJim Jagielski bool finalized = false;
276*b1cdbd2cSJim Jagielski for (;;) {
277*b1cdbd2cSJim Jagielski int attrNsId;
278*b1cdbd2cSJim Jagielski xmlreader::Span attrLn;
279*b1cdbd2cSJim Jagielski if (!reader.nextAttribute(&attrNsId, &attrLn)) {
280*b1cdbd2cSJim Jagielski break;
281*b1cdbd2cSJim Jagielski }
282*b1cdbd2cSJim Jagielski if (attrNsId == ParseManager::NAMESPACE_OOR &&
283*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("package")))
284*b1cdbd2cSJim Jagielski {
285*b1cdbd2cSJim Jagielski if (hasPackage) {
286*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
287*b1cdbd2cSJim Jagielski (rtl::OUString(
288*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
289*b1cdbd2cSJim Jagielski "multiple component-update package attributes"
290*b1cdbd2cSJim Jagielski " in ")) +
291*b1cdbd2cSJim Jagielski reader.getUrl()),
292*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
293*b1cdbd2cSJim Jagielski }
294*b1cdbd2cSJim Jagielski hasPackage = true;
295*b1cdbd2cSJim Jagielski xmlreader::Span s(reader.getAttributeValue(false));
296*b1cdbd2cSJim Jagielski buf.insert(0, s.begin, s.length);
297*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
298*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
299*b1cdbd2cSJim Jagielski {
300*b1cdbd2cSJim Jagielski if (hasName) {
301*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
302*b1cdbd2cSJim Jagielski (rtl::OUString(
303*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
304*b1cdbd2cSJim Jagielski "multiple component-update name attributes in ")) +
305*b1cdbd2cSJim Jagielski reader.getUrl()),
306*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
307*b1cdbd2cSJim Jagielski }
308*b1cdbd2cSJim Jagielski hasName = true;
309*b1cdbd2cSJim Jagielski xmlreader::Span s(reader.getAttributeValue(false));
310*b1cdbd2cSJim Jagielski buf.append(s.begin, s.length);
311*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
312*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
313*b1cdbd2cSJim Jagielski {
314*b1cdbd2cSJim Jagielski op = parseOperation(reader.getAttributeValue(true));
315*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
316*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
317*b1cdbd2cSJim Jagielski {
318*b1cdbd2cSJim Jagielski finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
319*b1cdbd2cSJim Jagielski }
320*b1cdbd2cSJim Jagielski }
321*b1cdbd2cSJim Jagielski if (!hasPackage) {
322*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
323*b1cdbd2cSJim Jagielski (rtl::OUString(
324*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
325*b1cdbd2cSJim Jagielski "no component-data package attribute in ")) +
326*b1cdbd2cSJim Jagielski reader.getUrl()),
327*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
328*b1cdbd2cSJim Jagielski }
329*b1cdbd2cSJim Jagielski if (!hasName) {
330*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
331*b1cdbd2cSJim Jagielski (rtl::OUString(
332*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
333*b1cdbd2cSJim Jagielski "no component-data name attribute in ")) +
334*b1cdbd2cSJim Jagielski reader.getUrl()),
335*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
336*b1cdbd2cSJim Jagielski }
337*b1cdbd2cSJim Jagielski componentName_ = xmlreader::Span(buf.getStr(), buf.getLength()).
338*b1cdbd2cSJim Jagielski convertFromUtf8();
339*b1cdbd2cSJim Jagielski if (trackPath_) {
340*b1cdbd2cSJim Jagielski OSL_ASSERT(path_.empty());
341*b1cdbd2cSJim Jagielski path_.push_back(componentName_);
342*b1cdbd2cSJim Jagielski if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
343*b1cdbd2cSJim Jagielski {
344*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
345*b1cdbd2cSJim Jagielski return;
346*b1cdbd2cSJim Jagielski }
347*b1cdbd2cSJim Jagielski }
348*b1cdbd2cSJim Jagielski rtl::Reference< Node > node(
349*b1cdbd2cSJim Jagielski Data::findNode(
350*b1cdbd2cSJim Jagielski valueParser_.getLayer(), data_.components, componentName_));
351*b1cdbd2cSJim Jagielski if (!node.is()) {
352*b1cdbd2cSJim Jagielski OSL_TRACE(
353*b1cdbd2cSJim Jagielski "configmgr unknown component %s in %s",
354*b1cdbd2cSJim Jagielski rtl::OUStringToOString(
355*b1cdbd2cSJim Jagielski componentName_, RTL_TEXTENCODING_UTF8).getStr(),
356*b1cdbd2cSJim Jagielski rtl::OUStringToOString(
357*b1cdbd2cSJim Jagielski reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
358*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
359*b1cdbd2cSJim Jagielski return;
360*b1cdbd2cSJim Jagielski }
361*b1cdbd2cSJim Jagielski switch (op) {
362*b1cdbd2cSJim Jagielski case OPERATION_MODIFY:
363*b1cdbd2cSJim Jagielski case OPERATION_FUSE:
364*b1cdbd2cSJim Jagielski break;
365*b1cdbd2cSJim Jagielski default:
366*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
367*b1cdbd2cSJim Jagielski (rtl::OUString(
368*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
369*b1cdbd2cSJim Jagielski "invalid operation on root node in ")) +
370*b1cdbd2cSJim Jagielski reader.getUrl()),
371*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
372*b1cdbd2cSJim Jagielski }
373*b1cdbd2cSJim Jagielski int finalizedLayer = std::min(
374*b1cdbd2cSJim Jagielski finalized ? valueParser_.getLayer() : Data::NO_LAYER,
375*b1cdbd2cSJim Jagielski node->getFinalized());
376*b1cdbd2cSJim Jagielski node->setFinalized(finalizedLayer);
377*b1cdbd2cSJim Jagielski state_.push(State(node, finalizedLayer < valueParser_.getLayer()));
378*b1cdbd2cSJim Jagielski }
379*b1cdbd2cSJim Jagielski
handleItem(xmlreader::XmlReader & reader)380*b1cdbd2cSJim Jagielski void XcuParser::handleItem(xmlreader::XmlReader & reader) {
381*b1cdbd2cSJim Jagielski xmlreader::Span attrPath;
382*b1cdbd2cSJim Jagielski for (;;) {
383*b1cdbd2cSJim Jagielski int attrNsId;
384*b1cdbd2cSJim Jagielski xmlreader::Span attrLn;
385*b1cdbd2cSJim Jagielski if (!reader.nextAttribute(&attrNsId, &attrLn)) {
386*b1cdbd2cSJim Jagielski break;
387*b1cdbd2cSJim Jagielski }
388*b1cdbd2cSJim Jagielski if (attrNsId == ParseManager::NAMESPACE_OOR &&
389*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("path")))
390*b1cdbd2cSJim Jagielski {
391*b1cdbd2cSJim Jagielski attrPath = reader.getAttributeValue(false);
392*b1cdbd2cSJim Jagielski }
393*b1cdbd2cSJim Jagielski }
394*b1cdbd2cSJim Jagielski if (!attrPath.is()) {
395*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
396*b1cdbd2cSJim Jagielski (rtl::OUString(
397*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("missing path attribute in ")) +
398*b1cdbd2cSJim Jagielski reader.getUrl()),
399*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
400*b1cdbd2cSJim Jagielski }
401*b1cdbd2cSJim Jagielski rtl::OUString path(attrPath.convertFromUtf8());
402*b1cdbd2cSJim Jagielski int finalizedLayer;
403*b1cdbd2cSJim Jagielski rtl::Reference< Node > node(
404*b1cdbd2cSJim Jagielski data_.resolvePathRepresentation(
405*b1cdbd2cSJim Jagielski path, 0, &path_, &finalizedLayer));
406*b1cdbd2cSJim Jagielski if (!node.is()) {
407*b1cdbd2cSJim Jagielski OSL_TRACE(
408*b1cdbd2cSJim Jagielski "configmgr unknown item %s in %s",
409*b1cdbd2cSJim Jagielski rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr(),
410*b1cdbd2cSJim Jagielski rtl::OUStringToOString(
411*b1cdbd2cSJim Jagielski reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
412*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
413*b1cdbd2cSJim Jagielski return;
414*b1cdbd2cSJim Jagielski }
415*b1cdbd2cSJim Jagielski OSL_ASSERT(!path_.empty());
416*b1cdbd2cSJim Jagielski componentName_ = path_.front();
417*b1cdbd2cSJim Jagielski if (trackPath_) {
418*b1cdbd2cSJim Jagielski if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
419*b1cdbd2cSJim Jagielski {
420*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
421*b1cdbd2cSJim Jagielski return;
422*b1cdbd2cSJim Jagielski }
423*b1cdbd2cSJim Jagielski } else {
424*b1cdbd2cSJim Jagielski path_.clear();
425*b1cdbd2cSJim Jagielski }
426*b1cdbd2cSJim Jagielski switch (node->kind()) {
427*b1cdbd2cSJim Jagielski case Node::KIND_PROPERTY:
428*b1cdbd2cSJim Jagielski case Node::KIND_LOCALIZED_VALUE:
429*b1cdbd2cSJim Jagielski OSL_TRACE(
430*b1cdbd2cSJim Jagielski "configmgr item of bad type %s in %s",
431*b1cdbd2cSJim Jagielski rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr(),
432*b1cdbd2cSJim Jagielski rtl::OUStringToOString(
433*b1cdbd2cSJim Jagielski reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
434*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
435*b1cdbd2cSJim Jagielski return;
436*b1cdbd2cSJim Jagielski case Node::KIND_LOCALIZED_PROPERTY:
437*b1cdbd2cSJim Jagielski valueParser_.type_ = dynamic_cast< LocalizedPropertyNode * >(
438*b1cdbd2cSJim Jagielski node.get())->getStaticType();
439*b1cdbd2cSJim Jagielski break;
440*b1cdbd2cSJim Jagielski default:
441*b1cdbd2cSJim Jagielski break;
442*b1cdbd2cSJim Jagielski }
443*b1cdbd2cSJim Jagielski state_.push(State(node, finalizedLayer < valueParser_.getLayer()));
444*b1cdbd2cSJim Jagielski }
445*b1cdbd2cSJim Jagielski
handlePropValue(xmlreader::XmlReader & reader,PropertyNode * prop)446*b1cdbd2cSJim Jagielski void XcuParser::handlePropValue(
447*b1cdbd2cSJim Jagielski xmlreader::XmlReader & reader, PropertyNode * prop)
448*b1cdbd2cSJim Jagielski {
449*b1cdbd2cSJim Jagielski bool nil = false;
450*b1cdbd2cSJim Jagielski rtl::OString separator;
451*b1cdbd2cSJim Jagielski rtl::OUString external;
452*b1cdbd2cSJim Jagielski for (;;) {
453*b1cdbd2cSJim Jagielski int attrNsId;
454*b1cdbd2cSJim Jagielski xmlreader::Span attrLn;
455*b1cdbd2cSJim Jagielski if (!reader.nextAttribute(&attrNsId, &attrLn)) {
456*b1cdbd2cSJim Jagielski break;
457*b1cdbd2cSJim Jagielski }
458*b1cdbd2cSJim Jagielski if (attrNsId == ParseManager::NAMESPACE_XSI &&
459*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nil")))
460*b1cdbd2cSJim Jagielski {
461*b1cdbd2cSJim Jagielski nil = xmldata::parseBoolean(reader.getAttributeValue(true));
462*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
463*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
464*b1cdbd2cSJim Jagielski {
465*b1cdbd2cSJim Jagielski Type type = xmldata::parseType(
466*b1cdbd2cSJim Jagielski reader, reader.getAttributeValue(true));
467*b1cdbd2cSJim Jagielski if (valueParser_.type_ != TYPE_ANY && type != valueParser_.type_) {
468*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
469*b1cdbd2cSJim Jagielski (rtl::OUString(
470*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("invalid value type in ")) +
471*b1cdbd2cSJim Jagielski reader.getUrl()),
472*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
473*b1cdbd2cSJim Jagielski }
474*b1cdbd2cSJim Jagielski valueParser_.type_ = type;
475*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
476*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator")))
477*b1cdbd2cSJim Jagielski {
478*b1cdbd2cSJim Jagielski xmlreader::Span s(reader.getAttributeValue(false));
479*b1cdbd2cSJim Jagielski if (s.length == 0) {
480*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
481*b1cdbd2cSJim Jagielski (rtl::OUString(
482*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
483*b1cdbd2cSJim Jagielski "bad oor:separator attribute in ")) +
484*b1cdbd2cSJim Jagielski reader.getUrl()),
485*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
486*b1cdbd2cSJim Jagielski }
487*b1cdbd2cSJim Jagielski separator = rtl::OString(s.begin, s.length);
488*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
489*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("external")))
490*b1cdbd2cSJim Jagielski {
491*b1cdbd2cSJim Jagielski external = reader.getAttributeValue(true).convertFromUtf8();
492*b1cdbd2cSJim Jagielski if (external.getLength() == 0) {
493*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
494*b1cdbd2cSJim Jagielski (rtl::OUString(
495*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
496*b1cdbd2cSJim Jagielski "bad oor:external attribute value in ")) +
497*b1cdbd2cSJim Jagielski reader.getUrl()),
498*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
499*b1cdbd2cSJim Jagielski }
500*b1cdbd2cSJim Jagielski }
501*b1cdbd2cSJim Jagielski }
502*b1cdbd2cSJim Jagielski if (nil) {
503*b1cdbd2cSJim Jagielski if (!prop->isNillable()) {
504*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
505*b1cdbd2cSJim Jagielski (rtl::OUString(
506*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
507*b1cdbd2cSJim Jagielski "xsi:nil attribute for non-nillable prop in ")) +
508*b1cdbd2cSJim Jagielski reader.getUrl()),
509*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
510*b1cdbd2cSJim Jagielski }
511*b1cdbd2cSJim Jagielski if (external.getLength() != 0) {
512*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
513*b1cdbd2cSJim Jagielski (rtl::OUString(
514*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
515*b1cdbd2cSJim Jagielski "xsi:nil and oor:external attributes for prop in ")) +
516*b1cdbd2cSJim Jagielski reader.getUrl()),
517*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
518*b1cdbd2cSJim Jagielski }
519*b1cdbd2cSJim Jagielski prop->setValue(valueParser_.getLayer(), css::uno::Any());
520*b1cdbd2cSJim Jagielski state_.push(State(false));
521*b1cdbd2cSJim Jagielski } else if (external.getLength() == 0) {
522*b1cdbd2cSJim Jagielski valueParser_.separator_ = separator;
523*b1cdbd2cSJim Jagielski valueParser_.start(prop);
524*b1cdbd2cSJim Jagielski } else {
525*b1cdbd2cSJim Jagielski prop->setExternal(valueParser_.getLayer(), external);
526*b1cdbd2cSJim Jagielski state_.push(State(false));
527*b1cdbd2cSJim Jagielski }
528*b1cdbd2cSJim Jagielski }
529*b1cdbd2cSJim Jagielski
handleLocpropValue(xmlreader::XmlReader & reader,LocalizedPropertyNode * locprop)530*b1cdbd2cSJim Jagielski void XcuParser::handleLocpropValue(
531*b1cdbd2cSJim Jagielski xmlreader::XmlReader & reader, LocalizedPropertyNode * locprop)
532*b1cdbd2cSJim Jagielski {
533*b1cdbd2cSJim Jagielski rtl::OUString name;
534*b1cdbd2cSJim Jagielski bool nil = false;
535*b1cdbd2cSJim Jagielski rtl::OString separator;
536*b1cdbd2cSJim Jagielski Operation op = OPERATION_FUSE;
537*b1cdbd2cSJim Jagielski for (;;) {
538*b1cdbd2cSJim Jagielski int attrNsId;
539*b1cdbd2cSJim Jagielski xmlreader::Span attrLn;
540*b1cdbd2cSJim Jagielski if (!reader.nextAttribute(&attrNsId, &attrLn)) {
541*b1cdbd2cSJim Jagielski break;
542*b1cdbd2cSJim Jagielski }
543*b1cdbd2cSJim Jagielski if (attrNsId == xmlreader::XmlReader::NAMESPACE_XML &&
544*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("lang")))
545*b1cdbd2cSJim Jagielski {
546*b1cdbd2cSJim Jagielski name = reader.getAttributeValue(false).convertFromUtf8();
547*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_XSI &&
548*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nil")))
549*b1cdbd2cSJim Jagielski {
550*b1cdbd2cSJim Jagielski nil = xmldata::parseBoolean(reader.getAttributeValue(true));
551*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
552*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
553*b1cdbd2cSJim Jagielski {
554*b1cdbd2cSJim Jagielski Type type = xmldata::parseType(
555*b1cdbd2cSJim Jagielski reader, reader.getAttributeValue(true));
556*b1cdbd2cSJim Jagielski if (valueParser_.type_ != TYPE_ANY && type != valueParser_.type_) {
557*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
558*b1cdbd2cSJim Jagielski (rtl::OUString(
559*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("invalid value type in ")) +
560*b1cdbd2cSJim Jagielski reader.getUrl()),
561*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
562*b1cdbd2cSJim Jagielski }
563*b1cdbd2cSJim Jagielski valueParser_.type_ = type;
564*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
565*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator")))
566*b1cdbd2cSJim Jagielski {
567*b1cdbd2cSJim Jagielski xmlreader::Span s(reader.getAttributeValue(false));
568*b1cdbd2cSJim Jagielski if (s.length == 0) {
569*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
570*b1cdbd2cSJim Jagielski (rtl::OUString(
571*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
572*b1cdbd2cSJim Jagielski "bad oor:separator attribute in ")) +
573*b1cdbd2cSJim Jagielski reader.getUrl()),
574*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
575*b1cdbd2cSJim Jagielski }
576*b1cdbd2cSJim Jagielski separator = rtl::OString(s.begin, s.length);
577*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
578*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
579*b1cdbd2cSJim Jagielski {
580*b1cdbd2cSJim Jagielski op = parseOperation(reader.getAttributeValue(true));
581*b1cdbd2cSJim Jagielski }
582*b1cdbd2cSJim Jagielski }
583*b1cdbd2cSJim Jagielski if (trackPath_) {
584*b1cdbd2cSJim Jagielski path_.push_back(name);
585*b1cdbd2cSJim Jagielski if (partial_ != 0 &&
586*b1cdbd2cSJim Jagielski partial_->contains(path_) != Partial::CONTAINS_NODE)
587*b1cdbd2cSJim Jagielski {
588*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
589*b1cdbd2cSJim Jagielski return;
590*b1cdbd2cSJim Jagielski }
591*b1cdbd2cSJim Jagielski }
592*b1cdbd2cSJim Jagielski NodeMap::iterator i(locprop->getMembers().find(name));
593*b1cdbd2cSJim Jagielski if (i != locprop->getMembers().end() &&
594*b1cdbd2cSJim Jagielski i->second->getLayer() > valueParser_.getLayer())
595*b1cdbd2cSJim Jagielski {
596*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
597*b1cdbd2cSJim Jagielski return;
598*b1cdbd2cSJim Jagielski }
599*b1cdbd2cSJim Jagielski if (nil && !locprop->isNillable()) {
600*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
601*b1cdbd2cSJim Jagielski (rtl::OUString(
602*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
603*b1cdbd2cSJim Jagielski "xsi:nil attribute for non-nillable prop in ")) +
604*b1cdbd2cSJim Jagielski reader.getUrl()),
605*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
606*b1cdbd2cSJim Jagielski }
607*b1cdbd2cSJim Jagielski switch (op) {
608*b1cdbd2cSJim Jagielski case OPERATION_FUSE:
609*b1cdbd2cSJim Jagielski {
610*b1cdbd2cSJim Jagielski bool pop = false;
611*b1cdbd2cSJim Jagielski if (nil) {
612*b1cdbd2cSJim Jagielski if (i == locprop->getMembers().end()) {
613*b1cdbd2cSJim Jagielski locprop->getMembers()[name] = new LocalizedValueNode(
614*b1cdbd2cSJim Jagielski valueParser_.getLayer(), css::uno::Any());
615*b1cdbd2cSJim Jagielski } else {
616*b1cdbd2cSJim Jagielski dynamic_cast< LocalizedValueNode * >(
617*b1cdbd2cSJim Jagielski i->second.get())->setValue(
618*b1cdbd2cSJim Jagielski valueParser_.getLayer(), css::uno::Any());
619*b1cdbd2cSJim Jagielski }
620*b1cdbd2cSJim Jagielski state_.push(State(true));
621*b1cdbd2cSJim Jagielski } else {
622*b1cdbd2cSJim Jagielski valueParser_.separator_ = separator;
623*b1cdbd2cSJim Jagielski valueParser_.start(locprop, name);
624*b1cdbd2cSJim Jagielski pop = true;
625*b1cdbd2cSJim Jagielski }
626*b1cdbd2cSJim Jagielski if (trackPath_) {
627*b1cdbd2cSJim Jagielski recordModification(false);
628*b1cdbd2cSJim Jagielski if (pop) {
629*b1cdbd2cSJim Jagielski path_.pop_back();
630*b1cdbd2cSJim Jagielski }
631*b1cdbd2cSJim Jagielski }
632*b1cdbd2cSJim Jagielski }
633*b1cdbd2cSJim Jagielski break;
634*b1cdbd2cSJim Jagielski case OPERATION_REMOVE:
635*b1cdbd2cSJim Jagielski //TODO: only allow if parent.op == OPERATION_FUSE
636*b1cdbd2cSJim Jagielski //TODO: disallow removing when e.g. lang=""?
637*b1cdbd2cSJim Jagielski if (i != locprop->getMembers().end()) {
638*b1cdbd2cSJim Jagielski locprop->getMembers().erase(i);
639*b1cdbd2cSJim Jagielski }
640*b1cdbd2cSJim Jagielski state_.push(State(true));
641*b1cdbd2cSJim Jagielski recordModification(false);
642*b1cdbd2cSJim Jagielski break;
643*b1cdbd2cSJim Jagielski default:
644*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
645*b1cdbd2cSJim Jagielski (rtl::OUString(
646*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
647*b1cdbd2cSJim Jagielski "bad op attribute for value element in ")) +
648*b1cdbd2cSJim Jagielski reader.getUrl()),
649*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
650*b1cdbd2cSJim Jagielski }
651*b1cdbd2cSJim Jagielski }
652*b1cdbd2cSJim Jagielski
handleGroupProp(xmlreader::XmlReader & reader,GroupNode * group)653*b1cdbd2cSJim Jagielski void XcuParser::handleGroupProp(
654*b1cdbd2cSJim Jagielski xmlreader::XmlReader & reader, GroupNode * group)
655*b1cdbd2cSJim Jagielski {
656*b1cdbd2cSJim Jagielski bool hasName = false;
657*b1cdbd2cSJim Jagielski rtl::OUString name;
658*b1cdbd2cSJim Jagielski Type type = TYPE_ERROR;
659*b1cdbd2cSJim Jagielski Operation op = OPERATION_MODIFY;
660*b1cdbd2cSJim Jagielski bool finalized = false;
661*b1cdbd2cSJim Jagielski for (;;) {
662*b1cdbd2cSJim Jagielski int attrNsId;
663*b1cdbd2cSJim Jagielski xmlreader::Span attrLn;
664*b1cdbd2cSJim Jagielski if (!reader.nextAttribute(&attrNsId, &attrLn)) {
665*b1cdbd2cSJim Jagielski break;
666*b1cdbd2cSJim Jagielski }
667*b1cdbd2cSJim Jagielski if (attrNsId == ParseManager::NAMESPACE_OOR &&
668*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
669*b1cdbd2cSJim Jagielski {
670*b1cdbd2cSJim Jagielski hasName = true;
671*b1cdbd2cSJim Jagielski name = reader.getAttributeValue(false).convertFromUtf8();
672*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
673*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
674*b1cdbd2cSJim Jagielski {
675*b1cdbd2cSJim Jagielski type = xmldata::parseType(reader, reader.getAttributeValue(true));
676*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
677*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
678*b1cdbd2cSJim Jagielski {
679*b1cdbd2cSJim Jagielski op = parseOperation(reader.getAttributeValue(true));
680*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
681*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
682*b1cdbd2cSJim Jagielski {
683*b1cdbd2cSJim Jagielski finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
684*b1cdbd2cSJim Jagielski }
685*b1cdbd2cSJim Jagielski }
686*b1cdbd2cSJim Jagielski if (!hasName) {
687*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
688*b1cdbd2cSJim Jagielski (rtl::OUString(
689*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("no prop name attribute in ")) +
690*b1cdbd2cSJim Jagielski reader.getUrl()),
691*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
692*b1cdbd2cSJim Jagielski }
693*b1cdbd2cSJim Jagielski if (trackPath_) {
694*b1cdbd2cSJim Jagielski path_.push_back(name);
695*b1cdbd2cSJim Jagielski //TODO: This ignores locprop values for which specific include paths
696*b1cdbd2cSJim Jagielski // exist (i.e., for which contains(locprop path) = CONTAINS_SUBNODES):
697*b1cdbd2cSJim Jagielski if (partial_ != 0 &&
698*b1cdbd2cSJim Jagielski partial_->contains(path_) != Partial::CONTAINS_NODE)
699*b1cdbd2cSJim Jagielski {
700*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
701*b1cdbd2cSJim Jagielski return;
702*b1cdbd2cSJim Jagielski }
703*b1cdbd2cSJim Jagielski }
704*b1cdbd2cSJim Jagielski NodeMap::iterator i(group->getMembers().find(name));
705*b1cdbd2cSJim Jagielski if (i == group->getMembers().end()) {
706*b1cdbd2cSJim Jagielski handleUnknownGroupProp(reader, group, name, type, op, finalized);
707*b1cdbd2cSJim Jagielski } else {
708*b1cdbd2cSJim Jagielski switch (i->second->kind()) {
709*b1cdbd2cSJim Jagielski case Node::KIND_PROPERTY:
710*b1cdbd2cSJim Jagielski handlePlainGroupProp(reader, group, i, name, type, op, finalized);
711*b1cdbd2cSJim Jagielski break;
712*b1cdbd2cSJim Jagielski case Node::KIND_LOCALIZED_PROPERTY:
713*b1cdbd2cSJim Jagielski handleLocalizedGroupProp(
714*b1cdbd2cSJim Jagielski reader,
715*b1cdbd2cSJim Jagielski dynamic_cast< LocalizedPropertyNode * >(i->second.get()), name,
716*b1cdbd2cSJim Jagielski type, op, finalized);
717*b1cdbd2cSJim Jagielski break;
718*b1cdbd2cSJim Jagielski default:
719*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
720*b1cdbd2cSJim Jagielski (rtl::OUString(
721*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("inappropriate prop ")) +
722*b1cdbd2cSJim Jagielski name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
723*b1cdbd2cSJim Jagielski reader.getUrl()),
724*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
725*b1cdbd2cSJim Jagielski }
726*b1cdbd2cSJim Jagielski }
727*b1cdbd2cSJim Jagielski }
728*b1cdbd2cSJim Jagielski
handleUnknownGroupProp(xmlreader::XmlReader const & reader,GroupNode * group,rtl::OUString const & name,Type type,Operation operation,bool finalized)729*b1cdbd2cSJim Jagielski void XcuParser::handleUnknownGroupProp(
730*b1cdbd2cSJim Jagielski xmlreader::XmlReader const & reader, GroupNode * group,
731*b1cdbd2cSJim Jagielski rtl::OUString const & name, Type type, Operation operation, bool finalized)
732*b1cdbd2cSJim Jagielski {
733*b1cdbd2cSJim Jagielski switch (operation) {
734*b1cdbd2cSJim Jagielski case OPERATION_REPLACE:
735*b1cdbd2cSJim Jagielski case OPERATION_FUSE:
736*b1cdbd2cSJim Jagielski if (group->isExtensible()) {
737*b1cdbd2cSJim Jagielski if (type == TYPE_ERROR) {
738*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
739*b1cdbd2cSJim Jagielski (rtl::OUString(
740*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
741*b1cdbd2cSJim Jagielski "missing type attribute for prop ")) +
742*b1cdbd2cSJim Jagielski name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
743*b1cdbd2cSJim Jagielski reader.getUrl()),
744*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
745*b1cdbd2cSJim Jagielski }
746*b1cdbd2cSJim Jagielski valueParser_.type_ = type;
747*b1cdbd2cSJim Jagielski rtl::Reference< Node > prop(
748*b1cdbd2cSJim Jagielski new PropertyNode(
749*b1cdbd2cSJim Jagielski valueParser_.getLayer(), TYPE_ANY, true, css::uno::Any(),
750*b1cdbd2cSJim Jagielski true));
751*b1cdbd2cSJim Jagielski if (finalized) {
752*b1cdbd2cSJim Jagielski prop->setFinalized(valueParser_.getLayer());
753*b1cdbd2cSJim Jagielski }
754*b1cdbd2cSJim Jagielski state_.push(State(prop, name, state_.top().locked));
755*b1cdbd2cSJim Jagielski recordModification(false);
756*b1cdbd2cSJim Jagielski break;
757*b1cdbd2cSJim Jagielski }
758*b1cdbd2cSJim Jagielski // fall through
759*b1cdbd2cSJim Jagielski default:
760*b1cdbd2cSJim Jagielski OSL_TRACE(
761*b1cdbd2cSJim Jagielski "configmgr unknown property %s in %s",
762*b1cdbd2cSJim Jagielski rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(),
763*b1cdbd2cSJim Jagielski rtl::OUStringToOString(
764*b1cdbd2cSJim Jagielski reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
765*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
766*b1cdbd2cSJim Jagielski break;
767*b1cdbd2cSJim Jagielski }
768*b1cdbd2cSJim Jagielski }
769*b1cdbd2cSJim Jagielski
handlePlainGroupProp(xmlreader::XmlReader const & reader,GroupNode * group,NodeMap::iterator const & propertyIndex,rtl::OUString const & name,Type type,Operation operation,bool finalized)770*b1cdbd2cSJim Jagielski void XcuParser::handlePlainGroupProp(
771*b1cdbd2cSJim Jagielski xmlreader::XmlReader const & reader, GroupNode * group,
772*b1cdbd2cSJim Jagielski NodeMap::iterator const & propertyIndex, rtl::OUString const & name,
773*b1cdbd2cSJim Jagielski Type type, Operation operation, bool finalized)
774*b1cdbd2cSJim Jagielski {
775*b1cdbd2cSJim Jagielski PropertyNode * property = dynamic_cast< PropertyNode * >(
776*b1cdbd2cSJim Jagielski propertyIndex->second.get());
777*b1cdbd2cSJim Jagielski if (property->getLayer() > valueParser_.getLayer()) {
778*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
779*b1cdbd2cSJim Jagielski return;
780*b1cdbd2cSJim Jagielski }
781*b1cdbd2cSJim Jagielski int finalizedLayer = std::min(
782*b1cdbd2cSJim Jagielski finalized ? valueParser_.getLayer() : Data::NO_LAYER,
783*b1cdbd2cSJim Jagielski property->getFinalized());
784*b1cdbd2cSJim Jagielski property->setFinalized(finalizedLayer);
785*b1cdbd2cSJim Jagielski if (type != TYPE_ERROR && property->getStaticType() != TYPE_ANY &&
786*b1cdbd2cSJim Jagielski type != property->getStaticType())
787*b1cdbd2cSJim Jagielski {
788*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
789*b1cdbd2cSJim Jagielski (rtl::OUString(
790*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("invalid type for prop ")) +
791*b1cdbd2cSJim Jagielski name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
792*b1cdbd2cSJim Jagielski reader.getUrl()),
793*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
794*b1cdbd2cSJim Jagielski }
795*b1cdbd2cSJim Jagielski valueParser_.type_ = type == TYPE_ERROR ? property->getStaticType() : type;
796*b1cdbd2cSJim Jagielski switch (operation) {
797*b1cdbd2cSJim Jagielski case OPERATION_MODIFY:
798*b1cdbd2cSJim Jagielski case OPERATION_REPLACE:
799*b1cdbd2cSJim Jagielski case OPERATION_FUSE:
800*b1cdbd2cSJim Jagielski state_.push(
801*b1cdbd2cSJim Jagielski State(
802*b1cdbd2cSJim Jagielski property,
803*b1cdbd2cSJim Jagielski (state_.top().locked ||
804*b1cdbd2cSJim Jagielski finalizedLayer < valueParser_.getLayer())));
805*b1cdbd2cSJim Jagielski recordModification(false);
806*b1cdbd2cSJim Jagielski break;
807*b1cdbd2cSJim Jagielski case OPERATION_REMOVE:
808*b1cdbd2cSJim Jagielski if (!property->isExtension()) {
809*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
810*b1cdbd2cSJim Jagielski (rtl::OUString(
811*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
812*b1cdbd2cSJim Jagielski "invalid remove of non-extension prop ")) +
813*b1cdbd2cSJim Jagielski name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
814*b1cdbd2cSJim Jagielski reader.getUrl()),
815*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
816*b1cdbd2cSJim Jagielski }
817*b1cdbd2cSJim Jagielski group->getMembers().erase(propertyIndex);
818*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignore children
819*b1cdbd2cSJim Jagielski recordModification(false);
820*b1cdbd2cSJim Jagielski break;
821*b1cdbd2cSJim Jagielski }
822*b1cdbd2cSJim Jagielski }
823*b1cdbd2cSJim Jagielski
handleLocalizedGroupProp(xmlreader::XmlReader const & reader,LocalizedPropertyNode * property,rtl::OUString const & name,Type type,Operation operation,bool finalized)824*b1cdbd2cSJim Jagielski void XcuParser::handleLocalizedGroupProp(
825*b1cdbd2cSJim Jagielski xmlreader::XmlReader const & reader, LocalizedPropertyNode * property,
826*b1cdbd2cSJim Jagielski rtl::OUString const & name, Type type, Operation operation, bool finalized)
827*b1cdbd2cSJim Jagielski {
828*b1cdbd2cSJim Jagielski if (property->getLayer() > valueParser_.getLayer()) {
829*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
830*b1cdbd2cSJim Jagielski return;
831*b1cdbd2cSJim Jagielski }
832*b1cdbd2cSJim Jagielski int finalizedLayer = std::min(
833*b1cdbd2cSJim Jagielski finalized ? valueParser_.getLayer() : Data::NO_LAYER,
834*b1cdbd2cSJim Jagielski property->getFinalized());
835*b1cdbd2cSJim Jagielski property->setFinalized(finalizedLayer);
836*b1cdbd2cSJim Jagielski if (type != TYPE_ERROR && property->getStaticType() != TYPE_ANY &&
837*b1cdbd2cSJim Jagielski type != property->getStaticType())
838*b1cdbd2cSJim Jagielski {
839*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
840*b1cdbd2cSJim Jagielski (rtl::OUString(
841*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("invalid type for prop ")) +
842*b1cdbd2cSJim Jagielski name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
843*b1cdbd2cSJim Jagielski reader.getUrl()),
844*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
845*b1cdbd2cSJim Jagielski }
846*b1cdbd2cSJim Jagielski valueParser_.type_ = type == TYPE_ERROR ? property->getStaticType() : type;
847*b1cdbd2cSJim Jagielski switch (operation) {
848*b1cdbd2cSJim Jagielski case OPERATION_MODIFY:
849*b1cdbd2cSJim Jagielski case OPERATION_FUSE:
850*b1cdbd2cSJim Jagielski state_.push(
851*b1cdbd2cSJim Jagielski State(
852*b1cdbd2cSJim Jagielski property,
853*b1cdbd2cSJim Jagielski (state_.top().locked ||
854*b1cdbd2cSJim Jagielski finalizedLayer < valueParser_.getLayer())));
855*b1cdbd2cSJim Jagielski break;
856*b1cdbd2cSJim Jagielski case OPERATION_REPLACE:
857*b1cdbd2cSJim Jagielski {
858*b1cdbd2cSJim Jagielski rtl::Reference< Node > replacement(
859*b1cdbd2cSJim Jagielski new LocalizedPropertyNode(
860*b1cdbd2cSJim Jagielski valueParser_.getLayer(), property->getStaticType(),
861*b1cdbd2cSJim Jagielski property->isNillable()));
862*b1cdbd2cSJim Jagielski replacement->setFinalized(property->getFinalized());
863*b1cdbd2cSJim Jagielski state_.push(
864*b1cdbd2cSJim Jagielski State(
865*b1cdbd2cSJim Jagielski replacement, name,
866*b1cdbd2cSJim Jagielski (state_.top().locked ||
867*b1cdbd2cSJim Jagielski finalizedLayer < valueParser_.getLayer())));
868*b1cdbd2cSJim Jagielski recordModification(false);
869*b1cdbd2cSJim Jagielski }
870*b1cdbd2cSJim Jagielski break;
871*b1cdbd2cSJim Jagielski case OPERATION_REMOVE:
872*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
873*b1cdbd2cSJim Jagielski (rtl::OUString(
874*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
875*b1cdbd2cSJim Jagielski "invalid remove of non-extension prop ")) +
876*b1cdbd2cSJim Jagielski name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
877*b1cdbd2cSJim Jagielski reader.getUrl()),
878*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
879*b1cdbd2cSJim Jagielski }
880*b1cdbd2cSJim Jagielski }
881*b1cdbd2cSJim Jagielski
handleGroupNode(xmlreader::XmlReader & reader,rtl::Reference<Node> const & group)882*b1cdbd2cSJim Jagielski void XcuParser::handleGroupNode(
883*b1cdbd2cSJim Jagielski xmlreader::XmlReader & reader, rtl::Reference< Node > const & group)
884*b1cdbd2cSJim Jagielski {
885*b1cdbd2cSJim Jagielski bool hasName = false;
886*b1cdbd2cSJim Jagielski rtl::OUString name;
887*b1cdbd2cSJim Jagielski Operation op = OPERATION_MODIFY;
888*b1cdbd2cSJim Jagielski bool finalized = false;
889*b1cdbd2cSJim Jagielski for (;;) {
890*b1cdbd2cSJim Jagielski int attrNsId;
891*b1cdbd2cSJim Jagielski xmlreader::Span attrLn;
892*b1cdbd2cSJim Jagielski if (!reader.nextAttribute(&attrNsId, &attrLn)) {
893*b1cdbd2cSJim Jagielski break;
894*b1cdbd2cSJim Jagielski }
895*b1cdbd2cSJim Jagielski if (attrNsId == ParseManager::NAMESPACE_OOR &&
896*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
897*b1cdbd2cSJim Jagielski {
898*b1cdbd2cSJim Jagielski hasName = true;
899*b1cdbd2cSJim Jagielski name = reader.getAttributeValue(false).convertFromUtf8();
900*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
901*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
902*b1cdbd2cSJim Jagielski {
903*b1cdbd2cSJim Jagielski op = parseOperation(reader.getAttributeValue(true));
904*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
905*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
906*b1cdbd2cSJim Jagielski {
907*b1cdbd2cSJim Jagielski finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
908*b1cdbd2cSJim Jagielski }
909*b1cdbd2cSJim Jagielski }
910*b1cdbd2cSJim Jagielski if (!hasName) {
911*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
912*b1cdbd2cSJim Jagielski (rtl::OUString(
913*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("no node name attribute in ")) +
914*b1cdbd2cSJim Jagielski reader.getUrl()),
915*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
916*b1cdbd2cSJim Jagielski }
917*b1cdbd2cSJim Jagielski if (trackPath_) {
918*b1cdbd2cSJim Jagielski path_.push_back(name);
919*b1cdbd2cSJim Jagielski if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
920*b1cdbd2cSJim Jagielski {
921*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
922*b1cdbd2cSJim Jagielski return;
923*b1cdbd2cSJim Jagielski }
924*b1cdbd2cSJim Jagielski }
925*b1cdbd2cSJim Jagielski rtl::Reference< Node > child(
926*b1cdbd2cSJim Jagielski Data::findNode(valueParser_.getLayer(), group->getMembers(), name));
927*b1cdbd2cSJim Jagielski if (!child.is()) {
928*b1cdbd2cSJim Jagielski OSL_TRACE(
929*b1cdbd2cSJim Jagielski "configmgr unknown node %s in %s",
930*b1cdbd2cSJim Jagielski rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(),
931*b1cdbd2cSJim Jagielski rtl::OUStringToOString(
932*b1cdbd2cSJim Jagielski reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr());
933*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
934*b1cdbd2cSJim Jagielski return;
935*b1cdbd2cSJim Jagielski }
936*b1cdbd2cSJim Jagielski if (op != OPERATION_MODIFY && op != OPERATION_FUSE) {
937*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
938*b1cdbd2cSJim Jagielski (rtl::OUString(
939*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
940*b1cdbd2cSJim Jagielski "invalid operation on group node in ")) +
941*b1cdbd2cSJim Jagielski reader.getUrl()),
942*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
943*b1cdbd2cSJim Jagielski }
944*b1cdbd2cSJim Jagielski int finalizedLayer = std::min(
945*b1cdbd2cSJim Jagielski finalized ? valueParser_.getLayer() : Data::NO_LAYER,
946*b1cdbd2cSJim Jagielski child->getFinalized());
947*b1cdbd2cSJim Jagielski child->setFinalized(finalizedLayer);
948*b1cdbd2cSJim Jagielski state_.push(
949*b1cdbd2cSJim Jagielski State(
950*b1cdbd2cSJim Jagielski child,
951*b1cdbd2cSJim Jagielski state_.top().locked || finalizedLayer < valueParser_.getLayer()));
952*b1cdbd2cSJim Jagielski }
953*b1cdbd2cSJim Jagielski
handleSetNode(xmlreader::XmlReader & reader,SetNode * set)954*b1cdbd2cSJim Jagielski void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) {
955*b1cdbd2cSJim Jagielski bool hasName = false;
956*b1cdbd2cSJim Jagielski rtl::OUString name;
957*b1cdbd2cSJim Jagielski rtl::OUString component(componentName_);
958*b1cdbd2cSJim Jagielski bool hasNodeType = false;
959*b1cdbd2cSJim Jagielski rtl::OUString nodeType;
960*b1cdbd2cSJim Jagielski Operation op = OPERATION_MODIFY;
961*b1cdbd2cSJim Jagielski bool finalized = false;
962*b1cdbd2cSJim Jagielski bool mandatory = false;
963*b1cdbd2cSJim Jagielski for (;;) {
964*b1cdbd2cSJim Jagielski int attrNsId;
965*b1cdbd2cSJim Jagielski xmlreader::Span attrLn;
966*b1cdbd2cSJim Jagielski if (!reader.nextAttribute(&attrNsId, &attrLn)) {
967*b1cdbd2cSJim Jagielski break;
968*b1cdbd2cSJim Jagielski }
969*b1cdbd2cSJim Jagielski if (attrNsId == ParseManager::NAMESPACE_OOR &&
970*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
971*b1cdbd2cSJim Jagielski {
972*b1cdbd2cSJim Jagielski hasName = true;
973*b1cdbd2cSJim Jagielski name = reader.getAttributeValue(false).convertFromUtf8();
974*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
975*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
976*b1cdbd2cSJim Jagielski {
977*b1cdbd2cSJim Jagielski component = reader.getAttributeValue(false).convertFromUtf8();
978*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
979*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
980*b1cdbd2cSJim Jagielski {
981*b1cdbd2cSJim Jagielski hasNodeType = true;
982*b1cdbd2cSJim Jagielski nodeType = reader.getAttributeValue(false).convertFromUtf8();
983*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
984*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
985*b1cdbd2cSJim Jagielski {
986*b1cdbd2cSJim Jagielski op = parseOperation(reader.getAttributeValue(true));
987*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
988*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
989*b1cdbd2cSJim Jagielski {
990*b1cdbd2cSJim Jagielski finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
991*b1cdbd2cSJim Jagielski } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
992*b1cdbd2cSJim Jagielski attrLn.equals(RTL_CONSTASCII_STRINGPARAM("mandatory")))
993*b1cdbd2cSJim Jagielski {
994*b1cdbd2cSJim Jagielski mandatory = xmldata::parseBoolean(reader.getAttributeValue(true));
995*b1cdbd2cSJim Jagielski }
996*b1cdbd2cSJim Jagielski }
997*b1cdbd2cSJim Jagielski if (!hasName) {
998*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
999*b1cdbd2cSJim Jagielski (rtl::OUString(
1000*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM("no node name attribute in ")) +
1001*b1cdbd2cSJim Jagielski reader.getUrl()),
1002*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
1003*b1cdbd2cSJim Jagielski }
1004*b1cdbd2cSJim Jagielski if (trackPath_) {
1005*b1cdbd2cSJim Jagielski path_.push_back(name);
1006*b1cdbd2cSJim Jagielski if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
1007*b1cdbd2cSJim Jagielski {
1008*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
1009*b1cdbd2cSJim Jagielski return;
1010*b1cdbd2cSJim Jagielski }
1011*b1cdbd2cSJim Jagielski }
1012*b1cdbd2cSJim Jagielski rtl::OUString templateName(
1013*b1cdbd2cSJim Jagielski xmldata::parseTemplateReference(
1014*b1cdbd2cSJim Jagielski component, hasNodeType, nodeType, &set->getDefaultTemplateName()));
1015*b1cdbd2cSJim Jagielski if (!set->isValidTemplate(templateName)) {
1016*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
1017*b1cdbd2cSJim Jagielski (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("set member node ")) +
1018*b1cdbd2cSJim Jagielski name +
1019*b1cdbd2cSJim Jagielski rtl::OUString(
1020*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(" references invalid template ")) +
1021*b1cdbd2cSJim Jagielski templateName + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
1022*b1cdbd2cSJim Jagielski reader.getUrl()),
1023*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
1024*b1cdbd2cSJim Jagielski }
1025*b1cdbd2cSJim Jagielski rtl::Reference< Node > tmpl(
1026*b1cdbd2cSJim Jagielski data_.getTemplate(valueParser_.getLayer(), templateName));
1027*b1cdbd2cSJim Jagielski if (!tmpl.is()) {
1028*b1cdbd2cSJim Jagielski throw css::uno::RuntimeException(
1029*b1cdbd2cSJim Jagielski (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("set member node ")) +
1030*b1cdbd2cSJim Jagielski name +
1031*b1cdbd2cSJim Jagielski rtl::OUString(
1032*b1cdbd2cSJim Jagielski RTL_CONSTASCII_USTRINGPARAM(
1033*b1cdbd2cSJim Jagielski " references undefined template ")) +
1034*b1cdbd2cSJim Jagielski templateName + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
1035*b1cdbd2cSJim Jagielski reader.getUrl()),
1036*b1cdbd2cSJim Jagielski css::uno::Reference< css::uno::XInterface >());
1037*b1cdbd2cSJim Jagielski }
1038*b1cdbd2cSJim Jagielski int finalizedLayer = finalized ? valueParser_.getLayer() : Data::NO_LAYER;
1039*b1cdbd2cSJim Jagielski int mandatoryLayer = mandatory ? valueParser_.getLayer() : Data::NO_LAYER;
1040*b1cdbd2cSJim Jagielski NodeMap::iterator i(set->getMembers().find(name));
1041*b1cdbd2cSJim Jagielski if (i != set->getMembers().end()) {
1042*b1cdbd2cSJim Jagielski finalizedLayer = std::min(finalizedLayer, i->second->getFinalized());
1043*b1cdbd2cSJim Jagielski i->second->setFinalized(finalizedLayer);
1044*b1cdbd2cSJim Jagielski mandatoryLayer = std::min(mandatoryLayer, i->second->getMandatory());
1045*b1cdbd2cSJim Jagielski i->second->setMandatory(mandatoryLayer);
1046*b1cdbd2cSJim Jagielski if (i->second->getLayer() > valueParser_.getLayer()) {
1047*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
1048*b1cdbd2cSJim Jagielski return;
1049*b1cdbd2cSJim Jagielski }
1050*b1cdbd2cSJim Jagielski }
1051*b1cdbd2cSJim Jagielski switch (op) {
1052*b1cdbd2cSJim Jagielski case OPERATION_MODIFY:
1053*b1cdbd2cSJim Jagielski if (i == set->getMembers().end()) {
1054*b1cdbd2cSJim Jagielski OSL_TRACE("ignoring modify of unknown set member node");
1055*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
1056*b1cdbd2cSJim Jagielski } else {
1057*b1cdbd2cSJim Jagielski state_.push(
1058*b1cdbd2cSJim Jagielski State(
1059*b1cdbd2cSJim Jagielski i->second,
1060*b1cdbd2cSJim Jagielski (state_.top().locked ||
1061*b1cdbd2cSJim Jagielski finalizedLayer < valueParser_.getLayer())));
1062*b1cdbd2cSJim Jagielski }
1063*b1cdbd2cSJim Jagielski break;
1064*b1cdbd2cSJim Jagielski case OPERATION_REPLACE:
1065*b1cdbd2cSJim Jagielski if (state_.top().locked || finalizedLayer < valueParser_.getLayer()) {
1066*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
1067*b1cdbd2cSJim Jagielski } else {
1068*b1cdbd2cSJim Jagielski rtl::Reference< Node > member(tmpl->clone(true));
1069*b1cdbd2cSJim Jagielski member->setLayer(valueParser_.getLayer());
1070*b1cdbd2cSJim Jagielski member->setFinalized(finalizedLayer);
1071*b1cdbd2cSJim Jagielski member->setMandatory(mandatoryLayer);
1072*b1cdbd2cSJim Jagielski state_.push(State(member, name, false));
1073*b1cdbd2cSJim Jagielski recordModification(i == set->getMembers().end());
1074*b1cdbd2cSJim Jagielski }
1075*b1cdbd2cSJim Jagielski break;
1076*b1cdbd2cSJim Jagielski case OPERATION_FUSE:
1077*b1cdbd2cSJim Jagielski if (i == set->getMembers().end()) {
1078*b1cdbd2cSJim Jagielski if (state_.top().locked || finalizedLayer < valueParser_.getLayer())
1079*b1cdbd2cSJim Jagielski {
1080*b1cdbd2cSJim Jagielski state_.push(State(true)); // ignored
1081*b1cdbd2cSJim Jagielski } else {
1082*b1cdbd2cSJim Jagielski rtl::Reference< Node > member(tmpl->clone(true));
1083*b1cdbd2cSJim Jagielski member->setLayer(valueParser_.getLayer());
1084*b1cdbd2cSJim Jagielski member->setFinalized(finalizedLayer);
1085*b1cdbd2cSJim Jagielski member->setMandatory(mandatoryLayer);
1086*b1cdbd2cSJim Jagielski state_.push(State(member, name, false));
1087*b1cdbd2cSJim Jagielski recordModification(true);
1088*b1cdbd2cSJim Jagielski }
1089*b1cdbd2cSJim Jagielski } else {
1090*b1cdbd2cSJim Jagielski state_.push(
1091*b1cdbd2cSJim Jagielski State(
1092*b1cdbd2cSJim Jagielski i->second,
1093*b1cdbd2cSJim Jagielski (state_.top().locked ||
1094*b1cdbd2cSJim Jagielski finalizedLayer < valueParser_.getLayer())));
1095*b1cdbd2cSJim Jagielski }
1096*b1cdbd2cSJim Jagielski break;
1097*b1cdbd2cSJim Jagielski case OPERATION_REMOVE:
1098*b1cdbd2cSJim Jagielski {
1099*b1cdbd2cSJim Jagielski // Ignore removal of unknown members, members finalized in a lower
1100*b1cdbd2cSJim Jagielski // layer, and members made mandatory in this or a lower layer;
1101*b1cdbd2cSJim Jagielski // forget about user-layer removals that no longer remove anything
1102*b1cdbd2cSJim Jagielski // (so that paired additions/removals in the user layer do not grow
1103*b1cdbd2cSJim Jagielski // registrymodifications.xcu unbounded):
1104*b1cdbd2cSJim Jagielski bool known = i != set->getMembers().end();
1105*b1cdbd2cSJim Jagielski if (known && !state_.top().locked &&
1106*b1cdbd2cSJim Jagielski finalizedLayer >= valueParser_.getLayer() &&
1107*b1cdbd2cSJim Jagielski mandatoryLayer > valueParser_.getLayer())
1108*b1cdbd2cSJim Jagielski {
1109*b1cdbd2cSJim Jagielski set->getMembers().erase(i);
1110*b1cdbd2cSJim Jagielski }
1111*b1cdbd2cSJim Jagielski state_.push(State(true));
1112*b1cdbd2cSJim Jagielski if (known) {
1113*b1cdbd2cSJim Jagielski recordModification(false);
1114*b1cdbd2cSJim Jagielski }
1115*b1cdbd2cSJim Jagielski break;
1116*b1cdbd2cSJim Jagielski }
1117*b1cdbd2cSJim Jagielski }
1118*b1cdbd2cSJim Jagielski }
1119*b1cdbd2cSJim Jagielski
recordModification(bool addition)1120*b1cdbd2cSJim Jagielski void XcuParser::recordModification(bool addition) {
1121*b1cdbd2cSJim Jagielski if (broadcastModifications_ != 0) {
1122*b1cdbd2cSJim Jagielski broadcastModifications_->add(path_);
1123*b1cdbd2cSJim Jagielski }
1124*b1cdbd2cSJim Jagielski if (addition && additions_ != 0) {
1125*b1cdbd2cSJim Jagielski additions_->push_back(path_);
1126*b1cdbd2cSJim Jagielski }
1127*b1cdbd2cSJim Jagielski if (recordModifications_) {
1128*b1cdbd2cSJim Jagielski data_.modifications.add(path_);
1129*b1cdbd2cSJim Jagielski }
1130*b1cdbd2cSJim Jagielski }
1131*b1cdbd2cSJim Jagielski
1132*b1cdbd2cSJim Jagielski }
1133