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

Generated by: LCOV version 1.10