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