Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "sal/config.h"
21 : :
22 : : #include <cassert>
23 : : #include <cstddef>
24 : :
25 : : #include "com/sun/star/uno/Any.hxx"
26 : : #include "com/sun/star/uno/Reference.hxx"
27 : : #include "com/sun/star/uno/RuntimeException.hpp"
28 : : #include "com/sun/star/uno/XInterface.hpp"
29 : : #include "rtl/ref.hxx"
30 : : #include "rtl/strbuf.hxx"
31 : : #include "rtl/string.h"
32 : : #include "rtl/string.hxx"
33 : : #include "rtl/ustring.h"
34 : : #include "rtl/ustring.hxx"
35 : : #include "xmlreader/span.hxx"
36 : : #include "xmlreader/xmlreader.hxx"
37 : :
38 : : #include "data.hxx"
39 : : #include "localizedpropertynode.hxx"
40 : : #include "groupnode.hxx"
41 : : #include "node.hxx"
42 : : #include "nodemap.hxx"
43 : : #include "parsemanager.hxx"
44 : : #include "propertynode.hxx"
45 : : #include "setnode.hxx"
46 : : #include "xcsparser.hxx"
47 : : #include "xmldata.hxx"
48 : :
49 : : namespace configmgr {
50 : :
51 : : namespace {
52 : :
53 : : namespace css = com::sun::star;
54 : :
55 : : // Conservatively merge a template or component (and its recursive parts) into
56 : : // an existing instance:
57 : 0 : void merge(
58 : : rtl::Reference< Node > const & original,
59 : : rtl::Reference< Node > const & update)
60 : : {
61 : : assert(
62 : : original.is() && update.is() && original->kind() == update->kind() &&
63 : : update->getFinalized() == Data::NO_LAYER);
64 [ # # # # ]: 0 : if (update->getLayer() >= original->getLayer() &&
[ # # ]
65 : 0 : update->getLayer() <= original->getFinalized())
66 : : {
67 [ # # # # : 0 : switch (original->kind()) {
# ]
68 : : case Node::KIND_PROPERTY:
69 : : case Node::KIND_LOCALIZED_PROPERTY:
70 : : case Node::KIND_LOCALIZED_VALUE:
71 : 0 : break; //TODO: merge certain parts?
72 : : case Node::KIND_GROUP:
73 [ # # ][ # # ]: 0 : for (NodeMap::const_iterator i2(update->getMembers().begin());
74 [ # # ]: 0 : i2 != update->getMembers().end(); ++i2)
75 : : {
76 [ # # ]: 0 : NodeMap & members = original->getMembers();
77 [ # # ]: 0 : NodeMap::iterator i1(members.find(i2->first));
78 [ # # ]: 0 : if (i1 == members.end()) {
79 [ # # ][ # # ]: 0 : if (i2->second->kind() == Node::KIND_PROPERTY &&
[ # # ][ # # ]
80 : : dynamic_cast< GroupNode * >(
81 [ # # ][ # # ]: 0 : original.get())->isExtensible())
82 : : {
83 [ # # ]: 0 : members.insert(*i2);
84 : : }
85 [ # # ][ # # ]: 0 : } else if (i2->second->kind() == i1->second->kind()) {
[ # # ]
86 [ # # ]: 0 : merge(i1->second, i2->second);
87 : : }
88 : : }
89 : 0 : break;
90 : : case Node::KIND_SET:
91 [ # # ][ # # ]: 0 : for (NodeMap::const_iterator i2(update->getMembers().begin());
92 [ # # ]: 0 : i2 != update->getMembers().end(); ++i2)
93 : : {
94 [ # # ]: 0 : NodeMap & members = original->getMembers();
95 [ # # ]: 0 : NodeMap::iterator i1(members.find(i2->first));
96 [ # # ]: 0 : if (i1 == members.end()) {
97 [ # # # # ]: 0 : if (dynamic_cast< SetNode * >(original.get())->
98 [ # # # # ]: 0 : isValidTemplate(i2->second->getTemplateName()))
99 : : {
100 [ # # ]: 0 : members.insert(*i2);
101 : : }
102 [ # # ][ # # ]: 0 : } else if (i2->second->kind() == i1->second->kind() &&
[ # # # # ]
[ # # ]
103 : 0 : (i2->second->getTemplateName() ==
104 [ # # # # ]: 0 : i1->second->getTemplateName()))
[ # # ][ # # ]
[ # # # # ]
105 : : {
106 [ # # ]: 0 : merge(i1->second, i2->second);
107 : : }
108 : : }
109 : 0 : break;
110 : : case Node::KIND_ROOT:
111 : : assert(false); // this cannot happen
112 : 0 : break;
113 : : }
114 : : }
115 : 0 : }
116 : :
117 : : }
118 : :
119 : 33652 : XcsParser::XcsParser(int layer, Data & data):
120 [ + - ][ + - ]: 33652 : valueParser_(layer), data_(data), state_(STATE_START)
[ + - ]
121 : 33652 : {}
122 : :
123 [ + - ][ - + ]: 67304 : XcsParser::~XcsParser() {}
124 : :
125 : 7540612 : xmlreader::XmlReader::Text XcsParser::getTextMode() {
126 : 7540612 : return valueParser_.getTextMode();
127 : : }
128 : :
129 : 3554322 : bool XcsParser::startElement(
130 : : xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
131 : : {
132 [ + + ]: 3554322 : if (valueParser_.startElement(reader, nsId, name)) {
133 : 8100 : return true;
134 : : }
135 [ + + ]: 3546222 : if (state_ == STATE_START) {
136 [ + - + - ]: 67304 : if (nsId == ParseManager::NAMESPACE_OOR &&
[ + - ]
137 : 33652 : name.equals(RTL_CONSTASCII_STRINGPARAM("component-schema"))) {
138 : 33652 : handleComponentSchema(reader);
139 : 33652 : state_ = STATE_COMPONENT_SCHEMA;
140 : 33652 : ignoring_ = 0;
141 : 33652 : return true;
142 : : }
143 : : } else {
144 : : //TODO: ignoring component-schema import, component-schema uses, and
145 : : // prop constraints; accepting all four at illegal places (and with
146 : : // illegal content):
147 [ + + ][ + - : 10928232 : if (ignoring_ > 0 ||
+ + + + +
+ + + ]
[ + + ]
148 : : (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
149 : 2319186 : (name.equals(RTL_CONSTASCII_STRINGPARAM("info")) ||
150 : 1705428 : name.equals(RTL_CONSTASCII_STRINGPARAM("import")) ||
151 : 1698410 : name.equals(RTL_CONSTASCII_STRINGPARAM("uses")) ||
152 : 1692638 : name.equals(RTL_CONSTASCII_STRINGPARAM("constraints")))))
153 : : {
154 : : assert(ignoring_ < LONG_MAX);
155 : 1856666 : ++ignoring_;
156 : 1856666 : return true;
157 : : }
158 [ + + + + : 1655904 : switch (state_) {
- - ]
159 : : case STATE_COMPONENT_SCHEMA:
160 [ + - + + ]: 67304 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
[ + + ]
161 : 33652 : name.equals(RTL_CONSTASCII_STRINGPARAM("templates")))
162 : : {
163 : 30798 : state_ = STATE_TEMPLATES;
164 : 30798 : return true;
165 : : }
166 : : // fall through
167 : : case STATE_TEMPLATES_DONE:
168 [ + - + - ]: 67304 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
[ + - ]
169 : 33652 : name.equals(RTL_CONSTASCII_STRINGPARAM("component")))
170 : : {
171 : 33652 : state_ = STATE_COMPONENT;
172 : : assert(elements_.empty());
173 : : elements_.push(
174 : : Element(
175 : : new GroupNode(
176 [ + - ]: 33652 : valueParser_.getLayer(), false, rtl::OUString()),
177 [ + - ][ + - ]: 67304 : componentName_));
[ + - ][ + - ]
[ + - ][ + - ]
178 : 33652 : return true;
179 : : }
180 : 0 : break;
181 : : case STATE_TEMPLATES:
182 [ + + ]: 378362 : if (elements_.empty()) {
183 [ + - + + ]: 120896 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
[ + + ]
184 : 60448 : name.equals(RTL_CONSTASCII_STRINGPARAM("group")))
185 : : {
186 : 57856 : handleGroup(reader, true);
187 : 57856 : return true;
188 : : }
189 [ + - + - ]: 5184 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
[ + - ]
190 : 2592 : name.equals(RTL_CONSTASCII_STRINGPARAM("set")))
191 : : {
192 : 2592 : handleSet(reader, true);
193 : 2592 : return true;
194 : : }
195 : 0 : break;
196 : : }
197 : : // fall through
198 : : case STATE_COMPONENT:
199 : : assert(!elements_.empty());
200 [ + + - - ]: 1531006 : switch (elements_.top().node->kind()) {
201 : : case Node::KIND_PROPERTY:
202 : : case Node::KIND_LOCALIZED_PROPERTY:
203 [ + - + - ]: 961388 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
[ + - ]
204 : 480694 : name.equals(RTL_CONSTASCII_STRINGPARAM("value")))
205 : : {
206 : 480694 : handlePropValue(reader, elements_.top().node);
207 : 480694 : return true;
208 : : }
209 : 0 : break;
210 : : case Node::KIND_GROUP:
211 [ + - + + ]: 2100624 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
[ + + ]
212 : 1050312 : name.equals(RTL_CONSTASCII_STRINGPARAM("prop")))
213 : : {
214 : 779748 : handleProp(reader);
215 : 779748 : return true;
216 : : }
217 [ + - + + ]: 541128 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
[ + + ]
218 : 270564 : name.equals(RTL_CONSTASCII_STRINGPARAM("node-ref")))
219 : : {
220 : 12558 : handleNodeRef(reader);
221 : 12558 : return true;
222 : : }
223 [ + - + + ]: 516012 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
[ + + ]
224 : 258006 : name.equals(RTL_CONSTASCII_STRINGPARAM("group")))
225 : : {
226 : 185174 : handleGroup(reader, false);
227 : 185174 : return true;
228 : : }
229 [ + - + - ]: 145664 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
[ + - ]
230 : 72832 : name.equals(RTL_CONSTASCII_STRINGPARAM("set")))
231 : : {
232 : 72832 : handleSet(reader, false);
233 : 72832 : return true;
234 : : }
235 : 0 : break;
236 : : case Node::KIND_SET:
237 [ # # # # ]: 0 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
[ # # ]
238 : 0 : name.equals(RTL_CONSTASCII_STRINGPARAM("item")))
239 : : {
240 : : handleSetItem(
241 : : reader,
242 [ # # ]: 0 : dynamic_cast< SetNode * >(elements_.top().node.get()));
243 : 0 : return true;
244 : : }
245 : 0 : break;
246 : : default: // Node::KIND_LOCALIZED_VALUE
247 : : assert(false); // this cannot happen
248 : 0 : break;
249 : : }
250 : 0 : break;
251 : : case STATE_COMPONENT_DONE:
252 : 0 : break;
253 : : default: // STATE_START
254 : : assert(false); // this cannot happen
255 : 0 : break;
256 : : }
257 : : }
258 : : throw css::uno::RuntimeException(
259 : : (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad member <")) +
260 : : name.convertFromUtf8() +
261 : : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + reader.getUrl()),
262 [ # # ][ # # ]: 3554322 : css::uno::Reference< css::uno::XInterface >());
[ # # ][ # # ]
[ # # ]
263 : : }
264 : :
265 : 3554322 : void XcsParser::endElement(xmlreader::XmlReader const & reader) {
266 [ + + ]: 3554322 : if (valueParser_.endElement()) {
267 : 3554322 : return;
268 : : }
269 [ + + ]: 3065528 : if (ignoring_ > 0) {
270 : 1856666 : --ignoring_;
271 [ + + ]: 1208862 : } else if (!elements_.empty()) {
272 [ + - ][ + - ]: 1144412 : Element top(elements_.top());
273 [ + - ]: 1144412 : elements_.pop();
274 [ + - ]: 1144412 : if (top.node.is()) {
275 [ + + ]: 1144412 : if (elements_.empty()) {
276 [ + + - ]: 94100 : switch (state_) {
277 : : case STATE_TEMPLATES:
278 : : {
279 [ + - ]: 60448 : NodeMap::iterator i(data_.templates.find(top.name));
280 [ + - ]: 60448 : if (i == data_.templates.end()) {
281 : : data_.templates.insert(
282 [ + - ][ + - ]: 60448 : NodeMap::value_type(top.name, top.node));
[ + - ]
283 : : } else {
284 [ # # ]: 0 : merge(i->second, top.node);
285 : : }
286 : : }
287 : 60448 : break;
288 : : case STATE_COMPONENT:
289 : : {
290 [ + - ]: 33652 : NodeMap & components = data_.getComponents();
291 [ + - ]: 33652 : NodeMap::iterator i(components.find(top.name));
292 [ + - ]: 33652 : if (i == components.end()) {
293 : : components.insert(
294 [ + - ][ + - ]: 33652 : NodeMap::value_type(top.name, top.node));
[ + - ]
295 : : } else {
296 [ # # ]: 0 : merge(i->second, top.node);
297 : : }
298 : 33652 : state_ = STATE_COMPONENT_DONE;
299 : : }
300 : 33652 : break;
301 : : default:
302 : : assert(false);
303 : : throw css::uno::RuntimeException(
304 : : rtl::OUString(
305 : : RTL_CONSTASCII_USTRINGPARAM("this cannot happen")),
306 [ # # ][ # # ]: 94100 : css::uno::Reference< css::uno::XInterface >());
307 : : }
308 : : } else {
309 [ + - ][ + - ]: 2100624 : if (!elements_.top().node->getMembers().insert(
[ - + ]
310 [ + - ][ + - ]: 2100624 : NodeMap::value_type(top.name, top.node)).second)
[ + - ]
311 : : {
312 : : throw css::uno::RuntimeException(
313 : : (rtl::OUString(
314 : : RTL_CONSTASCII_USTRINGPARAM("duplicate ")) +
315 : : top.name +
316 : : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
317 : : reader.getUrl()),
318 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ][ # # ]
319 : : }
320 : : }
321 [ + - ]: 1144412 : }
322 : : } else {
323 [ - + - + : 64450 : switch (state_) {
- ]
324 : : case STATE_COMPONENT_SCHEMA:
325 : : // To support old, broken extensions with .xcs files that contain
326 : : // empty <component-schema> elements:
327 : 0 : state_ = STATE_COMPONENT_DONE;
328 : 0 : break;
329 : : case STATE_TEMPLATES:
330 : 30798 : state_ = STATE_TEMPLATES_DONE;
331 : 30798 : break;
332 : : case STATE_TEMPLATES_DONE:
333 : : throw css::uno::RuntimeException(
334 : : (rtl::OUString(
335 : : RTL_CONSTASCII_USTRINGPARAM("no component element in ")) +
336 : : reader.getUrl()),
337 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
338 : : case STATE_COMPONENT_DONE:
339 : 33652 : break;
340 : : default:
341 : : assert(false); // this cannot happen
342 : : }
343 : : }
344 : : }
345 : :
346 : 429676 : void XcsParser::characters(xmlreader::Span const & text) {
347 : 429676 : valueParser_.characters(text);
348 : 429676 : }
349 : :
350 : 33652 : void XcsParser::handleComponentSchema(xmlreader::XmlReader & reader) {
351 : : //TODO: oor:version, xml:lang attributes
352 : 33652 : rtl::OStringBuffer buf;
353 [ + - ]: 33652 : buf.append('.');
354 : 33652 : bool hasPackage = false;
355 : 33652 : bool hasName = false;
356 : 100956 : for (;;) {
357 : : int attrNsId;
358 : 134608 : xmlreader::Span attrLn;
359 [ + + ][ + - ]: 134608 : if (!reader.nextAttribute(&attrNsId, &attrLn)) {
360 : : break;
361 : : }
362 [ + + + + ]: 168260 : if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + + ]
363 : 67304 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("package")))
364 : : {
365 [ - + ]: 33652 : if (hasPackage) {
366 : : throw css::uno::RuntimeException(
367 : : (rtl::OUString(
368 : : RTL_CONSTASCII_USTRINGPARAM(
369 : : "multiple component-schema package attributes"
370 : : " in ")) +
371 : : reader.getUrl()),
372 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
373 : : }
374 : 33652 : hasPackage = true;
375 [ + - ]: 33652 : xmlreader::Span s(reader.getAttributeValue(false));
376 [ + - ]: 33652 : buf.insert(0, s.begin, s.length);
377 [ + + + - ]: 100956 : } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + + ]
378 : 33652 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
379 : : {
380 [ - + ]: 33652 : if (hasName) {
381 : : throw css::uno::RuntimeException(
382 : : (rtl::OUString(
383 : : RTL_CONSTASCII_USTRINGPARAM(
384 : : "multiple component-schema name attributes in ")) +
385 : : reader.getUrl()),
386 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
387 : : }
388 : 33652 : hasName = true;
389 [ + - ]: 33652 : xmlreader::Span s(reader.getAttributeValue(false));
390 [ + - ]: 33652 : buf.append(s.begin, s.length);
391 : : }
392 : : }
393 [ - + ]: 33652 : if (!hasPackage) {
394 : : throw css::uno::RuntimeException(
395 : : (rtl::OUString(
396 : : RTL_CONSTASCII_USTRINGPARAM(
397 : : "no component-schema package attribute in ")) +
398 : : reader.getUrl()),
399 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
400 : : }
401 [ - + ]: 33652 : if (!hasName) {
402 : : throw css::uno::RuntimeException(
403 : : (rtl::OUString(
404 : : RTL_CONSTASCII_USTRINGPARAM(
405 : : "no component-schema name attribute in ")) +
406 : : reader.getUrl()),
407 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
408 : : }
409 : : componentName_ = xmlreader::Span(buf.getStr(), buf.getLength()).
410 [ + - ]: 33652 : convertFromUtf8();
411 : 33652 : }
412 : :
413 : 12558 : void XcsParser::handleNodeRef(xmlreader::XmlReader & reader) {
414 : 12558 : bool hasName = false;
415 : 12558 : rtl::OUString name;
416 : 12558 : rtl::OUString component(componentName_);
417 : 12558 : bool hasNodeType = false;
418 : 12558 : rtl::OUString nodeType;
419 : 25116 : for (;;) {
420 : : int attrNsId;
421 : 37674 : xmlreader::Span attrLn;
422 [ + + ][ + - ]: 37674 : if (!reader.nextAttribute(&attrNsId, &attrLn)) {
423 : : break;
424 : : }
425 [ + - + + ]: 50232 : if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + + ]
426 : 25116 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
427 : : {
428 : 12558 : hasName = true;
429 [ + - ][ + - ]: 12558 : name = reader.getAttributeValue(false).convertFromUtf8();
430 [ + - - + ]: 25116 : } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ - + ]
431 : 12558 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
432 : : {
433 [ # # ][ # # ]: 0 : component = reader.getAttributeValue(false).convertFromUtf8();
434 [ + - + - ]: 25116 : } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + - ]
435 : 12558 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
436 : : {
437 : 12558 : hasNodeType = true;
438 [ + - ][ + - ]: 12558 : nodeType = reader.getAttributeValue(false).convertFromUtf8();
439 : : }
440 : : }
441 [ - + ]: 12558 : if (!hasName) {
442 : : throw css::uno::RuntimeException(
443 : : (rtl::OUString(
444 : : RTL_CONSTASCII_USTRINGPARAM("no node-ref name attribute in ")) +
445 : : reader.getUrl()),
446 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
447 : : }
448 : : rtl::Reference< Node > tmpl(
449 : : data_.getTemplate(
450 : : valueParser_.getLayer(),
451 : : xmldata::parseTemplateReference(
452 [ + - ][ + - ]: 12558 : component, hasNodeType, nodeType, 0)));
[ + - ]
453 [ - + ]: 12558 : if (!tmpl.is()) {
454 : : //TODO: this can erroneously happen as long as import/uses attributes
455 : : // are not correctly processed
456 : : throw css::uno::RuntimeException(
457 : : (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown node-ref ")) +
458 : : name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
459 : : reader.getUrl()),
460 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ][ # # ]
461 : : }
462 [ + - ]: 12558 : rtl::Reference< Node > node(tmpl->clone(false));
463 [ + - ][ + - ]: 12558 : node->setLayer(valueParser_.getLayer());
464 [ + - ][ + - ]: 12558 : elements_.push(Element(node, name));
[ + - ][ + - ]
[ + - ]
465 : 12558 : }
466 : :
467 : 779748 : void XcsParser::handleProp(xmlreader::XmlReader & reader) {
468 : 779748 : bool hasName = false;
469 : 779748 : rtl::OUString name;
470 : 779748 : valueParser_.type_ = TYPE_ERROR;
471 : 779748 : bool localized = false;
472 : 779748 : bool nillable = true;
473 : 2064946 : for (;;) {
474 : : int attrNsId;
475 : 2844694 : xmlreader::Span attrLn;
476 [ + + ][ + - ]: 2844694 : if (!reader.nextAttribute(&attrNsId, &attrLn)) {
477 : : break;
478 : : }
479 [ + - + + ]: 4129892 : if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + + ]
480 : 2064946 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
481 : : {
482 : 779748 : hasName = true;
483 [ + - ][ + - ]: 779748 : name = reader.getAttributeValue(false).convertFromUtf8();
484 [ + - + + ]: 2570396 : } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + + ]
485 : 1285198 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
486 : : {
487 : : valueParser_.type_ = xmldata::parseType(
488 [ + - ][ + - ]: 779748 : reader, reader.getAttributeValue(true));
489 [ + - + + ]: 1010900 : } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + + ]
490 : 505450 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("localized")))
491 : : {
492 [ + - ][ + - ]: 60274 : localized = xmldata::parseBoolean(reader.getAttributeValue(true));
493 [ + - + - ]: 890352 : } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + - ]
494 : 445176 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nillable")))
495 : : {
496 [ + - ][ + - ]: 445176 : nillable = xmldata::parseBoolean(reader.getAttributeValue(true));
497 : : }
498 : : }
499 [ - + ]: 779748 : if (!hasName) {
500 : : throw css::uno::RuntimeException(
501 : : (rtl::OUString(
502 : : RTL_CONSTASCII_USTRINGPARAM("no prop name attribute in ")) +
503 : : reader.getUrl()),
504 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
505 : : }
506 [ - + ]: 779748 : if (valueParser_.type_ == TYPE_ERROR) {
507 : : throw css::uno::RuntimeException(
508 : : (rtl::OUString(
509 : : RTL_CONSTASCII_USTRINGPARAM("no prop type attribute in ")) +
510 : : reader.getUrl()),
511 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
512 : : }
513 : : elements_.push(
514 : : Element(
515 : : (localized
516 : : ? rtl::Reference< Node >(
517 : : new LocalizedPropertyNode(
518 [ + - ]: 59302 : valueParser_.getLayer(), valueParser_.type_, nillable))
519 : : : rtl::Reference< Node >(
520 : : new PropertyNode(
521 : 720446 : valueParser_.getLayer(), valueParser_.type_, nillable,
522 [ + - ]: 720446 : css::uno::Any(), false))),
523 [ + + ][ + - ]: 1559496 : name));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ # # ]
524 : 779748 : }
525 : :
526 : 480694 : void XcsParser::handlePropValue(
527 : : xmlreader::XmlReader & reader, rtl::Reference< Node > const & property)
528 : : {
529 : 480694 : xmlreader::Span attrSeparator;
530 : 2268 : for (;;) {
531 : : int attrNsId;
532 : 482962 : xmlreader::Span attrLn;
533 [ + + ][ + - ]: 482962 : if (!reader.nextAttribute(&attrNsId, &attrLn)) {
534 : : break;
535 : : }
536 [ + - + - ]: 4536 : if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + - ]
537 : 2268 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator")))
538 : : {
539 [ + - ]: 2268 : attrSeparator = reader.getAttributeValue(false);
540 [ - + ]: 2268 : if (attrSeparator.length == 0) {
541 : : throw css::uno::RuntimeException(
542 : : (rtl::OUString(
543 : : RTL_CONSTASCII_USTRINGPARAM(
544 : : "bad oor:separator attribute in ")) +
545 : : reader.getUrl()),
546 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
547 : : }
548 : : }
549 : : }
550 : : valueParser_.separator_ = rtl::OString(
551 : 480694 : attrSeparator.begin, attrSeparator.length);
552 [ + - ]: 480694 : valueParser_.start(property);
553 : 480694 : }
554 : :
555 : 243030 : void XcsParser::handleGroup(xmlreader::XmlReader & reader, bool isTemplate) {
556 : 243030 : bool hasName = false;
557 : 243030 : rtl::OUString name;
558 : 243030 : bool extensible = false;
559 : 250744 : for (;;) {
560 : : int attrNsId;
561 : 493774 : xmlreader::Span attrLn;
562 [ + + ][ + - ]: 493774 : if (!reader.nextAttribute(&attrNsId, &attrLn)) {
563 : : break;
564 : : }
565 [ + - + + ]: 501488 : if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + + ]
566 : 250744 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
567 : : {
568 : 243030 : hasName = true;
569 [ + - ][ + - ]: 243030 : name = reader.getAttributeValue(false).convertFromUtf8();
570 [ + - + + ]: 15428 : } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + + ]
571 : 7714 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("extensible")))
572 : : {
573 [ + - ][ + - ]: 7390 : extensible = xmldata::parseBoolean(reader.getAttributeValue(true));
574 : : }
575 : : }
576 [ - + ]: 243030 : if (!hasName) {
577 : : throw css::uno::RuntimeException(
578 : : (rtl::OUString(
579 : : RTL_CONSTASCII_USTRINGPARAM("no group name attribute in ")) +
580 : : reader.getUrl()),
581 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
582 : : }
583 [ + + ]: 243030 : if (isTemplate) {
584 [ + - ]: 57856 : name = Data::fullTemplateName(componentName_, name);
585 : : }
586 : : elements_.push(
587 : : Element(
588 : : new GroupNode(
589 : 243030 : valueParser_.getLayer(), extensible,
590 [ + - ]: 243030 : isTemplate ? name : rtl::OUString()),
591 [ + - ][ + + ]: 486060 : name));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
592 : 243030 : }
593 : :
594 : 75424 : void XcsParser::handleSet(xmlreader::XmlReader & reader, bool isTemplate) {
595 : 75424 : bool hasName = false;
596 : 75424 : rtl::OUString name;
597 : 75424 : rtl::OUString component(componentName_);
598 : 75424 : bool hasNodeType = false;
599 : 75424 : rtl::OUString nodeType;
600 : 164918 : for (;;) {
601 : : int attrNsId;
602 : 240342 : xmlreader::Span attrLn;
603 [ + + ][ + - ]: 240342 : if (!reader.nextAttribute(&attrNsId, &attrLn)) {
604 : : break;
605 : : }
606 [ + - + + ]: 329836 : if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + + ]
607 : 164918 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
608 : : {
609 : 75424 : hasName = true;
610 [ + - ][ + - ]: 75424 : name = reader.getAttributeValue(false).convertFromUtf8();
611 [ + - + + ]: 178988 : } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + + ]
612 : 89494 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
613 : : {
614 [ + - ][ + - ]: 14070 : component = reader.getAttributeValue(false).convertFromUtf8();
615 [ + - + - ]: 150848 : } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ + - ]
616 : 75424 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
617 : : {
618 : 75424 : hasNodeType = true;
619 [ + - ][ + - ]: 75424 : nodeType = reader.getAttributeValue(false).convertFromUtf8();
620 : : }
621 : : }
622 [ - + ]: 75424 : if (!hasName) {
623 : : throw css::uno::RuntimeException(
624 : : (rtl::OUString(
625 : : RTL_CONSTASCII_USTRINGPARAM("no set name attribute in ")) +
626 : : reader.getUrl()),
627 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
628 : : }
629 [ + + ]: 75424 : if (isTemplate) {
630 [ + - ]: 2592 : name = Data::fullTemplateName(componentName_, name);
631 : : }
632 : : elements_.push(
633 : : Element(
634 : : new SetNode(
635 : 75424 : valueParser_.getLayer(),
636 : : xmldata::parseTemplateReference(
637 : : component, hasNodeType, nodeType, 0),
638 [ + - ]: 75424 : isTemplate ? name : rtl::OUString()),
639 [ + - ][ + - ]: 150848 : name));
[ + + ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
640 : 75424 : }
641 : :
642 : 0 : void XcsParser::handleSetItem(xmlreader::XmlReader & reader, SetNode * set) {
643 : 0 : rtl::OUString component(componentName_);
644 : 0 : bool hasNodeType = false;
645 : 0 : rtl::OUString nodeType;
646 : 0 : for (;;) {
647 : : int attrNsId;
648 : 0 : xmlreader::Span attrLn;
649 [ # # ][ # # ]: 0 : if (!reader.nextAttribute(&attrNsId, &attrLn)) {
650 : : break;
651 : : }
652 [ # # # # ]: 0 : if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ # # ]
653 : 0 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
654 : : {
655 [ # # ][ # # ]: 0 : component = reader.getAttributeValue(false).convertFromUtf8();
656 [ # # # # ]: 0 : } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
[ # # ]
657 : 0 : attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
658 : : {
659 : 0 : hasNodeType = true;
660 [ # # ][ # # ]: 0 : nodeType = reader.getAttributeValue(false).convertFromUtf8();
661 : : }
662 : : }
663 [ # # ]: 0 : set->getAdditionalTemplateNames().push_back(
664 [ # # ][ # # ]: 0 : xmldata::parseTemplateReference(component, hasNodeType, nodeType, 0));
665 [ # # ][ # # ]: 0 : elements_.push(Element(rtl::Reference< Node >(), rtl::OUString()));
[ # # ][ # # ]
666 : 0 : }
667 : :
668 : : }
669 : :
670 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|