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 <algorithm> 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 "localizedvaluenode.hxx" 46cdf0e10cSrcweir #include "groupnode.hxx" 47cdf0e10cSrcweir #include "modifications.hxx" 48cdf0e10cSrcweir #include "node.hxx" 49cdf0e10cSrcweir #include "nodemap.hxx" 50cdf0e10cSrcweir #include "parsemanager.hxx" 51cdf0e10cSrcweir #include "partial.hxx" 52cdf0e10cSrcweir #include "path.hxx" 53cdf0e10cSrcweir #include "propertynode.hxx" 54cdf0e10cSrcweir #include "setnode.hxx" 55cdf0e10cSrcweir #include "xcuparser.hxx" 56cdf0e10cSrcweir #include "xmldata.hxx" 57cdf0e10cSrcweir 58cdf0e10cSrcweir namespace configmgr { 59cdf0e10cSrcweir 60cdf0e10cSrcweir namespace { 61cdf0e10cSrcweir 62cdf0e10cSrcweir namespace css = com::sun::star; 63cdf0e10cSrcweir 64cdf0e10cSrcweir } 65cdf0e10cSrcweir 66cdf0e10cSrcweir XcuParser::XcuParser( 67cdf0e10cSrcweir int layer, Data & data, Partial const * partial, 68cdf0e10cSrcweir Modifications * broadcastModifications, Additions * additions): 69cdf0e10cSrcweir valueParser_(layer), data_(data), 70cdf0e10cSrcweir partial_(partial), broadcastModifications_(broadcastModifications), 71cdf0e10cSrcweir additions_(additions), recordModifications_(layer == Data::NO_LAYER), 72cdf0e10cSrcweir trackPath_( 73cdf0e10cSrcweir partial_ != 0 || broadcastModifications_ != 0 || additions_ != 0 || 74cdf0e10cSrcweir recordModifications_) 75cdf0e10cSrcweir {} 76cdf0e10cSrcweir 77cdf0e10cSrcweir XcuParser::~XcuParser() {} 78cdf0e10cSrcweir 79cdf0e10cSrcweir xmlreader::XmlReader::Text XcuParser::getTextMode() { 80cdf0e10cSrcweir return valueParser_.getTextMode(); 81cdf0e10cSrcweir } 82cdf0e10cSrcweir 83cdf0e10cSrcweir bool XcuParser::startElement( 84cdf0e10cSrcweir xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name) 85cdf0e10cSrcweir { 86cdf0e10cSrcweir if (valueParser_.startElement(reader, nsId, name)) { 87cdf0e10cSrcweir return true; 88cdf0e10cSrcweir } 89cdf0e10cSrcweir if (state_.empty()) { 90cdf0e10cSrcweir if (nsId == ParseManager::NAMESPACE_OOR && 91cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("component-data"))) 92cdf0e10cSrcweir { 93cdf0e10cSrcweir handleComponentData(reader); 94cdf0e10cSrcweir } else if (nsId == ParseManager::NAMESPACE_OOR && 95cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("items"))) 96cdf0e10cSrcweir { 97cdf0e10cSrcweir state_.push(State(rtl::Reference< Node >(), false)); 98cdf0e10cSrcweir } else { 99cdf0e10cSrcweir throw css::uno::RuntimeException( 100cdf0e10cSrcweir (rtl::OUString( 101cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("bad root element <")) + 102cdf0e10cSrcweir name.convertFromUtf8() + 103cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + 104cdf0e10cSrcweir reader.getUrl()), 105cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 106cdf0e10cSrcweir } 107cdf0e10cSrcweir } else if (state_.top().ignore) { 108cdf0e10cSrcweir state_.push(State(false)); 109cdf0e10cSrcweir } else if (!state_.top().node.is()) { 110cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 111cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("item"))) 112cdf0e10cSrcweir { 113cdf0e10cSrcweir handleItem(reader); 114cdf0e10cSrcweir } else { 115cdf0e10cSrcweir throw css::uno::RuntimeException( 116cdf0e10cSrcweir (rtl::OUString( 117cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("bad items node member <")) + 118cdf0e10cSrcweir name.convertFromUtf8() + 119cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + 120cdf0e10cSrcweir reader.getUrl()), 121cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 122cdf0e10cSrcweir } 123cdf0e10cSrcweir } else { 124cdf0e10cSrcweir switch (state_.top().node->kind()) { 125cdf0e10cSrcweir case Node::KIND_PROPERTY: 126cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 127cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("value"))) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir handlePropValue( 130cdf0e10cSrcweir reader, 131cdf0e10cSrcweir dynamic_cast< PropertyNode * >(state_.top().node.get())); 132cdf0e10cSrcweir } else { 133cdf0e10cSrcweir throw css::uno::RuntimeException( 134cdf0e10cSrcweir (rtl::OUString( 135cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 136cdf0e10cSrcweir "bad property node member <")) + 137cdf0e10cSrcweir name.convertFromUtf8() + 138cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + 139cdf0e10cSrcweir reader.getUrl()), 140cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir break; 143cdf0e10cSrcweir case Node::KIND_LOCALIZED_PROPERTY: 144cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 145cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("value"))) 146cdf0e10cSrcweir { 147cdf0e10cSrcweir handleLocpropValue( 148cdf0e10cSrcweir reader, 149cdf0e10cSrcweir dynamic_cast< LocalizedPropertyNode * >( 150cdf0e10cSrcweir state_.top().node.get())); 151cdf0e10cSrcweir } else { 152cdf0e10cSrcweir throw css::uno::RuntimeException( 153cdf0e10cSrcweir (rtl::OUString( 154cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 155cdf0e10cSrcweir "bad localized property node member <")) + 156cdf0e10cSrcweir name.convertFromUtf8() + 157cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + 158cdf0e10cSrcweir reader.getUrl()), 159cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 160cdf0e10cSrcweir } 161cdf0e10cSrcweir break; 162cdf0e10cSrcweir case Node::KIND_LOCALIZED_VALUE: 163cdf0e10cSrcweir throw css::uno::RuntimeException( 164cdf0e10cSrcweir (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad member <")) + 165cdf0e10cSrcweir name.convertFromUtf8() + 166cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + 167cdf0e10cSrcweir reader.getUrl()), 168cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 169cdf0e10cSrcweir case Node::KIND_GROUP: 170cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 171cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("prop"))) 172cdf0e10cSrcweir { 173cdf0e10cSrcweir handleGroupProp( 174cdf0e10cSrcweir reader, 175cdf0e10cSrcweir dynamic_cast< GroupNode * >(state_.top().node.get())); 176cdf0e10cSrcweir } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 177cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("node"))) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir handleGroupNode(reader, state_.top().node); 180cdf0e10cSrcweir } else { 181cdf0e10cSrcweir throw css::uno::RuntimeException( 182cdf0e10cSrcweir (rtl::OUString( 183cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 184cdf0e10cSrcweir "bad group node member <")) + 185cdf0e10cSrcweir name.convertFromUtf8() + 186cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + 187cdf0e10cSrcweir reader.getUrl()), 188cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 189cdf0e10cSrcweir } 190cdf0e10cSrcweir break; 191cdf0e10cSrcweir case Node::KIND_SET: 192cdf0e10cSrcweir if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 193cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("node"))) 194cdf0e10cSrcweir { 195cdf0e10cSrcweir handleSetNode( 196cdf0e10cSrcweir reader, dynamic_cast< SetNode * >(state_.top().node.get())); 197cdf0e10cSrcweir } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 198cdf0e10cSrcweir name.equals(RTL_CONSTASCII_STRINGPARAM("prop"))) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir OSL_TRACE( 201cdf0e10cSrcweir "configmgr bad set node <prop> member in %s", 202cdf0e10cSrcweir rtl::OUStringToOString( 203cdf0e10cSrcweir reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr()); 204cdf0e10cSrcweir state_.push(State(true)); // ignored 205cdf0e10cSrcweir } else { 206cdf0e10cSrcweir throw css::uno::RuntimeException( 207cdf0e10cSrcweir (rtl::OUString( 208cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("bad set node member <")) + 209cdf0e10cSrcweir name.convertFromUtf8() + 210cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) + 211cdf0e10cSrcweir reader.getUrl()), 212cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 213cdf0e10cSrcweir } 214cdf0e10cSrcweir break; 215cdf0e10cSrcweir } 216cdf0e10cSrcweir } 217cdf0e10cSrcweir return true; 218cdf0e10cSrcweir } 219cdf0e10cSrcweir 220cdf0e10cSrcweir void XcuParser::endElement(xmlreader::XmlReader const &) { 221cdf0e10cSrcweir if (valueParser_.endElement()) { 222cdf0e10cSrcweir return; 223cdf0e10cSrcweir } 224cdf0e10cSrcweir OSL_ASSERT(!state_.empty()); 225cdf0e10cSrcweir bool pop = state_.top().pop; 226cdf0e10cSrcweir rtl::Reference< Node > insert; 227cdf0e10cSrcweir rtl::OUString name; 228cdf0e10cSrcweir if (state_.top().insert) { 229cdf0e10cSrcweir insert = state_.top().node; 230cdf0e10cSrcweir OSL_ASSERT(insert.is()); 231cdf0e10cSrcweir name = state_.top().name; 232cdf0e10cSrcweir } 233cdf0e10cSrcweir state_.pop(); 234cdf0e10cSrcweir if (insert.is()) { 235cdf0e10cSrcweir OSL_ASSERT(!state_.empty() && state_.top().node.is()); 236cdf0e10cSrcweir state_.top().node->getMembers()[name] = insert; 237cdf0e10cSrcweir } 238cdf0e10cSrcweir if (pop && !path_.empty()) { 239cdf0e10cSrcweir path_.pop_back(); 240cdf0e10cSrcweir // </item> will pop less than <item> pushed, but that is harmless, 241cdf0e10cSrcweir // as the next <item> will reset path_ 242cdf0e10cSrcweir } 243cdf0e10cSrcweir } 244cdf0e10cSrcweir 245cdf0e10cSrcweir void XcuParser::characters(xmlreader::Span const & text) { 246cdf0e10cSrcweir valueParser_.characters(text); 247cdf0e10cSrcweir } 248cdf0e10cSrcweir 249cdf0e10cSrcweir XcuParser::Operation XcuParser::parseOperation(xmlreader::Span const & text) { 250cdf0e10cSrcweir OSL_ASSERT(text.is()); 251cdf0e10cSrcweir if (text.equals(RTL_CONSTASCII_STRINGPARAM("modify"))) { 252cdf0e10cSrcweir return OPERATION_MODIFY; 253cdf0e10cSrcweir } 254cdf0e10cSrcweir if (text.equals(RTL_CONSTASCII_STRINGPARAM("replace"))) { 255cdf0e10cSrcweir return OPERATION_REPLACE; 256cdf0e10cSrcweir } 257cdf0e10cSrcweir if (text.equals(RTL_CONSTASCII_STRINGPARAM("fuse"))) { 258cdf0e10cSrcweir return OPERATION_FUSE; 259cdf0e10cSrcweir } 260cdf0e10cSrcweir if (text.equals(RTL_CONSTASCII_STRINGPARAM("remove"))) { 261cdf0e10cSrcweir return OPERATION_REMOVE; 262cdf0e10cSrcweir } 263cdf0e10cSrcweir throw css::uno::RuntimeException( 264cdf0e10cSrcweir (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("invalid op ")) + 265cdf0e10cSrcweir text.convertFromUtf8()), 266cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 267cdf0e10cSrcweir } 268cdf0e10cSrcweir 269cdf0e10cSrcweir void XcuParser::handleComponentData(xmlreader::XmlReader & reader) { 270cdf0e10cSrcweir rtl::OStringBuffer buf; 271cdf0e10cSrcweir buf.append('.'); 272cdf0e10cSrcweir bool hasPackage = false; 273cdf0e10cSrcweir bool hasName = false; 274cdf0e10cSrcweir Operation op = OPERATION_MODIFY; 275cdf0e10cSrcweir bool finalized = false; 276cdf0e10cSrcweir for (;;) { 277cdf0e10cSrcweir int attrNsId; 278cdf0e10cSrcweir xmlreader::Span attrLn; 279cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) { 280cdf0e10cSrcweir break; 281cdf0e10cSrcweir } 282cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR && 283cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("package"))) 284cdf0e10cSrcweir { 285cdf0e10cSrcweir if (hasPackage) { 286cdf0e10cSrcweir throw css::uno::RuntimeException( 287cdf0e10cSrcweir (rtl::OUString( 288cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 289cdf0e10cSrcweir "multiple component-update package attributes" 290cdf0e10cSrcweir " in ")) + 291cdf0e10cSrcweir reader.getUrl()), 292cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 293cdf0e10cSrcweir } 294cdf0e10cSrcweir hasPackage = true; 295cdf0e10cSrcweir xmlreader::Span s(reader.getAttributeValue(false)); 296cdf0e10cSrcweir buf.insert(0, s.begin, s.length); 297cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 298cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name"))) 299cdf0e10cSrcweir { 300cdf0e10cSrcweir if (hasName) { 301cdf0e10cSrcweir throw css::uno::RuntimeException( 302cdf0e10cSrcweir (rtl::OUString( 303cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 304cdf0e10cSrcweir "multiple component-update name attributes in ")) + 305cdf0e10cSrcweir reader.getUrl()), 306cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 307cdf0e10cSrcweir } 308cdf0e10cSrcweir hasName = true; 309cdf0e10cSrcweir xmlreader::Span s(reader.getAttributeValue(false)); 310cdf0e10cSrcweir buf.append(s.begin, s.length); 311cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 312cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op"))) 313cdf0e10cSrcweir { 314cdf0e10cSrcweir op = parseOperation(reader.getAttributeValue(true)); 315cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 316cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized"))) 317cdf0e10cSrcweir { 318cdf0e10cSrcweir finalized = xmldata::parseBoolean(reader.getAttributeValue(true)); 319cdf0e10cSrcweir } 320cdf0e10cSrcweir } 321cdf0e10cSrcweir if (!hasPackage) { 322cdf0e10cSrcweir throw css::uno::RuntimeException( 323cdf0e10cSrcweir (rtl::OUString( 324cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 325cdf0e10cSrcweir "no component-data package attribute in ")) + 326cdf0e10cSrcweir reader.getUrl()), 327cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 328cdf0e10cSrcweir } 329cdf0e10cSrcweir if (!hasName) { 330cdf0e10cSrcweir throw css::uno::RuntimeException( 331cdf0e10cSrcweir (rtl::OUString( 332cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 333cdf0e10cSrcweir "no component-data name attribute in ")) + 334cdf0e10cSrcweir reader.getUrl()), 335cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 336cdf0e10cSrcweir } 337cdf0e10cSrcweir componentName_ = xmlreader::Span(buf.getStr(), buf.getLength()). 338cdf0e10cSrcweir convertFromUtf8(); 339cdf0e10cSrcweir if (trackPath_) { 340cdf0e10cSrcweir OSL_ASSERT(path_.empty()); 341cdf0e10cSrcweir path_.push_back(componentName_); 342cdf0e10cSrcweir if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT) 343cdf0e10cSrcweir { 344cdf0e10cSrcweir state_.push(State(true)); // ignored 345cdf0e10cSrcweir return; 346cdf0e10cSrcweir } 347cdf0e10cSrcweir } 348cdf0e10cSrcweir rtl::Reference< Node > node( 349cdf0e10cSrcweir Data::findNode( 350cdf0e10cSrcweir valueParser_.getLayer(), data_.components, componentName_)); 351cdf0e10cSrcweir if (!node.is()) { 352cdf0e10cSrcweir OSL_TRACE( 353cdf0e10cSrcweir "configmgr unknown component %s in %s", 354cdf0e10cSrcweir rtl::OUStringToOString( 355cdf0e10cSrcweir componentName_, RTL_TEXTENCODING_UTF8).getStr(), 356cdf0e10cSrcweir rtl::OUStringToOString( 357cdf0e10cSrcweir reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr()); 358cdf0e10cSrcweir state_.push(State(true)); // ignored 359cdf0e10cSrcweir return; 360cdf0e10cSrcweir } 361cdf0e10cSrcweir switch (op) { 362cdf0e10cSrcweir case OPERATION_MODIFY: 363cdf0e10cSrcweir case OPERATION_FUSE: 364cdf0e10cSrcweir break; 365cdf0e10cSrcweir default: 366cdf0e10cSrcweir throw css::uno::RuntimeException( 367cdf0e10cSrcweir (rtl::OUString( 368cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 369cdf0e10cSrcweir "invalid operation on root node in ")) + 370cdf0e10cSrcweir reader.getUrl()), 371cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 372cdf0e10cSrcweir } 373cdf0e10cSrcweir int finalizedLayer = std::min( 374cdf0e10cSrcweir finalized ? valueParser_.getLayer() : Data::NO_LAYER, 375cdf0e10cSrcweir node->getFinalized()); 376cdf0e10cSrcweir node->setFinalized(finalizedLayer); 377cdf0e10cSrcweir state_.push(State(node, finalizedLayer < valueParser_.getLayer())); 378cdf0e10cSrcweir } 379cdf0e10cSrcweir 380cdf0e10cSrcweir void XcuParser::handleItem(xmlreader::XmlReader & reader) { 381cdf0e10cSrcweir xmlreader::Span attrPath; 382cdf0e10cSrcweir for (;;) { 383cdf0e10cSrcweir int attrNsId; 384cdf0e10cSrcweir xmlreader::Span attrLn; 385cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) { 386cdf0e10cSrcweir break; 387cdf0e10cSrcweir } 388cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR && 389cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("path"))) 390cdf0e10cSrcweir { 391cdf0e10cSrcweir attrPath = reader.getAttributeValue(false); 392cdf0e10cSrcweir } 393cdf0e10cSrcweir } 394cdf0e10cSrcweir if (!attrPath.is()) { 395cdf0e10cSrcweir throw css::uno::RuntimeException( 396cdf0e10cSrcweir (rtl::OUString( 397cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("missing path attribute in ")) + 398cdf0e10cSrcweir reader.getUrl()), 399cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 400cdf0e10cSrcweir } 401cdf0e10cSrcweir rtl::OUString path(attrPath.convertFromUtf8()); 402cdf0e10cSrcweir int finalizedLayer; 403cdf0e10cSrcweir rtl::Reference< Node > node( 404cdf0e10cSrcweir data_.resolvePathRepresentation( 405cdf0e10cSrcweir path, 0, &path_, &finalizedLayer)); 406cdf0e10cSrcweir if (!node.is()) { 407cdf0e10cSrcweir OSL_TRACE( 408cdf0e10cSrcweir "configmgr unknown item %s in %s", 409cdf0e10cSrcweir rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr(), 410cdf0e10cSrcweir rtl::OUStringToOString( 411cdf0e10cSrcweir reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr()); 412cdf0e10cSrcweir state_.push(State(true)); // ignored 413cdf0e10cSrcweir return; 414cdf0e10cSrcweir } 415cdf0e10cSrcweir OSL_ASSERT(!path_.empty()); 416cdf0e10cSrcweir componentName_ = path_.front(); 417cdf0e10cSrcweir if (trackPath_) { 418cdf0e10cSrcweir if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT) 419cdf0e10cSrcweir { 420cdf0e10cSrcweir state_.push(State(true)); // ignored 421cdf0e10cSrcweir return; 422cdf0e10cSrcweir } 423cdf0e10cSrcweir } else { 424cdf0e10cSrcweir path_.clear(); 425cdf0e10cSrcweir } 426cdf0e10cSrcweir switch (node->kind()) { 427cdf0e10cSrcweir case Node::KIND_PROPERTY: 428cdf0e10cSrcweir case Node::KIND_LOCALIZED_VALUE: 429cdf0e10cSrcweir OSL_TRACE( 430cdf0e10cSrcweir "configmgr item of bad type %s in %s", 431cdf0e10cSrcweir rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr(), 432cdf0e10cSrcweir rtl::OUStringToOString( 433cdf0e10cSrcweir reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr()); 434cdf0e10cSrcweir state_.push(State(true)); // ignored 435cdf0e10cSrcweir return; 436cdf0e10cSrcweir case Node::KIND_LOCALIZED_PROPERTY: 437cdf0e10cSrcweir valueParser_.type_ = dynamic_cast< LocalizedPropertyNode * >( 438cdf0e10cSrcweir node.get())->getStaticType(); 439cdf0e10cSrcweir break; 440cdf0e10cSrcweir default: 441cdf0e10cSrcweir break; 442cdf0e10cSrcweir } 443cdf0e10cSrcweir state_.push(State(node, finalizedLayer < valueParser_.getLayer())); 444cdf0e10cSrcweir } 445cdf0e10cSrcweir 446cdf0e10cSrcweir void XcuParser::handlePropValue( 447cdf0e10cSrcweir xmlreader::XmlReader & reader, PropertyNode * prop) 448cdf0e10cSrcweir { 449cdf0e10cSrcweir bool nil = false; 450cdf0e10cSrcweir rtl::OString separator; 451cdf0e10cSrcweir rtl::OUString external; 452cdf0e10cSrcweir for (;;) { 453cdf0e10cSrcweir int attrNsId; 454cdf0e10cSrcweir xmlreader::Span attrLn; 455cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) { 456cdf0e10cSrcweir break; 457cdf0e10cSrcweir } 458cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_XSI && 459cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nil"))) 460cdf0e10cSrcweir { 461cdf0e10cSrcweir nil = xmldata::parseBoolean(reader.getAttributeValue(true)); 462cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 463cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type"))) 464cdf0e10cSrcweir { 465cdf0e10cSrcweir Type type = xmldata::parseType( 466cdf0e10cSrcweir reader, reader.getAttributeValue(true)); 467cdf0e10cSrcweir if (valueParser_.type_ != TYPE_ANY && type != valueParser_.type_) { 468cdf0e10cSrcweir throw css::uno::RuntimeException( 469cdf0e10cSrcweir (rtl::OUString( 470cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("invalid value type in ")) + 471cdf0e10cSrcweir reader.getUrl()), 472cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 473cdf0e10cSrcweir } 474cdf0e10cSrcweir valueParser_.type_ = type; 475cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 476cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator"))) 477cdf0e10cSrcweir { 478cdf0e10cSrcweir xmlreader::Span s(reader.getAttributeValue(false)); 479cdf0e10cSrcweir if (s.length == 0) { 480cdf0e10cSrcweir throw css::uno::RuntimeException( 481cdf0e10cSrcweir (rtl::OUString( 482cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 483cdf0e10cSrcweir "bad oor:separator attribute in ")) + 484cdf0e10cSrcweir reader.getUrl()), 485cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 486cdf0e10cSrcweir } 487cdf0e10cSrcweir separator = rtl::OString(s.begin, s.length); 488cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 489cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("external"))) 490cdf0e10cSrcweir { 491cdf0e10cSrcweir external = reader.getAttributeValue(true).convertFromUtf8(); 492cdf0e10cSrcweir if (external.getLength() == 0) { 493cdf0e10cSrcweir throw css::uno::RuntimeException( 494cdf0e10cSrcweir (rtl::OUString( 495cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 496cdf0e10cSrcweir "bad oor:external attribute value in ")) + 497cdf0e10cSrcweir reader.getUrl()), 498cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 499cdf0e10cSrcweir } 500cdf0e10cSrcweir } 501cdf0e10cSrcweir } 502cdf0e10cSrcweir if (nil) { 503cdf0e10cSrcweir if (!prop->isNillable()) { 504cdf0e10cSrcweir throw css::uno::RuntimeException( 505cdf0e10cSrcweir (rtl::OUString( 506cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 507cdf0e10cSrcweir "xsi:nil attribute for non-nillable prop in ")) + 508cdf0e10cSrcweir reader.getUrl()), 509cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 510cdf0e10cSrcweir } 511cdf0e10cSrcweir if (external.getLength() != 0) { 512cdf0e10cSrcweir throw css::uno::RuntimeException( 513cdf0e10cSrcweir (rtl::OUString( 514cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 515cdf0e10cSrcweir "xsi:nil and oor:external attributes for prop in ")) + 516cdf0e10cSrcweir reader.getUrl()), 517cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 518cdf0e10cSrcweir } 519cdf0e10cSrcweir prop->setValue(valueParser_.getLayer(), css::uno::Any()); 520cdf0e10cSrcweir state_.push(State(false)); 521cdf0e10cSrcweir } else if (external.getLength() == 0) { 522cdf0e10cSrcweir valueParser_.separator_ = separator; 523cdf0e10cSrcweir valueParser_.start(prop); 524cdf0e10cSrcweir } else { 525cdf0e10cSrcweir prop->setExternal(valueParser_.getLayer(), external); 526cdf0e10cSrcweir state_.push(State(false)); 527cdf0e10cSrcweir } 528cdf0e10cSrcweir } 529cdf0e10cSrcweir 530cdf0e10cSrcweir void XcuParser::handleLocpropValue( 531cdf0e10cSrcweir xmlreader::XmlReader & reader, LocalizedPropertyNode * locprop) 532cdf0e10cSrcweir { 533cdf0e10cSrcweir rtl::OUString name; 534cdf0e10cSrcweir bool nil = false; 535cdf0e10cSrcweir rtl::OString separator; 536cdf0e10cSrcweir Operation op = OPERATION_FUSE; 537cdf0e10cSrcweir for (;;) { 538cdf0e10cSrcweir int attrNsId; 539cdf0e10cSrcweir xmlreader::Span attrLn; 540cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) { 541cdf0e10cSrcweir break; 542cdf0e10cSrcweir } 543cdf0e10cSrcweir if (attrNsId == xmlreader::XmlReader::NAMESPACE_XML && 544cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("lang"))) 545cdf0e10cSrcweir { 546cdf0e10cSrcweir name = reader.getAttributeValue(false).convertFromUtf8(); 547cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_XSI && 548cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nil"))) 549cdf0e10cSrcweir { 550cdf0e10cSrcweir nil = xmldata::parseBoolean(reader.getAttributeValue(true)); 551cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 552cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type"))) 553cdf0e10cSrcweir { 554cdf0e10cSrcweir Type type = xmldata::parseType( 555cdf0e10cSrcweir reader, reader.getAttributeValue(true)); 556cdf0e10cSrcweir if (valueParser_.type_ != TYPE_ANY && type != valueParser_.type_) { 557cdf0e10cSrcweir throw css::uno::RuntimeException( 558cdf0e10cSrcweir (rtl::OUString( 559cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("invalid value type in ")) + 560cdf0e10cSrcweir reader.getUrl()), 561cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 562cdf0e10cSrcweir } 563cdf0e10cSrcweir valueParser_.type_ = type; 564cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 565cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator"))) 566cdf0e10cSrcweir { 567cdf0e10cSrcweir xmlreader::Span s(reader.getAttributeValue(false)); 568cdf0e10cSrcweir if (s.length == 0) { 569cdf0e10cSrcweir throw css::uno::RuntimeException( 570cdf0e10cSrcweir (rtl::OUString( 571cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 572cdf0e10cSrcweir "bad oor:separator attribute in ")) + 573cdf0e10cSrcweir reader.getUrl()), 574cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 575cdf0e10cSrcweir } 576cdf0e10cSrcweir separator = rtl::OString(s.begin, s.length); 577cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 578cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op"))) 579cdf0e10cSrcweir { 580cdf0e10cSrcweir op = parseOperation(reader.getAttributeValue(true)); 581cdf0e10cSrcweir } 582cdf0e10cSrcweir } 583cdf0e10cSrcweir if (trackPath_) { 584cdf0e10cSrcweir path_.push_back(name); 585cdf0e10cSrcweir if (partial_ != 0 && 586cdf0e10cSrcweir partial_->contains(path_) != Partial::CONTAINS_NODE) 587cdf0e10cSrcweir { 588cdf0e10cSrcweir state_.push(State(true)); // ignored 589cdf0e10cSrcweir return; 590cdf0e10cSrcweir } 591cdf0e10cSrcweir } 592cdf0e10cSrcweir NodeMap::iterator i(locprop->getMembers().find(name)); 593cdf0e10cSrcweir if (i != locprop->getMembers().end() && 594cdf0e10cSrcweir i->second->getLayer() > valueParser_.getLayer()) 595cdf0e10cSrcweir { 596cdf0e10cSrcweir state_.push(State(true)); // ignored 597cdf0e10cSrcweir return; 598cdf0e10cSrcweir } 599cdf0e10cSrcweir if (nil && !locprop->isNillable()) { 600cdf0e10cSrcweir throw css::uno::RuntimeException( 601cdf0e10cSrcweir (rtl::OUString( 602cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 603cdf0e10cSrcweir "xsi:nil attribute for non-nillable prop in ")) + 604cdf0e10cSrcweir reader.getUrl()), 605cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 606cdf0e10cSrcweir } 607cdf0e10cSrcweir switch (op) { 608cdf0e10cSrcweir case OPERATION_FUSE: 609cdf0e10cSrcweir { 610cdf0e10cSrcweir bool pop = false; 611cdf0e10cSrcweir if (nil) { 612cdf0e10cSrcweir if (i == locprop->getMembers().end()) { 613cdf0e10cSrcweir locprop->getMembers()[name] = new LocalizedValueNode( 614cdf0e10cSrcweir valueParser_.getLayer(), css::uno::Any()); 615cdf0e10cSrcweir } else { 616cdf0e10cSrcweir dynamic_cast< LocalizedValueNode * >( 617cdf0e10cSrcweir i->second.get())->setValue( 618cdf0e10cSrcweir valueParser_.getLayer(), css::uno::Any()); 619cdf0e10cSrcweir } 620cdf0e10cSrcweir state_.push(State(true)); 621cdf0e10cSrcweir } else { 622cdf0e10cSrcweir valueParser_.separator_ = separator; 623cdf0e10cSrcweir valueParser_.start(locprop, name); 624cdf0e10cSrcweir pop = true; 625cdf0e10cSrcweir } 626cdf0e10cSrcweir if (trackPath_) { 627cdf0e10cSrcweir recordModification(false); 628cdf0e10cSrcweir if (pop) { 629cdf0e10cSrcweir path_.pop_back(); 630cdf0e10cSrcweir } 631cdf0e10cSrcweir } 632cdf0e10cSrcweir } 633cdf0e10cSrcweir break; 634cdf0e10cSrcweir case OPERATION_REMOVE: 635cdf0e10cSrcweir //TODO: only allow if parent.op == OPERATION_FUSE 636cdf0e10cSrcweir //TODO: disallow removing when e.g. lang=""? 637cdf0e10cSrcweir if (i != locprop->getMembers().end()) { 638cdf0e10cSrcweir locprop->getMembers().erase(i); 639cdf0e10cSrcweir } 640cdf0e10cSrcweir state_.push(State(true)); 641cdf0e10cSrcweir recordModification(false); 642cdf0e10cSrcweir break; 643cdf0e10cSrcweir default: 644cdf0e10cSrcweir throw css::uno::RuntimeException( 645cdf0e10cSrcweir (rtl::OUString( 646cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 647cdf0e10cSrcweir "bad op attribute for value element in ")) + 648cdf0e10cSrcweir reader.getUrl()), 649cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 650cdf0e10cSrcweir } 651cdf0e10cSrcweir } 652cdf0e10cSrcweir 653cdf0e10cSrcweir void XcuParser::handleGroupProp( 654cdf0e10cSrcweir xmlreader::XmlReader & reader, GroupNode * group) 655cdf0e10cSrcweir { 656cdf0e10cSrcweir bool hasName = false; 657cdf0e10cSrcweir rtl::OUString name; 658cdf0e10cSrcweir Type type = TYPE_ERROR; 659cdf0e10cSrcweir Operation op = OPERATION_MODIFY; 660cdf0e10cSrcweir bool finalized = false; 661cdf0e10cSrcweir for (;;) { 662cdf0e10cSrcweir int attrNsId; 663cdf0e10cSrcweir xmlreader::Span attrLn; 664cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) { 665cdf0e10cSrcweir break; 666cdf0e10cSrcweir } 667cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR && 668cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name"))) 669cdf0e10cSrcweir { 670cdf0e10cSrcweir hasName = true; 671cdf0e10cSrcweir name = reader.getAttributeValue(false).convertFromUtf8(); 672cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 673cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type"))) 674cdf0e10cSrcweir { 675cdf0e10cSrcweir type = xmldata::parseType(reader, reader.getAttributeValue(true)); 676cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 677cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op"))) 678cdf0e10cSrcweir { 679cdf0e10cSrcweir op = parseOperation(reader.getAttributeValue(true)); 680cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 681cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized"))) 682cdf0e10cSrcweir { 683cdf0e10cSrcweir finalized = xmldata::parseBoolean(reader.getAttributeValue(true)); 684cdf0e10cSrcweir } 685cdf0e10cSrcweir } 686cdf0e10cSrcweir if (!hasName) { 687cdf0e10cSrcweir throw css::uno::RuntimeException( 688cdf0e10cSrcweir (rtl::OUString( 689cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("no prop name attribute in ")) + 690cdf0e10cSrcweir reader.getUrl()), 691cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 692cdf0e10cSrcweir } 693cdf0e10cSrcweir if (trackPath_) { 694cdf0e10cSrcweir path_.push_back(name); 695cdf0e10cSrcweir //TODO: This ignores locprop values for which specific include paths 696cdf0e10cSrcweir // exist (i.e., for which contains(locprop path) = CONTAINS_SUBNODES): 697cdf0e10cSrcweir if (partial_ != 0 && 698cdf0e10cSrcweir partial_->contains(path_) != Partial::CONTAINS_NODE) 699cdf0e10cSrcweir { 700cdf0e10cSrcweir state_.push(State(true)); // ignored 701cdf0e10cSrcweir return; 702cdf0e10cSrcweir } 703cdf0e10cSrcweir } 704cdf0e10cSrcweir NodeMap::iterator i(group->getMembers().find(name)); 705cdf0e10cSrcweir if (i == group->getMembers().end()) { 706cdf0e10cSrcweir handleUnknownGroupProp(reader, group, name, type, op, finalized); 707cdf0e10cSrcweir } else { 708cdf0e10cSrcweir switch (i->second->kind()) { 709cdf0e10cSrcweir case Node::KIND_PROPERTY: 710cdf0e10cSrcweir handlePlainGroupProp(reader, group, i, name, type, op, finalized); 711cdf0e10cSrcweir break; 712cdf0e10cSrcweir case Node::KIND_LOCALIZED_PROPERTY: 713cdf0e10cSrcweir handleLocalizedGroupProp( 714cdf0e10cSrcweir reader, 715cdf0e10cSrcweir dynamic_cast< LocalizedPropertyNode * >(i->second.get()), name, 716cdf0e10cSrcweir type, op, finalized); 717cdf0e10cSrcweir break; 718cdf0e10cSrcweir default: 719cdf0e10cSrcweir throw css::uno::RuntimeException( 720cdf0e10cSrcweir (rtl::OUString( 721cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("inappropriate prop ")) + 722cdf0e10cSrcweir name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) + 723cdf0e10cSrcweir reader.getUrl()), 724cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 725cdf0e10cSrcweir } 726cdf0e10cSrcweir } 727cdf0e10cSrcweir } 728cdf0e10cSrcweir 729cdf0e10cSrcweir void XcuParser::handleUnknownGroupProp( 730cdf0e10cSrcweir xmlreader::XmlReader const & reader, GroupNode * group, 731cdf0e10cSrcweir rtl::OUString const & name, Type type, Operation operation, bool finalized) 732cdf0e10cSrcweir { 733cdf0e10cSrcweir switch (operation) { 734cdf0e10cSrcweir case OPERATION_REPLACE: 735cdf0e10cSrcweir case OPERATION_FUSE: 736cdf0e10cSrcweir if (group->isExtensible()) { 737cdf0e10cSrcweir if (type == TYPE_ERROR) { 738cdf0e10cSrcweir throw css::uno::RuntimeException( 739cdf0e10cSrcweir (rtl::OUString( 740cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 741cdf0e10cSrcweir "missing type attribute for prop ")) + 742cdf0e10cSrcweir name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) + 743cdf0e10cSrcweir reader.getUrl()), 744cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 745cdf0e10cSrcweir } 746cdf0e10cSrcweir valueParser_.type_ = type; 747cdf0e10cSrcweir rtl::Reference< Node > prop( 748cdf0e10cSrcweir new PropertyNode( 749cdf0e10cSrcweir valueParser_.getLayer(), TYPE_ANY, true, css::uno::Any(), 750cdf0e10cSrcweir true)); 751cdf0e10cSrcweir if (finalized) { 752cdf0e10cSrcweir prop->setFinalized(valueParser_.getLayer()); 753cdf0e10cSrcweir } 754cdf0e10cSrcweir state_.push(State(prop, name, state_.top().locked)); 755cdf0e10cSrcweir recordModification(false); 756cdf0e10cSrcweir break; 757cdf0e10cSrcweir } 758cdf0e10cSrcweir // fall through 759cdf0e10cSrcweir default: 760cdf0e10cSrcweir OSL_TRACE( 761cdf0e10cSrcweir "configmgr unknown property %s in %s", 762cdf0e10cSrcweir rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(), 763cdf0e10cSrcweir rtl::OUStringToOString( 764cdf0e10cSrcweir reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr()); 765cdf0e10cSrcweir state_.push(State(true)); // ignored 766cdf0e10cSrcweir break; 767cdf0e10cSrcweir } 768cdf0e10cSrcweir } 769cdf0e10cSrcweir 770cdf0e10cSrcweir void XcuParser::handlePlainGroupProp( 771cdf0e10cSrcweir xmlreader::XmlReader const & reader, GroupNode * group, 772cdf0e10cSrcweir NodeMap::iterator const & propertyIndex, rtl::OUString const & name, 773cdf0e10cSrcweir Type type, Operation operation, bool finalized) 774cdf0e10cSrcweir { 775cdf0e10cSrcweir PropertyNode * property = dynamic_cast< PropertyNode * >( 776cdf0e10cSrcweir propertyIndex->second.get()); 777cdf0e10cSrcweir if (property->getLayer() > valueParser_.getLayer()) { 778cdf0e10cSrcweir state_.push(State(true)); // ignored 779cdf0e10cSrcweir return; 780cdf0e10cSrcweir } 781cdf0e10cSrcweir int finalizedLayer = std::min( 782cdf0e10cSrcweir finalized ? valueParser_.getLayer() : Data::NO_LAYER, 783cdf0e10cSrcweir property->getFinalized()); 784cdf0e10cSrcweir property->setFinalized(finalizedLayer); 785cdf0e10cSrcweir if (type != TYPE_ERROR && property->getStaticType() != TYPE_ANY && 786cdf0e10cSrcweir type != property->getStaticType()) 787cdf0e10cSrcweir { 788cdf0e10cSrcweir throw css::uno::RuntimeException( 789cdf0e10cSrcweir (rtl::OUString( 790cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("invalid type for prop ")) + 791cdf0e10cSrcweir name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) + 792cdf0e10cSrcweir reader.getUrl()), 793cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 794cdf0e10cSrcweir } 795cdf0e10cSrcweir valueParser_.type_ = type == TYPE_ERROR ? property->getStaticType() : type; 796cdf0e10cSrcweir switch (operation) { 797cdf0e10cSrcweir case OPERATION_MODIFY: 798cdf0e10cSrcweir case OPERATION_REPLACE: 799cdf0e10cSrcweir case OPERATION_FUSE: 800cdf0e10cSrcweir state_.push( 801cdf0e10cSrcweir State( 802cdf0e10cSrcweir property, 803cdf0e10cSrcweir (state_.top().locked || 804cdf0e10cSrcweir finalizedLayer < valueParser_.getLayer()))); 805cdf0e10cSrcweir recordModification(false); 806cdf0e10cSrcweir break; 807cdf0e10cSrcweir case OPERATION_REMOVE: 808cdf0e10cSrcweir if (!property->isExtension()) { 809cdf0e10cSrcweir throw css::uno::RuntimeException( 810cdf0e10cSrcweir (rtl::OUString( 811cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 812cdf0e10cSrcweir "invalid remove of non-extension prop ")) + 813cdf0e10cSrcweir name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) + 814cdf0e10cSrcweir reader.getUrl()), 815cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 816cdf0e10cSrcweir } 817cdf0e10cSrcweir group->getMembers().erase(propertyIndex); 818cdf0e10cSrcweir state_.push(State(true)); // ignore children 819cdf0e10cSrcweir recordModification(false); 820cdf0e10cSrcweir break; 821cdf0e10cSrcweir } 822cdf0e10cSrcweir } 823cdf0e10cSrcweir 824cdf0e10cSrcweir void XcuParser::handleLocalizedGroupProp( 825cdf0e10cSrcweir xmlreader::XmlReader const & reader, LocalizedPropertyNode * property, 826cdf0e10cSrcweir rtl::OUString const & name, Type type, Operation operation, bool finalized) 827cdf0e10cSrcweir { 828cdf0e10cSrcweir if (property->getLayer() > valueParser_.getLayer()) { 829cdf0e10cSrcweir state_.push(State(true)); // ignored 830cdf0e10cSrcweir return; 831cdf0e10cSrcweir } 832cdf0e10cSrcweir int finalizedLayer = std::min( 833cdf0e10cSrcweir finalized ? valueParser_.getLayer() : Data::NO_LAYER, 834cdf0e10cSrcweir property->getFinalized()); 835cdf0e10cSrcweir property->setFinalized(finalizedLayer); 836cdf0e10cSrcweir if (type != TYPE_ERROR && property->getStaticType() != TYPE_ANY && 837cdf0e10cSrcweir type != property->getStaticType()) 838cdf0e10cSrcweir { 839cdf0e10cSrcweir throw css::uno::RuntimeException( 840cdf0e10cSrcweir (rtl::OUString( 841cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("invalid type for prop ")) + 842cdf0e10cSrcweir name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) + 843cdf0e10cSrcweir reader.getUrl()), 844cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 845cdf0e10cSrcweir } 846cdf0e10cSrcweir valueParser_.type_ = type == TYPE_ERROR ? property->getStaticType() : type; 847cdf0e10cSrcweir switch (operation) { 848cdf0e10cSrcweir case OPERATION_MODIFY: 849cdf0e10cSrcweir case OPERATION_FUSE: 850cdf0e10cSrcweir state_.push( 851cdf0e10cSrcweir State( 852cdf0e10cSrcweir property, 853cdf0e10cSrcweir (state_.top().locked || 854cdf0e10cSrcweir finalizedLayer < valueParser_.getLayer()))); 855cdf0e10cSrcweir break; 856cdf0e10cSrcweir case OPERATION_REPLACE: 857cdf0e10cSrcweir { 858cdf0e10cSrcweir rtl::Reference< Node > replacement( 859cdf0e10cSrcweir new LocalizedPropertyNode( 860cdf0e10cSrcweir valueParser_.getLayer(), property->getStaticType(), 861cdf0e10cSrcweir property->isNillable())); 862cdf0e10cSrcweir replacement->setFinalized(property->getFinalized()); 863cdf0e10cSrcweir state_.push( 864cdf0e10cSrcweir State( 865cdf0e10cSrcweir replacement, name, 866cdf0e10cSrcweir (state_.top().locked || 867cdf0e10cSrcweir finalizedLayer < valueParser_.getLayer()))); 868cdf0e10cSrcweir recordModification(false); 869cdf0e10cSrcweir } 870cdf0e10cSrcweir break; 871cdf0e10cSrcweir case OPERATION_REMOVE: 872cdf0e10cSrcweir throw css::uno::RuntimeException( 873cdf0e10cSrcweir (rtl::OUString( 874cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 875cdf0e10cSrcweir "invalid remove of non-extension prop ")) + 876cdf0e10cSrcweir name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) + 877cdf0e10cSrcweir reader.getUrl()), 878cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 879cdf0e10cSrcweir } 880cdf0e10cSrcweir } 881cdf0e10cSrcweir 882cdf0e10cSrcweir void XcuParser::handleGroupNode( 883cdf0e10cSrcweir xmlreader::XmlReader & reader, rtl::Reference< Node > const & group) 884cdf0e10cSrcweir { 885cdf0e10cSrcweir bool hasName = false; 886cdf0e10cSrcweir rtl::OUString name; 887cdf0e10cSrcweir Operation op = OPERATION_MODIFY; 888cdf0e10cSrcweir bool finalized = false; 889cdf0e10cSrcweir for (;;) { 890cdf0e10cSrcweir int attrNsId; 891cdf0e10cSrcweir xmlreader::Span attrLn; 892cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) { 893cdf0e10cSrcweir break; 894cdf0e10cSrcweir } 895cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR && 896cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name"))) 897cdf0e10cSrcweir { 898cdf0e10cSrcweir hasName = true; 899cdf0e10cSrcweir name = reader.getAttributeValue(false).convertFromUtf8(); 900cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 901cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op"))) 902cdf0e10cSrcweir { 903cdf0e10cSrcweir op = parseOperation(reader.getAttributeValue(true)); 904cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 905cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized"))) 906cdf0e10cSrcweir { 907cdf0e10cSrcweir finalized = xmldata::parseBoolean(reader.getAttributeValue(true)); 908cdf0e10cSrcweir } 909cdf0e10cSrcweir } 910cdf0e10cSrcweir if (!hasName) { 911cdf0e10cSrcweir throw css::uno::RuntimeException( 912cdf0e10cSrcweir (rtl::OUString( 913cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("no node name attribute in ")) + 914cdf0e10cSrcweir reader.getUrl()), 915cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 916cdf0e10cSrcweir } 917cdf0e10cSrcweir if (trackPath_) { 918cdf0e10cSrcweir path_.push_back(name); 919cdf0e10cSrcweir if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT) 920cdf0e10cSrcweir { 921cdf0e10cSrcweir state_.push(State(true)); // ignored 922cdf0e10cSrcweir return; 923cdf0e10cSrcweir } 924cdf0e10cSrcweir } 925cdf0e10cSrcweir rtl::Reference< Node > child( 926cdf0e10cSrcweir Data::findNode(valueParser_.getLayer(), group->getMembers(), name)); 927cdf0e10cSrcweir if (!child.is()) { 928cdf0e10cSrcweir OSL_TRACE( 929cdf0e10cSrcweir "configmgr unknown node %s in %s", 930cdf0e10cSrcweir rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(), 931cdf0e10cSrcweir rtl::OUStringToOString( 932cdf0e10cSrcweir reader.getUrl(), RTL_TEXTENCODING_UTF8).getStr()); 933cdf0e10cSrcweir state_.push(State(true)); // ignored 934cdf0e10cSrcweir return; 935cdf0e10cSrcweir } 936cdf0e10cSrcweir if (op != OPERATION_MODIFY && op != OPERATION_FUSE) { 937cdf0e10cSrcweir throw css::uno::RuntimeException( 938cdf0e10cSrcweir (rtl::OUString( 939cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 940cdf0e10cSrcweir "invalid operation on group node in ")) + 941cdf0e10cSrcweir reader.getUrl()), 942cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 943cdf0e10cSrcweir } 944cdf0e10cSrcweir int finalizedLayer = std::min( 945cdf0e10cSrcweir finalized ? valueParser_.getLayer() : Data::NO_LAYER, 946cdf0e10cSrcweir child->getFinalized()); 947cdf0e10cSrcweir child->setFinalized(finalizedLayer); 948cdf0e10cSrcweir state_.push( 949cdf0e10cSrcweir State( 950cdf0e10cSrcweir child, 951cdf0e10cSrcweir state_.top().locked || finalizedLayer < valueParser_.getLayer())); 952cdf0e10cSrcweir } 953cdf0e10cSrcweir 954cdf0e10cSrcweir void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) { 955cdf0e10cSrcweir bool hasName = false; 956cdf0e10cSrcweir rtl::OUString name; 957cdf0e10cSrcweir rtl::OUString component(componentName_); 958cdf0e10cSrcweir bool hasNodeType = false; 959cdf0e10cSrcweir rtl::OUString nodeType; 960cdf0e10cSrcweir Operation op = OPERATION_MODIFY; 961cdf0e10cSrcweir bool finalized = false; 962cdf0e10cSrcweir bool mandatory = false; 963cdf0e10cSrcweir for (;;) { 964cdf0e10cSrcweir int attrNsId; 965cdf0e10cSrcweir xmlreader::Span attrLn; 966cdf0e10cSrcweir if (!reader.nextAttribute(&attrNsId, &attrLn)) { 967cdf0e10cSrcweir break; 968cdf0e10cSrcweir } 969cdf0e10cSrcweir if (attrNsId == ParseManager::NAMESPACE_OOR && 970cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name"))) 971cdf0e10cSrcweir { 972cdf0e10cSrcweir hasName = true; 973cdf0e10cSrcweir name = reader.getAttributeValue(false).convertFromUtf8(); 974cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 975cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component"))) 976cdf0e10cSrcweir { 977cdf0e10cSrcweir component = reader.getAttributeValue(false).convertFromUtf8(); 978cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 979cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type"))) 980cdf0e10cSrcweir { 981cdf0e10cSrcweir hasNodeType = true; 982cdf0e10cSrcweir nodeType = reader.getAttributeValue(false).convertFromUtf8(); 983cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 984cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op"))) 985cdf0e10cSrcweir { 986cdf0e10cSrcweir op = parseOperation(reader.getAttributeValue(true)); 987cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 988cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized"))) 989cdf0e10cSrcweir { 990cdf0e10cSrcweir finalized = xmldata::parseBoolean(reader.getAttributeValue(true)); 991cdf0e10cSrcweir } else if (attrNsId == ParseManager::NAMESPACE_OOR && 992cdf0e10cSrcweir attrLn.equals(RTL_CONSTASCII_STRINGPARAM("mandatory"))) 993cdf0e10cSrcweir { 994cdf0e10cSrcweir mandatory = xmldata::parseBoolean(reader.getAttributeValue(true)); 995cdf0e10cSrcweir } 996cdf0e10cSrcweir } 997cdf0e10cSrcweir if (!hasName) { 998cdf0e10cSrcweir throw css::uno::RuntimeException( 999cdf0e10cSrcweir (rtl::OUString( 1000cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("no node name attribute in ")) + 1001cdf0e10cSrcweir reader.getUrl()), 1002cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 1003cdf0e10cSrcweir } 1004cdf0e10cSrcweir if (trackPath_) { 1005cdf0e10cSrcweir path_.push_back(name); 1006cdf0e10cSrcweir if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT) 1007cdf0e10cSrcweir { 1008cdf0e10cSrcweir state_.push(State(true)); // ignored 1009cdf0e10cSrcweir return; 1010cdf0e10cSrcweir } 1011cdf0e10cSrcweir } 1012cdf0e10cSrcweir rtl::OUString templateName( 1013cdf0e10cSrcweir xmldata::parseTemplateReference( 1014cdf0e10cSrcweir component, hasNodeType, nodeType, &set->getDefaultTemplateName())); 1015cdf0e10cSrcweir if (!set->isValidTemplate(templateName)) { 1016cdf0e10cSrcweir throw css::uno::RuntimeException( 1017cdf0e10cSrcweir (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("set member node ")) + 1018cdf0e10cSrcweir name + 1019cdf0e10cSrcweir rtl::OUString( 1020cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM(" references invalid template ")) + 1021cdf0e10cSrcweir templateName + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) + 1022cdf0e10cSrcweir reader.getUrl()), 1023cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 1024cdf0e10cSrcweir } 1025cdf0e10cSrcweir rtl::Reference< Node > tmpl( 1026cdf0e10cSrcweir data_.getTemplate(valueParser_.getLayer(), templateName)); 1027cdf0e10cSrcweir if (!tmpl.is()) { 1028cdf0e10cSrcweir throw css::uno::RuntimeException( 1029cdf0e10cSrcweir (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("set member node ")) + 1030cdf0e10cSrcweir name + 1031cdf0e10cSrcweir rtl::OUString( 1032cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 1033cdf0e10cSrcweir " references undefined template ")) + 1034cdf0e10cSrcweir templateName + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) + 1035cdf0e10cSrcweir reader.getUrl()), 1036cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 1037cdf0e10cSrcweir } 1038cdf0e10cSrcweir int finalizedLayer = finalized ? valueParser_.getLayer() : Data::NO_LAYER; 1039cdf0e10cSrcweir int mandatoryLayer = mandatory ? valueParser_.getLayer() : Data::NO_LAYER; 1040cdf0e10cSrcweir NodeMap::iterator i(set->getMembers().find(name)); 1041cdf0e10cSrcweir if (i != set->getMembers().end()) { 1042cdf0e10cSrcweir finalizedLayer = std::min(finalizedLayer, i->second->getFinalized()); 1043cdf0e10cSrcweir i->second->setFinalized(finalizedLayer); 1044cdf0e10cSrcweir mandatoryLayer = std::min(mandatoryLayer, i->second->getMandatory()); 1045cdf0e10cSrcweir i->second->setMandatory(mandatoryLayer); 1046cdf0e10cSrcweir if (i->second->getLayer() > valueParser_.getLayer()) { 1047cdf0e10cSrcweir state_.push(State(true)); // ignored 1048cdf0e10cSrcweir return; 1049cdf0e10cSrcweir } 1050cdf0e10cSrcweir } 1051cdf0e10cSrcweir switch (op) { 1052cdf0e10cSrcweir case OPERATION_MODIFY: 1053cdf0e10cSrcweir if (i == set->getMembers().end()) { 1054cdf0e10cSrcweir OSL_TRACE("ignoring modify of unknown set member node"); 1055cdf0e10cSrcweir state_.push(State(true)); // ignored 1056cdf0e10cSrcweir } else { 1057cdf0e10cSrcweir state_.push( 1058cdf0e10cSrcweir State( 1059cdf0e10cSrcweir i->second, 1060cdf0e10cSrcweir (state_.top().locked || 1061cdf0e10cSrcweir finalizedLayer < valueParser_.getLayer()))); 1062cdf0e10cSrcweir } 1063cdf0e10cSrcweir break; 1064cdf0e10cSrcweir case OPERATION_REPLACE: 1065cdf0e10cSrcweir if (state_.top().locked || finalizedLayer < valueParser_.getLayer()) { 1066cdf0e10cSrcweir state_.push(State(true)); // ignored 1067cdf0e10cSrcweir } else { 1068cdf0e10cSrcweir rtl::Reference< Node > member(tmpl->clone(true)); 1069cdf0e10cSrcweir member->setLayer(valueParser_.getLayer()); 1070cdf0e10cSrcweir member->setFinalized(finalizedLayer); 1071cdf0e10cSrcweir member->setMandatory(mandatoryLayer); 1072cdf0e10cSrcweir state_.push(State(member, name, false)); 1073cdf0e10cSrcweir recordModification(i == set->getMembers().end()); 1074cdf0e10cSrcweir } 1075cdf0e10cSrcweir break; 1076cdf0e10cSrcweir case OPERATION_FUSE: 1077cdf0e10cSrcweir if (i == set->getMembers().end()) { 1078cdf0e10cSrcweir if (state_.top().locked || finalizedLayer < valueParser_.getLayer()) 1079cdf0e10cSrcweir { 1080cdf0e10cSrcweir state_.push(State(true)); // ignored 1081cdf0e10cSrcweir } else { 1082cdf0e10cSrcweir rtl::Reference< Node > member(tmpl->clone(true)); 1083cdf0e10cSrcweir member->setLayer(valueParser_.getLayer()); 1084cdf0e10cSrcweir member->setFinalized(finalizedLayer); 1085cdf0e10cSrcweir member->setMandatory(mandatoryLayer); 1086cdf0e10cSrcweir state_.push(State(member, name, false)); 1087cdf0e10cSrcweir recordModification(true); 1088cdf0e10cSrcweir } 1089cdf0e10cSrcweir } else { 1090cdf0e10cSrcweir state_.push( 1091cdf0e10cSrcweir State( 1092cdf0e10cSrcweir i->second, 1093cdf0e10cSrcweir (state_.top().locked || 1094cdf0e10cSrcweir finalizedLayer < valueParser_.getLayer()))); 1095cdf0e10cSrcweir } 1096cdf0e10cSrcweir break; 1097cdf0e10cSrcweir case OPERATION_REMOVE: 1098cdf0e10cSrcweir { 1099cdf0e10cSrcweir // Ignore removal of unknown members, members finalized in a lower 1100cdf0e10cSrcweir // layer, and members made mandatory in this or a lower layer; 1101cdf0e10cSrcweir // forget about user-layer removals that no longer remove anything 1102cdf0e10cSrcweir // (so that paired additions/removals in the user layer do not grow 1103cdf0e10cSrcweir // registrymodifications.xcu unbounded): 1104cdf0e10cSrcweir bool known = i != set->getMembers().end(); 1105cdf0e10cSrcweir if (known && !state_.top().locked && 1106cdf0e10cSrcweir finalizedLayer >= valueParser_.getLayer() && 1107cdf0e10cSrcweir mandatoryLayer > valueParser_.getLayer()) 1108cdf0e10cSrcweir { 1109cdf0e10cSrcweir set->getMembers().erase(i); 1110cdf0e10cSrcweir } 1111cdf0e10cSrcweir state_.push(State(true)); 1112cdf0e10cSrcweir if (known) { 1113cdf0e10cSrcweir recordModification(false); 1114cdf0e10cSrcweir } 1115cdf0e10cSrcweir break; 1116cdf0e10cSrcweir } 1117cdf0e10cSrcweir } 1118cdf0e10cSrcweir } 1119cdf0e10cSrcweir 1120cdf0e10cSrcweir void XcuParser::recordModification(bool addition) { 1121cdf0e10cSrcweir if (broadcastModifications_ != 0) { 1122cdf0e10cSrcweir broadcastModifications_->add(path_); 1123cdf0e10cSrcweir } 1124cdf0e10cSrcweir if (addition && additions_ != 0) { 1125cdf0e10cSrcweir additions_->push_back(path_); 1126cdf0e10cSrcweir } 1127cdf0e10cSrcweir if (recordModifications_) { 1128cdf0e10cSrcweir data_.modifications.add(path_); 1129cdf0e10cSrcweir } 1130cdf0e10cSrcweir } 1131cdf0e10cSrcweir 1132cdf0e10cSrcweir } 1133