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