cid#1640468 Dereference after null check
[LibreOffice.git] / stoc / source / servicemanager / servicemanager.cxx
blobb38381ddaddb5e809eab57543a8a45e23d507ff0
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 <sal/log.hxx>
27 #include <cppuhelper/basemutex.hxx>
28 #include <cppuhelper/factory.hxx>
29 #include <cppuhelper/weakref.hxx>
30 #include <cppuhelper/implbase.hxx>
31 #include <cppuhelper/compbase.hxx>
32 #include <cppuhelper/supportsservice.hxx>
33 #include <comphelper/sequence.hxx>
34 #include <rtl/ref.hxx>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
38 #include <com/sun/star/lang/XServiceInfo.hpp>
39 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
40 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
41 #include <com/sun/star/lang/XInitialization.hpp>
42 #include <com/sun/star/lang/XEventListener.hpp>
43 #include <com/sun/star/lang/DisposedException.hpp>
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 #include <com/sun/star/beans/PropertyAttribute.hpp>
46 #include <com/sun/star/registry/XRegistryKey.hpp>
47 #include <com/sun/star/registry/XSimpleRegistry.hpp>
48 #include <com/sun/star/container/XSet.hpp>
49 #include <com/sun/star/container/XElementAccess.hpp>
50 #include <com/sun/star/container/XEnumeration.hpp>
51 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
52 #include <com/sun/star/uno/XComponentContext.hpp>
54 #include <iterator>
55 #include <mutex>
56 #include <string_view>
57 #include <unordered_map>
58 #include <unordered_set>
59 #include <utility>
61 using namespace com::sun::star;
62 using namespace css::uno;
63 using namespace css::beans;
64 using namespace css::registry;
65 using namespace css::lang;
66 using namespace css::container;
67 using namespace cppu;
68 using namespace osl;
70 namespace {
72 Sequence< OUString > retrieveAsciiValueList(
73 const Reference< XSimpleRegistry > &xReg, const OUString &keyName )
75 Reference< XEnumerationAccess > xAccess( xReg, UNO_QUERY );
76 Sequence< OUString > seq;
77 if( xAccess.is() )
79 Reference< XEnumeration > xEnum = xAccess->createEnumeration();
80 while( xEnum.is() && xEnum->hasMoreElements() )
82 Reference< XSimpleRegistry > xTempReg;
83 xEnum->nextElement() >>= xTempReg;
84 if( xTempReg.is() )
86 const Sequence< OUString > seq2 = retrieveAsciiValueList( xTempReg, keyName );
88 if( seq2.hasElements() )
90 sal_Int32 n1Len = seq.getLength();
91 sal_Int32 n2Len = seq2.getLength();
93 seq.realloc( n1Len + n2Len );
94 std::copy(seq2.begin(), seq2.end(), std::next(seq.getArray(), n1Len));
99 else if( xReg.is () )
103 Reference< XRegistryKey > rRootKey = xReg->getRootKey();
104 if( rRootKey.is() )
106 Reference<XRegistryKey > xKey = rRootKey->openKey(keyName);
107 if( xKey.is() )
109 seq = xKey->getAsciiListValue();
113 catch( InvalidRegistryException & )
116 catch (InvalidValueException &)
120 return seq;
123 /*****************************************************************************
124 Enumeration by ServiceName
125 *****************************************************************************/
127 typedef std::unordered_set< Reference<XInterface > > HashSet_Ref;
130 class ServiceEnumeration_Impl : public WeakImplHelper< XEnumeration >
132 public:
133 explicit ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories )
134 : aFactories( rFactories )
135 , nIt( 0 )
138 // XEnumeration
139 sal_Bool SAL_CALL hasMoreElements() override;
140 Any SAL_CALL nextElement() override;
141 private:
142 std::mutex aMutex;
143 Sequence< Reference<XInterface > > aFactories;
144 sal_Int32 nIt;
147 // XEnumeration
148 sal_Bool ServiceEnumeration_Impl::hasMoreElements()
150 std::scoped_lock aGuard( aMutex );
151 return nIt != aFactories.getLength();
154 // XEnumeration
155 Any ServiceEnumeration_Impl::nextElement()
157 std::scoped_lock aGuard( aMutex );
158 if( nIt == aFactories.getLength() )
159 throw NoSuchElementException(u"no more elements"_ustr);
161 return Any( &aFactories[nIt++], cppu::UnoType<XInterface>::get());
165 class PropertySetInfo_Impl : public WeakImplHelper< beans::XPropertySetInfo >
167 Sequence< beans::Property > m_properties;
169 public:
170 explicit PropertySetInfo_Impl( Sequence< beans::Property > const & properties )
171 : m_properties( properties )
174 // XPropertySetInfo impl
175 virtual Sequence< beans::Property > SAL_CALL getProperties() override;
176 virtual beans::Property SAL_CALL getPropertyByName( OUString const & name ) override;
177 virtual sal_Bool SAL_CALL hasPropertyByName( OUString const & name ) override;
180 Sequence< beans::Property > PropertySetInfo_Impl::getProperties()
182 return m_properties;
185 beans::Property PropertySetInfo_Impl::getPropertyByName( OUString const & name )
187 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
189 if (m_properties[nPos].Name == name)
190 return m_properties[nPos];
192 throw beans::UnknownPropertyException(
193 "unknown property: " + name );
196 sal_Bool PropertySetInfo_Impl::hasPropertyByName( OUString const & name )
198 return std::any_of(std::cbegin(m_properties), std::cend(m_properties),
199 [&name](const beans::Property& rProp) { return rProp.Name == name; });
203 /*****************************************************************************
204 Enumeration by implementation
205 *****************************************************************************/
206 class ImplementationEnumeration_Impl : public WeakImplHelper< XEnumeration >
208 public:
209 explicit ImplementationEnumeration_Impl( HashSet_Ref xImplementationMap )
210 : aImplementationMap(std::move( xImplementationMap ))
211 , aIt( aImplementationMap.begin() )
214 // XEnumeration
215 virtual sal_Bool SAL_CALL hasMoreElements() override;
216 virtual Any SAL_CALL nextElement() override;
218 private:
219 std::mutex aMutex;
220 HashSet_Ref aImplementationMap;
221 HashSet_Ref::iterator aIt;
224 // XEnumeration
225 sal_Bool ImplementationEnumeration_Impl::hasMoreElements()
227 std::scoped_lock aGuard( aMutex );
228 return aIt != aImplementationMap.end();
231 // XEnumeration
232 Any ImplementationEnumeration_Impl::nextElement()
234 std::scoped_lock aGuard( aMutex );
235 if( aIt == aImplementationMap.end() )
236 throw NoSuchElementException(u"no more elements"_ustr);
238 Any ret( &(*aIt), cppu::UnoType<XInterface>::get());
239 ++aIt;
240 return ret;
243 /*****************************************************************************
244 Hash tables
245 *****************************************************************************/
246 typedef std::unordered_set
248 OUString
249 > HashSet_OWString;
251 typedef std::unordered_multimap
253 OUString,
254 Reference<XInterface >
255 > HashMultimap_OWString_Interface;
257 typedef std::unordered_map
259 OUString,
260 Reference<XInterface >
261 > HashMap_OWString_Interface;
263 /*****************************************************************************
264 class OServiceManager_Listener
265 *****************************************************************************/
266 class OServiceManager_Listener : public WeakImplHelper< XEventListener >
268 private:
269 WeakReference<XSet > xSMgr;
271 public:
272 explicit OServiceManager_Listener( const Reference<XSet > & rSMgr )
273 : xSMgr( rSMgr )
276 // XEventListener
277 virtual void SAL_CALL disposing(const EventObject & rEvt ) override;
280 void OServiceManager_Listener::disposing(const EventObject & rEvt )
282 Reference<XSet > x( xSMgr );
283 if( !x.is() )
284 return;
288 x->remove( Any( &rEvt.Source, cppu::UnoType<XInterface>::get()) );
290 catch( const IllegalArgumentException & )
292 OSL_FAIL( "IllegalArgumentException caught" );
294 catch( const NoSuchElementException & )
296 OSL_FAIL( "NoSuchElementException caught" );
301 /*****************************************************************************
302 class OServiceManager
303 *****************************************************************************/
305 typedef WeakComponentImplHelper<
306 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
307 lang::XInitialization,
308 container::XSet, container::XContentEnumerationAccess,
309 beans::XPropertySet > t_OServiceManager_impl;
311 class OServiceManager
312 : public cppu::BaseMutex
313 , public t_OServiceManager_impl
315 public:
316 explicit OServiceManager( Reference< XComponentContext > const & xContext );
318 // XInitialization
319 void SAL_CALL initialize( Sequence< Any > const & args ) override;
321 // XServiceInfo
322 virtual OUString SAL_CALL getImplementationName() override;
323 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
324 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
326 // XMultiComponentFactory
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;
333 // virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
334 // throw (RuntimeException);
336 // XMultiServiceFactory
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;
341 // The same as the getAvailableServiceNames, but only unique names
342 Sequence< OUString > getUniqueAvailableServiceNames(
343 HashSet_OWString & aNameSet );
345 // XElementAccess
346 virtual Type SAL_CALL getElementType() override;
347 virtual sal_Bool SAL_CALL hasElements() override;
349 // XEnumerationAccess
350 virtual Reference<XEnumeration > SAL_CALL createEnumeration() override;
352 // XSet
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;
357 // XContentEnumerationAccess
358 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
359 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) override;
361 // XComponent
362 virtual void SAL_CALL dispose() override;
364 // XPropertySet
365 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
366 void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue) override;
367 Any SAL_CALL getPropertyValue(const OUString& PropertyName) 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;
373 protected:
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 );
383 Reference< XComponentContext > m_xContext;
385 Reference< beans::XPropertySetInfo > m_xPropertyInfo;
387 // factories which have been loaded and not inserted( by XSet::insert)
388 // are remembered by this set.
389 HashSet_Ref m_SetLoadedFactories;
390 private:
392 Reference<XEventListener > getFactoryListener();
395 HashMultimap_OWString_Interface m_ServiceMap;
396 HashSet_Ref m_ImplementationMap;
397 HashMap_OWString_Interface m_ImplementationNameMap;
398 rtl::Reference<OServiceManager_Listener > xFactoryListener;
399 bool m_bInDisposing;
403 bool OServiceManager::is_disposed() const
405 // ought to be guarded by m_mutex:
406 return (m_bInDisposing || rBHelper.bDisposed);
410 void OServiceManager::check_undisposed() const
412 if (is_disposed())
414 throw lang::DisposedException(
415 u"service manager instance has already been disposed!"_ustr,
416 const_cast<OServiceManager *>(this)->getXWeak() );
421 typedef WeakComponentImplHelper<
422 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
423 container::XSet, container::XContentEnumerationAccess,
424 beans::XPropertySet > t_OServiceManagerWrapper_impl;
426 class OServiceManagerWrapper : public cppu::BaseMutex, public t_OServiceManagerWrapper_impl
428 Reference< XComponentContext > m_xContext;
429 Reference< XMultiComponentFactory > m_root;
430 Reference< XMultiComponentFactory > const & getRoot() const
432 if (! m_root.is())
434 throw lang::DisposedException(
435 u"service manager instance has already been disposed!"_ustr );
437 return m_root;
440 protected:
441 virtual void SAL_CALL disposing() override;
443 public:
444 explicit OServiceManagerWrapper(
445 Reference< XComponentContext > const & xContext );
447 // XServiceInfo
448 virtual OUString SAL_CALL getImplementationName() override
449 { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getImplementationName(); }
450 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override
451 { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->supportsService( ServiceName ); }
452 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override
453 { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getSupportedServiceNames(); }
455 // XMultiComponentFactory
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 ); }
464 // virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
465 // throw (RuntimeException);
467 // XMultiServiceFactory
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 ); }
475 // XElementAccess
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(); }
481 // XEnumerationAccess
482 virtual Reference<XEnumeration > SAL_CALL createEnumeration() override
483 { return Reference< XEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createEnumeration(); }
485 // XSet
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 ); }
493 // XContentEnumerationAccess
494 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
495 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) override
496 { return Reference< XContentEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createContentEnumeration( aServiceName ); }
498 // XPropertySet
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;
503 Any SAL_CALL getPropertyValue(const OUString& PropertyName) 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 ); }
515 void 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 u"no XComponentContext given!"_ustr,
525 getXWeak(), 1 );
528 MutexGuard aGuard( m_aMutex );
529 m_xContext = std::move(xContext);
532 else
534 Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->setPropertyValue( PropertyName, aValue );
538 Any SAL_CALL OServiceManagerWrapper::getPropertyValue(
539 const OUString& PropertyName )
541 if ( PropertyName == "DefaultContext" )
543 MutexGuard aGuard( m_aMutex );
544 if( m_xContext.is() )
545 return Any( m_xContext );
546 else
547 return Any();
549 else
551 return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertyValue( PropertyName );
555 void OServiceManagerWrapper::disposing()
557 m_xContext.clear();
559 // no m_root->dispose(), because every context disposes its service manager...
560 m_root.clear();
563 OServiceManagerWrapper::OServiceManagerWrapper(
564 Reference< XComponentContext > const & xContext )
565 : t_OServiceManagerWrapper_impl( m_aMutex )
566 , m_xContext( xContext )
567 , m_root( xContext->getServiceManager() )
569 if (! m_root.is())
571 throw RuntimeException(
572 u"no service manager to wrap"_ustr );
578 * Create a ServiceManager
580 OServiceManager::OServiceManager( Reference< XComponentContext > const & xContext )
581 : t_OServiceManager_impl( m_aMutex )
582 , m_xContext( xContext )
583 , m_bInDisposing( false )
586 // XComponent
587 void OServiceManager::dispose()
589 if (rBHelper.bDisposed || rBHelper.bInDispose)
590 return;
591 t_OServiceManager_impl::dispose();
594 void OServiceManager::disposing()
596 // dispose all factories
597 HashSet_Ref aImpls;
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 ) );
608 if( xComp.is() )
609 xComp->dispose();
611 catch (const RuntimeException & exc)
613 SAL_INFO("stoc", "RuntimeException occurred upon disposing factory: " << exc);
617 // dispose
618 HashSet_Ref aImplMap;
620 MutexGuard aGuard( m_aMutex );
621 // erase all members
622 m_ServiceMap = HashMultimap_OWString_Interface();
623 aImplMap = m_ImplementationMap;
624 m_ImplementationMap = HashSet_Ref();
625 m_ImplementationNameMap = HashMap_OWString_Interface();
626 m_SetLoadedFactories= HashSet_Ref();
629 m_xContext.clear();
631 // not only the Event should hold the object
632 OSL_ASSERT( m_refCount != 1 );
635 // XPropertySet
636 Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo()
638 check_undisposed();
639 if (! m_xPropertyInfo.is())
641 Sequence< beans::Property > seq{ beans::Property(
642 u"DefaultContext"_ustr, -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 = std::move(xInfo);
651 return m_xPropertyInfo;
654 void OServiceManager::setPropertyValue(
655 const OUString& PropertyName, const Any& aValue )
657 check_undisposed();
658 if ( PropertyName != "DefaultContext" )
660 throw UnknownPropertyException(
661 "unknown property " + PropertyName,
662 getXWeak() );
665 Reference< XComponentContext > xContext;
666 if (!(aValue >>= xContext))
668 throw IllegalArgumentException(
669 u"no XComponentContext given!"_ustr,
670 getXWeak(), 1 );
673 MutexGuard aGuard( m_aMutex );
674 m_xContext = std::move(xContext);
677 Any OServiceManager::getPropertyValue(const OUString& PropertyName)
679 check_undisposed();
680 if ( PropertyName == "DefaultContext" )
682 MutexGuard aGuard( m_aMutex );
683 if( m_xContext.is() )
684 return Any( m_xContext );
685 else
686 return Any();
688 else
690 UnknownPropertyException except("ServiceManager : unknown property " + PropertyName, {});
691 throw except;
695 void OServiceManager::addPropertyChangeListener(
696 const OUString&, const Reference<XPropertyChangeListener >&)
698 check_undisposed();
699 throw UnknownPropertyException(u"unsupported"_ustr);
702 void OServiceManager::removePropertyChangeListener(
703 const OUString&, const Reference<XPropertyChangeListener >&)
705 check_undisposed();
706 throw UnknownPropertyException(u"unsupported"_ustr);
709 void OServiceManager::addVetoableChangeListener(
710 const OUString&, const Reference<XVetoableChangeListener >&)
712 check_undisposed();
713 throw UnknownPropertyException(u"unsupported"_ustr);
716 void OServiceManager::removeVetoableChangeListener(
717 const OUString&, const Reference<XVetoableChangeListener >&)
719 check_undisposed();
720 throw UnknownPropertyException(u"unsupported"_ustr);
723 // OServiceManager
724 Reference<XEventListener > OServiceManager::getFactoryListener()
726 check_undisposed();
727 MutexGuard aGuard( m_aMutex );
728 if( !xFactoryListener.is() )
729 xFactoryListener = new OServiceManager_Listener( this );
730 return xFactoryListener;
733 // XMultiServiceFactory, XContentEnumeration
734 Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames(
735 HashSet_OWString & aNameSet )
737 check_undisposed();
738 MutexGuard aGuard( m_aMutex );
739 for( const auto& rEntry : m_ServiceMap )
740 aNameSet.insert( rEntry.first );
742 /* do not return the implementation names
743 HashMap_OWString_Interface m_ImplementationNameMap;
744 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.begin();
745 while( aIt != m_ImplementationNameMap.end() )
746 aNameSet.insert( (*aIt++).first );
749 return comphelper::containerToSequence(aNameSet);
752 // XMultiComponentFactory
753 Reference< XInterface > OServiceManager::createInstanceWithContext(
754 OUString const & rServiceSpecifier,
755 Reference< XComponentContext > const & xContext )
757 check_undisposed();
758 #if OSL_DEBUG_LEVEL > 0
759 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
760 OSL_ASSERT( xProps.is() );
761 if (xProps.is())
763 Reference< XComponentContext > xDefContext;
764 xProps->getPropertyValue( u"DefaultContext"_ustr ) >>= xDefContext;
765 OSL_ENSURE(
766 xContext == xDefContext,
767 "### default context of service manager singleton differs from context holding it!" );
769 #endif
771 const Sequence< Reference< XInterface > > factories(
772 queryServiceFactories( rServiceSpecifier, xContext ) );
773 for ( Reference< XInterface > const & xFactory : factories )
777 if (xFactory.is())
779 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
780 if (xFac.is())
782 return xFac->createInstanceWithContext( xContext );
784 else
786 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
787 if (xFac2.is())
789 SAL_INFO("stoc", "ignoring given context raising service " << rServiceSpecifier << "!!!");
790 return xFac2->createInstance();
795 catch (const lang::DisposedException & exc)
797 SAL_INFO("stoc", "DisposedException occurred: " << exc);
801 return Reference< XInterface >();
803 // XMultiComponentFactory
804 Reference< XInterface > OServiceManager::createInstanceWithArgumentsAndContext(
805 OUString const & rServiceSpecifier,
806 Sequence< Any > const & rArguments,
807 Reference< XComponentContext > const & xContext )
809 check_undisposed();
810 #if OSL_DEBUG_LEVEL > 0
811 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
812 OSL_ASSERT( xProps.is() );
813 if (xProps.is())
815 Reference< XComponentContext > xDefContext;
816 xProps->getPropertyValue( u"DefaultContext"_ustr ) >>= xDefContext;
817 OSL_ENSURE(
818 xContext == xDefContext,
819 "### default context of service manager singleton differs from context holding it!" );
821 #endif
823 const Sequence< Reference< XInterface > > factories(
824 queryServiceFactories( rServiceSpecifier, xContext ) );
825 for ( Reference< XInterface > const & xFactory : factories )
829 if (xFactory.is())
831 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
832 if (xFac.is())
834 return xFac->createInstanceWithArgumentsAndContext( rArguments, xContext );
836 else
838 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
839 if (xFac2.is())
841 SAL_INFO("stoc", "ignoring given context raising service " << rServiceSpecifier << "!!!");
842 return xFac2->createInstanceWithArguments( rArguments );
847 catch (const lang::DisposedException & exc)
849 SAL_INFO("stoc", "DisposedException occurred: " << exc);
853 return Reference< XInterface >();
856 // XMultiServiceFactory, XMultiComponentFactory, XContentEnumeration
857 Sequence< OUString > OServiceManager::getAvailableServiceNames()
859 check_undisposed();
860 // all names
861 HashSet_OWString aNameSet;
862 return getUniqueAvailableServiceNames( aNameSet );
865 // XMultipleServiceFactory
866 Reference<XInterface > OServiceManager::createInstance(
867 const OUString& rServiceSpecifier )
869 return createInstanceWithContext(
870 rServiceSpecifier, m_xContext );
873 // XMultipleServiceFactory
874 Reference<XInterface > OServiceManager::createInstanceWithArguments(
875 const OUString& rServiceSpecifier,
876 const Sequence<Any >& rArguments )
878 return createInstanceWithArgumentsAndContext(
879 rServiceSpecifier, rArguments, m_xContext );
882 // XInitialization
883 void OServiceManager::initialize( Sequence< Any > const & )
885 check_undisposed();
886 OSL_FAIL( "not impl!" );
889 // XServiceInfo
890 OUString OServiceManager::getImplementationName()
892 return u"com.sun.star.comp.stoc.OServiceManager"_ustr;
895 // XServiceInfo
896 sal_Bool OServiceManager::supportsService(const OUString& ServiceName)
898 return cppu::supportsService(this, ServiceName);
901 // XServiceInfo
902 Sequence< OUString > OServiceManager::getSupportedServiceNames()
904 return { u"com.sun.star.lang.MultiServiceFactory"_ustr, u"com.sun.star.lang.ServiceManager"_ustr };
908 Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories(
909 const OUString& aServiceName, Reference< XComponentContext > const & )
911 Sequence< Reference< XInterface > > ret;
913 MutexGuard aGuard( m_aMutex );
914 ::std::pair<
915 HashMultimap_OWString_Interface::iterator,
916 HashMultimap_OWString_Interface::iterator> p(
917 m_ServiceMap.equal_range( aServiceName ) );
919 if (p.first == p.second) // no factories
921 // no service found, look for an implementation
922 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.find( aServiceName );
923 if( aIt != m_ImplementationNameMap.end() )
925 Reference< XInterface > const & x = aIt->second;
926 // an implementation found
927 ret = Sequence< Reference< XInterface > >( &x, 1 );
930 else
932 ::std::vector< Reference< XInterface > > vec;
933 vec.reserve( 4 );
934 while (p.first != p.second)
936 vec.push_back( p.first->second );
937 ++p.first;
939 ret = Sequence< Reference< XInterface > >( vec.data(), vec.size() );
942 return ret;
945 // XContentEnumerationAccess
946 Reference<XEnumeration > OServiceManager::createContentEnumeration(
947 const OUString& aServiceName )
949 check_undisposed();
950 Sequence< Reference< XInterface > > factories(
951 OServiceManager::queryServiceFactories( aServiceName, m_xContext ) );
952 if (factories.hasElements())
953 return new ServiceEnumeration_Impl( factories );
954 else
955 return Reference< XEnumeration >();
958 // XEnumeration
959 Reference<XEnumeration > OServiceManager::createEnumeration()
961 check_undisposed();
962 MutexGuard aGuard( m_aMutex );
963 return new ImplementationEnumeration_Impl( m_ImplementationMap );
966 // XElementAccess
967 Type OServiceManager::getElementType()
969 check_undisposed();
970 return cppu::UnoType<XInterface>::get();
973 // XElementAccess
974 sal_Bool OServiceManager::hasElements()
976 check_undisposed();
977 MutexGuard aGuard( m_aMutex );
978 return !m_ImplementationMap.empty();
981 // XSet
982 sal_Bool OServiceManager::has( const Any & Element )
984 check_undisposed();
985 if( Element.getValueTypeClass() == TypeClass_INTERFACE )
987 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
988 MutexGuard aGuard( m_aMutex );
989 return m_ImplementationMap.find( xEle ) !=
990 m_ImplementationMap.end();
992 else if (auto implName = o3tl::tryAccess<OUString>(Element))
994 MutexGuard aGuard( m_aMutex );
995 return m_ImplementationNameMap.find( *implName ) !=
996 m_ImplementationNameMap.end();
998 return false;
1001 // XSet
1002 void OServiceManager::insert( const Any & Element )
1004 check_undisposed();
1005 if( Element.getValueTypeClass() != TypeClass_INTERFACE )
1007 throw IllegalArgumentException(
1008 "exception interface, got " + Element.getValueTypeName(),
1009 Reference< XInterface >(), 0 );
1011 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
1014 MutexGuard aGuard( m_aMutex );
1015 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1016 if( aIt != m_ImplementationMap.end() )
1018 throw ElementExistException( u"element already exists!"_ustr );
1021 // put into the implementation hashmap
1022 m_ImplementationMap.insert( xEle );
1024 // put into the implementation name hashmap
1025 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1026 if( xInfo.is() )
1028 OUString aImplName = xInfo->getImplementationName();
1029 if( !aImplName.isEmpty() )
1030 m_ImplementationNameMap[ aImplName ] = xEle;
1032 //put into the service map
1033 const Sequence< OUString > aServiceNames = xInfo->getSupportedServiceNames();
1034 for( const OUString& rServiceName : aServiceNames )
1036 m_ServiceMap.emplace(
1037 rServiceName, *o3tl::doAccess<Reference<XInterface>>(Element) );
1041 // add the disposing listener to the factory
1042 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1043 if( xComp.is() )
1044 xComp->addEventListener( getFactoryListener() );
1047 // helper function
1048 bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName)
1050 return m_ImplementationNameMap.contains(aImplName);
1053 // XSet
1054 void OServiceManager::remove( const Any & Element )
1056 if (is_disposed())
1057 return;
1059 Reference<XInterface > xEle;
1060 if (Element.getValueTypeClass() == TypeClass_INTERFACE)
1062 xEle.set( Element, UNO_QUERY_THROW );
1064 else if (auto implName = o3tl::tryAccess<OUString>(Element))
1066 MutexGuard aGuard( m_aMutex );
1067 HashMap_OWString_Interface::const_iterator const iFind(
1068 m_ImplementationNameMap.find( *implName ) );
1069 if (iFind == m_ImplementationNameMap.end())
1071 throw NoSuchElementException(
1072 "element is not in: " + *implName,
1073 getXWeak() );
1075 xEle = iFind->second;
1077 else
1079 throw IllegalArgumentException(
1080 "expected interface or string, got " + Element.getValueTypeName(),
1081 Reference< XInterface >(), 0 );
1084 // remove the disposing listener from the factory
1085 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1086 if( xComp.is() )
1087 xComp->removeEventListener( getFactoryListener() );
1089 MutexGuard aGuard( m_aMutex );
1090 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1091 if( aIt == m_ImplementationMap.end() )
1093 throw NoSuchElementException(
1094 u"element not found"_ustr,
1095 getXWeak() );
1097 //First remove all factories which have been loaded by ORegistryServiceManager.
1098 m_SetLoadedFactories.erase( *aIt);
1099 //Remove from the implementation map. It contains all factories of m_SetLoadedFactories
1100 //which have been added directly through XSet, that is not via ORegistryServiceManager
1101 m_ImplementationMap.erase( aIt );
1103 // remove from the implementation name hashmap
1104 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1105 if( xInfo.is() )
1107 OUString aImplName = xInfo->getImplementationName();
1108 if( !aImplName.isEmpty() )
1109 m_ImplementationNameMap.erase( aImplName );
1112 //remove from the service map
1113 Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) );
1114 if( !xSF.is() )
1115 return;
1117 const Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames();
1118 for( const OUString& rServiceName : aServiceNames )
1120 std::pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> p =
1121 m_ServiceMap.equal_range( rServiceName );
1123 while( p.first != p.second )
1125 if( xEle == (*p.first).second )
1127 m_ServiceMap.erase( p.first );
1128 break;
1130 ++p.first;
1135 /*****************************************************************************
1136 class ORegistryServiceManager
1137 *****************************************************************************/
1138 class ORegistryServiceManager : public OServiceManager
1140 public:
1141 explicit ORegistryServiceManager( Reference< XComponentContext > const & xContext );
1143 // XInitialization
1144 void SAL_CALL initialize(const Sequence< Any >& Arguments) override;
1146 // XServiceInfo
1147 OUString SAL_CALL getImplementationName() override
1148 { return u"com.sun.star.comp.stoc.ORegistryServiceManager"_ustr; }
1150 Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
1152 // XMultiServiceFactory
1153 Sequence< OUString > SAL_CALL getAvailableServiceNames() override;
1155 // XContentEnumerationAccess
1156 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
1157 Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) override;
1159 // XComponent
1160 void SAL_CALL dispose() override;
1162 // OServiceManager
1163 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
1164 Any SAL_CALL getPropertyValue(const OUString& PropertyName) override;
1166 protected:
1167 //OServiceManager
1168 Sequence< Reference< XInterface > > queryServiceFactories(
1169 const OUString& aServiceName, Reference< XComponentContext > const & xContext ) override;
1170 private:
1171 Reference<XRegistryKey > getRootKey();
1172 Reference<XInterface > loadWithImplementationName(
1173 const OUString & rImplName, Reference< XComponentContext > const & xContext );
1174 Sequence<OUString> getFromServiceName(std::u16string_view serviceName) const;
1175 Reference<XInterface > loadWithServiceName(
1176 std::u16string_view rImplName, Reference< XComponentContext > const & xContext );
1177 void fillAllNamesFromRegistry( HashSet_OWString & );
1179 bool m_searchedRegistry;
1180 Reference<XSimpleRegistry > m_xRegistry; // readonly property Registry
1181 Reference<XRegistryKey > m_xRootKey;
1183 #if OSL_DEBUG_LEVEL > 0
1184 bool m_init;
1185 #endif
1189 * Create a ServiceManager
1191 ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext > const & xContext )
1192 : OServiceManager( xContext )
1193 , m_searchedRegistry(false)
1194 #if OSL_DEBUG_LEVEL > 0
1195 , m_init( false )
1196 #endif
1200 // XComponent
1201 void ORegistryServiceManager::dispose()
1203 if (rBHelper.bDisposed || rBHelper.bInDispose)
1204 return;
1205 OServiceManager::dispose();
1206 // dispose
1207 MutexGuard aGuard( m_aMutex );
1208 // erase all members
1209 m_xRegistry.clear();
1210 m_xRootKey.clear();
1214 * Return the root key of the registry. The Default registry service is ordered
1215 * if no registry is set.
1217 //Reference<XServiceProvider > create_DefaultRegistry_ServiceProvider();
1219 Reference<XRegistryKey > ORegistryServiceManager::getRootKey()
1221 if( !m_xRootKey.is() )
1223 MutexGuard aGuard( m_aMutex );
1224 // DefaultRegistry suchen !!!!
1225 if( !m_xRegistry.is() && !m_searchedRegistry )
1227 // NB. we only search this once
1228 m_searchedRegistry = true;
1230 m_xRegistry.set(
1231 createInstanceWithContext(
1232 u"com.sun.star.registry.DefaultRegistry"_ustr,
1233 m_xContext ),
1234 UNO_QUERY );
1236 if( m_xRegistry.is() && !m_xRootKey.is() )
1237 m_xRootKey = m_xRegistry->getRootKey();
1240 return m_xRootKey;
1244 * Create a service provider from the registry with an implementation name
1246 Reference<XInterface > ORegistryServiceManager::loadWithImplementationName(
1247 const OUString& name, Reference< XComponentContext > const & xContext )
1249 Reference<XInterface > ret;
1251 Reference<XRegistryKey > xRootKey = getRootKey();
1252 if( !xRootKey.is() )
1253 return ret;
1257 OUString implementationName = "/IMPLEMENTATIONS/" + name;
1258 Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName);
1260 if( xImpKey.is() )
1262 Reference< lang::XMultiServiceFactory > xMgr;
1263 if (xContext.is())
1264 xMgr.set( xContext->getServiceManager(), UNO_QUERY_THROW );
1265 else
1266 xMgr.set( this );
1267 ret = createSingleRegistryFactory( xMgr, name, xImpKey );
1268 insert( Any( ret ) );
1269 // Remember this factory as loaded in contrast to inserted ( XSet::insert)
1270 // factories. Those loaded factories in this set are candidates for being
1271 // released on an unloading notification.
1272 m_SetLoadedFactories.insert( ret);
1275 catch (InvalidRegistryException &)
1279 return ret;
1283 * Return all implementation out of the registry.
1285 Sequence<OUString> ORegistryServiceManager::getFromServiceName(
1286 std::u16string_view serviceName ) const
1288 OUString buf = OUString::Concat("/SERVICES/") + serviceName;
1289 return retrieveAsciiValueList( m_xRegistry, buf );
1293 * Create a service provider from the registry
1295 Reference<XInterface > ORegistryServiceManager::loadWithServiceName(
1296 std::u16string_view serviceName, Reference< XComponentContext > const & xContext )
1298 const Sequence<OUString> implEntries = getFromServiceName( serviceName );
1299 for (const auto& rEntry : implEntries)
1301 Reference< XInterface > x( loadWithImplementationName( rEntry, xContext ) );
1302 if (x.is())
1303 return x;
1306 return Reference<XInterface >();
1310 * Return a sequence of all service names from the registry.
1312 void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet )
1314 Reference<XRegistryKey > xRootKey = getRootKey();
1315 if( !xRootKey.is() )
1316 return;
1320 Reference<XRegistryKey > xServicesKey = xRootKey->openKey( u"SERVICES"_ustr );
1321 // root + /Services + /
1322 if( xServicesKey.is() )
1324 sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1;
1325 const Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys();
1326 std::transform(aKeys.begin(), aKeys.end(), std::inserter(rSet, rSet.end()),
1327 [nPrefix](const Reference<XRegistryKey>& rKey) -> OUString {
1328 return rKey->getKeyName().copy( nPrefix ); });
1331 catch (InvalidRegistryException &)
1336 // XInitialization
1337 void ORegistryServiceManager::initialize(const Sequence< Any >& Arguments)
1339 check_undisposed();
1340 MutexGuard aGuard( m_aMutex );
1341 if (Arguments.hasElements())
1343 m_xRootKey.clear();
1344 Arguments[ 0 ] >>= m_xRegistry;
1346 #if OSL_DEBUG_LEVEL > 0
1347 // to find all bootstrapping processes to be fixed...
1348 OSL_ENSURE( !m_init, "### second init of service manager instance!" );
1349 m_init = true;
1350 #endif
1353 // XMultiServiceFactory, XContentEnumeration
1354 Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames()
1356 check_undisposed();
1357 MutexGuard aGuard( m_aMutex );
1358 // all names
1359 HashSet_OWString aNameSet;
1361 // all names from the registry
1362 fillAllNamesFromRegistry( aNameSet );
1364 return OServiceManager::getUniqueAvailableServiceNames( aNameSet );
1367 // XServiceInfo
1368 Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames()
1370 return { u"com.sun.star.lang.MultiServiceFactory"_ustr, u"com.sun.star.lang.RegistryServiceManager"_ustr };
1374 // OServiceManager
1375 Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories(
1376 const OUString& aServiceName, Reference< XComponentContext > const & xContext )
1378 Sequence< Reference< XInterface > > ret(
1379 OServiceManager::queryServiceFactories( aServiceName, xContext ) );
1380 if (ret.hasElements())
1382 return ret;
1384 else
1386 MutexGuard aGuard( m_aMutex );
1387 Reference< XInterface > x( loadWithServiceName( aServiceName, xContext ) );
1388 if (! x.is())
1389 x = loadWithImplementationName( aServiceName, xContext );
1390 return Sequence< Reference< XInterface > >( &x, 1 );
1394 // XContentEnumerationAccess
1395 Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
1396 const OUString& aServiceName )
1398 check_undisposed();
1399 MutexGuard aGuard(m_aMutex);
1400 // get all implementation names registered under this service name from the registry
1401 const Sequence<OUString> aImpls = getFromServiceName( aServiceName );
1402 // load and insert all factories specified by the registry
1403 for( const OUString& aImplName : aImpls )
1405 if ( !haveFactoryWithThisImplementation(aImplName) )
1407 loadWithImplementationName( aImplName, m_xContext );
1410 // call the superclass to enumerate all contents
1411 return OServiceManager::createContentEnumeration( aServiceName );
1414 // OServiceManager
1415 Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo()
1417 check_undisposed();
1418 if (! m_xPropertyInfo.is())
1420 Sequence< beans::Property > seq{
1421 beans::Property(u"DefaultContext"_ustr, -1, cppu::UnoType<decltype(m_xContext)>::get(), 0),
1422 beans::Property(u"Registry"_ustr, -1, cppu::UnoType<decltype(m_xRegistry)>::get(),
1423 beans::PropertyAttribute::READONLY)
1425 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
1427 MutexGuard aGuard( m_aMutex );
1428 if (! m_xPropertyInfo.is())
1430 m_xPropertyInfo = std::move(xInfo);
1433 return m_xPropertyInfo;
1436 Any ORegistryServiceManager::getPropertyValue(const OUString& PropertyName)
1438 check_undisposed();
1439 if ( PropertyName == "Registry" )
1441 MutexGuard aGuard( m_aMutex );
1442 if( m_xRegistry.is() )
1443 return Any( m_xRegistry );
1444 else
1445 return Any();
1447 return OServiceManager::getPropertyValue( PropertyName );
1450 } // namespace
1452 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1453 com_sun_star_comp_stoc_OServiceManager_get_implementation(
1454 css::uno::XComponentContext *context,
1455 css::uno::Sequence<css::uno::Any> const &)
1457 return cppu::acquire(new OServiceManager(context));
1460 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1461 com_sun_star_comp_stoc_ORegistryServiceManager_get_implementation(
1462 css::uno::XComponentContext *context,
1463 css::uno::Sequence<css::uno::Any> const &)
1465 return cppu::acquire(new ORegistryServiceManager(context));
1468 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1469 com_sun_star_comp_stoc_OServiceManagerWrapper_get_implementation(
1470 css::uno::XComponentContext *context,
1471 css::uno::Sequence<css::uno::Any> const &)
1473 return cppu::acquire(new OServiceManagerWrapper(context));
1476 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */