LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/configmgr/source - xcsparser.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 236 351 67.2 %
Date: 2013-07-09 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.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: */

Generated by: LCOV version 1.10