diff options
Diffstat (limited to 'stoc/source/servicemanager/servicemanager.cxx')
-rw-r--r-- | stoc/source/servicemanager/servicemanager.cxx | 2059 |
1 files changed, 2059 insertions, 0 deletions
diff --git a/stoc/source/servicemanager/servicemanager.cxx b/stoc/source/servicemanager/servicemanager.cxx new file mode 100644 index 000000000000..97eb82b6b997 --- /dev/null +++ b/stoc/source/servicemanager/servicemanager.cxx @@ -0,0 +1,2059 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_stoc.hxx" +#include <osl/mutex.hxx> +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> + +#include <hash_map> +#include <hash_set> +#include <list> +#include <uno/mapping.hxx> +#include <uno/dispatcher.h> +#include <cppuhelper/queryinterface.hxx> +#include <cppuhelper/weakref.hxx> +#include <cppuhelper/component.hxx> +#include <cppuhelper/factory.hxx> +#ifndef _CPPUHELPER_IMPLBASE1_HXX +#include <cppuhelper/implbase1.hxx> +#endif +#include <cppuhelper/typeprovider.hxx> +#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_ +#include <cppuhelper/implementationentry.hxx> +#endif +#include <rtl/unload.h> +#include <cppuhelper/component_context.hxx> +#include <cppuhelper/bootstrap.hxx> +#include <cppuhelper/compbase8.hxx> + + +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/container/XSet.hpp> +#include <com/sun/star/container/XElementAccess.hpp> +#include <com/sun/star/container/XEnumeration.hpp> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/uno/XUnloadingPreference.hpp> + +#include <bootstrapservices.hxx> + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) + + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::registry; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; +using namespace cppu; +using namespace osl; +using namespace rtl; +using namespace std; + +rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; + +namespace stoc_bootstrap +{ +Sequence< OUString > smgr_wrapper_getSupportedServiceNames() +{ + static Sequence < OUString > *pNames = 0; + if( ! pNames ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( !pNames ) + { + static Sequence< OUString > seqNames(1); + seqNames.getArray()[0] = OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory") ); + pNames = &seqNames; + } + } + return *pNames; +} + +OUString smgr_wrapper_getImplementationName() +{ + static OUString *pImplName = 0; + if( ! pImplName ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pImplName ) + { + static OUString implName( + RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.OServiceManagerWrapper" ) ); + pImplName = &implName; + } + } + return *pImplName; +} + +Sequence< OUString > smgr_getSupportedServiceNames() +{ + static Sequence < OUString > *pNames = 0; + if( ! pNames ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( !pNames ) + { + static Sequence< OUString > seqNames(2); + seqNames.getArray()[0] = OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory") ); + seqNames.getArray()[1] = OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.ServiceManager") ); + pNames = &seqNames; + } + } + return *pNames; +} + +OUString smgr_getImplementationName() +{ + static OUString *pImplName = 0; + if( ! pImplName ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pImplName ) + { + static OUString implName( + RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.OServiceManager" ) ); + pImplName = &implName; + } + } + return *pImplName; +} + +Sequence< OUString > regsmgr_getSupportedServiceNames() +{ + static Sequence < OUString > *pNames = 0; + if( ! pNames ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( !pNames ) + { + static Sequence< OUString > seqNames(2); + seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory")); + seqNames.getArray()[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.RegistryServiceManager")); + pNames = &seqNames; + } + } + return *pNames; +} + +OUString regsmgr_getImplementationName() +{ + static OUString *pImplName = 0; + if( ! pImplName ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pImplName ) + { + static OUString implName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.ORegistryServiceManager" ) ); + pImplName = &implName; + } + } + return *pImplName; +} +} + +namespace stoc_smgr +{ +static Sequence< sal_Int8 > smgr_getImplementationId() +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + + +static Sequence< OUString > retrieveAsciiValueList( + const Reference< XSimpleRegistry > &xReg, const OUString &keyName ) +{ + Reference< XEnumerationAccess > xAccess( xReg, UNO_QUERY ); + Sequence< OUString > seq; + if( xAccess.is() ) + { + Reference< XEnumeration > xEnum = xAccess->createEnumeration(); + while( xEnum.is() && xEnum->hasMoreElements() ) + { + Reference< XSimpleRegistry > xTempReg; + xEnum->nextElement() >>= xTempReg; + if( xTempReg.is() ) + { + Sequence< OUString > seq2 = retrieveAsciiValueList( xTempReg, keyName ); + + if( seq2.getLength() ) + { + sal_Int32 n1Len = seq.getLength(); + sal_Int32 n2Len = seq2.getLength(); + + seq.realloc( n1Len + n2Len ); + const OUString *pSource = seq2.getConstArray(); + OUString *pTarget = seq.getArray(); + for( int i = 0 ; i < n2Len ; i ++ ) + { + pTarget[i+n1Len] = pSource[i]; + } + } + } + } + } + else if( xReg.is () ) + { + try + { + Reference< XRegistryKey > rRootKey = xReg->getRootKey(); + if( rRootKey.is() ) + { + Reference<XRegistryKey > xKey = rRootKey->openKey(keyName); + if( xKey.is() ) + { + seq = xKey->getAsciiListValue(); + } + } + } + catch( InvalidRegistryException & ) + { + } + catch (InvalidValueException &) + { + } + } + return seq; +} + +/***************************************************************************** + Enumeration by ServiceName +*****************************************************************************/ +struct hashRef_Impl +{ + size_t operator()(const Reference<XInterface > & rName) const + { + // query to XInterface. The cast to XInterface* must be the same for the same object + Reference<XInterface > x( Reference<XInterface >::query( rName ) ); + return (size_t)x.get(); + } +}; + +struct equaltoRef_Impl +{ + size_t operator()(const Reference<XInterface > & rName1, const Reference<XInterface > & rName2 ) const + { return rName1 == rName2; } +}; + +typedef hash_set +< + Reference<XInterface >, + hashRef_Impl, + equaltoRef_Impl +> HashSet_Ref; + + +class ServiceEnumeration_Impl : public WeakImplHelper1< XEnumeration > +{ +public: + ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories ) + : aFactories( rFactories ) + , nIt( 0 ) + { g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); } + virtual ~ServiceEnumeration_Impl() + { g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); } + + // XEnumeration + sal_Bool SAL_CALL hasMoreElements() + throw(::com::sun::star::uno::RuntimeException); + Any SAL_CALL nextElement() + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); +private: + Mutex aMutex; + Sequence< Reference<XInterface > > aFactories; + sal_Int32 nIt; +}; + +// XEnumeration +sal_Bool ServiceEnumeration_Impl::hasMoreElements() throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( aMutex ); + return nIt != aFactories.getLength(); +} + +// XEnumeration +Any ServiceEnumeration_Impl::nextElement() + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( aMutex ); + if( nIt == aFactories.getLength() ) + throw NoSuchElementException(); + + return Any( &aFactories.getConstArray()[nIt++], ::getCppuType( (const Reference<XInterface > *)0 ) ); +} + +//================================================================================================== +class PropertySetInfo_Impl : public WeakImplHelper1< beans::XPropertySetInfo > +{ + Sequence< beans::Property > m_properties; + +public: + inline PropertySetInfo_Impl( Sequence< beans::Property > const & properties ) SAL_THROW( () ) + : m_properties( properties ) + {} + + // XPropertySetInfo impl + virtual Sequence< beans::Property > SAL_CALL getProperties() + throw (RuntimeException); + virtual beans::Property SAL_CALL getPropertyByName( OUString const & name ) + throw (beans::UnknownPropertyException, RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( OUString const & name ) + throw (RuntimeException); +}; +//__________________________________________________________________________________________________ +Sequence< beans::Property > PropertySetInfo_Impl::getProperties() + throw (RuntimeException) +{ + return m_properties; +} +//__________________________________________________________________________________________________ +beans::Property PropertySetInfo_Impl::getPropertyByName( OUString const & name ) + throw (beans::UnknownPropertyException, RuntimeException) +{ + beans::Property const * p = m_properties.getConstArray(); + for ( sal_Int32 nPos = m_properties.getLength(); nPos--; ) + { + if (p[ nPos ].Name.equals( name )) + return p[ nPos ]; + } + throw beans::UnknownPropertyException( + OUSTR("unknown property: ") + name, Reference< XInterface >() ); +} +//__________________________________________________________________________________________________ +sal_Bool PropertySetInfo_Impl::hasPropertyByName( OUString const & name ) + throw (RuntimeException) +{ + beans::Property const * p = m_properties.getConstArray(); + for ( sal_Int32 nPos = m_properties.getLength(); nPos--; ) + { + if (p[ nPos ].Name.equals( name )) + return sal_True; + } + return sal_False; +} + + +/***************************************************************************** + Enumeration by implementation +*****************************************************************************/ +class ImplementationEnumeration_Impl : public WeakImplHelper1< XEnumeration > +{ +public: + ImplementationEnumeration_Impl( const HashSet_Ref & rImplementationMap ) + : aImplementationMap( rImplementationMap ) + , aIt( aImplementationMap.begin() ) + { + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + } + virtual ~ImplementationEnumeration_Impl(); + + // XEnumeration + virtual sal_Bool SAL_CALL hasMoreElements() + throw(::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL nextElement() + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + +private: + Mutex aMutex; + HashSet_Ref aImplementationMap; + HashSet_Ref::iterator aIt; + sal_Int32 nNext; + Reference<XInterface > xNext; +}; + +ImplementationEnumeration_Impl::~ImplementationEnumeration_Impl() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +// XEnumeration +sal_Bool ImplementationEnumeration_Impl::hasMoreElements() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( aMutex ); + return aIt != aImplementationMap.end(); +} + +// XEnumeration +Any ImplementationEnumeration_Impl::nextElement() + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( aMutex ); + if( aIt == aImplementationMap.end() ) + throw NoSuchElementException(); + + Any ret( &(*aIt), ::getCppuType( (const Reference<XInterface > *)0 ) ); + ++aIt; + return ret; +} + +/***************************************************************************** + Hash tables +*****************************************************************************/ +struct equalOWString_Impl +{ + sal_Bool operator()(const OUString & s1, const OUString & s2) const + { return s1 == s2; } +}; + +struct hashOWString_Impl +{ + size_t operator()(const OUString & rName) const + { return rName.hashCode(); } +}; + +typedef hash_set +< + OUString, + hashOWString_Impl, + equalOWString_Impl +> HashSet_OWString; + +typedef hash_multimap +< + OUString, + Reference<XInterface >, + hashOWString_Impl, + equalOWString_Impl +> HashMultimap_OWString_Interface; + +typedef hash_map +< + OUString, + Reference<XInterface >, + hashOWString_Impl, + equalOWString_Impl +> HashMap_OWString_Interface; + +/***************************************************************************** + class OServiceManager_Listener +*****************************************************************************/ +class OServiceManager_Listener : public WeakImplHelper1< XEventListener > +{ +private: + WeakReference<XSet > xSMgr; + +public: + OServiceManager_Listener( const Reference<XSet > & rSMgr ) + : xSMgr( rSMgr ) + {} + + // XEventListener + virtual void SAL_CALL disposing(const EventObject & rEvt ) throw(::com::sun::star::uno::RuntimeException); +}; + +void OServiceManager_Listener::disposing(const EventObject & rEvt ) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference<XSet > x( xSMgr ); + if( x.is() ) + { + try + { + x->remove( Any( &rEvt.Source, ::getCppuType( (const Reference<XInterface > *)0 ) ) ); + } + catch( const IllegalArgumentException & ) + { + OSL_ENSURE( sal_False, "IllegalArgumentException catched" ); + } + catch( const NoSuchElementException & ) + { + OSL_ENSURE( sal_False, "NoSuchElementException catched" ); + } + } +} + + +/***************************************************************************** + class OServiceManager +*****************************************************************************/ +struct OServiceManagerMutex +{ + Mutex m_mutex; +}; + +extern "C" void SAL_CALL smgrUnloadingListener(void* id); + +typedef WeakComponentImplHelper8< + lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo, + lang::XInitialization, lang::XUnoTunnel, + container::XSet, container::XContentEnumerationAccess, + beans::XPropertySet > t_OServiceManager_impl; + +class OServiceManager + : public OServiceManagerMutex + , public t_OServiceManager_impl +{ +public: + friend void SAL_CALL smgrUnloadingListener(void* id); + + OServiceManager( Reference< XComponentContext > const & xContext ); + virtual ~OServiceManager(); + + // XUnoTunnel + sal_Int64 SAL_CALL getSomething( Sequence< sal_Int8 > const & id ) + throw (RuntimeException); + + // XInitialization + void SAL_CALL initialize( Sequence< Any > const & args ) + throw (Exception); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + static OUString getImplementationName_Static() throw(::com::sun::star::uno::RuntimeException) + { return stoc_bootstrap::smgr_getImplementationName(); } + virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // XMultiComponentFactory + virtual Reference< XInterface > SAL_CALL createInstanceWithContext( + OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext ) + throw (Exception, RuntimeException); + virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( + OUString const & rServiceSpecifier, + Sequence< Any > const & rArguments, + Reference< XComponentContext > const & xContext ) + throw (Exception, RuntimeException); +// virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() +// throw (RuntimeException); + + // XMultiServiceFactory + virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(::com::sun::star::uno::RuntimeException); + virtual Reference<XInterface > SAL_CALL createInstance(const OUString &) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString &, const Sequence<Any >& Arguments) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // The same as the getAvailableServiceNames, but only uique names + Sequence< OUString > getUniqueAvailableServiceNames( + HashSet_OWString & aNameSet ); + + // XElementAccess + virtual Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException); + + // XEnumerationAccess + virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw(::com::sun::star::uno::RuntimeException); + + // XSet + virtual sal_Bool SAL_CALL has( const Any & Element ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL insert( const Any & Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL remove( const Any & Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException); + + // XContentEnumerationAccess + //Sequence< OUString > getAvailableServiceNames() throw( (Exception) ); + virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(::com::sun::star::uno::RuntimeException); + virtual Reference<XEnumeration > SAL_CALL createContentEnumeration( + const OUString& aServiceName, Reference< XComponentContext > const & xContext ) + throw(::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); + + // XPropertySet + Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() + throw(::com::sun::star::uno::RuntimeException); + void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue) + 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); + Any SAL_CALL getPropertyValue(const OUString& PropertyName) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + +protected: + inline bool is_disposed() const SAL_THROW( (lang::DisposedException) ); + inline void check_undisposed() const SAL_THROW( (lang::DisposedException) ); + virtual void SAL_CALL disposing(); + + sal_Bool haveFactoryWithThisImplementation(const OUString& aImplName); + + virtual Sequence< Reference< XInterface > > queryServiceFactories( + const OUString& aServiceName, Reference< XComponentContext > const & xContext ); + + Reference< XComponentContext > m_xContext; + + Reference< beans::XPropertySetInfo > m_xPropertyInfo; + + sal_Int32 m_nUnloadingListenerId; + + // Does clean up when the unloading mechanism has been set off. It is called from + // the listener function smgrUnloadingListener. + void onUnloadingNotify(); + // factories which have been loaded and not inserted( by XSet::insert) + // are remembered by this set. Those factories + // are not released on a call to onUnloadingNotify + HashSet_Ref m_SetLoadedFactories; +private: + + Reference<XEventListener > getFactoryListener(); + + + HashMultimap_OWString_Interface m_ServiceMap; + HashSet_Ref m_ImplementationMap; + HashMap_OWString_Interface m_ImplementationNameMap; + Reference<XEventListener > xFactoryListener; + bool m_bInDisposing; +}; + + +//______________________________________________________________________________ +inline bool OServiceManager::is_disposed() const + SAL_THROW( (lang::DisposedException) ) +{ + // ought to be guarded by m_mutex: + return (m_bInDisposing || rBHelper.bDisposed); +} + +//______________________________________________________________________________ +inline void OServiceManager::check_undisposed() const + SAL_THROW( (lang::DisposedException) ) +{ + if (is_disposed()) + { + throw lang::DisposedException( + OUSTR("service manager instance has already been disposed!"), + (OWeakObject *)this ); + } +} + +//################################################################################################## +//################################################################################################## +//################################################################################################## + +class OServiceManagerWrapper : public OServiceManagerMutex, public t_OServiceManager_impl +{ + Reference< XComponentContext > m_xContext; + OServiceManager * m_root; + inline OServiceManager * getRoot() SAL_THROW( (RuntimeException) ) + { + if (! m_root) + { + throw lang::DisposedException( + OUSTR("service manager instance has already been disposed!"), + Reference< XInterface >() ); + } + return m_root; + } + +protected: + virtual void SAL_CALL disposing(); + +public: + OServiceManagerWrapper( + Reference< XComponentContext > const & xContext ) + SAL_THROW( (RuntimeException) ); + virtual ~OServiceManagerWrapper() SAL_THROW( () ); + + // XUnoTunnel + sal_Int64 SAL_CALL getSomething( Sequence< sal_Int8 > const & id ) throw (RuntimeException) + { return getRoot()->getSomething( id ); } + + // XInitialization + void SAL_CALL initialize( Sequence< Any > const & args ) throw (Exception) + { getRoot()->initialize( args ); } + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw (RuntimeException) + { return getRoot()->getImplementationName(); } + virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (RuntimeException) + { return getRoot()->supportsService( ServiceName ); } + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException) + { return getRoot()->getSupportedServiceNames(); } + + // XMultiComponentFactory + virtual Reference< XInterface > SAL_CALL createInstanceWithContext( + OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext ) + throw (Exception, RuntimeException) + { return getRoot()->createInstanceWithContext( rServiceSpecifier, xContext ); } + virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( + OUString const & rServiceSpecifier, + Sequence< Any > const & rArguments, + Reference< XComponentContext > const & xContext ) + throw (Exception, RuntimeException) + { return getRoot()->createInstanceWithArgumentsAndContext( rServiceSpecifier, rArguments, xContext ); } +// virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() +// throw (RuntimeException); + + // XMultiServiceFactory + virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw (RuntimeException) + { return getRoot()->getAvailableServiceNames(); } + virtual Reference<XInterface > SAL_CALL createInstance(const OUString & name) throw (Exception) + { return getRoot()->createInstanceWithContext( name, m_xContext ); } + virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString & name, const Sequence<Any >& Arguments) throw (Exception) + { return getRoot()->createInstanceWithArgumentsAndContext( name, Arguments, m_xContext ); } + + // XElementAccess + virtual Type SAL_CALL getElementType() throw (RuntimeException) + { return getRoot()->getElementType(); } + virtual sal_Bool SAL_CALL hasElements() throw (RuntimeException) + { return getRoot()->hasElements(); } + + // XEnumerationAccess + virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw (RuntimeException) + { return getRoot()->createEnumeration(); } + + // XSet + virtual sal_Bool SAL_CALL has( const Any & Element ) throw (RuntimeException) + { return getRoot()->has( Element ); } + virtual void SAL_CALL insert( const Any & Element ) throw (lang::IllegalArgumentException, container::ElementExistException, RuntimeException) + { getRoot()->insert( Element ); } + virtual void SAL_CALL remove( const Any & Element ) throw (lang::IllegalArgumentException, container::NoSuchElementException, RuntimeException) + { getRoot()->remove( Element ); } + + // XContentEnumerationAccess + //Sequence< OUString > getAvailableServiceNames() throw( (Exception) ); + virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw (RuntimeException) + { return getRoot()->createContentEnumeration( aServiceName, m_xContext ); } + + // XPropertySet + Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() throw (RuntimeException) + { return getRoot()->getPropertySetInfo(); } + + void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue) + throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException); + Any SAL_CALL getPropertyValue(const OUString& PropertyName) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException); + + void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException) + { getRoot()->addPropertyChangeListener( PropertyName, aListener ); } + void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException) + { getRoot()->removePropertyChangeListener( PropertyName, aListener ); } + void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException) + { getRoot()->addVetoableChangeListener( PropertyName, aListener ); } + void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException) + { getRoot()->removeVetoableChangeListener( PropertyName, aListener ); } +}; +//__________________________________________________________________________________________________ +void SAL_CALL OServiceManagerWrapper::setPropertyValue( + const OUString& PropertyName, const Any& aValue ) + throw (beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException) +{ + if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") )) + { + Reference< XComponentContext > xContext; + if (aValue >>= xContext) + { + MutexGuard aGuard( m_mutex ); + m_xContext = xContext; + } + else + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no XComponentContext given!") ), + (OWeakObject *)this, 1 ); + } + } + else + { + getRoot()->setPropertyValue( PropertyName, aValue ); + } +} +//__________________________________________________________________________________________________ +Any SAL_CALL OServiceManagerWrapper::getPropertyValue( + const OUString& PropertyName ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException) +{ + if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") )) + { + MutexGuard aGuard( m_mutex ); + if( m_xContext.is() ) + return makeAny( m_xContext ); + else + return Any(); + } + else + { + return getRoot()->getPropertyValue( PropertyName ); + } +} +//__________________________________________________________________________________________________ +void OServiceManagerWrapper::disposing() +{ + m_xContext.clear(); + + if (m_root) + { +// no m_root->dispose(), because every context disposes its service manager... + m_root->release(); + m_root = 0; + } +} +//__________________________________________________________________________________________________ +OServiceManagerWrapper::~OServiceManagerWrapper() SAL_THROW( () ) +{ + if (m_root) + { + m_root->release(); + m_root = 0; + } + + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} +//__________________________________________________________________________________________________ +OServiceManagerWrapper::OServiceManagerWrapper( + Reference< XComponentContext > const & xContext ) + SAL_THROW( (RuntimeException) ) + : t_OServiceManager_impl( m_mutex ) + , m_xContext( xContext ) + , m_root( 0 ) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + + Reference< XUnoTunnel > xTunnel( m_xContext->getServiceManager(), UNO_QUERY ); + OSL_ASSERT( xTunnel.is() ); + if (xTunnel.is()) + { + m_root = reinterpret_cast< OServiceManager * >( + xTunnel->getSomething( smgr_getImplementationId() ) ); + OSL_ASSERT( m_root ); + if (m_root) + { + m_root->acquire(); + } + } + + if (! m_root) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("can only wrap OServiceManager instances!") ), + Reference< XInterface >() ); + } +} + +//################################################################################################## +//################################################################################################## +//################################################################################################## + +// XUnoTunnel +sal_Int64 OServiceManager::getSomething( Sequence< sal_Int8 > const & id ) + throw (RuntimeException) +{ + check_undisposed(); + if (id == smgr_getImplementationId()) + return reinterpret_cast< sal_Int64 >(this); + else + return 0; +} + +/** + * Create a ServiceManager + */ +OServiceManager::OServiceManager( Reference< XComponentContext > const & xContext ) + : t_OServiceManager_impl( m_mutex ) + , m_xContext( xContext ) + , m_bInDisposing( false ) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + m_nUnloadingListenerId= rtl_addUnloadingListener( smgrUnloadingListener, this); +} + +/** + * Destroy the ServiceManager + */ +OServiceManager::~OServiceManager() +{ + if( m_nUnloadingListenerId != 0) + rtl_removeUnloadingListener( m_nUnloadingListenerId ); + + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +// Removes entries in m_ServiceMap, m_ImplementationNameMap and m_ImplementationNameMap +// if those entries have not been inserted through XSet::insert. Therefore the entries +// are compared with the entries in m_SetLoadedFactories. +void OServiceManager::onUnloadingNotify() +{ + MutexGuard aGuard( m_mutex); + + typedef HashSet_Ref::const_iterator CIT_S; + typedef HashMultimap_OWString_Interface::iterator IT_MM; + + CIT_S it_SetEnd= m_SetLoadedFactories.end(); + IT_MM it_end1= m_ServiceMap.end(); + list<IT_MM> listDeleteServiceMap; + typedef list<IT_MM>::const_iterator CIT_DMM; + // find occurences in m_ServiceMap + for(IT_MM it_i1= m_ServiceMap.begin(); it_i1 != it_end1; it_i1++) + { + if( m_SetLoadedFactories.find( it_i1->second) != it_SetEnd) + { + Reference<XUnloadingPreference> xunl( it_i1->second, UNO_QUERY); + if( xunl.is()) + { + if( xunl->releaseOnNotification()) + listDeleteServiceMap.push_front( it_i1); + } + else + listDeleteServiceMap.push_front( it_i1); + } + } + // delete elements from m_ServiceMap + CIT_DMM it_end2= listDeleteServiceMap.end(); + for( CIT_DMM it_i2= listDeleteServiceMap.begin(); it_i2 != it_end2; it_i2++) + m_ServiceMap.erase( *it_i2); + + // find elements in m_ImplementationNameMap + typedef HashMap_OWString_Interface::iterator IT_M; + IT_M it_end3= m_ImplementationNameMap.end(); + list<IT_M> listDeleteImplementationNameMap; + typedef list<IT_M>::const_iterator CIT_DM; + for( IT_M it_i3= m_ImplementationNameMap.begin(); it_i3 != it_end3; it_i3++) + { + if( m_SetLoadedFactories.find( it_i3->second) != it_SetEnd) + { + Reference<XUnloadingPreference> xunl( it_i3->second, UNO_QUERY); + if( xunl.is()) + { + if( xunl->releaseOnNotification()) + listDeleteImplementationNameMap.push_front( it_i3); + } + else + listDeleteImplementationNameMap.push_front( it_i3); + } + } + // delete elements from m_ImplementationNameMap + CIT_DM it_end4= listDeleteImplementationNameMap.end(); + for( CIT_DM it_i4= listDeleteImplementationNameMap.begin(); it_i4 != it_end4; it_i4++) + m_ImplementationNameMap.erase( *it_i4); + + // find elements in m_ImplementationMap + typedef HashSet_Ref::iterator IT_S; + IT_S it_end5= m_ImplementationMap.end(); + list<IT_S> listDeleteImplementationMap; + typedef list<IT_S>::const_iterator CIT_DS; + for( IT_S it_i5= m_ImplementationMap.begin(); it_i5 != it_end5; it_i5++) + { + if( m_SetLoadedFactories.find( *it_i5) != it_SetEnd) + { + Reference<XUnloadingPreference> xunl( *it_i5, UNO_QUERY); + if( xunl.is()) + { + if( xunl->releaseOnNotification()) + listDeleteImplementationMap.push_front( it_i5); + } + else + listDeleteImplementationMap.push_front( it_i5); + } + } + // delete elements from m_ImplementationMap + CIT_DS it_end6= listDeleteImplementationMap.end(); + for( CIT_DS it_i6= listDeleteImplementationMap.begin(); it_i6 != it_end6; it_i6++) + m_ImplementationMap.erase( *it_i6); + + // remove Event listener before the factories are released. + IT_S it_end7= m_SetLoadedFactories.end(); + + Reference<XEventListener> xlistener= getFactoryListener(); + for( IT_S it_i7= m_SetLoadedFactories.begin(); it_i7 != it_end7; it_i7++) + { + Reference<XComponent> xcomp( *it_i7, UNO_QUERY); + if( xcomp.is()) + xcomp->removeEventListener( xlistener); + } + // release the factories in m_SetLoadedFactories + m_SetLoadedFactories.clear(); +} + +// XComponent +void OServiceManager::dispose() + throw(::com::sun::star::uno::RuntimeException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + return; + t_OServiceManager_impl::dispose(); +} + +void OServiceManager::disposing() +{ + // dispose all factories + HashSet_Ref aImpls; + { + MutexGuard aGuard( m_mutex ); + m_bInDisposing = true; + aImpls = m_ImplementationMap; + } + HashSet_Ref::iterator aIt = aImpls.begin(); + while( aIt != aImpls.end() ) + { + try + { + Reference<XComponent > xComp( Reference<XComponent >::query( *aIt++ ) ); + if( xComp.is() ) + xComp->dispose(); + } + catch (RuntimeException & exc) + { +#if OSL_DEBUG_LEVEL > 1 + OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "### RuntimeException occured upon disposing factory: %s", str.getStr() ); +#else + (void) exc; // unused +#endif + } + } + + // dispose + HashSet_Ref aImplMap; + { + MutexGuard aGuard( m_mutex ); + // erase all members + m_ServiceMap = HashMultimap_OWString_Interface(); + aImplMap = m_ImplementationMap; + m_ImplementationMap = HashSet_Ref(); + m_ImplementationNameMap = HashMap_OWString_Interface(); + m_SetLoadedFactories= HashSet_Ref(); + } + + m_xContext.clear(); + + // not only the Event should hold the object + OSL_ASSERT( m_refCount != 1 ); + + // Revoke this service manager as unloading listener + rtl_removeUnloadingListener( m_nUnloadingListenerId); + m_nUnloadingListenerId=0; +} + +// XPropertySet +Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo() + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + if (! m_xPropertyInfo.is()) + { + Sequence< beans::Property > seq( 1 ); + seq[ 0 ] = beans::Property( + OUSTR("DefaultContext"), -1, ::getCppuType( &m_xContext ), 0 ); + Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) ); + + MutexGuard aGuard( m_mutex ); + if (! m_xPropertyInfo.is()) + { + m_xPropertyInfo = xInfo; + } + } + return m_xPropertyInfo; +} + +void OServiceManager::setPropertyValue( + const OUString& PropertyName, const Any& aValue ) + 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) +{ + check_undisposed(); + if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") )) + { + Reference< XComponentContext > xContext; + if (aValue >>= xContext) + { + MutexGuard aGuard( m_mutex ); + m_xContext = xContext; + } + else + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no XComponentContext given!") ), + (OWeakObject *)this, 1 ); + } + } + else + { + throw UnknownPropertyException( + OUString( RTL_CONSTASCII_USTRINGPARAM("unknown property ") ) + PropertyName, + (OWeakObject *)this ); + } +} + +Any OServiceManager::getPropertyValue(const OUString& PropertyName) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") )) + { + MutexGuard aGuard( m_mutex ); + if( m_xContext.is() ) + return makeAny( m_xContext ); + else + return Any(); + } + else + { + UnknownPropertyException except; + except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager : unknown property " ) ); + except.Message += PropertyName; + throw except; + } +} + +void OServiceManager::addPropertyChangeListener( + const OUString&, const Reference<XPropertyChangeListener >&) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + throw UnknownPropertyException(); +} + +void OServiceManager::removePropertyChangeListener( + const OUString&, const Reference<XPropertyChangeListener >&) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + throw UnknownPropertyException(); +} + +void OServiceManager::addVetoableChangeListener( + const OUString&, const Reference<XVetoableChangeListener >&) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + throw UnknownPropertyException(); +} + +void OServiceManager::removeVetoableChangeListener( + const OUString&, const Reference<XVetoableChangeListener >&) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + throw UnknownPropertyException(); +} + +// OServiceManager +Reference<XEventListener > OServiceManager::getFactoryListener() +{ + check_undisposed(); + MutexGuard aGuard( m_mutex ); + if( !xFactoryListener.is() ) + xFactoryListener = new OServiceManager_Listener( this ); + return xFactoryListener; +} + +// XMultiServiceFactory, XContentEnumeration +Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames( + HashSet_OWString & aNameSet ) +{ + check_undisposed(); + MutexGuard aGuard( m_mutex ); + HashMultimap_OWString_Interface::iterator aSIt = m_ServiceMap.begin(); + while( aSIt != m_ServiceMap.end() ) + aNameSet.insert( (*aSIt++).first ); + + /* do not return the implementation names + HashMap_OWString_Interface m_ImplementationNameMap; + HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.begin(); + while( aIt != m_ImplementationNameMap.end() ) + aNameSet.insert( (*aIt++).first ); + */ + + Sequence< OUString > aNames( aNameSet.size() ); + OUString * pArray = aNames.getArray(); + sal_Int32 i = 0; + HashSet_OWString::iterator next = aNameSet.begin(); + while( next != aNameSet.end() ) + pArray[i++] = (*next++); + + return aNames; +} + +// XMultiComponentFactory +Reference< XInterface > OServiceManager::createInstanceWithContext( + OUString const & rServiceSpecifier, + Reference< XComponentContext > const & xContext ) + throw (Exception, RuntimeException) +{ + check_undisposed(); +#if OSL_DEBUG_LEVEL > 0 + Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + if (xProps.is()) + { + Reference< XComponentContext > xDefContext; + xProps->getPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xDefContext; + OSL_ENSURE( + xContext == xDefContext, + "### default context of service manager singleton differs from context holding it!" ); + } +#endif + + Sequence< Reference< XInterface > > factories( + queryServiceFactories( rServiceSpecifier, xContext ) ); + Reference< XInterface > const * p = factories.getConstArray(); + for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos ) + { + try + { + Reference< XInterface > const & xFactory = p[ nPos ]; + if (xFactory.is()) + { + Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY ); + if (xFac.is()) + { + return xFac->createInstanceWithContext( xContext ); + } + else + { + Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY ); + if (xFac2.is()) + { +#if OSL_DEBUG_LEVEL > 1 + OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "### ignoring given context raising service %s !!!\n", aStr.getStr() ); +#endif + return xFac2->createInstance(); + } + } + } + } + catch (lang::DisposedException & exc) + { +#if OSL_DEBUG_LEVEL > 1 + OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "### DisposedException occured: %s", str.getStr() ); +#else + (void) exc; // unused +#endif + } + } + + return Reference< XInterface >(); +} +// XMultiComponentFactory +Reference< XInterface > OServiceManager::createInstanceWithArgumentsAndContext( + OUString const & rServiceSpecifier, + Sequence< Any > const & rArguments, + Reference< XComponentContext > const & xContext ) + throw (Exception, RuntimeException) +{ + check_undisposed(); +#if OSL_DEBUG_LEVEL > 0 + Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + if (xProps.is()) + { + Reference< XComponentContext > xDefContext; + xProps->getPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xDefContext; + OSL_ENSURE( + xContext == xDefContext, + "### default context of service manager singleton differs from context holding it!" ); + } +#endif + + Sequence< Reference< XInterface > > factories( + queryServiceFactories( rServiceSpecifier, xContext ) ); + Reference< XInterface > const * p = factories.getConstArray(); + for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos ) + { + try + { + Reference< XInterface > const & xFactory = p[ nPos ]; + if (xFactory.is()) + { + Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY ); + if (xFac.is()) + { + return xFac->createInstanceWithArgumentsAndContext( rArguments, xContext ); + } + else + { + Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY ); + if (xFac2.is()) + { +#if OSL_DEBUG_LEVEL > 1 + OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "### ignoring given context raising service %s !!!\n", aStr.getStr() ); +#endif + return xFac2->createInstanceWithArguments( rArguments ); + } + } + } + } + catch (lang::DisposedException & exc) + { +#if OSL_DEBUG_LEVEL > 1 + OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "### DisposedException occured: %s", str.getStr() ); +#else + (void) exc; // unused +#endif + } + } + + return Reference< XInterface >(); +} + +// XMultiServiceFactory, XMultiComponentFactory, XContentEnumeration +Sequence< OUString > OServiceManager::getAvailableServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + // all names + HashSet_OWString aNameSet; + return getUniqueAvailableServiceNames( aNameSet ); +} + +// XMultibleServiceFactory +Reference<XInterface > OServiceManager::createInstance( + const OUString& rServiceSpecifier ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + return createInstanceWithContext( + rServiceSpecifier, m_xContext ); +} + +// XMultibleServiceFactory +Reference<XInterface > OServiceManager::createInstanceWithArguments( + const OUString& rServiceSpecifier, + const Sequence<Any >& rArguments ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + return createInstanceWithArgumentsAndContext( + rServiceSpecifier, rArguments, m_xContext ); +} + +// XInitialization +void OServiceManager::initialize( Sequence< Any > const & ) + throw (Exception) +{ + check_undisposed(); + OSL_ENSURE( 0, "not impl!" ); +} + +// XServiceInfo +OUString OServiceManager::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + return getImplementationName_Static(); +} + +// XServiceInfo +sal_Bool OServiceManager::supportsService(const OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +// XServiceInfo +Sequence< OUString > OServiceManager::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + return stoc_bootstrap::smgr_getSupportedServiceNames(); +} + + +Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories( + const OUString& aServiceName, Reference< XComponentContext > const & ) +{ + Sequence< Reference< XInterface > > ret; + + MutexGuard aGuard( m_mutex ); + ::std::pair< + HashMultimap_OWString_Interface::iterator, + HashMultimap_OWString_Interface::iterator> p( + m_ServiceMap.equal_range( aServiceName ) ); + + if (p.first == p.second) // no factories + { + // no service found, look for an implementation + HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.find( aServiceName ); + if( aIt != m_ImplementationNameMap.end() ) + { + Reference< XInterface > const & x = aIt->second; + // an implementation found + ret = Sequence< Reference< XInterface > >( &x, 1 ); + } + } + else + { + ::std::vector< Reference< XInterface > > vec; + vec.reserve( 4 ); + while (p.first != p.second) + { + vec.push_back( p.first->second ); + ++p.first; + } + ret = Sequence< Reference< XInterface > >( + vec.empty() ? 0 : &vec[ 0 ], vec.size() ); + } + + return ret; +} + +// XContentEnumerationAccess +Reference<XEnumeration > OServiceManager::createContentEnumeration( + const OUString& aServiceName, Reference< XComponentContext > const & xContext ) + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + Sequence< Reference< XInterface > > factories( + OServiceManager::queryServiceFactories( aServiceName, xContext ) ); + if (factories.getLength()) + return new ServiceEnumeration_Impl( factories ); + else + return Reference< XEnumeration >(); +} +Reference<XEnumeration > OServiceManager::createContentEnumeration( + const OUString& aServiceName ) + throw(::com::sun::star::uno::RuntimeException) +{ + return createContentEnumeration( aServiceName, m_xContext ); +} + +// XEnumeration +Reference<XEnumeration > OServiceManager::createEnumeration() throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + MutexGuard aGuard( m_mutex ); + return new ImplementationEnumeration_Impl( m_ImplementationMap ); +} + +// XElementAccess +Type OServiceManager::getElementType() + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + return ::getCppuType( (const Reference< XInterface > *)0 ); +} + +// XElementAccess +sal_Bool OServiceManager::hasElements() + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + MutexGuard aGuard( m_mutex ); + return !m_ImplementationMap.empty(); +} + +// XSet +sal_Bool OServiceManager::has( const Any & Element ) + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + if( Element.getValueTypeClass() == TypeClass_INTERFACE ) + { + Reference<XInterface > xEle( Element, UNO_QUERY_THROW ); + MutexGuard aGuard( m_mutex ); + return m_ImplementationMap.find( xEle ) != + m_ImplementationMap.end(); + } + else if (Element.getValueTypeClass() == TypeClass_STRING) + { + OUString const & implName = + *reinterpret_cast< OUString const * >(Element.getValue()); + MutexGuard aGuard( m_mutex ); + return m_ImplementationNameMap.find( implName ) != + m_ImplementationNameMap.end(); + } + return sal_False; +} + +// XSet +void OServiceManager::insert( const Any & Element ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + if( Element.getValueTypeClass() != TypeClass_INTERFACE ) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no interface given!") ), + Reference< XInterface >(), 0 ); + } + Reference<XInterface > xEle( Element, UNO_QUERY_THROW ); + + { + MutexGuard aGuard( m_mutex ); + HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle ); + if( aIt != m_ImplementationMap.end() ) + { + throw ElementExistException( + OUString( RTL_CONSTASCII_USTRINGPARAM("element already exists!") ), + Reference< XInterface >() ); + } + + // put into the implementation hashmap + m_ImplementationMap.insert( xEle ); + + // put into the implementation name hashmap + Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) ); + if( xInfo.is() ) + { + OUString aImplName = xInfo->getImplementationName(); + if( aImplName.getLength() ) + m_ImplementationNameMap[ aImplName ] = xEle; + + //put into the service map + Sequence< OUString > aServiceNames = xInfo->getSupportedServiceNames(); + const OUString * pArray = aServiceNames.getConstArray(); + for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ ) + { + m_ServiceMap.insert( HashMultimap_OWString_Interface::value_type( + pArray[i], *(Reference<XInterface > *)Element.getValue() ) ); + } + } + } + // add the disposing listener to the factory + Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) ); + if( xComp.is() ) + xComp->addEventListener( getFactoryListener() ); +} + +// helper function +sal_Bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName) +{ + return ( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end()); +} + +// XSet +void OServiceManager::remove( const Any & Element ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException) +{ + if (is_disposed()) + return; + + Reference<XInterface > xEle; + if (Element.getValueTypeClass() == TypeClass_INTERFACE) + { + xEle.set( Element, UNO_QUERY_THROW ); + } + else if (Element.getValueTypeClass() == TypeClass_STRING) + { + OUString const & implName = + *reinterpret_cast< OUString const * >(Element.getValue()); + MutexGuard aGuard( m_mutex ); + HashMap_OWString_Interface::const_iterator const iFind( + m_ImplementationNameMap.find( implName ) ); + if (iFind == m_ImplementationNameMap.end()) + { + throw NoSuchElementException( + OUString( RTL_CONSTASCII_USTRINGPARAM("element is not in: ") ) + + implName, static_cast< OWeakObject * >(this) ); + } + xEle = iFind->second; + } + else + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM( + "neither interface nor string given!") ), + Reference< XInterface >(), 0 ); + } + + // remove the disposing listener from the factory + Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) ); + if( xComp.is() ) + xComp->removeEventListener( getFactoryListener() ); + + MutexGuard aGuard( m_mutex ); + HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle ); + if( aIt == m_ImplementationMap.end() ) + { + throw NoSuchElementException( + OUString( RTL_CONSTASCII_USTRINGPARAM("element is not in!") ), + static_cast< OWeakObject * >(this) ); + } + //First remove all factories which have been loaded by ORegistryServiceManager. + m_SetLoadedFactories.erase( *aIt); + //Remove from the implementation map. It contains all factories of m_SetLoadedFactories + //which have been added directly through XSet, that is not via ORegistryServiceManager + m_ImplementationMap.erase( aIt ); + + // remove from the implementation name hashmap + Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) ); + if( xInfo.is() ) + { + OUString aImplName = xInfo->getImplementationName(); + if( aImplName.getLength() ) + m_ImplementationNameMap.erase( aImplName ); + } + + //remove from the service map + Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) ); + if( xSF.is() ) + { + Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames(); + const OUString * pArray = aServiceNames.getConstArray(); + for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ ) + { + pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> p = + m_ServiceMap.equal_range( pArray[i] ); + + while( p.first != p.second ) + { + if( xEle == (*p.first).second ) + { + m_ServiceMap.erase( p.first ); + break; + } + ++p.first; + } + } + } +} + +/***************************************************************************** + class ORegistryServiceManager +*****************************************************************************/ +class ORegistryServiceManager : public OServiceManager +{ +public: + ORegistryServiceManager( Reference< XComponentContext > const & xContext ); + virtual ~ORegistryServiceManager(); + + // XInitialization + void SAL_CALL initialize(const Sequence< Any >& Arguments) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException) + { return stoc_bootstrap::regsmgr_getImplementationName(); } + + Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // XMultiServiceFactory + Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // XContentEnumerationAccess + //Sequence< OUString > getAvailableServiceNames() throw( (Exception) ); + Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(::com::sun::star::uno::RuntimeException); + virtual Reference<XEnumeration > SAL_CALL createContentEnumeration( + const OUString& aServiceName, Reference< XComponentContext > const & xContext ) + throw(::com::sun::star::uno::RuntimeException); + + // XComponent + void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); + + // OServiceManager + Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() + throw(::com::sun::star::uno::RuntimeException); + Any SAL_CALL getPropertyValue(const OUString& PropertyName) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + +protected: + //OServiceManager + Sequence< Reference< XInterface > > queryServiceFactories( + const OUString& aServiceName, Reference< XComponentContext > const & xContext ); +private: + Reference<XRegistryKey > getRootKey(); + Reference<XInterface > loadWithImplementationName( + const OUString & rImplName, Reference< XComponentContext > const & xContext ); + Sequence<OUString> getFromServiceName(const OUString& serviceName); + Reference<XInterface > loadWithServiceName( + const OUString & rImplName, Reference< XComponentContext > const & xContext ); + void fillAllNamesFromRegistry( HashSet_OWString & ); + + sal_Bool m_searchedRegistry; + Reference<XSimpleRegistry > m_xRegistry; // readonly property Registry + Reference<XRegistryKey > m_xRootKey; + +#if OSL_DEBUG_LEVEL > 0 + bool m_init; +#endif +}; + +/** + * Create a ServiceManager + */ +ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext > const & xContext ) + : OServiceManager( xContext ) + , m_searchedRegistry(sal_False) +#if OSL_DEBUG_LEVEL > 0 + , m_init( false ) +#endif +{ +} + +/** + * Destroy the ServiceManager + */ +ORegistryServiceManager::~ORegistryServiceManager() +{ +} + +// XComponent +void ORegistryServiceManager::dispose() + throw(::com::sun::star::uno::RuntimeException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + return; + OServiceManager::dispose(); + // dispose + MutexGuard aGuard( m_mutex ); + // erase all members + m_xRegistry = Reference<XSimpleRegistry >(); + m_xRootKey = Reference<XRegistryKey >(); +} + +/** + * Return the root key of the registry. The Default registry service is ordered + * if no registry is set. + */ +//Reference<XServiceProvider > create_DefaultRegistry_ServiceProvider(); + +Reference<XRegistryKey > ORegistryServiceManager::getRootKey() +{ + if( !m_xRootKey.is() ) + { + MutexGuard aGuard( m_mutex ); + // DefaultRegistry suchen !!!! + if( !m_xRegistry.is() && !m_searchedRegistry ) + { + // merken, es wird nur einmal gesucht + m_searchedRegistry = sal_True; + + m_xRegistry.set( + createInstanceWithContext( + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.DefaultRegistry") ), + m_xContext ), + UNO_QUERY ); + } + if( m_xRegistry.is() && !m_xRootKey.is() ) + m_xRootKey = m_xRegistry->getRootKey(); + } + + return m_xRootKey; +} + +/** + * Create a service provider from the registry with an implementation name + */ +Reference<XInterface > ORegistryServiceManager::loadWithImplementationName( + const OUString& name, Reference< XComponentContext > const & xContext ) +{ + Reference<XInterface > ret; + + Reference<XRegistryKey > xRootKey = getRootKey(); + if( !xRootKey.is() ) + return ret; + + try + { + OUString implementationName = OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS/") ) + name; + Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName); + + if( xImpKey.is() ) + { + Reference< lang::XMultiServiceFactory > xMgr; + if (xContext.is()) + xMgr.set( xContext->getServiceManager(), UNO_QUERY_THROW ); + else + xMgr.set( this ); + ret = createSingleRegistryFactory( xMgr, name, xImpKey ); + insert( makeAny( ret ) ); + // Remember this factory as loaded in contrast to inserted ( XSet::insert) + // factories. Those loaded factories in this set are candidates for being + // released on an unloading notification. + m_SetLoadedFactories.insert( ret); + } + } + catch (InvalidRegistryException &) + { + } + + return ret; +} + +/** + * Return all implementation out of the registry. + */ +Sequence<OUString> ORegistryServiceManager::getFromServiceName( + const OUString& serviceName ) +{ + OUStringBuffer buf; + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/SERVICES/" ) ); + buf.append( serviceName ); + return retrieveAsciiValueList( m_xRegistry, buf.makeStringAndClear() ); +} + +/** + * Create a service provider from the registry + */ +Reference<XInterface > ORegistryServiceManager::loadWithServiceName( + const OUString& serviceName, Reference< XComponentContext > const & xContext ) +{ + Sequence<OUString> implEntries = getFromServiceName( serviceName ); + for (sal_Int32 i = 0; i < implEntries.getLength(); i++) + { + Reference< XInterface > x( + loadWithImplementationName( implEntries.getConstArray()[i], xContext ) ); + if (x.is()) + return x; + } + + return Reference<XInterface >(); +} + +/** + * Return a sequence of all service names from the registry. + */ +void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet ) +{ + Reference<XRegistryKey > xRootKey = getRootKey(); + if( !xRootKey.is() ) + return; + + try + { + Reference<XRegistryKey > xServicesKey = xRootKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("SERVICES") ) ); + // root + /Services + / + if( xServicesKey.is() ) + { + sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1; + Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys(); + for( sal_Int32 i = 0; i < aKeys.getLength(); i++ ) + rSet.insert( aKeys.getConstArray()[i]->getKeyName().copy( nPrefix ) ); + } + } + catch (InvalidRegistryException &) + { + } +} + +// XInitialization +void ORegistryServiceManager::initialize(const Sequence< Any >& Arguments) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + MutexGuard aGuard( m_mutex ); + if (Arguments.getLength() > 0) + { + m_xRootKey.clear(); + Arguments[ 0 ] >>= m_xRegistry; + } +#if OSL_DEBUG_LEVEL > 0 + // to find all bootstrapping processes to be fixed... + OSL_ENSURE( !m_init, "### second init of service manager instance!" ); + m_init = true; +#endif +} + +// XMultiServiceFactory, XContentEnumeration +Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + MutexGuard aGuard( m_mutex ); + // all names + HashSet_OWString aNameSet; + + // all names from the registry + fillAllNamesFromRegistry( aNameSet ); + + return OServiceManager::getUniqueAvailableServiceNames( aNameSet ); +} + +// XServiceInfo +Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + return stoc_bootstrap::regsmgr_getSupportedServiceNames(); +} + + +// OServiceManager +Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories( + const OUString& aServiceName, Reference< XComponentContext > const & xContext ) +{ + Sequence< Reference< XInterface > > ret( + OServiceManager::queryServiceFactories( aServiceName, xContext ) ); + if (ret.getLength()) + { + return ret; + } + else + { + MutexGuard aGuard( m_mutex ); + Reference< XInterface > x( loadWithServiceName( aServiceName, xContext ) ); + if (! x.is()) + x = loadWithImplementationName( aServiceName, xContext ); + return Sequence< Reference< XInterface > >( &x, 1 ); + } +} + +// XContentEnumerationAccess +Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration( + const OUString& aServiceName, Reference< XComponentContext > const & xContext ) + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + MutexGuard aGuard( ((ORegistryServiceManager *)this)->m_mutex ); + // get all implementation names registered under this service name from the registry + Sequence<OUString> aImpls = ((ORegistryServiceManager *)this)->getFromServiceName( aServiceName ); + // load and insert all factories specified by the registry + sal_Int32 i; + OUString aImplName; + for( i = 0; i < aImpls.getLength(); i++ ) + { + aImplName = aImpls.getConstArray()[i]; + if ( !haveFactoryWithThisImplementation(aImplName) ) + { + loadWithImplementationName( aImplName, xContext ); + } + } + // call the superclass to enumerate all contents + return OServiceManager::createContentEnumeration( aServiceName, xContext ); +} +Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration( + const OUString& aServiceName ) + throw(::com::sun::star::uno::RuntimeException) +{ + return createContentEnumeration( aServiceName, m_xContext ); +} + +// OServiceManager +Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo() + throw(::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + if (! m_xPropertyInfo.is()) + { + Sequence< beans::Property > seq( 2 ); + seq[ 0 ] = beans::Property( + OUSTR("DefaultContext"), -1, ::getCppuType( &m_xContext ), 0 ); + seq[ 1 ] = beans::Property( + OUSTR("Registry"), -1, ::getCppuType( &m_xRegistry ), + beans::PropertyAttribute::READONLY ); + Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) ); + + MutexGuard aGuard( m_mutex ); + if (! m_xPropertyInfo.is()) + { + m_xPropertyInfo = xInfo; + } + } + return m_xPropertyInfo; +} + +Any ORegistryServiceManager::getPropertyValue(const OUString& PropertyName) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + check_undisposed(); + if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Registry") )) + { + MutexGuard aGuard( m_mutex ); + if( m_xRegistry.is() ) + return makeAny( m_xRegistry ); + else + return Any(); + } + return OServiceManager::getPropertyValue( PropertyName ); +} + +/* This is the listener function used by the service manager in order +to implement the unloading mechanism, id is the this pointer of the +service manager instances. On notification, that is the function is being called +by rtl_unloadUnusedModules, the cached factroies are being removed from the +service manager ( except manually inserted factories). +*/ +extern "C" void SAL_CALL smgrUnloadingListener(void* id) +{ + stoc_smgr::OServiceManager* pMgr= reinterpret_cast<stoc_smgr::OServiceManager*>( id); + pMgr->onUnloadingNotify(); +} + +} // namespace + +namespace stoc_bootstrap +{ +/** + * Create the ServiceManager + */ +Reference<XInterface > SAL_CALL OServiceManager_CreateInstance( + const Reference< XComponentContext > & xContext ) +{ + return Reference<XInterface >( + SAL_STATIC_CAST( + XInterface *, SAL_STATIC_CAST( + OWeakObject *, new stoc_smgr::OServiceManager( xContext ) ) ) ); +} + +/** + * Create the ServiceManager + */ +Reference<XInterface > SAL_CALL ORegistryServiceManager_CreateInstance( + const Reference< XComponentContext > & xContext ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + return Reference<XInterface >( + SAL_STATIC_CAST( + XInterface *, SAL_STATIC_CAST( + OWeakObject *, new stoc_smgr::ORegistryServiceManager( xContext ) ) ) ); +} + +Reference<XInterface > SAL_CALL OServiceManagerWrapper_CreateInstance( + const Reference< XComponentContext > & xContext ) + throw (Exception) +{ + return (OWeakObject *)new stoc_smgr::OServiceManagerWrapper( xContext ); +} +} |