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