LCOV - code coverage report
Current view: top level - libreoffice/cppuhelper/source - defaultbootstrap.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 526 853 61.7 %
Date: 2012-12-17 Functions: 66 92 71.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10