LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/cppuhelper/source - servicemanager.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 427 744 57.4 %
Date: 2013-07-09 Functions: 47 69 68.1 %
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             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include "sal/config.h"
      11             : 
      12             : #include <algorithm>
      13             : #include <cassert>
      14             : #include <vector>
      15             : 
      16             : #include "boost/noncopyable.hpp"
      17             : #include "boost/shared_ptr.hpp"
      18             : #include "com/sun/star/beans/NamedValue.hpp"
      19             : #include "com/sun/star/beans/PropertyAttribute.hpp"
      20             : #include "com/sun/star/container/ElementExistException.hpp"
      21             : #include "com/sun/star/container/XEnumeration.hpp"
      22             : #include "com/sun/star/container/XNameContainer.hpp"
      23             : #include "com/sun/star/lang/XServiceInfo.hpp"
      24             : #include "com/sun/star/lang/XSingleComponentFactory.hpp"
      25             : #include "com/sun/star/lang/XSingleServiceFactory.hpp"
      26             : #include "com/sun/star/loader/XImplementationLoader.hpp"
      27             : #include "com/sun/star/registry/InvalidRegistryException.hpp"
      28             : #include "com/sun/star/uno/DeploymentException.hpp"
      29             : #include "com/sun/star/uno/Reference.hxx"
      30             : #include "com/sun/star/uno/XComponentContext.hpp"
      31             : #include "cppuhelper/bootstrap.hxx"
      32             : #include "cppuhelper/component_context.hxx"
      33             : #include "cppuhelper/implbase1.hxx"
      34             : #include "cppuhelper/implbase3.hxx"
      35             : #include "cppuhelper/shlib.hxx"
      36             : #include "cppuhelper/supportsservice.hxx"
      37             : #include "osl/file.hxx"
      38             : #include "rtl/ref.hxx"
      39             : #include "rtl/uri.hxx"
      40             : #include "rtl/ustring.hxx"
      41             : #include "rtl/strbuf.hxx"
      42             : #include "sal/log.hxx"
      43             : 
      44             : using rtl::OUString;
      45             : using rtl::OString;
      46             : using rtl::OStringBuffer;
      47             : 
      48             : #include "registry/registry.hxx"
      49             : #include "xmlreader/xmlreader.hxx"
      50             : 
      51             : #include "paths.hxx"
      52             : #include "servicemanager.hxx"
      53             : 
      54             : namespace {
      55             : 
      56         830 : void insertImplementationMap(
      57             :     cppuhelper::ServiceManager::Data::ImplementationMap * destination,
      58             :     cppuhelper::ServiceManager::Data::ImplementationMap const & source)
      59             : {
      60             :     assert(destination != 0);
      61        3735 :     for (cppuhelper::ServiceManager::Data::ImplementationMap::const_iterator i(
      62         830 :              source.begin());
      63        2490 :          i != source.end(); ++i)
      64             :     {
      65             :         std::vector<
      66             :             boost::shared_ptr<
      67             :                 cppuhelper::ServiceManager::Data::Implementation > > & impls
      68         415 :             = (*destination)[i->first];
      69         415 :         impls.insert(impls.end(), i->second.begin(), i->second.end());
      70             :     }
      71         830 : }
      72             : 
      73          14 : void removeFromImplementationMap(
      74             :     cppuhelper::ServiceManager::Data::ImplementationMap * map,
      75             :     std::vector< rtl::OUString > const & elements,
      76             :     boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation >
      77             :         const & implementation)
      78             : {
      79             :     // The underlying data structures make this function somewhat inefficient,
      80             :     // but the assumption is that it is rarely called:
      81             :     assert(map != 0);
      82          63 :     for (std::vector< rtl::OUString >::const_iterator i(elements.begin());
      83          42 :          i != elements.end(); ++i)
      84             :     {
      85             :         cppuhelper::ServiceManager::Data::ImplementationMap::iterator j(
      86           7 :             map->find(*i));
      87             :         assert(j != map->end());
      88             :         std::vector<
      89             :             boost::shared_ptr<
      90             :                 cppuhelper::ServiceManager::Data::Implementation > >::iterator
      91           7 :             k(std::find(j->second.begin(), j->second.end(), implementation));
      92             :         assert(k != j->second.end());
      93           7 :         j->second.erase(k);
      94           7 :         if (j->second.empty()) {
      95           7 :             map->erase(j);
      96             :         }
      97             :     }
      98          14 : }
      99             : 
     100             : // For simplicity, this code keeps throwing
     101             : // css::registry::InvalidRegistryException for invalid XML rdbs (even though
     102             : // that does not fit the exception's name):
     103        2565 : class Parser: private boost::noncopyable {
     104             : public:
     105             :     Parser(
     106             :         rtl::OUString const & uri,
     107             :         css::uno::Reference< css::uno::XComponentContext > const & alienContext,
     108             :         cppuhelper::ServiceManager::Data * data);
     109             : 
     110             : private:
     111             :     void handleComponent();
     112             : 
     113             :     void handleImplementation();
     114             : 
     115             :     void handleService();
     116             : 
     117             :     void handleSingleton();
     118             : 
     119             :     rtl::OUString getNameAttribute();
     120             : 
     121             :     xmlreader::XmlReader reader_;
     122             :     css::uno::Reference< css::uno::XComponentContext > alienContext_;
     123             :     cppuhelper::ServiceManager::Data * data_;
     124             :     rtl::OUString attrLoader_;
     125             :     rtl::OUString attrUri_;
     126             :     rtl::OUString attrPrefix_;
     127             :     rtl::OUString attrImplementation_;
     128             :     boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation >
     129             :         implementation_;
     130             : };
     131             : 
     132        2567 : Parser::Parser(
     133             :     rtl::OUString const & uri,
     134             :     css::uno::Reference< css::uno::XComponentContext > const & alienContext,
     135             :     cppuhelper::ServiceManager::Data * data):
     136        2567 :     reader_(uri), alienContext_(alienContext), data_(data)
     137             : {
     138             :     assert(data != 0);
     139             :     int ucNsId = reader_.registerNamespaceIri(
     140             :         xmlreader::Span(
     141             :             RTL_CONSTASCII_STRINGPARAM(
     142        2565 :                 "http://openoffice.org/2010/uno-components")));
     143             :     enum State {
     144             :         STATE_BEGIN, STATE_END, STATE_COMPONENTS, STATE_COMPONENT_INITIAL,
     145             :         STATE_COMPONENT, STATE_IMPLEMENTATION, STATE_SERVICE, STATE_SINGLETON };
     146        2565 :     for (State state = STATE_BEGIN;;) {
     147      626549 :         xmlreader::Span name;
     148             :         int nsId;
     149             :         xmlreader::XmlReader::Result res = reader_.nextItem(
     150      626549 :             xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
     151      626549 :         switch (state) {
     152             :         case STATE_BEGIN:
     153        5130 :             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
     154        5130 :                 && name.equals(RTL_CONSTASCII_STRINGPARAM("components")))
     155             :             {
     156        2565 :                 state = STATE_COMPONENTS;
     157        2565 :                 break;
     158             :             }
     159             :             throw css::registry::InvalidRegistryException(
     160           0 :                 reader_.getUrl() + ": unexpected item in outer level",
     161           0 :                 css::uno::Reference< css::uno::XInterface >());
     162             :         case STATE_END:
     163        2565 :             if (res == xmlreader::XmlReader::RESULT_DONE) {
     164        5130 :                 return;
     165             :             }
     166             :             throw css::registry::InvalidRegistryException(
     167           0 :                 reader_.getUrl() + ": unexpected item in outer level",
     168           0 :                 css::uno::Reference< css::uno::XInterface >());
     169             :         case STATE_COMPONENTS:
     170       26944 :             if (res == xmlreader::XmlReader::RESULT_END) {
     171        2565 :                 state = STATE_END;
     172        2565 :                 break;
     173             :             }
     174       48758 :             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
     175       48758 :                 && name.equals(RTL_CONSTASCII_STRINGPARAM("component")))
     176             :             {
     177       24379 :                 handleComponent();
     178       24379 :                 state = STATE_COMPONENT_INITIAL;
     179       24379 :                 break;
     180             :             }
     181             :             throw css::registry::InvalidRegistryException(
     182           0 :                 reader_.getUrl() + ": unexpected item in <components>",
     183           0 :                 css::uno::Reference< css::uno::XInterface >());
     184             :         case STATE_COMPONENT:
     185      126974 :             if (res == xmlreader::XmlReader::RESULT_END) {
     186       24379 :                 state = STATE_COMPONENTS;
     187       24379 :                 break;
     188             :             }
     189             :             // fall through
     190             :         case STATE_COMPONENT_INITIAL:
     191      253948 :             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
     192      253948 :                 && name.equals(RTL_CONSTASCII_STRINGPARAM("implementation")))
     193             :             {
     194      126974 :                 handleImplementation();
     195      126974 :                 state = STATE_IMPLEMENTATION;
     196      126974 :                 break;
     197             :             }
     198             :             throw css::registry::InvalidRegistryException(
     199           0 :                 reader_.getUrl() + ": unexpected item in <component>",
     200           0 :                 css::uno::Reference< css::uno::XInterface >());
     201             :         case STATE_IMPLEMENTATION:
     202      285048 :             if (res == xmlreader::XmlReader::RESULT_END) {
     203      126974 :                 state = STATE_COMPONENT;
     204      126974 :                 break;
     205             :             }
     206      316148 :             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
     207      316148 :                 && name.equals(RTL_CONSTASCII_STRINGPARAM("service")))
     208             :             {
     209      155695 :                 handleService();
     210      155695 :                 state = STATE_SERVICE;
     211      155695 :                 break;
     212             :             }
     213        4758 :             if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
     214        4758 :                 && name.equals(RTL_CONSTASCII_STRINGPARAM("singleton")))
     215             :             {
     216        2379 :                 handleSingleton();
     217        2379 :                 state = STATE_SINGLETON;
     218        2379 :                 break;
     219             :             }
     220             :             throw css::registry::InvalidRegistryException(
     221           0 :                 reader_.getUrl() + ": unexpected item in <implementation>",
     222           0 :                 css::uno::Reference< css::uno::XInterface >());
     223             :         case STATE_SERVICE:
     224      155695 :             if (res == xmlreader::XmlReader::RESULT_END) {
     225      155695 :                 state = STATE_IMPLEMENTATION;
     226      155695 :                 break;
     227             :             }
     228             :             throw css::registry::InvalidRegistryException(
     229           0 :                 reader_.getUrl() + ": unexpected item in <service>",
     230           0 :                 css::uno::Reference< css::uno::XInterface >());
     231             :         case STATE_SINGLETON:
     232        2379 :             if (res == xmlreader::XmlReader::RESULT_END) {
     233        2379 :                 state = STATE_IMPLEMENTATION;
     234        2379 :                 break;
     235             :             }
     236             :             throw css::registry::InvalidRegistryException(
     237           0 :                 reader_.getUrl() + ": unexpected item in <service>",
     238           0 :                 css::uno::Reference< css::uno::XInterface >());
     239             :         }
     240      623984 :     }
     241             : }
     242             : 
     243       24379 : void Parser::handleComponent() {
     244       24379 :     attrLoader_ = rtl::OUString();
     245       24379 :     attrUri_ = rtl::OUString();
     246       24379 :     attrPrefix_ = rtl::OUString();
     247       24379 :     xmlreader::Span name;
     248             :     int nsId;
     249       24379 :     while (reader_.nextAttribute(&nsId, &name)) {
     250      143376 :         if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
     251       71688 :             && name.equals(RTL_CONSTASCII_STRINGPARAM("loader")))
     252             :         {
     253       24379 :             if (!attrLoader_.isEmpty()) {
     254             :                 throw css::registry::InvalidRegistryException(
     255             :                     (reader_.getUrl()
     256           0 :                      + ": <component> has multiple \"loader\" attributes"),
     257           0 :                     css::uno::Reference< css::uno::XInterface >());
     258             :             }
     259       24379 :             attrLoader_ = reader_.getAttributeValue(false).convertFromUtf8();
     260       24379 :             if (attrLoader_.isEmpty()) {
     261             :                 throw css::registry::InvalidRegistryException(
     262             :                     (reader_.getUrl()
     263           0 :                      + ": <component> has empty \"loader\" attribute"),
     264           0 :                     css::uno::Reference< css::uno::XInterface >());
     265             :             }
     266       94618 :         } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
     267       47309 :                    && name.equals(RTL_CONSTASCII_STRINGPARAM("uri")))
     268             :         {
     269       24379 :             if (!attrUri_.isEmpty()) {
     270             :                 throw css::registry::InvalidRegistryException(
     271             :                     (reader_.getUrl()
     272           0 :                      + ": <component> has multiple \"uri\" attributes"),
     273           0 :                     css::uno::Reference< css::uno::XInterface >());
     274             :             }
     275       24379 :             attrUri_ = reader_.getAttributeValue(false).convertFromUtf8();
     276       24379 :             if (attrUri_.isEmpty()) {
     277             :                 throw css::registry::InvalidRegistryException(
     278             :                     (reader_.getUrl()
     279           0 :                      + ": <component> has empty \"uri\" attribute"),
     280           0 :                     css::uno::Reference< css::uno::XInterface >());
     281             :             }
     282       45860 :         } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
     283       22930 :                    && name.equals(RTL_CONSTASCII_STRINGPARAM("prefix")))
     284             :         {
     285       22930 :             if (!attrPrefix_.isEmpty()) {
     286             :                 throw css::registry::InvalidRegistryException(
     287           0 :                     (reader_.getUrl() +
     288           0 :                      ": <component> has multiple \"prefix\" attributes"),
     289           0 :                     css::uno::Reference< css::uno::XInterface >());
     290             :             }
     291       22930 :             attrPrefix_ = reader_.getAttributeValue(false).convertFromUtf8();
     292       22930 :             if (attrPrefix_.isEmpty()) {
     293             :                 throw css::registry::InvalidRegistryException(
     294           0 :                     (reader_.getUrl() +
     295           0 :                      ": <component> has empty \"prefix\" attribute"),
     296           0 :                     css::uno::Reference< css::uno::XInterface >());
     297             :             }
     298             :         } else {
     299             :             throw css::registry::InvalidRegistryException(
     300           0 :                 (reader_.getUrl() + ": unexpected attribute \""
     301           0 :                  + name.convertFromUtf8() + "\" in <component>"),
     302           0 :                 css::uno::Reference< css::uno::XInterface >());
     303             :         }
     304             :     }
     305       24379 :     if (attrLoader_.isEmpty()) {
     306             :         throw css::registry::InvalidRegistryException(
     307           0 :             reader_.getUrl() + ": <component> is missing \"loader\" attribute",
     308           0 :             css::uno::Reference< css::uno::XInterface >());
     309             :     }
     310       24379 :     if (attrUri_.isEmpty()) {
     311             :         throw css::registry::InvalidRegistryException(
     312           0 :             reader_.getUrl() + ": <component> is missing \"uri\" attribute",
     313           0 :             css::uno::Reference< css::uno::XInterface >());
     314             :     }
     315             : #ifndef DISABLE_DYNLOADING
     316             :     try {
     317       24379 :         attrUri_ = rtl::Uri::convertRelToAbs(reader_.getUrl(), attrUri_);
     318           0 :     } catch (const rtl::MalformedUriException & e) {
     319             :         throw css::registry::InvalidRegistryException(
     320           0 :             reader_.getUrl() + ": bad \"uri\" attribute: " + e.getMessage(),
     321           0 :             css::uno::Reference< css::uno::XInterface >());
     322             :     }
     323             : #endif
     324       24379 : }
     325             : 
     326      126974 : void Parser::handleImplementation() {
     327      126974 :     attrImplementation_ = getNameAttribute();
     328             :     implementation_.reset(
     329             :         new cppuhelper::ServiceManager::Data::Implementation(
     330             :             attrImplementation_, attrLoader_, attrUri_, attrPrefix_,
     331      126974 :             alienContext_, reader_.getUrl()));
     332      253948 :     if (!data_->namedImplementations.insert(
     333             :             cppuhelper::ServiceManager::Data::NamedImplementations::value_type(
     334      253948 :                 attrImplementation_, implementation_)).
     335      253948 :         second)
     336             :     {
     337             :         throw css::registry::InvalidRegistryException(
     338           0 :             (reader_.getUrl() + ": duplicate <implementation name=\""
     339           0 :              + attrImplementation_ + "\">"),
     340           0 :             css::uno::Reference< css::uno::XInterface >());
     341             :     }
     342      126974 : }
     343             : 
     344      155695 : void Parser::handleService() {
     345      155695 :     rtl::OUString name(getNameAttribute());
     346      155695 :     implementation_->info->services.push_back(name);
     347      155695 :     data_->services[name].push_back(implementation_);
     348      155695 : }
     349             : 
     350        2379 : void Parser::handleSingleton() {
     351        2379 :     rtl::OUString name(getNameAttribute());
     352        2379 :     implementation_->info->singletons.push_back(name);
     353        2379 :     data_->singletons[name].push_back(implementation_);
     354        2379 : }
     355             : 
     356      285048 : rtl::OUString Parser::getNameAttribute() {
     357      285048 :     rtl::OUString attrName;
     358      285048 :     xmlreader::Span name;
     359             :     int nsId;
     360      285048 :     while (reader_.nextAttribute(&nsId, &name)) {
     361      570096 :         if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
     362      285048 :             && name.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     363             :         {
     364      285048 :             if (!attrName.isEmpty()) {
     365             :                 throw css::registry::InvalidRegistryException(
     366             :                     (reader_.getUrl()
     367           0 :                      + ": element has multiple \"name\" attributes"),
     368           0 :                     css::uno::Reference< css::uno::XInterface >());
     369             :             }
     370      285048 :             attrName = reader_.getAttributeValue(false).convertFromUtf8();
     371      285048 :             if (attrName.isEmpty()) {
     372             :                 throw css::registry::InvalidRegistryException(
     373           0 :                     reader_.getUrl() + ": element has empty \"name\" attribute",
     374           0 :                     css::uno::Reference< css::uno::XInterface >());
     375             :             }
     376             :         } else {
     377             :             throw css::registry::InvalidRegistryException(
     378           0 :                 reader_.getUrl() + ": expected element attribute \"name\"",
     379           0 :                 css::uno::Reference< css::uno::XInterface >());
     380             :         }
     381             :     }
     382      285048 :     if (attrName.isEmpty()) {
     383             :         throw css::registry::InvalidRegistryException(
     384           0 :             reader_.getUrl() + ": element is missing \"name\" attribute",
     385           0 :             css::uno::Reference< css::uno::XInterface >());
     386             :     }
     387      285048 :     return attrName;
     388             : }
     389             : 
     390             : class ContentEnumeration:
     391             :     public cppu::WeakImplHelper1< css::container::XEnumeration >,
     392             :     private boost::noncopyable
     393             : {
     394             : public:
     395         805 :     explicit ContentEnumeration(std::vector< css::uno::Any > const & factories):
     396         805 :         factories_(factories), iterator_(factories_.begin()) {}
     397             : 
     398             : private:
     399        1610 :     virtual ~ContentEnumeration() {}
     400             : 
     401             :     virtual sal_Bool SAL_CALL hasMoreElements()
     402             :         throw (css::uno::RuntimeException);
     403             : 
     404             :     virtual css::uno::Any SAL_CALL nextElement()
     405             :         throw (
     406             :             css::container::NoSuchElementException,
     407             :             css::lang::WrappedTargetException, css::uno::RuntimeException);
     408             : 
     409             :     osl::Mutex mutex_;
     410             :     std::vector< css::uno::Any > factories_;
     411             :     std::vector< css::uno::Any >::const_iterator iterator_;
     412             : };
     413             : 
     414        2501 : sal_Bool ContentEnumeration::hasMoreElements()
     415             :     throw (css::uno::RuntimeException)
     416             : {
     417        2501 :     osl::MutexGuard g(mutex_);
     418        2501 :     return iterator_ != factories_.end();
     419             : }
     420             : 
     421        1697 : css::uno::Any ContentEnumeration::nextElement()
     422             :     throw (
     423             :         css::container::NoSuchElementException,
     424             :         css::lang::WrappedTargetException, css::uno::RuntimeException)
     425             : {
     426        1697 :     osl::MutexGuard g(mutex_);
     427        1697 :     if (iterator_ == factories_.end()) {
     428             :         throw css::container::NoSuchElementException(
     429             :             "Bootstrap service manager service enumerator has no more elements",
     430           0 :             static_cast< cppu::OWeakObject * >(this));
     431             :     }
     432        1697 :     return *iterator_++;
     433             : }
     434             : 
     435           1 : css::beans::Property getDefaultContextProperty() {
     436             :     return css::beans::Property(
     437             :         "DefaultContext", -1,
     438           1 :         cppu::UnoType< css::uno::XComponentContext >::get(),
     439           1 :         css::beans::PropertyAttribute::READONLY);
     440             : }
     441             : 
     442             : class FactoryWrapper:
     443             :     public cppu::WeakImplHelper3<
     444             :         css::lang::XSingleComponentFactory, css::lang::XSingleServiceFactory,
     445             :         css::lang::XServiceInfo >,
     446             :     private boost::noncopyable
     447             : {
     448             : public:
     449         529 :     FactoryWrapper(
     450             :         rtl::Reference< cppuhelper::ServiceManager > const & manager,
     451             :         boost::shared_ptr<
     452             :             cppuhelper::ServiceManager::Data::ImplementationInfo > const &
     453             :             info):
     454         529 :         manager_(manager), info_(info), loaded_(false)
     455         529 :     { assert(manager.is() && info.get() != 0); }
     456             : 
     457             : private:
     458         956 :     virtual ~FactoryWrapper() {}
     459             : 
     460             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     461             :     createInstanceWithContext(
     462             :         css::uno::Reference< css::uno::XComponentContext > const & Context)
     463             :         throw (css::uno::Exception, css::uno::RuntimeException);
     464             : 
     465             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     466             :     createInstanceWithArgumentsAndContext(
     467             :         css::uno::Sequence< css::uno::Any > const & Arguments,
     468             :         css::uno::Reference< css::uno::XComponentContext > const & Context)
     469             :         throw (css::uno::Exception, css::uno::RuntimeException);
     470             : 
     471             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     472             :     createInstance() throw (css::uno::Exception, css::uno::RuntimeException);
     473             : 
     474             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     475             :     createInstanceWithArguments(
     476             :         css::uno::Sequence< css::uno::Any > const & Arguments)
     477             :         throw (css::uno::Exception, css::uno::RuntimeException);
     478             : 
     479             :     virtual rtl::OUString SAL_CALL getImplementationName()
     480             :         throw (css::uno::RuntimeException);
     481             : 
     482             :     virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
     483             :         throw (css::uno::RuntimeException);
     484             : 
     485             :     virtual css::uno::Sequence< rtl::OUString > SAL_CALL
     486             :     getSupportedServiceNames() throw (css::uno::RuntimeException);
     487             : 
     488             :     void loadImplementation(
     489             :         css::uno::Reference< css::uno::XComponentContext > const & context);
     490             : 
     491             :     rtl::Reference< cppuhelper::ServiceManager > manager_;
     492             :     boost::shared_ptr< cppuhelper::ServiceManager::Data::ImplementationInfo >
     493             :         info_;
     494             : 
     495             :     osl::Mutex mutex_;
     496             :     bool loaded_;
     497             :     css::uno::Reference< css::lang::XSingleComponentFactory > factory1_;
     498             :     css::uno::Reference< css::lang::XSingleServiceFactory > factory2_;
     499             : };
     500             : 
     501             : css::uno::Reference< css::uno::XInterface >
     502          96 : FactoryWrapper::createInstanceWithContext(
     503             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
     504             :     throw (css::uno::Exception, css::uno::RuntimeException)
     505             : {
     506          96 :     loadImplementation(Context);
     507          96 :     return factory1_.is()
     508          96 :         ? factory1_->createInstanceWithContext(Context)
     509         192 :         : factory2_->createInstance();
     510             : }
     511             : 
     512             : css::uno::Reference< css::uno::XInterface >
     513        1647 : FactoryWrapper::createInstanceWithArgumentsAndContext(
     514             :     css::uno::Sequence< css::uno::Any > const & Arguments,
     515             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
     516             :     throw (css::uno::Exception, css::uno::RuntimeException)
     517             : {
     518        1647 :     loadImplementation(Context);
     519        1647 :     return factory1_.is()
     520        1647 :         ? factory1_->createInstanceWithArgumentsAndContext(Arguments, Context)
     521        3294 :         : factory2_->createInstanceWithArguments(Arguments);
     522             : }
     523             : 
     524           0 : css::uno::Reference< css::uno::XInterface > FactoryWrapper::createInstance()
     525             :     throw (css::uno::Exception, css::uno::RuntimeException)
     526             : {
     527           0 :     loadImplementation(manager_->getContext());
     528           0 :     return factory1_.is()
     529           0 :         ? factory1_->createInstanceWithContext(manager_->getContext())
     530           0 :         : factory2_->createInstance();
     531             : }
     532             : 
     533             : css::uno::Reference< css::uno::XInterface >
     534           0 : FactoryWrapper::createInstanceWithArguments(
     535             :     css::uno::Sequence< css::uno::Any > const & Arguments)
     536             :     throw (css::uno::Exception, css::uno::RuntimeException)
     537             : {
     538           0 :     loadImplementation(manager_->getContext());
     539           0 :     return factory1_.is()
     540           0 :         ? factory1_->createInstanceWithArgumentsAndContext(
     541           0 :             Arguments, manager_->getContext())
     542           0 :         : factory2_->createInstanceWithArguments(Arguments);
     543             : }
     544             : 
     545        1570 : rtl::OUString FactoryWrapper::getImplementationName()
     546             :     throw (css::uno::RuntimeException)
     547             : {
     548        1570 :     return info_->name;
     549             : }
     550             : 
     551           0 : sal_Bool FactoryWrapper::supportsService(rtl::OUString const & ServiceName)
     552             :     throw (css::uno::RuntimeException)
     553             : {
     554           0 :     return cppu::supportsService(this, ServiceName);
     555             : }
     556             : 
     557          36 : css::uno::Sequence< rtl::OUString > FactoryWrapper::getSupportedServiceNames()
     558             :     throw (css::uno::RuntimeException)
     559             : {
     560          36 :     if (info_->services.size() > static_cast< sal_uInt32 >(SAL_MAX_INT32)) {
     561             :         throw css::uno::RuntimeException(
     562           0 :             "Implementation " + info_->name + " supports too many services",
     563           0 :             static_cast< cppu::OWeakObject * >(this));
     564             :     }
     565             :     css::uno::Sequence< rtl::OUString > names(
     566          36 :         static_cast< sal_Int32 >(info_->services.size()));
     567          36 :     sal_Int32 i = 0;
     568         528 :     for (std::vector< rtl::OUString >::const_iterator j(
     569          36 :              info_->services.begin());
     570         352 :          j != info_->services.end(); ++j)
     571             :     {
     572         140 :         names[i++] = *j;
     573             :     }
     574          36 :     return names;
     575             : }
     576             : 
     577        1743 : void FactoryWrapper::loadImplementation(
     578             :     css::uno::Reference< css::uno::XComponentContext > const & context)
     579             : {
     580             :     {
     581        1743 :         osl::MutexGuard g(mutex_);
     582        1743 :         if (loaded_) {
     583        3011 :             return;
     584         475 :         }
     585             :     }
     586         475 :     css::uno::Reference< css::lang::XSingleComponentFactory > f1;
     587         950 :     css::uno::Reference< css::lang::XSingleServiceFactory > f2;
     588             :     //TODO: There is a race here, as the relevant service factory can already
     589             :     // have been removed and loading can thus fail, as the entity from which to
     590             :     // load can disappear once the service factory is removed:
     591         475 :     manager_->loadImplementation(context, info_, &f1, &f2);
     592         475 :     if (!(f1.is() || f2.is())) {
     593             :         throw css::uno::DeploymentException(
     594           0 :             "Implementation " + info_->name + " does not provide a factory",
     595           0 :             static_cast< cppu::OWeakObject * >(this));
     596             :     }
     597         950 :     osl::MutexGuard g(mutex_);
     598         475 :     if (!loaded_) {
     599         475 :         loaded_ = true;
     600         475 :         factory1_ = f1;
     601         475 :         factory2_ = f2;
     602         475 :     }
     603             : }
     604             : 
     605             : }
     606             : 
     607         391 : void cppuhelper::ServiceManager::addSingletonContextEntries(
     608             :     std::vector< cppu::ContextEntry_Init > * entries) const
     609             : {
     610             :     assert(entries != 0);
     611        8310 :     for (Data::ImplementationMap::const_iterator i(data_.singletons.begin());
     612        5540 :          i != data_.singletons.end(); ++i)
     613             :     {
     614             :         assert(!i->second.empty());
     615             :         assert(i->second[0].get() != 0);
     616             :         SAL_INFO_IF(
     617             :             i->second.size() > 1, "cppuhelper",
     618             :             "Arbitrarily chosing " << i->second[0]->info->name
     619             :                 << " among multiple implementations for " << i->first);
     620             :         entries->push_back(
     621             :             cppu::ContextEntry_Init(
     622        4758 :                 "/singletons/" + i->first,
     623        7137 :                 css::uno::makeAny(i->second[0]->info->name), true));
     624             :     }
     625         391 : }
     626             : 
     627        9445 : void cppuhelper::ServiceManager::loadImplementation(
     628             :         css::uno::Reference< css::uno::XComponentContext > const & context,
     629             :         boost::shared_ptr< Data::ImplementationInfo > const & info,
     630             :         css::uno::Reference< css::lang::XSingleComponentFactory > * factory1,
     631             :         css::uno::Reference< css::lang::XSingleServiceFactory > * factory2)
     632             : {
     633             :     assert(
     634             :         info.get() != 0 && factory1 != 0 && !factory1->is() && factory2 != 0
     635             :         && !factory2->is());
     636        9445 :     rtl::OUString uri;
     637             :     try {
     638        9445 :         uri = cppu::bootstrap_expandUri(info->uri);
     639           0 :     } catch (css::lang::IllegalArgumentException & e) {
     640             :         throw css::uno::DeploymentException(
     641           0 :             "Cannot expand URI" + info->uri + ": " + e.Message,
     642           0 :             static_cast< cppu::OWeakObject * >(this));
     643             :     }
     644       18890 :     css::uno::Reference< css::uno::XInterface > f0;
     645             :     // Shortcut loading via SharedLibrary loader, to pass in prefix argument
     646             :     // (which the loader's activate implementation would normally obtain through
     647             :     // the legacy xKey argument):
     648       18890 :     if (!info->alienContext.is()
     649        9445 :         && info->loader == "com.sun.star.loader.SharedLibrary")
     650             :     {
     651        9444 :         rtl::OUString prefix(info->prefix);
     652        9444 :         if (!prefix.isEmpty()) {
     653        9440 :             prefix += "_";
     654             :         }
     655       28332 :         f0 = cppu::loadSharedLibComponentFactory(
     656        9444 :             uri, rtl::OUString(), info->name, this,
     657       18888 :             css::uno::Reference< css::registry::XRegistryKey >(), prefix);
     658             :     } else {
     659             :         SAL_INFO_IF(
     660             :             !info->prefix.isEmpty(), "cppuhelper",
     661             :             "Loader " << info->loader << " and non-empty prefix "
     662             :                 << info->prefix);
     663           1 :         css::uno::Reference< css::uno::XComponentContext > ctxt;
     664           2 :         css::uno::Reference< css::lang::XMultiComponentFactory > smgr;
     665           1 :         if (info->alienContext.is()) {
     666           0 :             ctxt = info->alienContext;
     667           0 :             smgr = css::uno::Reference< css::lang::XMultiComponentFactory >(
     668           0 :                 ctxt->getServiceManager(), css::uno::UNO_SET_THROW);
     669             :         } else {
     670             :             assert(context.is());
     671           1 :             ctxt = context;
     672           1 :             smgr = this;
     673             :         }
     674             :         css::uno::Reference< css::loader::XImplementationLoader > loader(
     675           1 :             smgr->createInstanceWithContext(info->loader, ctxt),
     676           2 :             css::uno::UNO_QUERY_THROW);
     677           4 :         f0 = loader->activate(
     678           1 :             info->name, rtl::OUString(), uri,
     679           3 :             css::uno::Reference< css::registry::XRegistryKey >());
     680             :     }
     681        9445 :     factory1->set(f0, css::uno::UNO_QUERY);
     682        9445 :     if (!factory1->is()) {
     683         113 :         factory2->set(f0, css::uno::UNO_QUERY);
     684        9445 :     }
     685        9445 : }
     686             : 
     687         166 : void cppuhelper::ServiceManager::disposing() {
     688         166 :     std::vector< css::uno::Reference< css::lang::XComponent > > comps;
     689         332 :     Data clear;
     690             :     {
     691         166 :         osl::MutexGuard g(rBHelper.rMutex);
     692        1704 :         for (Data::DynamicImplementations::const_iterator i(
     693         166 :                  data_.dynamicImplementations.begin());
     694        1136 :              i != data_.dynamicImplementations.end(); ++i)
     695             :         {
     696             :             assert(i->second.get() != 0);
     697         402 :             if (i->second->component.is()) {
     698         402 :                 comps.push_back(i->second->component);
     699             :             }
     700             :         }
     701         166 :         data_.namedImplementations.swap(clear.namedImplementations);
     702         166 :         data_.dynamicImplementations.swap(clear.dynamicImplementations);
     703         166 :         data_.services.swap(clear.services);
     704         166 :         data_.singletons.swap(clear.singletons);
     705             :     }
     706        1704 :     for (std::vector<
     707             :              css::uno::Reference< css::lang::XComponent > >::const_iterator i(
     708         166 :                  comps.begin());
     709        1136 :          i != comps.end(); ++i)
     710             :     {
     711         402 :         removeEventListenerFromComponent(*i);
     712         166 :     }
     713         166 : }
     714             : 
     715           0 : rtl::OUString cppuhelper::ServiceManager::getImplementationName()
     716             :     throw (css::uno::RuntimeException)
     717             : {
     718             :     return rtl::OUString(
     719           0 :         "com.sun.star.comp.cppuhelper.bootstrap.ServiceManager");
     720             : }
     721             : 
     722           0 : sal_Bool cppuhelper::ServiceManager::supportsService(
     723             :     rtl::OUString const & ServiceName)
     724             :     throw (css::uno::RuntimeException)
     725             : {
     726           0 :     return cppu::supportsService(this, ServiceName);
     727             : }
     728             : 
     729             : css::uno::Sequence< rtl::OUString >
     730           0 : cppuhelper::ServiceManager::getSupportedServiceNames()
     731             :     throw (css::uno::RuntimeException)
     732             : {
     733           0 :     css::uno::Sequence< rtl::OUString > names(2);
     734           0 :     names[0] = "com.sun.star.lang.MultiServiceFactory";
     735           0 :     names[1] = "com.sun.star.lang.ServiceManager";
     736           0 :     return names;
     737             : }
     738             : 
     739             : css::uno::Reference< css::uno::XInterface >
     740       19360 : cppuhelper::ServiceManager::createInstance(
     741             :     rtl::OUString const & aServiceSpecifier)
     742             :     throw (css::uno::Exception, css::uno::RuntimeException)
     743             : {
     744             :     assert(context_.is());
     745       19360 :     return createInstanceWithContext(aServiceSpecifier, context_);
     746             : }
     747             : 
     748             : css::uno::Reference< css::uno::XInterface >
     749         505 : cppuhelper::ServiceManager::createInstanceWithArguments(
     750             :     rtl::OUString const & ServiceSpecifier,
     751             :     css::uno::Sequence< css::uno::Any > const & Arguments)
     752             :     throw (css::uno::Exception, css::uno::RuntimeException)
     753             : {
     754             :     assert(context_.is());
     755             :     return createInstanceWithArgumentsAndContext(
     756         505 :         ServiceSpecifier, Arguments, context_);
     757             : }
     758             : 
     759             : css::uno::Sequence< rtl::OUString >
     760           0 : cppuhelper::ServiceManager::getAvailableServiceNames()
     761             :     throw (css::uno::RuntimeException)
     762             : {
     763           0 :     osl::MutexGuard g(rBHelper.rMutex);
     764           0 :     if (isDisposed()) {
     765           0 :         return css::uno::Sequence< rtl::OUString >();
     766             :     }
     767           0 :     Data::ImplementationMap::size_type n = data_.services.size();
     768           0 :     if (n > static_cast< sal_uInt32 >(SAL_MAX_INT32)) {
     769             :         throw css::uno::RuntimeException(
     770             :             "getAvailableServiceNames: too many services",
     771           0 :             static_cast< cppu::OWeakObject * >(this));
     772             :     }
     773           0 :     css::uno::Sequence< rtl::OUString > names(static_cast< sal_Int32 >(n));
     774           0 :     sal_Int32 i = 0;
     775           0 :     for (Data::ImplementationMap::const_iterator j(data_.services.begin());
     776           0 :          j != data_.services.end(); ++j)
     777             :     {
     778           0 :         names[i++] = j->first;
     779             :     }
     780             :     assert(i == names.getLength());
     781           0 :     return names;
     782             : }
     783             : 
     784             : css::uno::Reference< css::uno::XInterface >
     785      637902 : cppuhelper::ServiceManager::createInstanceWithContext(
     786             :     rtl::OUString const & aServiceSpecifier,
     787             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
     788             :     throw (css::uno::Exception, css::uno::RuntimeException)
     789             : {
     790             :     boost::shared_ptr< Data::Implementation > impl(
     791      637902 :         findServiceImplementation(Context, aServiceSpecifier));
     792      637902 :     if (impl.get() == 0) {
     793       52103 :         return css::uno::Reference< css::uno::XInterface >();
     794             :     }
     795      585799 :     if (impl->factory1.is()) {
     796      584551 :         return impl->factory1->createInstanceWithContext(Context);
     797             :     }
     798        1248 :     if (impl->factory2.is()) {
     799        1248 :         return impl->factory2->createInstance();
     800             :     }
     801             :     throw css::uno::DeploymentException(
     802           0 :         "Implementation " + impl->info->name + " does not provide a factory",
     803           0 :         static_cast< cppu::OWeakObject * >(this));
     804             : }
     805             : 
     806             : css::uno::Reference< css::uno::XInterface >
     807      121419 : cppuhelper::ServiceManager::createInstanceWithArgumentsAndContext(
     808             :     rtl::OUString const & ServiceSpecifier,
     809             :     css::uno::Sequence< css::uno::Any > const & Arguments,
     810             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
     811             :     throw (css::uno::Exception, css::uno::RuntimeException)
     812             : {
     813             :     boost::shared_ptr< Data::Implementation > impl(
     814      121419 :         findServiceImplementation(Context, ServiceSpecifier));
     815      121419 :     if (impl.get() == 0) {
     816        9423 :         return css::uno::Reference< css::uno::XInterface >();
     817             :     }
     818      111996 :     if (impl->factory1.is()) {
     819      111211 :         return impl->factory1->createInstanceWithArgumentsAndContext(
     820      111211 :             Arguments, Context);
     821             :     }
     822         785 :     if (impl->factory2.is()) {
     823         785 :         return impl->factory2->createInstanceWithArguments(Arguments);
     824             :     }
     825             :     throw css::uno::DeploymentException(
     826           0 :         "Implementation " + impl->info->name + " does not provide a factory",
     827           0 :         static_cast< cppu::OWeakObject * >(this));
     828             : }
     829             : 
     830           0 : css::uno::Type cppuhelper::ServiceManager::getElementType()
     831             :     throw (css::uno::RuntimeException)
     832             : {
     833           0 :     return css::uno::Type();
     834             : }
     835             : 
     836           0 : sal_Bool cppuhelper::ServiceManager::hasElements()
     837             :     throw (css::uno::RuntimeException)
     838             : {
     839           0 :     osl::MutexGuard g(rBHelper.rMutex);
     840             :     return
     841           0 :         !(data_.namedImplementations.empty()
     842           0 :           && data_.dynamicImplementations.empty());
     843             : }
     844             : 
     845             : css::uno::Reference< css::container::XEnumeration >
     846           0 : cppuhelper::ServiceManager::createEnumeration()
     847             :     throw (css::uno::RuntimeException)
     848             : {
     849             :     throw css::uno::RuntimeException(
     850             :         "ServiceManager createEnumeration: method not supported",
     851           0 :         static_cast< cppu::OWeakObject * >(this));
     852             : }
     853             : 
     854           0 : sal_Bool cppuhelper::ServiceManager::has(css::uno::Any const &)
     855             :     throw (css::uno::RuntimeException)
     856             : {
     857             :     throw css::uno::RuntimeException(
     858             :         "ServiceManager has: method not supported",
     859           0 :         static_cast< cppu::OWeakObject * >(this));
     860             : }
     861             : 
     862         415 : void cppuhelper::ServiceManager::insert(css::uno::Any const & aElement)
     863             :     throw (
     864             :         css::lang::IllegalArgumentException,
     865             :         css::container::ElementExistException, css::uno::RuntimeException)
     866             : {
     867         415 :     css::uno::Sequence< css::beans::NamedValue > args;
     868         415 :     if (aElement >>= args) {
     869           0 :         std::vector< rtl::OUString > uris;
     870           0 :         css::uno::Reference< css::uno::XComponentContext > alienContext;
     871           0 :         for (sal_Int32 i = 0; i < args.getLength(); ++i) {
     872           0 :             if (args[i].Name == "uri") {
     873           0 :                 rtl::OUString uri;
     874           0 :                 if (!(args[i].Value >>= uri)) {
     875             :                     throw css::lang::IllegalArgumentException(
     876             :                         "Bad uri argument",
     877           0 :                         static_cast< cppu::OWeakObject * >(this), 0);
     878             :                 }
     879           0 :                 uris.push_back(uri);
     880           0 :             } else if (args[i].Name == "component-context") {
     881           0 :                 if (alienContext.is()) {
     882             :                     throw css::lang::IllegalArgumentException(
     883             :                         "Multiple component-context arguments",
     884           0 :                         static_cast< cppu::OWeakObject * >(this), 0);
     885             :                 }
     886           0 :                 if (!(args[i].Value >>= alienContext) || !alienContext.is()) {
     887             :                     throw css::lang::IllegalArgumentException(
     888             :                         "Bad component-context argument",
     889           0 :                         static_cast< cppu::OWeakObject * >(this), 0);
     890             :                 }
     891             :             } else {
     892             :                 throw css::lang::IllegalArgumentException(
     893           0 :                     "Bad argument " + args[i].Name,
     894           0 :                     static_cast< cppu::OWeakObject * >(this), 0);
     895             :             }
     896             :         }
     897           0 :         insertRdbFiles(uris, alienContext);
     898           0 :         return;
     899             :     }
     900         830 :     css::uno::Reference< css::lang::XServiceInfo > info;
     901         415 :     if ((aElement >>= info) && info.is()) {
     902         415 :         insertLegacyFactory(info);
     903         415 :         return;
     904             :     }
     905             : // At least revisions up to 1.7 of LanguageTool.oxt (incl. the bundled 1.4.0 in
     906             : // module languagetool) contain an (actively registered) factory that does not
     907             : // implement XServiceInfo (see <http://sourceforge.net/tracker/?
     908             : // func=detail&aid=3526635&group_id=110216&atid=655717> "SingletonFactory should
     909             : // implement XServiceInfo"); the old OServiceManager::insert
     910             : // (stoc/source/servicemanager/servicemanager.cxx) silently did not add such
     911             : // broken factories to its m_ImplementationNameMap, so ignore them here for
     912             : // backwards compatibility of live-insertion of extensions, too.
     913             : 
     914             : // (The plan was that this warning would go away (and we would do the
     915             : // throw instead) for the incompatible LO 4, but we changed our mind):
     916           0 :     css::uno::Reference< css::lang::XSingleComponentFactory > legacy;
     917           0 :     if ((aElement >>= legacy) && legacy.is()) {
     918             :         SAL_WARN(
     919             :             "cppuhelper",
     920             :             "Ignored XSingleComponentFactory not implementing XServiceInfo");
     921           0 :         return;
     922             :     }
     923             : 
     924             :     throw css::lang::IllegalArgumentException(
     925         415 :         "Bad insert element", static_cast< cppu::OWeakObject * >(this), 0);
     926             : }
     927             : 
     928           1 : void cppuhelper::ServiceManager::remove(css::uno::Any const & aElement)
     929             :     throw (
     930             :         css::lang::IllegalArgumentException,
     931             :         css::container::NoSuchElementException, css::uno::RuntimeException)
     932             : {
     933           1 :     css::uno::Sequence< css::beans::NamedValue > args;
     934           1 :     if (aElement >>= args) {
     935           0 :         std::vector< rtl::OUString > uris;
     936           0 :         for (sal_Int32 i = 0; i < args.getLength(); ++i) {
     937           0 :             if (args[i].Name == "uri") {
     938           0 :                 rtl::OUString uri;
     939           0 :                 if (!(args[i].Value >>= uri)) {
     940             :                     throw css::lang::IllegalArgumentException(
     941             :                         "Bad uri argument",
     942           0 :                         static_cast< cppu::OWeakObject * >(this), 0);
     943             :                 }
     944           0 :                 uris.push_back(uri);
     945             :             } else {
     946             :                 throw css::lang::IllegalArgumentException(
     947           0 :                     "Bad argument " + args[i].Name,
     948           0 :                     static_cast< cppu::OWeakObject * >(this), 0);
     949             :             }
     950             :         }
     951           0 :         removeRdbFiles(uris);
     952           0 :         return;
     953             :     }
     954           2 :     css::uno::Reference< css::lang::XServiceInfo > info;
     955           1 :     if ((aElement >>= info) && info.is()) {
     956           0 :         if (!removeLegacyFactory(info, true)) {
     957             :             throw css::container::NoSuchElementException(
     958             :                 "Remove non-inserted factory object",
     959           0 :                 static_cast< cppu::OWeakObject * >(this));
     960             :         }
     961           0 :         return;
     962             :     }
     963           2 :     rtl::OUString impl;
     964           1 :     if (aElement >>= impl) {
     965             :         // For live-removal of extensions:
     966           1 :         removeImplementation(impl);
     967           1 :         return;
     968             :     }
     969             :     throw css::lang::IllegalArgumentException(
     970           1 :         "Bad remove element", static_cast< cppu::OWeakObject * >(this), 0);
     971             : }
     972             : 
     973             : css::uno::Reference< css::container::XEnumeration >
     974         805 : cppuhelper::ServiceManager::createContentEnumeration(
     975             :     rtl::OUString const & aServiceName)
     976             :     throw (css::uno::RuntimeException)
     977             : {
     978         805 :     std::vector< boost::shared_ptr< Data::Implementation > > impls;
     979             :     {
     980         805 :         osl::MutexGuard g(rBHelper.rMutex);
     981             :         Data::ImplementationMap::const_iterator i(
     982         805 :             data_.services.find(aServiceName));
     983         805 :         if (i != data_.services.end()) {
     984         366 :             impls = i->second;
     985         805 :         }
     986             :     }
     987        1610 :     std::vector< css::uno::Any > factories;
     988        7521 :     for (std::vector<
     989             :              boost::shared_ptr< Data::Implementation > >::const_iterator i(
     990         805 :                  impls.begin());
     991        5014 :          i != impls.end(); ++i)
     992             :     {
     993        1702 :         Data::Implementation * impl = i->get();
     994             :         assert(impl != 0);
     995             :         {
     996        1702 :             osl::MutexGuard g(rBHelper.rMutex);
     997        1702 :             if (isDisposed()) {
     998           0 :                 factories.clear();
     999           0 :                 break;
    1000             :             }
    1001        1702 :             if (!impl->loaded) {
    1002             :                 // Postpone actual factory instantiation as long as possible (so
    1003             :                 // that e.g. opening LO's "Tools - Macros" menu does not try to
    1004             :                 // instantiate a JVM, which can lead to a synchronous error
    1005             :                 // dialog when no JVM is specified, and showing the dialog while
    1006             :                 // hovering over a menu can cause trouble):
    1007         529 :                 impl->factory1 = new FactoryWrapper(this, impl->info);
    1008         529 :                 impl->loaded = true;
    1009        1702 :             }
    1010             :         }
    1011        1702 :         if (impl->factory1.is()) {
    1012        1702 :             factories.push_back(css::uno::makeAny(impl->factory1));
    1013           0 :         } else if (impl->factory2.is()) {
    1014           0 :             factories.push_back(css::uno::makeAny(impl->factory2));
    1015             :         } else {
    1016             :             throw css::uno::DeploymentException(
    1017           0 :                 ("Implementation " + impl->info->name
    1018           0 :                  + " does not provide a factory"),
    1019           0 :                 static_cast< cppu::OWeakObject * >(this));
    1020             :         }
    1021             :     }
    1022        1610 :     return new ContentEnumeration(factories);
    1023             : }
    1024             : 
    1025             : css::uno::Reference< css::beans::XPropertySetInfo >
    1026           6 : cppuhelper::ServiceManager::getPropertySetInfo()
    1027             :     throw (css::uno::RuntimeException)
    1028             : {
    1029           6 :     return this;
    1030             : }
    1031             : 
    1032           0 : void cppuhelper::ServiceManager::setPropertyValue(
    1033             :     rtl::OUString const & aPropertyName, css::uno::Any const &)
    1034             :     throw (
    1035             :         css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
    1036             :         css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
    1037             :         css::uno::RuntimeException)
    1038             : {
    1039           0 :     if (aPropertyName == "DefaultContext") {
    1040             :         throw css::beans::PropertyVetoException(
    1041           0 :             aPropertyName, static_cast< cppu::OWeakObject * >(this));
    1042             :     } else {
    1043             :         throw css::beans::UnknownPropertyException(
    1044           0 :             aPropertyName, static_cast< cppu::OWeakObject * >(this));
    1045             :     }
    1046             : }
    1047             : 
    1048      735610 : css::uno::Any cppuhelper::ServiceManager::getPropertyValue(
    1049             :     rtl::OUString const & PropertyName)
    1050             :     throw (
    1051             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1052             :         css::uno::RuntimeException)
    1053             : {
    1054      735610 :     if (PropertyName != "DefaultContext") {
    1055             :         throw css::beans::UnknownPropertyException(
    1056           0 :             PropertyName, static_cast< cppu::OWeakObject * >(this));
    1057             :     }
    1058             :     assert(context_.is());
    1059      735610 :     return css::uno::makeAny(context_);
    1060             : }
    1061             : 
    1062           0 : void cppuhelper::ServiceManager::addPropertyChangeListener(
    1063             :     rtl::OUString const & aPropertyName,
    1064             :     css::uno::Reference< css::beans::XPropertyChangeListener > const &
    1065             :         xListener)
    1066             :     throw (
    1067             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1068             :         css::uno::RuntimeException)
    1069             : {
    1070           0 :     if (!aPropertyName.isEmpty() && aPropertyName != "DefaultContext") {
    1071             :         throw css::beans::UnknownPropertyException(
    1072           0 :             aPropertyName, static_cast< cppu::OWeakObject * >(this));
    1073             :     }
    1074             :     // DefaultContext does not change, so just treat it as an event listener:
    1075           0 :     return addEventListener(xListener.get());
    1076             : }
    1077             : 
    1078           0 : void cppuhelper::ServiceManager::removePropertyChangeListener(
    1079             :     rtl::OUString const & aPropertyName,
    1080             :     css::uno::Reference< css::beans::XPropertyChangeListener > const &
    1081             :         aListener)
    1082             :     throw (
    1083             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1084             :         css::uno::RuntimeException)
    1085             : {
    1086           0 :     if (!aPropertyName.isEmpty() && aPropertyName != "DefaultContext") {
    1087             :         throw css::beans::UnknownPropertyException(
    1088           0 :             aPropertyName, static_cast< cppu::OWeakObject * >(this));
    1089             :     }
    1090             :     // DefaultContext does not change, so just treat it as an event listener:
    1091           0 :     return removeEventListener(aListener.get());
    1092             : }
    1093             : 
    1094           0 : void cppuhelper::ServiceManager::addVetoableChangeListener(
    1095             :     rtl::OUString const & PropertyName,
    1096             :     css::uno::Reference< css::beans::XVetoableChangeListener > const &
    1097             :         aListener)
    1098             :     throw (
    1099             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1100             :         css::uno::RuntimeException)
    1101             : {
    1102           0 :     if (!PropertyName.isEmpty() && PropertyName != "DefaultContext") {
    1103             :         throw css::beans::UnknownPropertyException(
    1104           0 :             PropertyName, static_cast< cppu::OWeakObject * >(this));
    1105             :     }
    1106             :     // DefaultContext does not change, so just treat it as an event listener:
    1107           0 :     return addEventListener(aListener.get());
    1108             : }
    1109             : 
    1110           0 : void cppuhelper::ServiceManager::removeVetoableChangeListener(
    1111             :     rtl::OUString const & PropertyName,
    1112             :     css::uno::Reference< css::beans::XVetoableChangeListener > const &
    1113             :         aListener)
    1114             :     throw (
    1115             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1116             :         css::uno::RuntimeException)
    1117             : {
    1118           0 :     if (!PropertyName.isEmpty() && PropertyName != "DefaultContext") {
    1119             :         throw css::beans::UnknownPropertyException(
    1120           0 :             PropertyName, static_cast< cppu::OWeakObject * >(this));
    1121             :     }
    1122             :     // DefaultContext does not change, so just treat it as an event listener:
    1123           0 :     return removeEventListener(aListener.get());
    1124             : }
    1125             : 
    1126             : css::uno::Sequence< css::beans::Property >
    1127           1 : cppuhelper::ServiceManager::getProperties() throw (css::uno::RuntimeException) {
    1128           1 :     css::uno::Sequence< css::beans::Property > props(1);
    1129           1 :     props[0] = getDefaultContextProperty();
    1130           1 :     return props;
    1131             : }
    1132             : 
    1133           0 : css::beans::Property cppuhelper::ServiceManager::getPropertyByName(
    1134             :     rtl::OUString const & aName)
    1135             :     throw (css::beans::UnknownPropertyException, css::uno::RuntimeException)
    1136             : {
    1137           0 :     if (aName != "DefaultContext") {
    1138             :         throw css::beans::UnknownPropertyException(
    1139           0 :             aName, static_cast< cppu::OWeakObject * >(this));
    1140             :     }
    1141           0 :     return getDefaultContextProperty();
    1142             : }
    1143             : 
    1144           0 : sal_Bool cppuhelper::ServiceManager::hasPropertyByName(
    1145             :     rtl::OUString const & Name)
    1146             :     throw (css::uno::RuntimeException)
    1147             : {
    1148           0 :     return Name == "DefaultContext";
    1149             : }
    1150             : 
    1151           6 : void cppuhelper::ServiceManager::disposing(
    1152             :     css::lang::EventObject const & Source)
    1153             :     throw (css::uno::RuntimeException)
    1154             : {
    1155             :     removeLegacyFactory(
    1156             :         css::uno::Reference< css::lang::XServiceInfo >(
    1157             :             Source.Source, css::uno::UNO_QUERY_THROW),
    1158           6 :         false);
    1159           6 : }
    1160             : 
    1161         402 : void cppuhelper::ServiceManager::removeEventListenerFromComponent(
    1162             :     css::uno::Reference< css::lang::XComponent > const & component)
    1163             : {
    1164             :     assert(component.is());
    1165             :     try {
    1166         402 :         component->removeEventListener(this);
    1167           0 :     } catch (css::uno::RuntimeException & e) {
    1168             :         SAL_INFO(
    1169             :             "cppuhelper",
    1170             :             "Ignored removeEventListener RuntimeException " + e.Message);
    1171             :     }
    1172         402 : }
    1173             : 
    1174         391 : void cppuhelper::ServiceManager::readRdbs(rtl::OUString const & uris) {
    1175        3302 :     for (sal_Int32 i = 0; i != -1;) {
    1176        2520 :         rtl::OUString uri(uris.getToken(0, ' ', i));
    1177        2520 :         if (uri.isEmpty()) {
    1178         378 :             continue;
    1179             :         }
    1180             :         bool optional;
    1181             :         bool directory;
    1182        2142 :         cppu::decodeRdbUri(&uri, &optional, &directory);
    1183        2142 :         if (directory) {
    1184          85 :             readRdbDirectory(uri, optional);
    1185             :         } else {
    1186        2057 :             readRdbFile(uri, optional);
    1187             :         }
    1188        2142 :     }
    1189         391 : }
    1190             : 
    1191          85 : void cppuhelper::ServiceManager::readRdbDirectory(
    1192             :     rtl::OUString const & uri, bool optional)
    1193             : {
    1194          85 :     osl::Directory dir(uri);
    1195          85 :     switch (dir.open()) {
    1196             :     case osl::FileBase::E_None:
    1197          85 :         break;
    1198             :     case osl::FileBase::E_NOENT:
    1199           0 :         if (optional) {
    1200             :             SAL_INFO("cppuhelper", "Ignored optional " << uri);
    1201          85 :             return;
    1202             :         }
    1203             :         // fall through
    1204             :     default:
    1205             :         throw css::uno::DeploymentException(
    1206           0 :             "Cannot open directory " + uri,
    1207           0 :             static_cast< cppu::OWeakObject * >(this));
    1208             :     }
    1209             :     for (;;) {
    1210         595 :         rtl::OUString url;
    1211         595 :         if (!cppu::nextDirectoryItem(dir, &url)) {
    1212          85 :             break;
    1213             :         }
    1214         510 :         readRdbFile(url, false);
    1215         510 :     }
    1216             : }
    1217             : 
    1218        2567 : void cppuhelper::ServiceManager::readRdbFile(
    1219             :     rtl::OUString const & uri, bool optional)
    1220             : {
    1221             :     try {
    1222             :         Parser(
    1223        2569 :             uri, css::uno::Reference< css::uno::XComponentContext >(), &data_);
    1224           0 :     } catch (css::container::NoSuchElementException &) {
    1225           0 :         if (!optional) {
    1226             :             throw css::uno::DeploymentException(
    1227           0 :                 uri + ": no such file",
    1228           0 :                 static_cast< cppu::OWeakObject * >(this));
    1229             :         }
    1230             :         SAL_INFO("cppuhelper", "Ignored optional " << uri);
    1231           0 :     } catch (css::registry::InvalidRegistryException & e) {
    1232           0 :         if (!readLegacyRdbFile(uri)) {
    1233             :             throw css::uno::DeploymentException(
    1234           0 :                 "InvalidRegistryException: " + e.Message,
    1235           0 :                 static_cast< cppu::OWeakObject * >(this));
    1236             :         }
    1237           4 :     } catch (css::uno::RuntimeException &) {
    1238           2 :         if (!readLegacyRdbFile(uri)) {
    1239           0 :             throw;
    1240             :         }
    1241             :     }
    1242        2567 : }
    1243             : 
    1244           2 : bool cppuhelper::ServiceManager::readLegacyRdbFile(rtl::OUString const & uri) {
    1245           2 :     Registry reg;
    1246           2 :     switch (reg.open(uri, REG_READONLY)) {
    1247             :     case REG_NO_ERROR:
    1248           0 :         break;
    1249             :     case REG_REGISTRY_NOT_EXISTS:
    1250             :     case REG_INVALID_REGISTRY:
    1251             :         {
    1252             :             // Ignore empty rdb files (which are at least seen by subordinate
    1253             :             // uno processes during extension registration; Registry::open can
    1254             :             // fail on them if mmap(2) returns EINVAL for a zero length):
    1255           2 :             osl::DirectoryItem item;
    1256           2 :             if (osl::DirectoryItem::get(uri, item) == osl::FileBase::E_None) {
    1257           2 :                 osl::FileStatus status(osl_FileStatus_Mask_FileSize);
    1258           4 :                 if (item.getFileStatus(status) == osl::FileBase::E_None
    1259           2 :                     && status.getFileSize() == 0)
    1260             :                 {
    1261           2 :                     return true;
    1262           0 :                 }
    1263           0 :             }
    1264             :         }
    1265             :         // fall through
    1266             :     default:
    1267           0 :         return false;
    1268             :     }
    1269           0 :     RegistryKey rootKey;
    1270           0 :     if (reg.openRootKey(rootKey) != REG_NO_ERROR) {
    1271             :         throw css::uno::DeploymentException(
    1272           0 :             "Failure reading legacy rdb file " + uri,
    1273           0 :             static_cast< cppu::OWeakObject * >(this));
    1274             :     }
    1275           0 :     RegistryKeyArray impls;
    1276           0 :     switch (rootKey.openSubKeys("IMPLEMENTATIONS", impls)) {
    1277             :     case REG_NO_ERROR:
    1278           0 :         break;
    1279             :     case REG_KEY_NOT_EXISTS:
    1280           0 :         return true;
    1281             :     default:
    1282             :         throw css::uno::DeploymentException(
    1283           0 :             "Failure reading legacy rdb file " + uri,
    1284           0 :             static_cast< cppu::OWeakObject * >(this));
    1285             :     }
    1286           0 :     for (sal_uInt32 i = 0; i != impls.getLength(); ++i) {
    1287           0 :         RegistryKey implKey(impls.getElement(i));
    1288             :         assert(implKey.getName().match("/IMPLEMENTATIONS/"));
    1289             :         rtl::OUString name(
    1290           0 :             implKey.getName().copy(RTL_CONSTASCII_LENGTH("/IMPLEMENTATIONS/")));
    1291             :         boost::shared_ptr< Data::Implementation > impl(
    1292             :             new Data::Implementation(
    1293             :                 name, readLegacyRdbString(uri, implKey, "UNO/ACTIVATOR"),
    1294             :                 readLegacyRdbString(uri, implKey, "UNO/LOCATION"),
    1295             :                 rtl::OUString(),
    1296           0 :                 css::uno::Reference< css::uno::XComponentContext >(), uri));
    1297           0 :         if (!data_.namedImplementations.insert(
    1298           0 :                 Data::NamedImplementations::value_type(name, impl)).
    1299           0 :             second)
    1300             :         {
    1301             :             throw css::registry::InvalidRegistryException(
    1302           0 :                 uri + ": duplicate <implementation name=\"" + name + "\">",
    1303           0 :                 css::uno::Reference< css::uno::XInterface >());
    1304             :         }
    1305             :         readLegacyRdbStrings(
    1306           0 :             uri, implKey, "UNO/SERVICES", &impl->info->services);
    1307           0 :         for (std::vector< rtl::OUString >::const_iterator j(
    1308           0 :                  impl->info->services.begin());
    1309           0 :              j != impl->info->services.end(); ++j)
    1310             :         {
    1311           0 :             data_.services[*j].push_back(impl);
    1312             :         }
    1313             :         readLegacyRdbStrings(
    1314           0 :             uri, implKey, "UNO/SINGLETONS", &impl->info->singletons);
    1315           0 :         for (std::vector< rtl::OUString >::const_iterator j(
    1316           0 :                  impl->info->singletons.begin());
    1317           0 :              j != impl->info->singletons.end(); ++j)
    1318             :         {
    1319           0 :             data_.singletons[*j].push_back(impl);
    1320             :         }
    1321           0 :     }
    1322           0 :     return true;
    1323             : }
    1324             : 
    1325           0 : rtl::OUString cppuhelper::ServiceManager::readLegacyRdbString(
    1326             :     rtl::OUString const & uri, RegistryKey & key, rtl::OUString const & path)
    1327             : {
    1328           0 :     RegistryKey subkey;
    1329             :     RegValueType t;
    1330           0 :     sal_uInt32 s(0);
    1331           0 :     if (key.openKey(path, subkey) != REG_NO_ERROR
    1332           0 :         || subkey.getValueInfo(rtl::OUString(), &t, &s) != REG_NO_ERROR
    1333           0 :         || t != RG_VALUETYPE_STRING
    1334           0 :         || s == 0 || s > static_cast< sal_uInt32 >(SAL_MAX_INT32))
    1335             :     {
    1336             :         throw css::uno::DeploymentException(
    1337           0 :             "Failure reading legacy rdb file " + uri,
    1338           0 :             static_cast< cppu::OWeakObject * >(this));
    1339             :     }
    1340           0 :     rtl::OUString val;
    1341           0 :     std::vector< char > v(s); // assuming sal_uInt32 fits into vector::size_type
    1342           0 :     if (subkey.getValue(rtl::OUString(), &v[0]) != REG_NO_ERROR
    1343           0 :         || v.back() != '\0'
    1344           0 :         || !rtl_convertStringToUString(
    1345           0 :             &val.pData, &v[0], static_cast< sal_Int32 >(s - 1),
    1346             :             RTL_TEXTENCODING_UTF8,
    1347             :             (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
    1348             :              | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
    1349           0 :              | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
    1350             :     {
    1351             :         throw css::uno::DeploymentException(
    1352           0 :             "Failure reading legacy rdb file " + uri,
    1353           0 :             static_cast< cppu::OWeakObject * >(this));
    1354             :     }
    1355           0 :     return val;
    1356             : }
    1357             : 
    1358           0 : void cppuhelper::ServiceManager::readLegacyRdbStrings(
    1359             :     rtl::OUString const & uri, RegistryKey & key, rtl::OUString const & path,
    1360             :     std::vector< rtl::OUString > * strings)
    1361             : {
    1362             :     assert(strings != 0);
    1363           0 :     RegistryKey subkey;
    1364           0 :     switch (key.openKey(path, subkey)) {
    1365             :     case REG_NO_ERROR:
    1366           0 :         break;
    1367             :     case REG_KEY_NOT_EXISTS:
    1368           0 :         return;
    1369             :     default:
    1370             :         throw css::uno::DeploymentException(
    1371           0 :             "Failure reading legacy rdb file " + uri,
    1372           0 :             static_cast< cppu::OWeakObject * >(this));
    1373             :     }
    1374           0 :     rtl::OUString prefix(subkey.getName() + "/");
    1375           0 :     RegistryKeyNames names;
    1376           0 :     if (subkey.getKeyNames(rtl::OUString(), names) != REG_NO_ERROR) {
    1377             :         throw css::uno::DeploymentException(
    1378           0 :             "Failure reading legacy rdb file " + uri,
    1379           0 :             static_cast< cppu::OWeakObject * >(this));
    1380             :     }
    1381           0 :     for (sal_uInt32 i = 0; i != names.getLength(); ++i) {
    1382             :         assert(names.getElement(i).match(prefix));
    1383           0 :         strings->push_back(names.getElement(i).copy(prefix.getLength()));
    1384           0 :     }
    1385             : }
    1386             : 
    1387           0 : void cppuhelper::ServiceManager::insertRdbFiles(
    1388             :     std::vector< rtl::OUString > const & uris,
    1389             :     css::uno::Reference< css::uno::XComponentContext > const & alienContext)
    1390             : {
    1391           0 :     Data extra;
    1392           0 :     for (std::vector< rtl::OUString >::const_iterator i(uris.begin());
    1393           0 :          i != uris.end(); ++i)
    1394             :     {
    1395             :         try {
    1396           0 :             Parser(*i, alienContext, &extra);
    1397           0 :         } catch (css::container::NoSuchElementException &) {
    1398             :             throw css::lang::IllegalArgumentException(
    1399           0 :                 *i + ": no such file", static_cast< cppu::OWeakObject * >(this),
    1400           0 :                 0);
    1401           0 :         } catch (css::registry::InvalidRegistryException & e) {
    1402             :             throw css::lang::IllegalArgumentException(
    1403           0 :                 "InvalidRegistryException: " + e.Message,
    1404           0 :                 static_cast< cppu::OWeakObject * >(this), 0);
    1405             :         }
    1406             :     }
    1407           0 :     insertExtraData(extra);
    1408           0 : }
    1409             : 
    1410         415 : void cppuhelper::ServiceManager::insertLegacyFactory(
    1411             :     css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo)
    1412             : {
    1413             :     assert(factoryInfo.is());
    1414         415 :     rtl::OUString name(factoryInfo->getImplementationName());
    1415             :     css::uno::Reference< css::lang::XSingleComponentFactory > f1(
    1416         830 :         factoryInfo, css::uno::UNO_QUERY);
    1417         830 :     css::uno::Reference< css::lang::XSingleServiceFactory > f2;
    1418         415 :     if (!f1.is()) {
    1419           0 :         f2 = css::uno::Reference< css::lang::XSingleServiceFactory >(
    1420           0 :             factoryInfo, css::uno::UNO_QUERY);
    1421             :     }
    1422             :     css::uno::Reference< css::lang::XComponent > comp(
    1423         830 :         factoryInfo, css::uno::UNO_QUERY);
    1424             :     boost::shared_ptr< Data::Implementation > impl(
    1425         830 :         new Data::Implementation(name, f1, f2, comp));
    1426         830 :     Data extra;
    1427         415 :     if (!name.isEmpty()) {
    1428             :         extra.namedImplementations.insert(
    1429          75 :             Data::NamedImplementations::value_type(name, impl));
    1430             :     }
    1431             :     extra.dynamicImplementations.insert(
    1432         415 :         Data::DynamicImplementations::value_type(factoryInfo, impl));
    1433             :     css::uno::Sequence< rtl::OUString > services(
    1434         830 :         factoryInfo->getSupportedServiceNames());
    1435         830 :     for (sal_Int32 i = 0; i != services.getLength(); ++i) {
    1436         415 :         impl->info->services.push_back(services[i]);
    1437         415 :         extra.services[services[i]].push_back(impl);
    1438             :     }
    1439         415 :     if (insertExtraData(extra) && comp.is()) {
    1440         415 :         comp->addEventListener(this);
    1441         415 :     }
    1442         415 : }
    1443             : 
    1444         415 : bool cppuhelper::ServiceManager::insertExtraData(Data const & extra) {
    1445             :     {
    1446         415 :         osl::MutexGuard g(rBHelper.rMutex);
    1447         415 :         if (isDisposed()) {
    1448           0 :             return false;
    1449             :         }
    1450        1470 :         for (Data::NamedImplementations::const_iterator i(
    1451         415 :                  extra.namedImplementations.begin());
    1452         980 :              i != extra.namedImplementations.end(); ++i)
    1453             :         {
    1454         225 :             if (data_.namedImplementations.find(i->first)
    1455         225 :                 != data_.namedImplementations.end())
    1456             :             {
    1457             :                 throw css::lang::IllegalArgumentException(
    1458           0 :                     "Insert duplicate implementation name " + i->first,
    1459           0 :                     static_cast< cppu::OWeakObject * >(this), 0);
    1460             :             }
    1461             :         }
    1462        2490 :         for (Data::DynamicImplementations::const_iterator i(
    1463         415 :                  extra.dynamicImplementations.begin());
    1464        1660 :              i != extra.dynamicImplementations.end(); ++i)
    1465             :         {
    1466        1245 :             if (data_.dynamicImplementations.find(i->first)
    1467        1245 :                 != data_.dynamicImplementations.end())
    1468             :             {
    1469             :                 throw css::lang::IllegalArgumentException(
    1470             :                     "Insert duplicate factory object",
    1471           0 :                     static_cast< cppu::OWeakObject * >(this), 0);
    1472             :             }
    1473             :         }
    1474             :         //TODO: The below leaves data_ in an inconsistent state upon exceptions:
    1475             :         data_.namedImplementations.insert(
    1476             :             extra.namedImplementations.begin(),
    1477         415 :             extra.namedImplementations.end());
    1478             :         data_.dynamicImplementations.insert(
    1479             :             extra.dynamicImplementations.begin(),
    1480         415 :             extra.dynamicImplementations.end());
    1481         415 :         insertImplementationMap(&data_.services, extra.services);
    1482         415 :         insertImplementationMap(&data_.singletons, extra.singletons);
    1483             :     }
    1484             :     //TODO: Updating the component context singleton data should be part of the
    1485             :     // atomic service manager update:
    1486         415 :     if (!extra.singletons.empty()) {
    1487             :         assert(context_.is());
    1488             :         css::uno::Reference< css::container::XNameContainer > cont(
    1489           0 :             context_, css::uno::UNO_QUERY_THROW);
    1490           0 :         for (Data::ImplementationMap::const_iterator i(
    1491           0 :                  extra.singletons.begin());
    1492           0 :              i != extra.singletons.end(); ++i)
    1493             :         {
    1494           0 :             rtl::OUString name("/singletons/" + i->first);
    1495             :             //TODO: Update should be atomic:
    1496             :             try {
    1497           0 :                 cont->removeByName(name + "/arguments");
    1498           0 :             } catch (const css::container::NoSuchElementException &) {}
    1499             :             assert(!i->second.empty());
    1500             :             assert(i->second[0].get() != 0);
    1501             :             SAL_INFO_IF(
    1502             :                 i->second.size() > 1, "cppuhelper",
    1503             :                 "Arbitrarily chosing " << i->second[0]->info->name
    1504             :                     << " among multiple implementations for singleton "
    1505             :                     << i->first);
    1506             :             try {
    1507           0 :                 cont->insertByName(
    1508           0 :                     name + "/service", css::uno::Any(i->second[0]->info->name));
    1509           0 :             } catch (css::container::ElementExistException &) {
    1510           0 :                 cont->replaceByName(
    1511           0 :                     name + "/service", css::uno::Any(i->second[0]->info->name));
    1512             :             }
    1513             :             try {
    1514           0 :                 cont->insertByName(name, css::uno::Any());
    1515           0 :             } catch (css::container::ElementExistException &) {
    1516             :                 SAL_INFO("cppuhelper", "Overwriting singleton " << i->first);
    1517           0 :                 cont->replaceByName(name, css::uno::Any());
    1518             :             }
    1519           0 :         }
    1520             :     }
    1521         415 :     return true;
    1522             : }
    1523             : 
    1524           0 : void cppuhelper::ServiceManager::removeRdbFiles(
    1525             :     std::vector< rtl::OUString > const & uris)
    1526             : {
    1527             :     // The underlying data structures make this function somewhat inefficient,
    1528             :     // but the assumption is that it is rarely called (and that if it is called,
    1529             :     // it is called with a uris vector of size one):
    1530           0 :     std::vector< boost::shared_ptr< Data::Implementation > > clear;
    1531             :     {
    1532           0 :         osl::MutexGuard g(rBHelper.rMutex);
    1533           0 :         for (std::vector< rtl::OUString >::const_iterator i(uris.begin());
    1534           0 :              i != uris.end(); ++i)
    1535             :         {
    1536           0 :             for (Data::NamedImplementations::iterator j(
    1537           0 :                      data_.namedImplementations.begin());
    1538           0 :                  j != data_.namedImplementations.end();)
    1539             :             {
    1540             :                 assert(j->second.get() != 0);
    1541           0 :                 if (j->second->info->rdbFile == *i) {
    1542           0 :                     clear.push_back(j->second);
    1543             :                     //TODO: The below leaves data_ in an inconsistent state upon
    1544             :                     // exceptions:
    1545             :                     removeFromImplementationMap(
    1546           0 :                         &data_.services, j->second->info->services, j->second);
    1547             :                     removeFromImplementationMap(
    1548           0 :                         &data_.singletons, j->second->info->singletons,
    1549           0 :                         j->second);
    1550           0 :                     data_.namedImplementations.erase(j++);
    1551             :                 } else {
    1552           0 :                     ++j;
    1553             :                 }
    1554             :             }
    1555           0 :         }
    1556           0 :     }
    1557             :     //TODO: Update the component context singleton data
    1558           0 : }
    1559             : 
    1560           6 : bool cppuhelper::ServiceManager::removeLegacyFactory(
    1561             :     css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo,
    1562             :     bool removeListener)
    1563             : {
    1564             :     assert(factoryInfo.is());
    1565           6 :     boost::shared_ptr< Data::Implementation > clear;
    1566          12 :     css::uno::Reference< css::lang::XComponent > comp;
    1567             :     {
    1568           6 :         osl::MutexGuard g(rBHelper.rMutex);
    1569             :         Data::DynamicImplementations::iterator i(
    1570           6 :             data_.dynamicImplementations.find(factoryInfo));
    1571           6 :         if (i == data_.dynamicImplementations.end()) {
    1572           0 :             return isDisposed();
    1573             :         }
    1574             :         assert(i->second.get() != 0);
    1575           6 :         clear = i->second;
    1576           6 :         if (removeListener) {
    1577           0 :             comp = i->second->component;
    1578             :         }
    1579             :         //TODO: The below leaves data_ in an inconsistent state upon exceptions:
    1580             :         removeFromImplementationMap(
    1581           6 :             &data_.services, i->second->info->services, i->second);
    1582             :         removeFromImplementationMap(
    1583           6 :             &data_.singletons, i->second->info->singletons, i->second);
    1584           6 :         if (!i->second->info->name.isEmpty()) {
    1585           6 :             data_.namedImplementations.erase(i->second->info->name);
    1586             :         }
    1587           6 :         data_.dynamicImplementations.erase(i);
    1588             :     }
    1589           6 :     if (comp.is()) {
    1590           0 :         removeEventListenerFromComponent(comp);
    1591             :     }
    1592          12 :     return true;
    1593             : }
    1594             : 
    1595           1 : void cppuhelper::ServiceManager::removeImplementation(rtl::OUString name) {
    1596             :     // The underlying data structures make this function somewhat inefficient,
    1597             :     // but the assumption is that it is rarely called:
    1598           1 :     boost::shared_ptr< Data::Implementation > clear;
    1599             :     {
    1600           1 :         osl::MutexGuard g(rBHelper.rMutex);
    1601           1 :         if (isDisposed()) {
    1602           1 :             return;
    1603             :         }
    1604             :         Data::NamedImplementations::iterator i(
    1605           1 :             data_.namedImplementations.find(name));
    1606           1 :         if (i == data_.namedImplementations.end()) {
    1607             :             throw css::container::NoSuchElementException(
    1608           0 :                 "Remove non-inserted implementation " + name,
    1609           0 :                 static_cast< cppu::OWeakObject * >(this));
    1610             :         }
    1611             :         assert(i->second.get() != 0);
    1612           1 :         clear = i->second;
    1613             :         //TODO: The below leaves data_ in an inconsistent state upon exceptions:
    1614             :         removeFromImplementationMap(
    1615           1 :             &data_.services, i->second->info->services, i->second);
    1616             :         removeFromImplementationMap(
    1617           1 :             &data_.singletons, i->second->info->singletons, i->second);
    1618          21 :         for (Data::DynamicImplementations::iterator j(
    1619           1 :                  data_.dynamicImplementations.begin());
    1620          14 :              j != data_.dynamicImplementations.end(); ++j)
    1621             :         {
    1622           7 :             if (j->second == i->second) {
    1623           1 :                 data_.dynamicImplementations.erase(j);
    1624           1 :                 break;
    1625             :             }
    1626             :         }
    1627           1 :         data_.namedImplementations.erase(i);
    1628           1 :     }
    1629             : }
    1630             : 
    1631             : boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation >
    1632      759321 : cppuhelper::ServiceManager::findServiceImplementation(
    1633             :     css::uno::Reference< css::uno::XComponentContext > const & context,
    1634             :     rtl::OUString const & specifier)
    1635             : {
    1636      759321 :     boost::shared_ptr< Data::Implementation > impl;
    1637             :     bool loaded;
    1638             :     {
    1639      759321 :         osl::MutexGuard g(rBHelper.rMutex);
    1640             :         Data::ImplementationMap::const_iterator i(
    1641      759321 :             data_.services.find(specifier));
    1642      759321 :         if (i == data_.services.end()) {
    1643             :             Data::NamedImplementations::const_iterator j(
    1644       81381 :                 data_.namedImplementations.find(specifier));
    1645       81381 :             if (j == data_.namedImplementations.end()) {
    1646             :                 SAL_INFO("cppuhelper", "No implementation for " << specifier);
    1647       61526 :                 return boost::shared_ptr< Data::Implementation >();
    1648             :             }
    1649       19855 :             impl = j->second;
    1650             :         } else {
    1651             :             assert(!i->second.empty());
    1652             :             SAL_INFO_IF(
    1653             :                 i->second.size() > 1, "cppuhelper",
    1654             :                 "Arbitrarily chosing " << i->second[0]->info->name
    1655             :                     << " among multiple implementations for " << i->first);
    1656      677940 :             impl = i->second[0];
    1657             :         }
    1658             :         assert(impl.get() != 0);
    1659      697795 :         loaded = impl->loaded;
    1660             :     }
    1661             :     //TODO: There is a race here, as the relevant service factory can be removed
    1662             :     // while the mutex is unlocked and loading can thus fail, as the entity from
    1663             :     // which to load can disappear once the service factory is removed.
    1664      697795 :     if (!loaded) {
    1665        8970 :         css::uno::Reference< css::lang::XSingleComponentFactory > f1;
    1666       17940 :         css::uno::Reference< css::lang::XSingleServiceFactory > f2;
    1667        8970 :         loadImplementation(context, impl->info, &f1, &f2);
    1668       17940 :         osl::MutexGuard g(rBHelper.rMutex);
    1669        8970 :         if (!(isDisposed() || impl->loaded)) {
    1670        8970 :             impl->loaded = true;
    1671        8970 :             impl->factory1 = f1;
    1672        8970 :             impl->factory2 = f2;
    1673        8970 :         }
    1674             :     }
    1675      697795 :     return impl;
    1676             : }
    1677             : 
    1678             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10