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 <cstddef>
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 "groupnode.hxx"
46cdf0e10cSrcweir #include "node.hxx"
47cdf0e10cSrcweir #include "nodemap.hxx"
48cdf0e10cSrcweir #include "parsemanager.hxx"
49cdf0e10cSrcweir #include "propertynode.hxx"
50cdf0e10cSrcweir #include "setnode.hxx"
51cdf0e10cSrcweir #include "xcsparser.hxx"
52cdf0e10cSrcweir #include "xmldata.hxx"
53cdf0e10cSrcweir
54cdf0e10cSrcweir namespace configmgr {
55cdf0e10cSrcweir
56cdf0e10cSrcweir namespace {
57cdf0e10cSrcweir
58cdf0e10cSrcweir namespace css = com::sun::star;
59cdf0e10cSrcweir
60cdf0e10cSrcweir // Conservatively merge a template or component (and its recursive parts) into
61cdf0e10cSrcweir // an existing instance:
merge(rtl::Reference<Node> const & original,rtl::Reference<Node> const & update)62cdf0e10cSrcweir void merge(
63cdf0e10cSrcweir rtl::Reference< Node > const & original,
64cdf0e10cSrcweir rtl::Reference< Node > const & update)
65cdf0e10cSrcweir {
66cdf0e10cSrcweir OSL_ASSERT(
67cdf0e10cSrcweir original.is() && update.is() && original->kind() == update->kind() &&
68cdf0e10cSrcweir update->getFinalized() == Data::NO_LAYER);
69cdf0e10cSrcweir if (update->getLayer() >= original->getLayer() &&
70cdf0e10cSrcweir update->getLayer() <= original->getFinalized())
71cdf0e10cSrcweir {
72cdf0e10cSrcweir switch (original->kind()) {
73cdf0e10cSrcweir case Node::KIND_PROPERTY:
74cdf0e10cSrcweir case Node::KIND_LOCALIZED_PROPERTY:
75cdf0e10cSrcweir case Node::KIND_LOCALIZED_VALUE:
76cdf0e10cSrcweir break; //TODO: merge certain parts?
77cdf0e10cSrcweir case Node::KIND_GROUP:
78cdf0e10cSrcweir for (NodeMap::iterator i2(update->getMembers().begin());
79cdf0e10cSrcweir i2 != update->getMembers().end(); ++i2)
80cdf0e10cSrcweir {
81cdf0e10cSrcweir NodeMap::iterator i1(original->getMembers().find(i2->first));
82cdf0e10cSrcweir if (i1 == original->getMembers().end()) {
83cdf0e10cSrcweir if (i2->second->kind() == Node::KIND_PROPERTY &&
84cdf0e10cSrcweir dynamic_cast< GroupNode * >(
85cdf0e10cSrcweir original.get())->isExtensible())
86cdf0e10cSrcweir {
87cdf0e10cSrcweir original->getMembers().insert(*i2);
88cdf0e10cSrcweir }
89cdf0e10cSrcweir } else if (i2->second->kind() == i1->second->kind()) {
90cdf0e10cSrcweir merge(i1->second, i2->second);
91cdf0e10cSrcweir }
92cdf0e10cSrcweir }
93cdf0e10cSrcweir break;
94cdf0e10cSrcweir case Node::KIND_SET:
95cdf0e10cSrcweir for (NodeMap::iterator i2(update->getMembers().begin());
96cdf0e10cSrcweir i2 != update->getMembers().end(); ++i2)
97cdf0e10cSrcweir {
98cdf0e10cSrcweir NodeMap::iterator i1(original->getMembers().find(i2->first));
99cdf0e10cSrcweir if (i1 == original->getMembers().end()) {
100cdf0e10cSrcweir if (dynamic_cast< SetNode * >(original.get())->
101cdf0e10cSrcweir isValidTemplate(i2->second->getTemplateName()))
102cdf0e10cSrcweir {
103cdf0e10cSrcweir original->getMembers().insert(*i2);
104cdf0e10cSrcweir }
105cdf0e10cSrcweir } else if (i2->second->kind() == i1->second->kind() &&
106cdf0e10cSrcweir (i2->second->getTemplateName() ==
107cdf0e10cSrcweir i1->second->getTemplateName()))
108cdf0e10cSrcweir {
109cdf0e10cSrcweir merge(i1->second, i2->second);
110cdf0e10cSrcweir }
111cdf0e10cSrcweir }
112cdf0e10cSrcweir break;
113cdf0e10cSrcweir }
114cdf0e10cSrcweir }
115cdf0e10cSrcweir }
116cdf0e10cSrcweir
117cdf0e10cSrcweir }
118cdf0e10cSrcweir
XcsParser(int layer,Data & data)119cdf0e10cSrcweir XcsParser::XcsParser(int layer, Data & data):
120cdf0e10cSrcweir valueParser_(layer), data_(data), state_(STATE_START)
121cdf0e10cSrcweir {}
122cdf0e10cSrcweir
~XcsParser()123cdf0e10cSrcweir XcsParser::~XcsParser() {}
124cdf0e10cSrcweir
getTextMode()125cdf0e10cSrcweir xmlreader::XmlReader::Text XcsParser::getTextMode() {
126cdf0e10cSrcweir return valueParser_.getTextMode();
127cdf0e10cSrcweir }
128cdf0e10cSrcweir
startElement(xmlreader::XmlReader & reader,int nsId,xmlreader::Span const & name)129cdf0e10cSrcweir bool XcsParser::startElement(
130cdf0e10cSrcweir xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
131cdf0e10cSrcweir {
132cdf0e10cSrcweir if (valueParser_.startElement(reader, nsId, name)) {
133cdf0e10cSrcweir return true;
134cdf0e10cSrcweir }
135cdf0e10cSrcweir if (state_ == STATE_START) {
136cdf0e10cSrcweir if (nsId == ParseManager::NAMESPACE_OOR &&
137cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("component-schema"))) {
138cdf0e10cSrcweir handleComponentSchema(reader);
139cdf0e10cSrcweir state_ = STATE_COMPONENT_SCHEMA;
140cdf0e10cSrcweir ignoring_ = 0;
141cdf0e10cSrcweir return true;
142cdf0e10cSrcweir }
143cdf0e10cSrcweir } else {
144cdf0e10cSrcweir //TODO: ignoring component-schema import, component-schema uses, and
145cdf0e10cSrcweir // prop constraints; accepting all four at illegal places (and with
146cdf0e10cSrcweir // illegal content):
147cdf0e10cSrcweir if (ignoring_ > 0 ||
148cdf0e10cSrcweir (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
149cdf0e10cSrcweir (name.equals(RTL_CONSTASCII_STRINGPARAM("info")) ||
150cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("import")) ||
151cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("uses")) ||
152cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("constraints")))))
153cdf0e10cSrcweir {
154cdf0e10cSrcweir OSL_ASSERT(ignoring_ < LONG_MAX);
155cdf0e10cSrcweir ++ignoring_;
156cdf0e10cSrcweir return true;
157cdf0e10cSrcweir }
158cdf0e10cSrcweir switch (state_) {
159cdf0e10cSrcweir case STATE_COMPONENT_SCHEMA:
160cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
161cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("templates")))
162cdf0e10cSrcweir {
163cdf0e10cSrcweir state_ = STATE_TEMPLATES;
164cdf0e10cSrcweir return true;
165cdf0e10cSrcweir }
166cdf0e10cSrcweir // fall through
167cdf0e10cSrcweir case STATE_TEMPLATES_DONE:
168cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
169cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("component")))
170cdf0e10cSrcweir {
171cdf0e10cSrcweir state_ = STATE_COMPONENT;
172cdf0e10cSrcweir OSL_ASSERT(elements_.empty());
173cdf0e10cSrcweir elements_.push(
174cdf0e10cSrcweir Element(
175cdf0e10cSrcweir new GroupNode(
176cdf0e10cSrcweir valueParser_.getLayer(), false, rtl::OUString()),
177cdf0e10cSrcweir componentName_));
178cdf0e10cSrcweir return true;
179cdf0e10cSrcweir }
180cdf0e10cSrcweir break;
181cdf0e10cSrcweir case STATE_TEMPLATES:
182cdf0e10cSrcweir if (elements_.empty()) {
183cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
184cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("group")))
185cdf0e10cSrcweir {
186cdf0e10cSrcweir handleGroup(reader, true);
187cdf0e10cSrcweir return true;
188cdf0e10cSrcweir }
189cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
190cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("set")))
191cdf0e10cSrcweir {
192cdf0e10cSrcweir handleSet(reader, true);
193cdf0e10cSrcweir return true;
194cdf0e10cSrcweir }
195cdf0e10cSrcweir break;
196cdf0e10cSrcweir }
197cdf0e10cSrcweir // fall through
198cdf0e10cSrcweir case STATE_COMPONENT:
199cdf0e10cSrcweir OSL_ASSERT(!elements_.empty());
200cdf0e10cSrcweir switch (elements_.top().node->kind()) {
201cdf0e10cSrcweir case Node::KIND_PROPERTY:
202cdf0e10cSrcweir case Node::KIND_LOCALIZED_PROPERTY:
203cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
204cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("value")))
205cdf0e10cSrcweir {
206cdf0e10cSrcweir handlePropValue(reader, elements_.top().node);
207cdf0e10cSrcweir return true;
208cdf0e10cSrcweir }
209cdf0e10cSrcweir break;
210cdf0e10cSrcweir case Node::KIND_GROUP:
211cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
212cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("prop")))
213cdf0e10cSrcweir {
214cdf0e10cSrcweir handleProp(reader);
215cdf0e10cSrcweir return true;
216cdf0e10cSrcweir }
217cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
218cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("node-ref")))
219cdf0e10cSrcweir {
220cdf0e10cSrcweir handleNodeRef(reader);
221cdf0e10cSrcweir return true;
222cdf0e10cSrcweir }
223cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
224cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("group")))
225cdf0e10cSrcweir {
226cdf0e10cSrcweir handleGroup(reader, false);
227cdf0e10cSrcweir return true;
228cdf0e10cSrcweir }
229cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
230cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("set")))
231cdf0e10cSrcweir {
232cdf0e10cSrcweir handleSet(reader, false);
233cdf0e10cSrcweir return true;
234cdf0e10cSrcweir }
235cdf0e10cSrcweir break;
236cdf0e10cSrcweir case Node::KIND_SET:
237cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
238cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("item")))
239cdf0e10cSrcweir {
240cdf0e10cSrcweir handleSetItem(
241cdf0e10cSrcweir reader,
242cdf0e10cSrcweir dynamic_cast< SetNode * >(elements_.top().node.get()));
243cdf0e10cSrcweir return true;
244cdf0e10cSrcweir }
245cdf0e10cSrcweir break;
246cdf0e10cSrcweir default: // Node::KIND_LOCALIZED_VALUE
247cdf0e10cSrcweir OSL_ASSERT(false); // this cannot happen
248cdf0e10cSrcweir break;
249cdf0e10cSrcweir }
250cdf0e10cSrcweir break;
251cdf0e10cSrcweir case STATE_COMPONENT_DONE:
252cdf0e10cSrcweir break;
253cdf0e10cSrcweir default: // STATE_START
254cdf0e10cSrcweir OSL_ASSERT(false); // this cannot happen
255cdf0e10cSrcweir break;
256cdf0e10cSrcweir }
257cdf0e10cSrcweir }
258cdf0e10cSrcweir throw css::uno::RuntimeException(
259cdf0e10cSrcweir (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad member <")) +
260cdf0e10cSrcweir name.convertFromUtf8() +
261cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + reader.getUrl()),
262cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
263cdf0e10cSrcweir }
264cdf0e10cSrcweir
endElement(xmlreader::XmlReader const & reader)265cdf0e10cSrcweir void XcsParser::endElement(xmlreader::XmlReader const & reader) {
266cdf0e10cSrcweir if (valueParser_.endElement()) {
267cdf0e10cSrcweir return;
268cdf0e10cSrcweir }
269cdf0e10cSrcweir if (ignoring_ > 0) {
270cdf0e10cSrcweir --ignoring_;
271cdf0e10cSrcweir } else if (!elements_.empty()) {
272cdf0e10cSrcweir Element top(elements_.top());
273cdf0e10cSrcweir elements_.pop();
274cdf0e10cSrcweir if (top.node.is()) {
275cdf0e10cSrcweir if (elements_.empty()) {
276cdf0e10cSrcweir switch (state_) {
277cdf0e10cSrcweir case STATE_TEMPLATES:
278cdf0e10cSrcweir {
279cdf0e10cSrcweir NodeMap::iterator i(data_.templates.find(top.name));
280cdf0e10cSrcweir if (i == data_.templates.end()) {
281cdf0e10cSrcweir data_.templates.insert(
282cdf0e10cSrcweir NodeMap::value_type(top.name, top.node));
283cdf0e10cSrcweir } else {
284cdf0e10cSrcweir merge(i->second, top.node);
285cdf0e10cSrcweir }
286cdf0e10cSrcweir }
287cdf0e10cSrcweir break;
288cdf0e10cSrcweir case STATE_COMPONENT:
289cdf0e10cSrcweir {
290cdf0e10cSrcweir NodeMap::iterator i(data_.components.find(top.name));
291cdf0e10cSrcweir if (i == data_.components.end()) {
292cdf0e10cSrcweir data_.components.insert(
293cdf0e10cSrcweir NodeMap::value_type(top.name, top.node));
294cdf0e10cSrcweir } else {
295cdf0e10cSrcweir merge(i->second, top.node);
296cdf0e10cSrcweir }
297cdf0e10cSrcweir state_ = STATE_COMPONENT_DONE;
298cdf0e10cSrcweir }
299cdf0e10cSrcweir break;
300cdf0e10cSrcweir default:
301cdf0e10cSrcweir OSL_ASSERT(false);
302cdf0e10cSrcweir throw css::uno::RuntimeException(
303cdf0e10cSrcweir rtl::OUString(
304cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("this cannot happen")),
305cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
306cdf0e10cSrcweir }
307cdf0e10cSrcweir } else if (!elements_.top().node->getMembers().insert(
308cdf0e10cSrcweir NodeMap::value_type(top.name, top.node)).second)
309cdf0e10cSrcweir {
310cdf0e10cSrcweir throw css::uno::RuntimeException(
311cdf0e10cSrcweir (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("duplicate ")) +
312cdf0e10cSrcweir top.name +
313cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
314cdf0e10cSrcweir reader.getUrl()),
315cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
316cdf0e10cSrcweir }
317cdf0e10cSrcweir }
318cdf0e10cSrcweir } else {
319cdf0e10cSrcweir switch (state_) {
320cdf0e10cSrcweir case STATE_COMPONENT_SCHEMA:
321cdf0e10cSrcweir // To support old, broken extensions with .xcs files that contain
322cdf0e10cSrcweir // empty <component-schema> elements:
323cdf0e10cSrcweir state_ = STATE_COMPONENT_DONE;
324cdf0e10cSrcweir break;
325cdf0e10cSrcweir case STATE_TEMPLATES:
326cdf0e10cSrcweir state_ = STATE_TEMPLATES_DONE;
327cdf0e10cSrcweir break;
328cdf0e10cSrcweir case STATE_TEMPLATES_DONE:
329cdf0e10cSrcweir throw css::uno::RuntimeException(
330cdf0e10cSrcweir (rtl::OUString(
331cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("no component element in ")) +
332cdf0e10cSrcweir reader.getUrl()),
333cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
334cdf0e10cSrcweir case STATE_COMPONENT_DONE:
335cdf0e10cSrcweir break;
336cdf0e10cSrcweir default:
337cdf0e10cSrcweir OSL_ASSERT(false); // this cannot happen
338cdf0e10cSrcweir }
339cdf0e10cSrcweir }
340cdf0e10cSrcweir }
341cdf0e10cSrcweir
characters(xmlreader::Span const & text)342cdf0e10cSrcweir void XcsParser::characters(xmlreader::Span const & text) {
343cdf0e10cSrcweir valueParser_.characters(text);
344cdf0e10cSrcweir }
345cdf0e10cSrcweir
handleComponentSchema(xmlreader::XmlReader & reader)346cdf0e10cSrcweir void XcsParser::handleComponentSchema(xmlreader::XmlReader & reader) {
347cdf0e10cSrcweir //TODO: oor:version, xml:lang attributes
348cdf0e10cSrcweir rtl::OStringBuffer buf;
349cdf0e10cSrcweir buf.append('.');
350cdf0e10cSrcweir bool hasPackage = false;
351cdf0e10cSrcweir bool hasName = false;
352cdf0e10cSrcweir for (;;) {
353cdf0e10cSrcweir int attrNsId;
354cdf0e10cSrcweir xmlreader::Span attrLn;
355cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) {
356cdf0e10cSrcweir break;
357cdf0e10cSrcweir }
358cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR &&
359cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("package")))
360cdf0e10cSrcweir {
361cdf0e10cSrcweir if (hasPackage) {
362cdf0e10cSrcweir throw css::uno::RuntimeException(
363cdf0e10cSrcweir (rtl::OUString(
364cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
365cdf0e10cSrcweir "multiple component-schema package attributes"
366cdf0e10cSrcweir " in ")) +
367cdf0e10cSrcweir reader.getUrl()),
368cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
369cdf0e10cSrcweir }
370cdf0e10cSrcweir hasPackage = true;
371cdf0e10cSrcweir xmlreader::Span s(reader.getAttributeValue(false));
372cdf0e10cSrcweir buf.insert(0, s.begin, s.length);
373cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
374cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
375cdf0e10cSrcweir {
376cdf0e10cSrcweir if (hasName) {
377cdf0e10cSrcweir throw css::uno::RuntimeException(
378cdf0e10cSrcweir (rtl::OUString(
379cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
380cdf0e10cSrcweir "multiple component-schema name attributes in ")) +
381cdf0e10cSrcweir reader.getUrl()),
382cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
383cdf0e10cSrcweir }
384cdf0e10cSrcweir hasName = true;
385cdf0e10cSrcweir xmlreader::Span s(reader.getAttributeValue(false));
386cdf0e10cSrcweir buf.append(s.begin, s.length);
387cdf0e10cSrcweir }
388cdf0e10cSrcweir }
389cdf0e10cSrcweir if (!hasPackage) {
390cdf0e10cSrcweir throw css::uno::RuntimeException(
391cdf0e10cSrcweir (rtl::OUString(
392cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
393cdf0e10cSrcweir "no component-schema package attribute in ")) +
394cdf0e10cSrcweir reader.getUrl()),
395cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
396cdf0e10cSrcweir }
397cdf0e10cSrcweir if (!hasName) {
398cdf0e10cSrcweir throw css::uno::RuntimeException(
399cdf0e10cSrcweir (rtl::OUString(
400cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
401cdf0e10cSrcweir "no component-schema name attribute in ")) +
402cdf0e10cSrcweir reader.getUrl()),
403cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
404cdf0e10cSrcweir }
405cdf0e10cSrcweir componentName_ = xmlreader::Span(buf.getStr(), buf.getLength()).
406cdf0e10cSrcweir convertFromUtf8();
407cdf0e10cSrcweir }
408cdf0e10cSrcweir
handleNodeRef(xmlreader::XmlReader & reader)409cdf0e10cSrcweir void XcsParser::handleNodeRef(xmlreader::XmlReader & reader) {
410cdf0e10cSrcweir bool hasName = false;
411cdf0e10cSrcweir rtl::OUString name;
412cdf0e10cSrcweir rtl::OUString component(componentName_);
413cdf0e10cSrcweir bool hasNodeType = false;
414cdf0e10cSrcweir rtl::OUString nodeType;
415cdf0e10cSrcweir for (;;) {
416cdf0e10cSrcweir int attrNsId;
417cdf0e10cSrcweir xmlreader::Span attrLn;
418cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) {
419cdf0e10cSrcweir break;
420cdf0e10cSrcweir }
421cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR &&
422cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
423cdf0e10cSrcweir {
424cdf0e10cSrcweir hasName = true;
425cdf0e10cSrcweir name = reader.getAttributeValue(false).convertFromUtf8();
426cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
427cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
428cdf0e10cSrcweir {
429cdf0e10cSrcweir component = reader.getAttributeValue(false).convertFromUtf8();
430cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
431cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
432cdf0e10cSrcweir {
433cdf0e10cSrcweir hasNodeType = true;
434cdf0e10cSrcweir nodeType = reader.getAttributeValue(false).convertFromUtf8();
435cdf0e10cSrcweir }
436cdf0e10cSrcweir }
437cdf0e10cSrcweir if (!hasName) {
438cdf0e10cSrcweir throw css::uno::RuntimeException(
439cdf0e10cSrcweir (rtl::OUString(
440cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("no node-ref name attribute in ")) +
441cdf0e10cSrcweir reader.getUrl()),
442cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
443cdf0e10cSrcweir }
444cdf0e10cSrcweir rtl::Reference< Node > tmpl(
445cdf0e10cSrcweir data_.getTemplate(
446cdf0e10cSrcweir valueParser_.getLayer(),
447cdf0e10cSrcweir xmldata::parseTemplateReference(
448cdf0e10cSrcweir component, hasNodeType, nodeType, 0)));
449cdf0e10cSrcweir if (!tmpl.is()) {
450cdf0e10cSrcweir //TODO: this can erroneously happen as long as import/uses attributes
451cdf0e10cSrcweir // are not correctly processed
452cdf0e10cSrcweir throw css::uno::RuntimeException(
453cdf0e10cSrcweir (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown node-ref ")) +
454cdf0e10cSrcweir name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
455cdf0e10cSrcweir reader.getUrl()),
456cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
457cdf0e10cSrcweir }
458cdf0e10cSrcweir rtl::Reference< Node > node(tmpl->clone(false));
459cdf0e10cSrcweir node->setLayer(valueParser_.getLayer());
460cdf0e10cSrcweir elements_.push(Element(node, name));
461cdf0e10cSrcweir }
462cdf0e10cSrcweir
handleProp(xmlreader::XmlReader & reader)463cdf0e10cSrcweir void XcsParser::handleProp(xmlreader::XmlReader & reader) {
464cdf0e10cSrcweir bool hasName = false;
465cdf0e10cSrcweir rtl::OUString name;
466cdf0e10cSrcweir valueParser_.type_ = TYPE_ERROR;
467cdf0e10cSrcweir bool localized = false;
468cdf0e10cSrcweir bool nillable = true;
469cdf0e10cSrcweir for (;;) {
470cdf0e10cSrcweir int attrNsId;
471cdf0e10cSrcweir xmlreader::Span attrLn;
472cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) {
473cdf0e10cSrcweir break;
474cdf0e10cSrcweir }
475cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR &&
476cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
477cdf0e10cSrcweir {
478cdf0e10cSrcweir hasName = true;
479cdf0e10cSrcweir name = reader.getAttributeValue(false).convertFromUtf8();
480cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
481cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
482cdf0e10cSrcweir {
483cdf0e10cSrcweir valueParser_.type_ = xmldata::parseType(
484cdf0e10cSrcweir reader, reader.getAttributeValue(true));
485cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
486cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("localized")))
487cdf0e10cSrcweir {
488cdf0e10cSrcweir localized = xmldata::parseBoolean(reader.getAttributeValue(true));
489cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
490cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nillable")))
491cdf0e10cSrcweir {
492cdf0e10cSrcweir nillable = xmldata::parseBoolean(reader.getAttributeValue(true));
493cdf0e10cSrcweir }
494cdf0e10cSrcweir }
495cdf0e10cSrcweir if (!hasName) {
496cdf0e10cSrcweir throw css::uno::RuntimeException(
497cdf0e10cSrcweir (rtl::OUString(
498cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("no prop name attribute in ")) +
499cdf0e10cSrcweir reader.getUrl()),
500cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
501cdf0e10cSrcweir }
502cdf0e10cSrcweir if (valueParser_.type_ == TYPE_ERROR) {
503cdf0e10cSrcweir throw css::uno::RuntimeException(
504cdf0e10cSrcweir (rtl::OUString(
505cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("no prop type attribute in ")) +
506cdf0e10cSrcweir reader.getUrl()),
507cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
508cdf0e10cSrcweir }
509cdf0e10cSrcweir elements_.push(
510cdf0e10cSrcweir Element(
511cdf0e10cSrcweir (localized
512cdf0e10cSrcweir ? rtl::Reference< Node >(
513cdf0e10cSrcweir new LocalizedPropertyNode(
514cdf0e10cSrcweir valueParser_.getLayer(), valueParser_.type_, nillable))
515cdf0e10cSrcweir : rtl::Reference< Node >(
516cdf0e10cSrcweir new PropertyNode(
517cdf0e10cSrcweir valueParser_.getLayer(), valueParser_.type_, nillable,
518cdf0e10cSrcweir css::uno::Any(), false))),
519cdf0e10cSrcweir name));
520cdf0e10cSrcweir }
521cdf0e10cSrcweir
handlePropValue(xmlreader::XmlReader & reader,rtl::Reference<Node> const & property)522cdf0e10cSrcweir void XcsParser::handlePropValue(
523cdf0e10cSrcweir xmlreader::XmlReader & reader, rtl::Reference< Node > const & property)
524cdf0e10cSrcweir {
525cdf0e10cSrcweir xmlreader::Span attrSeparator;
526cdf0e10cSrcweir for (;;) {
527cdf0e10cSrcweir int attrNsId;
528cdf0e10cSrcweir xmlreader::Span attrLn;
529cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) {
530cdf0e10cSrcweir break;
531cdf0e10cSrcweir }
532cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR &&
533cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator")))
534cdf0e10cSrcweir {
535cdf0e10cSrcweir attrSeparator = reader.getAttributeValue(false);
536cdf0e10cSrcweir if (attrSeparator.length == 0) {
537cdf0e10cSrcweir throw css::uno::RuntimeException(
538cdf0e10cSrcweir (rtl::OUString(
539cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(
540cdf0e10cSrcweir "bad oor:separator attribute in ")) +
541cdf0e10cSrcweir reader.getUrl()),
542cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
543cdf0e10cSrcweir }
544cdf0e10cSrcweir }
545cdf0e10cSrcweir }
546cdf0e10cSrcweir valueParser_.separator_ = rtl::OString(
547cdf0e10cSrcweir attrSeparator.begin, attrSeparator.length);
548cdf0e10cSrcweir valueParser_.start(property);
549cdf0e10cSrcweir }
550cdf0e10cSrcweir
handleGroup(xmlreader::XmlReader & reader,bool isTemplate)551cdf0e10cSrcweir void XcsParser::handleGroup(xmlreader::XmlReader & reader, bool isTemplate) {
552cdf0e10cSrcweir bool hasName = false;
553cdf0e10cSrcweir rtl::OUString name;
554cdf0e10cSrcweir bool extensible = false;
555cdf0e10cSrcweir for (;;) {
556cdf0e10cSrcweir int attrNsId;
557cdf0e10cSrcweir xmlreader::Span attrLn;
558cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) {
559cdf0e10cSrcweir break;
560cdf0e10cSrcweir }
561cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR &&
562cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
563cdf0e10cSrcweir {
564cdf0e10cSrcweir hasName = true;
565cdf0e10cSrcweir name = reader.getAttributeValue(false).convertFromUtf8();
566cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
567cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("extensible")))
568cdf0e10cSrcweir {
569cdf0e10cSrcweir extensible = xmldata::parseBoolean(reader.getAttributeValue(true));
570cdf0e10cSrcweir }
571cdf0e10cSrcweir }
572cdf0e10cSrcweir if (!hasName) {
573cdf0e10cSrcweir throw css::uno::RuntimeException(
574cdf0e10cSrcweir (rtl::OUString(
575cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("no group name attribute in ")) +
576cdf0e10cSrcweir reader.getUrl()),
577cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
578cdf0e10cSrcweir }
579cdf0e10cSrcweir if (isTemplate) {
580cdf0e10cSrcweir name = Data::fullTemplateName(componentName_, name);
581cdf0e10cSrcweir }
582cdf0e10cSrcweir elements_.push(
583cdf0e10cSrcweir Element(
584cdf0e10cSrcweir new GroupNode(
585cdf0e10cSrcweir valueParser_.getLayer(), extensible,
586cdf0e10cSrcweir isTemplate ? name : rtl::OUString()),
587cdf0e10cSrcweir name));
588cdf0e10cSrcweir }
589cdf0e10cSrcweir
handleSet(xmlreader::XmlReader & reader,bool isTemplate)590cdf0e10cSrcweir void XcsParser::handleSet(xmlreader::XmlReader & reader, bool isTemplate) {
591cdf0e10cSrcweir bool hasName = false;
592cdf0e10cSrcweir rtl::OUString name;
593cdf0e10cSrcweir rtl::OUString component(componentName_);
594cdf0e10cSrcweir bool hasNodeType = false;
595cdf0e10cSrcweir rtl::OUString nodeType;
596cdf0e10cSrcweir for (;;) {
597cdf0e10cSrcweir int attrNsId;
598cdf0e10cSrcweir xmlreader::Span attrLn;
599cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) {
600cdf0e10cSrcweir break;
601cdf0e10cSrcweir }
602cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR &&
603cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
604cdf0e10cSrcweir {
605cdf0e10cSrcweir hasName = true;
606cdf0e10cSrcweir name = reader.getAttributeValue(false).convertFromUtf8();
607cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
608cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
609cdf0e10cSrcweir {
610cdf0e10cSrcweir component = reader.getAttributeValue(false).convertFromUtf8();
611cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
612cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
613cdf0e10cSrcweir {
614cdf0e10cSrcweir hasNodeType = true;
615cdf0e10cSrcweir nodeType = reader.getAttributeValue(false).convertFromUtf8();
616cdf0e10cSrcweir }
617cdf0e10cSrcweir }
618cdf0e10cSrcweir if (!hasName) {
619cdf0e10cSrcweir throw css::uno::RuntimeException(
620cdf0e10cSrcweir (rtl::OUString(
621cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("no set name attribute in ")) +
622cdf0e10cSrcweir reader.getUrl()),
623cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >());
624cdf0e10cSrcweir }
625cdf0e10cSrcweir if (isTemplate) {
626cdf0e10cSrcweir name = Data::fullTemplateName(componentName_, name);
627cdf0e10cSrcweir }
628cdf0e10cSrcweir elements_.push(
629cdf0e10cSrcweir Element(
630cdf0e10cSrcweir new SetNode(
631cdf0e10cSrcweir valueParser_.getLayer(),
632cdf0e10cSrcweir xmldata::parseTemplateReference(
633cdf0e10cSrcweir component, hasNodeType, nodeType, 0),
634cdf0e10cSrcweir isTemplate ? name : rtl::OUString()),
635cdf0e10cSrcweir name));
636cdf0e10cSrcweir }
637cdf0e10cSrcweir
handleSetItem(xmlreader::XmlReader & reader,SetNode * set)638cdf0e10cSrcweir void XcsParser::handleSetItem(xmlreader::XmlReader & reader, SetNode * set) {
639cdf0e10cSrcweir rtl::OUString component(componentName_);
640cdf0e10cSrcweir bool hasNodeType = false;
641cdf0e10cSrcweir rtl::OUString nodeType;
642cdf0e10cSrcweir for (;;) {
643cdf0e10cSrcweir int attrNsId;
644cdf0e10cSrcweir xmlreader::Span attrLn;
645cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) {
646cdf0e10cSrcweir break;
647cdf0e10cSrcweir }
648cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR &&
649cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
650cdf0e10cSrcweir {
651cdf0e10cSrcweir component = reader.getAttributeValue(false).convertFromUtf8();
652cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
653cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
654cdf0e10cSrcweir {
655cdf0e10cSrcweir hasNodeType = true;
656cdf0e10cSrcweir nodeType = reader.getAttributeValue(false).convertFromUtf8();
657cdf0e10cSrcweir }
658cdf0e10cSrcweir }
659cdf0e10cSrcweir set->getAdditionalTemplateNames().push_back(
660cdf0e10cSrcweir xmldata::parseTemplateReference(component, hasNodeType, nodeType, 0));
661cdf0e10cSrcweir elements_.push(Element(rtl::Reference< Node >(), rtl::OUString()));
662cdf0e10cSrcweir }
663cdf0e10cSrcweir
664cdf0e10cSrcweir }
665