1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "precompiled_configmgr.hxx" 29*cdf0e10cSrcweir #include "sal/config.h" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <algorithm> 32*cdf0e10cSrcweir #include <cstddef> 33*cdf0e10cSrcweir #include <list> 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include "com/sun/star/beans/Optional.hpp" 36*cdf0e10cSrcweir #include "com/sun/star/beans/UnknownPropertyException.hpp" 37*cdf0e10cSrcweir #include "com/sun/star/beans/XPropertySet.hpp" 38*cdf0e10cSrcweir #include "com/sun/star/container/NoSuchElementException.hpp" 39*cdf0e10cSrcweir #include "com/sun/star/lang/WrappedTargetException.hpp" 40*cdf0e10cSrcweir #include "com/sun/star/lang/XMultiComponentFactory.hpp" 41*cdf0e10cSrcweir #include "com/sun/star/uno/Any.hxx" 42*cdf0e10cSrcweir #include "com/sun/star/uno/Exception.hpp" 43*cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx" 44*cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp" 45*cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp" 46*cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp" 47*cdf0e10cSrcweir #include "osl/conditn.hxx" 48*cdf0e10cSrcweir #include "osl/diagnose.h" 49*cdf0e10cSrcweir #include "osl/file.hxx" 50*cdf0e10cSrcweir #include "osl/mutex.hxx" 51*cdf0e10cSrcweir #include "osl/thread.hxx" 52*cdf0e10cSrcweir #include "rtl/bootstrap.hxx" 53*cdf0e10cSrcweir #include "rtl/logfile.h" 54*cdf0e10cSrcweir #include "rtl/ref.hxx" 55*cdf0e10cSrcweir #include "rtl/string.h" 56*cdf0e10cSrcweir #include "rtl/textenc.h" 57*cdf0e10cSrcweir #include "rtl/ustring.h" 58*cdf0e10cSrcweir #include "rtl/ustring.hxx" 59*cdf0e10cSrcweir #include "sal/types.h" 60*cdf0e10cSrcweir #include "salhelper/simplereferenceobject.hxx" 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir #include "additions.hxx" 63*cdf0e10cSrcweir #include "components.hxx" 64*cdf0e10cSrcweir #include "data.hxx" 65*cdf0e10cSrcweir #include "lock.hxx" 66*cdf0e10cSrcweir #include "modifications.hxx" 67*cdf0e10cSrcweir #include "node.hxx" 68*cdf0e10cSrcweir #include "nodemap.hxx" 69*cdf0e10cSrcweir #include "parsemanager.hxx" 70*cdf0e10cSrcweir #include "partial.hxx" 71*cdf0e10cSrcweir #include "rootaccess.hxx" 72*cdf0e10cSrcweir #include "writemodfile.hxx" 73*cdf0e10cSrcweir #include "xcdparser.hxx" 74*cdf0e10cSrcweir #include "xcuparser.hxx" 75*cdf0e10cSrcweir #include "xcsparser.hxx" 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir namespace configmgr { 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir namespace { 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir namespace css = com::sun::star; 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir struct UnresolvedListItem { 84*cdf0e10cSrcweir rtl::OUString name; 85*cdf0e10cSrcweir rtl::Reference< ParseManager > manager; 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir UnresolvedListItem( 88*cdf0e10cSrcweir rtl::OUString const & theName, 89*cdf0e10cSrcweir rtl::Reference< ParseManager > theManager): 90*cdf0e10cSrcweir name(theName), manager(theManager) {} 91*cdf0e10cSrcweir }; 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir typedef std::list< UnresolvedListItem > UnresolvedList; 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir void parseXcsFile( 96*cdf0e10cSrcweir rtl::OUString const & url, int layer, Data & data, Partial const * partial, 97*cdf0e10cSrcweir Modifications * modifications, Additions * additions) 98*cdf0e10cSrcweir SAL_THROW(( 99*cdf0e10cSrcweir css::container::NoSuchElementException, css::uno::RuntimeException)) 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir OSL_ASSERT(partial == 0 && modifications == 0 && additions == 0); 102*cdf0e10cSrcweir (void) partial; (void) modifications; (void) additions; 103*cdf0e10cSrcweir OSL_VERIFY( 104*cdf0e10cSrcweir rtl::Reference< ParseManager >( 105*cdf0e10cSrcweir new ParseManager(url, new XcsParser(layer, data)))->parse()); 106*cdf0e10cSrcweir } 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir void parseXcuFile( 109*cdf0e10cSrcweir rtl::OUString const & url, int layer, Data & data, Partial const * partial, 110*cdf0e10cSrcweir Modifications * modifications, Additions * additions) 111*cdf0e10cSrcweir SAL_THROW(( 112*cdf0e10cSrcweir css::container::NoSuchElementException, css::uno::RuntimeException)) 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir OSL_VERIFY( 115*cdf0e10cSrcweir rtl::Reference< ParseManager >( 116*cdf0e10cSrcweir new ParseManager( 117*cdf0e10cSrcweir url, 118*cdf0e10cSrcweir new XcuParser( 119*cdf0e10cSrcweir layer, data, partial, modifications, additions)))-> 120*cdf0e10cSrcweir parse()); 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir rtl::OUString expand(rtl::OUString const & str) { 124*cdf0e10cSrcweir rtl::OUString s(str); 125*cdf0e10cSrcweir rtl::Bootstrap::expandMacros(s); //TODO: detect failure 126*cdf0e10cSrcweir return s; 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir bool canRemoveFromLayer(int layer, rtl::Reference< Node > const & node) { 130*cdf0e10cSrcweir OSL_ASSERT(node.is()); 131*cdf0e10cSrcweir if (node->getLayer() > layer && node->getLayer() < Data::NO_LAYER) { 132*cdf0e10cSrcweir return false; 133*cdf0e10cSrcweir } 134*cdf0e10cSrcweir switch (node->kind()) { 135*cdf0e10cSrcweir case Node::KIND_LOCALIZED_PROPERTY: 136*cdf0e10cSrcweir case Node::KIND_GROUP: 137*cdf0e10cSrcweir for (NodeMap::iterator i(node->getMembers().begin()); 138*cdf0e10cSrcweir i != node->getMembers().end(); ++i) 139*cdf0e10cSrcweir { 140*cdf0e10cSrcweir if (!canRemoveFromLayer(layer, i->second)) { 141*cdf0e10cSrcweir return false; 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir return true; 145*cdf0e10cSrcweir case Node::KIND_SET: 146*cdf0e10cSrcweir return node->getMembers().empty(); 147*cdf0e10cSrcweir default: // Node::KIND_PROPERTY, Node::KIND_LOCALIZED_VALUE 148*cdf0e10cSrcweir return true; 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir static bool singletonCreated = false; 153*cdf0e10cSrcweir static Components * singleton = 0; 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir class Components::WriteThread: 158*cdf0e10cSrcweir public osl::Thread, public salhelper::SimpleReferenceObject 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir public: 161*cdf0e10cSrcweir static void * operator new(std::size_t size) 162*cdf0e10cSrcweir { return Thread::operator new(size); } 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir static void operator delete(void * pointer) 165*cdf0e10cSrcweir { Thread::operator delete(pointer); } 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir WriteThread( 168*cdf0e10cSrcweir rtl::Reference< WriteThread > * reference, Components & components, 169*cdf0e10cSrcweir rtl::OUString const & url, Data const & data); 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir void flush() { delay_.set(); } 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir private: 174*cdf0e10cSrcweir virtual ~WriteThread() {} 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir virtual void SAL_CALL run(); 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir virtual void SAL_CALL onTerminated() { release(); } 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir rtl::Reference< WriteThread > * reference_; 181*cdf0e10cSrcweir Components & components_; 182*cdf0e10cSrcweir rtl::OUString url_; 183*cdf0e10cSrcweir Data const & data_; 184*cdf0e10cSrcweir osl::Condition delay_; 185*cdf0e10cSrcweir }; 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir Components::WriteThread::WriteThread( 188*cdf0e10cSrcweir rtl::Reference< WriteThread > * reference, Components & components, 189*cdf0e10cSrcweir rtl::OUString const & url, Data const & data): 190*cdf0e10cSrcweir reference_(reference), components_(components), url_(url), data_(data) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir OSL_ASSERT(reference != 0); 193*cdf0e10cSrcweir acquire(); 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir void Components::WriteThread::run() { 197*cdf0e10cSrcweir TimeValue t = { 1, 0 }; // 1 sec 198*cdf0e10cSrcweir delay_.wait(&t); // must not throw; result_error is harmless and ignored 199*cdf0e10cSrcweir osl::MutexGuard g(lock); // must not throw 200*cdf0e10cSrcweir try { 201*cdf0e10cSrcweir try { 202*cdf0e10cSrcweir writeModFile(components_, url_, data_); 203*cdf0e10cSrcweir } catch (css::uno::RuntimeException & e) { 204*cdf0e10cSrcweir // Silently ignore write errors, instead of aborting: 205*cdf0e10cSrcweir OSL_TRACE( 206*cdf0e10cSrcweir "configmgr error writing modifications: %s", 207*cdf0e10cSrcweir rtl::OUStringToOString( 208*cdf0e10cSrcweir e.Message, RTL_TEXTENCODING_UTF8).getStr()); 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir } catch (...) { 211*cdf0e10cSrcweir reference_->clear(); 212*cdf0e10cSrcweir throw; 213*cdf0e10cSrcweir } 214*cdf0e10cSrcweir reference_->clear(); 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir Components & Components::getSingleton( 218*cdf0e10cSrcweir css::uno::Reference< css::uno::XComponentContext > const & context) 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir OSL_ASSERT(context.is()); 221*cdf0e10cSrcweir if (!singletonCreated) { 222*cdf0e10cSrcweir singletonCreated = true; 223*cdf0e10cSrcweir static Components theSingleton(context); 224*cdf0e10cSrcweir singleton = &theSingleton; 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir if (singleton == 0) { 227*cdf0e10cSrcweir throw css::uno::RuntimeException( 228*cdf0e10cSrcweir rtl::OUString( 229*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 230*cdf0e10cSrcweir "configmgr no Components singleton")), 231*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir return *singleton; 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir bool Components::allLocales(rtl::OUString const & locale) { 237*cdf0e10cSrcweir return locale.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("*")); 238*cdf0e10cSrcweir } 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir rtl::Reference< Node > Components::resolvePathRepresentation( 241*cdf0e10cSrcweir rtl::OUString const & pathRepresentation, 242*cdf0e10cSrcweir rtl::OUString * canonicRepresentation, Path * path, int * finalizedLayer) 243*cdf0e10cSrcweir const 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir return data_.resolvePathRepresentation( 246*cdf0e10cSrcweir pathRepresentation, canonicRepresentation, path, finalizedLayer); 247*cdf0e10cSrcweir } 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir rtl::Reference< Node > Components::getTemplate( 250*cdf0e10cSrcweir int layer, rtl::OUString const & fullName) const 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir return data_.getTemplate(layer, fullName); 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir void Components::addRootAccess(rtl::Reference< RootAccess > const & access) { 256*cdf0e10cSrcweir roots_.insert(access.get()); 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir void Components::removeRootAccess(RootAccess * access) { 260*cdf0e10cSrcweir roots_.erase(access); 261*cdf0e10cSrcweir } 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir void Components::initGlobalBroadcaster( 264*cdf0e10cSrcweir Modifications const & modifications, 265*cdf0e10cSrcweir rtl::Reference< RootAccess > const & exclude, Broadcaster * broadcaster) 266*cdf0e10cSrcweir { 267*cdf0e10cSrcweir //TODO: Iterate only over roots w/ listeners: 268*cdf0e10cSrcweir for (WeakRootSet::iterator i(roots_.begin()); i != roots_.end(); ++i) { 269*cdf0e10cSrcweir rtl::Reference< RootAccess > root; 270*cdf0e10cSrcweir if ((*i)->acquireCounting() > 1) { 271*cdf0e10cSrcweir root.set(*i); // must not throw 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir (*i)->releaseNondeleting(); 274*cdf0e10cSrcweir if (root.is()) { 275*cdf0e10cSrcweir if (root != exclude) { 276*cdf0e10cSrcweir Path path(root->getAbsolutePath()); 277*cdf0e10cSrcweir Modifications::Node const * mods = &modifications.getRoot(); 278*cdf0e10cSrcweir for (Path::iterator j(path.begin()); j != path.end(); ++j) { 279*cdf0e10cSrcweir Modifications::Node::Children::const_iterator k( 280*cdf0e10cSrcweir mods->children.find(*j)); 281*cdf0e10cSrcweir if (k == mods->children.end()) { 282*cdf0e10cSrcweir mods = 0; 283*cdf0e10cSrcweir break; 284*cdf0e10cSrcweir } 285*cdf0e10cSrcweir mods = &k->second; 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir //TODO: If the complete tree of which root is a part is deleted, 288*cdf0e10cSrcweir // or replaced, mods will be null, but some of the listeners 289*cdf0e10cSrcweir // from within root should probably fire nonetheless: 290*cdf0e10cSrcweir if (mods != 0) { 291*cdf0e10cSrcweir root->initBroadcaster(*mods, broadcaster); 292*cdf0e10cSrcweir } 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir } 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir void Components::addModification(Path const & path) { 299*cdf0e10cSrcweir data_.modifications.add(path); 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir 302*cdf0e10cSrcweir void Components::writeModifications() { 303*cdf0e10cSrcweir if (!writeThread_.is()) { 304*cdf0e10cSrcweir writeThread_ = new WriteThread( 305*cdf0e10cSrcweir &writeThread_, *this, getModificationFileUrl(), data_); 306*cdf0e10cSrcweir writeThread_->create(); 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir void Components::flushModifications() { 311*cdf0e10cSrcweir rtl::Reference< WriteThread > thread; 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir osl::MutexGuard g(lock); 314*cdf0e10cSrcweir thread = writeThread_; 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir if (thread.is()) { 317*cdf0e10cSrcweir thread->flush(); 318*cdf0e10cSrcweir thread->join(); 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir void Components::insertExtensionXcsFile( 323*cdf0e10cSrcweir bool shared, rtl::OUString const & fileUri) 324*cdf0e10cSrcweir { 325*cdf0e10cSrcweir try { 326*cdf0e10cSrcweir parseXcsFile(fileUri, shared ? 9 : 13, data_, 0, 0, 0); 327*cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) { 328*cdf0e10cSrcweir throw css::uno::RuntimeException( 329*cdf0e10cSrcweir (rtl::OUString( 330*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 331*cdf0e10cSrcweir "insertExtensionXcsFile does not exist: ")) + 332*cdf0e10cSrcweir e.Message), 333*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir void Components::insertExtensionXcuFile( 338*cdf0e10cSrcweir bool shared, rtl::OUString const & fileUri, Modifications * modifications) 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir OSL_ASSERT(modifications != 0); 341*cdf0e10cSrcweir int layer = shared ? 10 : 14; 342*cdf0e10cSrcweir Additions * adds = data_.addExtensionXcuAdditions(fileUri, layer); 343*cdf0e10cSrcweir try { 344*cdf0e10cSrcweir parseXcuFile(fileUri, layer, data_, 0, modifications, adds); 345*cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) { 346*cdf0e10cSrcweir data_.removeExtensionXcuAdditions(fileUri); 347*cdf0e10cSrcweir throw css::uno::RuntimeException( 348*cdf0e10cSrcweir (rtl::OUString( 349*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 350*cdf0e10cSrcweir "insertExtensionXcuFile does not exist: ")) + 351*cdf0e10cSrcweir e.Message), 352*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 353*cdf0e10cSrcweir } 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir 356*cdf0e10cSrcweir void Components::removeExtensionXcuFile( 357*cdf0e10cSrcweir rtl::OUString const & fileUri, Modifications * modifications) 358*cdf0e10cSrcweir { 359*cdf0e10cSrcweir //TODO: Ideally, exactly the data coming from the specified xcu file would 360*cdf0e10cSrcweir // be removed. However, not enough information is recorded in the in-memory 361*cdf0e10cSrcweir // data structures to do so. So, as a workaround, all those set elements 362*cdf0e10cSrcweir // that were freshly added by the xcu and have afterwards been left 363*cdf0e10cSrcweir // unchanged or have only had their properties changed in the user layer are 364*cdf0e10cSrcweir // removed (and nothing else). The heuristic to determine 365*cdf0e10cSrcweir // whether a node has been left unchanged is to check the layer ID (as 366*cdf0e10cSrcweir // usual) and additionally to check that the node does not recursively 367*cdf0e10cSrcweir // contain any non-empty sets (multiple extension xcu files are merged into 368*cdf0e10cSrcweir // one layer, so checking layer ID alone is not enough). Since 369*cdf0e10cSrcweir // item->additions records all additions of set members in textual order, 370*cdf0e10cSrcweir // the latter check works well when iterating through item->additions in 371*cdf0e10cSrcweir // reverse order. 372*cdf0e10cSrcweir OSL_ASSERT(modifications != 0); 373*cdf0e10cSrcweir rtl::Reference< Data::ExtensionXcu > item( 374*cdf0e10cSrcweir data_.removeExtensionXcuAdditions(fileUri)); 375*cdf0e10cSrcweir if (item.is()) { 376*cdf0e10cSrcweir for (Additions::reverse_iterator i(item->additions.rbegin()); 377*cdf0e10cSrcweir i != item->additions.rend(); ++i) 378*cdf0e10cSrcweir { 379*cdf0e10cSrcweir rtl::Reference< Node > parent; 380*cdf0e10cSrcweir NodeMap const * map = &data_.components; 381*cdf0e10cSrcweir rtl::Reference< Node > node; 382*cdf0e10cSrcweir for (Path::const_iterator j(i->begin()); j != i->end(); ++j) { 383*cdf0e10cSrcweir parent = node; 384*cdf0e10cSrcweir node = Data::findNode(Data::NO_LAYER, *map, *j); 385*cdf0e10cSrcweir if (!node.is()) { 386*cdf0e10cSrcweir break; 387*cdf0e10cSrcweir } 388*cdf0e10cSrcweir map = &node->getMembers(); 389*cdf0e10cSrcweir } 390*cdf0e10cSrcweir if (node.is()) { 391*cdf0e10cSrcweir OSL_ASSERT(parent.is()); 392*cdf0e10cSrcweir if (parent->kind() == Node::KIND_SET) { 393*cdf0e10cSrcweir OSL_ASSERT( 394*cdf0e10cSrcweir node->kind() == Node::KIND_GROUP || 395*cdf0e10cSrcweir node->kind() == Node::KIND_SET); 396*cdf0e10cSrcweir if (canRemoveFromLayer(item->layer, node)) { 397*cdf0e10cSrcweir parent->getMembers().erase(i->back()); 398*cdf0e10cSrcweir data_.modifications.remove(*i); 399*cdf0e10cSrcweir modifications->add(*i); 400*cdf0e10cSrcweir } 401*cdf0e10cSrcweir } 402*cdf0e10cSrcweir } 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir writeModifications(); 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir void Components::insertModificationXcuFile( 409*cdf0e10cSrcweir rtl::OUString const & fileUri, 410*cdf0e10cSrcweir std::set< rtl::OUString > const & includedPaths, 411*cdf0e10cSrcweir std::set< rtl::OUString > const & excludedPaths, 412*cdf0e10cSrcweir Modifications * modifications) 413*cdf0e10cSrcweir { 414*cdf0e10cSrcweir OSL_ASSERT(modifications != 0); 415*cdf0e10cSrcweir Partial part(includedPaths, excludedPaths); 416*cdf0e10cSrcweir try { 417*cdf0e10cSrcweir parseFileLeniently( 418*cdf0e10cSrcweir &parseXcuFile, fileUri, Data::NO_LAYER, data_, &part, modifications, 419*cdf0e10cSrcweir 0); 420*cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) { 421*cdf0e10cSrcweir OSL_TRACE( 422*cdf0e10cSrcweir "configmgr error inserting non-existing %s: %s", 423*cdf0e10cSrcweir rtl::OUStringToOString(fileUri, RTL_TEXTENCODING_UTF8).getStr(), 424*cdf0e10cSrcweir rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr()); 425*cdf0e10cSrcweir } 426*cdf0e10cSrcweir } 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir css::beans::Optional< css::uno::Any > Components::getExternalValue( 429*cdf0e10cSrcweir rtl::OUString const & descriptor) 430*cdf0e10cSrcweir { 431*cdf0e10cSrcweir sal_Int32 i = descriptor.indexOf(' '); 432*cdf0e10cSrcweir if (i <= 0) { 433*cdf0e10cSrcweir throw css::uno::RuntimeException( 434*cdf0e10cSrcweir (rtl::OUString( 435*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("bad external value descriptor ")) + 436*cdf0e10cSrcweir descriptor), 437*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir //TODO: Do not make calls with mutex locked: 440*cdf0e10cSrcweir rtl::OUString name(descriptor.copy(0, i)); 441*cdf0e10cSrcweir ExternalServices::iterator j(externalServices_.find(name)); 442*cdf0e10cSrcweir if (j == externalServices_.end()) { 443*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > service; 444*cdf0e10cSrcweir try { 445*cdf0e10cSrcweir service = css::uno::Reference< css::lang::XMultiComponentFactory >( 446*cdf0e10cSrcweir context_->getServiceManager(), css::uno::UNO_SET_THROW)-> 447*cdf0e10cSrcweir createInstanceWithContext(name, context_); 448*cdf0e10cSrcweir } catch (css::uno::RuntimeException &) { 449*cdf0e10cSrcweir // Assuming these exceptions are real errors: 450*cdf0e10cSrcweir throw; 451*cdf0e10cSrcweir } catch (css::uno::Exception & e) { 452*cdf0e10cSrcweir // Assuming these exceptions indicate that the service is not 453*cdf0e10cSrcweir // installed: 454*cdf0e10cSrcweir OSL_TRACE( 455*cdf0e10cSrcweir "createInstance(%s) failed with %s", 456*cdf0e10cSrcweir rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(), 457*cdf0e10cSrcweir rtl::OUStringToOString( 458*cdf0e10cSrcweir e.Message, RTL_TEXTENCODING_UTF8).getStr()); 459*cdf0e10cSrcweir } 460*cdf0e10cSrcweir css::uno::Reference< css::beans::XPropertySet > propset; 461*cdf0e10cSrcweir if (service.is()) { 462*cdf0e10cSrcweir propset = css::uno::Reference< css::beans::XPropertySet >( 463*cdf0e10cSrcweir service, css::uno::UNO_QUERY_THROW); 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir j = externalServices_.insert( 466*cdf0e10cSrcweir ExternalServices::value_type(name, propset)).first; 467*cdf0e10cSrcweir } 468*cdf0e10cSrcweir css::beans::Optional< css::uno::Any > value; 469*cdf0e10cSrcweir if (j->second.is()) { 470*cdf0e10cSrcweir try { 471*cdf0e10cSrcweir if (!(j->second->getPropertyValue(descriptor.copy(i + 1)) >>= 472*cdf0e10cSrcweir value)) 473*cdf0e10cSrcweir { 474*cdf0e10cSrcweir throw css::uno::RuntimeException( 475*cdf0e10cSrcweir (rtl::OUString( 476*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 477*cdf0e10cSrcweir "cannot obtain external value through ")) + 478*cdf0e10cSrcweir descriptor), 479*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir } catch (css::beans::UnknownPropertyException & e) { 482*cdf0e10cSrcweir throw css::uno::RuntimeException( 483*cdf0e10cSrcweir (rtl::OUString( 484*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 485*cdf0e10cSrcweir "unknwon external value descriptor ID: ")) + 486*cdf0e10cSrcweir e.Message), 487*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 488*cdf0e10cSrcweir } catch (css::lang::WrappedTargetException & e) { 489*cdf0e10cSrcweir throw css::uno::RuntimeException( 490*cdf0e10cSrcweir (rtl::OUString( 491*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 492*cdf0e10cSrcweir "cannot obtain external value: ")) + 493*cdf0e10cSrcweir e.Message), 494*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 495*cdf0e10cSrcweir } 496*cdf0e10cSrcweir } 497*cdf0e10cSrcweir return value; 498*cdf0e10cSrcweir } 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir Components::Components( 501*cdf0e10cSrcweir css::uno::Reference< css::uno::XComponentContext > const & context): 502*cdf0e10cSrcweir context_(context) 503*cdf0e10cSrcweir { 504*cdf0e10cSrcweir OSL_ASSERT(context.is()); 505*cdf0e10cSrcweir RTL_LOGFILE_TRACE_AUTHOR("configmgr", "sb", "begin parsing"); 506*cdf0e10cSrcweir parseXcsXcuLayer( 507*cdf0e10cSrcweir 0, 508*cdf0e10cSrcweir expand( 509*cdf0e10cSrcweir rtl::OUString( 510*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/registry")))); 511*cdf0e10cSrcweir parseModuleLayer( 512*cdf0e10cSrcweir 2, 513*cdf0e10cSrcweir expand( 514*cdf0e10cSrcweir rtl::OUString( 515*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 516*cdf0e10cSrcweir "$OOO_BASE_DIR/share/registry/modules")))); 517*cdf0e10cSrcweir parseResLayer( 518*cdf0e10cSrcweir 3, 519*cdf0e10cSrcweir expand( 520*cdf0e10cSrcweir rtl::OUString( 521*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/registry")))); 522*cdf0e10cSrcweir parseXcsXcuLayer( 523*cdf0e10cSrcweir 4, 524*cdf0e10cSrcweir expand( 525*cdf0e10cSrcweir rtl::OUString( 526*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 527*cdf0e10cSrcweir "$BRAND_BASE_DIR/share/registry")))); 528*cdf0e10cSrcweir parseModuleLayer( 529*cdf0e10cSrcweir 6, 530*cdf0e10cSrcweir expand( 531*cdf0e10cSrcweir rtl::OUString( 532*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 533*cdf0e10cSrcweir "$BRAND_BASE_DIR/share/registry/modules")))); 534*cdf0e10cSrcweir parseXcsXcuIniLayer( 535*cdf0e10cSrcweir 7, 536*cdf0e10cSrcweir expand( 537*cdf0e10cSrcweir rtl::OUString( 538*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 539*cdf0e10cSrcweir "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno") 540*cdf0e10cSrcweir ":BUNDLED_EXTENSIONS_USER}/registry/" 541*cdf0e10cSrcweir "com.sun.star.comp.deployment.configuration." 542*cdf0e10cSrcweir "PackageRegistryBackend/configmgr.ini"))), 543*cdf0e10cSrcweir false); 544*cdf0e10cSrcweir parseXcsXcuIniLayer( 545*cdf0e10cSrcweir 9, 546*cdf0e10cSrcweir expand( 547*cdf0e10cSrcweir rtl::OUString( 548*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 549*cdf0e10cSrcweir "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno") 550*cdf0e10cSrcweir ":SHARED_EXTENSIONS_USER}/registry/" 551*cdf0e10cSrcweir "com.sun.star.comp.deployment.configuration." 552*cdf0e10cSrcweir "PackageRegistryBackend/configmgr.ini"))), 553*cdf0e10cSrcweir true); 554*cdf0e10cSrcweir parseXcsXcuLayer( 555*cdf0e10cSrcweir 11, 556*cdf0e10cSrcweir expand( 557*cdf0e10cSrcweir rtl::OUString( 558*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 559*cdf0e10cSrcweir "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno") 560*cdf0e10cSrcweir ":UNO_USER_PACKAGES_CACHE}/registry/" 561*cdf0e10cSrcweir "com.sun.star.comp.deployment.configuration." 562*cdf0e10cSrcweir "PackageRegistryBackend/registry")))); 563*cdf0e10cSrcweir // can be dropped once old UserInstallation format can no longer exist 564*cdf0e10cSrcweir // (probably OOo 4) 565*cdf0e10cSrcweir parseXcsXcuIniLayer( 566*cdf0e10cSrcweir 13, 567*cdf0e10cSrcweir expand( 568*cdf0e10cSrcweir rtl::OUString( 569*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 570*cdf0e10cSrcweir "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno") 571*cdf0e10cSrcweir ":UNO_USER_PACKAGES_CACHE}/registry/" 572*cdf0e10cSrcweir "com.sun.star.comp.deployment.configuration." 573*cdf0e10cSrcweir "PackageRegistryBackend/configmgr.ini"))), 574*cdf0e10cSrcweir true); 575*cdf0e10cSrcweir parseModificationLayer(); 576*cdf0e10cSrcweir RTL_LOGFILE_TRACE_AUTHOR("configmgr", "sb", "end parsing"); 577*cdf0e10cSrcweir } 578*cdf0e10cSrcweir 579*cdf0e10cSrcweir Components::~Components() {} 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir void Components::parseFileLeniently( 582*cdf0e10cSrcweir FileParser * parseFile, rtl::OUString const & url, int layer, Data & data, 583*cdf0e10cSrcweir Partial const * partial, Modifications * modifications, 584*cdf0e10cSrcweir Additions * additions) 585*cdf0e10cSrcweir { 586*cdf0e10cSrcweir OSL_ASSERT(parseFile != 0); 587*cdf0e10cSrcweir try { 588*cdf0e10cSrcweir (*parseFile)(url, layer, data, partial, modifications, additions); 589*cdf0e10cSrcweir } catch (css::container::NoSuchElementException &) { 590*cdf0e10cSrcweir throw; 591*cdf0e10cSrcweir } catch (css::uno::Exception & e) { //TODO: more specific exception catching 592*cdf0e10cSrcweir // Silently ignore invalid XML files, instead of completely preventing 593*cdf0e10cSrcweir // OOo from starting: 594*cdf0e10cSrcweir OSL_TRACE( 595*cdf0e10cSrcweir "configmgr error reading %s: %s", 596*cdf0e10cSrcweir rtl::OUStringToOString(url, RTL_TEXTENCODING_UTF8).getStr(), 597*cdf0e10cSrcweir rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr()); 598*cdf0e10cSrcweir } 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir 601*cdf0e10cSrcweir void Components::parseFiles( 602*cdf0e10cSrcweir int layer, rtl::OUString const & extension, FileParser * parseFile, 603*cdf0e10cSrcweir rtl::OUString const & url, bool recursive) 604*cdf0e10cSrcweir { 605*cdf0e10cSrcweir osl::Directory dir(url); 606*cdf0e10cSrcweir switch (dir.open()) { 607*cdf0e10cSrcweir case osl::FileBase::E_None: 608*cdf0e10cSrcweir break; 609*cdf0e10cSrcweir case osl::FileBase::E_NOENT: 610*cdf0e10cSrcweir if (!recursive) { 611*cdf0e10cSrcweir return; 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir // fall through 614*cdf0e10cSrcweir default: 615*cdf0e10cSrcweir throw css::uno::RuntimeException( 616*cdf0e10cSrcweir (rtl::OUString( 617*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot open directory ")) + 618*cdf0e10cSrcweir url), 619*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 620*cdf0e10cSrcweir } 621*cdf0e10cSrcweir for (;;) { 622*cdf0e10cSrcweir osl::DirectoryItem i; 623*cdf0e10cSrcweir osl::FileBase::RC rc = dir.getNextItem(i, SAL_MAX_UINT32); 624*cdf0e10cSrcweir if (rc == osl::FileBase::E_NOENT) { 625*cdf0e10cSrcweir break; 626*cdf0e10cSrcweir } 627*cdf0e10cSrcweir if (rc != osl::FileBase::E_None) { 628*cdf0e10cSrcweir throw css::uno::RuntimeException( 629*cdf0e10cSrcweir (rtl::OUString( 630*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot iterate directory ")) + 631*cdf0e10cSrcweir url), 632*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 633*cdf0e10cSrcweir } 634*cdf0e10cSrcweir osl::FileStatus stat( 635*cdf0e10cSrcweir FileStatusMask_Type | FileStatusMask_FileName | 636*cdf0e10cSrcweir FileStatusMask_FileURL); 637*cdf0e10cSrcweir if (i.getFileStatus(stat) != osl::FileBase::E_None) { 638*cdf0e10cSrcweir throw css::uno::RuntimeException( 639*cdf0e10cSrcweir (rtl::OUString( 640*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot stat in directory ")) + 641*cdf0e10cSrcweir url), 642*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 643*cdf0e10cSrcweir } 644*cdf0e10cSrcweir if (stat.getFileType() == osl::FileStatus::Directory) { //TODO: symlinks 645*cdf0e10cSrcweir parseFiles(layer, extension, parseFile, stat.getFileURL(), true); 646*cdf0e10cSrcweir } else { 647*cdf0e10cSrcweir rtl::OUString file(stat.getFileName()); 648*cdf0e10cSrcweir if (file.getLength() >= extension.getLength() && 649*cdf0e10cSrcweir file.match(extension, file.getLength() - extension.getLength())) 650*cdf0e10cSrcweir { 651*cdf0e10cSrcweir try { 652*cdf0e10cSrcweir parseFileLeniently( 653*cdf0e10cSrcweir parseFile, stat.getFileURL(), layer, data_, 0, 0, 0); 654*cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) { 655*cdf0e10cSrcweir throw css::uno::RuntimeException( 656*cdf0e10cSrcweir (rtl::OUString( 657*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 658*cdf0e10cSrcweir "stat'ed file does not exist: ")) + 659*cdf0e10cSrcweir e.Message), 660*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 661*cdf0e10cSrcweir } 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir } 664*cdf0e10cSrcweir } 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir 667*cdf0e10cSrcweir void Components::parseFileList( 668*cdf0e10cSrcweir int layer, FileParser * parseFile, rtl::OUString const & urls, 669*cdf0e10cSrcweir rtl::Bootstrap const & ini, bool recordAdditions) 670*cdf0e10cSrcweir { 671*cdf0e10cSrcweir for (sal_Int32 i = 0;;) { 672*cdf0e10cSrcweir rtl::OUString url(urls.getToken(0, ' ', i)); 673*cdf0e10cSrcweir if (url.getLength() != 0) { 674*cdf0e10cSrcweir ini.expandMacrosFrom(url); //TODO: detect failure 675*cdf0e10cSrcweir Additions * adds = 0; 676*cdf0e10cSrcweir if (recordAdditions) { 677*cdf0e10cSrcweir adds = data_.addExtensionXcuAdditions(url, layer); 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir try { 680*cdf0e10cSrcweir parseFileLeniently(parseFile, url, layer, data_, 0, 0, adds); 681*cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) { 682*cdf0e10cSrcweir OSL_TRACE( 683*cdf0e10cSrcweir "configmgr file does not exist: %s", 684*cdf0e10cSrcweir rtl::OUStringToOString( 685*cdf0e10cSrcweir e.Message, RTL_TEXTENCODING_UTF8).getStr()); 686*cdf0e10cSrcweir if (adds != 0) { 687*cdf0e10cSrcweir data_.removeExtensionXcuAdditions(url); 688*cdf0e10cSrcweir } 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir } 691*cdf0e10cSrcweir if (i == -1) { 692*cdf0e10cSrcweir break; 693*cdf0e10cSrcweir } 694*cdf0e10cSrcweir } 695*cdf0e10cSrcweir } 696*cdf0e10cSrcweir 697*cdf0e10cSrcweir void Components::parseXcdFiles(int layer, rtl::OUString const & url) { 698*cdf0e10cSrcweir osl::Directory dir(url); 699*cdf0e10cSrcweir switch (dir.open()) { 700*cdf0e10cSrcweir case osl::FileBase::E_None: 701*cdf0e10cSrcweir break; 702*cdf0e10cSrcweir case osl::FileBase::E_NOENT: 703*cdf0e10cSrcweir return; 704*cdf0e10cSrcweir default: 705*cdf0e10cSrcweir throw css::uno::RuntimeException( 706*cdf0e10cSrcweir (rtl::OUString( 707*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot open directory ")) + 708*cdf0e10cSrcweir url), 709*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 710*cdf0e10cSrcweir } 711*cdf0e10cSrcweir UnresolvedList unres; 712*cdf0e10cSrcweir XcdParser::Dependencies deps; 713*cdf0e10cSrcweir for (;;) { 714*cdf0e10cSrcweir osl::DirectoryItem i; 715*cdf0e10cSrcweir osl::FileBase::RC rc = dir.getNextItem(i, SAL_MAX_UINT32); 716*cdf0e10cSrcweir if (rc == osl::FileBase::E_NOENT) { 717*cdf0e10cSrcweir break; 718*cdf0e10cSrcweir } 719*cdf0e10cSrcweir if (rc != osl::FileBase::E_None) { 720*cdf0e10cSrcweir throw css::uno::RuntimeException( 721*cdf0e10cSrcweir (rtl::OUString( 722*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot iterate directory ")) + 723*cdf0e10cSrcweir url), 724*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 725*cdf0e10cSrcweir } 726*cdf0e10cSrcweir osl::FileStatus stat( 727*cdf0e10cSrcweir FileStatusMask_Type | FileStatusMask_FileName | 728*cdf0e10cSrcweir FileStatusMask_FileURL); 729*cdf0e10cSrcweir if (i.getFileStatus(stat) != osl::FileBase::E_None) { 730*cdf0e10cSrcweir throw css::uno::RuntimeException( 731*cdf0e10cSrcweir (rtl::OUString( 732*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("cannot stat in directory ")) + 733*cdf0e10cSrcweir url), 734*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir if (stat.getFileType() != osl::FileStatus::Directory) { //TODO: symlinks 737*cdf0e10cSrcweir rtl::OUString file(stat.getFileName()); 738*cdf0e10cSrcweir if (file.getLength() >= RTL_CONSTASCII_LENGTH(".xcd") && 739*cdf0e10cSrcweir file.matchAsciiL( 740*cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(".xcd"), 741*cdf0e10cSrcweir file.getLength() - RTL_CONSTASCII_LENGTH(".xcd"))) 742*cdf0e10cSrcweir { 743*cdf0e10cSrcweir rtl::OUString name( 744*cdf0e10cSrcweir file.copy( 745*cdf0e10cSrcweir 0, file.getLength() - RTL_CONSTASCII_LENGTH(".xcd"))); 746*cdf0e10cSrcweir rtl::Reference< ParseManager > manager; 747*cdf0e10cSrcweir try { 748*cdf0e10cSrcweir manager = new ParseManager( 749*cdf0e10cSrcweir stat.getFileURL(), new XcdParser(layer, deps, data_)); 750*cdf0e10cSrcweir } catch (css::container::NoSuchElementException & e) { 751*cdf0e10cSrcweir throw css::uno::RuntimeException( 752*cdf0e10cSrcweir (rtl::OUString( 753*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 754*cdf0e10cSrcweir "stat'ed file does not exist: ")) + 755*cdf0e10cSrcweir e.Message), 756*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 757*cdf0e10cSrcweir } 758*cdf0e10cSrcweir if (manager->parse()) { 759*cdf0e10cSrcweir deps.insert(name); 760*cdf0e10cSrcweir } else { 761*cdf0e10cSrcweir unres.push_back(UnresolvedListItem(name, manager)); 762*cdf0e10cSrcweir } 763*cdf0e10cSrcweir } 764*cdf0e10cSrcweir } 765*cdf0e10cSrcweir } 766*cdf0e10cSrcweir while (!unres.empty()) { 767*cdf0e10cSrcweir bool resolved = false; 768*cdf0e10cSrcweir for (UnresolvedList::iterator i(unres.begin()); i != unres.end();) { 769*cdf0e10cSrcweir if (i->manager->parse()) { 770*cdf0e10cSrcweir deps.insert(i->name); 771*cdf0e10cSrcweir unres.erase(i++); 772*cdf0e10cSrcweir resolved = true; 773*cdf0e10cSrcweir } else { 774*cdf0e10cSrcweir ++i; 775*cdf0e10cSrcweir } 776*cdf0e10cSrcweir } 777*cdf0e10cSrcweir if (!resolved) { 778*cdf0e10cSrcweir throw css::uno::RuntimeException( 779*cdf0e10cSrcweir (rtl::OUString( 780*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 781*cdf0e10cSrcweir "xcd: unresolved dependencies in ")) + 782*cdf0e10cSrcweir url), 783*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 784*cdf0e10cSrcweir } 785*cdf0e10cSrcweir } 786*cdf0e10cSrcweir } 787*cdf0e10cSrcweir 788*cdf0e10cSrcweir void Components::parseXcsXcuLayer(int layer, rtl::OUString const & url) { 789*cdf0e10cSrcweir parseXcdFiles(layer, url); 790*cdf0e10cSrcweir parseFiles( 791*cdf0e10cSrcweir layer, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcs")), 792*cdf0e10cSrcweir &parseXcsFile, 793*cdf0e10cSrcweir url + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/schema")), false); 794*cdf0e10cSrcweir parseFiles( 795*cdf0e10cSrcweir layer + 1, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")), 796*cdf0e10cSrcweir &parseXcuFile, 797*cdf0e10cSrcweir url + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/data")), false); 798*cdf0e10cSrcweir } 799*cdf0e10cSrcweir 800*cdf0e10cSrcweir void Components::parseXcsXcuIniLayer( 801*cdf0e10cSrcweir int layer, rtl::OUString const & url, bool recordAdditions) 802*cdf0e10cSrcweir { 803*cdf0e10cSrcweir //TODO: rtl::Bootstrap::getFrom "first trie[s] to retrieve the value via the 804*cdf0e10cSrcweir // global function" 805*cdf0e10cSrcweir rtl::Bootstrap ini(url); 806*cdf0e10cSrcweir rtl::OUString urls; 807*cdf0e10cSrcweir if (ini.getFrom(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SCHEMA")), urls)) 808*cdf0e10cSrcweir { 809*cdf0e10cSrcweir parseFileList(layer, &parseXcsFile, urls, ini, false); 810*cdf0e10cSrcweir } 811*cdf0e10cSrcweir if (ini.getFrom(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DATA")), urls)) 812*cdf0e10cSrcweir { 813*cdf0e10cSrcweir parseFileList(layer + 1, &parseXcuFile, urls, ini, recordAdditions); 814*cdf0e10cSrcweir } 815*cdf0e10cSrcweir } 816*cdf0e10cSrcweir 817*cdf0e10cSrcweir void Components::parseModuleLayer(int layer, rtl::OUString const & url) { 818*cdf0e10cSrcweir parseFiles( 819*cdf0e10cSrcweir layer, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")), 820*cdf0e10cSrcweir &parseXcuFile, url, false); 821*cdf0e10cSrcweir } 822*cdf0e10cSrcweir 823*cdf0e10cSrcweir void Components::parseResLayer(int layer, rtl::OUString const & url) { 824*cdf0e10cSrcweir rtl::OUString resUrl( 825*cdf0e10cSrcweir url + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/res"))); 826*cdf0e10cSrcweir parseXcdFiles(layer, resUrl); 827*cdf0e10cSrcweir parseFiles( 828*cdf0e10cSrcweir layer, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")), 829*cdf0e10cSrcweir &parseXcuFile, resUrl, false); 830*cdf0e10cSrcweir } 831*cdf0e10cSrcweir 832*cdf0e10cSrcweir rtl::OUString Components::getModificationFileUrl() const { 833*cdf0e10cSrcweir return expand( 834*cdf0e10cSrcweir rtl::OUString( 835*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 836*cdf0e10cSrcweir "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap") 837*cdf0e10cSrcweir ":UserInstallation}/user/registrymodifications.xcu"))); 838*cdf0e10cSrcweir } 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir void Components::parseModificationLayer() { 841*cdf0e10cSrcweir try { 842*cdf0e10cSrcweir parseFileLeniently( 843*cdf0e10cSrcweir &parseXcuFile, getModificationFileUrl(), Data::NO_LAYER, data_, 0, 844*cdf0e10cSrcweir 0, 0); 845*cdf0e10cSrcweir } catch (css::container::NoSuchElementException &) { 846*cdf0e10cSrcweir OSL_TRACE( 847*cdf0e10cSrcweir "configmgr user registrymodifications.xcu does not (yet) exist"); 848*cdf0e10cSrcweir // Migrate old user layer data (can be removed once migration is no 849*cdf0e10cSrcweir // longer relevant, probably OOo 4; also see hack for xsi namespace in 850*cdf0e10cSrcweir // xmlreader::XmlReader::registerNamespaceIri): 851*cdf0e10cSrcweir parseFiles( 852*cdf0e10cSrcweir Data::NO_LAYER, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")), 853*cdf0e10cSrcweir &parseXcuFile, 854*cdf0e10cSrcweir expand( 855*cdf0e10cSrcweir rtl::OUString( 856*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 857*cdf0e10cSrcweir "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap") 858*cdf0e10cSrcweir ":UserInstallation}/user/registry/data"))), 859*cdf0e10cSrcweir false); 860*cdf0e10cSrcweir } 861*cdf0e10cSrcweir } 862*cdf0e10cSrcweir 863*cdf0e10cSrcweir } 864