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