LibreOffice Module stoc (master) 1
servicemanager.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <o3tl/any.hxx>
23#include <osl/mutex.hxx>
24#include <osl/diagnose.h>
25#include <sal/log.hxx>
26
34
35#include <com/sun/star/lang/XMultiServiceFactory.hpp>
36#include <com/sun/star/lang/XMultiComponentFactory.hpp>
37#include <com/sun/star/lang/XServiceInfo.hpp>
38#include <com/sun/star/lang/XSingleServiceFactory.hpp>
39#include <com/sun/star/lang/XSingleComponentFactory.hpp>
40#include <com/sun/star/lang/XInitialization.hpp>
41#include <com/sun/star/lang/XEventListener.hpp>
42#include <com/sun/star/lang/DisposedException.hpp>
43#include <com/sun/star/beans/XPropertySet.hpp>
44#include <com/sun/star/beans/PropertyAttribute.hpp>
45#include <com/sun/star/registry/XRegistryKey.hpp>
46#include <com/sun/star/registry/XSimpleRegistry.hpp>
47#include <com/sun/star/container/XSet.hpp>
48#include <com/sun/star/container/XElementAccess.hpp>
49#include <com/sun/star/container/XEnumeration.hpp>
50#include <com/sun/star/container/XContentEnumerationAccess.hpp>
51#include <com/sun/star/uno/XComponentContext.hpp>
52
53#include <iterator>
54#include <mutex>
55#include <string_view>
56#include <unordered_map>
57#include <unordered_set>
58#include <utility>
59
60using namespace com::sun::star;
61using namespace css::uno;
62using namespace css::beans;
63using namespace css::registry;
64using namespace css::lang;
65using namespace css::container;
66using namespace cppu;
67using namespace osl;
68
69namespace {
70
71Sequence< OUString > retrieveAsciiValueList(
72 const Reference< XSimpleRegistry > &xReg, const OUString &keyName )
73{
74 Reference< XEnumerationAccess > xAccess( xReg, UNO_QUERY );
75 Sequence< OUString > seq;
76 if( xAccess.is() )
77 {
78 Reference< XEnumeration > xEnum = xAccess->createEnumeration();
79 while( xEnum.is() && xEnum->hasMoreElements() )
80 {
81 Reference< XSimpleRegistry > xTempReg;
82 xEnum->nextElement() >>= xTempReg;
83 if( xTempReg.is() )
84 {
85 const Sequence< OUString > seq2 = retrieveAsciiValueList( xTempReg, keyName );
86
87 if( seq2.hasElements() )
88 {
89 sal_Int32 n1Len = seq.getLength();
90 sal_Int32 n2Len = seq2.getLength();
91
92 seq.realloc( n1Len + n2Len );
93 std::copy(seq2.begin(), seq2.end(), std::next(seq.getArray(), n1Len));
94 }
95 }
96 }
97 }
98 else if( xReg.is () )
99 {
100 try
101 {
102 Reference< XRegistryKey > rRootKey = xReg->getRootKey();
103 if( rRootKey.is() )
104 {
105 Reference<XRegistryKey > xKey = rRootKey->openKey(keyName);
106 if( xKey.is() )
107 {
108 seq = xKey->getAsciiListValue();
109 }
110 }
111 }
112 catch( InvalidRegistryException & )
113 {
114 }
115 catch (InvalidValueException &)
116 {
117 }
118 }
119 return seq;
120}
121
122/*****************************************************************************
123 Enumeration by ServiceName
124*****************************************************************************/
125
126typedef std::unordered_set< Reference<XInterface > > HashSet_Ref;
127
128
129class ServiceEnumeration_Impl : public WeakImplHelper< XEnumeration >
130{
131public:
132 explicit ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories )
133 : aFactories( rFactories )
134 , nIt( 0 )
135 {}
136
137 // XEnumeration
138 sal_Bool SAL_CALL hasMoreElements() override;
139 Any SAL_CALL nextElement() override;
140private:
141 std::mutex aMutex;
142 Sequence< Reference<XInterface > > aFactories;
143 sal_Int32 nIt;
144};
145
146// XEnumeration
147sal_Bool ServiceEnumeration_Impl::hasMoreElements()
148{
149 std::scoped_lock aGuard( aMutex );
150 return nIt != aFactories.getLength();
151}
152
153// XEnumeration
154Any ServiceEnumeration_Impl::nextElement()
155{
156 std::scoped_lock aGuard( aMutex );
157 if( nIt == aFactories.getLength() )
158 throw NoSuchElementException("no more elements");
159
160 return Any( &aFactories.getConstArray()[nIt++], cppu::UnoType<XInterface>::get());
161}
162
163
164class PropertySetInfo_Impl : public WeakImplHelper< beans::XPropertySetInfo >
165{
166 Sequence< beans::Property > m_properties;
167
168public:
169 explicit PropertySetInfo_Impl( Sequence< beans::Property > const & properties )
170 : m_properties( properties )
171 {}
172
173 // XPropertySetInfo impl
174 virtual Sequence< beans::Property > SAL_CALL getProperties() override;
175 virtual beans::Property SAL_CALL getPropertyByName( OUString const & name ) override;
176 virtual sal_Bool SAL_CALL hasPropertyByName( OUString const & name ) override;
177};
178
179Sequence< beans::Property > PropertySetInfo_Impl::getProperties()
180{
181 return m_properties;
182}
183
184beans::Property PropertySetInfo_Impl::getPropertyByName( OUString const & name )
185{
186 beans::Property const * p = m_properties.getConstArray();
187 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
188 {
189 if (p[ nPos ].Name == name)
190 return p[ nPos ];
191 }
192 throw beans::UnknownPropertyException(
193 "unknown property: " + name );
194}
195
197{
198 return std::any_of(std::cbegin(m_properties), std::cend(m_properties),
199 [&name](const beans::Property& rProp) { return rProp.Name == name; });
200}
201
202
203/*****************************************************************************
204 Enumeration by implementation
205*****************************************************************************/
206class ImplementationEnumeration_Impl : public WeakImplHelper< XEnumeration >
207{
208public:
209 explicit ImplementationEnumeration_Impl( HashSet_Ref xImplementationMap )
210 : aImplementationMap(std::move( xImplementationMap ))
211 , aIt( aImplementationMap.begin() )
212 {}
213
214 // XEnumeration
215 virtual sal_Bool SAL_CALL hasMoreElements() override;
216 virtual Any SAL_CALL nextElement() override;
217
218private:
219 std::mutex aMutex;
220 HashSet_Ref aImplementationMap;
221 HashSet_Ref::iterator aIt;
222};
223
224// XEnumeration
225sal_Bool ImplementationEnumeration_Impl::hasMoreElements()
226{
227 std::scoped_lock aGuard( aMutex );
228 return aIt != aImplementationMap.end();
229}
230
231// XEnumeration
232Any ImplementationEnumeration_Impl::nextElement()
233{
234 std::scoped_lock aGuard( aMutex );
235 if( aIt == aImplementationMap.end() )
236 throw NoSuchElementException("no more elements");
237
238 Any ret( &(*aIt), cppu::UnoType<XInterface>::get());
239 ++aIt;
240 return ret;
241}
242
243/*****************************************************************************
244 Hash tables
245*****************************************************************************/
246typedef std::unordered_set
247<
248 OUString
249> HashSet_OWString;
250
251typedef std::unordered_multimap
252<
253 OUString,
254 Reference<XInterface >
255> HashMultimap_OWString_Interface;
256
257typedef std::unordered_map
258<
259 OUString,
260 Reference<XInterface >
262
263/*****************************************************************************
264 class OServiceManager_Listener
265*****************************************************************************/
266class OServiceManager_Listener : public WeakImplHelper< XEventListener >
267{
268private:
269 WeakReference<XSet > xSMgr;
270
271public:
272 explicit OServiceManager_Listener( const Reference<XSet > & rSMgr )
273 : xSMgr( rSMgr )
274 {}
275
276 // XEventListener
277 virtual void SAL_CALL disposing(const EventObject & rEvt ) override;
278};
279
280void OServiceManager_Listener::disposing(const EventObject & rEvt )
281{
282 Reference<XSet > x( xSMgr );
283 if( !x.is() )
284 return;
285
286 try
287 {
288 x->remove( Any( &rEvt.Source, cppu::UnoType<XInterface>::get()) );
289 }
290 catch( const IllegalArgumentException & )
291 {
292 OSL_FAIL( "IllegalArgumentException caught" );
293 }
294 catch( const NoSuchElementException & )
295 {
296 OSL_FAIL( "NoSuchElementException caught" );
297 }
298}
299
300
301/*****************************************************************************
302 class OServiceManager
303*****************************************************************************/
304
305typedef WeakComponentImplHelper<
306 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
307 lang::XInitialization,
308 container::XSet, container::XContentEnumerationAccess,
309 beans::XPropertySet > t_OServiceManager_impl;
310
311class OServiceManager
312 : public cppu::BaseMutex
313 , public t_OServiceManager_impl
314{
315public:
316 explicit OServiceManager( Reference< XComponentContext > const & xContext );
317
318 // XInitialization
319 void SAL_CALL initialize( Sequence< Any > const & args ) override;
320
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;
325
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);
335
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;
340
341 // The same as the getAvailableServiceNames, but only unique names
342 Sequence< OUString > getUniqueAvailableServiceNames(
343 HashSet_OWString & aNameSet );
344
345 // XElementAccess
346 virtual Type SAL_CALL getElementType() override;
347 virtual sal_Bool SAL_CALL hasElements() override;
348
349 // XEnumerationAccess
350 virtual Reference<XEnumeration > SAL_CALL createEnumeration() override;
351
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;
356
357 // XContentEnumerationAccess
358 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
359 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) override;
360
361 // XComponent
362 virtual void SAL_CALL dispose() override;
363
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;
372
373protected:
374 bool is_disposed() const;
375 void check_undisposed() const;
376 virtual void SAL_CALL disposing() override;
377
378 bool haveFactoryWithThisImplementation(const OUString& aImplName);
379
380 virtual Sequence< Reference< XInterface > > queryServiceFactories(
381 const OUString& aServiceName, Reference< XComponentContext > const & xContext );
382
383 Reference< XComponentContext > m_xContext;
384
385 Reference< beans::XPropertySetInfo > m_xPropertyInfo;
386
387 // factories which have been loaded and not inserted( by XSet::insert)
388 // are remembered by this set.
389 HashSet_Ref m_SetLoadedFactories;
390private:
391
392 Reference<XEventListener > getFactoryListener();
393
394
395 HashMultimap_OWString_Interface m_ServiceMap;
396 HashSet_Ref m_ImplementationMap;
397 HashMap_OWString_Interface m_ImplementationNameMap;
398 Reference<XEventListener > xFactoryListener;
399 bool m_bInDisposing;
400};
401
402
403bool OServiceManager::is_disposed() const
404{
405 // ought to be guarded by m_mutex:
406 return (m_bInDisposing || rBHelper.bDisposed);
407}
408
409
410void OServiceManager::check_undisposed() const
411{
412 if (is_disposed())
413 {
414 throw lang::DisposedException(
415 "service manager instance has already been disposed!",
416 const_cast<OServiceManager *>(this)->getXWeak() );
417 }
418}
419
420
421typedef WeakComponentImplHelper<
422 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
423 container::XSet, container::XContentEnumerationAccess,
424 beans::XPropertySet > t_OServiceManagerWrapper_impl;
425
426class OServiceManagerWrapper : public cppu::BaseMutex, public t_OServiceManagerWrapper_impl
427{
428 Reference< XComponentContext > m_xContext;
429 Reference< XMultiComponentFactory > m_root;
430 Reference< XMultiComponentFactory > const & getRoot() const
431 {
432 if (! m_root.is())
433 {
434 throw lang::DisposedException(
435 "service manager instance has already been disposed!" );
436 }
437 return m_root;
438 }
439
440protected:
441 virtual void SAL_CALL disposing() override;
442
443public:
444 explicit OServiceManagerWrapper(
445 Reference< XComponentContext > const & xContext );
446
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(); }
454
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);
466
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 ); }
474
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(); }
480
481 // XEnumerationAccess
482 virtual Reference<XEnumeration > SAL_CALL createEnumeration() override
483 { return Reference< XEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createEnumeration(); }
484
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 ); }
492
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 ); }
497
498 // XPropertySet
499 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() override
500 { return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertySetInfo(); }
501
502 void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue) override;
503 Any SAL_CALL getPropertyValue(const OUString& PropertyName) override;
504
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 ); }
513};
514
515void SAL_CALL OServiceManagerWrapper::setPropertyValue(
516 const OUString& PropertyName, const Any& aValue )
517{
518 if ( PropertyName == "DefaultContext" )
519 {
520 Reference< XComponentContext > xContext;
521 if (!(aValue >>= xContext))
522 {
523 throw IllegalArgumentException(
524 "no XComponentContext given!",
525 getXWeak(), 1 );
526 }
527
528 MutexGuard aGuard( m_aMutex );
529 m_xContext = xContext;
530
531 }
532 else
533 {
534 Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->setPropertyValue( PropertyName, aValue );
535 }
536}
537
538Any SAL_CALL OServiceManagerWrapper::getPropertyValue(
539 const OUString& PropertyName )
540{
541 if ( PropertyName == "DefaultContext" )
542 {
543 MutexGuard aGuard( m_aMutex );
544 if( m_xContext.is() )
545 return Any( m_xContext );
546 else
547 return Any();
548 }
549 else
550 {
551 return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertyValue( PropertyName );
552 }
553}
554
555void OServiceManagerWrapper::disposing()
556{
557 m_xContext.clear();
558
559// no m_root->dispose(), because every context disposes its service manager...
560 m_root.clear();
561}
562
563OServiceManagerWrapper::OServiceManagerWrapper(
564 Reference< XComponentContext > const & xContext )
565 : t_OServiceManagerWrapper_impl( m_aMutex )
566 , m_xContext( xContext )
567 , m_root( xContext->getServiceManager() )
568{
569 if (! m_root.is())
570 {
571 throw RuntimeException(
572 "no service manager to wrap" );
573 }
574}
575
576
580OServiceManager::OServiceManager( Reference< XComponentContext > const & xContext )
581 : t_OServiceManager_impl( m_aMutex )
582 , m_xContext( xContext )
583 , m_bInDisposing( false )
584{}
585
586// XComponent
587void OServiceManager::dispose()
588{
589 if (rBHelper.bDisposed || rBHelper.bInDispose)
590 return;
591 t_OServiceManager_impl::dispose();
592}
593
594void OServiceManager::disposing()
595{
596 // dispose all factories
597 HashSet_Ref aImpls;
598 {
599 MutexGuard aGuard( m_aMutex );
600 m_bInDisposing = true;
601 aImpls = m_ImplementationMap;
602 }
603 for( const auto& rxImpl : aImpls )
604 {
605 try
606 {
607 Reference<XComponent > xComp( Reference<XComponent >::query( rxImpl ) );
608 if( xComp.is() )
609 xComp->dispose();
610 }
611 catch (const RuntimeException & exc)
612 {
613 SAL_INFO("stoc", "RuntimeException occurred upon disposing factory: " << exc);
614 }
615 }
616
617 // dispose
618 HashSet_Ref aImplMap;
619 {
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();
627 }
628
629 m_xContext.clear();
630
631 // not only the Event should hold the object
632 OSL_ASSERT( m_refCount != 1 );
633}
634
635// XPropertySet
636Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo()
637{
638 check_undisposed();
639 if (! m_xPropertyInfo.is())
640 {
641 Sequence< beans::Property > seq{ beans::Property(
642 "DefaultContext", -1, cppu::UnoType<decltype(m_xContext)>::get(), 0 ) };
643 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
644
645 MutexGuard aGuard( m_aMutex );
646 if (! m_xPropertyInfo.is())
647 {
648 m_xPropertyInfo = xInfo;
649 }
650 }
651 return m_xPropertyInfo;
652}
653
654void OServiceManager::setPropertyValue(
655 const OUString& PropertyName, const Any& aValue )
656{
657 check_undisposed();
658 if ( PropertyName != "DefaultContext" )
659 {
660 throw UnknownPropertyException(
661 "unknown property " + PropertyName,
662 getXWeak() );
663 }
664
665 Reference< XComponentContext > xContext;
666 if (!(aValue >>= xContext))
667 {
668 throw IllegalArgumentException(
669 "no XComponentContext given!",
670 getXWeak(), 1 );
671 }
672
673 MutexGuard aGuard( m_aMutex );
674 m_xContext = xContext;
675}
676
677Any OServiceManager::getPropertyValue(const OUString& PropertyName)
678{
679 check_undisposed();
680 if ( PropertyName == "DefaultContext" )
681 {
682 MutexGuard aGuard( m_aMutex );
683 if( m_xContext.is() )
684 return Any( m_xContext );
685 else
686 return Any();
687 }
688 else
689 {
690 UnknownPropertyException except;
691 except.Message = "ServiceManager : unknown property " + PropertyName;
692 throw except;
693 }
694}
695
696void OServiceManager::addPropertyChangeListener(
697 const OUString&, const Reference<XPropertyChangeListener >&)
698{
699 check_undisposed();
700 throw UnknownPropertyException("unsupported");
701}
702
703void OServiceManager::removePropertyChangeListener(
704 const OUString&, const Reference<XPropertyChangeListener >&)
705{
706 check_undisposed();
707 throw UnknownPropertyException("unsupported");
708}
709
710void OServiceManager::addVetoableChangeListener(
711 const OUString&, const Reference<XVetoableChangeListener >&)
712{
713 check_undisposed();
714 throw UnknownPropertyException("unsupported");
715}
716
717void OServiceManager::removeVetoableChangeListener(
718 const OUString&, const Reference<XVetoableChangeListener >&)
719{
720 check_undisposed();
721 throw UnknownPropertyException("unsupported");
722}
723
724// OServiceManager
725Reference<XEventListener > OServiceManager::getFactoryListener()
726{
727 check_undisposed();
728 MutexGuard aGuard( m_aMutex );
729 if( !xFactoryListener.is() )
730 xFactoryListener = new OServiceManager_Listener( this );
731 return xFactoryListener;
732}
733
734// XMultiServiceFactory, XContentEnumeration
735Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames(
736 HashSet_OWString & aNameSet )
737{
738 check_undisposed();
739 MutexGuard aGuard( m_aMutex );
740 for( const auto& rEntry : m_ServiceMap )
741 aNameSet.insert( rEntry.first );
742
743 /* do not return the implementation names
744 HashMap_OWString_Interface m_ImplementationNameMap;
745 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.begin();
746 while( aIt != m_ImplementationNameMap.end() )
747 aNameSet.insert( (*aIt++).first );
748 */
749
750 return comphelper::containerToSequence(aNameSet);
751}
752
753// XMultiComponentFactory
754Reference< XInterface > OServiceManager::createInstanceWithContext(
755 OUString const & rServiceSpecifier,
756 Reference< XComponentContext > const & xContext )
757{
758 check_undisposed();
759#if OSL_DEBUG_LEVEL > 0
760 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
761 OSL_ASSERT( xProps.is() );
762 if (xProps.is())
763 {
764 Reference< XComponentContext > xDefContext;
765 xProps->getPropertyValue( "DefaultContext" ) >>= xDefContext;
766 OSL_ENSURE(
767 xContext == xDefContext,
768 "### default context of service manager singleton differs from context holding it!" );
769 }
770#endif
771
772 const Sequence< Reference< XInterface > > factories(
773 queryServiceFactories( rServiceSpecifier, xContext ) );
774 for ( Reference< XInterface > const & xFactory : factories )
775 {
776 try
777 {
778 if (xFactory.is())
779 {
780 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
781 if (xFac.is())
782 {
783 return xFac->createInstanceWithContext( xContext );
784 }
785 else
786 {
787 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
788 if (xFac2.is())
789 {
790 SAL_INFO("stoc", "ignoring given context raising service " << rServiceSpecifier << "!!!");
791 return xFac2->createInstance();
792 }
793 }
794 }
795 }
796 catch (const lang::DisposedException & exc)
797 {
798 SAL_INFO("stoc", "DisposedException occurred: " << exc);
799 }
800 }
801
802 return Reference< XInterface >();
803}
804// XMultiComponentFactory
805Reference< XInterface > OServiceManager::createInstanceWithArgumentsAndContext(
806 OUString const & rServiceSpecifier,
807 Sequence< Any > const & rArguments,
808 Reference< XComponentContext > const & xContext )
809{
810 check_undisposed();
811#if OSL_DEBUG_LEVEL > 0
812 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
813 OSL_ASSERT( xProps.is() );
814 if (xProps.is())
815 {
816 Reference< XComponentContext > xDefContext;
817 xProps->getPropertyValue( "DefaultContext" ) >>= xDefContext;
818 OSL_ENSURE(
819 xContext == xDefContext,
820 "### default context of service manager singleton differs from context holding it!" );
821 }
822#endif
823
824 const Sequence< Reference< XInterface > > factories(
825 queryServiceFactories( rServiceSpecifier, xContext ) );
826 for ( Reference< XInterface > const & xFactory : factories )
827 {
828 try
829 {
830 if (xFactory.is())
831 {
832 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
833 if (xFac.is())
834 {
835 return xFac->createInstanceWithArgumentsAndContext( rArguments, xContext );
836 }
837 else
838 {
839 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
840 if (xFac2.is())
841 {
842 SAL_INFO("stoc", "ignoring given context raising service " << rServiceSpecifier << "!!!");
843 return xFac2->createInstanceWithArguments( rArguments );
844 }
845 }
846 }
847 }
848 catch (const lang::DisposedException & exc)
849 {
850 SAL_INFO("stoc", "DisposedException occurred: " << exc);
851 }
852 }
853
854 return Reference< XInterface >();
855}
856
857// XMultiServiceFactory, XMultiComponentFactory, XContentEnumeration
858Sequence< OUString > OServiceManager::getAvailableServiceNames()
859{
860 check_undisposed();
861 // all names
862 HashSet_OWString aNameSet;
863 return getUniqueAvailableServiceNames( aNameSet );
864}
865
866// XMultipleServiceFactory
867Reference<XInterface > OServiceManager::createInstance(
868 const OUString& rServiceSpecifier )
869{
870 return createInstanceWithContext(
871 rServiceSpecifier, m_xContext );
872}
873
874// XMultipleServiceFactory
875Reference<XInterface > OServiceManager::createInstanceWithArguments(
876 const OUString& rServiceSpecifier,
877 const Sequence<Any >& rArguments )
878{
879 return createInstanceWithArgumentsAndContext(
880 rServiceSpecifier, rArguments, m_xContext );
881}
882
883// XInitialization
884void OServiceManager::initialize( Sequence< Any > const & )
885{
886 check_undisposed();
887 OSL_FAIL( "not impl!" );
888}
889
890// XServiceInfo
891OUString OServiceManager::getImplementationName()
892{
893 return "com.sun.star.comp.stoc.OServiceManager";
894}
895
896// XServiceInfo
897sal_Bool OServiceManager::supportsService(const OUString& ServiceName)
898{
899 return cppu::supportsService(this, ServiceName);
900}
901
902// XServiceInfo
903Sequence< OUString > OServiceManager::getSupportedServiceNames()
904{
905 return { "com.sun.star.lang.MultiServiceFactory", "com.sun.star.lang.ServiceManager" };
906}
907
908
909Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories(
910 const OUString& aServiceName, Reference< XComponentContext > const & )
911{
912 Sequence< Reference< XInterface > > ret;
913
914 MutexGuard aGuard( m_aMutex );
915 ::std::pair<
916 HashMultimap_OWString_Interface::iterator,
917 HashMultimap_OWString_Interface::iterator> p(
918 m_ServiceMap.equal_range( aServiceName ) );
919
920 if (p.first == p.second) // no factories
921 {
922 // no service found, look for an implementation
923 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.find( aServiceName );
924 if( aIt != m_ImplementationNameMap.end() )
925 {
926 Reference< XInterface > const & x = aIt->second;
927 // an implementation found
928 ret = Sequence< Reference< XInterface > >( &x, 1 );
929 }
930 }
931 else
932 {
933 ::std::vector< Reference< XInterface > > vec;
934 vec.reserve( 4 );
935 while (p.first != p.second)
936 {
937 vec.push_back( p.first->second );
938 ++p.first;
939 }
940 ret = Sequence< Reference< XInterface > >( vec.data(), vec.size() );
941 }
942
943 return ret;
944}
945
946// XContentEnumerationAccess
947Reference<XEnumeration > OServiceManager::createContentEnumeration(
948 const OUString& aServiceName )
949{
950 check_undisposed();
951 Sequence< Reference< XInterface > > factories(
952 OServiceManager::queryServiceFactories( aServiceName, m_xContext ) );
953 if (factories.hasElements())
954 return new ServiceEnumeration_Impl( factories );
955 else
956 return Reference< XEnumeration >();
957}
958
959// XEnumeration
960Reference<XEnumeration > OServiceManager::createEnumeration()
961{
962 check_undisposed();
963 MutexGuard aGuard( m_aMutex );
964 return new ImplementationEnumeration_Impl( m_ImplementationMap );
965}
966
967// XElementAccess
968Type OServiceManager::getElementType()
969{
970 check_undisposed();
972}
973
974// XElementAccess
975sal_Bool OServiceManager::hasElements()
976{
977 check_undisposed();
978 MutexGuard aGuard( m_aMutex );
979 return !m_ImplementationMap.empty();
980}
981
982// XSet
983sal_Bool OServiceManager::has( const Any & Element )
984{
985 check_undisposed();
986 if( Element.getValueTypeClass() == TypeClass_INTERFACE )
987 {
988 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
989 MutexGuard aGuard( m_aMutex );
990 return m_ImplementationMap.find( xEle ) !=
991 m_ImplementationMap.end();
992 }
993 else if (auto implName = o3tl::tryAccess<OUString>(Element))
994 {
995 MutexGuard aGuard( m_aMutex );
996 return m_ImplementationNameMap.find( *implName ) !=
997 m_ImplementationNameMap.end();
998 }
999 return false;
1000}
1001
1002// XSet
1003void OServiceManager::insert( const Any & Element )
1004{
1005 check_undisposed();
1006 if( Element.getValueTypeClass() != TypeClass_INTERFACE )
1007 {
1008 throw IllegalArgumentException(
1009 "exception interface, got " + Element.getValueType().getTypeName(),
1010 Reference< XInterface >(), 0 );
1011 }
1012 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
1013
1014 {
1015 MutexGuard aGuard( m_aMutex );
1016 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1017 if( aIt != m_ImplementationMap.end() )
1018 {
1019 throw ElementExistException( "element already exists!" );
1020 }
1021
1022 // put into the implementation hashmap
1023 m_ImplementationMap.insert( xEle );
1024
1025 // put into the implementation name hashmap
1026 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1027 if( xInfo.is() )
1028 {
1029 OUString aImplName = xInfo->getImplementationName();
1030 if( !aImplName.isEmpty() )
1031 m_ImplementationNameMap[ aImplName ] = xEle;
1032
1033 //put into the service map
1034 const Sequence< OUString > aServiceNames = xInfo->getSupportedServiceNames();
1035 for( const OUString& rServiceName : aServiceNames )
1036 {
1037 m_ServiceMap.emplace(
1038 rServiceName, *o3tl::doAccess<Reference<XInterface>>(Element) );
1039 }
1040 }
1041 }
1042 // add the disposing listener to the factory
1043 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1044 if( xComp.is() )
1045 xComp->addEventListener( getFactoryListener() );
1046}
1047
1048// helper function
1049bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName)
1050{
1051 return ( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end());
1052}
1053
1054// XSet
1055void OServiceManager::remove( const Any & Element )
1056{
1057 if (is_disposed())
1058 return;
1059
1060 Reference<XInterface > xEle;
1061 if (Element.getValueTypeClass() == TypeClass_INTERFACE)
1062 {
1063 xEle.set( Element, UNO_QUERY_THROW );
1064 }
1065 else if (auto implName = o3tl::tryAccess<OUString>(Element))
1066 {
1067 MutexGuard aGuard( m_aMutex );
1068 HashMap_OWString_Interface::const_iterator const iFind(
1069 m_ImplementationNameMap.find( *implName ) );
1070 if (iFind == m_ImplementationNameMap.end())
1071 {
1072 throw NoSuchElementException(
1073 "element is not in: " + *implName,
1074 getXWeak() );
1075 }
1076 xEle = iFind->second;
1077 }
1078 else
1079 {
1080 throw IllegalArgumentException(
1081 "expected interface or string, got " + Element.getValueType().getTypeName(),
1082 Reference< XInterface >(), 0 );
1083 }
1084
1085 // remove the disposing listener from the factory
1086 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1087 if( xComp.is() )
1088 xComp->removeEventListener( getFactoryListener() );
1089
1090 MutexGuard aGuard( m_aMutex );
1091 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1092 if( aIt == m_ImplementationMap.end() )
1093 {
1094 throw NoSuchElementException(
1095 "element not found",
1096 getXWeak() );
1097 }
1098 //First remove all factories which have been loaded by ORegistryServiceManager.
1099 m_SetLoadedFactories.erase( *aIt);
1100 //Remove from the implementation map. It contains all factories of m_SetLoadedFactories
1101 //which have been added directly through XSet, that is not via ORegistryServiceManager
1102 m_ImplementationMap.erase( aIt );
1103
1104 // remove from the implementation name hashmap
1105 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1106 if( xInfo.is() )
1107 {
1108 OUString aImplName = xInfo->getImplementationName();
1109 if( !aImplName.isEmpty() )
1110 m_ImplementationNameMap.erase( aImplName );
1111 }
1112
1113 //remove from the service map
1114 Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) );
1115 if( !xSF.is() )
1116 return;
1117
1118 const Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames();
1119 for( const OUString& rServiceName : aServiceNames )
1120 {
1121 std::pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> p =
1122 m_ServiceMap.equal_range( rServiceName );
1123
1124 while( p.first != p.second )
1125 {
1126 if( xEle == (*p.first).second )
1127 {
1128 m_ServiceMap.erase( p.first );
1129 break;
1130 }
1131 ++p.first;
1132 }
1133 }
1134}
1135
1136/*****************************************************************************
1137 class ORegistryServiceManager
1138*****************************************************************************/
1139class ORegistryServiceManager : public OServiceManager
1140{
1141public:
1142 explicit ORegistryServiceManager( Reference< XComponentContext > const & xContext );
1143
1144 // XInitialization
1145 void SAL_CALL initialize(const Sequence< Any >& Arguments) override;
1146
1147 // XServiceInfo
1148 OUString SAL_CALL getImplementationName() override
1149 { return "com.sun.star.comp.stoc.ORegistryServiceManager"; }
1150
1151 Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
1152
1153 // XMultiServiceFactory
1154 Sequence< OUString > SAL_CALL getAvailableServiceNames() override;
1155
1156 // XContentEnumerationAccess
1157 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
1158 Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) override;
1159
1160 // XComponent
1161 void SAL_CALL dispose() override;
1162
1163 // OServiceManager
1164 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
1165 Any SAL_CALL getPropertyValue(const OUString& PropertyName) override;
1166
1167protected:
1168 //OServiceManager
1169 Sequence< Reference< XInterface > > queryServiceFactories(
1170 const OUString& aServiceName, Reference< XComponentContext > const & xContext ) override;
1171private:
1172 Reference<XRegistryKey > getRootKey();
1173 Reference<XInterface > loadWithImplementationName(
1174 const OUString & rImplName, Reference< XComponentContext > const & xContext );
1175 Sequence<OUString> getFromServiceName(std::u16string_view serviceName) const;
1176 Reference<XInterface > loadWithServiceName(
1177 std::u16string_view rImplName, Reference< XComponentContext > const & xContext );
1178 void fillAllNamesFromRegistry( HashSet_OWString & );
1179
1180 bool m_searchedRegistry;
1181 Reference<XSimpleRegistry > m_xRegistry; // readonly property Registry
1182 Reference<XRegistryKey > m_xRootKey;
1183
1184#if OSL_DEBUG_LEVEL > 0
1185 bool m_init;
1186#endif
1187};
1188
1192ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext > const & xContext )
1193 : OServiceManager( xContext )
1194 , m_searchedRegistry(false)
1195#if OSL_DEBUG_LEVEL > 0
1196 , m_init( false )
1197#endif
1198{
1199}
1200
1201// XComponent
1202void ORegistryServiceManager::dispose()
1203{
1204 if (rBHelper.bDisposed || rBHelper.bInDispose)
1205 return;
1206 OServiceManager::dispose();
1207 // dispose
1208 MutexGuard aGuard( m_aMutex );
1209 // erase all members
1210 m_xRegistry.clear();
1211 m_xRootKey.clear();
1212}
1213
1218//Reference<XServiceProvider > create_DefaultRegistry_ServiceProvider();
1219
1220Reference<XRegistryKey > ORegistryServiceManager::getRootKey()
1221{
1222 if( !m_xRootKey.is() )
1223 {
1224 MutexGuard aGuard( m_aMutex );
1225 // DefaultRegistry suchen !!!!
1226 if( !m_xRegistry.is() && !m_searchedRegistry )
1227 {
1228 // NB. we only search this once
1229 m_searchedRegistry = true;
1230
1231 m_xRegistry.set(
1232 createInstanceWithContext(
1233 "com.sun.star.registry.DefaultRegistry",
1234 m_xContext ),
1235 UNO_QUERY );
1236 }
1237 if( m_xRegistry.is() && !m_xRootKey.is() )
1238 m_xRootKey = m_xRegistry->getRootKey();
1239 }
1240
1241 return m_xRootKey;
1242}
1243
1247Reference<XInterface > ORegistryServiceManager::loadWithImplementationName(
1248 const OUString& name, Reference< XComponentContext > const & xContext )
1249{
1250 Reference<XInterface > ret;
1251
1252 Reference<XRegistryKey > xRootKey = getRootKey();
1253 if( !xRootKey.is() )
1254 return ret;
1255
1256 try
1257 {
1258 OUString implementationName = "/IMPLEMENTATIONS/" + name;
1259 Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName);
1260
1261 if( xImpKey.is() )
1262 {
1263 Reference< lang::XMultiServiceFactory > xMgr;
1264 if (xContext.is())
1265 xMgr.set( xContext->getServiceManager(), UNO_QUERY_THROW );
1266 else
1267 xMgr.set( this );
1268 ret = createSingleRegistryFactory( xMgr, name, xImpKey );
1269 insert( Any( ret ) );
1270 // Remember this factory as loaded in contrast to inserted ( XSet::insert)
1271 // factories. Those loaded factories in this set are candidates for being
1272 // released on an unloading notification.
1273 m_SetLoadedFactories.insert( ret);
1274 }
1275 }
1276 catch (InvalidRegistryException &)
1277 {
1278 }
1279
1280 return ret;
1281}
1282
1286Sequence<OUString> ORegistryServiceManager::getFromServiceName(
1287 std::u16string_view serviceName ) const
1288{
1289 OUString buf = OUString::Concat("/SERVICES/") + serviceName;
1290 return retrieveAsciiValueList( m_xRegistry, buf );
1291}
1292
1296Reference<XInterface > ORegistryServiceManager::loadWithServiceName(
1297 std::u16string_view serviceName, Reference< XComponentContext > const & xContext )
1298{
1299 const Sequence<OUString> implEntries = getFromServiceName( serviceName );
1300 for (const auto& rEntry : implEntries)
1301 {
1302 Reference< XInterface > x( loadWithImplementationName( rEntry, xContext ) );
1303 if (x.is())
1304 return x;
1305 }
1306
1307 return Reference<XInterface >();
1308}
1309
1313void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet )
1314{
1315 Reference<XRegistryKey > xRootKey = getRootKey();
1316 if( !xRootKey.is() )
1317 return;
1318
1319 try
1320 {
1321 Reference<XRegistryKey > xServicesKey = xRootKey->openKey( "SERVICES" );
1322 // root + /Services + /
1323 if( xServicesKey.is() )
1324 {
1325 sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1;
1326 const Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys();
1327 std::transform(aKeys.begin(), aKeys.end(), std::inserter(rSet, rSet.end()),
1328 [nPrefix](const Reference<XRegistryKey>& rKey) -> OUString {
1329 return rKey->getKeyName().copy( nPrefix ); });
1330 }
1331 }
1332 catch (InvalidRegistryException &)
1333 {
1334 }
1335}
1336
1337// XInitialization
1338void ORegistryServiceManager::initialize(const Sequence< Any >& Arguments)
1339{
1340 check_undisposed();
1341 MutexGuard aGuard( m_aMutex );
1342 if (Arguments.hasElements())
1343 {
1344 m_xRootKey.clear();
1345 Arguments[ 0 ] >>= m_xRegistry;
1346 }
1347#if OSL_DEBUG_LEVEL > 0
1348 // to find all bootstrapping processes to be fixed...
1349 OSL_ENSURE( !m_init, "### second init of service manager instance!" );
1350 m_init = true;
1351#endif
1352}
1353
1354// XMultiServiceFactory, XContentEnumeration
1355Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames()
1356{
1357 check_undisposed();
1358 MutexGuard aGuard( m_aMutex );
1359 // all names
1360 HashSet_OWString aNameSet;
1361
1362 // all names from the registry
1363 fillAllNamesFromRegistry( aNameSet );
1364
1365 return OServiceManager::getUniqueAvailableServiceNames( aNameSet );
1366}
1367
1368// XServiceInfo
1369Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames()
1370{
1371 return { "com.sun.star.lang.MultiServiceFactory", "com.sun.star.lang.RegistryServiceManager" };
1372}
1373
1374
1375// OServiceManager
1376Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories(
1377 const OUString& aServiceName, Reference< XComponentContext > const & xContext )
1378{
1379 Sequence< Reference< XInterface > > ret(
1380 OServiceManager::queryServiceFactories( aServiceName, xContext ) );
1381 if (ret.hasElements())
1382 {
1383 return ret;
1384 }
1385 else
1386 {
1387 MutexGuard aGuard( m_aMutex );
1388 Reference< XInterface > x( loadWithServiceName( aServiceName, xContext ) );
1389 if (! x.is())
1390 x = loadWithImplementationName( aServiceName, xContext );
1391 return Sequence< Reference< XInterface > >( &x, 1 );
1392 }
1393}
1394
1395// XContentEnumerationAccess
1396Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
1397 const OUString& aServiceName )
1398{
1399 check_undisposed();
1400 MutexGuard aGuard(m_aMutex);
1401 // get all implementation names registered under this service name from the registry
1402 const Sequence<OUString> aImpls = getFromServiceName( aServiceName );
1403 // load and insert all factories specified by the registry
1404 for( const OUString& aImplName : aImpls )
1405 {
1406 if ( !haveFactoryWithThisImplementation(aImplName) )
1407 {
1408 loadWithImplementationName( aImplName, m_xContext );
1409 }
1410 }
1411 // call the superclass to enumerate all contents
1412 return OServiceManager::createContentEnumeration( aServiceName );
1413}
1414
1415// OServiceManager
1416Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo()
1417{
1418 check_undisposed();
1419 if (! m_xPropertyInfo.is())
1420 {
1421 Sequence< beans::Property > seq{
1422 beans::Property("DefaultContext", -1, cppu::UnoType<decltype(m_xContext)>::get(), 0),
1423 beans::Property("Registry", -1, cppu::UnoType<decltype(m_xRegistry)>::get(),
1424 beans::PropertyAttribute::READONLY)
1425 };
1426 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
1427
1428 MutexGuard aGuard( m_aMutex );
1429 if (! m_xPropertyInfo.is())
1430 {
1431 m_xPropertyInfo = xInfo;
1432 }
1433 }
1434 return m_xPropertyInfo;
1435}
1436
1437Any ORegistryServiceManager::getPropertyValue(const OUString& PropertyName)
1438{
1439 check_undisposed();
1440 if ( PropertyName == "Registry" )
1441 {
1442 MutexGuard aGuard( m_aMutex );
1443 if( m_xRegistry.is() )
1444 return Any( m_xRegistry );
1445 else
1446 return Any();
1447 }
1448 return OServiceManager::getPropertyValue( PropertyName );
1449}
1450
1451} // namespace
1452
1453extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1455 css::uno::XComponentContext *context,
1456 css::uno::Sequence<css::uno::Any> const &)
1457{
1458 return cppu::acquire(new OServiceManager(context));
1459}
1460
1461extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1463 css::uno::XComponentContext *context,
1464 css::uno::Sequence<css::uno::Any> const &)
1465{
1466 return cppu::acquire(new ORegistryServiceManager(context));
1467}
1468
1469extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1471 css::uno::XComponentContext *context,
1472 css::uno::Sequence<css::uno::Any> const &)
1473{
1474 return cppu::acquire(new OServiceManagerWrapper(context));
1475}
1476
1477/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XComponentContext > m_xContext
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
virtual Property SAL_CALL getPropertyByName(const OUString &aName) override
virtual sal_Bool SAL_CALL hasPropertyByName(const OUString &Name) override
virtual Sequence< Property > SAL_CALL getProperties() override
PropertySetInfo_Impl(PersistentPropertySet *pOwner)
css::uno::Type const & get()
float x
Reference< XMultiServiceFactory > xSMgr
Reference< XSingleServiceFactory > xFactory
Sequence< OUString > aServiceNames
std::mutex m_aMutex
const char * name
void * p
sal_uInt16 nPos
#define SAL_INFO(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
OUStringBuffer & remove(OUStringBuffer &rIn, sal_Unicode c)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
Type
Reference< XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(const Reference< XMultiServiceFactory > &rServiceManager, const OUString &rImplementationName, const Reference< XRegistryKey > &rImplementationKey)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
constexpr OUStringLiteral implementationName
detail::Optional< T >::type doAccess(css::uno::Any const &any)
enumrange< T >::Iterator begin(enumrange< T >)
VBAHELPER_DLLPUBLIC bool setPropertyValue(css::uno::Sequence< css::beans::PropertyValue > &aProp, const OUString &aName, const css::uno::Any &aValue)
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
std::unordered_map< OUString, Reference< XInterface > > HashMap_OWString_Interface
void dispose()
std::mutex aMutex
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_OServiceManager_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_ORegistryServiceManager_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_OServiceManagerWrapper_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
static SfxItemSet & rSet
unsigned char sal_Bool