LCOV - code coverage report
Current view: top level - stoc/source/servicemanager - servicemanager.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 82 570 14.4 %
Date: 2015-06-13 12:38:46 Functions: 26 106 24.5 %
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             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <osl/mutex.hxx>
      21             : #include <osl/diagnose.h>
      22             : #include <rtl/ref.hxx>
      23             : #include <rtl/ustrbuf.hxx>
      24             : 
      25             : #include <uno/mapping.hxx>
      26             : #include <uno/dispatcher.h>
      27             : #include <cppuhelper/queryinterface.hxx>
      28             : #include <cppuhelper/weakref.hxx>
      29             : #include <cppuhelper/component.hxx>
      30             : #include <cppuhelper/implbase1.hxx>
      31             : #include <cppuhelper/implementationentry.hxx>
      32             : #include <cppuhelper/component_context.hxx>
      33             : #include <cppuhelper/bootstrap.hxx>
      34             : #include <cppuhelper/compbase6.hxx>
      35             : #include <cppuhelper/compbase7.hxx>
      36             : #include <cppuhelper/supportsservice.hxx>
      37             : 
      38             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      39             : #include <com/sun/star/lang/XMultiComponentFactory.hpp>
      40             : #include <com/sun/star/lang/XServiceInfo.hpp>
      41             : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
      42             : #include <com/sun/star/lang/XInitialization.hpp>
      43             : #include <com/sun/star/lang/XEventListener.hpp>
      44             : #include <com/sun/star/lang/DisposedException.hpp>
      45             : #include <com/sun/star/beans/XPropertySet.hpp>
      46             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      47             : #include <com/sun/star/registry/XRegistryKey.hpp>
      48             : #include <com/sun/star/registry/XSimpleRegistry.hpp>
      49             : #include <com/sun/star/container/XSet.hpp>
      50             : #include <com/sun/star/container/XElementAccess.hpp>
      51             : #include <com/sun/star/container/XEnumeration.hpp>
      52             : #include <com/sun/star/container/XContentEnumerationAccess.hpp>
      53             : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
      54             : #include <com/sun/star/uno/XUnloadingPreference.hpp>
      55             : 
      56             : #include <unordered_map>
      57             : #include <unordered_set>
      58             : 
      59             : using namespace com::sun::star;
      60             : using namespace css::uno;
      61             : using namespace css::beans;
      62             : using namespace css::registry;
      63             : using namespace css::lang;
      64             : using namespace css::container;
      65             : using namespace cppu;
      66             : using namespace osl;
      67             : using namespace std;
      68             : 
      69             : namespace {
      70             : 
      71           0 : static Sequence< OUString > retrieveAsciiValueList(
      72             :     const Reference< XSimpleRegistry > &xReg, const OUString &keyName )
      73             : {
      74           0 :     Reference< XEnumerationAccess > xAccess( xReg, UNO_QUERY );
      75           0 :     Sequence< OUString > seq;
      76           0 :     if( xAccess.is() )
      77             :     {
      78           0 :         Reference< XEnumeration > xEnum = xAccess->createEnumeration();
      79           0 :         while( xEnum.is() && xEnum->hasMoreElements() )
      80             :         {
      81           0 :             Reference< XSimpleRegistry > xTempReg;
      82           0 :             xEnum->nextElement() >>= xTempReg;
      83           0 :             if( xTempReg.is() )
      84             :             {
      85           0 :                 Sequence< OUString > seq2 = retrieveAsciiValueList( xTempReg, keyName );
      86             : 
      87           0 :                 if( seq2.getLength() )
      88             :                 {
      89           0 :                     sal_Int32 n1Len = seq.getLength();
      90           0 :                     sal_Int32 n2Len = seq2.getLength();
      91             : 
      92           0 :                     seq.realloc( n1Len + n2Len );
      93           0 :                     const OUString *pSource = seq2.getConstArray();
      94           0 :                     OUString *pTarget = seq.getArray();
      95           0 :                     for( int i = 0 ; i < n2Len ; i ++ )
      96             :                     {
      97           0 :                         pTarget[i+n1Len] = pSource[i];
      98             :                     }
      99           0 :                 }
     100             :             }
     101           0 :         }
     102             :     }
     103           0 :     else if( xReg.is () )
     104             :     {
     105             :         try
     106             :         {
     107           0 :             Reference< XRegistryKey > rRootKey = xReg->getRootKey();
     108           0 :             if( rRootKey.is() )
     109             :             {
     110           0 :                 Reference<XRegistryKey > xKey = rRootKey->openKey(keyName);
     111           0 :                 if( xKey.is() )
     112             :                 {
     113           0 :                     seq = xKey->getAsciiListValue();
     114           0 :                 }
     115           0 :             }
     116             :         }
     117           0 :         catch( InvalidRegistryException & )
     118             :         {
     119             :         }
     120           0 :         catch (InvalidValueException &)
     121             :         {
     122             :         }
     123             :     }
     124           0 :     return seq;
     125             : }
     126             : 
     127             : /*****************************************************************************
     128             :     Enumeration by ServiceName
     129             : *****************************************************************************/
     130             : struct hashRef_Impl
     131             : {
     132           0 :     size_t operator()(const Reference<XInterface > & rName) const
     133             :     {
     134             :         // query to XInterface. The cast to XInterface* must be the same for the same object
     135           0 :         Reference<XInterface > x( Reference<XInterface >::query( rName ) );
     136           0 :         return reinterpret_cast<size_t>(x.get());
     137             :     }
     138             : };
     139             : 
     140             : struct equaltoRef_Impl
     141             : {
     142           0 :     bool operator()(const Reference<XInterface > & rName1, const Reference<XInterface > & rName2 ) const
     143           0 :         { return rName1 == rName2; }
     144             : };
     145             : 
     146             : typedef std::unordered_set
     147             : <
     148             :     Reference<XInterface >,
     149             :     hashRef_Impl,
     150             :     equaltoRef_Impl
     151             : > HashSet_Ref;
     152             : 
     153             : 
     154             : class ServiceEnumeration_Impl : public WeakImplHelper1< XEnumeration >
     155             : {
     156             : public:
     157           0 :     ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories )
     158             :         : aFactories( rFactories )
     159           0 :         , nIt( 0 )
     160           0 :         {}
     161           0 :     virtual ~ServiceEnumeration_Impl() {}
     162             : 
     163             :     // XEnumeration
     164             :     sal_Bool SAL_CALL hasMoreElements()
     165             :         throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     166             :     Any SAL_CALL nextElement()
     167             :         throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     168             : private:
     169             :     Mutex                               aMutex;
     170             :     Sequence< Reference<XInterface > >  aFactories;
     171             :     sal_Int32                           nIt;
     172             : };
     173             : 
     174             : // XEnumeration
     175           0 : sal_Bool ServiceEnumeration_Impl::hasMoreElements() throw(css::uno::RuntimeException, std::exception)
     176             : {
     177           0 :     MutexGuard aGuard( aMutex );
     178           0 :     return nIt != aFactories.getLength();
     179             : }
     180             : 
     181             : // XEnumeration
     182           0 : Any ServiceEnumeration_Impl::nextElement()
     183             :     throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
     184             : {
     185           0 :     MutexGuard aGuard( aMutex );
     186           0 :     if( nIt == aFactories.getLength() )
     187           0 :         throw NoSuchElementException();
     188             : 
     189           0 :     return Any( &aFactories.getConstArray()[nIt++], cppu::UnoType<XInterface>::get());
     190             : }
     191             : 
     192             : 
     193           0 : class PropertySetInfo_Impl : public WeakImplHelper1< beans::XPropertySetInfo >
     194             : {
     195             :     Sequence< beans::Property > m_properties;
     196             : 
     197             : public:
     198           0 :     inline PropertySetInfo_Impl( Sequence< beans::Property > const & properties )
     199           0 :         : m_properties( properties )
     200           0 :         {}
     201             : 
     202             :     // XPropertySetInfo impl
     203             :     virtual Sequence< beans::Property > SAL_CALL getProperties()
     204             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     205             :     virtual beans::Property SAL_CALL getPropertyByName( OUString const & name )
     206             :         throw (beans::UnknownPropertyException, RuntimeException, std::exception) SAL_OVERRIDE;
     207             :     virtual sal_Bool SAL_CALL hasPropertyByName( OUString const & name )
     208             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     209             : };
     210             : 
     211           0 : Sequence< beans::Property > PropertySetInfo_Impl::getProperties()
     212             :     throw (RuntimeException, std::exception)
     213             : {
     214           0 :     return m_properties;
     215             : }
     216             : 
     217           0 : beans::Property PropertySetInfo_Impl::getPropertyByName( OUString const & name )
     218             :     throw (beans::UnknownPropertyException, RuntimeException, std::exception)
     219             : {
     220           0 :     beans::Property const * p = m_properties.getConstArray();
     221           0 :     for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
     222             :     {
     223           0 :         if (p[ nPos ].Name.equals( name ))
     224           0 :             return p[ nPos ];
     225             :     }
     226             :     throw beans::UnknownPropertyException(
     227           0 :         "unknown property: " + name );
     228             : }
     229             : 
     230           0 : sal_Bool PropertySetInfo_Impl::hasPropertyByName( OUString const & name )
     231             :     throw (RuntimeException, std::exception)
     232             : {
     233           0 :     beans::Property const * p = m_properties.getConstArray();
     234           0 :     for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
     235             :     {
     236           0 :         if (p[ nPos ].Name.equals( name ))
     237           0 :             return sal_True;
     238             :     }
     239           0 :     return sal_False;
     240             : }
     241             : 
     242             : 
     243             : /*****************************************************************************
     244             :     Enumeration by implementation
     245             : *****************************************************************************/
     246             : class ImplementationEnumeration_Impl : public WeakImplHelper1< XEnumeration >
     247             : {
     248             : public:
     249           0 :     ImplementationEnumeration_Impl( const HashSet_Ref & rImplementationMap )
     250             :         : aImplementationMap( rImplementationMap )
     251           0 :         , aIt( aImplementationMap.begin() )
     252           0 :         {}
     253             :     virtual ~ImplementationEnumeration_Impl();
     254             : 
     255             :     // XEnumeration
     256             :     virtual sal_Bool SAL_CALL hasMoreElements()
     257             :          throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     258             :     virtual Any SAL_CALL nextElement()
     259             :         throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     260             : 
     261             : private:
     262             :     Mutex                           aMutex;
     263             :     HashSet_Ref                     aImplementationMap;
     264             :     HashSet_Ref::iterator           aIt;
     265             :     Reference<XInterface >          xNext;
     266             : };
     267             : 
     268           0 : ImplementationEnumeration_Impl::~ImplementationEnumeration_Impl() {}
     269             : 
     270             : // XEnumeration
     271           0 : sal_Bool ImplementationEnumeration_Impl::hasMoreElements()
     272             :     throw(css::uno::RuntimeException, std::exception)
     273             : {
     274           0 :     MutexGuard aGuard( aMutex );
     275           0 :     return aIt != aImplementationMap.end();
     276             : }
     277             : 
     278             : // XEnumeration
     279           0 : Any ImplementationEnumeration_Impl::nextElement()
     280             :     throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
     281             : {
     282           0 :     MutexGuard aGuard( aMutex );
     283           0 :     if( aIt == aImplementationMap.end() )
     284           0 :         throw NoSuchElementException();
     285             : 
     286           0 :     Any ret( &(*aIt), cppu::UnoType<XInterface>::get());
     287           0 :     ++aIt;
     288           0 :     return ret;
     289             : }
     290             : 
     291             : /*****************************************************************************
     292             :     Hash tables
     293             : *****************************************************************************/
     294             : typedef std::unordered_set
     295             : <
     296             :     OUString,
     297             :     OUStringHash
     298             : > HashSet_OWString;
     299             : 
     300             : typedef std::unordered_multimap
     301             : <
     302             :     OUString,
     303             :     Reference<XInterface >,
     304             :     OUStringHash
     305             : > HashMultimap_OWString_Interface;
     306             : 
     307             : typedef std::unordered_map
     308             : <
     309             :     OUString,
     310             :     Reference<XInterface >,
     311             :     OUStringHash
     312             : > HashMap_OWString_Interface;
     313             : 
     314             : /*****************************************************************************
     315             :     class OServiceManager_Listener
     316             : *****************************************************************************/
     317           0 : class OServiceManager_Listener : public WeakImplHelper1< XEventListener >
     318             : {
     319             : private:
     320             :     WeakReference<XSet > xSMgr;
     321             : 
     322             : public:
     323           0 :     OServiceManager_Listener( const Reference<XSet > & rSMgr )
     324           0 :         : xSMgr( rSMgr )
     325           0 :         {}
     326             : 
     327             :     // XEventListener
     328             :     virtual void SAL_CALL disposing(const EventObject & rEvt ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     329             : };
     330             : 
     331           0 : void OServiceManager_Listener::disposing(const EventObject & rEvt )
     332             :     throw(css::uno::RuntimeException, std::exception)
     333             : {
     334           0 :     Reference<XSet > x( xSMgr );
     335           0 :     if( x.is() )
     336             :     {
     337             :         try
     338             :         {
     339           0 :             x->remove( Any( &rEvt.Source, cppu::UnoType<XInterface>::get()) );
     340             :         }
     341           0 :         catch( const IllegalArgumentException & )
     342             :         {
     343             :             OSL_FAIL( "IllegalArgumentException caught" );
     344             :         }
     345           0 :         catch( const NoSuchElementException & )
     346             :         {
     347             :             OSL_FAIL( "NoSuchElementException caught" );
     348             :         }
     349           0 :     }
     350           0 : }
     351             : 
     352             : 
     353             : /*****************************************************************************
     354             :     class OServiceManager
     355             : *****************************************************************************/
     356          45 : struct OServiceManagerMutex
     357             : {
     358             :     Mutex m_mutex;
     359             : };
     360             : 
     361             : typedef WeakComponentImplHelper7<
     362             :     lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
     363             :     lang::XInitialization,
     364             :     container::XSet, container::XContentEnumerationAccess,
     365             :     beans::XPropertySet > t_OServiceManager_impl;
     366             : 
     367             : class OServiceManager
     368             :     : public OServiceManagerMutex
     369             :     , public t_OServiceManager_impl
     370             : {
     371             : public:
     372             :     OServiceManager( Reference< XComponentContext > const & xContext );
     373             :     virtual ~OServiceManager();
     374             : 
     375             :     // XInitialization
     376             :     void SAL_CALL initialize( Sequence< Any > const & args )
     377             :         throw (Exception, std::exception) SAL_OVERRIDE;
     378             : 
     379             :     // XServiceInfo
     380             :     virtual OUString SAL_CALL getImplementationName() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     381             :     virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     382             :     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     383             : 
     384             :     // XMultiComponentFactory
     385             :     virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
     386             :         OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext )
     387             :         throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
     388             :     virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
     389             :         OUString const & rServiceSpecifier,
     390             :         Sequence< Any > const & rArguments,
     391             :         Reference< XComponentContext > const & xContext )
     392             :         throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
     393             : //      virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
     394             : //          throw (RuntimeException);
     395             : 
     396             :     // XMultiServiceFactory
     397             :     virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     398             :     virtual Reference<XInterface > SAL_CALL createInstance(const OUString &) throw(css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     399             :     virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString &, const Sequence<Any >& Arguments) throw(css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     400             : 
     401             :     // The same as the getAvailableServiceNames, but only uique names
     402             :     Sequence< OUString > getUniqueAvailableServiceNames(
     403             :         HashSet_OWString & aNameSet );
     404             : 
     405             :     // XElementAccess
     406             :     virtual Type SAL_CALL getElementType() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     407             :     virtual sal_Bool SAL_CALL hasElements() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     408             : 
     409             :     // XEnumerationAccess
     410             :     virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     411             : 
     412             :     // XSet
     413             :     virtual sal_Bool SAL_CALL has( const Any & Element ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     414             :     virtual void SAL_CALL insert( const Any & Element ) throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     415             :     virtual void SAL_CALL remove( const Any & Element ) throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     416             : 
     417             :     // XContentEnumerationAccess
     418             :     //Sequence< OUString >          getAvailableServiceNames() throw( (Exception) );
     419             :     virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     420             : 
     421             :     // XComponent
     422             :     virtual void SAL_CALL dispose() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     423             : 
     424             :     // XPropertySet
     425             :     Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
     426             :         throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     427             :     void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue)
     428             :         throw(css::beans::UnknownPropertyException, css::beans::PropertyVetoException, css::lang::IllegalArgumentException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     429             :     Any SAL_CALL getPropertyValue(const OUString& PropertyName)
     430             :         throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     431             :     void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
     432             :         throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     433             :     void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
     434             :         throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     435             :     void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
     436             :         throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     437             :     void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
     438             :         throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     439             : 
     440             : protected:
     441             :     inline bool is_disposed() const;
     442             :     inline void check_undisposed() const;
     443             :     virtual void SAL_CALL disposing() SAL_OVERRIDE;
     444             : 
     445             :     bool haveFactoryWithThisImplementation(const OUString& aImplName);
     446             : 
     447             :     virtual Sequence< Reference< XInterface > > queryServiceFactories(
     448             :         const OUString& aServiceName, Reference< XComponentContext > const & xContext );
     449             : 
     450             :     Reference< XComponentContext >  m_xContext;
     451             : 
     452             :     Reference< beans::XPropertySetInfo > m_xPropertyInfo;
     453             : 
     454             :     // factories which have been loaded and not inserted( by XSet::insert)
     455             :     // are remembered by this set.
     456             :     HashSet_Ref m_SetLoadedFactories;
     457             : private:
     458             : 
     459             :     Reference<XEventListener >      getFactoryListener();
     460             : 
     461             : 
     462             :     HashMultimap_OWString_Interface m_ServiceMap;
     463             :     HashSet_Ref                     m_ImplementationMap;
     464             :     HashMap_OWString_Interface      m_ImplementationNameMap;
     465             :     Reference<XEventListener >      xFactoryListener;
     466             :     bool                            m_bInDisposing;
     467             : };
     468             : 
     469             : 
     470             : 
     471           0 : inline bool OServiceManager::is_disposed() const
     472             : {
     473             :     // ought to be guarded by m_mutex:
     474           0 :     return (m_bInDisposing || rBHelper.bDisposed);
     475             : }
     476             : 
     477             : 
     478           0 : inline void OServiceManager::check_undisposed() const
     479             : {
     480           0 :     if (is_disposed())
     481             :     {
     482             :         throw lang::DisposedException(
     483             :             "service manager instance has already been disposed!",
     484           0 :             static_cast<OWeakObject *>(const_cast<OServiceManager *>(this)) );
     485             :     }
     486           0 : }
     487             : 
     488             : 
     489             : 
     490             : 
     491             : 
     492             : typedef WeakComponentImplHelper6<
     493             :     lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
     494             :     container::XSet, container::XContentEnumerationAccess,
     495             :     beans::XPropertySet > t_OServiceManagerWrapper_impl;
     496             : 
     497             : class OServiceManagerWrapper : public OServiceManagerMutex, public t_OServiceManagerWrapper_impl
     498             : {
     499             :     Reference< XComponentContext > m_xContext;
     500             :     Reference< XMultiComponentFactory > m_root;
     501         413 :     inline Reference< XMultiComponentFactory > getRoot()
     502             :     {
     503         413 :         if (! m_root.is())
     504             :         {
     505             :             throw lang::DisposedException(
     506           0 :                 "service manager instance has already been disposed!" );
     507             :         }
     508         413 :         return m_root;
     509             :     }
     510             : 
     511             : protected:
     512             :     virtual void SAL_CALL disposing() SAL_OVERRIDE;
     513             : 
     514             : public:
     515             :     OServiceManagerWrapper(
     516             :         Reference< XComponentContext > const & xContext );
     517             :     virtual ~OServiceManagerWrapper();
     518             : 
     519             :     // XServiceInfo
     520           0 :     virtual OUString SAL_CALL getImplementationName() throw (RuntimeException, std::exception) SAL_OVERRIDE
     521           0 :         { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getImplementationName(); }
     522           0 :     virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (RuntimeException, std::exception) SAL_OVERRIDE
     523           0 :         { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->supportsService( ServiceName ); }
     524           0 :     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException, std::exception) SAL_OVERRIDE
     525           0 :         { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getSupportedServiceNames(); }
     526             : 
     527             :     // XMultiComponentFactory
     528         255 :     virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
     529             :         OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext )
     530             :         throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE
     531         255 :         { return getRoot()->createInstanceWithContext( rServiceSpecifier, xContext ); }
     532         158 :     virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
     533             :         OUString const & rServiceSpecifier,
     534             :         Sequence< Any > const & rArguments,
     535             :         Reference< XComponentContext > const & xContext )
     536             :         throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE
     537         158 :         { return getRoot()->createInstanceWithArgumentsAndContext( rServiceSpecifier, rArguments, xContext ); }
     538             : //      virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
     539             : //          throw (RuntimeException);
     540             : 
     541             :     // XMultiServiceFactory
     542           0 :     virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw (RuntimeException, std::exception) SAL_OVERRIDE
     543           0 :         { return getRoot()->getAvailableServiceNames(); }
     544           0 :     virtual Reference<XInterface > SAL_CALL createInstance(const OUString & name) throw (Exception, std::exception) SAL_OVERRIDE
     545           0 :         { return getRoot()->createInstanceWithContext( name, m_xContext ); }
     546           0 :     virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString & name, const Sequence<Any >& Arguments) throw (Exception, std::exception) SAL_OVERRIDE
     547           0 :         { return getRoot()->createInstanceWithArgumentsAndContext( name, Arguments, m_xContext ); }
     548             : 
     549             :     // XElementAccess
     550           0 :     virtual Type SAL_CALL getElementType() throw (RuntimeException, std::exception) SAL_OVERRIDE
     551           0 :         { return Reference< XElementAccess >(getRoot(), UNO_QUERY_THROW)->getElementType(); }
     552           0 :     virtual sal_Bool SAL_CALL hasElements() throw (RuntimeException, std::exception) SAL_OVERRIDE
     553           0 :         { return Reference< XElementAccess >(getRoot(), UNO_QUERY_THROW)->hasElements(); }
     554             : 
     555             :     // XEnumerationAccess
     556           0 :     virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw (RuntimeException, std::exception) SAL_OVERRIDE
     557           0 :         { return Reference< XEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createEnumeration(); }
     558             : 
     559             :     // XSet
     560           0 :     virtual sal_Bool SAL_CALL has( const Any & Element ) throw (RuntimeException, std::exception) SAL_OVERRIDE
     561           0 :         { return Reference< XSet >(getRoot(), UNO_QUERY_THROW)->has( Element ); }
     562           0 :     virtual void SAL_CALL insert( const Any & Element ) throw (lang::IllegalArgumentException, container::ElementExistException, RuntimeException, std::exception) SAL_OVERRIDE
     563           0 :         { Reference< XSet >(getRoot(), UNO_QUERY_THROW)->insert( Element ); }
     564           0 :     virtual void SAL_CALL remove( const Any & Element ) throw (lang::IllegalArgumentException, container::NoSuchElementException, RuntimeException, std::exception) SAL_OVERRIDE
     565           0 :         { Reference< XSet >(getRoot(), UNO_QUERY_THROW)->remove( Element ); }
     566             : 
     567             :     // XContentEnumerationAccess
     568             :     //Sequence< OUString >          getAvailableServiceNames() throw( (Exception) );
     569           0 :     virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw (RuntimeException, std::exception) SAL_OVERRIDE
     570           0 :         { return Reference< XContentEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createContentEnumeration( aServiceName ); }
     571             : 
     572             :     // XPropertySet
     573           0 :     Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() throw (RuntimeException, std::exception) SAL_OVERRIDE
     574           0 :         { return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertySetInfo(); }
     575             : 
     576             :     void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue)
     577             :         throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException, std::exception) SAL_OVERRIDE;
     578             :     Any SAL_CALL getPropertyValue(const OUString& PropertyName)
     579             :         throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException, std::exception) SAL_OVERRIDE;
     580             : 
     581           0 :     void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
     582             :         throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException, std::exception) SAL_OVERRIDE
     583           0 :         { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->addPropertyChangeListener( PropertyName, aListener ); }
     584           0 :     void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
     585             :         throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException, std::exception) SAL_OVERRIDE
     586           0 :         { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->removePropertyChangeListener( PropertyName, aListener ); }
     587           0 :     void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
     588             :         throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException, std::exception) SAL_OVERRIDE
     589           0 :         { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->addVetoableChangeListener( PropertyName, aListener ); }
     590           0 :     void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
     591             :         throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException, std::exception) SAL_OVERRIDE
     592           0 :         { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->removeVetoableChangeListener( PropertyName, aListener ); }
     593             : };
     594             : 
     595          35 : void SAL_CALL OServiceManagerWrapper::setPropertyValue(
     596             :     const OUString& PropertyName, const Any& aValue )
     597             :     throw (beans::UnknownPropertyException, beans::PropertyVetoException,
     598             :            lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException, std::exception)
     599             : {
     600          35 :     if ( PropertyName == "DefaultContext" )
     601             :     {
     602          35 :         Reference< XComponentContext > xContext;
     603          35 :         if (aValue >>= xContext)
     604             :         {
     605          35 :             MutexGuard aGuard( m_mutex );
     606          35 :             m_xContext = xContext;
     607             :         }
     608             :         else
     609             :         {
     610             :             throw IllegalArgumentException(
     611             :                 "no XComponentContext given!",
     612           0 :                 static_cast<OWeakObject *>(this), 1 );
     613          35 :         }
     614             :     }
     615             :     else
     616             :     {
     617           0 :         Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->setPropertyValue( PropertyName, aValue );
     618             :     }
     619          35 : }
     620             : 
     621           0 : Any SAL_CALL OServiceManagerWrapper::getPropertyValue(
     622             :     const OUString& PropertyName )
     623             :     throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException, std::exception)
     624             : {
     625           0 :     if ( PropertyName == "DefaultContext" )
     626             :     {
     627           0 :         MutexGuard aGuard( m_mutex );
     628           0 :         if( m_xContext.is() )
     629           0 :             return makeAny( m_xContext );
     630             :         else
     631           0 :             return Any();
     632             :     }
     633             :     else
     634             :     {
     635           0 :         return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertyValue( PropertyName );
     636             :     }
     637             : }
     638             : 
     639           6 : void OServiceManagerWrapper::disposing()
     640             : {
     641           6 :     m_xContext.clear();
     642             : 
     643             : // no m_root->dispose(), because every context disposes its service manager...
     644           6 :     m_root.clear();
     645           6 : }
     646             : 
     647          12 : OServiceManagerWrapper::~OServiceManagerWrapper() {}
     648             : 
     649          35 : OServiceManagerWrapper::OServiceManagerWrapper(
     650             :     Reference< XComponentContext > const & xContext )
     651             :     : t_OServiceManagerWrapper_impl( m_mutex )
     652             :     , m_xContext( xContext )
     653          35 :     , m_root( xContext->getServiceManager() )
     654             : {
     655          35 :     if (! m_root.is())
     656             :     {
     657             :         throw RuntimeException(
     658           0 :             "no service manager to wrap" );
     659             :     }
     660          35 : }
     661             : 
     662             : 
     663             : 
     664             : 
     665             : 
     666             : /**
     667             :  * Create a ServiceManager
     668             :  */
     669           2 : OServiceManager::OServiceManager( Reference< XComponentContext > const & xContext )
     670             :     : t_OServiceManager_impl( m_mutex )
     671             :     , m_xContext( xContext )
     672           2 :     , m_bInDisposing( false )
     673           2 : {}
     674             : 
     675             : /**
     676             :  * Destroy the ServiceManager
     677             :  */
     678           3 : OServiceManager::~OServiceManager() {}
     679             : 
     680             : // XComponent
     681           2 : void OServiceManager::dispose()
     682             :     throw(css::uno::RuntimeException, std::exception)
     683             : {
     684           2 :     if (rBHelper.bDisposed || rBHelper.bInDispose)
     685           2 :         return;
     686           2 :     t_OServiceManager_impl::dispose();
     687             : }
     688             : 
     689           2 : void OServiceManager::disposing()
     690             : {
     691             :     // dispose all factories
     692           2 :     HashSet_Ref aImpls;
     693             :     {
     694           2 :         MutexGuard aGuard( m_mutex );
     695           2 :         m_bInDisposing = true;
     696           2 :         aImpls = m_ImplementationMap;
     697             :     }
     698           2 :     HashSet_Ref::iterator aIt = aImpls.begin();
     699           4 :     while( aIt != aImpls.end() )
     700             :     {
     701             :         try
     702             :         {
     703           0 :             Reference<XComponent > xComp( Reference<XComponent >::query( *aIt++ ) );
     704           0 :             if( xComp.is() )
     705           0 :                 xComp->dispose();
     706             :         }
     707           0 :         catch (const RuntimeException & exc)
     708             :         {
     709             : #if OSL_DEBUG_LEVEL > 1
     710             :             OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
     711             :             OSL_TRACE( "### RuntimeException occurred upon disposing factory: %s", str.getStr() );
     712             : #else
     713             :             (void) exc; // unused
     714             : #endif
     715             :         }
     716             :     }
     717             : 
     718             :     // dispose
     719           4 :     HashSet_Ref aImplMap;
     720             :     {
     721           2 :         MutexGuard aGuard( m_mutex );
     722             :         // erase all members
     723           2 :         m_ServiceMap = HashMultimap_OWString_Interface();
     724           2 :         aImplMap = m_ImplementationMap;
     725           2 :         m_ImplementationMap = HashSet_Ref();
     726           2 :         m_ImplementationNameMap = HashMap_OWString_Interface();
     727           2 :         m_SetLoadedFactories= HashSet_Ref();
     728             :     }
     729             : 
     730           2 :     m_xContext.clear();
     731             : 
     732             :     // not only the Event should hold the object
     733           2 :     OSL_ASSERT( m_refCount != 1 );
     734           2 : }
     735             : 
     736             : // XPropertySet
     737           0 : Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo()
     738             :     throw(css::uno::RuntimeException, std::exception)
     739             : {
     740           0 :     check_undisposed();
     741           0 :     if (! m_xPropertyInfo.is())
     742             :     {
     743           0 :         Sequence< beans::Property > seq( 1 );
     744           0 :         seq[ 0 ] = beans::Property(
     745           0 :             "DefaultContext", -1, cppu::UnoType<decltype(m_xContext)>::get(), 0 );
     746           0 :         Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
     747             : 
     748           0 :         MutexGuard aGuard( m_mutex );
     749           0 :         if (! m_xPropertyInfo.is())
     750             :         {
     751           0 :             m_xPropertyInfo = xInfo;
     752           0 :         }
     753             :     }
     754           0 :     return m_xPropertyInfo;
     755             : }
     756             : 
     757           0 : void OServiceManager::setPropertyValue(
     758             :     const OUString& PropertyName, const Any& aValue )
     759             :     throw(css::beans::UnknownPropertyException, css::beans::PropertyVetoException, css::lang::IllegalArgumentException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
     760             : {
     761           0 :     check_undisposed();
     762           0 :     if ( PropertyName == "DefaultContext" )
     763             :     {
     764           0 :         Reference< XComponentContext > xContext;
     765           0 :         if (aValue >>= xContext)
     766             :         {
     767           0 :             MutexGuard aGuard( m_mutex );
     768           0 :             m_xContext = xContext;
     769             :         }
     770             :         else
     771             :         {
     772             :             throw IllegalArgumentException(
     773             :                 "no XComponentContext given!",
     774           0 :                 static_cast<OWeakObject *>(this), 1 );
     775           0 :         }
     776             :     }
     777             :     else
     778             :     {
     779             :         throw UnknownPropertyException(
     780           0 :             "unknown property " + PropertyName,
     781           0 :             static_cast<OWeakObject *>(this) );
     782             :     }
     783           0 : }
     784             : 
     785           0 : Any OServiceManager::getPropertyValue(const OUString& PropertyName)
     786             :     throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
     787             : {
     788           0 :     check_undisposed();
     789           0 :     if ( PropertyName == "DefaultContext" )
     790             :     {
     791           0 :         MutexGuard aGuard( m_mutex );
     792           0 :         if( m_xContext.is() )
     793           0 :             return makeAny( m_xContext );
     794             :         else
     795           0 :             return Any();
     796             :     }
     797             :     else
     798             :     {
     799           0 :         UnknownPropertyException except;
     800           0 :         except.Message =  "ServiceManager : unknown property " + PropertyName;
     801           0 :         throw except;
     802             :     }
     803             : }
     804             : 
     805           0 : void OServiceManager::addPropertyChangeListener(
     806             :     const OUString&, const Reference<XPropertyChangeListener >&)
     807             :     throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
     808             : {
     809           0 :     check_undisposed();
     810           0 :     throw UnknownPropertyException();
     811             : }
     812             : 
     813           0 : void OServiceManager::removePropertyChangeListener(
     814             :     const OUString&, const Reference<XPropertyChangeListener >&)
     815             :     throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
     816             : {
     817           0 :     check_undisposed();
     818           0 :     throw UnknownPropertyException();
     819             : }
     820             : 
     821           0 : void OServiceManager::addVetoableChangeListener(
     822             :     const OUString&, const Reference<XVetoableChangeListener >&)
     823             :     throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
     824             : {
     825           0 :     check_undisposed();
     826           0 :     throw UnknownPropertyException();
     827             : }
     828             : 
     829           0 : void OServiceManager::removeVetoableChangeListener(
     830             :     const OUString&, const Reference<XVetoableChangeListener >&)
     831             :     throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
     832             : {
     833           0 :     check_undisposed();
     834           0 :     throw UnknownPropertyException();
     835             : }
     836             : 
     837             : // OServiceManager
     838           0 : Reference<XEventListener > OServiceManager::getFactoryListener()
     839             : {
     840           0 :     check_undisposed();
     841           0 :     MutexGuard aGuard( m_mutex );
     842           0 :     if( !xFactoryListener.is() )
     843           0 :         xFactoryListener = new OServiceManager_Listener( this );
     844           0 :     return xFactoryListener;
     845             : }
     846             : 
     847             : // XMultiServiceFactory, XContentEnumeration
     848           0 : Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames(
     849             :     HashSet_OWString & aNameSet )
     850             : {
     851           0 :     check_undisposed();
     852           0 :     MutexGuard aGuard( m_mutex );
     853           0 :     HashMultimap_OWString_Interface::iterator aSIt = m_ServiceMap.begin();
     854           0 :     while( aSIt != m_ServiceMap.end() )
     855           0 :         aNameSet.insert( (*aSIt++).first );
     856             : 
     857             :     /* do not return the implementation names
     858             :     HashMap_OWString_Interface      m_ImplementationNameMap;
     859             :     HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.begin();
     860             :     while( aIt != m_ImplementationNameMap.end() )
     861             :         aNameSet.insert( (*aIt++).first );
     862             :     */
     863             : 
     864           0 :     Sequence< OUString > aNames( aNameSet.size() );
     865           0 :     OUString * pArray = aNames.getArray();
     866           0 :     sal_Int32 i = 0;
     867           0 :     HashSet_OWString::iterator next = aNameSet.begin();
     868           0 :     while( next != aNameSet.end() )
     869           0 :         pArray[i++] = (*next++);
     870             : 
     871           0 :     return aNames;
     872             : }
     873             : 
     874             : // XMultiComponentFactory
     875           0 : Reference< XInterface > OServiceManager::createInstanceWithContext(
     876             :     OUString const & rServiceSpecifier,
     877             :     Reference< XComponentContext > const & xContext )
     878             :     throw (Exception, RuntimeException, std::exception)
     879             : {
     880           0 :     check_undisposed();
     881             : #if OSL_DEBUG_LEVEL > 0
     882             :     Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
     883             :     OSL_ASSERT( xProps.is() );
     884             :     if (xProps.is())
     885             :     {
     886             :         Reference< XComponentContext > xDefContext;
     887             :         xProps->getPropertyValue(
     888             :             OUString("DefaultContext") ) >>= xDefContext;
     889             :         OSL_ENSURE(
     890             :             xContext == xDefContext,
     891             :             "### default context of service manager singleton differs from context holding it!" );
     892             :     }
     893             : #endif
     894             : 
     895             :     Sequence< Reference< XInterface > > factories(
     896           0 :         queryServiceFactories( rServiceSpecifier, xContext ) );
     897           0 :     Reference< XInterface > const * p = factories.getConstArray();
     898           0 :     for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos )
     899             :     {
     900             :         try
     901             :         {
     902           0 :             Reference< XInterface > const & xFactory = p[ nPos ];
     903           0 :             if (xFactory.is())
     904             :             {
     905           0 :                 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
     906           0 :                 if (xFac.is())
     907             :                 {
     908           0 :                     return xFac->createInstanceWithContext( xContext );
     909             :                 }
     910             :                 else
     911             :                 {
     912           0 :                     Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
     913           0 :                     if (xFac2.is())
     914             :                     {
     915             : #if OSL_DEBUG_LEVEL > 1
     916             :                         OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) );
     917             :                         OSL_TRACE( "### ignoring given context raising service %s !!!", aStr.getStr() );
     918             : #endif
     919           0 :                         return xFac2->createInstance();
     920           0 :                     }
     921           0 :                 }
     922             :             }
     923             :         }
     924           0 :         catch (const lang::DisposedException & exc)
     925             :         {
     926             : #if OSL_DEBUG_LEVEL > 1
     927             :             OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
     928             :             OSL_TRACE( "### DisposedException occurred: %s", str.getStr() );
     929             : #else
     930             :             (void) exc; // unused
     931             : #endif
     932             :         }
     933             :     }
     934             : 
     935           0 :     return Reference< XInterface >();
     936             : }
     937             : // XMultiComponentFactory
     938           0 : Reference< XInterface > OServiceManager::createInstanceWithArgumentsAndContext(
     939             :     OUString const & rServiceSpecifier,
     940             :     Sequence< Any > const & rArguments,
     941             :     Reference< XComponentContext > const & xContext )
     942             :     throw (Exception, RuntimeException, std::exception)
     943             : {
     944           0 :     check_undisposed();
     945             : #if OSL_DEBUG_LEVEL > 0
     946             :     Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
     947             :     OSL_ASSERT( xProps.is() );
     948             :     if (xProps.is())
     949             :     {
     950             :         Reference< XComponentContext > xDefContext;
     951             :         xProps->getPropertyValue(
     952             :             OUString("DefaultContext") ) >>= xDefContext;
     953             :         OSL_ENSURE(
     954             :             xContext == xDefContext,
     955             :             "### default context of service manager singleton differs from context holding it!" );
     956             :     }
     957             : #endif
     958             : 
     959             :     Sequence< Reference< XInterface > > factories(
     960           0 :         queryServiceFactories( rServiceSpecifier, xContext ) );
     961           0 :     Reference< XInterface > const * p = factories.getConstArray();
     962           0 :     for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos )
     963             :     {
     964             :         try
     965             :         {
     966           0 :             Reference< XInterface > const & xFactory = p[ nPos ];
     967           0 :             if (xFactory.is())
     968             :             {
     969           0 :                 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
     970           0 :                 if (xFac.is())
     971             :                 {
     972           0 :                     return xFac->createInstanceWithArgumentsAndContext( rArguments, xContext );
     973             :                 }
     974             :                 else
     975             :                 {
     976           0 :                     Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
     977           0 :                     if (xFac2.is())
     978             :                     {
     979             : #if OSL_DEBUG_LEVEL > 1
     980             :                         OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) );
     981             :                         OSL_TRACE( "### ignoring given context raising service %s !!!", aStr.getStr() );
     982             : #endif
     983           0 :                         return xFac2->createInstanceWithArguments( rArguments );
     984           0 :                     }
     985           0 :                 }
     986             :             }
     987             :         }
     988           0 :         catch (const lang::DisposedException & exc)
     989             :         {
     990             : #if OSL_DEBUG_LEVEL > 1
     991             :             OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
     992             :             OSL_TRACE( "### DisposedException occurred: %s", str.getStr() );
     993             : #else
     994             :             (void) exc; // unused
     995             : #endif
     996             :         }
     997             :     }
     998             : 
     999           0 :     return Reference< XInterface >();
    1000             : }
    1001             : 
    1002             : // XMultiServiceFactory, XMultiComponentFactory, XContentEnumeration
    1003           0 : Sequence< OUString > OServiceManager::getAvailableServiceNames()
    1004             :     throw(css::uno::RuntimeException, std::exception)
    1005             : {
    1006           0 :     check_undisposed();
    1007             :     // all names
    1008           0 :     HashSet_OWString aNameSet;
    1009           0 :     return getUniqueAvailableServiceNames( aNameSet );
    1010             : }
    1011             : 
    1012             : // XMultibleServiceFactory
    1013           0 : Reference<XInterface > OServiceManager::createInstance(
    1014             :     const OUString& rServiceSpecifier )
    1015             :     throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
    1016             : {
    1017             :     return createInstanceWithContext(
    1018           0 :         rServiceSpecifier, m_xContext );
    1019             : }
    1020             : 
    1021             : // XMultibleServiceFactory
    1022           0 : Reference<XInterface > OServiceManager::createInstanceWithArguments(
    1023             :     const OUString& rServiceSpecifier,
    1024             :     const Sequence<Any >& rArguments )
    1025             :     throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
    1026             : {
    1027             :     return createInstanceWithArgumentsAndContext(
    1028           0 :         rServiceSpecifier, rArguments, m_xContext );
    1029             : }
    1030             : 
    1031             : // XInitialization
    1032           0 : void OServiceManager::initialize( Sequence< Any > const & )
    1033             :     throw (Exception, std::exception)
    1034             : {
    1035           0 :     check_undisposed();
    1036             :     OSL_FAIL( "not impl!" );
    1037           0 : }
    1038             : 
    1039             : // XServiceInfo
    1040           1 : OUString OServiceManager::getImplementationName()
    1041             :     throw(css::uno::RuntimeException, std::exception)
    1042             : {
    1043           1 :     return OUString("com.sun.star.comp.stoc.OServiceManager");
    1044             : }
    1045             : 
    1046             : // XServiceInfo
    1047           0 : sal_Bool OServiceManager::supportsService(const OUString& ServiceName)
    1048             :     throw(css::uno::RuntimeException, std::exception)
    1049             : {
    1050           0 :     return cppu::supportsService(this, ServiceName);
    1051             : }
    1052             : 
    1053             : // XServiceInfo
    1054           1 : Sequence< OUString > OServiceManager::getSupportedServiceNames()
    1055             :     throw(css::uno::RuntimeException, std::exception)
    1056             : {
    1057           1 :     Sequence< OUString > seqNames(2);
    1058           1 :     seqNames[0] = "com.sun.star.lang.MultiServiceFactory";
    1059           1 :     seqNames[1] = "com.sun.star.lang.ServiceManager";
    1060           1 :     return seqNames;
    1061             : }
    1062             : 
    1063             : 
    1064           0 : Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories(
    1065             :     const OUString& aServiceName, Reference< XComponentContext > const & )
    1066             : {
    1067           0 :     Sequence< Reference< XInterface > > ret;
    1068             : 
    1069           0 :     MutexGuard aGuard( m_mutex );
    1070             :     ::std::pair<
    1071             :           HashMultimap_OWString_Interface::iterator,
    1072             :           HashMultimap_OWString_Interface::iterator> p(
    1073           0 :               m_ServiceMap.equal_range( aServiceName ) );
    1074             : 
    1075           0 :     if (p.first == p.second) // no factories
    1076             :     {
    1077             :         // no service found, look for an implementation
    1078           0 :         HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.find( aServiceName );
    1079           0 :         if( aIt != m_ImplementationNameMap.end() )
    1080             :         {
    1081           0 :             Reference< XInterface > const & x = aIt->second;
    1082             :             // an implementation found
    1083           0 :             ret = Sequence< Reference< XInterface > >( &x, 1 );
    1084             :         }
    1085             :     }
    1086             :     else
    1087             :     {
    1088           0 :         ::std::vector< Reference< XInterface > > vec;
    1089           0 :         vec.reserve( 4 );
    1090           0 :         while (p.first != p.second)
    1091             :         {
    1092           0 :             vec.push_back( p.first->second );
    1093           0 :             ++p.first;
    1094             :         }
    1095           0 :         ret = Sequence< Reference< XInterface > >( vec.data(), vec.size() );
    1096             :     }
    1097             : 
    1098           0 :     return ret;
    1099             : }
    1100             : 
    1101             : // XContentEnumerationAccess
    1102           0 : Reference<XEnumeration > OServiceManager::createContentEnumeration(
    1103             :     const OUString& aServiceName )
    1104             :     throw(css::uno::RuntimeException, std::exception)
    1105             : {
    1106           0 :     check_undisposed();
    1107             :     Sequence< Reference< XInterface > > factories(
    1108           0 :         OServiceManager::queryServiceFactories( aServiceName, m_xContext ) );
    1109           0 :     if (factories.getLength())
    1110           0 :         return new ServiceEnumeration_Impl( factories );
    1111             :     else
    1112           0 :         return Reference< XEnumeration >();
    1113             : }
    1114             : 
    1115             : // XEnumeration
    1116           0 : Reference<XEnumeration > OServiceManager::createEnumeration() throw(css::uno::RuntimeException, std::exception)
    1117             : {
    1118           0 :     check_undisposed();
    1119           0 :     MutexGuard aGuard( m_mutex );
    1120           0 :     return new ImplementationEnumeration_Impl( m_ImplementationMap );
    1121             : }
    1122             : 
    1123             : // XElementAccess
    1124           0 : Type OServiceManager::getElementType()
    1125             :     throw(css::uno::RuntimeException, std::exception)
    1126             : {
    1127           0 :     check_undisposed();
    1128           0 :     return cppu::UnoType<XInterface>::get();
    1129             : }
    1130             : 
    1131             : // XElementAccess
    1132           0 : sal_Bool OServiceManager::hasElements()
    1133             :     throw(css::uno::RuntimeException, std::exception)
    1134             : {
    1135           0 :     check_undisposed();
    1136           0 :     MutexGuard aGuard( m_mutex );
    1137           0 :     return !m_ImplementationMap.empty();
    1138             : }
    1139             : 
    1140             : // XSet
    1141           0 : sal_Bool OServiceManager::has( const Any & Element )
    1142             :     throw(css::uno::RuntimeException, std::exception)
    1143             : {
    1144           0 :     check_undisposed();
    1145           0 :     if( Element.getValueTypeClass() == TypeClass_INTERFACE )
    1146             :     {
    1147           0 :         Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
    1148           0 :         MutexGuard aGuard( m_mutex );
    1149           0 :         return m_ImplementationMap.find( xEle ) !=
    1150           0 :             m_ImplementationMap.end();
    1151             :     }
    1152           0 :     else if (Element.getValueTypeClass() == TypeClass_STRING)
    1153             :     {
    1154             :         OUString const & implName =
    1155           0 :             *static_cast< OUString const * >(Element.getValue());
    1156           0 :         MutexGuard aGuard( m_mutex );
    1157           0 :         return m_ImplementationNameMap.find( implName ) !=
    1158           0 :             m_ImplementationNameMap.end();
    1159             :     }
    1160           0 :     return sal_False;
    1161             : }
    1162             : 
    1163             : // XSet
    1164           0 : void OServiceManager::insert( const Any & Element )
    1165             :     throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::uno::RuntimeException, std::exception)
    1166             : {
    1167           0 :     check_undisposed();
    1168           0 :     if( Element.getValueTypeClass() != TypeClass_INTERFACE )
    1169             :     {
    1170             :         throw IllegalArgumentException(
    1171             :             "no interface given!",
    1172           0 :             Reference< XInterface >(), 0 );
    1173             :     }
    1174           0 :     Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
    1175             : 
    1176             :     {
    1177           0 :     MutexGuard aGuard( m_mutex );
    1178           0 :     HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
    1179           0 :     if( aIt != m_ImplementationMap.end() )
    1180             :     {
    1181           0 :         throw ElementExistException( "element already exists!" );
    1182             :     }
    1183             : 
    1184             :     // put into the implementation hashmap
    1185           0 :     m_ImplementationMap.insert( xEle );
    1186             : 
    1187             :     // put into the implementation name hashmap
    1188           0 :     Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
    1189           0 :     if( xInfo.is() )
    1190             :     {
    1191           0 :         OUString aImplName = xInfo->getImplementationName();
    1192           0 :         if( !aImplName.isEmpty() )
    1193           0 :             m_ImplementationNameMap[ aImplName ] = xEle;
    1194             : 
    1195             :         //put into the service map
    1196           0 :         Sequence< OUString > aServiceNames = xInfo->getSupportedServiceNames();
    1197           0 :         const OUString * pArray = aServiceNames.getConstArray();
    1198           0 :         for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ )
    1199             :         {
    1200             :             m_ServiceMap.insert( HashMultimap_OWString_Interface::value_type(
    1201           0 :                 pArray[i], *static_cast<Reference<XInterface > const *>(Element.getValue()) ) );
    1202           0 :         }
    1203           0 :     }
    1204             :     }
    1205             :     // add the disposing listener to the factory
    1206           0 :     Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
    1207           0 :     if( xComp.is() )
    1208           0 :         xComp->addEventListener( getFactoryListener() );
    1209           0 : }
    1210             : 
    1211             : // helper function
    1212           0 : bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName)
    1213             : {
    1214           0 :     return ( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end());
    1215             : }
    1216             : 
    1217             : // XSet
    1218           0 : void OServiceManager::remove( const Any & Element )
    1219             :      throw(css::lang::IllegalArgumentException,
    1220             :            css::container::NoSuchElementException,
    1221             :            css::uno::RuntimeException, std::exception)
    1222             : {
    1223           0 :     if (is_disposed())
    1224           0 :         return;
    1225             : 
    1226           0 :     Reference<XInterface > xEle;
    1227           0 :     if (Element.getValueTypeClass() == TypeClass_INTERFACE)
    1228             :     {
    1229           0 :         xEle.set( Element, UNO_QUERY_THROW );
    1230             :     }
    1231           0 :     else if (Element.getValueTypeClass() == TypeClass_STRING)
    1232             :     {
    1233             :         OUString const & implName =
    1234           0 :             *static_cast< OUString const * >(Element.getValue());
    1235           0 :         MutexGuard aGuard( m_mutex );
    1236             :         HashMap_OWString_Interface::const_iterator const iFind(
    1237           0 :             m_ImplementationNameMap.find( implName ) );
    1238           0 :         if (iFind == m_ImplementationNameMap.end())
    1239             :         {
    1240             :             throw NoSuchElementException(
    1241           0 :                 "element is not in: " + implName,
    1242           0 :                 static_cast< OWeakObject * >(this) );
    1243             :         }
    1244           0 :         xEle = iFind->second;
    1245             :     }
    1246             :     else
    1247             :     {
    1248             :         throw IllegalArgumentException(
    1249             :             "neither interface nor string given!",
    1250           0 :             Reference< XInterface >(), 0 );
    1251             :     }
    1252             : 
    1253             :     // remove the disposing listener from the factory
    1254           0 :     Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
    1255           0 :     if( xComp.is() )
    1256           0 :         xComp->removeEventListener( getFactoryListener() );
    1257             : 
    1258           0 :     MutexGuard aGuard( m_mutex );
    1259           0 :     HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
    1260           0 :     if( aIt == m_ImplementationMap.end() )
    1261             :     {
    1262             :         throw NoSuchElementException(
    1263             :             "element is not in!",
    1264           0 :             static_cast< OWeakObject * >(this) );
    1265             :     }
    1266             :     //First remove all factories which have been loaded by ORegistryServiceManager.
    1267           0 :     m_SetLoadedFactories.erase( *aIt);
    1268             :     //Remove from the implementation map. It contains all factories of m_SetLoadedFactories
    1269             :     //which have been added directly through XSet, that is not via ORegistryServiceManager
    1270           0 :     m_ImplementationMap.erase( aIt );
    1271             : 
    1272             :     // remove from the implementation name hashmap
    1273           0 :     Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
    1274           0 :     if( xInfo.is() )
    1275             :     {
    1276           0 :         OUString aImplName = xInfo->getImplementationName();
    1277           0 :         if( !aImplName.isEmpty() )
    1278           0 :             m_ImplementationNameMap.erase( aImplName );
    1279             :     }
    1280             : 
    1281             :     //remove from the service map
    1282           0 :     Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) );
    1283           0 :     if( xSF.is() )
    1284             :     {
    1285           0 :         Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames();
    1286           0 :         const OUString * pArray = aServiceNames.getConstArray();
    1287           0 :         for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ )
    1288             :         {
    1289             :             pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> p =
    1290           0 :                 m_ServiceMap.equal_range( pArray[i] );
    1291             : 
    1292           0 :             while( p.first != p.second )
    1293             :             {
    1294           0 :                 if( xEle == (*p.first).second )
    1295             :                 {
    1296           0 :                     m_ServiceMap.erase( p.first );
    1297           0 :                     break;
    1298             :                 }
    1299           0 :                 ++p.first;
    1300             :             }
    1301           0 :         }
    1302           0 :     }
    1303             : }
    1304             : 
    1305             : /*****************************************************************************
    1306             :     class ORegistryServiceManager
    1307             : *****************************************************************************/
    1308             : class ORegistryServiceManager : public OServiceManager
    1309             : {
    1310             : public:
    1311             :     ORegistryServiceManager( Reference< XComponentContext > const & xContext );
    1312             :     virtual ~ORegistryServiceManager();
    1313             : 
    1314             :     // XInitialization
    1315             :     void SAL_CALL initialize(const Sequence< Any >& Arguments)
    1316             :         throw(css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1317             : 
    1318             :     // XServiceInfo
    1319           1 :     OUString SAL_CALL getImplementationName() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1320           1 :         { return OUString("com.sun.star.comp.stoc.ORegistryServiceManager"); }
    1321             : 
    1322             :     Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1323             : 
    1324             :     // XMultiServiceFactory
    1325             :     Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1326             : 
    1327             :     // XContentEnumerationAccess
    1328             :     //Sequence< OUString >          getAvailableServiceNames() throw( (Exception) );
    1329             :     Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1330             : 
    1331             :     // XComponent
    1332             :     void SAL_CALL dispose() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1333             : 
    1334             :     // OServiceManager
    1335             :     Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
    1336             :         throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1337             :     Any SAL_CALL getPropertyValue(const OUString& PropertyName)
    1338             :         throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1339             : 
    1340             : protected:
    1341             :     //OServiceManager
    1342             :     Sequence< Reference< XInterface > > queryServiceFactories(
    1343             :         const OUString& aServiceName, Reference< XComponentContext > const & xContext ) SAL_OVERRIDE;
    1344             : private:
    1345             :     Reference<XRegistryKey >        getRootKey();
    1346             :     Reference<XInterface > loadWithImplementationName(
    1347             :         const OUString & rImplName, Reference< XComponentContext > const & xContext );
    1348             :     Sequence<OUString>          getFromServiceName(const OUString& serviceName);
    1349             :     Reference<XInterface > loadWithServiceName(
    1350             :         const OUString & rImplName, Reference< XComponentContext > const & xContext );
    1351             :     void                        fillAllNamesFromRegistry( HashSet_OWString & );
    1352             : 
    1353             :     bool                    m_searchedRegistry;
    1354             :     Reference<XSimpleRegistry > m_xRegistry;    // readonly property Registry
    1355             :     Reference<XRegistryKey >    m_xRootKey;
    1356             : 
    1357             : #if OSL_DEBUG_LEVEL > 0
    1358             :     bool m_init;
    1359             : #endif
    1360             : };
    1361             : 
    1362             : /**
    1363             :  * Create a ServiceManager
    1364             :  */
    1365           1 : ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext > const & xContext )
    1366             :     : OServiceManager( xContext )
    1367           1 :     , m_searchedRegistry(false)
    1368             : #if OSL_DEBUG_LEVEL > 0
    1369             :     , m_init( false )
    1370             : #endif
    1371             : {
    1372           1 : }
    1373             : 
    1374             : /**
    1375             :  * Destroy the ServiceManager
    1376             :  */
    1377           2 : ORegistryServiceManager::~ORegistryServiceManager()
    1378             : {
    1379           2 : }
    1380             : 
    1381             : // XComponent
    1382           1 : void ORegistryServiceManager::dispose()
    1383             :     throw(css::uno::RuntimeException, std::exception)
    1384             : {
    1385           1 :     if (rBHelper.bDisposed || rBHelper.bInDispose)
    1386           1 :         return;
    1387           1 :     OServiceManager::dispose();
    1388             :     // dispose
    1389           1 :     MutexGuard aGuard( m_mutex );
    1390             :     // erase all members
    1391           1 :     m_xRegistry.clear();
    1392           1 :     m_xRootKey.clear();
    1393             : }
    1394             : 
    1395             : /**
    1396             :  * Return the root key of the registry. The Default registry service is ordered
    1397             :  * if no registry is set.
    1398             :  */
    1399             : //Reference<XServiceProvider > create_DefaultRegistry_ServiceProvider();
    1400             : 
    1401           0 : Reference<XRegistryKey > ORegistryServiceManager::getRootKey()
    1402             : {
    1403           0 :     if( !m_xRootKey.is() )
    1404             :     {
    1405           0 :         MutexGuard aGuard( m_mutex );
    1406             :         //  DefaultRegistry suchen !!!!
    1407           0 :         if( !m_xRegistry.is() && !m_searchedRegistry )
    1408             :         {
    1409             :             // merken, es wird nur einmal gesucht
    1410           0 :             m_searchedRegistry = true;
    1411             : 
    1412             :             m_xRegistry.set(
    1413             :                 createInstanceWithContext(
    1414             :                     OUString("com.sun.star.registry.DefaultRegistry"),
    1415           0 :                     m_xContext ),
    1416           0 :                 UNO_QUERY );
    1417             :         }
    1418           0 :         if( m_xRegistry.is() && !m_xRootKey.is() )
    1419           0 :             m_xRootKey = m_xRegistry->getRootKey();
    1420             :     }
    1421             : 
    1422           0 :     return m_xRootKey;
    1423             : }
    1424             : 
    1425             : /**
    1426             :  * Create a service provider from the registry with an implementation name
    1427             :  */
    1428           0 : Reference<XInterface > ORegistryServiceManager::loadWithImplementationName(
    1429             :     const OUString& name, Reference< XComponentContext > const & xContext )
    1430             : {
    1431           0 :     Reference<XInterface > ret;
    1432             : 
    1433           0 :     Reference<XRegistryKey > xRootKey = getRootKey();
    1434           0 :     if( !xRootKey.is() )
    1435           0 :         return ret;
    1436             : 
    1437             :     try
    1438             :     {
    1439           0 :         OUString implementationName = "/IMPLEMENTATIONS/" + name;
    1440           0 :         Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName);
    1441             : 
    1442           0 :         if( xImpKey.is() )
    1443             :         {
    1444           0 :             Reference< lang::XMultiServiceFactory > xMgr;
    1445           0 :             if (xContext.is())
    1446           0 :                 xMgr.set( xContext->getServiceManager(), UNO_QUERY_THROW );
    1447             :             else
    1448           0 :                 xMgr.set( this );
    1449           0 :             ret = createSingleRegistryFactory( xMgr, name, xImpKey );
    1450           0 :             insert( makeAny( ret ) );
    1451             :             // Remember this factory as loaded in contrast to inserted ( XSet::insert)
    1452             :             // factories. Those loaded factories in this set are candidates for being
    1453             :             // released on an unloading notification.
    1454           0 :             m_SetLoadedFactories.insert( ret);
    1455           0 :         }
    1456             :     }
    1457           0 :     catch (InvalidRegistryException &)
    1458             :     {
    1459             :     }
    1460             : 
    1461           0 :     return ret;
    1462             : }
    1463             : 
    1464             : /**
    1465             :  * Return all implementation out of the registry.
    1466             :  */
    1467           0 : Sequence<OUString> ORegistryServiceManager::getFromServiceName(
    1468             :     const OUString& serviceName )
    1469             : {
    1470           0 :     OUStringBuffer buf;
    1471           0 :     buf.append( "/SERVICES/" );
    1472           0 :     buf.append( serviceName );
    1473           0 :     return retrieveAsciiValueList( m_xRegistry, buf.makeStringAndClear() );
    1474             : }
    1475             : 
    1476             : /**
    1477             :  * Create a service provider from the registry
    1478             :  */
    1479           0 : Reference<XInterface > ORegistryServiceManager::loadWithServiceName(
    1480             :     const OUString& serviceName, Reference< XComponentContext > const & xContext )
    1481             : {
    1482           0 :     Sequence<OUString> implEntries = getFromServiceName( serviceName );
    1483           0 :     for (sal_Int32 i = 0; i < implEntries.getLength(); i++)
    1484             :     {
    1485             :         Reference< XInterface > x(
    1486           0 :             loadWithImplementationName( implEntries.getConstArray()[i], xContext ) );
    1487           0 :         if (x.is())
    1488           0 :             return x;
    1489           0 :     }
    1490             : 
    1491           0 :     return Reference<XInterface >();
    1492             : }
    1493             : 
    1494             : /**
    1495             :  * Return a sequence of all service names from the registry.
    1496             :  */
    1497           0 : void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet )
    1498             : {
    1499           0 :     Reference<XRegistryKey > xRootKey = getRootKey();
    1500           0 :     if( !xRootKey.is() )
    1501           0 :         return;
    1502             : 
    1503             :     try
    1504             :     {
    1505           0 :         Reference<XRegistryKey > xServicesKey = xRootKey->openKey(
    1506           0 :             OUString("SERVICES") );
    1507             :         // root + /Services + /
    1508           0 :         if( xServicesKey.is() )
    1509             :         {
    1510           0 :             sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1;
    1511           0 :             Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys();
    1512           0 :             for( sal_Int32 i = 0; i < aKeys.getLength(); i++ )
    1513           0 :                 rSet.insert( aKeys.getConstArray()[i]->getKeyName().copy( nPrefix ) );
    1514           0 :         }
    1515             :     }
    1516           0 :     catch (InvalidRegistryException &)
    1517             :     {
    1518           0 :     }
    1519             : }
    1520             : 
    1521             : // XInitialization
    1522           0 : void ORegistryServiceManager::initialize(const Sequence< Any >& Arguments)
    1523             :     throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
    1524             : {
    1525           0 :     check_undisposed();
    1526           0 :     MutexGuard aGuard( m_mutex );
    1527           0 :     if (Arguments.getLength() > 0)
    1528             :     {
    1529           0 :         m_xRootKey.clear();
    1530           0 :         Arguments[ 0 ] >>= m_xRegistry;
    1531           0 :     }
    1532             : #if OSL_DEBUG_LEVEL > 0
    1533             :     // to find all bootstrapping processes to be fixed...
    1534             :     OSL_ENSURE( !m_init, "### second init of service manager instance!" );
    1535             :     m_init = true;
    1536             : #endif
    1537           0 : }
    1538             : 
    1539             : // XMultiServiceFactory, XContentEnumeration
    1540           0 : Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames()
    1541             :     throw(css::uno::RuntimeException, std::exception)
    1542             : {
    1543           0 :     check_undisposed();
    1544           0 :     MutexGuard aGuard( m_mutex );
    1545             :     // all names
    1546           0 :     HashSet_OWString aNameSet;
    1547             : 
    1548             :     // all names from the registry
    1549           0 :     fillAllNamesFromRegistry( aNameSet );
    1550             : 
    1551           0 :     return OServiceManager::getUniqueAvailableServiceNames( aNameSet );
    1552             : }
    1553             : 
    1554             : // XServiceInfo
    1555           1 : Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames()
    1556             :     throw(css::uno::RuntimeException, std::exception)
    1557             : {
    1558           1 :     Sequence< OUString > seqNames(2);
    1559           1 :     seqNames[0] = "com.sun.star.lang.MultiServiceFactory";
    1560           1 :     seqNames[1] = "com.sun.star.lang.RegistryServiceManager";
    1561           1 :     return seqNames;
    1562             : }
    1563             : 
    1564             : 
    1565             : // OServiceManager
    1566           0 : Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories(
    1567             :     const OUString& aServiceName, Reference< XComponentContext > const & xContext )
    1568             : {
    1569             :     Sequence< Reference< XInterface > > ret(
    1570           0 :         OServiceManager::queryServiceFactories( aServiceName, xContext ) );
    1571           0 :     if (ret.getLength())
    1572             :     {
    1573           0 :         return ret;
    1574             :     }
    1575             :     else
    1576             :     {
    1577           0 :         MutexGuard aGuard( m_mutex );
    1578           0 :         Reference< XInterface > x( loadWithServiceName( aServiceName, xContext ) );
    1579           0 :         if (! x.is())
    1580           0 :             x = loadWithImplementationName( aServiceName, xContext );
    1581           0 :         return Sequence< Reference< XInterface > >( &x, 1 );
    1582           0 :     }
    1583             : }
    1584             : 
    1585             : // XContentEnumerationAccess
    1586           0 : Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
    1587             :     const OUString& aServiceName )
    1588             :     throw(css::uno::RuntimeException, std::exception)
    1589             : {
    1590           0 :     check_undisposed();
    1591           0 :     MutexGuard aGuard(m_mutex);
    1592             :     // get all implementation names registered under this service name from the registry
    1593           0 :     Sequence<OUString> aImpls = getFromServiceName( aServiceName );
    1594             :     // load and insert all factories specified by the registry
    1595             :     sal_Int32 i;
    1596           0 :     OUString aImplName;
    1597           0 :     for( i = 0; i < aImpls.getLength(); i++ )
    1598             :     {
    1599           0 :         aImplName = aImpls.getConstArray()[i];
    1600           0 :         if ( !haveFactoryWithThisImplementation(aImplName) )
    1601             :         {
    1602           0 :             loadWithImplementationName( aImplName, m_xContext );
    1603             :         }
    1604             :     }
    1605             :     // call the superclass to enumerate all contents
    1606           0 :     return OServiceManager::createContentEnumeration( aServiceName );
    1607             : }
    1608             : 
    1609             : // OServiceManager
    1610           0 : Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo()
    1611             :     throw(css::uno::RuntimeException, std::exception)
    1612             : {
    1613           0 :     check_undisposed();
    1614           0 :     if (! m_xPropertyInfo.is())
    1615             :     {
    1616           0 :         Sequence< beans::Property > seq( 2 );
    1617           0 :         seq[ 0 ] = beans::Property(
    1618           0 :             "DefaultContext", -1, cppu::UnoType<decltype(m_xContext)>::get(), 0 );
    1619           0 :         seq[ 1 ] = beans::Property(
    1620           0 :             "Registry", -1, cppu::UnoType<decltype(m_xRegistry)>::get(),
    1621           0 :             beans::PropertyAttribute::READONLY );
    1622           0 :         Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
    1623             : 
    1624           0 :         MutexGuard aGuard( m_mutex );
    1625           0 :         if (! m_xPropertyInfo.is())
    1626             :         {
    1627           0 :             m_xPropertyInfo = xInfo;
    1628           0 :         }
    1629             :     }
    1630           0 :     return m_xPropertyInfo;
    1631             : }
    1632             : 
    1633           0 : Any ORegistryServiceManager::getPropertyValue(const OUString& PropertyName)
    1634             :     throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
    1635             : {
    1636           0 :     check_undisposed();
    1637           0 :     if ( PropertyName == "Registry" )
    1638             :     {
    1639           0 :         MutexGuard aGuard( m_mutex );
    1640           0 :         if( m_xRegistry.is() )
    1641           0 :             return makeAny( m_xRegistry );
    1642             :         else
    1643           0 :             return Any();
    1644             :     }
    1645           0 :     return OServiceManager::getPropertyValue( PropertyName );
    1646             : }
    1647             : 
    1648             : } // namespace
    1649             : 
    1650             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    1651           1 : com_sun_star_comp_stoc_OServiceManager_get_implementation(
    1652             :     css::uno::XComponentContext *context,
    1653             :     css::uno::Sequence<css::uno::Any> const &)
    1654             : {
    1655           1 :     return cppu::acquire(new OServiceManager(context));
    1656             : }
    1657             : 
    1658             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    1659           1 : com_sun_star_comp_stoc_ORegistryServiceManager_get_implementation(
    1660             :     css::uno::XComponentContext *context,
    1661             :     css::uno::Sequence<css::uno::Any> const &)
    1662             : {
    1663           1 :     return cppu::acquire(new ORegistryServiceManager(context));
    1664             : }
    1665             : 
    1666             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    1667          35 : com_sun_star_comp_stoc_OServiceManagerWrapper_get_implementation(
    1668             :     css::uno::XComponentContext *context,
    1669             :     css::uno::Sequence<css::uno::Any> const &)
    1670             : {
    1671          35 :     return cppu::acquire(new OServiceManagerWrapper(context));
    1672             : }
    1673             : 
    1674             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11