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