| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_cppuhelper.hxx" |
| #include <osl/diagnose.h> |
| #include <osl/mutex.hxx> |
| #include <cppuhelper/weak.hxx> |
| #include <cppuhelper/component.hxx> |
| #include <cppuhelper/factory.hxx> |
| #ifndef _CPPUHELPER_IMPLBASE3_HXX |
| #include <cppuhelper/implbase3.hxx> |
| #endif |
| #include <cppuhelper/typeprovider.hxx> |
| #include <rtl/unload.h> |
| |
| #include "cppuhelper/propshlp.hxx" |
| |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/lang/XSingleServiceFactory.hpp> |
| #include <com/sun/star/lang/XSingleComponentFactory.hpp> |
| #include <com/sun/star/lang/XInitialization.hpp> |
| #include <com/sun/star/loader/XImplementationLoader.hpp> |
| #include <com/sun/star/lang/XComponent.hpp> |
| #include <com/sun/star/lang/IllegalArgumentException.hpp> |
| #include <com/sun/star/uno/XUnloadingPreference.hpp> |
| #include "com/sun/star/beans/PropertyAttribute.hpp" |
| |
| #include <memory> |
| |
| #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) |
| |
| |
| using namespace osl; |
| using namespace rtl; |
| using namespace com::sun::star; |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::lang; |
| using namespace com::sun::star::loader; |
| using namespace com::sun::star::registry; |
| |
| namespace cppu |
| { |
| |
| //----------------------------------------------------------------------------- |
| //----------------------------------------------------------------------------- |
| //----------------------------------------------------------------------------- |
| class OSingleFactoryHelper |
| : public XServiceInfo |
| , public XSingleServiceFactory |
| , public lang::XSingleComponentFactory |
| , public XUnloadingPreference |
| { |
| public: |
| OSingleFactoryHelper( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const OUString & rImplementationName_, |
| ComponentInstantiation pCreateFunction_, |
| ComponentFactoryFunc fptr, |
| const Sequence< OUString > * pServiceNames_ ) |
| SAL_THROW( () ) |
| : xSMgr( rServiceManager ) |
| , pCreateFunction( pCreateFunction_ ) |
| , m_fptr( fptr ) |
| , aImplementationName( rImplementationName_ ) |
| { |
| if( pServiceNames_ ) |
| aServiceNames = *pServiceNames_; |
| } |
| |
| // old function, only for backward compatibility |
| OSingleFactoryHelper( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const OUString & rImplementationName_ ) |
| SAL_THROW( () ) |
| : xSMgr( rServiceManager ) |
| , pCreateFunction( NULL ) |
| , m_fptr( 0 ) |
| , aImplementationName( rImplementationName_ ) |
| {} |
| |
| virtual ~OSingleFactoryHelper(); |
| |
| // XInterface |
| Any SAL_CALL queryInterface( const Type & rType ) |
| throw(::com::sun::star::uno::RuntimeException); |
| |
| // XSingleServiceFactory |
| Reference<XInterface > SAL_CALL createInstance() |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); |
| virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); |
| // XSingleComponentFactory |
| virtual Reference< XInterface > SAL_CALL createInstanceWithContext( |
| Reference< XComponentContext > const & xContext ) |
| throw (Exception, RuntimeException); |
| virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( |
| Sequence< Any > const & rArguments, |
| Reference< XComponentContext > const & xContext ) |
| throw (Exception, RuntimeException); |
| |
| // XServiceInfo |
| OUString SAL_CALL getImplementationName() |
| throw(::com::sun::star::uno::RuntimeException); |
| sal_Bool SAL_CALL supportsService(const OUString& ServiceName) |
| throw(::com::sun::star::uno::RuntimeException); |
| Sequence< OUString > SAL_CALL getSupportedServiceNames(void) |
| throw(::com::sun::star::uno::RuntimeException); |
| |
| protected: |
| /** |
| * Create an instance specified by the factory. The one instance logic is implemented |
| * in the createInstance and createInstanceWithArguments methods. |
| * @return the newly created instance. Do not return a previous (one instance) instance. |
| */ |
| virtual Reference<XInterface > createInstanceEveryTime( |
| Reference< XComponentContext > const & xContext ) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); |
| |
| Reference<XMultiServiceFactory > xSMgr; |
| ComponentInstantiation pCreateFunction; |
| ComponentFactoryFunc m_fptr; |
| Sequence< OUString > aServiceNames; |
| OUString aImplementationName; |
| }; |
| OSingleFactoryHelper::~OSingleFactoryHelper() |
| { |
| } |
| |
| |
| //----------------------------------------------------------------------------- |
| Any OSingleFactoryHelper::queryInterface( const Type & rType ) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return ::cppu::queryInterface( |
| rType, |
| static_cast< XSingleComponentFactory * >( this ), |
| static_cast< XSingleServiceFactory * >( this ), |
| static_cast< XServiceInfo * >( this ) , |
| static_cast< XUnloadingPreference * >( this )); |
| } |
| |
| // OSingleFactoryHelper |
| Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime( |
| Reference< XComponentContext > const & xContext ) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) |
| { |
| if (m_fptr) |
| { |
| return (*m_fptr)( xContext ); |
| } |
| else if( pCreateFunction ) |
| { |
| if (xContext.is()) |
| { |
| Reference< lang::XMultiServiceFactory > xContextMgr( |
| xContext->getServiceManager(), UNO_QUERY ); |
| if (xContextMgr.is()) |
| return (*pCreateFunction)( xContextMgr ); |
| } |
| return (*pCreateFunction)( xSMgr ); |
| } |
| else |
| { |
| return Reference< XInterface >(); |
| } |
| } |
| |
| // XSingleServiceFactory |
| Reference<XInterface > OSingleFactoryHelper::createInstance() |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) |
| { |
| return createInstanceWithContext( Reference< XComponentContext >() ); |
| } |
| |
| // XSingleServiceFactory |
| Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments( |
| const Sequence<Any>& Arguments ) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) |
| { |
| return createInstanceWithArgumentsAndContext( |
| Arguments, Reference< XComponentContext >() ); |
| } |
| |
| // XSingleComponentFactory |
| //__________________________________________________________________________________________________ |
| Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext( |
| Reference< XComponentContext > const & xContext ) |
| throw (Exception, RuntimeException) |
| { |
| return createInstanceEveryTime( xContext ); |
| } |
| //__________________________________________________________________________________________________ |
| Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext( |
| Sequence< Any > const & rArguments, |
| Reference< XComponentContext > const & xContext ) |
| throw (Exception, RuntimeException) |
| { |
| Reference< XInterface > xRet( createInstanceWithContext( xContext ) ); |
| |
| Reference< lang::XInitialization > xInit( xRet, UNO_QUERY ); |
| // always call initialize, even if there are no arguments. |
| // #i63511# / 2006-03-27 / frank.schoenheit@sun.com |
| if (xInit.is()) |
| { |
| xInit->initialize( rArguments ); |
| } |
| else |
| { |
| if ( rArguments.getLength() ) |
| { |
| // dispose the here created UNO object before throwing out exception |
| // to avoid risk of memory leaks #i113722# |
| Reference<XComponent> xComp( xRet, UNO_QUERY ); |
| if (xComp.is()) |
| xComp->dispose(); |
| |
| throw lang::IllegalArgumentException( |
| OUString( RTL_CONSTASCII_USTRINGPARAM("cannot pass arguments to component => no XInitialization implemented!") ), |
| Reference< XInterface >(), 0 ); |
| } |
| } |
| |
| return xRet; |
| } |
| |
| // XServiceInfo |
| OUString OSingleFactoryHelper::getImplementationName() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return aImplementationName; |
| } |
| |
| // XServiceInfo |
| sal_Bool OSingleFactoryHelper::supportsService( |
| const OUString& ServiceName ) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| Sequence< OUString > seqServices = getSupportedServiceNames(); |
| const OUString * pServices = seqServices.getConstArray(); |
| for( sal_Int32 i = 0; i < seqServices.getLength(); i++ ) |
| if( pServices[i] == ServiceName ) |
| return sal_True; |
| |
| return sal_False; |
| } |
| |
| // XServiceInfo |
| Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames(void) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return aServiceNames; |
| } |
| |
| |
| //---------------------------------------------------------------------- |
| //---------------------------------------------------------------------- |
| //---------------------------------------------------------------------- |
| struct OFactoryComponentHelper_Mutex |
| { |
| Mutex aMutex; |
| }; |
| |
| class OFactoryComponentHelper |
| : public OFactoryComponentHelper_Mutex |
| , public OComponentHelper |
| , public OSingleFactoryHelper |
| { |
| public: |
| OFactoryComponentHelper( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const OUString & rImplementationName_, |
| ComponentInstantiation pCreateFunction_, |
| ComponentFactoryFunc fptr, |
| const Sequence< OUString > * pServiceNames_, |
| sal_Bool bOneInstance_ = sal_False ) |
| SAL_THROW( () ) |
| : OComponentHelper( aMutex ) |
| , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ ) |
| , bOneInstance( bOneInstance_ ) |
| , pModuleCount(0) |
| { |
| } |
| |
| // Used by the createXXXFactory functions. The argument pModCount is used to prevent the unloading of the module |
| // which contains pCreateFunction_ |
| OFactoryComponentHelper( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const OUString & rImplementationName_, |
| ComponentInstantiation pCreateFunction_, |
| ComponentFactoryFunc fptr, |
| const Sequence< OUString > * pServiceNames_, |
| rtl_ModuleCount * pModCount, |
| sal_Bool bOneInstance_ = sal_False ) |
| SAL_THROW( () ) |
| : OComponentHelper( aMutex ) |
| , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ ) |
| , bOneInstance( bOneInstance_ ) |
| , pModuleCount(pModCount) |
| { |
| if(pModuleCount) |
| pModuleCount->acquire( pModuleCount); |
| } |
| |
| // old function, only for backward compatibility |
| OFactoryComponentHelper( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const OUString & rImplementationName_, |
| sal_Bool bOneInstance_ = sal_False ) |
| SAL_THROW( () ) |
| : OComponentHelper( aMutex ) |
| , OSingleFactoryHelper( rServiceManager, rImplementationName_ ) |
| , bOneInstance( bOneInstance_ ) |
| , pModuleCount(0) |
| { |
| } |
| |
| ~OFactoryComponentHelper() |
| { |
| if(pModuleCount) |
| pModuleCount->release( pModuleCount); |
| } |
| |
| // XInterface |
| Any SAL_CALL queryInterface( const Type & rType ) |
| throw(::com::sun::star::uno::RuntimeException); |
| void SAL_CALL acquire() throw() |
| { OComponentHelper::acquire(); } |
| void SAL_CALL release() throw() |
| { OComponentHelper::release(); } |
| |
| // XSingleServiceFactory |
| Reference<XInterface > SAL_CALL createInstance() |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); |
| Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments ) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); |
| // XSingleComponentFactory |
| virtual Reference< XInterface > SAL_CALL createInstanceWithContext( |
| Reference< XComponentContext > const & xContext ) |
| throw (Exception, RuntimeException); |
| virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( |
| Sequence< Any > const & rArguments, |
| Reference< XComponentContext > const & xContext ) |
| throw (Exception, RuntimeException); |
| |
| // XTypeProvider |
| virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); |
| virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); |
| |
| // XAggregation |
| Any SAL_CALL queryAggregation( const Type & rType ) |
| throw(::com::sun::star::uno::RuntimeException); |
| |
| // XUnloadingPreference |
| virtual sal_Bool SAL_CALL releaseOnNotification() |
| throw(::com::sun::star::uno::RuntimeException); |
| |
| // OComponentHelper |
| void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); |
| |
| private: |
| Reference<XInterface > xTheInstance; |
| sal_Bool bOneInstance; |
| rtl_ModuleCount * pModuleCount; |
| protected: |
| // needed for implementing XUnloadingPreference in inheriting classes |
| sal_Bool isOneInstance() {return bOneInstance;} |
| sal_Bool isInstance() {return xTheInstance.is();} |
| }; |
| |
| |
| Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType ) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| if( rType == ::getCppuType( (Reference<XUnloadingPreference>*)0)) |
| { |
| return makeAny( |
| Reference< XUnloadingPreference >( |
| static_cast< XUnloadingPreference * >(this) ) ); |
| } |
| return OComponentHelper::queryInterface( rType ); |
| } |
| |
| // XAggregation |
| Any OFactoryComponentHelper::queryAggregation( const Type & rType ) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| Any aRet( OComponentHelper::queryAggregation( rType ) ); |
| return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType )); |
| } |
| |
| // XTypeProvider |
| Sequence< Type > OFactoryComponentHelper::getTypes() |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| Type ar[ 4 ]; |
| ar[ 0 ] = ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ); |
| ar[ 1 ] = ::getCppuType( (const Reference< XServiceInfo > *)0 ); |
| ar[ 2 ] = ::getCppuType( (const Reference< XUnloadingPreference > *)0 ); |
| |
| if (m_fptr) |
| ar[ 3 ] = ::getCppuType( (const Reference< XSingleComponentFactory > *)0 ); |
| |
| return Sequence< Type >( ar, m_fptr ? 4 : 3 ); |
| } |
| |
| Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId() |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| static OImplementationId * pId = 0; |
| if (! pId) |
| { |
| MutexGuard aGuard( Mutex::getGlobalMutex() ); |
| if (! pId) |
| { |
| static OImplementationId aId; |
| pId = &aId; |
| } |
| } |
| return pId->getImplementationId(); |
| } |
| |
| // XSingleServiceFactory |
| Reference<XInterface > OFactoryComponentHelper::createInstance() |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) |
| { |
| if( bOneInstance ) |
| { |
| if( !xTheInstance.is() ) |
| { |
| MutexGuard aGuard( aMutex ); |
| if( !xTheInstance.is() ) |
| xTheInstance = OSingleFactoryHelper::createInstance(); |
| } |
| return xTheInstance; |
| } |
| return OSingleFactoryHelper::createInstance(); |
| } |
| |
| Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments( |
| const Sequence<Any>& Arguments ) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) |
| { |
| if( bOneInstance ) |
| { |
| if( !xTheInstance.is() ) |
| { |
| MutexGuard aGuard( aMutex ); |
| // OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" ); |
| if( !xTheInstance.is() ) |
| xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments ); |
| } |
| return xTheInstance; |
| } |
| return OSingleFactoryHelper::createInstanceWithArguments( Arguments ); |
| } |
| |
| // XSingleComponentFactory |
| //__________________________________________________________________________________________________ |
| Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext( |
| Reference< XComponentContext > const & xContext ) |
| throw (Exception, RuntimeException) |
| { |
| if( bOneInstance ) |
| { |
| if( !xTheInstance.is() ) |
| { |
| MutexGuard aGuard( aMutex ); |
| // OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" ); |
| if( !xTheInstance.is() ) |
| xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext ); |
| } |
| return xTheInstance; |
| } |
| return OSingleFactoryHelper::createInstanceWithContext( xContext ); |
| } |
| //__________________________________________________________________________________________________ |
| Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext( |
| Sequence< Any > const & rArguments, |
| Reference< XComponentContext > const & xContext ) |
| throw (Exception, RuntimeException) |
| { |
| if( bOneInstance ) |
| { |
| if( !xTheInstance.is() ) |
| { |
| MutexGuard aGuard( aMutex ); |
| // OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" ); |
| if( !xTheInstance.is() ) |
| xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext ); |
| } |
| return xTheInstance; |
| } |
| return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext ); |
| } |
| |
| |
| // OComponentHelper |
| void OFactoryComponentHelper::dispose() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| OComponentHelper::dispose(); |
| |
| Reference<XInterface > x; |
| { |
| // do not delete in the guard section |
| MutexGuard aGuard( aMutex ); |
| x = xTheInstance; |
| xTheInstance = Reference<XInterface >(); |
| } |
| // if it is a component call dispose at the component |
| Reference<XComponent > xComp( x, UNO_QUERY ); |
| if( xComp.is() ) |
| xComp->dispose(); |
| } |
| |
| // XUnloadingPreference |
| // This class is used for single factories, component factories and |
| // one-instance factories. Depending on the usage this function has |
| // to return different values. |
| // one-instance factory: sal_False |
| // single factory: sal_True |
| // component factory: sal_True |
| sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException) |
| { |
| if( bOneInstance) |
| return sal_False; |
| return sal_True; |
| } |
| |
| |
| //----------------------------------------------------------------------------- |
| //----------------------------------------------------------------------------- |
| //----------------------------------------------------------------------------- |
| class ORegistryFactoryHelper : public OFactoryComponentHelper, |
| public OPropertySetHelper |
| |
| { |
| public: |
| ORegistryFactoryHelper( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const OUString & rImplementationName_, |
| const Reference<XRegistryKey > & xImplementationKey_, |
| sal_Bool bOneInstance_ = sal_False ) SAL_THROW( () ) |
| : OFactoryComponentHelper( |
| rServiceManager, rImplementationName_, 0, 0, 0, bOneInstance_ ), |
| OPropertySetHelper( OComponentHelper::rBHelper ), |
| xImplementationKey( xImplementationKey_ ) |
| {} |
| |
| // XInterface |
| virtual Any SAL_CALL queryInterface( Type const & type ) |
| throw (RuntimeException); |
| virtual void SAL_CALL acquire() throw (); |
| virtual void SAL_CALL release() throw (); |
| // XTypeProvider |
| virtual Sequence< Type > SAL_CALL getTypes() |
| throw (RuntimeException); |
| // XPropertySet |
| virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() |
| throw (RuntimeException); |
| |
| // OPropertySetHelper |
| virtual IPropertyArrayHelper & SAL_CALL getInfoHelper(); |
| virtual sal_Bool SAL_CALL convertFastPropertyValue( |
| Any & rConvertedValue, Any & rOldValue, |
| sal_Int32 nHandle, Any const & rValue ) |
| throw (lang::IllegalArgumentException); |
| virtual void SAL_CALL setFastPropertyValue_NoBroadcast( |
| sal_Int32 nHandle, Any const & rValue ) |
| throw (Exception); |
| using OPropertySetHelper::getFastPropertyValue; |
| virtual void SAL_CALL getFastPropertyValue( |
| Any & rValue, sal_Int32 nHandle ) const; |
| |
| // OSingleFactoryHelper |
| Reference<XInterface > createInstanceEveryTime( |
| Reference< XComponentContext > const & xContext ) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); |
| |
| // XSingleServiceFactory |
| Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); |
| // XSingleComponentFactory |
| Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( |
| Sequence< Any > const & rArguments, |
| Reference< XComponentContext > const & xContext ) |
| throw (Exception, RuntimeException); |
| |
| // XServiceInfo |
| Sequence< OUString > SAL_CALL getSupportedServiceNames(void) |
| throw(::com::sun::star::uno::RuntimeException); |
| // XUnloadingPreference |
| sal_Bool SAL_CALL releaseOnNotification() |
| throw( RuntimeException); |
| |
| |
| private: |
| Reference< XInterface > createModuleFactory() |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); |
| |
| /** The registry key of the implementation section */ |
| Reference<XRegistryKey > xImplementationKey; |
| /** The factory created with the loader. */ |
| Reference<XSingleComponentFactory > xModuleFactory; |
| Reference<XSingleServiceFactory > xModuleFactoryDepr; |
| Reference< beans::XPropertySetInfo > m_xInfo; |
| ::std::auto_ptr< IPropertyArrayHelper > m_property_array_helper; |
| protected: |
| using OPropertySetHelper::getTypes; |
| }; |
| |
| // XInterface |
| //______________________________________________________________________________ |
| Any SAL_CALL ORegistryFactoryHelper::queryInterface( |
| Type const & type ) throw (RuntimeException) |
| { |
| Any ret( OFactoryComponentHelper::queryInterface( type ) ); |
| if (ret.hasValue()) |
| return ret; |
| else |
| return OPropertySetHelper::queryInterface( type ); |
| } |
| |
| //______________________________________________________________________________ |
| void ORegistryFactoryHelper::acquire() throw () |
| { |
| OFactoryComponentHelper::acquire(); |
| } |
| |
| //______________________________________________________________________________ |
| void ORegistryFactoryHelper::release() throw () |
| { |
| OFactoryComponentHelper::release(); |
| } |
| |
| // XTypeProvider |
| //______________________________________________________________________________ |
| Sequence< Type > ORegistryFactoryHelper::getTypes() throw (RuntimeException) |
| { |
| Sequence< Type > types( OFactoryComponentHelper::getTypes() ); |
| sal_Int32 pos = types.getLength(); |
| types.realloc( pos + 3 ); |
| Type * p = types.getArray(); |
| p[ pos++ ] = ::getCppuType( |
| reinterpret_cast< Reference< beans::XMultiPropertySet > const * >(0) ); |
| p[ pos++ ] = ::getCppuType( |
| reinterpret_cast< Reference< beans::XFastPropertySet > const * >(0) ); |
| p[ pos++ ] = ::getCppuType( |
| reinterpret_cast< Reference< beans::XPropertySet > const * >(0) ); |
| return types; |
| } |
| |
| // XPropertySet |
| //______________________________________________________________________________ |
| Reference< beans::XPropertySetInfo > |
| ORegistryFactoryHelper::getPropertySetInfo() throw (RuntimeException) |
| { |
| ::osl::MutexGuard guard( aMutex ); |
| if (! m_xInfo.is()) |
| m_xInfo = createPropertySetInfo( getInfoHelper() ); |
| return m_xInfo; |
| } |
| |
| // OPropertySetHelper |
| //______________________________________________________________________________ |
| IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper() |
| { |
| ::osl::MutexGuard guard( aMutex ); |
| if (m_property_array_helper.get() == 0) |
| { |
| beans::Property prop( |
| OUSTR("ImplementationKey") /* name */, |
| 0 /* handle */, |
| ::getCppuType( &xImplementationKey ), |
| beans::PropertyAttribute::READONLY | |
| beans::PropertyAttribute::OPTIONAL ); |
| m_property_array_helper.reset( |
| new ::cppu::OPropertyArrayHelper( &prop, 1 ) ); |
| } |
| return *m_property_array_helper.get(); |
| } |
| |
| //______________________________________________________________________________ |
| sal_Bool ORegistryFactoryHelper::convertFastPropertyValue( |
| Any &, Any &, sal_Int32, Any const & ) |
| throw (lang::IllegalArgumentException) |
| { |
| OSL_ENSURE( 0, "unexpected!" ); |
| return false; |
| } |
| |
| //______________________________________________________________________________ |
| void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast( |
| sal_Int32, Any const & ) |
| throw (Exception) |
| { |
| throw beans::PropertyVetoException( |
| OUSTR("unexpected: only readonly properties!"), |
| static_cast< OWeakObject * >(this) ); |
| } |
| |
| //______________________________________________________________________________ |
| void ORegistryFactoryHelper::getFastPropertyValue( |
| Any & rValue, sal_Int32 nHandle ) const |
| { |
| if (nHandle == 0) |
| { |
| rValue <<= xImplementationKey; |
| } |
| else |
| { |
| rValue.clear(); |
| throw beans::UnknownPropertyException( |
| OUSTR("unknown property!"), static_cast< OWeakObject * >( |
| const_cast< ORegistryFactoryHelper * >(this) ) ); |
| } |
| } |
| |
| Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime( |
| Reference< XComponentContext > const & xContext ) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) |
| { |
| if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) |
| { |
| Reference< XInterface > x( createModuleFactory() ); |
| if (x.is()) |
| { |
| MutexGuard aGuard( aMutex ); |
| if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) |
| { |
| xModuleFactory.set( x, UNO_QUERY ); |
| xModuleFactoryDepr.set( x, UNO_QUERY ); |
| } |
| } |
| } |
| if( xModuleFactory.is() ) |
| { |
| return xModuleFactory->createInstanceWithContext( xContext ); |
| } |
| else if( xModuleFactoryDepr.is() ) |
| { |
| return xModuleFactoryDepr->createInstance(); |
| } |
| |
| return Reference<XInterface >(); |
| } |
| |
| Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments( |
| const Sequence<Any>& Arguments ) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) |
| { |
| if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) |
| { |
| Reference< XInterface > x( createModuleFactory() ); |
| if (x.is()) |
| { |
| MutexGuard aGuard( aMutex ); |
| if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) |
| { |
| xModuleFactory.set( x, UNO_QUERY ); |
| xModuleFactoryDepr.set( x, UNO_QUERY ); |
| } |
| } |
| } |
| if( xModuleFactoryDepr.is() ) |
| { |
| return xModuleFactoryDepr->createInstanceWithArguments( Arguments ); |
| } |
| else if( xModuleFactory.is() ) |
| { |
| #if OSL_DEBUG_LEVEL > 1 |
| OSL_TRACE( "### no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!\n" ); |
| #endif |
| return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() ); |
| } |
| |
| return Reference<XInterface >(); |
| } |
| |
| Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext( |
| Sequence< Any > const & rArguments, |
| Reference< XComponentContext > const & xContext ) |
| throw (Exception, RuntimeException) |
| { |
| if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) |
| { |
| Reference< XInterface > x( createModuleFactory() ); |
| if (x.is()) |
| { |
| MutexGuard aGuard( aMutex ); |
| if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) |
| { |
| xModuleFactory.set( x, UNO_QUERY ); |
| xModuleFactoryDepr.set( x, UNO_QUERY ); |
| } |
| } |
| } |
| if( xModuleFactory.is() ) |
| { |
| return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext ); |
| } |
| else if( xModuleFactoryDepr.is() ) |
| { |
| #if OSL_DEBUG_LEVEL > 1 |
| if (xContext.is()) |
| { |
| OSL_TRACE( "### ignoring context calling ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!\n" ); |
| } |
| #endif |
| return xModuleFactoryDepr->createInstanceWithArguments( rArguments ); |
| } |
| |
| return Reference<XInterface >(); |
| } |
| |
| |
| // OSingleFactoryHelper |
| Reference< XInterface > ORegistryFactoryHelper::createModuleFactory() |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) |
| { |
| OUString aActivatorUrl; |
| OUString aActivatorName; |
| OUString aLocation; |
| |
| Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey( |
| OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") ) ); |
| if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII ) |
| { |
| aActivatorUrl = xActivatorKey->getAsciiValue(); |
| |
| OUString tmpActivator(aActivatorUrl.getStr()); |
| sal_Int32 nIndex = 0; |
| aActivatorName = tmpActivator.getToken(0, ':', nIndex ); |
| |
| Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey( |
| OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") ) ); |
| if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII ) |
| aLocation = xLocationKey->getAsciiValue(); |
| } |
| else |
| { |
| // old style"url" |
| // the location of the program code of the implementation |
| Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey( |
| OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/URL") ) ); |
| // is the the key of the right type ? |
| if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII ) |
| { |
| // one implementation found -> try to activate |
| aLocation = xLocationKey->getAsciiValue(); |
| |
| // search protocol delemitter |
| sal_Int32 nPos = aLocation.indexOf( |
| OUString( RTL_CONSTASCII_USTRINGPARAM("://") ) ); |
| if( nPos != -1 ) |
| { |
| aActivatorName = aLocation.copy( 0, nPos ); |
| if( aActivatorName.compareToAscii( "java" ) == 0 ) |
| aActivatorName = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.Java") ); |
| else if( aActivatorName.compareToAscii( "module" ) == 0 ) |
| aActivatorName = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary") ); |
| aLocation = aLocation.copy( nPos + 3 ); |
| } |
| } |
| } |
| |
| Reference< XInterface > xFactory; |
| if( aActivatorName.getLength() != 0 ) |
| { |
| Reference<XInterface > x = xSMgr->createInstance( aActivatorName ); |
| Reference<XImplementationLoader > xLoader( x, UNO_QUERY ); |
| Reference<XInterface > xMF; |
| if (xLoader.is()) |
| { |
| xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey ); |
| } |
| } |
| return xFactory; |
| } |
| |
| // XServiceInfo |
| Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames(void) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| MutexGuard aGuard( aMutex ); |
| if( aServiceNames.getLength() == 0 ) |
| { |
| // not yet loaded |
| try |
| { |
| Reference<XRegistryKey > xKey = xImplementationKey->openKey( |
| OUString( RTL_CONSTASCII_USTRINGPARAM("UNO/SERVICES") ) ); |
| |
| if (xKey.is()) |
| { |
| // length of prefix. +1 for the '/' at the end |
| sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1; |
| |
| // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..." |
| Sequence<OUString> seqKeys = xKey->getKeyNames(); |
| OUString* pKeys = seqKeys.getArray(); |
| for( sal_Int32 i = 0; i < seqKeys.getLength(); i++ ) |
| pKeys[i] = pKeys[i].copy(nPrefixLen); |
| |
| aServiceNames = seqKeys; |
| } |
| } |
| catch (InvalidRegistryException &) |
| { |
| } |
| } |
| return aServiceNames; |
| } |
| |
| sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException) |
| { |
| sal_Bool retVal= sal_True; |
| if( isOneInstance() && isInstance()) |
| { |
| retVal= sal_False; |
| } |
| else if( ! isOneInstance()) |
| { |
| // try to delegate |
| if( xModuleFactory.is()) |
| { |
| Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY); |
| if( xunloading.is()) |
| retVal= xunloading->releaseOnNotification(); |
| } |
| else if( xModuleFactoryDepr.is()) |
| { |
| Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY); |
| if( xunloading.is()) |
| retVal= xunloading->releaseOnNotification(); |
| } |
| } |
| return retVal; |
| } |
| |
| //----------------------------------------------------------------------------- |
| //----------------------------------------------------------------------------- |
| //----------------------------------------------------------------------------- |
| |
| class OFactoryProxyHelper : public WeakImplHelper3< XServiceInfo, XSingleServiceFactory, |
| XUnloadingPreference > |
| { |
| Reference<XSingleServiceFactory > xFactory; |
| |
| public: |
| |
| OFactoryProxyHelper( |
| const Reference<XMultiServiceFactory > & /*rServiceManager*/, |
| const Reference<XSingleServiceFactory > & rFactory ) |
| SAL_THROW( () ) |
| : xFactory( rFactory ) |
| {} |
| |
| // XSingleServiceFactory |
| Reference<XInterface > SAL_CALL createInstance() |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); |
| Reference<XInterface > SAL_CALL createInstanceWithArguments(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); |
| sal_Bool SAL_CALL supportsService(const OUString& ServiceName) |
| throw(::com::sun::star::uno::RuntimeException); |
| Sequence< OUString > SAL_CALL getSupportedServiceNames(void) |
| throw(::com::sun::star::uno::RuntimeException); |
| //XUnloadingPreference |
| sal_Bool SAL_CALL releaseOnNotification() |
| throw(::com::sun::star::uno::RuntimeException); |
| |
| }; |
| |
| // XSingleServiceFactory |
| Reference<XInterface > OFactoryProxyHelper::createInstance() |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) |
| { |
| return xFactory->createInstance(); |
| } |
| |
| // XSingleServiceFactory |
| Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments |
| ( |
| const Sequence<Any>& Arguments |
| ) |
| throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) |
| { |
| return xFactory->createInstanceWithArguments( Arguments ); |
| } |
| |
| // XServiceInfo |
| OUString OFactoryProxyHelper::getImplementationName() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY ); |
| if( xInfo.is() ) |
| return xInfo->getImplementationName(); |
| return OUString(); |
| } |
| |
| // XServiceInfo |
| sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY ); |
| if( xInfo.is() ) |
| return xInfo->supportsService( ServiceName ); |
| return sal_False; |
| } |
| |
| // XServiceInfo |
| Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames(void) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY ); |
| if( xInfo.is() ) |
| return xInfo->getSupportedServiceNames(); |
| return Sequence< OUString >(); |
| } |
| |
| sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException) |
| { |
| |
| Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY); |
| if( pref.is()) |
| return pref->releaseOnNotification(); |
| return sal_True; |
| } |
| |
| |
| //----------------------------------------------------------------------------- |
| //----------------------------------------------------------------------------- |
| //----------------------------------------------------------------------------- |
| // global function |
| Reference<XSingleServiceFactory > SAL_CALL createSingleFactory( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const OUString & rImplementationName, |
| ComponentInstantiation pCreateFunction, |
| const Sequence< OUString > & rServiceNames, |
| rtl_ModuleCount *pModCount ) |
| SAL_THROW( () ) |
| { |
| return new OFactoryComponentHelper( |
| rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_False ); |
| } |
| |
| // global function |
| Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const Reference<XSingleServiceFactory > & rFactory ) |
| SAL_THROW( () ) |
| { |
| return new OFactoryProxyHelper( |
| rServiceManager, rFactory ); |
| } |
| |
| // global function |
| Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const OUString & rImplementationName, |
| ComponentInstantiation pCreateFunction, |
| const Sequence< OUString > & rServiceNames, |
| rtl_ModuleCount *pModCount ) |
| SAL_THROW( () ) |
| { |
| return new OFactoryComponentHelper( |
| rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_True ); |
| // return new OFactoryUnloadableComponentHelper( |
| // rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_True ); |
| } |
| |
| // global function |
| Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const OUString & rImplementationName, |
| const Reference<XRegistryKey > & rImplementationKey ) |
| SAL_THROW( () ) |
| { |
| return new ORegistryFactoryHelper( |
| rServiceManager, rImplementationName, rImplementationKey, sal_False ); |
| } |
| |
| // global function |
| Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory( |
| const Reference<XMultiServiceFactory > & rServiceManager, |
| const OUString & rImplementationName, |
| const Reference<XRegistryKey > & rImplementationKey ) |
| SAL_THROW( () ) |
| { |
| return new ORegistryFactoryHelper( |
| rServiceManager, rImplementationName, rImplementationKey, sal_True ); |
| } |
| |
| //################################################################################################## |
| Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory( |
| ComponentFactoryFunc fptr, |
| OUString const & rImplementationName, |
| Sequence< OUString > const & rServiceNames, |
| rtl_ModuleCount * pModCount) |
| SAL_THROW( () ) |
| { |
| return new OFactoryComponentHelper( |
| Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, pModCount, sal_False ); |
| } |
| |
| Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory( |
| ComponentFactoryFunc fptr, |
| OUString const & rImplementationName, |
| Sequence< OUString > const & rServiceNames, |
| rtl_ModuleCount * pModCount) |
| SAL_THROW( () ) |
| { |
| return new OFactoryComponentHelper( |
| Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, pModCount, sal_True ); |
| } |
| |
| } |
| |
| |