LCOV - code coverage report
Current view: top level - libreoffice/configmgr/source - xcsparser.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 234 334 70.1 %
Date: 2012-12-27 Functions: 13 15 86.7 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.10