Files
libreoffice/stoc/source/servicemanager/servicemanager.cxx

1707 lines
62 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2012-06-28 21:09:53 +01:00
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
2000-09-18 14:29:57 +00:00
#include <osl/mutex.hxx>
#include <osl/diagnose.h>
#include <rtl/ustrbuf.hxx>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
2000-09-18 14:29:57 +00:00
#include <uno/mapping.hxx>
#include <uno/dispatcher.h>
#include <cppuhelper/queryinterface.hxx>
#include <cppuhelper/weakref.hxx>
#include <cppuhelper/component.hxx>
#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/implementationentry.hxx>
#include <cppuhelper/component_context.hxx>
#include <cppuhelper/bootstrap.hxx>
#include <cppuhelper/compbase6.hxx>
#include <cppuhelper/compbase7.hxx>
#include <cppuhelper/supportsservice.hxx>
2000-09-18 14:29:57 +00:00
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
2000-09-18 14:29:57 +00:00
#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>
2000-09-18 14:29:57 +00:00
#include <com/sun/star/beans/XPropertySet.hpp>
2002-11-07 14:46:09 +00:00
#include <com/sun/star/beans/PropertyAttribute.hpp>
2000-09-18 14:29:57 +00:00
#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>
2001-06-18 09:32:32 +00:00
#include <com/sun/star/uno/XUnloadingPreference.hpp>
2000-09-18 14:29:57 +00:00
using namespace com::sun::star;
2000-09-18 14:29:57 +00:00
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 std;
namespace {
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;
}
2001-06-18 09:32:32 +00:00
2000-09-18 14:29:57 +00:00
/*****************************************************************************
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 boost::unordered_set
2000-09-18 14:29:57 +00:00
<
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 )
{}
virtual ~ServiceEnumeration_Impl() {}
2000-09-18 14:29:57 +00:00
// 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 ) );
}
2002-11-07 14:46:09 +00:00
//==================================================================================================
class PropertySetInfo_Impl : public WeakImplHelper1< beans::XPropertySetInfo >
{
Sequence< beans::Property > m_properties;
public:
2012-01-26 16:00:09 +01:00
inline PropertySetInfo_Impl( Sequence< beans::Property > const & properties ) SAL_THROW(())
2002-11-07 14:46:09 +00:00
: 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(
"unknown property: " + name, Reference< XInterface >() );
2002-11-07 14:46:09 +00:00
}
//__________________________________________________________________________________________________
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;
}
2000-09-18 14:29:57 +00:00
/*****************************************************************************
Enumeration by implementation
*****************************************************************************/
class ImplementationEnumeration_Impl : public WeakImplHelper1< XEnumeration >
{
public:
ImplementationEnumeration_Impl( const HashSet_Ref & rImplementationMap )
: aImplementationMap( rImplementationMap )
, aIt( aImplementationMap.begin() )
{}
2000-09-18 14:29:57 +00:00
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;
Reference<XInterface > xNext;
};
ImplementationEnumeration_Impl::~ImplementationEnumeration_Impl() {}
2000-09-18 14:29:57 +00:00
// 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 boost::unordered_set
2000-09-18 14:29:57 +00:00
<
OUString,
hashOWString_Impl,
equalOWString_Impl
> HashSet_OWString;
typedef boost::unordered_multimap
2000-09-18 14:29:57 +00:00
<
OUString,
Reference<XInterface >,
hashOWString_Impl,
equalOWString_Impl
> HashMultimap_OWString_Interface;
typedef boost::unordered_map
2000-09-18 14:29:57 +00:00
<
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 & )
{
2011-04-13 09:49:52 +01:00
OSL_FAIL( "IllegalArgumentException caught" );
2000-09-18 14:29:57 +00:00
}
catch( const NoSuchElementException & )
{
2011-04-13 09:49:52 +01:00
OSL_FAIL( "NoSuchElementException caught" );
2000-09-18 14:29:57 +00:00
}
}
}
/*****************************************************************************
class OServiceManager
*****************************************************************************/
struct OServiceManagerMutex
{
Mutex m_mutex;
2000-09-18 14:29:57 +00:00
};
typedef WeakComponentImplHelper7<
lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
lang::XInitialization,
container::XSet, container::XContentEnumerationAccess,
beans::XPropertySet > t_OServiceManager_impl;
2000-09-18 14:29:57 +00:00
class OServiceManager
: public OServiceManagerMutex
, public t_OServiceManager_impl
2000-09-18 14:29:57 +00:00
{
public:
OServiceManager( Reference< XComponentContext > const & xContext );
virtual ~OServiceManager();
2000-09-18 14:29:57 +00:00
// XInitialization
void SAL_CALL initialize( Sequence< Any > const & args )
throw (Exception);
2000-09-18 14:29:57 +00:00
// XServiceInfo
virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
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);
2000-09-18 14:29:57 +00:00
// 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 );
2000-09-18 14:29:57 +00:00
// 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);
// 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);
2000-09-18 14:29:57 +00:00
protected:
inline bool is_disposed() const SAL_THROW( (lang::DisposedException) );
inline void check_undisposed() const SAL_THROW( (lang::DisposedException) );
virtual void SAL_CALL disposing();
2001-06-18 09:32:32 +00:00
2000-09-18 14:29:57 +00:00
sal_Bool haveFactoryWithThisImplementation(const OUString& aImplName);
virtual Sequence< Reference< XInterface > > queryServiceFactories(
const OUString& aServiceName, Reference< XComponentContext > const & xContext );
2000-09-18 14:29:57 +00:00
Reference< XComponentContext > m_xContext;
2002-11-07 14:46:09 +00:00
Reference< beans::XPropertySetInfo > m_xPropertyInfo;
// factories which have been loaded and not inserted( by XSet::insert)
// are remembered by this set.
HashSet_Ref m_SetLoadedFactories;
private:
2001-06-18 09:32:32 +00:00
2000-09-18 14:29:57 +00:00
Reference<XEventListener > getFactoryListener();
2000-09-18 14:29:57 +00:00
HashMultimap_OWString_Interface m_ServiceMap;
HashSet_Ref m_ImplementationMap;
HashMap_OWString_Interface m_ImplementationNameMap;
Reference<XEventListener > xFactoryListener;
bool m_bInDisposing;
2000-09-18 14:29:57 +00:00
};
//______________________________________________________________________________
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(
"service manager instance has already been disposed!",
(OWeakObject *)this );
}
}
2000-09-18 14:29:57 +00:00
//##################################################################################################
//##################################################################################################
//##################################################################################################
typedef WeakComponentImplHelper6<
lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
container::XSet, container::XContentEnumerationAccess,
beans::XPropertySet > t_OServiceManagerWrapper_impl;
class OServiceManagerWrapper : public OServiceManagerMutex, public t_OServiceManagerWrapper_impl
{
Reference< XComponentContext > m_xContext;
Reference< XMultiComponentFactory > m_root;
inline Reference< XMultiComponentFactory > getRoot() SAL_THROW( (RuntimeException) )
{
if (! m_root.is())
{
throw lang::DisposedException(
"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) );
2012-01-26 16:00:09 +01:00
virtual ~OServiceManagerWrapper() SAL_THROW(());
// XServiceInfo
virtual OUString SAL_CALL getImplementationName() throw (RuntimeException)
{ return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getImplementationName(); }
virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (RuntimeException)
{ return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->supportsService( ServiceName ); }
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException)
{ return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->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 Reference< XElementAccess >(getRoot(), UNO_QUERY_THROW)->getElementType(); }
virtual sal_Bool SAL_CALL hasElements() throw (RuntimeException)
{ return Reference< XElementAccess >(getRoot(), UNO_QUERY_THROW)->hasElements(); }
// XEnumerationAccess
virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw (RuntimeException)
{ return Reference< XEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createEnumeration(); }
// XSet
virtual sal_Bool SAL_CALL has( const Any & Element ) throw (RuntimeException)
{ return Reference< XSet >(getRoot(), UNO_QUERY_THROW)->has( Element ); }
virtual void SAL_CALL insert( const Any & Element ) throw (lang::IllegalArgumentException, container::ElementExistException, RuntimeException)
{ Reference< XSet >(getRoot(), UNO_QUERY_THROW)->insert( Element ); }
virtual void SAL_CALL remove( const Any & Element ) throw (lang::IllegalArgumentException, container::NoSuchElementException, RuntimeException)
{ Reference< XSet >(getRoot(), UNO_QUERY_THROW)->remove( Element ); }
// XContentEnumerationAccess
//Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw (RuntimeException)
{ return Reference< XContentEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createContentEnumeration( aServiceName ); }
// XPropertySet
Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() throw (RuntimeException)
{ return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->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)
{ Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->addPropertyChangeListener( PropertyName, aListener ); }
void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
{ Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->removePropertyChangeListener( PropertyName, aListener ); }
void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
{ Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->addVetoableChangeListener( PropertyName, aListener ); }
void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
{ Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->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 == "DefaultContext" )
{
Reference< XComponentContext > xContext;
if (aValue >>= xContext)
{
MutexGuard aGuard( m_mutex );
m_xContext = xContext;
}
else
{
throw IllegalArgumentException(
OUString("no XComponentContext given!"),
(OWeakObject *)this, 1 );
}
}
else
{
Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->setPropertyValue( PropertyName, aValue );
}
}
//__________________________________________________________________________________________________
Any SAL_CALL OServiceManagerWrapper::getPropertyValue(
const OUString& PropertyName )
throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
{
if ( PropertyName == "DefaultContext" )
{
MutexGuard aGuard( m_mutex );
if( m_xContext.is() )
return makeAny( m_xContext );
else
return Any();
}
else
{
return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertyValue( PropertyName );
}
}
//__________________________________________________________________________________________________
void OServiceManagerWrapper::disposing()
{
m_xContext.clear();
// no m_root->dispose(), because every context disposes its service manager...
m_root.clear();
}
//__________________________________________________________________________________________________
OServiceManagerWrapper::~OServiceManagerWrapper() SAL_THROW(()) {}
//__________________________________________________________________________________________________
OServiceManagerWrapper::OServiceManagerWrapper(
Reference< XComponentContext > const & xContext )
SAL_THROW( (RuntimeException) )
: t_OServiceManagerWrapper_impl( m_mutex )
, m_xContext( xContext )
, m_root( xContext->getServiceManager() )
{
if (! m_root.is())
{
throw RuntimeException(
OUString("no service manager to wrap"),
Reference< XInterface >() );
}
}
//##################################################################################################
//##################################################################################################
//##################################################################################################
2000-09-18 14:29:57 +00:00
/**
* Create a ServiceManager
*/
OServiceManager::OServiceManager( Reference< XComponentContext > const & xContext )
: t_OServiceManager_impl( m_mutex )
, m_xContext( xContext )
, m_bInDisposing( false )
{}
2000-09-18 14:29:57 +00:00
/**
* Destroy the ServiceManager
*/
OServiceManager::~OServiceManager() {}
2000-09-18 14:29:57 +00:00
// XComponent
2000-09-18 14:29:57 +00:00
void OServiceManager::dispose()
throw(::com::sun::star::uno::RuntimeException)
{
if (rBHelper.bDisposed || rBHelper.bInDispose)
return;
t_OServiceManager_impl::dispose();
}
2000-09-18 14:29:57 +00:00
void OServiceManager::disposing()
{
2000-09-18 14:29:57 +00:00
// dispose all factories
HashSet_Ref aImpls;
{
MutexGuard aGuard( m_mutex );
m_bInDisposing = true;
2000-09-18 14:29:57 +00:00
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();
}
2011-12-27 00:12:38 +09:00
catch (const RuntimeException & exc)
{
#if OSL_DEBUG_LEVEL > 1
OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
2010-12-05 19:11:58 +00:00
OSL_TRACE( "### RuntimeException occurred upon disposing factory: %s", str.getStr() );
#else
(void) exc; // unused
#endif
}
2000-09-18 14:29:57 +00:00
}
// 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();
2000-09-18 14:29:57 +00:00
}
m_xContext.clear();
2000-09-18 14:29:57 +00:00
// not only the Event should hold the object
OSL_ASSERT( m_refCount != 1 );
}
// XPropertySet
Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo()
2000-09-18 14:29:57 +00:00
throw(::com::sun::star::uno::RuntimeException)
{
check_undisposed();
2002-11-07 14:46:09 +00:00
if (! m_xPropertyInfo.is())
{
Sequence< beans::Property > seq( 1 );
seq[ 0 ] = beans::Property(
"DefaultContext", -1, ::getCppuType( &m_xContext ), 0 );
2002-11-07 14:46:09 +00:00
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 == "DefaultContext" )
2000-09-18 14:29:57 +00:00
{
Reference< XComponentContext > xContext;
if (aValue >>= xContext)
2000-09-18 14:29:57 +00:00
{
MutexGuard aGuard( m_mutex );
m_xContext = xContext;
}
else
{
throw IllegalArgumentException(
OUString("no XComponentContext given!"),
(OWeakObject *)this, 1 );
2000-09-18 14:29:57 +00:00
}
}
else
{
throw UnknownPropertyException(
OUString("unknown property ") + PropertyName,
(OWeakObject *)this );
}
2000-09-18 14:29:57 +00:00
}
Any OServiceManager::getPropertyValue(const OUString& PropertyName)
throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
2000-09-18 14:29:57 +00:00
{
check_undisposed();
if ( PropertyName == "DefaultContext" )
2000-09-18 14:29:57 +00:00
{
MutexGuard aGuard( m_mutex );
if( m_xContext.is() )
return makeAny( m_xContext );
else
return Any();
2000-09-18 14:29:57 +00:00
}
else
{
UnknownPropertyException except;
except.Message = "ServiceManager : unknown property " + 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();
2000-09-18 14:29:57 +00:00
}
// OServiceManager
Reference<XEventListener > OServiceManager::getFactoryListener()
{
check_undisposed();
2000-09-18 14:29:57 +00:00
MutexGuard aGuard( m_mutex );
if( !xFactoryListener.is() )
xFactoryListener = new OServiceManager_Listener( this );
return xFactoryListener;
}
// XMultiServiceFactory, XContentEnumeration
Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames(
HashSet_OWString & aNameSet )
2000-09-18 14:29:57 +00:00
{
check_undisposed();
2000-09-18 14:29:57 +00:00
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("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();
2002-04-29 10:59:19 +00:00
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())
{
2002-04-29 10:59:19 +00:00
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 !!!", aStr.getStr() );
#endif
return xFac2->createInstance();
}
}
}
}
2011-12-27 00:12:38 +09:00
catch (const lang::DisposedException & exc)
{
#if OSL_DEBUG_LEVEL > 1
OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
2010-12-05 19:11:58 +00:00
OSL_TRACE( "### DisposedException occurred: %s", str.getStr() );
#else
(void) exc; // unused
#endif
}
}
2002-04-29 10:59:19 +00:00
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("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();
2002-04-29 10:59:19 +00:00
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())
{
2002-04-29 10:59:19 +00:00
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 !!!", aStr.getStr() );
#endif
return xFac2->createInstanceWithArguments( rArguments );
}
}
}
}
2011-12-27 00:12:38 +09:00
catch (const lang::DisposedException & exc)
{
#if OSL_DEBUG_LEVEL > 1
OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
2010-12-05 19:11:58 +00:00
OSL_TRACE( "### DisposedException occurred: %s", str.getStr() );
#else
(void) exc; // unused
#endif
}
}
2002-04-29 10:59:19 +00:00
return Reference< XInterface >();
}
// XMultiServiceFactory, XMultiComponentFactory, XContentEnumeration
2000-09-18 14:29:57 +00:00
Sequence< OUString > OServiceManager::getAvailableServiceNames()
throw(::com::sun::star::uno::RuntimeException)
{
check_undisposed();
2000-09-18 14:29:57 +00:00
// all names
HashSet_OWString aNameSet;
return getUniqueAvailableServiceNames( aNameSet );
2000-09-18 14:29:57 +00:00
}
// XMultibleServiceFactory
Reference<XInterface > OServiceManager::createInstance(
const OUString& rServiceSpecifier )
2000-09-18 14:29:57 +00:00
throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
{
return createInstanceWithContext(
rServiceSpecifier, m_xContext );
2000-09-18 14:29:57 +00:00
}
// XMultibleServiceFactory
Reference<XInterface > OServiceManager::createInstanceWithArguments(
const OUString& rServiceSpecifier,
const Sequence<Any >& rArguments )
2000-09-18 14:29:57 +00:00
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_FAIL( "not impl!" );
2000-09-18 14:29:57 +00:00
}
// XServiceInfo
OUString OServiceManager::getImplementationName()
throw(::com::sun::star::uno::RuntimeException)
{
return OUString("com.sun.star.comp.stoc.OServiceManager");
2000-09-18 14:29:57 +00:00
}
// XServiceInfo
sal_Bool OServiceManager::supportsService(const OUString& ServiceName)
throw(::com::sun::star::uno::RuntimeException)
{
return cppu::supportsService(this, ServiceName);
2000-09-18 14:29:57 +00:00
}
// XServiceInfo
Sequence< OUString > OServiceManager::getSupportedServiceNames()
throw(::com::sun::star::uno::RuntimeException)
{
Sequence< OUString > seqNames(2);
seqNames[0] = "com.sun.star.lang.MultiServiceFactory";
seqNames[1] = "com.sun.star.lang.ServiceManager";
return seqNames;
2000-09-18 14:29:57 +00:00
}
Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories(
const OUString& aServiceName, Reference< XComponentContext > const & )
2000-09-18 14:29:57 +00:00
{
Sequence< Reference< XInterface > > ret;
2000-09-18 14:29:57 +00:00
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
2000-09-18 14:29:57 +00:00
{
// 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;
2000-09-18 14:29:57 +00:00
// an implementation found
ret = Sequence< Reference< XInterface > >( &x, 1 );
}
2000-09-18 14:29:57 +00:00
}
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() );
2000-09-18 14:29:57 +00:00
}
return ret;
2000-09-18 14:29:57 +00:00
}
// XContentEnumerationAccess
Reference<XEnumeration > OServiceManager::createContentEnumeration(
const OUString& aServiceName )
2000-09-18 14:29:57 +00:00
throw(::com::sun::star::uno::RuntimeException)
{
check_undisposed();
Sequence< Reference< XInterface > > factories(
OServiceManager::queryServiceFactories( aServiceName, m_xContext ) );
if (factories.getLength())
return new ServiceEnumeration_Impl( factories );
else
return Reference< XEnumeration >();
2000-09-18 14:29:57 +00:00
}
// XEnumeration
Reference<XEnumeration > OServiceManager::createEnumeration() throw(::com::sun::star::uno::RuntimeException)
{
check_undisposed();
2000-09-18 14:29:57 +00:00
MutexGuard aGuard( m_mutex );
return new ImplementationEnumeration_Impl( m_ImplementationMap );
}
// XElementAccess
Type OServiceManager::getElementType()
throw(::com::sun::star::uno::RuntimeException)
{
check_undisposed();
2000-09-18 14:29:57 +00:00
return ::getCppuType( (const Reference< XInterface > *)0 );
}
// XElementAccess
sal_Bool OServiceManager::hasElements()
throw(::com::sun::star::uno::RuntimeException)
{
check_undisposed();
2000-09-18 14:29:57 +00:00
MutexGuard aGuard( m_mutex );
return !m_ImplementationMap.empty();
}
// XSet
sal_Bool OServiceManager::has( const Any & Element )
throw(::com::sun::star::uno::RuntimeException)
{
check_undisposed();
2000-09-18 14:29:57 +00:00
if( Element.getValueTypeClass() == TypeClass_INTERFACE )
{
Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
2000-09-18 14:29:57 +00:00
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();
2000-09-18 14:29:57 +00:00
}
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();
2000-09-18 14:29:57 +00:00
if( Element.getValueTypeClass() != TypeClass_INTERFACE )
{
throw IllegalArgumentException(
OUString("no interface given!"),
Reference< XInterface >(), 0 );
}
Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
2000-09-18 14:29:57 +00:00
{
MutexGuard aGuard( m_mutex );
HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
if( aIt != m_ImplementationMap.end() )
{
throw ElementExistException(
OUString("element already exists!"),
Reference< XInterface >() );
}
2000-09-18 14:29:57 +00:00
// 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.isEmpty() )
2000-09-18 14:29:57 +00:00
m_ImplementationNameMap[ aImplName ] = xEle;
//put into the service map
Sequence< OUString > aServiceNames = xInfo->getSupportedServiceNames();
2000-09-18 14:29:57 +00:00
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() ) );
}
2000-09-18 14:29:57 +00:00
}
}
// 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());
2000-09-18 14:29:57 +00:00
}
// 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("element is not in: ")
+ implName, static_cast< OWeakObject * >(this) );
}
xEle = iFind->second;
}
else
{
throw IllegalArgumentException(
OUString(
"neither interface nor string given!"),
Reference< XInterface >(), 0 );
}
2000-09-18 14:29:57 +00:00
// 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("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
2000-09-18 14:29:57 +00:00
m_ImplementationMap.erase( aIt );
2000-09-18 14:29:57 +00:00
// remove from the implementation name hashmap
Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
if( xInfo.is() )
{
OUString aImplName = xInfo->getImplementationName();
if( !aImplName.isEmpty() )
2000-09-18 14:29:57 +00:00
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;
2000-09-18 14:29:57 +00:00
}
}
}
}
/*****************************************************************************
class ORegistryServiceManager
*****************************************************************************/
class ORegistryServiceManager : public OServiceManager
2000-09-18 14:29:57 +00:00
{
public:
ORegistryServiceManager( Reference< XComponentContext > const & xContext );
virtual ~ORegistryServiceManager();
2000-09-18 14:29:57 +00:00
// 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 OUString("com.sun.star.comp.stoc.ORegistryServiceManager"); }
2000-09-18 14:29:57 +00:00
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);
// XComponent
void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
// OServiceManager
2002-11-07 14:46:09 +00:00
Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
throw(::com::sun::star::uno::RuntimeException);
2000-09-18 14:29:57 +00:00
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 );
2000-09-18 14:29:57 +00:00
private:
Reference<XRegistryKey > getRootKey();
Reference<XInterface > loadWithImplementationName(
const OUString & rImplName, Reference< XComponentContext > const & xContext );
2000-09-18 14:29:57 +00:00
Sequence<OUString> getFromServiceName(const OUString& serviceName);
Reference<XInterface > loadWithServiceName(
const OUString & rImplName, Reference< XComponentContext > const & xContext );
2000-09-18 14:29:57 +00:00
void fillAllNamesFromRegistry( HashSet_OWString & );
sal_Bool m_searchedRegistry;
Reference<XSimpleRegistry > m_xRegistry; // readonly property Registry
Reference<XRegistryKey > m_xRootKey;
2001-05-11 12:43:43 +00:00
#if OSL_DEBUG_LEVEL > 0
2001-05-11 12:43:43 +00:00
bool m_init;
#endif
2000-09-18 14:29:57 +00:00
};
/**
* Create a ServiceManager
*/
ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext > const & xContext )
: OServiceManager( xContext )
, m_searchedRegistry(sal_False)
#if OSL_DEBUG_LEVEL > 0
2001-05-11 12:43:43 +00:00
, m_init( false )
#endif
2000-09-18 14:29:57 +00:00
{
}
/**
* Destroy the ServiceManager
*/
ORegistryServiceManager::~ORegistryServiceManager()
{
}
// XComponent
void ORegistryServiceManager::dispose()
throw(::com::sun::star::uno::RuntimeException)
2000-09-18 14:29:57 +00:00
{
if (rBHelper.bDisposed || rBHelper.bInDispose)
return;
2000-09-18 14:29:57 +00:00
OServiceManager::dispose();
// dispose
MutexGuard aGuard( m_mutex );
// erase all members
m_xRegistry.clear();
m_xRootKey.clear();
2000-09-18 14:29:57 +00:00
}
/**
* 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() )
2000-09-18 14:29:57 +00:00
{
MutexGuard aGuard( m_mutex );
2000-09-18 14:29:57 +00:00
// DefaultRegistry suchen !!!!
if( !m_xRegistry.is() && !m_searchedRegistry )
{
// merken, es wird nur einmal gesucht
m_searchedRegistry = sal_True;
m_xRegistry.set(
createInstanceWithContext(
OUString("com.sun.star.registry.DefaultRegistry"),
m_xContext ),
UNO_QUERY );
2000-09-18 14:29:57 +00:00
}
if( m_xRegistry.is() && !m_xRootKey.is() )
m_xRootKey = m_xRegistry->getRootKey();
}
return m_xRootKey;
2000-09-18 14:29:57 +00:00
}
/**
* Create a service provider from the registry with an implementation name
*/
Reference<XInterface > ORegistryServiceManager::loadWithImplementationName(
const OUString& name, Reference< XComponentContext > const & xContext )
2000-09-18 14:29:57 +00:00
{
Reference<XInterface > ret;
2000-09-18 14:29:57 +00:00
Reference<XRegistryKey > xRootKey = getRootKey();
if( !xRootKey.is() )
return ret;
try
{
OUString implementationName = "/IMPLEMENTATIONS/" + name;
2000-09-18 14:29:57 +00:00
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);
2000-09-18 14:29:57 +00:00
}
}
catch (InvalidRegistryException &)
{
}
2000-09-18 14:29:57 +00:00
return ret;
}
/**
* Return all implementation out of the registry.
*/
Sequence<OUString> ORegistryServiceManager::getFromServiceName(
const OUString& serviceName )
2000-09-18 14:29:57 +00:00
{
OUStringBuffer buf;
buf.append( "/SERVICES/" );
buf.append( serviceName );
return retrieveAsciiValueList( m_xRegistry, buf.makeStringAndClear() );
2000-09-18 14:29:57 +00:00
}
/**
* Create a service provider from the registry
*/
Reference<XInterface > ORegistryServiceManager::loadWithServiceName(
const OUString& serviceName, Reference< XComponentContext > const & xContext )
2000-09-18 14:29:57 +00:00
{
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;
}
2000-09-18 14:29:57 +00:00
return Reference<XInterface >();
2000-09-18 14:29:57 +00:00
}
/**
* 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("SERVICES") );
2000-09-18 14:29:57 +00:00
// root + /Services + /
if( xServicesKey.is() )
{
2001-05-11 10:37:39 +00:00
sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1;
2000-09-18 14:29:57 +00:00
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();
2000-09-18 14:29:57 +00:00
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...
2001-05-11 12:43:43 +00:00
OSL_ENSURE( !m_init, "### second init of service manager instance!" );
m_init = true;
#endif
2000-09-18 14:29:57 +00:00
}
// XMultiServiceFactory, XContentEnumeration
Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames()
throw(::com::sun::star::uno::RuntimeException)
{
check_undisposed();
2000-09-18 14:29:57 +00:00
MutexGuard aGuard( m_mutex );
// all names
HashSet_OWString aNameSet;
// all names from the registry
fillAllNamesFromRegistry( aNameSet );
return OServiceManager::getUniqueAvailableServiceNames( aNameSet );
2000-09-18 14:29:57 +00:00
}
// XServiceInfo
Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames()
throw(::com::sun::star::uno::RuntimeException)
{
Sequence< OUString > seqNames(2);
seqNames[0] = "com.sun.star.lang.MultiServiceFactory";
seqNames[1] = "com.sun.star.lang.RegistryServiceManager";
return seqNames;
2000-09-18 14:29:57 +00:00
}
// OServiceManager
Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories(
const OUString& aServiceName, Reference< XComponentContext > const & xContext )
2000-09-18 14:29:57 +00:00
{
Sequence< Reference< XInterface > > ret(
OServiceManager::queryServiceFactories( aServiceName, xContext ) );
if (ret.getLength())
{
return ret;
}
else
2000-09-18 14:29:57 +00:00
{
MutexGuard aGuard( m_mutex );
Reference< XInterface > x( loadWithServiceName( aServiceName, xContext ) );
if (! x.is())
x = loadWithImplementationName( aServiceName, xContext );
return Sequence< Reference< XInterface > >( &x, 1 );
2000-09-18 14:29:57 +00:00
}
}
// XContentEnumerationAccess
Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
const OUString& aServiceName )
2000-09-18 14:29:57 +00:00
throw(::com::sun::star::uno::RuntimeException)
{
check_undisposed();
2000-09-18 14:29:57 +00:00
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, m_xContext );
2000-09-18 14:29:57 +00:00
}
}
// call the superclass to enumerate all contents
return OServiceManager::createContentEnumeration( aServiceName );
2000-09-18 14:29:57 +00:00
}
// OServiceManager
2002-11-07 14:46:09 +00:00
Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo()
throw(::com::sun::star::uno::RuntimeException)
{
check_undisposed();
2002-11-07 14:46:09 +00:00
if (! m_xPropertyInfo.is())
{
Sequence< beans::Property > seq( 2 );
seq[ 0 ] = beans::Property(
"DefaultContext", -1, ::getCppuType( &m_xContext ), 0 );
2002-11-07 14:46:09 +00:00
seq[ 1 ] = beans::Property(
"Registry", -1, ::getCppuType( &m_xRegistry ),
2002-11-07 14:46:09 +00:00
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;
}
2000-09-18 14:29:57 +00:00
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 == "Registry" )
2000-09-18 14:29:57 +00:00
{
MutexGuard aGuard( m_mutex );
if( m_xRegistry.is() )
return makeAny( m_xRegistry );
else
return Any();
2000-09-18 14:29:57 +00:00
}
return OServiceManager::getPropertyValue( PropertyName );
2000-09-18 14:29:57 +00:00
}
} // namespace
2000-09-18 14:29:57 +00:00
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
com_sun_star_comp_stoc_OServiceManager(
css::uno::XComponentContext * context, uno_Sequence * arguments)
2000-09-18 14:29:57 +00:00
{
assert(arguments != 0 && arguments->nElements == 0); (void) arguments;
css::uno::Reference<css::uno::XInterface> x(
static_cast<cppu::OWeakObject *>(new OServiceManager(context)));
x->acquire();
return x.get();
}
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
com_sun_star_comp_stoc_ORegistryServiceManager(
css::uno::XComponentContext * context, uno_Sequence * arguments)
2000-09-18 14:29:57 +00:00
{
assert(arguments != 0 && arguments->nElements == 0); (void) arguments;
css::uno::Reference<css::uno::XInterface> x(
static_cast<cppu::OWeakObject *>(new ORegistryServiceManager(context)));
x->acquire();
return x.get();
}
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
com_sun_star_comp_stoc_OServiceManagerWrapper(
css::uno::XComponentContext * context, uno_Sequence * arguments)
2000-09-18 14:29:57 +00:00
{
assert(arguments != 0 && arguments->nElements == 0); (void) arguments;
css::uno::Reference<css::uno::XInterface> x(
static_cast<cppu::OWeakObject *>(new OServiceManagerWrapper(context)));
x->acquire();
return x.get();
2000-09-18 14:29:57 +00:00
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */