Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / stoc / source / servicemanager / servicemanager.cxx
blobeb5685a29b764361e6c9f07771ae5c94be3b65a6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <o3tl/any.hxx>
23 #include <osl/mutex.hxx>
24 #include <osl/diagnose.h>
25 #include <rtl/ref.hxx>
26 #include <rtl/ustrbuf.hxx>
28 #include <uno/mapping.hxx>
29 #include <uno/dispatcher.h>
30 #include <cppuhelper/queryinterface.hxx>
31 #include <cppuhelper/weakref.hxx>
32 #include <cppuhelper/component.hxx>
33 #include <cppuhelper/implbase.hxx>
34 #include <cppuhelper/implementationentry.hxx>
35 #include <cppuhelper/component_context.hxx>
36 #include <cppuhelper/bootstrap.hxx>
37 #include <cppuhelper/compbase.hxx>
38 #include <cppuhelper/supportsservice.hxx>
39 #include <comphelper/sequence.hxx>
41 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
42 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
45 #include <com/sun/star/lang/XInitialization.hpp>
46 #include <com/sun/star/lang/XEventListener.hpp>
47 #include <com/sun/star/lang/DisposedException.hpp>
48 #include <com/sun/star/beans/XPropertySet.hpp>
49 #include <com/sun/star/beans/PropertyAttribute.hpp>
50 #include <com/sun/star/registry/XRegistryKey.hpp>
51 #include <com/sun/star/registry/XSimpleRegistry.hpp>
52 #include <com/sun/star/container/XSet.hpp>
53 #include <com/sun/star/container/XElementAccess.hpp>
54 #include <com/sun/star/container/XEnumeration.hpp>
55 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
56 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
57 #include <com/sun/star/uno/XUnloadingPreference.hpp>
59 #include <unordered_map>
60 #include <unordered_set>
62 using namespace com::sun::star;
63 using namespace css::uno;
64 using namespace css::beans;
65 using namespace css::registry;
66 using namespace css::lang;
67 using namespace css::container;
68 using namespace cppu;
69 using namespace osl;
70 using namespace std;
72 namespace {
74 Sequence< OUString > retrieveAsciiValueList(
75 const Reference< XSimpleRegistry > &xReg, const OUString &keyName )
77 Reference< XEnumerationAccess > xAccess( xReg, UNO_QUERY );
78 Sequence< OUString > seq;
79 if( xAccess.is() )
81 Reference< XEnumeration > xEnum = xAccess->createEnumeration();
82 while( xEnum.is() && xEnum->hasMoreElements() )
84 Reference< XSimpleRegistry > xTempReg;
85 xEnum->nextElement() >>= xTempReg;
86 if( xTempReg.is() )
88 Sequence< OUString > seq2 = retrieveAsciiValueList( xTempReg, keyName );
90 if( seq2.getLength() )
92 sal_Int32 n1Len = seq.getLength();
93 sal_Int32 n2Len = seq2.getLength();
95 seq.realloc( n1Len + n2Len );
96 const OUString *pSource = seq2.getConstArray();
97 OUString *pTarget = seq.getArray();
98 for( int i = 0 ; i < n2Len ; i ++ )
100 pTarget[i+n1Len] = pSource[i];
106 else if( xReg.is () )
110 Reference< XRegistryKey > rRootKey = xReg->getRootKey();
111 if( rRootKey.is() )
113 Reference<XRegistryKey > xKey = rRootKey->openKey(keyName);
114 if( xKey.is() )
116 seq = xKey->getAsciiListValue();
120 catch( InvalidRegistryException & )
123 catch (InvalidValueException &)
127 return seq;
130 /*****************************************************************************
131 Enumeration by ServiceName
132 *****************************************************************************/
133 struct hashRef_Impl
135 size_t operator()(const Reference<XInterface > & rName) const
137 // query to XInterface. The cast to XInterface* must be the same for the same object
138 Reference<XInterface > x( Reference<XInterface >::query( rName ) );
139 return reinterpret_cast<size_t>(x.get());
143 struct equaltoRef_Impl
145 bool operator()(const Reference<XInterface > & rName1, const Reference<XInterface > & rName2 ) const
146 { return rName1 == rName2; }
149 typedef std::unordered_set
151 Reference<XInterface >,
152 hashRef_Impl,
153 equaltoRef_Impl
154 > HashSet_Ref;
157 class ServiceEnumeration_Impl : public WeakImplHelper< XEnumeration >
159 public:
160 explicit ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories )
161 : aFactories( rFactories )
162 , nIt( 0 )
165 // XEnumeration
166 sal_Bool SAL_CALL hasMoreElements() override;
167 Any SAL_CALL nextElement() override;
168 private:
169 Mutex aMutex;
170 Sequence< Reference<XInterface > > aFactories;
171 sal_Int32 nIt;
174 // XEnumeration
175 sal_Bool ServiceEnumeration_Impl::hasMoreElements()
177 MutexGuard aGuard( aMutex );
178 return nIt != aFactories.getLength();
181 // XEnumeration
182 Any ServiceEnumeration_Impl::nextElement()
184 MutexGuard aGuard( aMutex );
185 if( nIt == aFactories.getLength() )
186 throw NoSuchElementException("no more elements");
188 return Any( &aFactories.getConstArray()[nIt++], cppu::UnoType<XInterface>::get());
192 class PropertySetInfo_Impl : public WeakImplHelper< beans::XPropertySetInfo >
194 Sequence< beans::Property > m_properties;
196 public:
197 explicit PropertySetInfo_Impl( Sequence< beans::Property > const & properties )
198 : m_properties( properties )
201 // XPropertySetInfo impl
202 virtual Sequence< beans::Property > SAL_CALL getProperties() override;
203 virtual beans::Property SAL_CALL getPropertyByName( OUString const & name ) override;
204 virtual sal_Bool SAL_CALL hasPropertyByName( OUString const & name ) override;
207 Sequence< beans::Property > PropertySetInfo_Impl::getProperties()
209 return m_properties;
212 beans::Property PropertySetInfo_Impl::getPropertyByName( OUString const & name )
214 beans::Property const * p = m_properties.getConstArray();
215 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
217 if (p[ nPos ].Name.equals( name ))
218 return p[ nPos ];
220 throw beans::UnknownPropertyException(
221 "unknown property: " + name );
224 sal_Bool PropertySetInfo_Impl::hasPropertyByName( OUString const & name )
226 beans::Property const * p = m_properties.getConstArray();
227 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
229 if (p[ nPos ].Name.equals( name ))
230 return true;
232 return false;
236 /*****************************************************************************
237 Enumeration by implementation
238 *****************************************************************************/
239 class ImplementationEnumeration_Impl : public WeakImplHelper< XEnumeration >
241 public:
242 explicit ImplementationEnumeration_Impl( const HashSet_Ref & rImplementationMap )
243 : aImplementationMap( rImplementationMap )
244 , aIt( aImplementationMap.begin() )
247 // XEnumeration
248 virtual sal_Bool SAL_CALL hasMoreElements() override;
249 virtual Any SAL_CALL nextElement() override;
251 private:
252 Mutex aMutex;
253 HashSet_Ref aImplementationMap;
254 HashSet_Ref::iterator aIt;
257 // XEnumeration
258 sal_Bool ImplementationEnumeration_Impl::hasMoreElements()
260 MutexGuard aGuard( aMutex );
261 return aIt != aImplementationMap.end();
264 // XEnumeration
265 Any ImplementationEnumeration_Impl::nextElement()
267 MutexGuard aGuard( aMutex );
268 if( aIt == aImplementationMap.end() )
269 throw NoSuchElementException("no more elements");
271 Any ret( &(*aIt), cppu::UnoType<XInterface>::get());
272 ++aIt;
273 return ret;
276 /*****************************************************************************
277 Hash tables
278 *****************************************************************************/
279 typedef std::unordered_set
281 OUString,
282 OUStringHash
283 > HashSet_OWString;
285 typedef std::unordered_multimap
287 OUString,
288 Reference<XInterface >,
289 OUStringHash
290 > HashMultimap_OWString_Interface;
292 typedef std::unordered_map
294 OUString,
295 Reference<XInterface >,
296 OUStringHash
297 > HashMap_OWString_Interface;
299 /*****************************************************************************
300 class OServiceManager_Listener
301 *****************************************************************************/
302 class OServiceManager_Listener : public WeakImplHelper< XEventListener >
304 private:
305 WeakReference<XSet > xSMgr;
307 public:
308 explicit OServiceManager_Listener( const Reference<XSet > & rSMgr )
309 : xSMgr( rSMgr )
312 // XEventListener
313 virtual void SAL_CALL disposing(const EventObject & rEvt ) override;
316 void OServiceManager_Listener::disposing(const EventObject & rEvt )
318 Reference<XSet > x( xSMgr );
319 if( x.is() )
323 x->remove( Any( &rEvt.Source, cppu::UnoType<XInterface>::get()) );
325 catch( const IllegalArgumentException & )
327 OSL_FAIL( "IllegalArgumentException caught" );
329 catch( const NoSuchElementException & )
331 OSL_FAIL( "NoSuchElementException caught" );
337 /*****************************************************************************
338 class OServiceManager
339 *****************************************************************************/
340 struct OServiceManagerMutex
342 Mutex m_mutex;
345 typedef WeakComponentImplHelper<
346 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
347 lang::XInitialization,
348 container::XSet, container::XContentEnumerationAccess,
349 beans::XPropertySet > t_OServiceManager_impl;
351 class OServiceManager
352 : public OServiceManagerMutex
353 , public t_OServiceManager_impl
355 public:
356 explicit OServiceManager( Reference< XComponentContext > const & xContext );
358 // XInitialization
359 void SAL_CALL initialize( Sequence< Any > const & args ) override;
361 // XServiceInfo
362 virtual OUString SAL_CALL getImplementationName() override;
363 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
364 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
366 // XMultiComponentFactory
367 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
368 OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext ) override;
369 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
370 OUString const & rServiceSpecifier,
371 Sequence< Any > const & rArguments,
372 Reference< XComponentContext > const & xContext ) override;
373 // virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
374 // throw (RuntimeException);
376 // XMultiServiceFactory
377 virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() override;
378 virtual Reference<XInterface > SAL_CALL createInstance(const OUString &) override;
379 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString &, const Sequence<Any >& Arguments) override;
381 // The same as the getAvailableServiceNames, but only unique names
382 Sequence< OUString > getUniqueAvailableServiceNames(
383 HashSet_OWString & aNameSet );
385 // XElementAccess
386 virtual Type SAL_CALL getElementType() override;
387 virtual sal_Bool SAL_CALL hasElements() override;
389 // XEnumerationAccess
390 virtual Reference<XEnumeration > SAL_CALL createEnumeration() override;
392 // XSet
393 virtual sal_Bool SAL_CALL has( const Any & Element ) override;
394 virtual void SAL_CALL insert( const Any & Element ) override;
395 virtual void SAL_CALL remove( const Any & Element ) override;
397 // XContentEnumerationAccess
398 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
399 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) override;
401 // XComponent
402 virtual void SAL_CALL dispose() override;
404 // XPropertySet
405 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
406 void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue) override;
407 Any SAL_CALL getPropertyValue(const OUString& PropertyName) override;
408 void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) override;
409 void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) override;
410 void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) override;
411 void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) override;
413 protected:
414 inline bool is_disposed() const;
415 inline void check_undisposed() const;
416 virtual void SAL_CALL disposing() override;
418 bool haveFactoryWithThisImplementation(const OUString& aImplName);
420 virtual Sequence< Reference< XInterface > > queryServiceFactories(
421 const OUString& aServiceName, Reference< XComponentContext > const & xContext );
423 Reference< XComponentContext > m_xContext;
425 Reference< beans::XPropertySetInfo > m_xPropertyInfo;
427 // factories which have been loaded and not inserted( by XSet::insert)
428 // are remembered by this set.
429 HashSet_Ref m_SetLoadedFactories;
430 private:
432 Reference<XEventListener > getFactoryListener();
435 HashMultimap_OWString_Interface m_ServiceMap;
436 HashSet_Ref m_ImplementationMap;
437 HashMap_OWString_Interface m_ImplementationNameMap;
438 Reference<XEventListener > xFactoryListener;
439 bool m_bInDisposing;
443 inline bool OServiceManager::is_disposed() const
445 // ought to be guarded by m_mutex:
446 return (m_bInDisposing || rBHelper.bDisposed);
450 inline void OServiceManager::check_undisposed() const
452 if (is_disposed())
454 throw lang::DisposedException(
455 "service manager instance has already been disposed!",
456 static_cast<OWeakObject *>(const_cast<OServiceManager *>(this)) );
461 typedef WeakComponentImplHelper<
462 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
463 container::XSet, container::XContentEnumerationAccess,
464 beans::XPropertySet > t_OServiceManagerWrapper_impl;
466 class OServiceManagerWrapper : public OServiceManagerMutex, public t_OServiceManagerWrapper_impl
468 Reference< XComponentContext > m_xContext;
469 Reference< XMultiComponentFactory > m_root;
470 Reference< XMultiComponentFactory > const & getRoot()
472 if (! m_root.is())
474 throw lang::DisposedException(
475 "service manager instance has already been disposed!" );
477 return m_root;
480 protected:
481 virtual void SAL_CALL disposing() override;
483 public:
484 explicit OServiceManagerWrapper(
485 Reference< XComponentContext > const & xContext );
487 // XServiceInfo
488 virtual OUString SAL_CALL getImplementationName() override
489 { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getImplementationName(); }
490 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override
491 { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->supportsService( ServiceName ); }
492 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override
493 { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getSupportedServiceNames(); }
495 // XMultiComponentFactory
496 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
497 OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext ) override
498 { return getRoot()->createInstanceWithContext( rServiceSpecifier, xContext ); }
499 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
500 OUString const & rServiceSpecifier,
501 Sequence< Any > const & rArguments,
502 Reference< XComponentContext > const & xContext ) override
503 { return getRoot()->createInstanceWithArgumentsAndContext( rServiceSpecifier, rArguments, xContext ); }
504 // virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
505 // throw (RuntimeException);
507 // XMultiServiceFactory
508 virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() override
509 { return getRoot()->getAvailableServiceNames(); }
510 virtual Reference<XInterface > SAL_CALL createInstance(const OUString & name) override
511 { return getRoot()->createInstanceWithContext( name, m_xContext ); }
512 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString & name, const Sequence<Any >& Arguments) override
513 { return getRoot()->createInstanceWithArgumentsAndContext( name, Arguments, m_xContext ); }
515 // XElementAccess
516 virtual Type SAL_CALL getElementType() override
517 { return Reference< XElementAccess >(getRoot(), UNO_QUERY_THROW)->getElementType(); }
518 virtual sal_Bool SAL_CALL hasElements() override
519 { return Reference< XElementAccess >(getRoot(), UNO_QUERY_THROW)->hasElements(); }
521 // XEnumerationAccess
522 virtual Reference<XEnumeration > SAL_CALL createEnumeration() override
523 { return Reference< XEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createEnumeration(); }
525 // XSet
526 virtual sal_Bool SAL_CALL has( const Any & Element ) override
527 { return Reference< XSet >(getRoot(), UNO_QUERY_THROW)->has( Element ); }
528 virtual void SAL_CALL insert( const Any & Element ) override
529 { Reference< XSet >(getRoot(), UNO_QUERY_THROW)->insert( Element ); }
530 virtual void SAL_CALL remove( const Any & Element ) override
531 { Reference< XSet >(getRoot(), UNO_QUERY_THROW)->remove( Element ); }
533 // XContentEnumerationAccess
534 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
535 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) override
536 { return Reference< XContentEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createContentEnumeration( aServiceName ); }
538 // XPropertySet
539 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() override
540 { return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertySetInfo(); }
542 void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue) override;
543 Any SAL_CALL getPropertyValue(const OUString& PropertyName) override;
545 void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) override
546 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->addPropertyChangeListener( PropertyName, aListener ); }
547 void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) override
548 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->removePropertyChangeListener( PropertyName, aListener ); }
549 void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) override
550 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->addVetoableChangeListener( PropertyName, aListener ); }
551 void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) override
552 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->removeVetoableChangeListener( PropertyName, aListener ); }
555 void SAL_CALL OServiceManagerWrapper::setPropertyValue(
556 const OUString& PropertyName, const Any& aValue )
558 if ( PropertyName == "DefaultContext" )
560 Reference< XComponentContext > xContext;
561 if (aValue >>= xContext)
563 MutexGuard aGuard( m_mutex );
564 m_xContext = xContext;
566 else
568 throw IllegalArgumentException(
569 "no XComponentContext given!",
570 static_cast<OWeakObject *>(this), 1 );
573 else
575 Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->setPropertyValue( PropertyName, aValue );
579 Any SAL_CALL OServiceManagerWrapper::getPropertyValue(
580 const OUString& PropertyName )
582 if ( PropertyName == "DefaultContext" )
584 MutexGuard aGuard( m_mutex );
585 if( m_xContext.is() )
586 return makeAny( m_xContext );
587 else
588 return Any();
590 else
592 return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertyValue( PropertyName );
596 void OServiceManagerWrapper::disposing()
598 m_xContext.clear();
600 // no m_root->dispose(), because every context disposes its service manager...
601 m_root.clear();
604 OServiceManagerWrapper::OServiceManagerWrapper(
605 Reference< XComponentContext > const & xContext )
606 : t_OServiceManagerWrapper_impl( m_mutex )
607 , m_xContext( xContext )
608 , m_root( xContext->getServiceManager() )
610 if (! m_root.is())
612 throw RuntimeException(
613 "no service manager to wrap" );
619 * Create a ServiceManager
621 OServiceManager::OServiceManager( Reference< XComponentContext > const & xContext )
622 : t_OServiceManager_impl( m_mutex )
623 , m_xContext( xContext )
624 , m_bInDisposing( false )
627 // XComponent
628 void OServiceManager::dispose()
630 if (rBHelper.bDisposed || rBHelper.bInDispose)
631 return;
632 t_OServiceManager_impl::dispose();
635 void OServiceManager::disposing()
637 // dispose all factories
638 HashSet_Ref aImpls;
640 MutexGuard aGuard( m_mutex );
641 m_bInDisposing = true;
642 aImpls = m_ImplementationMap;
644 HashSet_Ref::iterator aIt = aImpls.begin();
645 while( aIt != aImpls.end() )
649 Reference<XComponent > xComp( Reference<XComponent >::query( *aIt++ ) );
650 if( xComp.is() )
651 xComp->dispose();
653 catch (const RuntimeException & exc)
655 SAL_INFO("stoc", "RuntimeException occurred upon disposing factory: " << exc.Message);
659 // dispose
660 HashSet_Ref aImplMap;
662 MutexGuard aGuard( m_mutex );
663 // erase all members
664 m_ServiceMap = HashMultimap_OWString_Interface();
665 aImplMap = m_ImplementationMap;
666 m_ImplementationMap = HashSet_Ref();
667 m_ImplementationNameMap = HashMap_OWString_Interface();
668 m_SetLoadedFactories= HashSet_Ref();
671 m_xContext.clear();
673 // not only the Event should hold the object
674 OSL_ASSERT( m_refCount != 1 );
677 // XPropertySet
678 Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo()
680 check_undisposed();
681 if (! m_xPropertyInfo.is())
683 Sequence< beans::Property > seq( 1 );
684 seq[ 0 ] = beans::Property(
685 "DefaultContext", -1, cppu::UnoType<decltype(m_xContext)>::get(), 0 );
686 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
688 MutexGuard aGuard( m_mutex );
689 if (! m_xPropertyInfo.is())
691 m_xPropertyInfo = xInfo;
694 return m_xPropertyInfo;
697 void OServiceManager::setPropertyValue(
698 const OUString& PropertyName, const Any& aValue )
700 check_undisposed();
701 if ( PropertyName == "DefaultContext" )
703 Reference< XComponentContext > xContext;
704 if (aValue >>= xContext)
706 MutexGuard aGuard( m_mutex );
707 m_xContext = xContext;
709 else
711 throw IllegalArgumentException(
712 "no XComponentContext given!",
713 static_cast<OWeakObject *>(this), 1 );
716 else
718 throw UnknownPropertyException(
719 "unknown property " + PropertyName,
720 static_cast<OWeakObject *>(this) );
724 Any OServiceManager::getPropertyValue(const OUString& PropertyName)
726 check_undisposed();
727 if ( PropertyName == "DefaultContext" )
729 MutexGuard aGuard( m_mutex );
730 if( m_xContext.is() )
731 return makeAny( m_xContext );
732 else
733 return Any();
735 else
737 UnknownPropertyException except;
738 except.Message = "ServiceManager : unknown property " + PropertyName;
739 throw except;
743 void OServiceManager::addPropertyChangeListener(
744 const OUString&, const Reference<XPropertyChangeListener >&)
746 check_undisposed();
747 throw UnknownPropertyException("unsupported");
750 void OServiceManager::removePropertyChangeListener(
751 const OUString&, const Reference<XPropertyChangeListener >&)
753 check_undisposed();
754 throw UnknownPropertyException("unsupported");
757 void OServiceManager::addVetoableChangeListener(
758 const OUString&, const Reference<XVetoableChangeListener >&)
760 check_undisposed();
761 throw UnknownPropertyException("unsupported");
764 void OServiceManager::removeVetoableChangeListener(
765 const OUString&, const Reference<XVetoableChangeListener >&)
767 check_undisposed();
768 throw UnknownPropertyException("unsupported");
771 // OServiceManager
772 Reference<XEventListener > OServiceManager::getFactoryListener()
774 check_undisposed();
775 MutexGuard aGuard( m_mutex );
776 if( !xFactoryListener.is() )
777 xFactoryListener = new OServiceManager_Listener( this );
778 return xFactoryListener;
781 // XMultiServiceFactory, XContentEnumeration
782 Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames(
783 HashSet_OWString & aNameSet )
785 check_undisposed();
786 MutexGuard aGuard( m_mutex );
787 HashMultimap_OWString_Interface::iterator aSIt = m_ServiceMap.begin();
788 while( aSIt != m_ServiceMap.end() )
789 aNameSet.insert( (*aSIt++).first );
791 /* do not return the implementation names
792 HashMap_OWString_Interface m_ImplementationNameMap;
793 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.begin();
794 while( aIt != m_ImplementationNameMap.end() )
795 aNameSet.insert( (*aIt++).first );
798 return comphelper::containerToSequence(aNameSet);
801 // XMultiComponentFactory
802 Reference< XInterface > OServiceManager::createInstanceWithContext(
803 OUString const & rServiceSpecifier,
804 Reference< XComponentContext > const & xContext )
806 check_undisposed();
807 #if OSL_DEBUG_LEVEL > 0
808 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
809 OSL_ASSERT( xProps.is() );
810 if (xProps.is())
812 Reference< XComponentContext > xDefContext;
813 xProps->getPropertyValue( "DefaultContext" ) >>= xDefContext;
814 OSL_ENSURE(
815 xContext == xDefContext,
816 "### default context of service manager singleton differs from context holding it!" );
818 #endif
820 Sequence< Reference< XInterface > > factories(
821 queryServiceFactories( rServiceSpecifier, xContext ) );
822 Reference< XInterface > const * p = factories.getConstArray();
823 for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos )
827 Reference< XInterface > const & xFactory = p[ nPos ];
828 if (xFactory.is())
830 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
831 if (xFac.is())
833 return xFac->createInstanceWithContext( xContext );
835 else
837 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
838 if (xFac2.is())
840 SAL_INFO("stoc", "ignoring given context raising service " << rServiceSpecifier << "!!!");
841 return xFac2->createInstance();
846 catch (const lang::DisposedException & exc)
848 SAL_INFO("stoc", "DisposedException occurred: " << exc.Message);
852 return Reference< XInterface >();
854 // XMultiComponentFactory
855 Reference< XInterface > OServiceManager::createInstanceWithArgumentsAndContext(
856 OUString const & rServiceSpecifier,
857 Sequence< Any > const & rArguments,
858 Reference< XComponentContext > const & xContext )
860 check_undisposed();
861 #if OSL_DEBUG_LEVEL > 0
862 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
863 OSL_ASSERT( xProps.is() );
864 if (xProps.is())
866 Reference< XComponentContext > xDefContext;
867 xProps->getPropertyValue( "DefaultContext" ) >>= xDefContext;
868 OSL_ENSURE(
869 xContext == xDefContext,
870 "### default context of service manager singleton differs from context holding it!" );
872 #endif
874 Sequence< Reference< XInterface > > factories(
875 queryServiceFactories( rServiceSpecifier, xContext ) );
876 Reference< XInterface > const * p = factories.getConstArray();
877 for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos )
881 Reference< XInterface > const & xFactory = p[ nPos ];
882 if (xFactory.is())
884 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
885 if (xFac.is())
887 return xFac->createInstanceWithArgumentsAndContext( rArguments, xContext );
889 else
891 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
892 if (xFac2.is())
894 SAL_INFO("stoc", "ignoring given context raising service " << rServiceSpecifier << "!!!");
895 return xFac2->createInstanceWithArguments( rArguments );
900 catch (const lang::DisposedException & exc)
902 SAL_INFO("stoc", "DisposedException occurred: " << exc.Message);
906 return Reference< XInterface >();
909 // XMultiServiceFactory, XMultiComponentFactory, XContentEnumeration
910 Sequence< OUString > OServiceManager::getAvailableServiceNames()
912 check_undisposed();
913 // all names
914 HashSet_OWString aNameSet;
915 return getUniqueAvailableServiceNames( aNameSet );
918 // XMultibleServiceFactory
919 Reference<XInterface > OServiceManager::createInstance(
920 const OUString& rServiceSpecifier )
922 return createInstanceWithContext(
923 rServiceSpecifier, m_xContext );
926 // XMultibleServiceFactory
927 Reference<XInterface > OServiceManager::createInstanceWithArguments(
928 const OUString& rServiceSpecifier,
929 const Sequence<Any >& rArguments )
931 return createInstanceWithArgumentsAndContext(
932 rServiceSpecifier, rArguments, m_xContext );
935 // XInitialization
936 void OServiceManager::initialize( Sequence< Any > const & )
938 check_undisposed();
939 OSL_FAIL( "not impl!" );
942 // XServiceInfo
943 OUString OServiceManager::getImplementationName()
945 return OUString("com.sun.star.comp.stoc.OServiceManager");
948 // XServiceInfo
949 sal_Bool OServiceManager::supportsService(const OUString& ServiceName)
951 return cppu::supportsService(this, ServiceName);
954 // XServiceInfo
955 Sequence< OUString > OServiceManager::getSupportedServiceNames()
957 Sequence< OUString > seqNames(2);
958 seqNames[0] = "com.sun.star.lang.MultiServiceFactory";
959 seqNames[1] = "com.sun.star.lang.ServiceManager";
960 return seqNames;
964 Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories(
965 const OUString& aServiceName, Reference< XComponentContext > const & )
967 Sequence< Reference< XInterface > > ret;
969 MutexGuard aGuard( m_mutex );
970 ::std::pair<
971 HashMultimap_OWString_Interface::iterator,
972 HashMultimap_OWString_Interface::iterator> p(
973 m_ServiceMap.equal_range( aServiceName ) );
975 if (p.first == p.second) // no factories
977 // no service found, look for an implementation
978 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.find( aServiceName );
979 if( aIt != m_ImplementationNameMap.end() )
981 Reference< XInterface > const & x = aIt->second;
982 // an implementation found
983 ret = Sequence< Reference< XInterface > >( &x, 1 );
986 else
988 ::std::vector< Reference< XInterface > > vec;
989 vec.reserve( 4 );
990 while (p.first != p.second)
992 vec.push_back( p.first->second );
993 ++p.first;
995 ret = Sequence< Reference< XInterface > >( vec.data(), vec.size() );
998 return ret;
1001 // XContentEnumerationAccess
1002 Reference<XEnumeration > OServiceManager::createContentEnumeration(
1003 const OUString& aServiceName )
1005 check_undisposed();
1006 Sequence< Reference< XInterface > > factories(
1007 OServiceManager::queryServiceFactories( aServiceName, m_xContext ) );
1008 if (factories.getLength())
1009 return new ServiceEnumeration_Impl( factories );
1010 else
1011 return Reference< XEnumeration >();
1014 // XEnumeration
1015 Reference<XEnumeration > OServiceManager::createEnumeration()
1017 check_undisposed();
1018 MutexGuard aGuard( m_mutex );
1019 return new ImplementationEnumeration_Impl( m_ImplementationMap );
1022 // XElementAccess
1023 Type OServiceManager::getElementType()
1025 check_undisposed();
1026 return cppu::UnoType<XInterface>::get();
1029 // XElementAccess
1030 sal_Bool OServiceManager::hasElements()
1032 check_undisposed();
1033 MutexGuard aGuard( m_mutex );
1034 return !m_ImplementationMap.empty();
1037 // XSet
1038 sal_Bool OServiceManager::has( const Any & Element )
1040 check_undisposed();
1041 if( Element.getValueTypeClass() == TypeClass_INTERFACE )
1043 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
1044 MutexGuard aGuard( m_mutex );
1045 return m_ImplementationMap.find( xEle ) !=
1046 m_ImplementationMap.end();
1048 else if (auto implName = o3tl::tryAccess<OUString>(Element))
1050 MutexGuard aGuard( m_mutex );
1051 return m_ImplementationNameMap.find( *implName ) !=
1052 m_ImplementationNameMap.end();
1054 return false;
1057 // XSet
1058 void OServiceManager::insert( const Any & Element )
1060 check_undisposed();
1061 if( Element.getValueTypeClass() != TypeClass_INTERFACE )
1063 throw IllegalArgumentException(
1064 "exception interface, got " + Element.getValueType().getTypeName(),
1065 Reference< XInterface >(), 0 );
1067 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
1070 MutexGuard aGuard( m_mutex );
1071 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1072 if( aIt != m_ImplementationMap.end() )
1074 throw ElementExistException( "element already exists!" );
1077 // put into the implementation hashmap
1078 m_ImplementationMap.insert( xEle );
1080 // put into the implementation name hashmap
1081 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1082 if( xInfo.is() )
1084 OUString aImplName = xInfo->getImplementationName();
1085 if( !aImplName.isEmpty() )
1086 m_ImplementationNameMap[ aImplName ] = xEle;
1088 //put into the service map
1089 Sequence< OUString > aServiceNames = xInfo->getSupportedServiceNames();
1090 const OUString * pArray = aServiceNames.getConstArray();
1091 for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ )
1093 m_ServiceMap.insert( HashMultimap_OWString_Interface::value_type(
1094 pArray[i], *o3tl::doAccess<Reference<XInterface>>(Element) ) );
1098 // add the disposing listener to the factory
1099 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1100 if( xComp.is() )
1101 xComp->addEventListener( getFactoryListener() );
1104 // helper function
1105 bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName)
1107 return ( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end());
1110 // XSet
1111 void OServiceManager::remove( const Any & Element )
1113 if (is_disposed())
1114 return;
1116 Reference<XInterface > xEle;
1117 if (Element.getValueTypeClass() == TypeClass_INTERFACE)
1119 xEle.set( Element, UNO_QUERY_THROW );
1121 else if (auto implName = o3tl::tryAccess<OUString>(Element))
1123 MutexGuard aGuard( m_mutex );
1124 HashMap_OWString_Interface::const_iterator const iFind(
1125 m_ImplementationNameMap.find( *implName ) );
1126 if (iFind == m_ImplementationNameMap.end())
1128 throw NoSuchElementException(
1129 "element is not in: " + *implName,
1130 static_cast< OWeakObject * >(this) );
1132 xEle = iFind->second;
1134 else
1136 throw IllegalArgumentException(
1137 "expected interface or string, got " + Element.getValueType().getTypeName(),
1138 Reference< XInterface >(), 0 );
1141 // remove the disposing listener from the factory
1142 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1143 if( xComp.is() )
1144 xComp->removeEventListener( getFactoryListener() );
1146 MutexGuard aGuard( m_mutex );
1147 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1148 if( aIt == m_ImplementationMap.end() )
1150 throw NoSuchElementException(
1151 "element not found",
1152 static_cast< OWeakObject * >(this) );
1154 //First remove all factories which have been loaded by ORegistryServiceManager.
1155 m_SetLoadedFactories.erase( *aIt);
1156 //Remove from the implementation map. It contains all factories of m_SetLoadedFactories
1157 //which have been added directly through XSet, that is not via ORegistryServiceManager
1158 m_ImplementationMap.erase( aIt );
1160 // remove from the implementation name hashmap
1161 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1162 if( xInfo.is() )
1164 OUString aImplName = xInfo->getImplementationName();
1165 if( !aImplName.isEmpty() )
1166 m_ImplementationNameMap.erase( aImplName );
1169 //remove from the service map
1170 Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) );
1171 if( xSF.is() )
1173 Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames();
1174 const OUString * pArray = aServiceNames.getConstArray();
1175 for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ )
1177 pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> p =
1178 m_ServiceMap.equal_range( pArray[i] );
1180 while( p.first != p.second )
1182 if( xEle == (*p.first).second )
1184 m_ServiceMap.erase( p.first );
1185 break;
1187 ++p.first;
1193 /*****************************************************************************
1194 class ORegistryServiceManager
1195 *****************************************************************************/
1196 class ORegistryServiceManager : public OServiceManager
1198 public:
1199 explicit ORegistryServiceManager( Reference< XComponentContext > const & xContext );
1201 // XInitialization
1202 void SAL_CALL initialize(const Sequence< Any >& Arguments) override;
1204 // XServiceInfo
1205 OUString SAL_CALL getImplementationName() override
1206 { return OUString("com.sun.star.comp.stoc.ORegistryServiceManager"); }
1208 Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
1210 // XMultiServiceFactory
1211 Sequence< OUString > SAL_CALL getAvailableServiceNames() override;
1213 // XContentEnumerationAccess
1214 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
1215 Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) override;
1217 // XComponent
1218 void SAL_CALL dispose() override;
1220 // OServiceManager
1221 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
1222 Any SAL_CALL getPropertyValue(const OUString& PropertyName) override;
1224 protected:
1225 //OServiceManager
1226 Sequence< Reference< XInterface > > queryServiceFactories(
1227 const OUString& aServiceName, Reference< XComponentContext > const & xContext ) override;
1228 private:
1229 Reference<XRegistryKey > getRootKey();
1230 Reference<XInterface > loadWithImplementationName(
1231 const OUString & rImplName, Reference< XComponentContext > const & xContext );
1232 Sequence<OUString> getFromServiceName(const OUString& serviceName);
1233 Reference<XInterface > loadWithServiceName(
1234 const OUString & rImplName, Reference< XComponentContext > const & xContext );
1235 void fillAllNamesFromRegistry( HashSet_OWString & );
1237 bool m_searchedRegistry;
1238 Reference<XSimpleRegistry > m_xRegistry; // readonly property Registry
1239 Reference<XRegistryKey > m_xRootKey;
1241 #if OSL_DEBUG_LEVEL > 0
1242 bool m_init;
1243 #endif
1247 * Create a ServiceManager
1249 ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext > const & xContext )
1250 : OServiceManager( xContext )
1251 , m_searchedRegistry(false)
1252 #if OSL_DEBUG_LEVEL > 0
1253 , m_init( false )
1254 #endif
1258 // XComponent
1259 void ORegistryServiceManager::dispose()
1261 if (rBHelper.bDisposed || rBHelper.bInDispose)
1262 return;
1263 OServiceManager::dispose();
1264 // dispose
1265 MutexGuard aGuard( m_mutex );
1266 // erase all members
1267 m_xRegistry.clear();
1268 m_xRootKey.clear();
1272 * Return the root key of the registry. The Default registry service is ordered
1273 * if no registry is set.
1275 //Reference<XServiceProvider > create_DefaultRegistry_ServiceProvider();
1277 Reference<XRegistryKey > ORegistryServiceManager::getRootKey()
1279 if( !m_xRootKey.is() )
1281 MutexGuard aGuard( m_mutex );
1282 // DefaultRegistry suchen !!!!
1283 if( !m_xRegistry.is() && !m_searchedRegistry )
1285 // NB. we only search this once
1286 m_searchedRegistry = true;
1288 m_xRegistry.set(
1289 createInstanceWithContext(
1290 "com.sun.star.registry.DefaultRegistry",
1291 m_xContext ),
1292 UNO_QUERY );
1294 if( m_xRegistry.is() && !m_xRootKey.is() )
1295 m_xRootKey = m_xRegistry->getRootKey();
1298 return m_xRootKey;
1302 * Create a service provider from the registry with an implementation name
1304 Reference<XInterface > ORegistryServiceManager::loadWithImplementationName(
1305 const OUString& name, Reference< XComponentContext > const & xContext )
1307 Reference<XInterface > ret;
1309 Reference<XRegistryKey > xRootKey = getRootKey();
1310 if( !xRootKey.is() )
1311 return ret;
1315 OUString implementationName = "/IMPLEMENTATIONS/" + name;
1316 Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName);
1318 if( xImpKey.is() )
1320 Reference< lang::XMultiServiceFactory > xMgr;
1321 if (xContext.is())
1322 xMgr.set( xContext->getServiceManager(), UNO_QUERY_THROW );
1323 else
1324 xMgr.set( this );
1325 ret = createSingleRegistryFactory( xMgr, name, xImpKey );
1326 insert( makeAny( ret ) );
1327 // Remember this factory as loaded in contrast to inserted ( XSet::insert)
1328 // factories. Those loaded factories in this set are candidates for being
1329 // released on an unloading notification.
1330 m_SetLoadedFactories.insert( ret);
1333 catch (InvalidRegistryException &)
1337 return ret;
1341 * Return all implementation out of the registry.
1343 Sequence<OUString> ORegistryServiceManager::getFromServiceName(
1344 const OUString& serviceName )
1346 OUStringBuffer buf;
1347 buf.append( "/SERVICES/" );
1348 buf.append( serviceName );
1349 return retrieveAsciiValueList( m_xRegistry, buf.makeStringAndClear() );
1353 * Create a service provider from the registry
1355 Reference<XInterface > ORegistryServiceManager::loadWithServiceName(
1356 const OUString& serviceName, Reference< XComponentContext > const & xContext )
1358 Sequence<OUString> implEntries = getFromServiceName( serviceName );
1359 for (sal_Int32 i = 0; i < implEntries.getLength(); i++)
1361 Reference< XInterface > x(
1362 loadWithImplementationName( implEntries.getConstArray()[i], xContext ) );
1363 if (x.is())
1364 return x;
1367 return Reference<XInterface >();
1371 * Return a sequence of all service names from the registry.
1373 void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet )
1375 Reference<XRegistryKey > xRootKey = getRootKey();
1376 if( !xRootKey.is() )
1377 return;
1381 Reference<XRegistryKey > xServicesKey = xRootKey->openKey( "SERVICES" );
1382 // root + /Services + /
1383 if( xServicesKey.is() )
1385 sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1;
1386 Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys();
1387 for( sal_Int32 i = 0; i < aKeys.getLength(); i++ )
1388 rSet.insert( aKeys.getConstArray()[i]->getKeyName().copy( nPrefix ) );
1391 catch (InvalidRegistryException &)
1396 // XInitialization
1397 void ORegistryServiceManager::initialize(const Sequence< Any >& Arguments)
1399 check_undisposed();
1400 MutexGuard aGuard( m_mutex );
1401 if (Arguments.getLength() > 0)
1403 m_xRootKey.clear();
1404 Arguments[ 0 ] >>= m_xRegistry;
1406 #if OSL_DEBUG_LEVEL > 0
1407 // to find all bootstrapping processes to be fixed...
1408 OSL_ENSURE( !m_init, "### second init of service manager instance!" );
1409 m_init = true;
1410 #endif
1413 // XMultiServiceFactory, XContentEnumeration
1414 Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames()
1416 check_undisposed();
1417 MutexGuard aGuard( m_mutex );
1418 // all names
1419 HashSet_OWString aNameSet;
1421 // all names from the registry
1422 fillAllNamesFromRegistry( aNameSet );
1424 return OServiceManager::getUniqueAvailableServiceNames( aNameSet );
1427 // XServiceInfo
1428 Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames()
1430 Sequence< OUString > seqNames(2);
1431 seqNames[0] = "com.sun.star.lang.MultiServiceFactory";
1432 seqNames[1] = "com.sun.star.lang.RegistryServiceManager";
1433 return seqNames;
1437 // OServiceManager
1438 Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories(
1439 const OUString& aServiceName, Reference< XComponentContext > const & xContext )
1441 Sequence< Reference< XInterface > > ret(
1442 OServiceManager::queryServiceFactories( aServiceName, xContext ) );
1443 if (ret.getLength())
1445 return ret;
1447 else
1449 MutexGuard aGuard( m_mutex );
1450 Reference< XInterface > x( loadWithServiceName( aServiceName, xContext ) );
1451 if (! x.is())
1452 x = loadWithImplementationName( aServiceName, xContext );
1453 return Sequence< Reference< XInterface > >( &x, 1 );
1457 // XContentEnumerationAccess
1458 Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
1459 const OUString& aServiceName )
1461 check_undisposed();
1462 MutexGuard aGuard(m_mutex);
1463 // get all implementation names registered under this service name from the registry
1464 Sequence<OUString> aImpls = getFromServiceName( aServiceName );
1465 // load and insert all factories specified by the registry
1466 sal_Int32 i;
1467 OUString aImplName;
1468 for( i = 0; i < aImpls.getLength(); i++ )
1470 aImplName = aImpls.getConstArray()[i];
1471 if ( !haveFactoryWithThisImplementation(aImplName) )
1473 loadWithImplementationName( aImplName, m_xContext );
1476 // call the superclass to enumerate all contents
1477 return OServiceManager::createContentEnumeration( aServiceName );
1480 // OServiceManager
1481 Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo()
1483 check_undisposed();
1484 if (! m_xPropertyInfo.is())
1486 Sequence< beans::Property > seq( 2 );
1487 seq[ 0 ] = beans::Property(
1488 "DefaultContext", -1, cppu::UnoType<decltype(m_xContext)>::get(), 0 );
1489 seq[ 1 ] = beans::Property(
1490 "Registry", -1, cppu::UnoType<decltype(m_xRegistry)>::get(),
1491 beans::PropertyAttribute::READONLY );
1492 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
1494 MutexGuard aGuard( m_mutex );
1495 if (! m_xPropertyInfo.is())
1497 m_xPropertyInfo = xInfo;
1500 return m_xPropertyInfo;
1503 Any ORegistryServiceManager::getPropertyValue(const OUString& PropertyName)
1505 check_undisposed();
1506 if ( PropertyName == "Registry" )
1508 MutexGuard aGuard( m_mutex );
1509 if( m_xRegistry.is() )
1510 return makeAny( m_xRegistry );
1511 else
1512 return Any();
1514 return OServiceManager::getPropertyValue( PropertyName );
1517 } // namespace
1519 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1520 com_sun_star_comp_stoc_OServiceManager_get_implementation(
1521 css::uno::XComponentContext *context,
1522 css::uno::Sequence<css::uno::Any> const &)
1524 return cppu::acquire(new OServiceManager(context));
1527 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1528 com_sun_star_comp_stoc_ORegistryServiceManager_get_implementation(
1529 css::uno::XComponentContext *context,
1530 css::uno::Sequence<css::uno::Any> const &)
1532 return cppu::acquire(new ORegistryServiceManager(context));
1535 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1536 com_sun_star_comp_stoc_OServiceManagerWrapper_get_implementation(
1537 css::uno::XComponentContext *context,
1538 css::uno::Sequence<css::uno::Any> const &)
1540 return cppu::acquire(new OServiceManagerWrapper(context));
1543 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */