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