23#include <osl/mutex.hxx>
24#include <osl/diagnose.h>
35#include <com/sun/star/lang/XMultiServiceFactory.hpp>
36#include <com/sun/star/lang/XMultiComponentFactory.hpp>
37#include <com/sun/star/lang/XServiceInfo.hpp>
38#include <com/sun/star/lang/XSingleServiceFactory.hpp>
39#include <com/sun/star/lang/XSingleComponentFactory.hpp>
40#include <com/sun/star/lang/XInitialization.hpp>
41#include <com/sun/star/lang/XEventListener.hpp>
42#include <com/sun/star/lang/DisposedException.hpp>
43#include <com/sun/star/beans/XPropertySet.hpp>
44#include <com/sun/star/beans/PropertyAttribute.hpp>
45#include <com/sun/star/registry/XRegistryKey.hpp>
46#include <com/sun/star/registry/XSimpleRegistry.hpp>
47#include <com/sun/star/container/XSet.hpp>
48#include <com/sun/star/container/XElementAccess.hpp>
49#include <com/sun/star/container/XEnumeration.hpp>
50#include <com/sun/star/container/XContentEnumerationAccess.hpp>
51#include <com/sun/star/uno/XComponentContext.hpp>
56#include <unordered_map>
57#include <unordered_set>
61using namespace css::uno;
62using namespace css::beans;
63using namespace css::registry;
64using namespace css::lang;
65using namespace css::container;
71Sequence< OUString > retrieveAsciiValueList(
72 const Reference< XSimpleRegistry > &xReg,
const OUString &keyName )
74 Reference< XEnumerationAccess > xAccess( xReg, UNO_QUERY );
75 Sequence< OUString > seq;
78 Reference< XEnumeration > xEnum = xAccess->createEnumeration();
79 while( xEnum.is() && xEnum->hasMoreElements() )
81 Reference< XSimpleRegistry > xTempReg;
82 xEnum->nextElement() >>= xTempReg;
85 const Sequence< OUString > seq2 = retrieveAsciiValueList( xTempReg, keyName );
87 if( seq2.hasElements() )
89 sal_Int32 n1Len = seq.getLength();
90 sal_Int32 n2Len = seq2.getLength();
92 seq.realloc( n1Len + n2Len );
93 std::copy(seq2.begin(), seq2.end(), std::next(seq.getArray(), n1Len));
102 Reference< XRegistryKey > rRootKey = xReg->getRootKey();
105 Reference<XRegistryKey > xKey = rRootKey->openKey(keyName);
108 seq = xKey->getAsciiListValue();
112 catch( InvalidRegistryException & )
115 catch (InvalidValueException &)
126typedef std::unordered_set< Reference<XInterface > > HashSet_Ref;
129class ServiceEnumeration_Impl :
public WeakImplHelper< XEnumeration >
132 explicit ServiceEnumeration_Impl(
const Sequence< Reference<XInterface > > & rFactories )
133 : aFactories( rFactories )
138 sal_Bool SAL_CALL hasMoreElements()
override;
139 Any SAL_CALL nextElement()
override;
142 Sequence< Reference<XInterface > > aFactories;
147sal_Bool ServiceEnumeration_Impl::hasMoreElements()
149 std::scoped_lock aGuard(
aMutex );
150 return nIt != aFactories.getLength();
154Any ServiceEnumeration_Impl::nextElement()
156 std::scoped_lock aGuard(
aMutex );
157 if( nIt == aFactories.getLength() )
158 throw NoSuchElementException(
"no more elements");
166 Sequence< beans::Property > m_properties;
174 virtual Sequence< beans::Property > SAL_CALL
getProperties()
override;
175 virtual beans::Property SAL_CALL
getPropertyByName( OUString
const & name )
override;
186 beans::Property
const *
p = m_properties.getConstArray();
187 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
189 if (p[ nPos ].Name == name)
192 throw beans::UnknownPropertyException(
193 "unknown property: " + name );
198 return std::any_of(std::cbegin(m_properties), std::cend(m_properties),
199 [&name](
const beans::Property& rProp) {
return rProp.Name ==
name; });
206class ImplementationEnumeration_Impl :
public WeakImplHelper< XEnumeration >
209 explicit ImplementationEnumeration_Impl( HashSet_Ref xImplementationMap )
210 : aImplementationMap(
std::move( xImplementationMap ))
211 , aIt( aImplementationMap.
begin() )
215 virtual sal_Bool SAL_CALL hasMoreElements()
override;
216 virtual Any SAL_CALL nextElement()
override;
220 HashSet_Ref aImplementationMap;
221 HashSet_Ref::iterator aIt;
225sal_Bool ImplementationEnumeration_Impl::hasMoreElements()
227 std::scoped_lock aGuard(
aMutex );
228 return aIt != aImplementationMap.end();
232Any ImplementationEnumeration_Impl::nextElement()
234 std::scoped_lock aGuard(
aMutex );
235 if( aIt == aImplementationMap.end() )
236 throw NoSuchElementException(
"no more elements");
246typedef std::unordered_set
251typedef std::unordered_multimap
254 Reference<XInterface >
255> HashMultimap_OWString_Interface;
257typedef std::unordered_map
260 Reference<XInterface >
266class OServiceManager_Listener :
public WeakImplHelper< XEventListener >
269 WeakReference<XSet >
xSMgr;
272 explicit OServiceManager_Listener(
const Reference<XSet > & rSMgr )
277 virtual void SAL_CALL disposing(
const EventObject & rEvt )
override;
280void OServiceManager_Listener::disposing(
const EventObject & rEvt )
282 Reference<XSet >
x( xSMgr );
290 catch(
const IllegalArgumentException & )
292 OSL_FAIL(
"IllegalArgumentException caught" );
294 catch(
const NoSuchElementException & )
296 OSL_FAIL(
"NoSuchElementException caught" );
305typedef WeakComponentImplHelper<
306 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
307 lang::XInitialization,
308 container::XSet, container::XContentEnumerationAccess,
309 beans::XPropertySet > t_OServiceManager_impl;
313 ,
public t_OServiceManager_impl
316 explicit OServiceManager( Reference< XComponentContext >
const & xContext );
319 void SAL_CALL initialize( Sequence< Any >
const & args )
override;
327 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
328 OUString
const & rServiceSpecifier, Reference< XComponentContext >
const & xContext )
override;
329 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
330 OUString
const & rServiceSpecifier,
331 Sequence< Any >
const & rArguments,
332 Reference< XComponentContext >
const & xContext )
override;
337 virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
override;
338 virtual Reference<XInterface > SAL_CALL
createInstance(
const OUString &)
override;
339 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(
const OUString &,
const Sequence<Any >& Arguments)
override;
342 Sequence< OUString > getUniqueAvailableServiceNames(
343 HashSet_OWString & aNameSet );
346 virtual Type SAL_CALL getElementType()
override;
347 virtual sal_Bool SAL_CALL hasElements()
override;
350 virtual Reference<XEnumeration > SAL_CALL createEnumeration()
override;
353 virtual sal_Bool SAL_CALL has(
const Any & Element )
override;
354 virtual void SAL_CALL insert(
const Any & Element )
override;
355 virtual void SAL_CALL
remove(
const Any & Element )
override;
359 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(
const OUString& aServiceName)
override;
362 virtual void SAL_CALL
dispose()
override;
365 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
override;
366 void SAL_CALL
setPropertyValue(
const OUString& PropertyName,
const Any& aValue)
override;
368 void SAL_CALL addPropertyChangeListener(
const OUString& PropertyName,
const Reference<XPropertyChangeListener >& aListener)
override;
369 void SAL_CALL removePropertyChangeListener(
const OUString& PropertyName,
const Reference<XPropertyChangeListener >& aListener)
override;
370 void SAL_CALL addVetoableChangeListener(
const OUString& PropertyName,
const Reference<XVetoableChangeListener >& aListener)
override;
371 void SAL_CALL removeVetoableChangeListener(
const OUString& PropertyName,
const Reference<XVetoableChangeListener >& aListener)
override;
374 bool is_disposed()
const;
375 void check_undisposed()
const;
376 virtual void SAL_CALL disposing()
override;
378 bool haveFactoryWithThisImplementation(
const OUString& aImplName);
380 virtual Sequence< Reference< XInterface > > queryServiceFactories(
381 const OUString& aServiceName, Reference< XComponentContext >
const & xContext );
385 Reference< beans::XPropertySetInfo > m_xPropertyInfo;
389 HashSet_Ref m_SetLoadedFactories;
392 Reference<XEventListener > getFactoryListener();
395 HashMultimap_OWString_Interface m_ServiceMap;
396 HashSet_Ref m_ImplementationMap;
398 Reference<XEventListener > xFactoryListener;
403bool OServiceManager::is_disposed()
const
406 return (m_bInDisposing || rBHelper.bDisposed);
410void OServiceManager::check_undisposed()
const
414 throw lang::DisposedException(
415 "service manager instance has already been disposed!",
416 const_cast<OServiceManager *
>(
this)->getXWeak() );
421typedef WeakComponentImplHelper<
422 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
423 container::XSet, container::XContentEnumerationAccess,
424 beans::XPropertySet > t_OServiceManagerWrapper_impl;
426class OServiceManagerWrapper :
public cppu::BaseMutex,
public t_OServiceManagerWrapper_impl
429 Reference< XMultiComponentFactory > m_root;
430 Reference< XMultiComponentFactory >
const & getRoot()
const
434 throw lang::DisposedException(
435 "service manager instance has already been disposed!" );
441 virtual void SAL_CALL disposing()
override;
444 explicit OServiceManagerWrapper(
445 Reference< XComponentContext >
const & xContext );
449 {
return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getImplementationName(); }
451 {
return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->supportsService( ServiceName ); }
453 {
return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getSupportedServiceNames(); }
456 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
457 OUString
const & rServiceSpecifier, Reference< XComponentContext >
const & xContext )
override
458 {
return getRoot()->createInstanceWithContext( rServiceSpecifier, xContext ); }
459 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
460 OUString
const & rServiceSpecifier,
461 Sequence< Any >
const & rArguments,
462 Reference< XComponentContext >
const & xContext )
override
463 {
return getRoot()->createInstanceWithArgumentsAndContext( rServiceSpecifier, rArguments, xContext ); }
468 virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
override
469 {
return getRoot()->getAvailableServiceNames(); }
470 virtual Reference<XInterface > SAL_CALL
createInstance(
const OUString & name)
override
471 {
return getRoot()->createInstanceWithContext( name, m_xContext ); }
472 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(
const OUString & name,
const Sequence<Any >& Arguments)
override
473 {
return getRoot()->createInstanceWithArgumentsAndContext( name, Arguments, m_xContext ); }
476 virtual Type SAL_CALL getElementType()
override
477 {
return Reference< XElementAccess >(getRoot(), UNO_QUERY_THROW)->getElementType(); }
478 virtual sal_Bool SAL_CALL hasElements()
override
479 {
return Reference< XElementAccess >(getRoot(), UNO_QUERY_THROW)->hasElements(); }
482 virtual Reference<XEnumeration > SAL_CALL createEnumeration()
override
483 {
return Reference< XEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createEnumeration(); }
486 virtual sal_Bool SAL_CALL has(
const Any & Element )
override
487 {
return Reference< XSet >(getRoot(), UNO_QUERY_THROW)->has( Element ); }
488 virtual void SAL_CALL insert(
const Any & Element )
override
489 { Reference< XSet >(getRoot(), UNO_QUERY_THROW)->insert( Element ); }
490 virtual void SAL_CALL
remove(
const Any & Element )
override
491 { Reference< XSet >(getRoot(), UNO_QUERY_THROW)->remove( Element ); }
495 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(
const OUString& aServiceName)
override
496 {
return Reference< XContentEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createContentEnumeration( aServiceName ); }
499 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
override
500 {
return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertySetInfo(); }
502 void SAL_CALL
setPropertyValue(
const OUString& PropertyName,
const Any& aValue)
override;
505 void SAL_CALL addPropertyChangeListener(
const OUString& PropertyName,
const Reference<XPropertyChangeListener >& aListener)
override
506 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->addPropertyChangeListener( PropertyName, aListener ); }
507 void SAL_CALL removePropertyChangeListener(
const OUString& PropertyName,
const Reference<XPropertyChangeListener >& aListener)
override
508 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->removePropertyChangeListener( PropertyName, aListener ); }
509 void SAL_CALL addVetoableChangeListener(
const OUString& PropertyName,
const Reference<XVetoableChangeListener >& aListener)
override
510 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->addVetoableChangeListener( PropertyName, aListener ); }
511 void SAL_CALL removeVetoableChangeListener(
const OUString& PropertyName,
const Reference<XVetoableChangeListener >& aListener)
override
512 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->removeVetoableChangeListener( PropertyName, aListener ); }
515void SAL_CALL OServiceManagerWrapper::setPropertyValue(
516 const OUString& PropertyName,
const Any& aValue )
518 if ( PropertyName ==
"DefaultContext" )
520 Reference< XComponentContext > xContext;
521 if (!(aValue >>= xContext))
523 throw IllegalArgumentException(
524 "no XComponentContext given!",
528 MutexGuard aGuard( m_aMutex );
534 Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->setPropertyValue( PropertyName, aValue );
538Any SAL_CALL OServiceManagerWrapper::getPropertyValue(
539 const OUString& PropertyName )
541 if ( PropertyName ==
"DefaultContext" )
543 MutexGuard aGuard( m_aMutex );
545 return Any( m_xContext );
551 return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertyValue( PropertyName );
555void OServiceManagerWrapper::disposing()
563OServiceManagerWrapper::OServiceManagerWrapper(
564 Reference< XComponentContext >
const & xContext )
565 : t_OServiceManagerWrapper_impl(
m_aMutex )
567 , m_root( xContext->getServiceManager() )
572 "no service manager to wrap" );
580OServiceManager::OServiceManager( Reference< XComponentContext >
const & xContext )
581 : t_OServiceManager_impl(
m_aMutex )
583 , m_bInDisposing( false )
587void OServiceManager::dispose()
589 if (rBHelper.bDisposed || rBHelper.bInDispose)
591 t_OServiceManager_impl::dispose();
594void OServiceManager::disposing()
599 MutexGuard aGuard( m_aMutex );
600 m_bInDisposing =
true;
601 aImpls = m_ImplementationMap;
603 for(
const auto& rxImpl : aImpls )
607 Reference<XComponent > xComp( Reference<XComponent >::query( rxImpl ) );
613 SAL_INFO(
"stoc",
"RuntimeException occurred upon disposing factory: " << exc);
618 HashSet_Ref aImplMap;
620 MutexGuard aGuard( m_aMutex );
622 m_ServiceMap = HashMultimap_OWString_Interface();
623 aImplMap = m_ImplementationMap;
624 m_ImplementationMap = HashSet_Ref();
626 m_SetLoadedFactories= HashSet_Ref();
632 OSL_ASSERT( m_refCount != 1 );
636Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo()
639 if (! m_xPropertyInfo.is())
641 Sequence< beans::Property > seq{ beans::Property(
642 "DefaultContext", -1,
cppu::UnoType<
decltype(m_xContext)>::get(), 0 ) };
643 Reference< beans::XPropertySetInfo > xInfo(
new PropertySetInfo_Impl( seq ) );
645 MutexGuard aGuard( m_aMutex );
646 if (! m_xPropertyInfo.is())
648 m_xPropertyInfo = xInfo;
651 return m_xPropertyInfo;
654void OServiceManager::setPropertyValue(
655 const OUString& PropertyName,
const Any& aValue )
658 if ( PropertyName !=
"DefaultContext" )
660 throw UnknownPropertyException(
661 "unknown property " + PropertyName,
665 Reference< XComponentContext > xContext;
666 if (!(aValue >>= xContext))
668 throw IllegalArgumentException(
669 "no XComponentContext given!",
673 MutexGuard aGuard( m_aMutex );
677Any OServiceManager::getPropertyValue(
const OUString& PropertyName)
680 if ( PropertyName ==
"DefaultContext" )
682 MutexGuard aGuard( m_aMutex );
684 return Any( m_xContext );
690 UnknownPropertyException except;
691 except.Message =
"ServiceManager : unknown property " + PropertyName;
696void OServiceManager::addPropertyChangeListener(
697 const OUString&,
const Reference<XPropertyChangeListener >&)
700 throw UnknownPropertyException(
"unsupported");
703void OServiceManager::removePropertyChangeListener(
704 const OUString&,
const Reference<XPropertyChangeListener >&)
707 throw UnknownPropertyException(
"unsupported");
710void OServiceManager::addVetoableChangeListener(
711 const OUString&,
const Reference<XVetoableChangeListener >&)
714 throw UnknownPropertyException(
"unsupported");
717void OServiceManager::removeVetoableChangeListener(
718 const OUString&,
const Reference<XVetoableChangeListener >&)
721 throw UnknownPropertyException(
"unsupported");
725Reference<XEventListener > OServiceManager::getFactoryListener()
728 MutexGuard aGuard( m_aMutex );
729 if( !xFactoryListener.is() )
730 xFactoryListener =
new OServiceManager_Listener(
this );
731 return xFactoryListener;
735Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames(
736 HashSet_OWString & aNameSet )
739 MutexGuard aGuard( m_aMutex );
740 for(
const auto& rEntry : m_ServiceMap )
741 aNameSet.insert( rEntry.first );
754Reference< XInterface > OServiceManager::createInstanceWithContext(
755 OUString
const & rServiceSpecifier,
756 Reference< XComponentContext >
const & xContext )
759#if OSL_DEBUG_LEVEL > 0
760 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
761 OSL_ASSERT( xProps.is() );
764 Reference< XComponentContext > xDefContext;
765 xProps->getPropertyValue(
"DefaultContext" ) >>= xDefContext;
767 xContext == xDefContext,
768 "### default context of service manager singleton differs from context holding it!" );
772 const Sequence< Reference< XInterface > > factories(
773 queryServiceFactories( rServiceSpecifier, xContext ) );
774 for ( Reference< XInterface >
const & xFactory : factories )
780 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
783 return xFac->createInstanceWithContext( xContext );
787 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
790 SAL_INFO(
"stoc",
"ignoring given context raising service " << rServiceSpecifier <<
"!!!");
791 return xFac2->createInstance();
796 catch (
const lang::DisposedException & exc)
798 SAL_INFO(
"stoc",
"DisposedException occurred: " << exc);
802 return Reference< XInterface >();
805Reference< XInterface > OServiceManager::createInstanceWithArgumentsAndContext(
806 OUString
const & rServiceSpecifier,
807 Sequence< Any >
const & rArguments,
808 Reference< XComponentContext >
const & xContext )
811#if OSL_DEBUG_LEVEL > 0
812 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
813 OSL_ASSERT( xProps.is() );
816 Reference< XComponentContext > xDefContext;
817 xProps->getPropertyValue(
"DefaultContext" ) >>= xDefContext;
819 xContext == xDefContext,
820 "### default context of service manager singleton differs from context holding it!" );
824 const Sequence< Reference< XInterface > > factories(
825 queryServiceFactories( rServiceSpecifier, xContext ) );
826 for ( Reference< XInterface >
const & xFactory : factories )
832 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
835 return xFac->createInstanceWithArgumentsAndContext( rArguments, xContext );
839 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
842 SAL_INFO(
"stoc",
"ignoring given context raising service " << rServiceSpecifier <<
"!!!");
843 return xFac2->createInstanceWithArguments( rArguments );
848 catch (
const lang::DisposedException & exc)
850 SAL_INFO(
"stoc",
"DisposedException occurred: " << exc);
854 return Reference< XInterface >();
858Sequence< OUString > OServiceManager::getAvailableServiceNames()
862 HashSet_OWString aNameSet;
863 return getUniqueAvailableServiceNames( aNameSet );
867Reference<XInterface > OServiceManager::createInstance(
868 const OUString& rServiceSpecifier )
870 return createInstanceWithContext(
871 rServiceSpecifier, m_xContext );
875Reference<XInterface > OServiceManager::createInstanceWithArguments(
876 const OUString& rServiceSpecifier,
877 const Sequence<Any >& rArguments )
879 return createInstanceWithArgumentsAndContext(
880 rServiceSpecifier, rArguments, m_xContext );
884void OServiceManager::initialize( Sequence< Any >
const & )
887 OSL_FAIL(
"not impl!" );
891OUString OServiceManager::getImplementationName()
893 return "com.sun.star.comp.stoc.OServiceManager";
897sal_Bool OServiceManager::supportsService(
const OUString& ServiceName)
903Sequence< OUString > OServiceManager::getSupportedServiceNames()
905 return {
"com.sun.star.lang.MultiServiceFactory",
"com.sun.star.lang.ServiceManager" };
909Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories(
910 const OUString& aServiceName, Reference< XComponentContext >
const & )
912 Sequence< Reference< XInterface > > ret;
914 MutexGuard aGuard( m_aMutex );
916 HashMultimap_OWString_Interface::iterator,
917 HashMultimap_OWString_Interface::iterator>
p(
918 m_ServiceMap.equal_range( aServiceName ) );
920 if (
p.first ==
p.second)
923 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.find( aServiceName );
924 if( aIt != m_ImplementationNameMap.end() )
926 Reference< XInterface >
const &
x = aIt->second;
928 ret = Sequence< Reference< XInterface > >( &
x, 1 );
933 ::std::vector< Reference< XInterface > > vec;
935 while (
p.first !=
p.second)
937 vec.push_back(
p.first->second );
940 ret = Sequence< Reference< XInterface > >( vec.data(), vec.size() );
947Reference<XEnumeration > OServiceManager::createContentEnumeration(
948 const OUString& aServiceName )
951 Sequence< Reference< XInterface > > factories(
952 OServiceManager::queryServiceFactories( aServiceName, m_xContext ) );
953 if (factories.hasElements())
954 return new ServiceEnumeration_Impl( factories );
956 return Reference< XEnumeration >();
960Reference<XEnumeration > OServiceManager::createEnumeration()
963 MutexGuard aGuard( m_aMutex );
964 return new ImplementationEnumeration_Impl( m_ImplementationMap );
968Type OServiceManager::getElementType()
975sal_Bool OServiceManager::hasElements()
978 MutexGuard aGuard( m_aMutex );
979 return !m_ImplementationMap.empty();
983sal_Bool OServiceManager::has(
const Any & Element )
986 if( Element.getValueTypeClass() == TypeClass_INTERFACE )
988 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
989 MutexGuard aGuard( m_aMutex );
990 return m_ImplementationMap.find( xEle ) !=
991 m_ImplementationMap.end();
993 else if (
auto implName = o3tl::tryAccess<OUString>(Element))
995 MutexGuard aGuard( m_aMutex );
996 return m_ImplementationNameMap.find( *implName ) !=
997 m_ImplementationNameMap.end();
1003void OServiceManager::insert(
const Any & Element )
1006 if( Element.getValueTypeClass() != TypeClass_INTERFACE )
1008 throw IllegalArgumentException(
1009 "exception interface, got " + Element.getValueType().getTypeName(),
1010 Reference< XInterface >(), 0 );
1012 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
1015 MutexGuard aGuard( m_aMutex );
1016 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1017 if( aIt != m_ImplementationMap.end() )
1019 throw ElementExistException(
"element already exists!" );
1023 m_ImplementationMap.insert( xEle );
1026 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1029 OUString aImplName = xInfo->getImplementationName();
1030 if( !aImplName.isEmpty() )
1031 m_ImplementationNameMap[ aImplName ] = xEle;
1034 const Sequence< OUString >
aServiceNames = xInfo->getSupportedServiceNames();
1035 for(
const OUString& rServiceName : aServiceNames )
1037 m_ServiceMap.emplace(
1043 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1045 xComp->addEventListener( getFactoryListener() );
1049bool OServiceManager::haveFactoryWithThisImplementation(
const OUString& aImplName)
1051 return ( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end());
1055void OServiceManager::remove(
const Any & Element )
1060 Reference<XInterface > xEle;
1061 if (Element.getValueTypeClass() == TypeClass_INTERFACE)
1063 xEle.set( Element, UNO_QUERY_THROW );
1065 else if (
auto implName = o3tl::tryAccess<OUString>(Element))
1067 MutexGuard aGuard( m_aMutex );
1068 HashMap_OWString_Interface::const_iterator
const iFind(
1069 m_ImplementationNameMap.find( *implName ) );
1070 if (iFind == m_ImplementationNameMap.end())
1072 throw NoSuchElementException(
1073 "element is not in: " + *implName,
1076 xEle = iFind->second;
1080 throw IllegalArgumentException(
1081 "expected interface or string, got " + Element.getValueType().getTypeName(),
1082 Reference< XInterface >(), 0 );
1086 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1088 xComp->removeEventListener( getFactoryListener() );
1090 MutexGuard aGuard( m_aMutex );
1091 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1092 if( aIt == m_ImplementationMap.end() )
1094 throw NoSuchElementException(
1095 "element not found",
1099 m_SetLoadedFactories.erase( *aIt);
1102 m_ImplementationMap.erase( aIt );
1105 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1108 OUString aImplName = xInfo->getImplementationName();
1109 if( !aImplName.isEmpty() )
1110 m_ImplementationNameMap.erase( aImplName );
1114 Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) );
1118 const Sequence< OUString >
aServiceNames = xSF->getSupportedServiceNames();
1119 for(
const OUString& rServiceName : aServiceNames )
1121 std::pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator>
p =
1122 m_ServiceMap.equal_range( rServiceName );
1124 while(
p.first !=
p.second )
1126 if( xEle == (*
p.first).second )
1128 m_ServiceMap.erase(
p.first );
1139class ORegistryServiceManager :
public OServiceManager
1142 explicit ORegistryServiceManager( Reference< XComponentContext >
const & xContext );
1145 void SAL_CALL initialize(
const Sequence< Any >& Arguments)
override;
1149 {
return "com.sun.star.comp.stoc.ORegistryServiceManager"; }
1154 Sequence< OUString > SAL_CALL getAvailableServiceNames()
override;
1158 Reference<XEnumeration > SAL_CALL createContentEnumeration(
const OUString& aServiceName)
override;
1161 void SAL_CALL
dispose()
override;
1164 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
override;
1169 Sequence< Reference< XInterface > > queryServiceFactories(
1170 const OUString& aServiceName, Reference< XComponentContext >
const & xContext )
override;
1172 Reference<XRegistryKey > getRootKey();
1173 Reference<XInterface > loadWithImplementationName(
1174 const OUString & rImplName, Reference< XComponentContext >
const & xContext );
1175 Sequence<OUString> getFromServiceName(std::u16string_view serviceName)
const;
1176 Reference<XInterface > loadWithServiceName(
1177 std::u16string_view rImplName, Reference< XComponentContext >
const & xContext );
1178 void fillAllNamesFromRegistry( HashSet_OWString & );
1180 bool m_searchedRegistry;
1181 Reference<XSimpleRegistry > m_xRegistry;
1182 Reference<XRegistryKey > m_xRootKey;
1184#if OSL_DEBUG_LEVEL > 0
1192ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext >
const & xContext )
1193 : OServiceManager( xContext )
1194 , m_searchedRegistry(false)
1195#
if OSL_DEBUG_LEVEL > 0
1202void ORegistryServiceManager::dispose()
1204 if (rBHelper.bDisposed || rBHelper.bInDispose)
1206 OServiceManager::dispose();
1208 MutexGuard aGuard( m_aMutex );
1210 m_xRegistry.clear();
1220Reference<XRegistryKey > ORegistryServiceManager::getRootKey()
1222 if( !m_xRootKey.is() )
1224 MutexGuard aGuard( m_aMutex );
1226 if( !m_xRegistry.is() && !m_searchedRegistry )
1229 m_searchedRegistry =
true;
1232 createInstanceWithContext(
1233 "com.sun.star.registry.DefaultRegistry",
1237 if( m_xRegistry.is() && !m_xRootKey.is() )
1238 m_xRootKey = m_xRegistry->getRootKey();
1247Reference<XInterface > ORegistryServiceManager::loadWithImplementationName(
1248 const OUString& name, Reference< XComponentContext >
const & xContext )
1250 Reference<XInterface > ret;
1252 Reference<XRegistryKey > xRootKey = getRootKey();
1253 if( !xRootKey.is() )
1259 Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName);
1263 Reference< lang::XMultiServiceFactory > xMgr;
1265 xMgr.set( xContext->getServiceManager(), UNO_QUERY_THROW );
1269 insert(
Any( ret ) );
1273 m_SetLoadedFactories.insert( ret);
1276 catch (InvalidRegistryException &)
1286Sequence<OUString> ORegistryServiceManager::getFromServiceName(
1287 std::u16string_view serviceName )
const
1289 OUString buf = OUString::Concat(
"/SERVICES/") + serviceName;
1290 return retrieveAsciiValueList( m_xRegistry, buf );
1296Reference<XInterface > ORegistryServiceManager::loadWithServiceName(
1297 std::u16string_view serviceName, Reference< XComponentContext >
const & xContext )
1299 const Sequence<OUString> implEntries = getFromServiceName( serviceName );
1300 for (
const auto& rEntry : implEntries)
1302 Reference< XInterface >
x( loadWithImplementationName( rEntry, xContext ) );
1307 return Reference<XInterface >();
1313void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet )
1315 Reference<XRegistryKey > xRootKey = getRootKey();
1316 if( !xRootKey.is() )
1321 Reference<XRegistryKey > xServicesKey = xRootKey->openKey(
"SERVICES" );
1323 if( xServicesKey.is() )
1325 sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1;
1326 const Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys();
1327 std::transform(aKeys.begin(), aKeys.end(), std::inserter(rSet,
rSet.end()),
1328 [nPrefix](
const Reference<XRegistryKey>& rKey) -> OUString {
1329 return rKey->getKeyName().copy( nPrefix ); });
1332 catch (InvalidRegistryException &)
1338void ORegistryServiceManager::initialize(
const Sequence< Any >& Arguments)
1341 MutexGuard aGuard( m_aMutex );
1342 if (Arguments.hasElements())
1345 Arguments[ 0 ] >>= m_xRegistry;
1347#if OSL_DEBUG_LEVEL > 0
1349 OSL_ENSURE( !m_init,
"### second init of service manager instance!" );
1355Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames()
1358 MutexGuard aGuard( m_aMutex );
1360 HashSet_OWString aNameSet;
1363 fillAllNamesFromRegistry( aNameSet );
1365 return OServiceManager::getUniqueAvailableServiceNames( aNameSet );
1369Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames()
1371 return {
"com.sun.star.lang.MultiServiceFactory",
"com.sun.star.lang.RegistryServiceManager" };
1376Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories(
1377 const OUString& aServiceName, Reference< XComponentContext >
const & xContext )
1379 Sequence< Reference< XInterface > > ret(
1380 OServiceManager::queryServiceFactories( aServiceName, xContext ) );
1381 if (ret.hasElements())
1387 MutexGuard aGuard( m_aMutex );
1388 Reference< XInterface >
x( loadWithServiceName( aServiceName, xContext ) );
1390 x = loadWithImplementationName( aServiceName, xContext );
1391 return Sequence< Reference< XInterface > >( &
x, 1 );
1396Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
1397 const OUString& aServiceName )
1400 MutexGuard aGuard(m_aMutex);
1402 const Sequence<OUString> aImpls = getFromServiceName( aServiceName );
1404 for(
const OUString& aImplName : aImpls )
1406 if ( !haveFactoryWithThisImplementation(aImplName) )
1408 loadWithImplementationName( aImplName, m_xContext );
1412 return OServiceManager::createContentEnumeration( aServiceName );
1416Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo()
1419 if (! m_xPropertyInfo.is())
1421 Sequence< beans::Property > seq{
1422 beans::Property(
"DefaultContext", -1,
cppu::UnoType<
decltype(m_xContext)>::get(), 0),
1423 beans::Property(
"Registry", -1,
cppu::UnoType<
decltype(m_xRegistry)>::get(),
1424 beans::PropertyAttribute::READONLY)
1426 Reference< beans::XPropertySetInfo > xInfo(
new PropertySetInfo_Impl( seq ) );
1428 MutexGuard aGuard( m_aMutex );
1429 if (! m_xPropertyInfo.is())
1431 m_xPropertyInfo = xInfo;
1434 return m_xPropertyInfo;
1437Any ORegistryServiceManager::getPropertyValue(
const OUString& PropertyName)
1440 if ( PropertyName ==
"Registry" )
1442 MutexGuard aGuard( m_aMutex );
1443 if( m_xRegistry.is() )
1444 return Any( m_xRegistry );
1448 return OServiceManager::getPropertyValue( PropertyName );
1453extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1455 css::uno::XComponentContext *context,
1456 css::uno::Sequence<css::uno::Any>
const &)
1458 return cppu::acquire(
new OServiceManager(context));
1461extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1463 css::uno::XComponentContext *context,
1464 css::uno::Sequence<css::uno::Any>
const &)
1466 return cppu::acquire(
new ORegistryServiceManager(context));
1469extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1471 css::uno::XComponentContext *context,
1472 css::uno::Sequence<css::uno::Any>
const &)
1474 return cppu::acquire(
new OServiceManagerWrapper(context));
Reference< XComponentContext > m_xContext
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
virtual Property SAL_CALL getPropertyByName(const OUString &aName) override
virtual sal_Bool SAL_CALL hasPropertyByName(const OUString &Name) override
virtual Sequence< Property > SAL_CALL getProperties() override
PropertySetInfo_Impl(PersistentPropertySet *pOwner)
css::uno::Type const & get()
Reference< XMultiServiceFactory > xSMgr
Reference< XSingleServiceFactory > xFactory
Sequence< OUString > aServiceNames
#define SAL_INFO(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
OUStringBuffer & remove(OUStringBuffer &rIn, sal_Unicode c)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
Reference< XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(const Reference< XMultiServiceFactory > &rServiceManager, const OUString &rImplementationName, const Reference< XRegistryKey > &rImplementationKey)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
constexpr OUStringLiteral implementationName
detail::Optional< T >::type doAccess(css::uno::Any const &any)
enumrange< T >::Iterator begin(enumrange< T >)
VBAHELPER_DLLPUBLIC bool setPropertyValue(css::uno::Sequence< css::beans::PropertyValue > &aProp, const OUString &aName, const css::uno::Any &aValue)
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
std::unordered_map< OUString, Reference< XInterface > > HashMap_OWString_Interface
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_OServiceManager_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_ORegistryServiceManager_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_OServiceManagerWrapper_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)