LCOV - code coverage report
Current view: top level - libreoffice/cppuhelper/source - defaultbootstrap.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 412 853 48.3 %
Date: 2012-12-27 Functions: 56 92 60.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
       4             :  *
       5             :  * The contents of this file are subject to the Mozilla Public License Version
       6             :  * 1.1 (the "License"); you may not use this file except in compliance with
       7             :  * the License or as specified alternatively below. You may obtain a copy of
       8             :  * the License at http://www.mozilla.org/MPL/
       9             :  *
      10             :  * Software distributed under the License is distributed on an "AS IS" basis,
      11             :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12             :  * for the specific language governing rights and limitations under the
      13             :  * License.
      14             :  *
      15             :  * Major Contributor(s):
      16             :  * [ Copyright (C) 2012 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
      17             :  *   (initial developer) ]
      18             :  *
      19             :  * All Rights Reserved.
      20             :  *
      21             :  * For minor contributions see the git repository.
      22             :  *
      23             :  * Alternatively, the contents of this file may be used under the terms of
      24             :  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      25             :  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
      26             :  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
      27             :  * instead of those above.
      28             :  */
      29             : 
      30             : #include "sal/config.h"
      31             : 
      32             : #include <algorithm>
      33             : #include <cassert>
      34             : #include <cstring>
      35             : #include <map>
      36             : #include <vector>
      37             : 
      38             : #include "boost/noncopyable.hpp"
      39             : #include "boost/shared_ptr.hpp"
      40             : #include "com/sun/star/beans/NamedValue.hpp"
      41             : #include "com/sun/star/beans/PropertyAttribute.hpp"
      42             : #include "com/sun/star/beans/XPropertySet.hpp"
      43             : #include "com/sun/star/container/ElementExistException.hpp"
      44             : #include "com/sun/star/container/XContentEnumerationAccess.hpp"
      45             : #include "com/sun/star/container/XEnumeration.hpp"
      46             : #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
      47             : #include "com/sun/star/container/XNameContainer.hpp"
      48             : #include "com/sun/star/container/XSet.hpp"
      49             : #include "com/sun/star/lang/XInitialization.hpp"
      50             : #include "com/sun/star/lang/XServiceInfo.hpp"
      51             : #include "com/sun/star/lang/XSingleComponentFactory.hpp"
      52             : #include "com/sun/star/lang/XSingleServiceFactory.hpp"
      53             : #include "com/sun/star/loader/XImplementationLoader.hpp"
      54             : #include "com/sun/star/registry/InvalidRegistryException.hpp"
      55             : #include "com/sun/star/registry/XSimpleRegistry.hpp"
      56             : #include "com/sun/star/uno/DeploymentException.hpp"
      57             : #include "com/sun/star/uno/Reference.hxx"
      58             : #include "com/sun/star/uno/XComponentContext.hpp"
      59             : #include "cppuhelper/bootstrap.hxx"
      60             : #include "cppuhelper/compbase8.hxx"
      61             : #include "cppuhelper/component_context.hxx"
      62             : #include "cppuhelper/implbase1.hxx"
      63             : #include "cppuhelper/implbase3.hxx"
      64             : #include "cppuhelper/shlib.hxx"
      65             : #include "cppuhelper/supportsservice.hxx"
      66             : #include "osl/file.hxx"
      67             : #include "registry/registry.hxx"
      68             : #include "rtl/bootstrap.hxx"
      69             : #include "rtl/ref.hxx"
      70             : #include "rtl/uri.hxx"
      71             : #include "rtl/ustring.hxx"
      72             : #include "xmlreader/xmlreader.hxx"
      73             : 
      74             : #include "macro_expander.hxx"
      75             : #include "paths.hxx"
      76             : #include "servicefactory_detail.hxx"
      77             : 
      78             : namespace {
      79             : 
      80           0 : bool nextDirectoryItem(osl::Directory & directory, rtl::OUString * url) {
      81             :     assert(url != 0);
      82           0 :     for (;;) {
      83           0 :         osl::DirectoryItem i;
      84           0 :         switch (directory.getNextItem(i, SAL_MAX_UINT32)) {
      85             :         case osl::FileBase::E_None:
      86           0 :             break;
      87             :         case osl::FileBase::E_NOENT:
      88           0 :             return false;
      89             :         default:
      90             :             throw css::uno::DeploymentException(
      91             :                 "Cannot iterate directory",
      92           0 :                 css::uno::Reference< css::uno::XInterface >());
      93             :         }
      94             :         osl::FileStatus stat(
      95             :             osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileName |
      96           0 :             osl_FileStatus_Mask_FileURL);
      97           0 :         if (i.getFileStatus(stat) != osl::FileBase::E_None) {
      98             :             throw css::uno::DeploymentException(
      99             :                 "Cannot stat in directory",
     100           0 :                 css::uno::Reference< css::uno::XInterface >());
     101             :         }
     102           0 :         if (stat.getFileType() != osl::FileStatus::Directory) { //TODO: symlinks
     103             :             // Ignore backup files:
     104           0 :             rtl::OUString name(stat.getFileName());
     105           0 :             if (!(name.match(".") || name.endsWith("~"))) {
     106           0 :                 *url = stat.getFileURL();
     107           0 :                 return true;
     108           0 :             }
     109             :         }
     110           0 :     }
     111             : }
     112             : 
     113        1282 : void decodeRdbUri(rtl::OUString * uri, bool * optional, bool * directory) {
     114             :     assert(uri != 0 && optional != 0 && directory != 0);
     115        1282 :     *optional = (*uri)[0] == '?';
     116        1282 :     if (*optional) {
     117           0 :         *uri = uri->copy(1);
     118             :     }
     119        2564 :     *directory = uri->getLength() >= 3 && (*uri)[0] == '<'
     120           0 :         && (*uri)[uri->getLength() - 2] == '>'
     121        2564 :         && (*uri)[uri->getLength() - 1] == '*';
     122        1282 :     if (*directory) {
     123           0 :         *uri = uri->copy(1, uri->getLength() - 3);
     124             :     }
     125        1282 : }
     126             : 
     127       11582 : struct ImplementationInfo: private boost::noncopyable {
     128       20720 :     ImplementationInfo(
     129             :         rtl::OUString const & theName, rtl::OUString const & theLoader,
     130             :         rtl::OUString const & theUri, rtl::OUString const & thePrefix,
     131             :         css::uno::Reference< css::uno::XComponentContext > const &
     132             :             theAlienContext,
     133             :         rtl::OUString const & theRdbFile):
     134             :         name(theName), loader(theLoader), uri(theUri), prefix(thePrefix),
     135       20720 :         alienContext(theAlienContext), rdbFile(theRdbFile)
     136       20720 :     {}
     137             : 
     138         102 :     explicit ImplementationInfo(rtl::OUString const & theName): name(theName) {}
     139             : 
     140             :     rtl::OUString const name;
     141             :     rtl::OUString const loader;
     142             :     rtl::OUString const uri;
     143             :     rtl::OUString const prefix;
     144             :     css::uno::Reference< css::uno::XComponentContext > const alienContext;
     145             :     rtl::OUString const rdbFile;
     146             :     std::vector< rtl::OUString > services;
     147             :     std::vector< rtl::OUString > singletons;
     148             : };
     149             : 
     150       11582 : struct Implementation: private boost::noncopyable {
     151       20720 :     Implementation(
     152             :         rtl::OUString const & name, rtl::OUString const & loader,
     153             :         rtl::OUString const & uri, rtl::OUString const & prefix,
     154             :         css::uno::Reference< css::uno::XComponentContext > const & alienContext,
     155             :         rtl::OUString const & rdbFile):
     156             :         info(
     157             :             new ImplementationInfo(
     158       20720 :                 name, loader, uri, prefix, alienContext, rdbFile)),
     159       41440 :         loaded(false)
     160       20720 :     {}
     161             : 
     162         102 :     Implementation(
     163             :         rtl::OUString const & name,
     164             :         css::uno::Reference< css::lang::XSingleComponentFactory > const &
     165             :             theFactory1,
     166             :         css::uno::Reference< css::lang::XSingleServiceFactory > const &
     167             :             theFactory2,
     168             :         css::uno::Reference< css::lang::XComponent > const & theComponent):
     169         102 :         info(new ImplementationInfo(name)), factory1(theFactory1),
     170         204 :         factory2(theFactory2), component(theComponent), loaded(true)
     171         102 :     {}
     172             : 
     173             :     boost::shared_ptr< ImplementationInfo > info;
     174             :     css::uno::Reference< css::lang::XSingleComponentFactory > factory1;
     175             :     css::uno::Reference< css::lang::XSingleServiceFactory > factory2;
     176             :     css::uno::Reference< css::lang::XComponent > component;
     177             :     bool loaded;
     178             : };
     179             : 
     180             : typedef std::map< rtl::OUString, boost::shared_ptr< Implementation > >
     181             : NamedImplementations;
     182             : 
     183             : typedef
     184             :     std::map<
     185             :         css::uno::Reference< css::lang::XServiceInfo >,
     186             :         boost::shared_ptr< Implementation > >
     187             :     DynamicImplementations;
     188             : 
     189             : typedef
     190             :     std::map<
     191             :         rtl::OUString, std::vector< boost::shared_ptr< Implementation > > >
     192             :     ImplementationMap;
     193             : 
     194         204 : void insertImplementationMap(
     195             :     ImplementationMap * destination, ImplementationMap const & source)
     196             : {
     197             :     assert(destination != 0);
     198         306 :     for (ImplementationMap::const_iterator i(source.begin()); i != source.end();
     199             :          ++i)
     200             :     {
     201             :         std::vector< boost::shared_ptr< Implementation > > & impls
     202         102 :             = (*destination)[i->first];
     203         102 :         impls.insert(impls.end(), i->second.begin(), i->second.end());
     204             :     }
     205         204 : }
     206             : 
     207           0 : void removeFromImplementationMap(
     208             :     ImplementationMap * map, std::vector< rtl::OUString > const & elements,
     209             :     boost::shared_ptr< Implementation > const & implementation)
     210             : {
     211             :     // The underlying data structures make this function somewhat inefficient,
     212             :     // but the assumption is that it is rarely called:
     213             :     assert(map != 0);
     214           0 :     for (std::vector< rtl::OUString >::const_iterator i(elements.begin());
     215           0 :          i != elements.end(); ++i)
     216             :     {
     217           0 :         ImplementationMap::iterator j(map->find(*i));
     218             :         assert(j != map->end());
     219             :         std::vector< boost::shared_ptr< Implementation > >::iterator k(
     220           0 :             std::find(j->second.begin(), j->second.end(), implementation));
     221             :         assert(k != j->second.end());
     222           0 :         j->second.erase(k);
     223           0 :         if (j->second.empty()) {
     224           0 :             map->erase(j);
     225             :         }
     226             :     }
     227           0 : }
     228             : 
     229         561 : struct Data: private boost::noncopyable {
     230             :     NamedImplementations namedImplementations;
     231             :     DynamicImplementations dynamicImplementations;
     232             :     ImplementationMap services;
     233             :     ImplementationMap singletons;
     234             : };
     235             : 
     236             : // For simplicity, this code keeps throwing
     237             : // css::registry::InvalidRegistryException for invalid XML rdbs (even though
     238             : // that does not fit the exception's name):
     239         980 : class Parser: private boost::noncopyable {
     240             : public:
     241             :     Parser(
     242             :         rtl::OUString const & uri,
     243             :         css::uno::Reference< css::uno::XComponentContext > const & alienContext,
     244             :         Data * data);
     245             : 
     246             : private:
     247             :     void handleComponent();
     248             : 
     249             :     void handleImplementation();
     250             : 
     251             :     void handleService();
     252             : 
     253             :     void handleSingleton();
     254             : 
     255             :     rtl::OUString getNameAttribute();
     256             : 
     257             :     xmlreader::XmlReader reader_;
     258             :     css::uno::Reference< css::uno::XComponentContext > alienContext_;
     259             :     Data * data_;
     260             :     rtl::OUString attrLoader_;
     261             :     rtl::OUString attrUri_;
     262             :     rtl::OUString attrPrefix_;
     263             :     rtl::OUString attrImplementation_;
     264             :     boost::shared_ptr< Implementation > implementation_;
     265             : };
     266             : 
     267         980 : Parser::Parser(
     268             :     rtl::OUString const & uri,
     269             :     css::uno::Reference< css::uno::XComponentContext > const & alienContext,
     270             :     Data * data):
     271         980 :     reader_(uri), alienContext_(alienContext), data_(data)
     272             : {
     273             :     assert(data != 0);
     274             :     int ucNsId = reader_.registerNamespaceIri(
     275             :         xmlreader::Span(
     276             :             RTL_CONSTASCII_STRINGPARAM(
     277         980 :                 "http://openoffice.org/2010/uno-components")));
     278             :     enum State {
     279             :         STATE_BEGIN, STATE_END, STATE_COMPONENTS, STATE_COMPONENT_INITIAL,
     280             :         STATE_COMPONENT, STATE_IMPLEMENTATION, STATE_SERVICE, STATE_SINGLETON };
     281      101952 :     for (State state = STATE_BEGIN;;) {
     282      101952 :         xmlreader::Span name;
     283             :         int nsId;
     284             :         xmlreader::XmlReader::Result res = reader_.nextItem(
     285      101952 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
     286      101952 :         switch (state) {
     287             :         case STATE_BEGIN:
     288        1960 :             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
     289         980 :                 && name.equals(RTL_CONSTASCII_STRINGPARAM("components")))
     290             :             {
     291         980 :                 state = STATE_COMPONENTS;
     292         980 :                 break;
     293             :             }
     294             :             throw css::registry::InvalidRegistryException(
     295           0 :                 reader_.getUrl() + ": unexpected item in outer level",
     296           0 :                 css::uno::Reference< css::uno::XInterface >());
     297             :         case STATE_END:
     298         980 :             if (res == xmlreader::XmlReader::RESULT_DONE) {
     299         980 :                 return;
     300             :             }
     301             :             throw css::registry::InvalidRegistryException(
     302           0 :                 reader_.getUrl() + ": unexpected item in outer level",
     303           0 :                 css::uno::Reference< css::uno::XInterface >());
     304             :         case STATE_COMPONENTS:
     305        6366 :             if (res == xmlreader::XmlReader::RESULT_END) {
     306         980 :                 state = STATE_END;
     307         980 :                 break;
     308             :             }
     309       10772 :             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
     310        5386 :                 && name.equals(RTL_CONSTASCII_STRINGPARAM("component")))
     311             :             {
     312        5386 :                 handleComponent();
     313        5386 :                 state = STATE_COMPONENT_INITIAL;
     314        5386 :                 break;
     315             :             }
     316             :             throw css::registry::InvalidRegistryException(
     317           0 :                 reader_.getUrl() + ": unexpected item in <components>",
     318           0 :                 css::uno::Reference< css::uno::XInterface >());
     319             :         case STATE_COMPONENT:
     320       20720 :             if (res == xmlreader::XmlReader::RESULT_END) {
     321        5386 :                 state = STATE_COMPONENTS;
     322        5386 :                 break;
     323             :             }
     324             :             // fall through
     325             :         case STATE_COMPONENT_INITIAL:
     326       41440 :             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
     327       20720 :                 && name.equals(RTL_CONSTASCII_STRINGPARAM("implementation")))
     328             :             {
     329       20720 :                 handleImplementation();
     330       20720 :                 state = STATE_IMPLEMENTATION;
     331       20720 :                 break;
     332             :             }
     333             :             throw css::registry::InvalidRegistryException(
     334           0 :                 reader_.getUrl() + ": unexpected item in <component>",
     335           0 :                 css::uno::Reference< css::uno::XInterface >());
     336             :         case STATE_IMPLEMENTATION:
     337       44120 :             if (res == xmlreader::XmlReader::RESULT_END) {
     338       20720 :                 state = STATE_COMPONENT;
     339       20720 :                 break;
     340             :             }
     341       46800 :             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
     342       23400 :                 && name.equals(RTL_CONSTASCII_STRINGPARAM("service")))
     343             :             {
     344       22752 :                 handleService();
     345       22752 :                 state = STATE_SERVICE;
     346       22752 :                 break;
     347             :             }
     348        1296 :             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
     349         648 :                 && name.equals(RTL_CONSTASCII_STRINGPARAM("singleton")))
     350             :             {
     351         648 :                 handleSingleton();
     352         648 :                 state = STATE_SINGLETON;
     353         648 :                 break;
     354             :             }
     355             :             throw css::registry::InvalidRegistryException(
     356           0 :                 reader_.getUrl() + ": unexpected item in <implementation>",
     357           0 :                 css::uno::Reference< css::uno::XInterface >());
     358             :         case STATE_SERVICE:
     359       22752 :             if (res == xmlreader::XmlReader::RESULT_END) {
     360       22752 :                 state = STATE_IMPLEMENTATION;
     361       22752 :                 break;
     362             :             }
     363             :             throw css::registry::InvalidRegistryException(
     364           0 :                 reader_.getUrl() + ": unexpected item in <service>",
     365           0 :                 css::uno::Reference< css::uno::XInterface >());
     366             :         case STATE_SINGLETON:
     367         648 :             if (res == xmlreader::XmlReader::RESULT_END) {
     368         648 :                 state = STATE_IMPLEMENTATION;
     369         648 :                 break;
     370             :             }
     371             :             throw css::registry::InvalidRegistryException(
     372           0 :                 reader_.getUrl() + ": unexpected item in <service>",
     373           0 :                 css::uno::Reference< css::uno::XInterface >());
     374             :         }
     375             :     }
     376             : }
     377             : 
     378        5386 : void Parser::handleComponent() {
     379        5386 :     attrLoader_ = rtl::OUString();
     380        5386 :     attrUri_ = rtl::OUString();
     381        5386 :     attrPrefix_ = rtl::OUString();
     382        5386 :     xmlreader::Span name;
     383             :     int nsId;
     384        5386 :     while (reader_.nextAttribute(&nsId, &name)) {
     385       31264 :         if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
     386       15632 :             && name.equals(RTL_CONSTASCII_STRINGPARAM("loader")))
     387             :         {
     388        5386 :             if (!attrLoader_.isEmpty()) {
     389             :                 throw css::registry::InvalidRegistryException(
     390             :                     (reader_.getUrl()
     391           0 :                      + ": <component> has multiple \"loader\" attributes"),
     392           0 :                     css::uno::Reference< css::uno::XInterface >());
     393             :             }
     394        5386 :             attrLoader_ = reader_.getAttributeValue(false).convertFromUtf8();
     395        5386 :             if (attrLoader_.isEmpty()) {
     396             :                 throw css::registry::InvalidRegistryException(
     397             :                     (reader_.getUrl()
     398           0 :                      + ": <component> has empty \"loader\" attribute"),
     399           0 :                     css::uno::Reference< css::uno::XInterface >());
     400             :             }
     401       20492 :         } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
     402       10246 :                    && name.equals(RTL_CONSTASCII_STRINGPARAM("uri")))
     403             :         {
     404        5386 :             if (!attrUri_.isEmpty()) {
     405             :                 throw css::registry::InvalidRegistryException(
     406             :                     (reader_.getUrl()
     407           0 :                      + ": <component> has multiple \"uri\" attributes"),
     408           0 :                     css::uno::Reference< css::uno::XInterface >());
     409             :             }
     410        5386 :             attrUri_ = reader_.getAttributeValue(false).convertFromUtf8();
     411        5386 :             if (attrUri_.isEmpty()) {
     412             :                 throw css::registry::InvalidRegistryException(
     413             :                     (reader_.getUrl()
     414           0 :                      + ": <component> has empty \"uri\" attribute"),
     415           0 :                     css::uno::Reference< css::uno::XInterface >());
     416             :             }
     417        9720 :         } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
     418        4860 :                    && name.equals(RTL_CONSTASCII_STRINGPARAM("prefix")))
     419             :         {
     420        4860 :             if (!attrPrefix_.isEmpty()) {
     421             :                 throw css::registry::InvalidRegistryException(
     422             :                     (reader_.getUrl() +
     423           0 :                      ": <component> has multiple \"prefix\" attributes"),
     424           0 :                     css::uno::Reference< css::uno::XInterface >());
     425             :             }
     426        4860 :             attrPrefix_ = reader_.getAttributeValue(false).convertFromUtf8();
     427        4860 :             if (attrPrefix_.isEmpty()) {
     428             :                 throw css::registry::InvalidRegistryException(
     429             :                     (reader_.getUrl() +
     430           0 :                      ": <component> has empty \"prefix\" attribute"),
     431           0 :                     css::uno::Reference< css::uno::XInterface >());
     432             :             }
     433             :         } else {
     434             :             throw css::registry::InvalidRegistryException(
     435           0 :                 (reader_.getUrl() + ": unexpected attribute \""
     436           0 :                  + name.convertFromUtf8() + "\" in <component>"),
     437           0 :                 css::uno::Reference< css::uno::XInterface >());
     438             :         }
     439             :     }
     440        5386 :     if (attrLoader_.isEmpty()) {
     441             :         throw css::registry::InvalidRegistryException(
     442           0 :             reader_.getUrl() + ": <component> is missing \"loader\" attribute",
     443           0 :             css::uno::Reference< css::uno::XInterface >());
     444             :     }
     445        5386 :     if (attrUri_.isEmpty()) {
     446             :         throw css::registry::InvalidRegistryException(
     447           0 :             reader_.getUrl() + ": <component> is missing \"uri\" attribute",
     448           0 :             css::uno::Reference< css::uno::XInterface >());
     449             :     }
     450             : #ifndef DISABLE_DYNLOADING
     451             :     try {
     452        5386 :         attrUri_ = rtl::Uri::convertRelToAbs(reader_.getUrl(), attrUri_);
     453           0 :     } catch (const rtl::MalformedUriException & e) {
     454             :         throw css::registry::InvalidRegistryException(
     455           0 :             reader_.getUrl() + ": bad \"uri\" attribute: " + e.getMessage(),
     456           0 :             css::uno::Reference< css::uno::XInterface >());
     457             :     }
     458             : #endif
     459        5386 : }
     460             : 
     461       20720 : void Parser::handleImplementation() {
     462       20720 :     attrImplementation_ = getNameAttribute();
     463             :     implementation_.reset(
     464             :         new Implementation(
     465             :             attrImplementation_, attrLoader_, attrUri_, attrPrefix_,
     466       20720 :             alienContext_, reader_.getUrl()));
     467       41440 :     if (!data_->namedImplementations.insert(
     468             :             NamedImplementations::value_type(
     469       41440 :                 attrImplementation_, implementation_)).
     470       41440 :         second)
     471             :     {
     472             :         throw css::registry::InvalidRegistryException(
     473           0 :             (reader_.getUrl() + ": duplicate <implementation name=\""
     474           0 :              + attrImplementation_ + "\">"),
     475           0 :             css::uno::Reference< css::uno::XInterface >());
     476             :     }
     477       20720 : }
     478             : 
     479       22752 : void Parser::handleService() {
     480       22752 :     rtl::OUString name(getNameAttribute());
     481       22752 :     implementation_->info->services.push_back(name);
     482       22752 :     data_->services[name].push_back(implementation_);
     483       22752 : }
     484             : 
     485         648 : void Parser::handleSingleton() {
     486         648 :     rtl::OUString name(getNameAttribute());
     487         648 :     implementation_->info->singletons.push_back(name);
     488         648 :     data_->singletons[name].push_back(implementation_);
     489         648 : }
     490             : 
     491       44120 : rtl::OUString Parser::getNameAttribute() {
     492       44120 :     rtl::OUString attrName;
     493       44120 :     xmlreader::Span name;
     494             :     int nsId;
     495       44120 :     while (reader_.nextAttribute(&nsId, &name)) {
     496       88240 :         if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
     497       44120 :             && name.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     498             :         {
     499       44120 :             if (!attrName.isEmpty()) {
     500             :                 throw css::registry::InvalidRegistryException(
     501             :                     (reader_.getUrl()
     502           0 :                      + ": element has multiple \"name\" attributes"),
     503           0 :                     css::uno::Reference< css::uno::XInterface >());
     504             :             }
     505       44120 :             attrName = reader_.getAttributeValue(false).convertFromUtf8();
     506       44120 :             if (attrName.isEmpty()) {
     507             :                 throw css::registry::InvalidRegistryException(
     508           0 :                     reader_.getUrl() + ": element has empty \"name\" attribute",
     509           0 :                     css::uno::Reference< css::uno::XInterface >());
     510             :             }
     511             :         } else {
     512             :             throw css::registry::InvalidRegistryException(
     513           0 :                 reader_.getUrl() + ": expected element attribute \"name\"",
     514           0 :                 css::uno::Reference< css::uno::XInterface >());
     515             :         }
     516             :     }
     517       44120 :     if (attrName.isEmpty()) {
     518             :         throw css::registry::InvalidRegistryException(
     519           0 :             reader_.getUrl() + ": element is missing \"name\" attribute",
     520           0 :             css::uno::Reference< css::uno::XInterface >());
     521             :     }
     522       44120 :     return attrName;
     523             : }
     524             : 
     525             : class ContentEnumeration:
     526             :     public cppu::WeakImplHelper1< css::container::XEnumeration >,
     527             :     private boost::noncopyable
     528             : {
     529             : public:
     530          45 :     explicit ContentEnumeration(std::vector< css::uno::Any > const & factories):
     531          45 :         factories_(factories), iterator_(factories_.begin()) {}
     532             : 
     533             : private:
     534          90 :     virtual ~ContentEnumeration() {}
     535             : 
     536             :     virtual sal_Bool SAL_CALL hasMoreElements()
     537             :         throw (css::uno::RuntimeException);
     538             : 
     539             :     virtual css::uno::Any SAL_CALL nextElement()
     540             :         throw (
     541             :             css::container::NoSuchElementException,
     542             :             css::lang::WrappedTargetException, css::uno::RuntimeException);
     543             : 
     544             :     osl::Mutex mutex_;
     545             :     std::vector< css::uno::Any > factories_;
     546             :     std::vector< css::uno::Any >::const_iterator iterator_;
     547             : };
     548             : 
     549          52 : sal_Bool ContentEnumeration::hasMoreElements()
     550             :     throw (css::uno::RuntimeException)
     551             : {
     552          52 :     osl::MutexGuard g(mutex_);
     553          52 :     return iterator_ != factories_.end();
     554             : }
     555             : 
     556           7 : css::uno::Any ContentEnumeration::nextElement()
     557             :     throw (
     558             :         css::container::NoSuchElementException,
     559             :         css::lang::WrappedTargetException, css::uno::RuntimeException)
     560             : {
     561           7 :     osl::MutexGuard g(mutex_);
     562           7 :     if (iterator_ == factories_.end()) {
     563             :         throw css::container::NoSuchElementException(
     564             :             "Bootstrap service manager service enumerator has no more elements",
     565           0 :             static_cast< cppu::OWeakObject * >(this));
     566             :     }
     567           7 :     return *iterator_++;
     568             : }
     569             : 
     570           0 : css::beans::Property getDefaultContextProperty() {
     571             :     return css::beans::Property(
     572             :         "DefaultContext", -1,
     573           0 :         cppu::UnoType< css::uno::XComponentContext >::get(),
     574           0 :         css::beans::PropertyAttribute::READONLY);
     575             : }
     576             : 
     577             : typedef cppu::WeakComponentImplHelper8<
     578             :     css::lang::XServiceInfo, css::lang::XMultiServiceFactory,
     579             :     css::lang::XMultiComponentFactory, css::container::XSet,
     580             :     css::container::XContentEnumerationAccess, css::beans::XPropertySet,
     581             :     css::beans::XPropertySetInfo, css::lang::XEventListener >
     582             : ServiceManagerBase;
     583             : 
     584             : class ServiceManager:
     585             :     private osl::Mutex, public ServiceManagerBase, private boost::noncopyable
     586             : {
     587             : public:
     588         259 :     explicit ServiceManager(rtl::OUString const & rdbUris):
     589         259 :         ServiceManagerBase(*static_cast< osl::Mutex * >(this))
     590         259 :     { readRdbs(rdbUris); }
     591             : 
     592             :     using ServiceManagerBase::acquire;
     593             :     using ServiceManagerBase::release;
     594             : 
     595         259 :     void setContext(
     596             :         css::uno::Reference< css::uno::XComponentContext > const & context)
     597             :     {
     598             :         assert(context.is());
     599             :         assert(!context_.is());
     600         259 :         context_ = context;
     601         259 :     }
     602             : 
     603           0 :     css::uno::Reference< css::uno::XComponentContext > getContext() const {
     604             :         assert(context_.is());
     605           0 :         return context_;
     606             :     }
     607             : 
     608         259 :     Data const & getData() const { return data_; }
     609             : 
     610             :     void loadImplementation(
     611             :         css::uno::Reference< css::uno::XComponentContext > const & context,
     612             :         boost::shared_ptr< ImplementationInfo > const & info,
     613             :         css::uno::Reference< css::lang::XSingleComponentFactory > * factory1,
     614             :         css::uno::Reference< css::lang::XSingleServiceFactory > * factory2);
     615             : 
     616             :     virtual rtl::OUString SAL_CALL getImplementationName()
     617             :         throw (css::uno::RuntimeException);
     618             : 
     619             :     virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
     620             :         throw (css::uno::RuntimeException);
     621             : 
     622             :     virtual css::uno::Sequence< rtl::OUString > SAL_CALL
     623             :     getSupportedServiceNames() throw (css::uno::RuntimeException);
     624             : 
     625             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
     626             :         rtl::OUString const & aServiceSpecifier)
     627             :         throw (css::uno::Exception, css::uno::RuntimeException);
     628             : 
     629             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     630             :     createInstanceWithArguments(
     631             :         rtl::OUString const & ServiceSpecifier,
     632             :         css::uno::Sequence< css::uno::Any > const & Arguments)
     633             :         throw (css::uno::Exception, css::uno::RuntimeException);
     634             : 
     635             :     virtual css::uno::Sequence< rtl::OUString > SAL_CALL
     636             :     getAvailableServiceNames() throw (css::uno::RuntimeException);
     637             : 
     638             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     639             :     createInstanceWithContext(
     640             :         rtl::OUString const & aServiceSpecifier,
     641             :         css::uno::Reference< css::uno::XComponentContext > const & Context)
     642             :         throw (css::uno::Exception, css::uno::RuntimeException);
     643             : 
     644             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     645             :     createInstanceWithArgumentsAndContext(
     646             :         rtl::OUString const & ServiceSpecifier,
     647             :         css::uno::Sequence< css::uno::Any > const & Arguments,
     648             :         css::uno::Reference< css::uno::XComponentContext > const & Context)
     649             :         throw (css::uno::Exception, css::uno::RuntimeException);
     650             : 
     651             :     virtual css::uno::Type SAL_CALL getElementType()
     652             :         throw (css::uno::RuntimeException);
     653             : 
     654             :     virtual sal_Bool SAL_CALL hasElements() throw (css::uno::RuntimeException);
     655             : 
     656             :     virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL
     657             :     createEnumeration() throw (css::uno::RuntimeException);
     658             : 
     659             :     virtual sal_Bool SAL_CALL has(css::uno::Any const & aElement)
     660             :         throw (css::uno::RuntimeException);
     661             : 
     662             :     virtual void SAL_CALL insert(css::uno::Any const & aElement)
     663             :         throw (
     664             :             css::lang::IllegalArgumentException,
     665             :             css::container::ElementExistException, css::uno::RuntimeException);
     666             : 
     667             :     virtual void SAL_CALL remove(css::uno::Any const & aElement)
     668             :         throw (
     669             :             css::lang::IllegalArgumentException,
     670             :             css::container::NoSuchElementException, css::uno::RuntimeException);
     671             : 
     672             :     virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL
     673             :     createContentEnumeration(rtl::OUString const & aServiceName)
     674             :         throw (css::uno::RuntimeException);
     675             : 
     676             :     virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
     677             :     getPropertySetInfo() throw (css::uno::RuntimeException);
     678             : 
     679             :     virtual void SAL_CALL setPropertyValue(
     680             :         rtl::OUString const & aPropertyName, css::uno::Any const & aValue)
     681             :         throw (
     682             :             css::beans::UnknownPropertyException,
     683             :             css::beans::PropertyVetoException,
     684             :             css::lang::IllegalArgumentException,
     685             :             css::lang::WrappedTargetException, css::uno::RuntimeException);
     686             : 
     687             :     virtual css::uno::Any SAL_CALL getPropertyValue(
     688             :         rtl::OUString const & PropertyName)
     689             :         throw (
     690             :             css::beans::UnknownPropertyException,
     691             :             css::lang::WrappedTargetException, css::uno::RuntimeException);
     692             : 
     693             :     virtual void SAL_CALL addPropertyChangeListener(
     694             :         rtl::OUString const & aPropertyName,
     695             :         css::uno::Reference< css::beans::XPropertyChangeListener > const &
     696             :             xListener)
     697             :         throw (
     698             :             css::beans::UnknownPropertyException,
     699             :             css::lang::WrappedTargetException, css::uno::RuntimeException);
     700             : 
     701             :     virtual void SAL_CALL removePropertyChangeListener(
     702             :         rtl::OUString const & aPropertyName,
     703             :         css::uno::Reference< css::beans::XPropertyChangeListener > const &
     704             :             aListener)
     705             :         throw (
     706             :             css::beans::UnknownPropertyException,
     707             :             css::lang::WrappedTargetException, css::uno::RuntimeException);
     708             : 
     709             :     virtual void SAL_CALL addVetoableChangeListener(
     710             :         rtl::OUString const & PropertyName,
     711             :         css::uno::Reference< css::beans::XVetoableChangeListener > const &
     712             :             aListener)
     713             :         throw (
     714             :             css::beans::UnknownPropertyException,
     715             :             css::lang::WrappedTargetException, css::uno::RuntimeException);
     716             : 
     717             :     virtual void SAL_CALL removeVetoableChangeListener(
     718             :         rtl::OUString const & PropertyName,
     719             :         css::uno::Reference< css::beans::XVetoableChangeListener > const &
     720             :             aListener)
     721             :         throw (
     722             :             css::beans::UnknownPropertyException,
     723             :             css::lang::WrappedTargetException, css::uno::RuntimeException);
     724             : 
     725             :     virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties()
     726             :         throw (css::uno::RuntimeException);
     727             : 
     728             :     virtual css::beans::Property SAL_CALL getPropertyByName(
     729             :         rtl::OUString const & aName)
     730             :         throw (
     731             :             css::beans::UnknownPropertyException, css::uno::RuntimeException);
     732             : 
     733             :     virtual sal_Bool SAL_CALL hasPropertyByName(rtl::OUString const & Name)
     734             :         throw (css::uno::RuntimeException);
     735             : 
     736             :     virtual void SAL_CALL disposing(css::lang::EventObject const & Source)
     737             :         throw (css::uno::RuntimeException);
     738             : 
     739             : private:
     740          40 :     virtual ~ServiceManager() {}
     741             : 
     742             :     virtual void SAL_CALL disposing();
     743             : 
     744             :     // needs to be called with rBHelper.rMutex locked:
     745        1956 :     bool isDisposed() { return rBHelper.bDisposed || rBHelper.bInDispose; }
     746             : 
     747             :     void removeEventListenerFromComponent(
     748             :         css::uno::Reference< css::lang::XComponent > const & component);
     749             : 
     750             :     void readRdbs(rtl::OUString const & uris);
     751             : 
     752             :     void readRdbDirectory(rtl::OUString const & uri, bool optional);
     753             : 
     754             :     void readRdbFile(rtl::OUString const & uri, bool optional);
     755             : 
     756             :     bool readLegacyRdbFile(rtl::OUString const & uri);
     757             : 
     758             :     rtl::OUString readLegacyRdbString(
     759             :         rtl::OUString const & uri, RegistryKey & key,
     760             :         rtl::OUString const & path);
     761             : 
     762             :     void readLegacyRdbStrings(
     763             :         rtl::OUString const & uri, RegistryKey & key,
     764             :         rtl::OUString const & path, std::vector< rtl::OUString > * strings);
     765             : 
     766             :     void insertRdbFiles(
     767             :         std::vector< rtl::OUString > const & uris,
     768             :         css::uno::Reference< css::uno::XComponentContext > const &
     769             :             alientContext);
     770             : 
     771             :     void insertLegacyFactory(
     772             :         css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo);
     773             : 
     774             :     bool insertExtraData(Data const & extra);
     775             : 
     776             :     void removeRdbFiles(std::vector< rtl::OUString > const & uris);
     777             : 
     778             :     bool removeLegacyFactory(
     779             :         css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo,
     780             :         bool removeListener);
     781             : 
     782             :     void removeImplementation(rtl::OUString name);
     783             : 
     784             :     boost::shared_ptr< Implementation > findServiceImplementation(
     785             :         css::uno::Reference< css::uno::XComponentContext > const & context,
     786             :         rtl::OUString const & specifier);
     787             : 
     788             :     css::uno::Reference< css::uno::XComponentContext > context_;
     789             :     Data data_;
     790             : };
     791             : 
     792             : class FactoryWrapper:
     793             :     public cppu::WeakImplHelper3<
     794             :         css::lang::XSingleComponentFactory, css::lang::XSingleServiceFactory,
     795             :         css::lang::XServiceInfo >,
     796             :     private boost::noncopyable
     797             : {
     798             : public:
     799           7 :     FactoryWrapper(
     800             :         rtl::Reference< ServiceManager > const & manager,
     801             :         boost::shared_ptr< ImplementationInfo > const & info):
     802           7 :         manager_(manager), info_(info), loaded_(false)
     803           7 :     { assert(manager.is() && info.get() != 0); }
     804             : 
     805             : private:
     806          14 :     virtual ~FactoryWrapper() {}
     807             : 
     808             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     809             :     createInstanceWithContext(
     810             :         css::uno::Reference< css::uno::XComponentContext > const & Context)
     811             :         throw (css::uno::Exception, css::uno::RuntimeException);
     812             : 
     813             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     814             :     createInstanceWithArgumentsAndContext(
     815             :         css::uno::Sequence< css::uno::Any > const & Arguments,
     816             :         css::uno::Reference< css::uno::XComponentContext > const & Context)
     817             :         throw (css::uno::Exception, css::uno::RuntimeException);
     818             : 
     819             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     820             :     createInstance() throw (css::uno::Exception, css::uno::RuntimeException);
     821             : 
     822             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     823             :     createInstanceWithArguments(
     824             :         css::uno::Sequence< css::uno::Any > const & Arguments)
     825             :         throw (css::uno::Exception, css::uno::RuntimeException);
     826             : 
     827             :     virtual rtl::OUString SAL_CALL getImplementationName()
     828             :         throw (css::uno::RuntimeException);
     829             : 
     830             :     virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
     831             :         throw (css::uno::RuntimeException);
     832             : 
     833             :     virtual css::uno::Sequence< rtl::OUString > SAL_CALL
     834             :     getSupportedServiceNames() throw (css::uno::RuntimeException);
     835             : 
     836             :     void loadImplementation(
     837             :         css::uno::Reference< css::uno::XComponentContext > const & context);
     838             : 
     839             :     rtl::Reference< ServiceManager > manager_;
     840             :     boost::shared_ptr< ImplementationInfo > info_;
     841             : 
     842             :     osl::Mutex mutex_;
     843             :     bool loaded_;
     844             :     css::uno::Reference< css::lang::XSingleComponentFactory > factory1_;
     845             :     css::uno::Reference< css::lang::XSingleServiceFactory > factory2_;
     846             : };
     847             : 
     848        1854 : void ServiceManager::loadImplementation(
     849             :         css::uno::Reference< css::uno::XComponentContext > const & context,
     850             :         boost::shared_ptr< ImplementationInfo > const & info,
     851             :         css::uno::Reference< css::lang::XSingleComponentFactory > * factory1,
     852             :         css::uno::Reference< css::lang::XSingleServiceFactory > * factory2)
     853             : {
     854             :     assert(
     855             :         info.get() != 0 && factory1 != 0 && !factory1->is() && factory2 != 0
     856             :         && !factory2->is());
     857        1854 :     rtl::OUString uri;
     858             :     try {
     859        1854 :         uri = cppu::bootstrap_expandUri(info->uri);
     860           0 :     } catch (css::lang::IllegalArgumentException & e) {
     861             :         throw css::uno::DeploymentException(
     862           0 :             "Cannot expand URI" + info->uri + ": " + e.Message,
     863           0 :             static_cast< cppu::OWeakObject * >(this));
     864             :     }
     865        1854 :     css::uno::Reference< css::uno::XInterface > f0;
     866             :     // Shortcut loading via SharedLibrary loader, to pass in prefix argument
     867             :     // (which the loader's activate implementation would normally obtain through
     868             :     // the legacy xKey argument):
     869        3708 :     if (!info->alienContext.is()
     870        1854 :         && info->loader == "com.sun.star.loader.SharedLibrary")
     871             :     {
     872        1854 :         rtl::OUString prefix(info->prefix);
     873        1854 :         if (!prefix.isEmpty()) {
     874        1331 :             prefix += "_";
     875             :         }
     876             :         f0 = cppu::loadSharedLibComponentFactory(
     877        1854 :             uri, rtl::OUString(), info->name, this,
     878        3708 :             css::uno::Reference< css::registry::XRegistryKey >(), prefix);
     879             :     } else {
     880             :         SAL_INFO_IF(
     881             :             !info->prefix.isEmpty(), "cppuhelper",
     882             :             "Loader " << info->loader << " and non-empty prefix "
     883             :                 << info->prefix);
     884           0 :         css::uno::Reference< css::uno::XComponentContext > ctxt;
     885           0 :         css::uno::Reference< css::lang::XMultiComponentFactory > smgr;
     886           0 :         if (info->alienContext.is()) {
     887           0 :             ctxt = info->alienContext;
     888             :             smgr = css::uno::Reference< css::lang::XMultiComponentFactory >(
     889           0 :                 ctxt->getServiceManager(), css::uno::UNO_SET_THROW);
     890             :         } else {
     891             :             assert(context.is());
     892           0 :             ctxt = context;
     893           0 :             smgr = this;
     894             :         }
     895             :         css::uno::Reference< css::loader::XImplementationLoader > loader(
     896           0 :             smgr->createInstanceWithContext(info->loader, ctxt),
     897           0 :             css::uno::UNO_QUERY_THROW);
     898           0 :         f0 = loader->activate(
     899           0 :             info->name, rtl::OUString(), uri,
     900           0 :             css::uno::Reference< css::registry::XRegistryKey >());
     901             :     }
     902        1854 :     factory1->set(f0, css::uno::UNO_QUERY);
     903        1854 :     if (!factory1->is()) {
     904          15 :         factory2->set(f0, css::uno::UNO_QUERY);
     905        1854 :     }
     906        1854 : }
     907             : 
     908           0 : rtl::OUString ServiceManager::getImplementationName()
     909             :     throw (css::uno::RuntimeException)
     910             : {
     911             :     return rtl::OUString(
     912           0 :         "com.sun.star.comp.cppuhelper.bootstrap.ServiceManager");
     913             : }
     914             : 
     915           0 : sal_Bool ServiceManager::supportsService(rtl::OUString const & ServiceName)
     916             :     throw (css::uno::RuntimeException)
     917             : {
     918           0 :     return cppu::supportsService(this, ServiceName);
     919             : }
     920             : 
     921           0 : css::uno::Sequence< rtl::OUString > ServiceManager::getSupportedServiceNames()
     922             :     throw (css::uno::RuntimeException)
     923             : {
     924           0 :     css::uno::Sequence< rtl::OUString > names(2);
     925           0 :     names[0] = "com.sun.star.lang.MultiServiceFactory";
     926           0 :     names[1] = "com.sun.star.lang.ServiceManager";
     927           0 :     return names;
     928             : }
     929             : 
     930       50982 : css::uno::Reference< css::uno::XInterface > ServiceManager::createInstance(
     931             :     rtl::OUString const & aServiceSpecifier)
     932             :     throw (css::uno::Exception, css::uno::RuntimeException)
     933             : {
     934             :     assert(context_.is());
     935       50982 :     return createInstanceWithContext(aServiceSpecifier, context_);
     936             : }
     937             : 
     938             : css::uno::Reference< css::uno::XInterface >
     939        7386 : ServiceManager::createInstanceWithArguments(
     940             :     rtl::OUString const & ServiceSpecifier,
     941             :     css::uno::Sequence< css::uno::Any > const & Arguments)
     942             :     throw (css::uno::Exception, css::uno::RuntimeException)
     943             : {
     944             :     assert(context_.is());
     945             :     return createInstanceWithArgumentsAndContext(
     946        7386 :         ServiceSpecifier, Arguments, context_);
     947             : }
     948             : 
     949           0 : css::uno::Sequence< rtl::OUString > ServiceManager::getAvailableServiceNames()
     950             :     throw (css::uno::RuntimeException)
     951             : {
     952           0 :     osl::MutexGuard g(rBHelper.rMutex);
     953           0 :     if (isDisposed()) {
     954           0 :         return css::uno::Sequence< rtl::OUString >();
     955             :     }
     956           0 :     ImplementationMap::size_type n = data_.services.size();
     957           0 :     if (n > static_cast< sal_uInt32 >(SAL_MAX_INT32)) {
     958             :         throw css::uno::RuntimeException(
     959             :             "getAvailableServiceNames: too many services",
     960           0 :             static_cast< cppu::OWeakObject * >(this));
     961             :     }
     962           0 :     css::uno::Sequence< rtl::OUString > names(static_cast< sal_Int32 >(n));
     963           0 :     sal_Int32 i = 0;
     964           0 :     for (ImplementationMap::const_iterator j(data_.services.begin());
     965           0 :          j != data_.services.end(); ++j)
     966             :     {
     967           0 :         names[i++] = j->first;
     968             :     }
     969             :     assert(i == names.getLength());
     970           0 :     return names;
     971             : }
     972             : 
     973             : css::uno::Reference< css::uno::XInterface >
     974      126259 : ServiceManager::createInstanceWithContext(
     975             :     rtl::OUString const & aServiceSpecifier,
     976             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
     977             :     throw (css::uno::Exception, css::uno::RuntimeException)
     978             : {
     979             :     boost::shared_ptr< Implementation > impl(
     980      126259 :         findServiceImplementation(Context, aServiceSpecifier));
     981      126259 :     if (impl.get() == 0) {
     982       19913 :         return css::uno::Reference< css::uno::XInterface >();
     983             :     }
     984      106346 :     if (impl->factory1.is()) {
     985      106114 :         return impl->factory1->createInstanceWithContext(Context);
     986             :     }
     987         232 :     if (impl->factory2.is()) {
     988         232 :         return impl->factory2->createInstance();
     989             :     }
     990             :     throw css::uno::DeploymentException(
     991           0 :         "Implementation " + impl->info->name + " does not provide a factory",
     992           0 :         static_cast< cppu::OWeakObject * >(this));
     993             : }
     994             : 
     995             : css::uno::Reference< css::uno::XInterface >
     996       27448 : ServiceManager::createInstanceWithArgumentsAndContext(
     997             :     rtl::OUString const & ServiceSpecifier,
     998             :     css::uno::Sequence< css::uno::Any > const & Arguments,
     999             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
    1000             :     throw (css::uno::Exception, css::uno::RuntimeException)
    1001             : {
    1002             :     boost::shared_ptr< Implementation > impl(
    1003       27448 :         findServiceImplementation(Context, ServiceSpecifier));
    1004       27448 :     if (impl.get() == 0) {
    1005        5954 :         return css::uno::Reference< css::uno::XInterface >();
    1006             :     }
    1007       21494 :     if (impl->factory1.is()) {
    1008       21409 :         return impl->factory1->createInstanceWithArgumentsAndContext(
    1009       21409 :             Arguments, Context);
    1010             :     }
    1011          85 :     if (impl->factory2.is()) {
    1012          85 :         return impl->factory2->createInstanceWithArguments(Arguments);
    1013             :     }
    1014             :     throw css::uno::DeploymentException(
    1015           0 :         "Implementation " + impl->info->name + " does not provide a factory",
    1016           0 :         static_cast< cppu::OWeakObject * >(this));
    1017             : }
    1018             : 
    1019           0 : css::uno::Type ServiceManager::getElementType()
    1020             :     throw (css::uno::RuntimeException)
    1021             : {
    1022           0 :     return css::uno::Type();
    1023             : }
    1024             : 
    1025           0 : sal_Bool ServiceManager::hasElements() throw (css::uno::RuntimeException) {
    1026           0 :     osl::MutexGuard g(rBHelper.rMutex);
    1027             :     return
    1028           0 :         !(data_.namedImplementations.empty()
    1029           0 :           && data_.dynamicImplementations.empty());
    1030             : }
    1031             : 
    1032             : css::uno::Reference< css::container::XEnumeration >
    1033           0 : ServiceManager::createEnumeration() throw (css::uno::RuntimeException) {
    1034             :     throw css::uno::RuntimeException(
    1035             :         "ServiceManager createEnumeration: method not supported",
    1036           0 :         static_cast< cppu::OWeakObject * >(this));
    1037             : }
    1038             : 
    1039           0 : sal_Bool ServiceManager::has(css::uno::Any const &)
    1040             :     throw (css::uno::RuntimeException)
    1041             : {
    1042             :     throw css::uno::RuntimeException(
    1043             :         "ServiceManager has: method not supported",
    1044           0 :         static_cast< cppu::OWeakObject * >(this));
    1045             : }
    1046             : 
    1047         102 : void ServiceManager::insert(css::uno::Any const & aElement)
    1048             :     throw (
    1049             :         css::lang::IllegalArgumentException,
    1050             :         css::container::ElementExistException, css::uno::RuntimeException)
    1051             : {
    1052         102 :     css::uno::Sequence< css::beans::NamedValue > args;
    1053         102 :     if (aElement >>= args) {
    1054           0 :         std::vector< rtl::OUString > uris;
    1055           0 :         css::uno::Reference< css::uno::XComponentContext > alienContext;
    1056           0 :         for (sal_Int32 i = 0; i < args.getLength(); ++i) {
    1057           0 :             if (args[i].Name == "uri") {
    1058           0 :                 rtl::OUString uri;
    1059           0 :                 if (!(args[i].Value >>= uri)) {
    1060             :                     throw css::lang::IllegalArgumentException(
    1061             :                         "Bad uri argument",
    1062           0 :                         static_cast< cppu::OWeakObject * >(this), 0);
    1063             :                 }
    1064           0 :                 uris.push_back(uri);
    1065           0 :             } else if (args[i].Name == "component-context") {
    1066           0 :                 if (alienContext.is()) {
    1067             :                     throw css::lang::IllegalArgumentException(
    1068             :                         "Multiple component-context arguments",
    1069           0 :                         static_cast< cppu::OWeakObject * >(this), 0);
    1070             :                 }
    1071           0 :                 if (!(args[i].Value >>= alienContext) || !alienContext.is()) {
    1072             :                     throw css::lang::IllegalArgumentException(
    1073             :                         "Bad component-context argument",
    1074           0 :                         static_cast< cppu::OWeakObject * >(this), 0);
    1075             :                 }
    1076             :             } else {
    1077             :                 throw css::lang::IllegalArgumentException(
    1078           0 :                     "Bad argument " + args[i].Name,
    1079           0 :                     static_cast< cppu::OWeakObject * >(this), 0);
    1080             :             }
    1081             :         }
    1082           0 :         insertRdbFiles(uris, alienContext);
    1083           0 :         return;
    1084             :     }
    1085         102 :     css::uno::Reference< css::lang::XServiceInfo > info;
    1086         102 :     if ((aElement >>= info) && info.is()) {
    1087         102 :         insertLegacyFactory(info);
    1088             :         return;
    1089             :     }
    1090             : // At least revisions up to 1.7 of LanguageTool.oxt (incl. the bundled 1.4.0 in
    1091             : // module languagetool) contain an (actively registered) factory that does not
    1092             : // implement XServiceInfo (see <http://sourceforge.net/tracker/?
    1093             : // func=detail&aid=3526635&group_id=110216&atid=655717> "SingletonFactory should
    1094             : // implement XServiceInfo"); the old OServiceManager::insert
    1095             : // (stoc/source/servicemanager/servicemanager.cxx) silently did not add such
    1096             : // broken factories to its m_ImplementationNameMap, so ignore them here for
    1097             : // backwards compatibility of live-insertion of extensions, too.
    1098             : 
    1099             : // (The plan was that this warning would go away (and we would do the
    1100             : // throw instead) for the incompatible LO 4, but we changed our mind):
    1101           0 :     css::uno::Reference< css::lang::XSingleComponentFactory > legacy;
    1102           0 :     if ((aElement >>= legacy) && legacy.is()) {
    1103             :         SAL_WARN(
    1104             :             "cppuhelper",
    1105             :             "Ignored XSingleComponentFactory not implementing XServiceInfo");
    1106             :         return;
    1107             :     }
    1108             : 
    1109             :     throw css::lang::IllegalArgumentException(
    1110           0 :         "Bad insert element", static_cast< cppu::OWeakObject * >(this), 0);
    1111             : }
    1112             : 
    1113           0 : void ServiceManager::remove(css::uno::Any const & aElement)
    1114             :     throw (
    1115             :         css::lang::IllegalArgumentException,
    1116             :         css::container::NoSuchElementException, css::uno::RuntimeException)
    1117             : {
    1118           0 :     css::uno::Sequence< css::beans::NamedValue > args;
    1119           0 :     if (aElement >>= args) {
    1120           0 :         std::vector< rtl::OUString > uris;
    1121           0 :         for (sal_Int32 i = 0; i < args.getLength(); ++i) {
    1122           0 :             if (args[i].Name == "uri") {
    1123           0 :                 rtl::OUString uri;
    1124           0 :                 if (!(args[i].Value >>= uri)) {
    1125             :                     throw css::lang::IllegalArgumentException(
    1126             :                         "Bad uri argument",
    1127           0 :                         static_cast< cppu::OWeakObject * >(this), 0);
    1128             :                 }
    1129           0 :                 uris.push_back(uri);
    1130             :             } else {
    1131             :                 throw css::lang::IllegalArgumentException(
    1132           0 :                     "Bad argument " + args[i].Name,
    1133           0 :                     static_cast< cppu::OWeakObject * >(this), 0);
    1134             :             }
    1135             :         }
    1136           0 :         removeRdbFiles(uris);
    1137           0 :         return;
    1138             :     }
    1139           0 :     css::uno::Reference< css::lang::XServiceInfo > info;
    1140           0 :     if ((aElement >>= info) && info.is()) {
    1141           0 :         if (!removeLegacyFactory(info, true)) {
    1142             :             throw css::container::NoSuchElementException(
    1143             :                 "Remove non-inserted factory object",
    1144           0 :                 static_cast< cppu::OWeakObject * >(this));
    1145             :         }
    1146             :         return;
    1147             :     }
    1148           0 :     rtl::OUString impl;
    1149           0 :     if (aElement >>= impl) {
    1150             :         // For live-removal of extensions:
    1151           0 :         removeImplementation(impl);
    1152             :         return;
    1153             :     }
    1154             :     throw css::lang::IllegalArgumentException(
    1155           0 :         "Bad remove element", static_cast< cppu::OWeakObject * >(this), 0);
    1156             : }
    1157             : 
    1158             : css::uno::Reference< css::container::XEnumeration >
    1159          45 : ServiceManager::createContentEnumeration(rtl::OUString const & aServiceName)
    1160             :     throw (css::uno::RuntimeException)
    1161             : {
    1162          45 :     std::vector< boost::shared_ptr< Implementation > > impls;
    1163             :     {
    1164          45 :         osl::MutexGuard g(rBHelper.rMutex);
    1165          45 :         ImplementationMap::const_iterator i(data_.services.find(aServiceName));
    1166          45 :         if (i != data_.services.end()) {
    1167           4 :             impls = i->second;
    1168          45 :         }
    1169             :     }
    1170          45 :     std::vector< css::uno::Any > factories;
    1171         156 :     for (std::vector< boost::shared_ptr< Implementation > >::const_iterator i(
    1172          45 :              impls.begin());
    1173         104 :          i != impls.end(); ++i)
    1174             :     {
    1175           7 :         Implementation * impl = i->get();
    1176             :         assert(impl != 0);
    1177             :         {
    1178           7 :             osl::MutexGuard g(rBHelper.rMutex);
    1179           7 :             if (isDisposed()) {
    1180           0 :                 factories.clear();
    1181             :                 break;
    1182             :             }
    1183           7 :             if (!impl->loaded) {
    1184             :                 // Postpone actual factory instantiation as long as possible (so
    1185             :                 // that e.g. opening LO's "Tools - Macros" menu does not try to
    1186             :                 // instantiate a JVM, which can lead to a synchronous error
    1187             :                 // dialog when no JVM is specified, and showing the dialog while
    1188             :                 // hovering over a menu can cause trouble):
    1189           7 :                 impl->factory1 = new FactoryWrapper(this, impl->info);
    1190           7 :                 impl->loaded = true;
    1191           7 :             }
    1192             :         }
    1193           7 :         if (impl->factory1.is()) {
    1194           7 :             factories.push_back(css::uno::makeAny(impl->factory1));
    1195           0 :         } else if (impl->factory2.is()) {
    1196           0 :             factories.push_back(css::uno::makeAny(impl->factory2));
    1197             :         } else {
    1198             :             throw css::uno::DeploymentException(
    1199           0 :                 ("Implementation " + impl->info->name
    1200           0 :                  + " does not provide a factory"),
    1201           0 :                 static_cast< cppu::OWeakObject * >(this));
    1202             :         }
    1203             :     }
    1204          45 :     return new ContentEnumeration(factories);
    1205             : }
    1206             : 
    1207             : css::uno::Reference< css::beans::XPropertySetInfo >
    1208           0 : ServiceManager::getPropertySetInfo() throw (css::uno::RuntimeException) {
    1209           0 :     return this;
    1210             : }
    1211             : 
    1212           0 : void ServiceManager::setPropertyValue(
    1213             :     rtl::OUString const & aPropertyName, css::uno::Any const &)
    1214             :     throw (
    1215             :         css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
    1216             :         css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
    1217             :         css::uno::RuntimeException)
    1218             : {
    1219           0 :     if (aPropertyName == "DefaultContext") {
    1220             :         throw css::beans::PropertyVetoException(
    1221           0 :             aPropertyName, static_cast< cppu::OWeakObject * >(this));
    1222             :     } else {
    1223             :         throw css::beans::UnknownPropertyException(
    1224           0 :             aPropertyName, static_cast< cppu::OWeakObject * >(this));
    1225             :     }
    1226             : }
    1227             : 
    1228      101698 : css::uno::Any ServiceManager::getPropertyValue(
    1229             :     rtl::OUString const & PropertyName)
    1230             :     throw (
    1231             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1232             :         css::uno::RuntimeException)
    1233             : {
    1234      101698 :     if (PropertyName != "DefaultContext") {
    1235             :         throw css::beans::UnknownPropertyException(
    1236           0 :             PropertyName, static_cast< cppu::OWeakObject * >(this));
    1237             :     }
    1238             :     assert(context_.is());
    1239      101698 :     return css::uno::makeAny(context_);
    1240             : }
    1241             : 
    1242           0 : void ServiceManager::addPropertyChangeListener(
    1243             :     rtl::OUString const & aPropertyName,
    1244             :     css::uno::Reference< css::beans::XPropertyChangeListener > const &
    1245             :         xListener)
    1246             :     throw (
    1247             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1248             :         css::uno::RuntimeException)
    1249             : {
    1250           0 :     if (!aPropertyName.isEmpty() && aPropertyName != "DefaultContext") {
    1251             :         throw css::beans::UnknownPropertyException(
    1252           0 :             aPropertyName, static_cast< cppu::OWeakObject * >(this));
    1253             :     }
    1254             :     // DefaultContext does not change, so just treat it as an event listener:
    1255           0 :     return addEventListener(xListener.get());
    1256             : }
    1257             : 
    1258           0 : void ServiceManager::removePropertyChangeListener(
    1259             :     rtl::OUString const & aPropertyName,
    1260             :     css::uno::Reference< css::beans::XPropertyChangeListener > const &
    1261             :         aListener)
    1262             :     throw (
    1263             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1264             :         css::uno::RuntimeException)
    1265             : {
    1266           0 :     if (!aPropertyName.isEmpty() && aPropertyName != "DefaultContext") {
    1267             :         throw css::beans::UnknownPropertyException(
    1268           0 :             aPropertyName, static_cast< cppu::OWeakObject * >(this));
    1269             :     }
    1270             :     // DefaultContext does not change, so just treat it as an event listener:
    1271           0 :     return removeEventListener(aListener.get());
    1272             : }
    1273             : 
    1274           0 : void ServiceManager::addVetoableChangeListener(
    1275             :     rtl::OUString const & PropertyName,
    1276             :     css::uno::Reference< css::beans::XVetoableChangeListener > const &
    1277             :         aListener)
    1278             :     throw (
    1279             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1280             :         css::uno::RuntimeException)
    1281             : {
    1282           0 :     if (!PropertyName.isEmpty() && PropertyName != "DefaultContext") {
    1283             :         throw css::beans::UnknownPropertyException(
    1284           0 :             PropertyName, static_cast< cppu::OWeakObject * >(this));
    1285             :     }
    1286             :     // DefaultContext does not change, so just treat it as an event listener:
    1287           0 :     return addEventListener(aListener.get());
    1288             : }
    1289             : 
    1290           0 : void ServiceManager::removeVetoableChangeListener(
    1291             :     rtl::OUString const & PropertyName,
    1292             :     css::uno::Reference< css::beans::XVetoableChangeListener > const &
    1293             :         aListener)
    1294             :     throw (
    1295             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1296             :         css::uno::RuntimeException)
    1297             : {
    1298           0 :     if (!PropertyName.isEmpty() && PropertyName != "DefaultContext") {
    1299             :         throw css::beans::UnknownPropertyException(
    1300           0 :             PropertyName, static_cast< cppu::OWeakObject * >(this));
    1301             :     }
    1302             :     // DefaultContext does not change, so just treat it as an event listener:
    1303           0 :     return removeEventListener(aListener.get());
    1304             : }
    1305             : 
    1306           0 : css::uno::Sequence< css::beans::Property > ServiceManager::getProperties()
    1307             :     throw (css::uno::RuntimeException)
    1308             : {
    1309           0 :     css::uno::Sequence< css::beans::Property > props(1);
    1310           0 :     props[0] = getDefaultContextProperty();
    1311           0 :     return props;
    1312             : }
    1313             : 
    1314           0 : css::beans::Property ServiceManager::getPropertyByName(
    1315             :     rtl::OUString const & aName)
    1316             :     throw (css::beans::UnknownPropertyException, css::uno::RuntimeException)
    1317             : {
    1318           0 :     if (aName != "DefaultContext") {
    1319             :         throw css::beans::UnknownPropertyException(
    1320           0 :             aName, static_cast< cppu::OWeakObject * >(this));
    1321             :     }
    1322           0 :     return getDefaultContextProperty();
    1323             : }
    1324             : 
    1325           0 : sal_Bool ServiceManager::hasPropertyByName(rtl::OUString const & Name)
    1326             :     throw (css::uno::RuntimeException)
    1327             : {
    1328           0 :     return Name == "DefaultContext";
    1329             : }
    1330             : 
    1331           0 : void ServiceManager::disposing(css::lang::EventObject const & Source)
    1332             :     throw (css::uno::RuntimeException)
    1333             : {
    1334             :     removeLegacyFactory(
    1335             :         css::uno::Reference< css::lang::XServiceInfo >(
    1336             :             Source.Source, css::uno::UNO_QUERY_THROW),
    1337           0 :         false);
    1338           0 : }
    1339             : 
    1340          39 : void ServiceManager::disposing() {
    1341          39 :     std::vector< css::uno::Reference< css::lang::XComponent > > comps;
    1342          39 :     Data clear;
    1343             :     {
    1344          39 :         osl::MutexGuard g(rBHelper.rMutex);
    1345         423 :         for (DynamicImplementations::const_iterator i(
    1346          39 :                  data_.dynamicImplementations.begin());
    1347         282 :              i != data_.dynamicImplementations.end(); ++i)
    1348             :         {
    1349             :             assert(i->second.get() != 0);
    1350         102 :             if (i->second->component.is()) {
    1351         102 :                 comps.push_back(i->second->component);
    1352             :             }
    1353             :         }
    1354          39 :         data_.namedImplementations.swap(clear.namedImplementations);
    1355          39 :         data_.dynamicImplementations.swap(clear.dynamicImplementations);
    1356          39 :         data_.services.swap(clear.services);
    1357          39 :         data_.singletons.swap(clear.singletons);
    1358             :     }
    1359         423 :     for (std::vector<
    1360             :              css::uno::Reference< css::lang::XComponent > >::const_iterator i(
    1361          39 :                  comps.begin());
    1362         282 :          i != comps.end(); ++i)
    1363             :     {
    1364         102 :         removeEventListenerFromComponent(*i);
    1365          39 :     }
    1366          39 : }
    1367             : 
    1368         102 : void ServiceManager::removeEventListenerFromComponent(
    1369             :     css::uno::Reference< css::lang::XComponent > const & component)
    1370             : {
    1371             :     assert(component.is());
    1372             :     try {
    1373         102 :         component->removeEventListener(this);
    1374           0 :     } catch (css::uno::RuntimeException & e) {
    1375             :         SAL_INFO(
    1376             :             "cppuhelper",
    1377             :             "Ignored removeEventListener RuntimeException " + e.Message);
    1378             :     }
    1379         102 : }
    1380             : 
    1381         259 : void ServiceManager::readRdbs(rtl::OUString const & uris) {
    1382        1498 :     for (sal_Int32 i = 0; i != -1;) {
    1383         980 :         rtl::OUString uri(uris.getToken(0, ' ', i));
    1384         980 :         if (uri.isEmpty()) {
    1385           0 :             continue;
    1386             :         }
    1387             :         bool optional;
    1388             :         bool directory;
    1389         980 :         decodeRdbUri(&uri, &optional, &directory);
    1390         980 :         if (directory) {
    1391           0 :             readRdbDirectory(uri, optional);
    1392             :         } else {
    1393         980 :             readRdbFile(uri, optional);
    1394             :         }
    1395         980 :     }
    1396         259 : }
    1397             : 
    1398           0 : void ServiceManager::readRdbDirectory(rtl::OUString const & uri, bool optional)
    1399             : {
    1400           0 :     osl::Directory dir(uri);
    1401           0 :     switch (dir.open()) {
    1402             :     case osl::FileBase::E_None:
    1403           0 :         break;
    1404             :     case osl::FileBase::E_NOENT:
    1405           0 :         if (optional) {
    1406             :             SAL_INFO("cppuhelper", "Ignored optional " << uri);
    1407           0 :             return;
    1408             :         }
    1409             :         // fall through
    1410             :     default:
    1411             :         throw css::uno::DeploymentException(
    1412             :             "Cannot open directory " + uri,
    1413           0 :             static_cast< cppu::OWeakObject * >(this));
    1414             :     }
    1415           0 :     for (;;) {
    1416           0 :         rtl::OUString url;
    1417           0 :         if (!nextDirectoryItem(dir, &url)) {
    1418             :             break;
    1419             :         }
    1420           0 :         readRdbFile(url, false);
    1421           0 :     }
    1422             : }
    1423             : 
    1424         980 : void ServiceManager::readRdbFile(rtl::OUString const & uri, bool optional) {
    1425             :     try {
    1426             :         Parser(
    1427         980 :             uri, css::uno::Reference< css::uno::XComponentContext >(), &data_);
    1428           0 :     } catch (css::container::NoSuchElementException &) {
    1429           0 :         if (!optional) {
    1430             :             throw css::uno::DeploymentException(
    1431             :                 uri + ": no such file",
    1432           0 :                 static_cast< cppu::OWeakObject * >(this));
    1433             :         }
    1434             :         SAL_INFO("cppuhelper", "Ignored optional " << uri);
    1435           0 :     } catch (css::registry::InvalidRegistryException & e) {
    1436           0 :         if (!readLegacyRdbFile(uri)) {
    1437             :             throw css::uno::DeploymentException(
    1438           0 :                 "InvalidRegistryException: " + e.Message,
    1439           0 :                 static_cast< cppu::OWeakObject * >(this));
    1440             :         }
    1441           0 :     } catch (css::uno::RuntimeException &) {
    1442           0 :         if (!readLegacyRdbFile(uri)) {
    1443           0 :             throw;
    1444             :         }
    1445             :     }
    1446         980 : }
    1447             : 
    1448           0 : bool ServiceManager::readLegacyRdbFile(rtl::OUString const & uri) {
    1449           0 :     Registry reg;
    1450           0 :     switch (reg.open(uri, REG_READONLY)) {
    1451             :     case REG_NO_ERROR:
    1452           0 :         break;
    1453             :     case REG_REGISTRY_NOT_EXISTS:
    1454             :     case REG_INVALID_REGISTRY:
    1455             :         {
    1456             :             // Ignore empty rdb files (which are at least seen by subordinate
    1457             :             // uno processes during extension registration; Registry::open can
    1458             :             // fail on them if mmap(2) returns EINVAL for a zero length):
    1459           0 :             osl::DirectoryItem item;
    1460           0 :             if (osl::DirectoryItem::get(uri, item) == osl::FileBase::E_None) {
    1461           0 :                 osl::FileStatus status(osl_FileStatus_Mask_FileSize);
    1462           0 :                 if (item.getFileStatus(status) == osl::FileBase::E_None
    1463           0 :                     && status.getFileSize() == 0)
    1464             :                 {
    1465           0 :                     return true;
    1466           0 :                 }
    1467           0 :             }
    1468             :         }
    1469             :         // fall through
    1470             :     default:
    1471           0 :         return false;
    1472             :     }
    1473           0 :     RegistryKey rootKey;
    1474           0 :     if (reg.openRootKey(rootKey) != REG_NO_ERROR) {
    1475             :         throw css::uno::DeploymentException(
    1476             :             "Failure reading legacy rdb file " + uri,
    1477           0 :             static_cast< cppu::OWeakObject * >(this));
    1478             :     }
    1479           0 :     RegistryKeyArray impls;
    1480           0 :     switch (rootKey.openSubKeys("IMPLEMENTATIONS", impls)) {
    1481             :     case REG_NO_ERROR:
    1482           0 :         break;
    1483             :     case REG_KEY_NOT_EXISTS:
    1484           0 :         return true;
    1485             :     default:
    1486             :         throw css::uno::DeploymentException(
    1487             :             "Failure reading legacy rdb file " + uri,
    1488           0 :             static_cast< cppu::OWeakObject * >(this));
    1489             :     }
    1490           0 :     for (sal_uInt32 i = 0; i != impls.getLength(); ++i) {
    1491           0 :         RegistryKey implKey(impls.getElement(i));
    1492             :         assert(implKey.getName().match("/IMPLEMENTATIONS/"));
    1493             :         rtl::OUString name(
    1494           0 :             implKey.getName().copy(RTL_CONSTASCII_LENGTH("/IMPLEMENTATIONS/")));
    1495             :         boost::shared_ptr< Implementation > impl(
    1496             :             new Implementation(
    1497             :                 name, readLegacyRdbString(uri, implKey, "UNO/ACTIVATOR"),
    1498             :                 readLegacyRdbString(uri, implKey, "UNO/LOCATION"),
    1499             :                 rtl::OUString(),
    1500           0 :                 css::uno::Reference< css::uno::XComponentContext >(), uri));
    1501           0 :         if (!data_.namedImplementations.insert(
    1502           0 :                 NamedImplementations::value_type(name, impl)).
    1503           0 :             second)
    1504             :         {
    1505             :             throw css::registry::InvalidRegistryException(
    1506           0 :                 uri + ": duplicate <implementation name=\"" + name + "\">",
    1507           0 :                 css::uno::Reference< css::uno::XInterface >());
    1508             :         }
    1509             :         readLegacyRdbStrings(
    1510           0 :             uri, implKey, "UNO/SERVICES", &impl->info->services);
    1511           0 :         for (std::vector< rtl::OUString >::const_iterator j(
    1512           0 :                  impl->info->services.begin());
    1513           0 :              j != impl->info->services.end(); ++j)
    1514             :         {
    1515           0 :             data_.services[*j].push_back(impl);
    1516             :         }
    1517             :         readLegacyRdbStrings(
    1518           0 :             uri, implKey, "UNO/SINGLETONS", &impl->info->singletons);
    1519           0 :         for (std::vector< rtl::OUString >::const_iterator j(
    1520           0 :                  impl->info->singletons.begin());
    1521           0 :              j != impl->info->singletons.end(); ++j)
    1522             :         {
    1523           0 :             data_.singletons[*j].push_back(impl);
    1524             :         }
    1525           0 :     }
    1526           0 :     return true;
    1527             : }
    1528             : 
    1529           0 : rtl::OUString ServiceManager::readLegacyRdbString(
    1530             :     rtl::OUString const & uri, RegistryKey & key, rtl::OUString const & path)
    1531             : {
    1532           0 :     RegistryKey subkey;
    1533             :     RegValueType t;
    1534           0 :     sal_uInt32 s(0);
    1535           0 :     if (key.openKey(path, subkey) != REG_NO_ERROR
    1536           0 :         || subkey.getValueInfo(rtl::OUString(), &t, &s) != REG_NO_ERROR
    1537             :         || t != RG_VALUETYPE_STRING
    1538             :         || s == 0 || s > static_cast< sal_uInt32 >(SAL_MAX_INT32))
    1539             :     {
    1540             :         throw css::uno::DeploymentException(
    1541             :             "Failure reading legacy rdb file " + uri,
    1542           0 :             static_cast< cppu::OWeakObject * >(this));
    1543             :     }
    1544           0 :     rtl::OUString val;
    1545           0 :     std::vector< char > v(s); // assuming sal_uInt32 fits into vector::size_type
    1546           0 :     if (subkey.getValue(rtl::OUString(), &v[0]) != REG_NO_ERROR
    1547           0 :         || v.back() != '\0'
    1548             :         || !rtl_convertStringToUString(
    1549           0 :             &val.pData, &v[0], static_cast< sal_Int32 >(s - 1),
    1550             :             RTL_TEXTENCODING_UTF8,
    1551             :             (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
    1552             :              | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
    1553           0 :              | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
    1554             :     {
    1555             :         throw css::uno::DeploymentException(
    1556             :             "Failure reading legacy rdb file " + uri,
    1557           0 :             static_cast< cppu::OWeakObject * >(this));
    1558             :     }
    1559           0 :     return val;
    1560             : }
    1561             : 
    1562           0 : void ServiceManager::readLegacyRdbStrings(
    1563             :     rtl::OUString const & uri, RegistryKey & key, rtl::OUString const & path,
    1564             :     std::vector< rtl::OUString > * strings)
    1565             : {
    1566             :     assert(strings != 0);
    1567           0 :     RegistryKey subkey;
    1568           0 :     switch (key.openKey(path, subkey)) {
    1569             :     case REG_NO_ERROR:
    1570           0 :         break;
    1571             :     case REG_KEY_NOT_EXISTS:
    1572           0 :         return;
    1573             :     default:
    1574             :         throw css::uno::DeploymentException(
    1575             :             "Failure reading legacy rdb file " + uri,
    1576           0 :             static_cast< cppu::OWeakObject * >(this));
    1577             :     }
    1578           0 :     rtl::OUString prefix(subkey.getName() + "/");
    1579           0 :     RegistryKeyNames names;
    1580           0 :     if (subkey.getKeyNames(rtl::OUString(), names) != REG_NO_ERROR) {
    1581             :         throw css::uno::DeploymentException(
    1582             :             "Failure reading legacy rdb file " + uri,
    1583           0 :             static_cast< cppu::OWeakObject * >(this));
    1584             :     }
    1585           0 :     for (sal_uInt32 i = 0; i != names.getLength(); ++i) {
    1586             :         assert(names.getElement(i).match(prefix));
    1587           0 :         strings->push_back(names.getElement(i).copy(prefix.getLength()));
    1588           0 :     }
    1589             : }
    1590             : 
    1591           0 : void ServiceManager::insertRdbFiles(
    1592             :     std::vector< rtl::OUString > const & uris,
    1593             :     css::uno::Reference< css::uno::XComponentContext > const & alienContext)
    1594             : {
    1595           0 :     Data extra;
    1596           0 :     for (std::vector< rtl::OUString >::const_iterator i(uris.begin());
    1597           0 :          i != uris.end(); ++i)
    1598             :     {
    1599             :         try {
    1600           0 :             Parser(*i, alienContext, &extra);
    1601           0 :         } catch (css::container::NoSuchElementException &) {
    1602             :             throw css::lang::IllegalArgumentException(
    1603           0 :                 *i + ": no such file", static_cast< cppu::OWeakObject * >(this),
    1604           0 :                 0);
    1605           0 :         } catch (css::registry::InvalidRegistryException & e) {
    1606             :             throw css::lang::IllegalArgumentException(
    1607           0 :                 "InvalidRegistryException: " + e.Message,
    1608           0 :                 static_cast< cppu::OWeakObject * >(this), 0);
    1609             :         }
    1610             :     }
    1611           0 :     insertExtraData(extra);
    1612           0 : }
    1613             : 
    1614         102 : void ServiceManager::insertLegacyFactory(
    1615             :     css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo)
    1616             : {
    1617             :     assert(factoryInfo.is());
    1618         102 :     rtl::OUString name(factoryInfo->getImplementationName());
    1619             :     css::uno::Reference< css::lang::XSingleComponentFactory > f1(
    1620         102 :         factoryInfo, css::uno::UNO_QUERY);
    1621         102 :     css::uno::Reference< css::lang::XSingleServiceFactory > f2;
    1622         102 :     if (!f1.is()) {
    1623             :         f2 = css::uno::Reference< css::lang::XSingleServiceFactory >(
    1624           0 :             factoryInfo, css::uno::UNO_QUERY);
    1625             :     }
    1626             :     css::uno::Reference< css::lang::XComponent > comp(
    1627         102 :         factoryInfo, css::uno::UNO_QUERY);
    1628             :     boost::shared_ptr< Implementation > impl(
    1629         102 :         new Implementation(name, f1, f2, comp));
    1630         102 :     Data extra;
    1631         102 :     if (!name.isEmpty()) {
    1632             :         extra.namedImplementations.insert(
    1633          17 :             NamedImplementations::value_type(name, impl));
    1634             :     }
    1635             :     extra.dynamicImplementations.insert(
    1636         102 :         DynamicImplementations::value_type(factoryInfo, impl));
    1637             :     css::uno::Sequence< rtl::OUString > services(
    1638         102 :         factoryInfo->getSupportedServiceNames());
    1639         204 :     for (sal_Int32 i = 0; i != services.getLength(); ++i) {
    1640         102 :         impl->info->services.push_back(services[i]);
    1641         102 :         extra.services[services[i]].push_back(impl);
    1642             :     }
    1643         102 :     if (insertExtraData(extra) && comp.is()) {
    1644         102 :         comp->addEventListener(this);
    1645         102 :     }
    1646         102 : }
    1647             : 
    1648         102 : bool ServiceManager::insertExtraData(Data const & extra) {
    1649             :     {
    1650         102 :         osl::MutexGuard g(rBHelper.rMutex);
    1651         102 :         if (isDisposed()) {
    1652           0 :             return false;
    1653             :         }
    1654         357 :         for (NamedImplementations::const_iterator i(
    1655         102 :                  extra.namedImplementations.begin());
    1656         238 :              i != extra.namedImplementations.end(); ++i)
    1657             :         {
    1658          51 :             if (data_.namedImplementations.find(i->first)
    1659          51 :                 != data_.namedImplementations.end())
    1660             :             {
    1661             :                 throw css::lang::IllegalArgumentException(
    1662           0 :                     "Insert duplicate implementation name " + i->first,
    1663           0 :                     static_cast< cppu::OWeakObject * >(this), 0);
    1664             :             }
    1665             :         }
    1666         612 :         for (DynamicImplementations::const_iterator i(
    1667         102 :                  extra.dynamicImplementations.begin());
    1668         408 :              i != extra.dynamicImplementations.end(); ++i)
    1669             :         {
    1670         306 :             if (data_.dynamicImplementations.find(i->first)
    1671         306 :                 != data_.dynamicImplementations.end())
    1672             :             {
    1673             :                 throw css::lang::IllegalArgumentException(
    1674             :                     "Insert duplicate factory object",
    1675           0 :                     static_cast< cppu::OWeakObject * >(this), 0);
    1676             :             }
    1677             :         }
    1678             :         //TODO: The below leaves data_ in an inconsistent state upon exceptions:
    1679             :         data_.namedImplementations.insert(
    1680             :             extra.namedImplementations.begin(),
    1681         102 :             extra.namedImplementations.end());
    1682             :         data_.dynamicImplementations.insert(
    1683             :             extra.dynamicImplementations.begin(),
    1684         102 :             extra.dynamicImplementations.end());
    1685         102 :         insertImplementationMap(&data_.services, extra.services);
    1686         102 :         insertImplementationMap(&data_.singletons, extra.singletons);
    1687             :     }
    1688             :     //TODO: Updating the component context singleton data should be part of the
    1689             :     // atomic service manager update:
    1690         102 :     if (!extra.singletons.empty()) {
    1691             :         assert(context_.is());
    1692             :         css::uno::Reference< css::container::XNameContainer > cont(
    1693           0 :             context_, css::uno::UNO_QUERY_THROW);
    1694           0 :         for (ImplementationMap::const_iterator i(extra.singletons.begin());
    1695           0 :              i != extra.singletons.end(); ++i)
    1696             :         {
    1697           0 :             rtl::OUString name("/singletons/" + i->first);
    1698             :             //TODO: Update should be atomic:
    1699             :             try {
    1700           0 :                 cont->removeByName(name + "/arguments");
    1701           0 :             } catch (const css::container::NoSuchElementException &) {}
    1702             :             assert(!i->second.empty());
    1703             :             assert(i->second[0].get() != 0);
    1704             :             SAL_INFO_IF(
    1705             :                 i->second.size() > 1, "cppuhelper",
    1706             :                 "Arbitrarily chosing " << i->second[0]->info->name
    1707             :                     << " among multiple implementations for singleton "
    1708             :                     << i->first);
    1709             :             try {
    1710           0 :                 cont->insertByName(
    1711           0 :                     name + "/service", css::uno::Any(i->second[0]->info->name));
    1712           0 :             } catch (css::container::ElementExistException &) {
    1713           0 :                 cont->replaceByName(
    1714           0 :                     name + "/service", css::uno::Any(i->second[0]->info->name));
    1715             :             }
    1716             :             try {
    1717           0 :                 cont->insertByName(name, css::uno::Any());
    1718           0 :             } catch (css::container::ElementExistException &) {
    1719             :                 SAL_INFO("cppuhelper", "Overwriting singleton " << i->first);
    1720           0 :                 cont->replaceByName(name, css::uno::Any());
    1721             :             }
    1722           0 :         }
    1723             :     }
    1724         102 :     return true;
    1725             : }
    1726             : 
    1727           0 : void ServiceManager::removeRdbFiles(std::vector< rtl::OUString > const & uris) {
    1728             :     // The underlying data structures make this function somewhat inefficient,
    1729             :     // but the assumption is that it is rarely called (and that if it is called,
    1730             :     // it is called with a uris vector of size one):
    1731           0 :     std::vector< boost::shared_ptr< Implementation > > clear;
    1732             :     {
    1733           0 :         osl::MutexGuard g(rBHelper.rMutex);
    1734           0 :         for (std::vector< rtl::OUString >::const_iterator i(uris.begin());
    1735           0 :              i != uris.end(); ++i)
    1736             :         {
    1737           0 :             for (NamedImplementations::iterator j(
    1738           0 :                      data_.namedImplementations.begin());
    1739           0 :                  j != data_.namedImplementations.end();)
    1740             :             {
    1741             :                 assert(j->second.get() != 0);
    1742           0 :                 if (j->second->info->rdbFile == *i) {
    1743           0 :                     clear.push_back(j->second);
    1744             :                     //TODO: The below leaves data_ in an inconsistent state upon
    1745             :                     // exceptions:
    1746             :                     removeFromImplementationMap(
    1747           0 :                         &data_.services, j->second->info->services, j->second);
    1748             :                     removeFromImplementationMap(
    1749           0 :                         &data_.singletons, j->second->info->singletons,
    1750           0 :                         j->second);
    1751           0 :                     data_.namedImplementations.erase(j++);
    1752             :                 } else {
    1753           0 :                     ++j;
    1754             :                 }
    1755             :             }
    1756           0 :         }
    1757           0 :     }
    1758             :     //TODO: Update the component context singleton data
    1759           0 : }
    1760             : 
    1761           0 : bool ServiceManager::removeLegacyFactory(
    1762             :     css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo,
    1763             :     bool removeListener)
    1764             : {
    1765             :     assert(factoryInfo.is());
    1766           0 :     boost::shared_ptr< Implementation > clear;
    1767           0 :     css::uno::Reference< css::lang::XComponent > comp;
    1768             :     {
    1769           0 :         osl::MutexGuard g(rBHelper.rMutex);
    1770             :         DynamicImplementations::iterator i(
    1771           0 :             data_.dynamicImplementations.find(factoryInfo));
    1772           0 :         if (i == data_.dynamicImplementations.end()) {
    1773           0 :             return isDisposed();
    1774             :         }
    1775             :         assert(i->second.get() != 0);
    1776           0 :         clear = i->second;
    1777             :         //TODO: The below leaves data_ in an inconsistent state upon exceptions:
    1778             :         removeFromImplementationMap(
    1779           0 :             &data_.services, i->second->info->services, i->second);
    1780             :         removeFromImplementationMap(
    1781           0 :             &data_.singletons, i->second->info->singletons, i->second);
    1782           0 :         if (!i->second->info->name.isEmpty()) {
    1783           0 :             data_.namedImplementations.erase(i->second->info->name);
    1784             :         }
    1785           0 :         data_.dynamicImplementations.erase(i);
    1786           0 :         if (removeListener) {
    1787           0 :             comp = i->second->component;
    1788           0 :         }
    1789             :     }
    1790           0 :     if (comp.is()) {
    1791           0 :         removeEventListenerFromComponent(comp);
    1792             :     }
    1793           0 :     return true;
    1794             : }
    1795             : 
    1796           0 : void ServiceManager::removeImplementation(rtl::OUString name) {
    1797             :     // The underlying data structures make this function somewhat inefficient,
    1798             :     // but the assumption is that it is rarely called:
    1799           0 :     boost::shared_ptr< Implementation > clear;
    1800             :     {
    1801           0 :         osl::MutexGuard g(rBHelper.rMutex);
    1802           0 :         if (isDisposed()) {
    1803           0 :             return;
    1804             :         }
    1805           0 :         NamedImplementations::iterator i(data_.namedImplementations.find(name));
    1806           0 :         if (i == data_.namedImplementations.end()) {
    1807             :             throw css::container::NoSuchElementException(
    1808             :                 "Remove non-inserted implementation " + name,
    1809           0 :                 static_cast< cppu::OWeakObject * >(this));
    1810             :         }
    1811             :         assert(i->second.get() != 0);
    1812           0 :         clear = i->second;
    1813             :         //TODO: The below leaves data_ in an inconsistent state upon exceptions:
    1814             :         removeFromImplementationMap(
    1815           0 :             &data_.services, i->second->info->services, i->second);
    1816             :         removeFromImplementationMap(
    1817           0 :             &data_.singletons, i->second->info->singletons, i->second);
    1818           0 :         for (DynamicImplementations::iterator j(
    1819           0 :                  data_.dynamicImplementations.begin());
    1820           0 :              j != data_.dynamicImplementations.end(); ++j)
    1821             :         {
    1822           0 :             if (j->second == i->second) {
    1823           0 :                 data_.dynamicImplementations.erase(j);
    1824           0 :                 break;
    1825             :             }
    1826             :         }
    1827           0 :         data_.namedImplementations.erase(i);
    1828           0 :     }
    1829             : }
    1830             : 
    1831      153707 : boost::shared_ptr< Implementation > ServiceManager::findServiceImplementation(
    1832             :     css::uno::Reference< css::uno::XComponentContext > const & context,
    1833             :     rtl::OUString const & specifier)
    1834             : {
    1835      153707 :     boost::shared_ptr< Implementation > impl;
    1836             :     bool loaded;
    1837             :     {
    1838      153707 :         osl::MutexGuard g(rBHelper.rMutex);
    1839      153707 :         ImplementationMap::const_iterator i(data_.services.find(specifier));
    1840      153707 :         if (i == data_.services.end()) {
    1841             :             NamedImplementations::const_iterator j(
    1842       29635 :                 data_.namedImplementations.find(specifier));
    1843       29635 :             if (j == data_.namedImplementations.end()) {
    1844             :                 SAL_INFO("cppuhelper", "No implementation for " << specifier);
    1845       25867 :                 return boost::shared_ptr< Implementation >();
    1846             :             }
    1847        3768 :             impl = j->second;
    1848             :         } else {
    1849             :             assert(!i->second.empty());
    1850             :             SAL_INFO_IF(
    1851             :                 i->second.size() > 1, "cppuhelper",
    1852             :                 "Arbitrarily chosing " << i->second[0]->info->name
    1853             :                     << " among multiple implementations for " << i->first);
    1854      124072 :             impl = i->second[0];
    1855             :         }
    1856             :         assert(impl.get() != 0);
    1857      127840 :         loaded = impl->loaded;
    1858             :     }
    1859             :     //TODO: There is a race here, as the relevant service factory can be removed
    1860             :     // while the mutex is unlocked and loading can thus fail, as the entity from
    1861             :     // which to load can disappear once the service factory is removed.
    1862      127840 :     if (!loaded) {
    1863        1847 :         css::uno::Reference< css::lang::XSingleComponentFactory > f1;
    1864        1847 :         css::uno::Reference< css::lang::XSingleServiceFactory > f2;
    1865        1847 :         loadImplementation(context, impl->info, &f1, &f2);
    1866        1847 :         osl::MutexGuard g(rBHelper.rMutex);
    1867        1847 :         if (!(isDisposed() || impl->loaded)) {
    1868        1847 :             impl->loaded = true;
    1869        1847 :             impl->factory1 = f1;
    1870        1847 :             impl->factory2 = f2;
    1871        1847 :         }
    1872             :     }
    1873      127840 :     return impl;
    1874             : }
    1875             : 
    1876             : css::uno::Reference< css::uno::XInterface >
    1877           6 : FactoryWrapper::createInstanceWithContext(
    1878             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
    1879             :     throw (css::uno::Exception, css::uno::RuntimeException)
    1880             : {
    1881           6 :     loadImplementation(Context);
    1882           6 :     return factory1_.is()
    1883           6 :         ? factory1_->createInstanceWithContext(Context)
    1884          12 :         : factory2_->createInstance();
    1885             : }
    1886             : 
    1887             : css::uno::Reference< css::uno::XInterface >
    1888           1 : FactoryWrapper::createInstanceWithArgumentsAndContext(
    1889             :     css::uno::Sequence< css::uno::Any > const & Arguments,
    1890             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
    1891             :     throw (css::uno::Exception, css::uno::RuntimeException)
    1892             : {
    1893           1 :     loadImplementation(Context);
    1894           1 :     return factory1_.is()
    1895           1 :         ? factory1_->createInstanceWithArgumentsAndContext(Arguments, Context)
    1896           2 :         : factory2_->createInstanceWithArguments(Arguments);
    1897             : }
    1898             : 
    1899           0 : css::uno::Reference< css::uno::XInterface > FactoryWrapper::createInstance()
    1900             :     throw (css::uno::Exception, css::uno::RuntimeException)
    1901             : {
    1902           0 :     loadImplementation(manager_->getContext());
    1903           0 :     return factory1_.is()
    1904           0 :         ? factory1_->createInstanceWithContext(manager_->getContext())
    1905           0 :         : factory2_->createInstance();
    1906             : }
    1907             : 
    1908             : css::uno::Reference< css::uno::XInterface >
    1909           0 : FactoryWrapper::createInstanceWithArguments(
    1910             :     css::uno::Sequence< css::uno::Any > const & Arguments)
    1911             :     throw (css::uno::Exception, css::uno::RuntimeException)
    1912             : {
    1913           0 :     loadImplementation(manager_->getContext());
    1914           0 :     return factory1_.is()
    1915           0 :         ? factory1_->createInstanceWithArgumentsAndContext(
    1916           0 :             Arguments, manager_->getContext())
    1917           0 :         : factory2_->createInstanceWithArguments(Arguments);
    1918             : }
    1919             : 
    1920           0 : rtl::OUString FactoryWrapper::getImplementationName()
    1921             :     throw (css::uno::RuntimeException)
    1922             : {
    1923           0 :     return info_->name;
    1924             : }
    1925             : 
    1926           0 : sal_Bool FactoryWrapper::supportsService(rtl::OUString const & ServiceName)
    1927             :     throw (css::uno::RuntimeException)
    1928             : {
    1929           0 :     return cppu::supportsService(this, ServiceName);
    1930             : }
    1931             : 
    1932           1 : css::uno::Sequence< rtl::OUString > FactoryWrapper::getSupportedServiceNames()
    1933             :     throw (css::uno::RuntimeException)
    1934             : {
    1935           1 :     if (info_->services.size() > static_cast< sal_uInt32 >(SAL_MAX_INT32)) {
    1936             :         throw css::uno::RuntimeException(
    1937           0 :             "Implementation " + info_->name + " supports too many services",
    1938           0 :             static_cast< cppu::OWeakObject * >(this));
    1939             :     }
    1940             :     css::uno::Sequence< rtl::OUString > names(
    1941           1 :         static_cast< sal_Int32 >(info_->services.size()));
    1942           1 :     sal_Int32 i = 0;
    1943          15 :     for (std::vector< rtl::OUString >::const_iterator j(
    1944           1 :              info_->services.begin());
    1945          10 :          j != info_->services.end(); ++j)
    1946             :     {
    1947           4 :         names[i++] = *j;
    1948             :     }
    1949           1 :     return names;
    1950             : }
    1951             : 
    1952           7 : void FactoryWrapper::loadImplementation(
    1953             :     css::uno::Reference< css::uno::XComponentContext > const & context)
    1954             : {
    1955             :     {
    1956           7 :         osl::MutexGuard g(mutex_);
    1957           7 :         if (loaded_) {
    1958           7 :             return;
    1959           7 :         }
    1960             :     }
    1961           7 :     css::uno::Reference< css::lang::XSingleComponentFactory > f1;
    1962           7 :     css::uno::Reference< css::lang::XSingleServiceFactory > f2;
    1963             :     //TODO: There is a race here, as the relevant service factory can already
    1964             :     // have been removed and loading can thus fail, as the entity from which to
    1965             :     // load can disappear once the service factory is removed:
    1966           7 :     manager_->loadImplementation(context, info_, &f1, &f2);
    1967           7 :     if (!(f1.is() || f2.is())) {
    1968             :         throw css::uno::DeploymentException(
    1969           0 :             "Implementation " + info_->name + " does not provide a factory",
    1970           0 :             static_cast< cppu::OWeakObject * >(this));
    1971             :     }
    1972           7 :     osl::MutexGuard g(mutex_);
    1973           7 :     if (!loaded_) {
    1974           7 :         loaded_ = true;
    1975           7 :         factory1_ = f1;
    1976           7 :         factory2_ = f2;
    1977           7 :     }
    1978             : }
    1979             : 
    1980         259 : css::uno::Reference< css::uno::XComponentContext > bootstrapComponentContext(
    1981             :     css::uno::Reference< css::registry::XSimpleRegistry > const & typeRegistry,
    1982             :     rtl::OUString const & serviceUris, rtl::Bootstrap const & bootstrap)
    1983             : {
    1984         259 :     rtl::Reference< ServiceManager > smgr(new ServiceManager(serviceUris));
    1985         259 :     cppu::ContextEntry_Init entry;
    1986         259 :     std::vector< cppu::ContextEntry_Init > context_values;
    1987             :     context_values.push_back(
    1988             :         cppu::ContextEntry_Init(
    1989             :             "/singletons/com.sun.star.lang.theServiceManager",
    1990             :             css::uno::makeAny(
    1991             :                 css::uno::Reference< css::uno::XInterface >(
    1992         259 :                     static_cast< cppu::OWeakObject * >(smgr.get()))),
    1993         259 :             false));
    1994             :     context_values.push_back( //TODO: from services.rdb?
    1995             :         cppu::ContextEntry_Init(
    1996             :             "/singletons/com.sun.star.reflection.theTypeDescriptionManager",
    1997             :             css::uno::makeAny(
    1998             :                 rtl::OUString("com.sun.star.comp.stoc.TypeDescriptionManager")),
    1999         259 :             true /*TODO: false?*/));
    2000             :     context_values.push_back( //TODO: from services.rdb?
    2001             :         cppu::ContextEntry_Init(
    2002             :             "/singletons/com.sun.star.util.theMacroExpander",
    2003             :             css::uno::makeAny(
    2004             :                 cppuhelper::detail::create_bootstrap_macro_expander_factory()),
    2005         259 :             true));
    2006         259 :     Data const & data = smgr->getData();
    2007        2721 :     for (ImplementationMap::const_iterator i(data.singletons.begin());
    2008        1814 :          i != data.singletons.end(); ++i)
    2009             :     {
    2010             :         assert(!i->second.empty());
    2011             :         assert(i->second[0].get() != 0);
    2012             :         SAL_INFO_IF(
    2013             :             i->second.size() > 1, "cppuhelper",
    2014             :             "Arbitrarily chosing " << i->second[0]->info->name
    2015             :                 << " among multiple implementations for " << i->first);
    2016             :         context_values.push_back(
    2017             :             cppu::ContextEntry_Init(
    2018         648 :                 "/singletons/" + i->first,
    2019        1296 :                 css::uno::makeAny(i->second[0]->info->name), true));
    2020             :     }
    2021         259 :     cppu::add_access_control_entries(&context_values, bootstrap);
    2022             :     assert(!context_values.empty());
    2023             :     css::uno::Reference< css::uno::XComponentContext > context(
    2024             :         createComponentContext(
    2025         518 :             &context_values[0], context_values.size(),
    2026         777 :             css::uno::Reference< css::uno::XComponentContext >()));
    2027         259 :     smgr->setContext(context);
    2028             :     css::uno::Reference< css::container::XHierarchicalNameAccess > tdmgr(
    2029         259 :         context->getValueByName(
    2030         259 :             "/singletons/com.sun.star.reflection.theTypeDescriptionManager"),
    2031         259 :         css::uno::UNO_QUERY_THROW);
    2032         259 :     if (typeRegistry.is()) {
    2033         259 :         css::uno::Sequence< css::uno::Any > arg(1);
    2034         259 :         arg[0] <<= typeRegistry;
    2035             :         css::uno::Reference< css::container::XSet >(
    2036         518 :             tdmgr, css::uno::UNO_QUERY_THROW)->
    2037             :             insert(
    2038             :                 css::uno::makeAny(
    2039         259 :                     smgr->createInstanceWithArgumentsAndContext(
    2040             :                         ("com.sun.star.comp.stoc"
    2041             :                          ".RegistryTypeDescriptionProvider"),
    2042         777 :                         arg, context)));
    2043             :     }
    2044         259 :     cppu::installTypeDescriptionManager(tdmgr);
    2045         259 :     return context;
    2046             : }
    2047             : 
    2048         777 : rtl::OUString getBootstrapVariable(
    2049             :     rtl::Bootstrap const & bootstrap, rtl::OUString const & name)
    2050             : {
    2051         777 :     rtl::OUString v;
    2052         777 :     if (!bootstrap.getFrom(name, v)) {
    2053             :         throw css::uno::DeploymentException(
    2054           0 :             "Cannot obtain " + name + " from uno ini",
    2055           0 :             css::uno::Reference< css::uno::XInterface >());
    2056             :     }
    2057         777 :     return v;
    2058             : }
    2059             : 
    2060         302 : css::uno::Reference< css::registry::XSimpleRegistry > readTypeRdbFile(
    2061             :     rtl::OUString const & uri, bool optional,
    2062             :     css::uno::Reference< css::registry::XSimpleRegistry > const & lastRegistry,
    2063             :     css::uno::Reference< css::lang::XSingleServiceFactory > const &
    2064             :         simpleRegistryFactory,
    2065             :     css::uno::Reference< css::lang::XSingleServiceFactory > const &
    2066             :         nestedRegistryFactory)
    2067             : {
    2068             :     assert(simpleRegistryFactory.is() && nestedRegistryFactory.is());
    2069             :     try {
    2070             :         css::uno::Reference< css::registry::XSimpleRegistry > simple(
    2071         302 :             simpleRegistryFactory->createInstance(), css::uno::UNO_QUERY_THROW);
    2072         302 :         simple->open(uri, true, false);
    2073         302 :         if (lastRegistry.is()) {
    2074             :             css::uno::Reference< css::registry::XSimpleRegistry > nested(
    2075          43 :                 nestedRegistryFactory->createInstance(),
    2076          43 :                 css::uno::UNO_QUERY_THROW);
    2077          43 :             css::uno::Sequence< css::uno::Any > args(2);
    2078          43 :             args[0] <<= lastRegistry;
    2079          43 :             args[1] <<= simple;
    2080             :             css::uno::Reference< css::lang::XInitialization >(
    2081          86 :                 nested, css::uno::UNO_QUERY_THROW)->
    2082          43 :                 initialize(args);
    2083          43 :             return nested;
    2084             :         } else {
    2085         259 :             return simple;
    2086         302 :         }
    2087           0 :     } catch (css::registry::InvalidRegistryException & e) {
    2088           0 :         if (!optional) {
    2089             :             throw css::uno::DeploymentException(
    2090           0 :                 "Invalid registry " + uri + ":" + e.Message,
    2091           0 :                 css::uno::Reference< css::uno::XInterface >());
    2092             :         }
    2093             :         SAL_INFO("cppuhelper", "Ignored optional " << uri);
    2094           0 :         return lastRegistry;
    2095             :     }
    2096             : }
    2097             : 
    2098           0 : css::uno::Reference< css::registry::XSimpleRegistry > readTypeRdbDirectory(
    2099             :     rtl::OUString const & uri, bool optional,
    2100             :     css::uno::Reference< css::registry::XSimpleRegistry > const & lastRegistry,
    2101             :     css::uno::Reference< css::lang::XSingleServiceFactory > const &
    2102             :         simpleRegistryFactory,
    2103             :     css::uno::Reference< css::lang::XSingleServiceFactory > const &
    2104             :         nestedRegistryFactory)
    2105             : {
    2106             :     assert(simpleRegistryFactory.is() && nestedRegistryFactory.is());
    2107           0 :     osl::Directory dir(uri);
    2108           0 :     switch (dir.open()) {
    2109             :     case osl::FileBase::E_None:
    2110           0 :         break;
    2111             :     case osl::FileBase::E_NOENT:
    2112           0 :         if (optional) {
    2113             :             SAL_INFO("cppuhelper", "Ignored optional " << uri);
    2114           0 :             return lastRegistry;
    2115             :         }
    2116             :         // fall through
    2117             :     default:
    2118             :         throw css::uno::DeploymentException(
    2119             :             "Cannot open directory " + uri,
    2120           0 :             css::uno::Reference< css::uno::XInterface >());
    2121             :     }
    2122           0 :     css::uno::Reference< css::registry::XSimpleRegistry > last(lastRegistry);
    2123           0 :     for (;;) {
    2124           0 :         rtl::OUString fileUri;
    2125           0 :         if (!nextDirectoryItem(dir, &fileUri)) {
    2126             :             break;
    2127             :         }
    2128             :         last = readTypeRdbFile(
    2129             :             fileUri, optional, last, simpleRegistryFactory,
    2130           0 :             nestedRegistryFactory);
    2131           0 :     }
    2132           0 :     return last;
    2133             : }
    2134             : 
    2135         259 : css::uno::Reference< css::registry::XSimpleRegistry > createTypeRegistry(
    2136             :     rtl::OUString const & uris, rtl::OUString const & libraryDirectoryUri)
    2137             : {
    2138             :     css::uno::Reference< css::lang::XMultiComponentFactory > factory(
    2139         259 :         cppu::bootstrapInitialSF(libraryDirectoryUri));
    2140             :     css::uno::Reference< css::lang::XSingleServiceFactory > simpleRegs(
    2141             :         cppu::loadSharedLibComponentFactory(
    2142             :             "bootstrap.uno" SAL_DLLEXTENSION, libraryDirectoryUri,
    2143             :             "com.sun.star.comp.stoc.SimpleRegistry",
    2144             :             css::uno::Reference< css::lang::XMultiServiceFactory >(
    2145             :                 factory, css::uno::UNO_QUERY_THROW),
    2146             :             css::uno::Reference< css::registry::XRegistryKey >()),
    2147         259 :         css::uno::UNO_QUERY_THROW);
    2148             :     css::uno::Reference< css::lang::XSingleServiceFactory > nestedRegs(
    2149             :         cppu::loadSharedLibComponentFactory(
    2150             :             "bootstrap.uno" SAL_DLLEXTENSION, libraryDirectoryUri,
    2151             :             "com.sun.star.comp.stoc.NestedRegistry",
    2152             :             css::uno::Reference< css::lang::XMultiServiceFactory >(
    2153             :                 factory, css::uno::UNO_QUERY_THROW),
    2154             :             css::uno::Reference< css::registry::XRegistryKey >()),
    2155         259 :         css::uno::UNO_QUERY_THROW);
    2156         259 :     css::uno::Reference< css::registry::XSimpleRegistry > reg;
    2157        1040 :     for (sal_Int32 i = 0; i != -1;) {
    2158         522 :         rtl::OUString uri(uris.getToken(0, ' ', i));
    2159         522 :         if (uri.isEmpty()) {
    2160         220 :             continue;
    2161             :         }
    2162             :         bool optional;
    2163             :         bool directory;
    2164         302 :         decodeRdbUri(&uri, &optional, &directory);
    2165             :         reg = directory
    2166             :             ? readTypeRdbDirectory(uri, optional, reg, simpleRegs, nestedRegs)
    2167         302 :             : readTypeRdbFile(uri, optional, reg, simpleRegs, nestedRegs);
    2168         522 :     }
    2169         259 :     return reg;
    2170             : }
    2171             : 
    2172             : }
    2173             : 
    2174             : css::uno::Reference< css::uno::XComponentContext >
    2175         259 : cppu::defaultBootstrap_InitialComponentContext(rtl::OUString const & iniUri)
    2176             :     SAL_THROW((css::uno::Exception))
    2177             : {
    2178         259 :     rtl::Bootstrap bs(iniUri);
    2179         259 :     if (bs.getHandle() == 0) {
    2180             :         throw css::uno::DeploymentException(
    2181             :             "Cannot open uno ini " + iniUri,
    2182           0 :             css::uno::Reference< css::uno::XInterface >());
    2183             :     }
    2184             :     return bootstrapComponentContext(
    2185             :         createTypeRegistry(
    2186             :             getBootstrapVariable(bs, "UNO_TYPES"),
    2187             :             getBootstrapVariable(bs, "URE_INTERNAL_LIB_DIR")),
    2188         259 :         getBootstrapVariable(bs, "UNO_SERVICES"), bs);
    2189             : }
    2190             : 
    2191             : css::uno::Reference< css::uno::XComponentContext >
    2192         259 : cppu::defaultBootstrap_InitialComponentContext()
    2193             :     SAL_THROW((css::uno::Exception))
    2194             : {
    2195         259 :     return defaultBootstrap_InitialComponentContext(getUnoIniUri());
    2196             : }
    2197             : 
    2198             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10