1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_stoc.hxx"
26 #include <osl/mutex.hxx>
27 #include <osl/diagnose.h>
28 #include <rtl/ustrbuf.hxx>
29
30 #include <hash_map>
31 #include <hash_set>
32 #include <list>
33 #include <uno/mapping.hxx>
34 #include <uno/dispatcher.h>
35 #include <cppuhelper/queryinterface.hxx>
36 #include <cppuhelper/weakref.hxx>
37 #include <cppuhelper/component.hxx>
38 #include <cppuhelper/factory.hxx>
39 #ifndef _CPPUHELPER_IMPLBASE1_HXX
40 #include <cppuhelper/implbase1.hxx>
41 #endif
42 #include <cppuhelper/typeprovider.hxx>
43 #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
44 #include <cppuhelper/implementationentry.hxx>
45 #endif
46 #include <rtl/unload.h>
47 #include <cppuhelper/component_context.hxx>
48 #include <cppuhelper/bootstrap.hxx>
49 #include <cppuhelper/compbase8.hxx>
50
51
52 #include <com/sun/star/lang/XUnoTunnel.hpp>
53 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
54 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
55 #include <com/sun/star/lang/XServiceInfo.hpp>
56 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
57 #include <com/sun/star/lang/XInitialization.hpp>
58 #include <com/sun/star/lang/XEventListener.hpp>
59 #include <com/sun/star/lang/DisposedException.hpp>
60 #include <com/sun/star/beans/XPropertySet.hpp>
61 #include <com/sun/star/beans/PropertyAttribute.hpp>
62 #include <com/sun/star/registry/XRegistryKey.hpp>
63 #include <com/sun/star/registry/XSimpleRegistry.hpp>
64 #include <com/sun/star/container/XSet.hpp>
65 #include <com/sun/star/container/XElementAccess.hpp>
66 #include <com/sun/star/container/XEnumeration.hpp>
67 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
68 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
69 #include <com/sun/star/uno/XUnloadingPreference.hpp>
70
71 #include <bootstrapservices.hxx>
72
73 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
74
75
76 using namespace com::sun::star;
77 using namespace com::sun::star::uno;
78 using namespace com::sun::star::beans;
79 using namespace com::sun::star::registry;
80 using namespace com::sun::star::lang;
81 using namespace com::sun::star::container;
82 using namespace cppu;
83 using namespace osl;
84 using namespace rtl;
85 using namespace std;
86
87 rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
88
89 namespace stoc_bootstrap
90 {
smgr_wrapper_getSupportedServiceNames()91 Sequence< OUString > smgr_wrapper_getSupportedServiceNames()
92 {
93 static Sequence < OUString > *pNames = 0;
94 if( ! pNames )
95 {
96 MutexGuard guard( Mutex::getGlobalMutex() );
97 if( !pNames )
98 {
99 static Sequence< OUString > seqNames(1);
100 seqNames.getArray()[0] = OUString(
101 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory") );
102 pNames = &seqNames;
103 }
104 }
105 return *pNames;
106 }
107
smgr_wrapper_getImplementationName()108 OUString smgr_wrapper_getImplementationName()
109 {
110 static OUString *pImplName = 0;
111 if( ! pImplName )
112 {
113 MutexGuard guard( Mutex::getGlobalMutex() );
114 if( ! pImplName )
115 {
116 static OUString implName(
117 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.OServiceManagerWrapper" ) );
118 pImplName = &implName;
119 }
120 }
121 return *pImplName;
122 }
123
smgr_getSupportedServiceNames()124 Sequence< OUString > smgr_getSupportedServiceNames()
125 {
126 static Sequence < OUString > *pNames = 0;
127 if( ! pNames )
128 {
129 MutexGuard guard( Mutex::getGlobalMutex() );
130 if( !pNames )
131 {
132 static Sequence< OUString > seqNames(2);
133 seqNames.getArray()[0] = OUString(
134 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory") );
135 seqNames.getArray()[1] = OUString(
136 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.ServiceManager") );
137 pNames = &seqNames;
138 }
139 }
140 return *pNames;
141 }
142
smgr_getImplementationName()143 OUString smgr_getImplementationName()
144 {
145 static OUString *pImplName = 0;
146 if( ! pImplName )
147 {
148 MutexGuard guard( Mutex::getGlobalMutex() );
149 if( ! pImplName )
150 {
151 static OUString implName(
152 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.OServiceManager" ) );
153 pImplName = &implName;
154 }
155 }
156 return *pImplName;
157 }
158
regsmgr_getSupportedServiceNames()159 Sequence< OUString > regsmgr_getSupportedServiceNames()
160 {
161 static Sequence < OUString > *pNames = 0;
162 if( ! pNames )
163 {
164 MutexGuard guard( Mutex::getGlobalMutex() );
165 if( !pNames )
166 {
167 static Sequence< OUString > seqNames(2);
168 seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory"));
169 seqNames.getArray()[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.RegistryServiceManager"));
170 pNames = &seqNames;
171 }
172 }
173 return *pNames;
174 }
175
regsmgr_getImplementationName()176 OUString regsmgr_getImplementationName()
177 {
178 static OUString *pImplName = 0;
179 if( ! pImplName )
180 {
181 MutexGuard guard( Mutex::getGlobalMutex() );
182 if( ! pImplName )
183 {
184 static OUString implName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.ORegistryServiceManager" ) );
185 pImplName = &implName;
186 }
187 }
188 return *pImplName;
189 }
190 }
191
192 namespace stoc_smgr
193 {
smgr_getImplementationId()194 static Sequence< sal_Int8 > smgr_getImplementationId()
195 {
196 static OImplementationId * s_pId = 0;
197 if (! s_pId)
198 {
199 MutexGuard aGuard( Mutex::getGlobalMutex() );
200 if (! s_pId)
201 {
202 static OImplementationId s_aId;
203 s_pId = &s_aId;
204 }
205 }
206 return s_pId->getImplementationId();
207 }
208
209
retrieveAsciiValueList(const Reference<XSimpleRegistry> & xReg,const OUString & keyName)210 static Sequence< OUString > retrieveAsciiValueList(
211 const Reference< XSimpleRegistry > &xReg, const OUString &keyName )
212 {
213 Reference< XEnumerationAccess > xAccess( xReg, UNO_QUERY );
214 Sequence< OUString > seq;
215 if( xAccess.is() )
216 {
217 Reference< XEnumeration > xEnum = xAccess->createEnumeration();
218 while( xEnum.is() && xEnum->hasMoreElements() )
219 {
220 Reference< XSimpleRegistry > xTempReg;
221 xEnum->nextElement() >>= xTempReg;
222 if( xTempReg.is() )
223 {
224 Sequence< OUString > seq2 = retrieveAsciiValueList( xTempReg, keyName );
225
226 if( seq2.getLength() )
227 {
228 sal_Int32 n1Len = seq.getLength();
229 sal_Int32 n2Len = seq2.getLength();
230
231 seq.realloc( n1Len + n2Len );
232 const OUString *pSource = seq2.getConstArray();
233 OUString *pTarget = seq.getArray();
234 for( int i = 0 ; i < n2Len ; i ++ )
235 {
236 pTarget[i+n1Len] = pSource[i];
237 }
238 }
239 }
240 }
241 }
242 else if( xReg.is () )
243 {
244 try
245 {
246 Reference< XRegistryKey > rRootKey = xReg->getRootKey();
247 if( rRootKey.is() )
248 {
249 Reference<XRegistryKey > xKey = rRootKey->openKey(keyName);
250 if( xKey.is() )
251 {
252 seq = xKey->getAsciiListValue();
253 }
254 }
255 }
256 catch( InvalidRegistryException & )
257 {
258 }
259 catch (InvalidValueException &)
260 {
261 }
262 }
263 return seq;
264 }
265
266 /*****************************************************************************
267 Enumeration by ServiceName
268 *****************************************************************************/
269 struct hashRef_Impl
270 {
operator ()stoc_smgr::hashRef_Impl271 size_t operator()(const Reference<XInterface > & rName) const
272 {
273 // query to XInterface. The cast to XInterface* must be the same for the same object
274 Reference<XInterface > x( Reference<XInterface >::query( rName ) );
275 return (size_t)x.get();
276 }
277 };
278
279 struct equaltoRef_Impl
280 {
operator ()stoc_smgr::equaltoRef_Impl281 size_t operator()(const Reference<XInterface > & rName1, const Reference<XInterface > & rName2 ) const
282 { return rName1 == rName2; }
283 };
284
285 typedef hash_set
286 <
287 Reference<XInterface >,
288 hashRef_Impl,
289 equaltoRef_Impl
290 > HashSet_Ref;
291
292
293 class ServiceEnumeration_Impl : public WeakImplHelper1< XEnumeration >
294 {
295 public:
ServiceEnumeration_Impl(const Sequence<Reference<XInterface>> & rFactories)296 ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories )
297 : aFactories( rFactories )
298 , nIt( 0 )
299 { g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); }
~ServiceEnumeration_Impl()300 virtual ~ServiceEnumeration_Impl()
301 { g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); }
302
303 // XEnumeration
304 sal_Bool SAL_CALL hasMoreElements();
305 Any SAL_CALL nextElement();
306 private:
307 Mutex aMutex;
308 Sequence< Reference<XInterface > > aFactories;
309 sal_Int32 nIt;
310 };
311
312 // XEnumeration
hasMoreElements()313 sal_Bool ServiceEnumeration_Impl::hasMoreElements()
314 {
315 MutexGuard aGuard( aMutex );
316 return nIt != aFactories.getLength();
317 }
318
319 // XEnumeration
nextElement()320 Any ServiceEnumeration_Impl::nextElement()
321 {
322 MutexGuard aGuard( aMutex );
323 if( nIt == aFactories.getLength() )
324 throw NoSuchElementException();
325
326 return Any( &aFactories.getConstArray()[nIt++], ::getCppuType( (const Reference<XInterface > *)0 ) );
327 }
328
329 //==================================================================================================
330 class PropertySetInfo_Impl : public WeakImplHelper1< beans::XPropertySetInfo >
331 {
332 Sequence< beans::Property > m_properties;
333
334 public:
335 inline PropertySetInfo_Impl( Sequence< beans::Property > const & properties ) SAL_THROW( () )
336 : m_properties( properties )
337 {}
338
339 // XPropertySetInfo impl
340 virtual Sequence< beans::Property > SAL_CALL getProperties();
341 virtual beans::Property SAL_CALL getPropertyByName( OUString const & name );
342 virtual sal_Bool SAL_CALL hasPropertyByName( OUString const & name );
343 };
344 //__________________________________________________________________________________________________
getProperties()345 Sequence< beans::Property > PropertySetInfo_Impl::getProperties()
346 {
347 return m_properties;
348 }
349 //__________________________________________________________________________________________________
getPropertyByName(OUString const & name)350 beans::Property PropertySetInfo_Impl::getPropertyByName( OUString const & name )
351 {
352 beans::Property const * p = m_properties.getConstArray();
353 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
354 {
355 if (p[ nPos ].Name.equals( name ))
356 return p[ nPos ];
357 }
358 throw beans::UnknownPropertyException(
359 OUSTR("unknown property: ") + name, Reference< XInterface >() );
360 }
361 //__________________________________________________________________________________________________
hasPropertyByName(OUString const & name)362 sal_Bool PropertySetInfo_Impl::hasPropertyByName( OUString const & name )
363 {
364 beans::Property const * p = m_properties.getConstArray();
365 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
366 {
367 if (p[ nPos ].Name.equals( name ))
368 return sal_True;
369 }
370 return sal_False;
371 }
372
373
374 /*****************************************************************************
375 Enumeration by implementation
376 *****************************************************************************/
377 class ImplementationEnumeration_Impl : public WeakImplHelper1< XEnumeration >
378 {
379 public:
ImplementationEnumeration_Impl(const HashSet_Ref & rImplementationMap)380 ImplementationEnumeration_Impl( const HashSet_Ref & rImplementationMap )
381 : aImplementationMap( rImplementationMap )
382 , aIt( aImplementationMap.begin() )
383 {
384 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
385 }
386 virtual ~ImplementationEnumeration_Impl();
387
388 // XEnumeration
389 virtual sal_Bool SAL_CALL hasMoreElements();
390 virtual Any SAL_CALL nextElement();
391
392 private:
393 Mutex aMutex;
394 HashSet_Ref aImplementationMap;
395 HashSet_Ref::iterator aIt;
396 sal_Int32 nNext;
397 Reference<XInterface > xNext;
398 };
399
~ImplementationEnumeration_Impl()400 ImplementationEnumeration_Impl::~ImplementationEnumeration_Impl()
401 {
402 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
403 }
404
405 // XEnumeration
hasMoreElements()406 sal_Bool ImplementationEnumeration_Impl::hasMoreElements()
407 {
408 MutexGuard aGuard( aMutex );
409 return aIt != aImplementationMap.end();
410 }
411
412 // XEnumeration
nextElement()413 Any ImplementationEnumeration_Impl::nextElement()
414 {
415 MutexGuard aGuard( aMutex );
416 if( aIt == aImplementationMap.end() )
417 throw NoSuchElementException();
418
419 Any ret( &(*aIt), ::getCppuType( (const Reference<XInterface > *)0 ) );
420 ++aIt;
421 return ret;
422 }
423
424 /*****************************************************************************
425 Hash tables
426 *****************************************************************************/
427 struct equalOWString_Impl
428 {
operator ()stoc_smgr::equalOWString_Impl429 sal_Bool operator()(const OUString & s1, const OUString & s2) const
430 { return s1 == s2; }
431 };
432
433 struct hashOWString_Impl
434 {
operator ()stoc_smgr::hashOWString_Impl435 size_t operator()(const OUString & rName) const
436 { return rName.hashCode(); }
437 };
438
439 typedef hash_set
440 <
441 OUString,
442 hashOWString_Impl,
443 equalOWString_Impl
444 > HashSet_OWString;
445
446 typedef hash_multimap
447 <
448 OUString,
449 Reference<XInterface >,
450 hashOWString_Impl,
451 equalOWString_Impl
452 > HashMultimap_OWString_Interface;
453
454 typedef hash_map
455 <
456 OUString,
457 Reference<XInterface >,
458 hashOWString_Impl,
459 equalOWString_Impl
460 > HashMap_OWString_Interface;
461
462 /*****************************************************************************
463 class OServiceManager_Listener
464 *****************************************************************************/
465 class OServiceManager_Listener : public WeakImplHelper1< XEventListener >
466 {
467 private:
468 WeakReference<XSet > xSMgr;
469
470 public:
OServiceManager_Listener(const Reference<XSet> & rSMgr)471 OServiceManager_Listener( const Reference<XSet > & rSMgr )
472 : xSMgr( rSMgr )
473 {}
474
475 // XEventListener
476 virtual void SAL_CALL disposing(const EventObject & rEvt );
477 };
478
disposing(const EventObject & rEvt)479 void OServiceManager_Listener::disposing(const EventObject & rEvt )
480 {
481 Reference<XSet > x( xSMgr );
482 if( x.is() )
483 {
484 try
485 {
486 x->remove( Any( &rEvt.Source, ::getCppuType( (const Reference<XInterface > *)0 ) ) );
487 }
488 catch( const IllegalArgumentException & )
489 {
490 OSL_ENSURE( sal_False, "IllegalArgumentException catched" );
491 }
492 catch( const NoSuchElementException & )
493 {
494 OSL_ENSURE( sal_False, "NoSuchElementException catched" );
495 }
496 }
497 }
498
499
500 /*****************************************************************************
501 class OServiceManager
502 *****************************************************************************/
503 struct OServiceManagerMutex
504 {
505 Mutex m_mutex;
506 };
507
508 extern "C" void SAL_CALL smgrUnloadingListener(void* id);
509
510 typedef WeakComponentImplHelper8<
511 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
512 lang::XInitialization, lang::XUnoTunnel,
513 container::XSet, container::XContentEnumerationAccess,
514 beans::XPropertySet > t_OServiceManager_impl;
515
516 class OServiceManager
517 : public OServiceManagerMutex
518 , public t_OServiceManager_impl
519 {
520 public:
521 friend void SAL_CALL smgrUnloadingListener(void* id);
522
523 OServiceManager( Reference< XComponentContext > const & xContext );
524 virtual ~OServiceManager();
525
526 // XUnoTunnel
527 sal_Int64 SAL_CALL getSomething( Sequence< sal_Int8 > const & id );
528
529 // XInitialization
530 void SAL_CALL initialize( Sequence< Any > const & args );
531
532 // XServiceInfo
533 virtual OUString SAL_CALL getImplementationName();
getImplementationName_Static()534 static OUString getImplementationName_Static()
535 { return stoc_bootstrap::smgr_getImplementationName(); }
536 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName);
537 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames();
538
539 // XMultiComponentFactory
540 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
541 OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext );
542 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
543 OUString const & rServiceSpecifier,
544 Sequence< Any > const & rArguments,
545 Reference< XComponentContext > const & xContext );
546 // virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
547 // throw (RuntimeException);
548
549 // XMultiServiceFactory
550 virtual Sequence< OUString > SAL_CALL getAvailableServiceNames();
551 virtual Reference<XInterface > SAL_CALL createInstance(const OUString &);
552 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString &, const Sequence<Any >& Arguments);
553
554 // The same as the getAvailableServiceNames, but only unique names
555 Sequence< OUString > getUniqueAvailableServiceNames(
556 HashSet_OWString & aNameSet );
557
558 // XElementAccess
559 virtual Type SAL_CALL getElementType();
560 virtual sal_Bool SAL_CALL hasElements();
561
562 // XEnumerationAccess
563 virtual Reference<XEnumeration > SAL_CALL createEnumeration();
564
565 // XSet
566 virtual sal_Bool SAL_CALL has( const Any & Element );
567 virtual void SAL_CALL insert( const Any & Element );
568 virtual void SAL_CALL remove( const Any & Element );
569
570 // XContentEnumerationAccess
571 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
572 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName);
573 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(
574 const OUString& aServiceName, Reference< XComponentContext > const & xContext );
575
576 // XComponent
577 virtual void SAL_CALL dispose();
578
579 // XPropertySet
580 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo();
581 void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue);
582 Any SAL_CALL getPropertyValue(const OUString& PropertyName);
583 void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener);
584 void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener);
585 void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener);
586 void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener);
587
588 protected:
589 inline bool is_disposed() const;
590 inline void check_undisposed() const;
591 virtual void SAL_CALL disposing();
592
593 sal_Bool haveFactoryWithThisImplementation(const OUString& aImplName);
594
595 virtual Sequence< Reference< XInterface > > queryServiceFactories(
596 const OUString& aServiceName, Reference< XComponentContext > const & xContext );
597
598 Reference< XComponentContext > m_xContext;
599
600 Reference< beans::XPropertySetInfo > m_xPropertyInfo;
601
602 sal_Int32 m_nUnloadingListenerId;
603
604 // Does clean up when the unloading mechanism has been set off. It is called from
605 // the listener function smgrUnloadingListener.
606 void onUnloadingNotify();
607 // factories which have been loaded and not inserted( by XSet::insert)
608 // are remembered by this set. Those factories
609 // are not released on a call to onUnloadingNotify
610 HashSet_Ref m_SetLoadedFactories;
611 private:
612
613 Reference<XEventListener > getFactoryListener();
614
615
616 HashMultimap_OWString_Interface m_ServiceMap;
617 HashSet_Ref m_ImplementationMap;
618 HashMap_OWString_Interface m_ImplementationNameMap;
619 Reference<XEventListener > xFactoryListener;
620 bool m_bInDisposing;
621 };
622
623
624 //______________________________________________________________________________
is_disposed() const625 inline bool OServiceManager::is_disposed() const
626 {
627 // ought to be guarded by m_mutex:
628 return (m_bInDisposing || rBHelper.bDisposed);
629 }
630
631 //______________________________________________________________________________
check_undisposed() const632 inline void OServiceManager::check_undisposed() const
633 {
634 if (is_disposed())
635 {
636 throw lang::DisposedException(
637 OUSTR("service manager instance has already been disposed!"),
638 (OWeakObject *)this );
639 }
640 }
641
642 //##################################################################################################
643 //##################################################################################################
644 //##################################################################################################
645
646 class OServiceManagerWrapper : public OServiceManagerMutex, public t_OServiceManager_impl
647 {
648 Reference< XComponentContext > m_xContext;
649 OServiceManager * m_root;
getRoot()650 inline OServiceManager * getRoot()
651 {
652 if (! m_root)
653 {
654 throw lang::DisposedException(
655 OUSTR("service manager instance has already been disposed!"),
656 Reference< XInterface >() );
657 }
658 return m_root;
659 }
660
661 protected:
662 virtual void SAL_CALL disposing();
663
664 public:
665 OServiceManagerWrapper(
666 Reference< XComponentContext > const & xContext );
667 virtual ~OServiceManagerWrapper() SAL_THROW( () );
668
669 // XUnoTunnel
getSomething(Sequence<sal_Int8> const & id)670 sal_Int64 SAL_CALL getSomething( Sequence< sal_Int8 > const & id )
671 { return getRoot()->getSomething( id ); }
672
673 // XInitialization
initialize(Sequence<Any> const & args)674 void SAL_CALL initialize( Sequence< Any > const & args )
675 { getRoot()->initialize( args ); }
676
677 // XServiceInfo
getImplementationName()678 virtual OUString SAL_CALL getImplementationName()
679 { return getRoot()->getImplementationName(); }
supportsService(const OUString & ServiceName)680 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
681 { return getRoot()->supportsService( ServiceName ); }
getSupportedServiceNames()682 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
683 { return getRoot()->getSupportedServiceNames(); }
684
685 // XMultiComponentFactory
createInstanceWithContext(OUString const & rServiceSpecifier,Reference<XComponentContext> const & xContext)686 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
687 OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext )
688 { return getRoot()->createInstanceWithContext( rServiceSpecifier, xContext ); }
createInstanceWithArgumentsAndContext(OUString const & rServiceSpecifier,Sequence<Any> const & rArguments,Reference<XComponentContext> const & xContext)689 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
690 OUString const & rServiceSpecifier,
691 Sequence< Any > const & rArguments,
692 Reference< XComponentContext > const & xContext )
693 { return getRoot()->createInstanceWithArgumentsAndContext( rServiceSpecifier, rArguments, xContext ); }
694 // virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
695 // throw (RuntimeException);
696
697 // XMultiServiceFactory
getAvailableServiceNames()698 virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
699 { return getRoot()->getAvailableServiceNames(); }
createInstance(const OUString & name)700 virtual Reference<XInterface > SAL_CALL createInstance(const OUString & name)
701 { return getRoot()->createInstanceWithContext( name, m_xContext ); }
createInstanceWithArguments(const OUString & name,const Sequence<Any> & Arguments)702 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString & name, const Sequence<Any >& Arguments)
703 { return getRoot()->createInstanceWithArgumentsAndContext( name, Arguments, m_xContext ); }
704
705 // XElementAccess
getElementType()706 virtual Type SAL_CALL getElementType()
707 { return getRoot()->getElementType(); }
hasElements()708 virtual sal_Bool SAL_CALL hasElements()
709 { return getRoot()->hasElements(); }
710
711 // XEnumerationAccess
createEnumeration()712 virtual Reference<XEnumeration > SAL_CALL createEnumeration()
713 { return getRoot()->createEnumeration(); }
714
715 // XSet
has(const Any & Element)716 virtual sal_Bool SAL_CALL has( const Any & Element )
717 { return getRoot()->has( Element ); }
insert(const Any & Element)718 virtual void SAL_CALL insert( const Any & Element )
719 { getRoot()->insert( Element ); }
remove(const Any & Element)720 virtual void SAL_CALL remove( const Any & Element )
721 { getRoot()->remove( Element ); }
722
723 // XContentEnumerationAccess
724 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
createContentEnumeration(const OUString & aServiceName)725 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName)
726 { return getRoot()->createContentEnumeration( aServiceName, m_xContext ); }
727
728 // XPropertySet
getPropertySetInfo()729 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
730 { return getRoot()->getPropertySetInfo(); }
731
732 void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue);
733 Any SAL_CALL getPropertyValue(const OUString& PropertyName);
734
addPropertyChangeListener(const OUString & PropertyName,const Reference<XPropertyChangeListener> & aListener)735 void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
736 { getRoot()->addPropertyChangeListener( PropertyName, aListener ); }
removePropertyChangeListener(const OUString & PropertyName,const Reference<XPropertyChangeListener> & aListener)737 void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
738 { getRoot()->removePropertyChangeListener( PropertyName, aListener ); }
addVetoableChangeListener(const OUString & PropertyName,const Reference<XVetoableChangeListener> & aListener)739 void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
740 { getRoot()->addVetoableChangeListener( PropertyName, aListener ); }
removeVetoableChangeListener(const OUString & PropertyName,const Reference<XVetoableChangeListener> & aListener)741 void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
742 { getRoot()->removeVetoableChangeListener( PropertyName, aListener ); }
743 };
744 //__________________________________________________________________________________________________
setPropertyValue(const OUString & PropertyName,const Any & aValue)745 void SAL_CALL OServiceManagerWrapper::setPropertyValue(
746 const OUString& PropertyName, const Any& aValue )
747 {
748 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") ))
749 {
750 Reference< XComponentContext > xContext;
751 if (aValue >>= xContext)
752 {
753 MutexGuard aGuard( m_mutex );
754 m_xContext = xContext;
755 }
756 else
757 {
758 throw IllegalArgumentException(
759 OUString( RTL_CONSTASCII_USTRINGPARAM("no XComponentContext given!") ),
760 (OWeakObject *)this, 1 );
761 }
762 }
763 else
764 {
765 getRoot()->setPropertyValue( PropertyName, aValue );
766 }
767 }
768 //__________________________________________________________________________________________________
getPropertyValue(const OUString & PropertyName)769 Any SAL_CALL OServiceManagerWrapper::getPropertyValue(
770 const OUString& PropertyName )
771 {
772 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") ))
773 {
774 MutexGuard aGuard( m_mutex );
775 if( m_xContext.is() )
776 return makeAny( m_xContext );
777 else
778 return Any();
779 }
780 else
781 {
782 return getRoot()->getPropertyValue( PropertyName );
783 }
784 }
785 //__________________________________________________________________________________________________
disposing()786 void OServiceManagerWrapper::disposing()
787 {
788 m_xContext.clear();
789
790 if (m_root)
791 {
792 // no m_root->dispose(), because every context disposes its service manager...
793 m_root->release();
794 m_root = 0;
795 }
796 }
797 //__________________________________________________________________________________________________
~OServiceManagerWrapper()798 OServiceManagerWrapper::~OServiceManagerWrapper() SAL_THROW( () )
799 {
800 if (m_root)
801 {
802 m_root->release();
803 m_root = 0;
804 }
805
806 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
807 }
808 //__________________________________________________________________________________________________
OServiceManagerWrapper(Reference<XComponentContext> const & xContext)809 OServiceManagerWrapper::OServiceManagerWrapper(
810 Reference< XComponentContext > const & xContext )
811 : t_OServiceManager_impl( m_mutex )
812 , m_xContext( xContext )
813 , m_root( 0 )
814 {
815 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
816
817 Reference< XUnoTunnel > xTunnel( m_xContext->getServiceManager(), UNO_QUERY );
818 OSL_ASSERT( xTunnel.is() );
819 if (xTunnel.is())
820 {
821 m_root = reinterpret_cast< OServiceManager * >(
822 xTunnel->getSomething( smgr_getImplementationId() ) );
823 OSL_ASSERT( m_root );
824 if (m_root)
825 {
826 m_root->acquire();
827 }
828 }
829
830 if (! m_root)
831 {
832 throw RuntimeException(
833 OUString( RTL_CONSTASCII_USTRINGPARAM("can only wrap OServiceManager instances!") ),
834 Reference< XInterface >() );
835 }
836 }
837
838 //##################################################################################################
839 //##################################################################################################
840 //##################################################################################################
841
842 // XUnoTunnel
getSomething(Sequence<sal_Int8> const & id)843 sal_Int64 OServiceManager::getSomething( Sequence< sal_Int8 > const & id )
844 {
845 check_undisposed();
846 if (id == smgr_getImplementationId())
847 return reinterpret_cast< sal_Int64 >(this);
848 else
849 return 0;
850 }
851
852 /**
853 * Create a ServiceManager
854 */
OServiceManager(Reference<XComponentContext> const & xContext)855 OServiceManager::OServiceManager( Reference< XComponentContext > const & xContext )
856 : t_OServiceManager_impl( m_mutex )
857 , m_xContext( xContext )
858 , m_bInDisposing( false )
859 {
860 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
861 m_nUnloadingListenerId= rtl_addUnloadingListener( smgrUnloadingListener, this);
862 }
863
864 /**
865 * Destroy the ServiceManager
866 */
~OServiceManager()867 OServiceManager::~OServiceManager()
868 {
869 if( m_nUnloadingListenerId != 0)
870 rtl_removeUnloadingListener( m_nUnloadingListenerId );
871
872 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
873 }
874
875 // Removes entries in m_ServiceMap, m_ImplementationNameMap and m_ImplementationNameMap
876 // if those entries have not been inserted through XSet::insert. Therefore the entries
877 // are compared with the entries in m_SetLoadedFactories.
onUnloadingNotify()878 void OServiceManager::onUnloadingNotify()
879 {
880 MutexGuard aGuard( m_mutex);
881
882 typedef HashSet_Ref::const_iterator CIT_S;
883 typedef HashMultimap_OWString_Interface::iterator IT_MM;
884
885 CIT_S it_SetEnd= m_SetLoadedFactories.end();
886 IT_MM it_end1= m_ServiceMap.end();
887 list<IT_MM> listDeleteServiceMap;
888 typedef list<IT_MM>::const_iterator CIT_DMM;
889 // find occurrences in m_ServiceMap
890 for(IT_MM it_i1= m_ServiceMap.begin(); it_i1 != it_end1; it_i1++)
891 {
892 if( m_SetLoadedFactories.find( it_i1->second) != it_SetEnd)
893 {
894 Reference<XUnloadingPreference> xunl( it_i1->second, UNO_QUERY);
895 if( xunl.is())
896 {
897 if( xunl->releaseOnNotification())
898 listDeleteServiceMap.push_front( it_i1);
899 }
900 else
901 listDeleteServiceMap.push_front( it_i1);
902 }
903 }
904 // delete elements from m_ServiceMap
905 CIT_DMM it_end2= listDeleteServiceMap.end();
906 for( CIT_DMM it_i2= listDeleteServiceMap.begin(); it_i2 != it_end2; it_i2++)
907 m_ServiceMap.erase( *it_i2);
908
909 // find elements in m_ImplementationNameMap
910 typedef HashMap_OWString_Interface::iterator IT_M;
911 IT_M it_end3= m_ImplementationNameMap.end();
912 list<IT_M> listDeleteImplementationNameMap;
913 typedef list<IT_M>::const_iterator CIT_DM;
914 for( IT_M it_i3= m_ImplementationNameMap.begin(); it_i3 != it_end3; it_i3++)
915 {
916 if( m_SetLoadedFactories.find( it_i3->second) != it_SetEnd)
917 {
918 Reference<XUnloadingPreference> xunl( it_i3->second, UNO_QUERY);
919 if( xunl.is())
920 {
921 if( xunl->releaseOnNotification())
922 listDeleteImplementationNameMap.push_front( it_i3);
923 }
924 else
925 listDeleteImplementationNameMap.push_front( it_i3);
926 }
927 }
928 // delete elements from m_ImplementationNameMap
929 CIT_DM it_end4= listDeleteImplementationNameMap.end();
930 for( CIT_DM it_i4= listDeleteImplementationNameMap.begin(); it_i4 != it_end4; it_i4++)
931 m_ImplementationNameMap.erase( *it_i4);
932
933 // find elements in m_ImplementationMap
934 typedef HashSet_Ref::iterator IT_S;
935 IT_S it_end5= m_ImplementationMap.end();
936 list<IT_S> listDeleteImplementationMap;
937 typedef list<IT_S>::const_iterator CIT_DS;
938 for( IT_S it_i5= m_ImplementationMap.begin(); it_i5 != it_end5; it_i5++)
939 {
940 if( m_SetLoadedFactories.find( *it_i5) != it_SetEnd)
941 {
942 Reference<XUnloadingPreference> xunl( *it_i5, UNO_QUERY);
943 if( xunl.is())
944 {
945 if( xunl->releaseOnNotification())
946 listDeleteImplementationMap.push_front( it_i5);
947 }
948 else
949 listDeleteImplementationMap.push_front( it_i5);
950 }
951 }
952 // delete elements from m_ImplementationMap
953 CIT_DS it_end6= listDeleteImplementationMap.end();
954 for( CIT_DS it_i6= listDeleteImplementationMap.begin(); it_i6 != it_end6; it_i6++)
955 m_ImplementationMap.erase( *it_i6);
956
957 // remove Event listener before the factories are released.
958 IT_S it_end7= m_SetLoadedFactories.end();
959
960 Reference<XEventListener> xlistener= getFactoryListener();
961 for( IT_S it_i7= m_SetLoadedFactories.begin(); it_i7 != it_end7; it_i7++)
962 {
963 Reference<XComponent> xcomp( *it_i7, UNO_QUERY);
964 if( xcomp.is())
965 xcomp->removeEventListener( xlistener);
966 }
967 // release the factories in m_SetLoadedFactories
968 m_SetLoadedFactories.clear();
969 }
970
971 // XComponent
dispose()972 void OServiceManager::dispose()
973 {
974 if (rBHelper.bDisposed || rBHelper.bInDispose)
975 return;
976 t_OServiceManager_impl::dispose();
977 }
978
disposing()979 void OServiceManager::disposing()
980 {
981 // dispose all factories
982 HashSet_Ref aImpls;
983 {
984 MutexGuard aGuard( m_mutex );
985 m_bInDisposing = true;
986 aImpls = m_ImplementationMap;
987 }
988 HashSet_Ref::iterator aIt = aImpls.begin();
989 while( aIt != aImpls.end() )
990 {
991 try
992 {
993 Reference<XComponent > xComp( Reference<XComponent >::query( *aIt++ ) );
994 if( xComp.is() )
995 xComp->dispose();
996 }
997 catch (RuntimeException & exc)
998 {
999 #if OSL_DEBUG_LEVEL > 1
1000 OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
1001 OSL_TRACE( "### RuntimeException occurred upon disposing factory: %s", str.getStr() );
1002 #else
1003 (void) exc; // unused
1004 #endif
1005 }
1006 }
1007
1008 // dispose
1009 HashSet_Ref aImplMap;
1010 {
1011 MutexGuard aGuard( m_mutex );
1012 // erase all members
1013 m_ServiceMap = HashMultimap_OWString_Interface();
1014 aImplMap = m_ImplementationMap;
1015 m_ImplementationMap = HashSet_Ref();
1016 m_ImplementationNameMap = HashMap_OWString_Interface();
1017 m_SetLoadedFactories= HashSet_Ref();
1018 }
1019
1020 m_xContext.clear();
1021
1022 // not only the Event should hold the object
1023 OSL_ASSERT( m_refCount != 1 );
1024
1025 // Revoke this service manager as unloading listener
1026 rtl_removeUnloadingListener( m_nUnloadingListenerId);
1027 m_nUnloadingListenerId=0;
1028 }
1029
1030 // XPropertySet
getPropertySetInfo()1031 Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo()
1032 {
1033 check_undisposed();
1034 if (! m_xPropertyInfo.is())
1035 {
1036 Sequence< beans::Property > seq( 1 );
1037 seq[ 0 ] = beans::Property(
1038 OUSTR("DefaultContext"), -1, ::getCppuType( &m_xContext ), 0 );
1039 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
1040
1041 MutexGuard aGuard( m_mutex );
1042 if (! m_xPropertyInfo.is())
1043 {
1044 m_xPropertyInfo = xInfo;
1045 }
1046 }
1047 return m_xPropertyInfo;
1048 }
1049
setPropertyValue(const OUString & PropertyName,const Any & aValue)1050 void OServiceManager::setPropertyValue(
1051 const OUString& PropertyName, const Any& aValue )
1052 {
1053 check_undisposed();
1054 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") ))
1055 {
1056 Reference< XComponentContext > xContext;
1057 if (aValue >>= xContext)
1058 {
1059 MutexGuard aGuard( m_mutex );
1060 m_xContext = xContext;
1061 }
1062 else
1063 {
1064 throw IllegalArgumentException(
1065 OUString( RTL_CONSTASCII_USTRINGPARAM("no XComponentContext given!") ),
1066 (OWeakObject *)this, 1 );
1067 }
1068 }
1069 else
1070 {
1071 throw UnknownPropertyException(
1072 OUString( RTL_CONSTASCII_USTRINGPARAM("unknown property ") ) + PropertyName,
1073 (OWeakObject *)this );
1074 }
1075 }
1076
getPropertyValue(const OUString & PropertyName)1077 Any OServiceManager::getPropertyValue(const OUString& PropertyName)
1078 {
1079 check_undisposed();
1080 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") ))
1081 {
1082 MutexGuard aGuard( m_mutex );
1083 if( m_xContext.is() )
1084 return makeAny( m_xContext );
1085 else
1086 return Any();
1087 }
1088 else
1089 {
1090 UnknownPropertyException except;
1091 except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager : unknown property " ) );
1092 except.Message += PropertyName;
1093 throw except;
1094 }
1095 }
1096
addPropertyChangeListener(const OUString &,const Reference<XPropertyChangeListener> &)1097 void OServiceManager::addPropertyChangeListener(
1098 const OUString&, const Reference<XPropertyChangeListener >&)
1099 {
1100 check_undisposed();
1101 throw UnknownPropertyException();
1102 }
1103
removePropertyChangeListener(const OUString &,const Reference<XPropertyChangeListener> &)1104 void OServiceManager::removePropertyChangeListener(
1105 const OUString&, const Reference<XPropertyChangeListener >&)
1106 {
1107 check_undisposed();
1108 throw UnknownPropertyException();
1109 }
1110
addVetoableChangeListener(const OUString &,const Reference<XVetoableChangeListener> &)1111 void OServiceManager::addVetoableChangeListener(
1112 const OUString&, const Reference<XVetoableChangeListener >&)
1113 {
1114 check_undisposed();
1115 throw UnknownPropertyException();
1116 }
1117
removeVetoableChangeListener(const OUString &,const Reference<XVetoableChangeListener> &)1118 void OServiceManager::removeVetoableChangeListener(
1119 const OUString&, const Reference<XVetoableChangeListener >&)
1120 {
1121 check_undisposed();
1122 throw UnknownPropertyException();
1123 }
1124
1125 // OServiceManager
getFactoryListener()1126 Reference<XEventListener > OServiceManager::getFactoryListener()
1127 {
1128 check_undisposed();
1129 MutexGuard aGuard( m_mutex );
1130 if( !xFactoryListener.is() )
1131 xFactoryListener = new OServiceManager_Listener( this );
1132 return xFactoryListener;
1133 }
1134
1135 // XMultiServiceFactory, XContentEnumeration
getUniqueAvailableServiceNames(HashSet_OWString & aNameSet)1136 Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames(
1137 HashSet_OWString & aNameSet )
1138 {
1139 check_undisposed();
1140 MutexGuard aGuard( m_mutex );
1141 HashMultimap_OWString_Interface::iterator aSIt = m_ServiceMap.begin();
1142 while( aSIt != m_ServiceMap.end() )
1143 aNameSet.insert( (*aSIt++).first );
1144
1145 /* do not return the implementation names
1146 HashMap_OWString_Interface m_ImplementationNameMap;
1147 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.begin();
1148 while( aIt != m_ImplementationNameMap.end() )
1149 aNameSet.insert( (*aIt++).first );
1150 */
1151
1152 Sequence< OUString > aNames( aNameSet.size() );
1153 OUString * pArray = aNames.getArray();
1154 sal_Int32 i = 0;
1155 HashSet_OWString::iterator next = aNameSet.begin();
1156 while( next != aNameSet.end() )
1157 pArray[i++] = (*next++);
1158
1159 return aNames;
1160 }
1161
1162 // XMultiComponentFactory
createInstanceWithContext(OUString const & rServiceSpecifier,Reference<XComponentContext> const & xContext)1163 Reference< XInterface > OServiceManager::createInstanceWithContext(
1164 OUString const & rServiceSpecifier,
1165 Reference< XComponentContext > const & xContext )
1166 {
1167 check_undisposed();
1168 #if OSL_DEBUG_LEVEL > 0
1169 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
1170 OSL_ASSERT( xProps.is() );
1171 if (xProps.is())
1172 {
1173 Reference< XComponentContext > xDefContext;
1174 xProps->getPropertyValue(
1175 OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xDefContext;
1176 OSL_ENSURE(
1177 xContext == xDefContext,
1178 "### default context of service manager singleton differs from context holding it!" );
1179 }
1180 #endif
1181
1182 Sequence< Reference< XInterface > > factories(
1183 queryServiceFactories( rServiceSpecifier, xContext ) );
1184 Reference< XInterface > const * p = factories.getConstArray();
1185 for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos )
1186 {
1187 try
1188 {
1189 Reference< XInterface > const & xFactory = p[ nPos ];
1190 if (xFactory.is())
1191 {
1192 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
1193 if (xFac.is())
1194 {
1195 return xFac->createInstanceWithContext( xContext );
1196 }
1197 else
1198 {
1199 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
1200 if (xFac2.is())
1201 {
1202 #if OSL_DEBUG_LEVEL > 1
1203 OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) );
1204 OSL_TRACE( "### ignoring given context raising service %s !!!\n", aStr.getStr() );
1205 #endif
1206 return xFac2->createInstance();
1207 }
1208 }
1209 }
1210 }
1211 catch (lang::DisposedException & exc)
1212 {
1213 #if OSL_DEBUG_LEVEL > 1
1214 OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
1215 OSL_TRACE( "### DisposedException occurred: %s", str.getStr() );
1216 #else
1217 (void) exc; // unused
1218 #endif
1219 }
1220 }
1221
1222 return Reference< XInterface >();
1223 }
1224 // XMultiComponentFactory
createInstanceWithArgumentsAndContext(OUString const & rServiceSpecifier,Sequence<Any> const & rArguments,Reference<XComponentContext> const & xContext)1225 Reference< XInterface > OServiceManager::createInstanceWithArgumentsAndContext(
1226 OUString const & rServiceSpecifier,
1227 Sequence< Any > const & rArguments,
1228 Reference< XComponentContext > const & xContext )
1229 {
1230 check_undisposed();
1231 #if OSL_DEBUG_LEVEL > 0
1232 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
1233 OSL_ASSERT( xProps.is() );
1234 if (xProps.is())
1235 {
1236 Reference< XComponentContext > xDefContext;
1237 xProps->getPropertyValue(
1238 OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xDefContext;
1239 OSL_ENSURE(
1240 xContext == xDefContext,
1241 "### default context of service manager singleton differs from context holding it!" );
1242 }
1243 #endif
1244
1245 Sequence< Reference< XInterface > > factories(
1246 queryServiceFactories( rServiceSpecifier, xContext ) );
1247 Reference< XInterface > const * p = factories.getConstArray();
1248 for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos )
1249 {
1250 try
1251 {
1252 Reference< XInterface > const & xFactory = p[ nPos ];
1253 if (xFactory.is())
1254 {
1255 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
1256 if (xFac.is())
1257 {
1258 return xFac->createInstanceWithArgumentsAndContext( rArguments, xContext );
1259 }
1260 else
1261 {
1262 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
1263 if (xFac2.is())
1264 {
1265 #if OSL_DEBUG_LEVEL > 1
1266 OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) );
1267 OSL_TRACE( "### ignoring given context raising service %s !!!\n", aStr.getStr() );
1268 #endif
1269 return xFac2->createInstanceWithArguments( rArguments );
1270 }
1271 }
1272 }
1273 }
1274 catch (lang::DisposedException & exc)
1275 {
1276 #if OSL_DEBUG_LEVEL > 1
1277 OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
1278 OSL_TRACE( "### DisposedException occurred: %s", str.getStr() );
1279 #else
1280 (void) exc; // unused
1281 #endif
1282 }
1283 }
1284
1285 return Reference< XInterface >();
1286 }
1287
1288 // XMultiServiceFactory, XMultiComponentFactory, XContentEnumeration
getAvailableServiceNames()1289 Sequence< OUString > OServiceManager::getAvailableServiceNames()
1290 {
1291 check_undisposed();
1292 // all names
1293 HashSet_OWString aNameSet;
1294 return getUniqueAvailableServiceNames( aNameSet );
1295 }
1296
1297 // XMultibleServiceFactory
createInstance(const OUString & rServiceSpecifier)1298 Reference<XInterface > OServiceManager::createInstance(
1299 const OUString& rServiceSpecifier )
1300 {
1301 return createInstanceWithContext(
1302 rServiceSpecifier, m_xContext );
1303 }
1304
1305 // XMultibleServiceFactory
createInstanceWithArguments(const OUString & rServiceSpecifier,const Sequence<Any> & rArguments)1306 Reference<XInterface > OServiceManager::createInstanceWithArguments(
1307 const OUString& rServiceSpecifier,
1308 const Sequence<Any >& rArguments )
1309 {
1310 return createInstanceWithArgumentsAndContext(
1311 rServiceSpecifier, rArguments, m_xContext );
1312 }
1313
1314 // XInitialization
initialize(Sequence<Any> const &)1315 void OServiceManager::initialize( Sequence< Any > const & )
1316 {
1317 check_undisposed();
1318 OSL_ENSURE( 0, "not impl!" );
1319 }
1320
1321 // XServiceInfo
getImplementationName()1322 OUString OServiceManager::getImplementationName()
1323 {
1324 check_undisposed();
1325 return getImplementationName_Static();
1326 }
1327
1328 // XServiceInfo
supportsService(const OUString & ServiceName)1329 sal_Bool OServiceManager::supportsService(const OUString& ServiceName)
1330 {
1331 check_undisposed();
1332 Sequence< OUString > aSNL = getSupportedServiceNames();
1333 const OUString * pArray = aSNL.getConstArray();
1334 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1335 if( pArray[i] == ServiceName )
1336 return sal_True;
1337 return sal_False;
1338 }
1339
1340 // XServiceInfo
getSupportedServiceNames()1341 Sequence< OUString > OServiceManager::getSupportedServiceNames()
1342 {
1343 check_undisposed();
1344 return stoc_bootstrap::smgr_getSupportedServiceNames();
1345 }
1346
1347
queryServiceFactories(const OUString & aServiceName,Reference<XComponentContext> const &)1348 Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories(
1349 const OUString& aServiceName, Reference< XComponentContext > const & )
1350 {
1351 Sequence< Reference< XInterface > > ret;
1352
1353 MutexGuard aGuard( m_mutex );
1354 ::std::pair<
1355 HashMultimap_OWString_Interface::iterator,
1356 HashMultimap_OWString_Interface::iterator> p(
1357 m_ServiceMap.equal_range( aServiceName ) );
1358
1359 if (p.first == p.second) // no factories
1360 {
1361 // no service found, look for an implementation
1362 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.find( aServiceName );
1363 if( aIt != m_ImplementationNameMap.end() )
1364 {
1365 Reference< XInterface > const & x = aIt->second;
1366 // an implementation found
1367 ret = Sequence< Reference< XInterface > >( &x, 1 );
1368 }
1369 }
1370 else
1371 {
1372 ::std::vector< Reference< XInterface > > vec;
1373 vec.reserve( 4 );
1374 while (p.first != p.second)
1375 {
1376 vec.push_back( p.first->second );
1377 ++p.first;
1378 }
1379 ret = Sequence< Reference< XInterface > >(
1380 vec.empty() ? 0 : &vec[ 0 ], vec.size() );
1381 }
1382
1383 return ret;
1384 }
1385
1386 // XContentEnumerationAccess
createContentEnumeration(const OUString & aServiceName,Reference<XComponentContext> const & xContext)1387 Reference<XEnumeration > OServiceManager::createContentEnumeration(
1388 const OUString& aServiceName, Reference< XComponentContext > const & xContext )
1389 {
1390 check_undisposed();
1391 Sequence< Reference< XInterface > > factories(
1392 OServiceManager::queryServiceFactories( aServiceName, xContext ) );
1393 if (factories.getLength())
1394 return new ServiceEnumeration_Impl( factories );
1395 else
1396 return Reference< XEnumeration >();
1397 }
createContentEnumeration(const OUString & aServiceName)1398 Reference<XEnumeration > OServiceManager::createContentEnumeration(
1399 const OUString& aServiceName )
1400 {
1401 return createContentEnumeration( aServiceName, m_xContext );
1402 }
1403
1404 // XEnumeration
createEnumeration()1405 Reference<XEnumeration > OServiceManager::createEnumeration()
1406 {
1407 check_undisposed();
1408 MutexGuard aGuard( m_mutex );
1409 return new ImplementationEnumeration_Impl( m_ImplementationMap );
1410 }
1411
1412 // XElementAccess
getElementType()1413 Type OServiceManager::getElementType()
1414 {
1415 check_undisposed();
1416 return ::getCppuType( (const Reference< XInterface > *)0 );
1417 }
1418
1419 // XElementAccess
hasElements()1420 sal_Bool OServiceManager::hasElements()
1421 {
1422 check_undisposed();
1423 MutexGuard aGuard( m_mutex );
1424 return !m_ImplementationMap.empty();
1425 }
1426
1427 // XSet
has(const Any & Element)1428 sal_Bool OServiceManager::has( const Any & Element )
1429 {
1430 check_undisposed();
1431 if( Element.getValueTypeClass() == TypeClass_INTERFACE )
1432 {
1433 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
1434 MutexGuard aGuard( m_mutex );
1435 return m_ImplementationMap.find( xEle ) !=
1436 m_ImplementationMap.end();
1437 }
1438 else if (Element.getValueTypeClass() == TypeClass_STRING)
1439 {
1440 OUString const & implName =
1441 *reinterpret_cast< OUString const * >(Element.getValue());
1442 MutexGuard aGuard( m_mutex );
1443 return m_ImplementationNameMap.find( implName ) !=
1444 m_ImplementationNameMap.end();
1445 }
1446 return sal_False;
1447 }
1448
1449 // XSet
insert(const Any & Element)1450 void OServiceManager::insert( const Any & Element )
1451 {
1452 check_undisposed();
1453 if( Element.getValueTypeClass() != TypeClass_INTERFACE )
1454 {
1455 throw IllegalArgumentException(
1456 OUString( RTL_CONSTASCII_USTRINGPARAM("no interface given!") ),
1457 Reference< XInterface >(), 0 );
1458 }
1459 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
1460
1461 {
1462 MutexGuard aGuard( m_mutex );
1463 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1464 if( aIt != m_ImplementationMap.end() )
1465 {
1466 throw ElementExistException(
1467 OUString( RTL_CONSTASCII_USTRINGPARAM("element already exists!") ),
1468 Reference< XInterface >() );
1469 }
1470
1471 // put into the implementation hashmap
1472 m_ImplementationMap.insert( xEle );
1473
1474 // put into the implementation name hashmap
1475 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1476 if( xInfo.is() )
1477 {
1478 OUString aImplName = xInfo->getImplementationName();
1479 if( aImplName.getLength() )
1480 m_ImplementationNameMap[ aImplName ] = xEle;
1481
1482 //put into the service map
1483 Sequence< OUString > aServiceNames = xInfo->getSupportedServiceNames();
1484 const OUString * pArray = aServiceNames.getConstArray();
1485 for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ )
1486 {
1487 m_ServiceMap.insert( HashMultimap_OWString_Interface::value_type(
1488 pArray[i], *(Reference<XInterface > *)Element.getValue() ) );
1489 }
1490 }
1491 }
1492 // add the disposing listener to the factory
1493 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1494 if( xComp.is() )
1495 xComp->addEventListener( getFactoryListener() );
1496 }
1497
1498 // helper function
haveFactoryWithThisImplementation(const OUString & aImplName)1499 sal_Bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName)
1500 {
1501 return ( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end());
1502 }
1503
1504 // XSet
remove(const Any & Element)1505 void OServiceManager::remove( const Any & Element )
1506 {
1507 if (is_disposed())
1508 return;
1509
1510 Reference<XInterface > xEle;
1511 if (Element.getValueTypeClass() == TypeClass_INTERFACE)
1512 {
1513 xEle.set( Element, UNO_QUERY_THROW );
1514 }
1515 else if (Element.getValueTypeClass() == TypeClass_STRING)
1516 {
1517 OUString const & implName =
1518 *reinterpret_cast< OUString const * >(Element.getValue());
1519 MutexGuard aGuard( m_mutex );
1520 HashMap_OWString_Interface::const_iterator const iFind(
1521 m_ImplementationNameMap.find( implName ) );
1522 if (iFind == m_ImplementationNameMap.end())
1523 {
1524 throw NoSuchElementException(
1525 OUString( RTL_CONSTASCII_USTRINGPARAM("element is not in: ") )
1526 + implName, static_cast< OWeakObject * >(this) );
1527 }
1528 xEle = iFind->second;
1529 }
1530 else
1531 {
1532 throw IllegalArgumentException(
1533 OUString( RTL_CONSTASCII_USTRINGPARAM(
1534 "neither interface nor string given!") ),
1535 Reference< XInterface >(), 0 );
1536 }
1537
1538 // remove the disposing listener from the factory
1539 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1540 if( xComp.is() )
1541 xComp->removeEventListener( getFactoryListener() );
1542
1543 MutexGuard aGuard( m_mutex );
1544 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1545 if( aIt == m_ImplementationMap.end() )
1546 {
1547 throw NoSuchElementException(
1548 OUString( RTL_CONSTASCII_USTRINGPARAM("element is not in!") ),
1549 static_cast< OWeakObject * >(this) );
1550 }
1551 //First remove all factories which have been loaded by ORegistryServiceManager.
1552 m_SetLoadedFactories.erase( *aIt);
1553 //Remove from the implementation map. It contains all factories of m_SetLoadedFactories
1554 //which have been added directly through XSet, that is not via ORegistryServiceManager
1555 m_ImplementationMap.erase( aIt );
1556
1557 // remove from the implementation name hashmap
1558 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1559 if( xInfo.is() )
1560 {
1561 OUString aImplName = xInfo->getImplementationName();
1562 if( aImplName.getLength() )
1563 m_ImplementationNameMap.erase( aImplName );
1564 }
1565
1566 //remove from the service map
1567 Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) );
1568 if( xSF.is() )
1569 {
1570 Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames();
1571 const OUString * pArray = aServiceNames.getConstArray();
1572 for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ )
1573 {
1574 pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> p =
1575 m_ServiceMap.equal_range( pArray[i] );
1576
1577 while( p.first != p.second )
1578 {
1579 if( xEle == (*p.first).second )
1580 {
1581 m_ServiceMap.erase( p.first );
1582 break;
1583 }
1584 ++p.first;
1585 }
1586 }
1587 }
1588 }
1589
1590 /*****************************************************************************
1591 class ORegistryServiceManager
1592 *****************************************************************************/
1593 class ORegistryServiceManager : public OServiceManager
1594 {
1595 public:
1596 ORegistryServiceManager( Reference< XComponentContext > const & xContext );
1597 virtual ~ORegistryServiceManager();
1598
1599 // XInitialization
1600 void SAL_CALL initialize(const Sequence< Any >& Arguments);
1601
1602 // XServiceInfo
getImplementationName()1603 OUString SAL_CALL getImplementationName()
1604 { return stoc_bootstrap::regsmgr_getImplementationName(); }
1605
1606 Sequence< OUString > SAL_CALL getSupportedServiceNames();
1607
1608 // XMultiServiceFactory
1609 Sequence< OUString > SAL_CALL getAvailableServiceNames();
1610
1611 // XContentEnumerationAccess
1612 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
1613 Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName);
1614 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(
1615 const OUString& aServiceName, Reference< XComponentContext > const & xContext );
1616
1617 // XComponent
1618 void SAL_CALL dispose();
1619
1620 // OServiceManager
1621 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo();
1622 Any SAL_CALL getPropertyValue(const OUString& PropertyName);
1623
1624 protected:
1625 //OServiceManager
1626 Sequence< Reference< XInterface > > queryServiceFactories(
1627 const OUString& aServiceName, Reference< XComponentContext > const & xContext );
1628 private:
1629 Reference<XRegistryKey > getRootKey();
1630 Reference<XInterface > loadWithImplementationName(
1631 const OUString & rImplName, Reference< XComponentContext > const & xContext );
1632 Sequence<OUString> getFromServiceName(const OUString& serviceName);
1633 Reference<XInterface > loadWithServiceName(
1634 const OUString & rImplName, Reference< XComponentContext > const & xContext );
1635 void fillAllNamesFromRegistry( HashSet_OWString & );
1636
1637 sal_Bool m_searchedRegistry;
1638 Reference<XSimpleRegistry > m_xRegistry; // readonly property Registry
1639 Reference<XRegistryKey > m_xRootKey;
1640
1641 #if OSL_DEBUG_LEVEL > 0
1642 bool m_init;
1643 #endif
1644 };
1645
1646 /**
1647 * Create a ServiceManager
1648 */
ORegistryServiceManager(Reference<XComponentContext> const & xContext)1649 ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext > const & xContext )
1650 : OServiceManager( xContext )
1651 , m_searchedRegistry(sal_False)
1652 #if OSL_DEBUG_LEVEL > 0
1653 , m_init( false )
1654 #endif
1655 {
1656 }
1657
1658 /**
1659 * Destroy the ServiceManager
1660 */
~ORegistryServiceManager()1661 ORegistryServiceManager::~ORegistryServiceManager()
1662 {
1663 }
1664
1665 // XComponent
dispose()1666 void ORegistryServiceManager::dispose()
1667 {
1668 if (rBHelper.bDisposed || rBHelper.bInDispose)
1669 return;
1670 OServiceManager::dispose();
1671 // dispose
1672 MutexGuard aGuard( m_mutex );
1673 // erase all members
1674 m_xRegistry = Reference<XSimpleRegistry >();
1675 m_xRootKey = Reference<XRegistryKey >();
1676 }
1677
1678 /**
1679 * Return the root key of the registry. The Default registry service is ordered
1680 * if no registry is set.
1681 */
1682 //Reference<XServiceProvider > create_DefaultRegistry_ServiceProvider();
1683
getRootKey()1684 Reference<XRegistryKey > ORegistryServiceManager::getRootKey()
1685 {
1686 if( !m_xRootKey.is() )
1687 {
1688 MutexGuard aGuard( m_mutex );
1689 // DefaultRegistry suchen !!!!
1690 if( !m_xRegistry.is() && !m_searchedRegistry )
1691 {
1692 // merken, es wird nur einmal gesucht
1693 m_searchedRegistry = sal_True;
1694
1695 m_xRegistry.set(
1696 createInstanceWithContext(
1697 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.DefaultRegistry") ),
1698 m_xContext ),
1699 UNO_QUERY );
1700 }
1701 if( m_xRegistry.is() && !m_xRootKey.is() )
1702 m_xRootKey = m_xRegistry->getRootKey();
1703 }
1704
1705 return m_xRootKey;
1706 }
1707
1708 /**
1709 * Create a service provider from the registry with an implementation name
1710 */
loadWithImplementationName(const OUString & name,Reference<XComponentContext> const & xContext)1711 Reference<XInterface > ORegistryServiceManager::loadWithImplementationName(
1712 const OUString& name, Reference< XComponentContext > const & xContext )
1713 {
1714 Reference<XInterface > ret;
1715
1716 Reference<XRegistryKey > xRootKey = getRootKey();
1717 if( !xRootKey.is() )
1718 return ret;
1719
1720 try
1721 {
1722 OUString implementationName = OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS/") ) + name;
1723 Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName);
1724
1725 if( xImpKey.is() )
1726 {
1727 Reference< lang::XMultiServiceFactory > xMgr;
1728 if (xContext.is())
1729 xMgr.set( xContext->getServiceManager(), UNO_QUERY_THROW );
1730 else
1731 xMgr.set( this );
1732 ret = createSingleRegistryFactory( xMgr, name, xImpKey );
1733 insert( makeAny( ret ) );
1734 // Remember this factory as loaded in contrast to inserted ( XSet::insert)
1735 // factories. Those loaded factories in this set are candidates for being
1736 // released on an unloading notification.
1737 m_SetLoadedFactories.insert( ret);
1738 }
1739 }
1740 catch (InvalidRegistryException &)
1741 {
1742 }
1743
1744 return ret;
1745 }
1746
1747 /**
1748 * Return all implementation out of the registry.
1749 */
getFromServiceName(const OUString & serviceName)1750 Sequence<OUString> ORegistryServiceManager::getFromServiceName(
1751 const OUString& serviceName )
1752 {
1753 OUStringBuffer buf;
1754 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/SERVICES/" ) );
1755 buf.append( serviceName );
1756 return retrieveAsciiValueList( m_xRegistry, buf.makeStringAndClear() );
1757 }
1758
1759 /**
1760 * Create a service provider from the registry
1761 */
loadWithServiceName(const OUString & serviceName,Reference<XComponentContext> const & xContext)1762 Reference<XInterface > ORegistryServiceManager::loadWithServiceName(
1763 const OUString& serviceName, Reference< XComponentContext > const & xContext )
1764 {
1765 Sequence<OUString> implEntries = getFromServiceName( serviceName );
1766 for (sal_Int32 i = 0; i < implEntries.getLength(); i++)
1767 {
1768 Reference< XInterface > x(
1769 loadWithImplementationName( implEntries.getConstArray()[i], xContext ) );
1770 if (x.is())
1771 return x;
1772 }
1773
1774 return Reference<XInterface >();
1775 }
1776
1777 /**
1778 * Return a sequence of all service names from the registry.
1779 */
fillAllNamesFromRegistry(HashSet_OWString & rSet)1780 void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet )
1781 {
1782 Reference<XRegistryKey > xRootKey = getRootKey();
1783 if( !xRootKey.is() )
1784 return;
1785
1786 try
1787 {
1788 Reference<XRegistryKey > xServicesKey = xRootKey->openKey(
1789 OUString( RTL_CONSTASCII_USTRINGPARAM("SERVICES") ) );
1790 // root + /Services + /
1791 if( xServicesKey.is() )
1792 {
1793 sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1;
1794 Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys();
1795 for( sal_Int32 i = 0; i < aKeys.getLength(); i++ )
1796 rSet.insert( aKeys.getConstArray()[i]->getKeyName().copy( nPrefix ) );
1797 }
1798 }
1799 catch (InvalidRegistryException &)
1800 {
1801 }
1802 }
1803
1804 // XInitialization
initialize(const Sequence<Any> & Arguments)1805 void ORegistryServiceManager::initialize(const Sequence< Any >& Arguments)
1806 {
1807 check_undisposed();
1808 MutexGuard aGuard( m_mutex );
1809 if (Arguments.getLength() > 0)
1810 {
1811 m_xRootKey.clear();
1812 Arguments[ 0 ] >>= m_xRegistry;
1813 }
1814 #if OSL_DEBUG_LEVEL > 0
1815 // to find all bootstrapping processes to be fixed...
1816 OSL_ENSURE( !m_init, "### second init of service manager instance!" );
1817 m_init = true;
1818 #endif
1819 }
1820
1821 // XMultiServiceFactory, XContentEnumeration
getAvailableServiceNames()1822 Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames()
1823 {
1824 check_undisposed();
1825 MutexGuard aGuard( m_mutex );
1826 // all names
1827 HashSet_OWString aNameSet;
1828
1829 // all names from the registry
1830 fillAllNamesFromRegistry( aNameSet );
1831
1832 return OServiceManager::getUniqueAvailableServiceNames( aNameSet );
1833 }
1834
1835 // XServiceInfo
getSupportedServiceNames()1836 Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames()
1837 {
1838 check_undisposed();
1839 return stoc_bootstrap::regsmgr_getSupportedServiceNames();
1840 }
1841
1842
1843 // OServiceManager
queryServiceFactories(const OUString & aServiceName,Reference<XComponentContext> const & xContext)1844 Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories(
1845 const OUString& aServiceName, Reference< XComponentContext > const & xContext )
1846 {
1847 Sequence< Reference< XInterface > > ret(
1848 OServiceManager::queryServiceFactories( aServiceName, xContext ) );
1849 if (ret.getLength())
1850 {
1851 return ret;
1852 }
1853 else
1854 {
1855 MutexGuard aGuard( m_mutex );
1856 Reference< XInterface > x( loadWithServiceName( aServiceName, xContext ) );
1857 if (! x.is())
1858 x = loadWithImplementationName( aServiceName, xContext );
1859 return Sequence< Reference< XInterface > >( &x, 1 );
1860 }
1861 }
1862
1863 // XContentEnumerationAccess
createContentEnumeration(const OUString & aServiceName,Reference<XComponentContext> const & xContext)1864 Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
1865 const OUString& aServiceName, Reference< XComponentContext > const & xContext )
1866 {
1867 check_undisposed();
1868 MutexGuard aGuard( ((ORegistryServiceManager *)this)->m_mutex );
1869 // get all implementation names registered under this service name from the registry
1870 Sequence<OUString> aImpls = ((ORegistryServiceManager *)this)->getFromServiceName( aServiceName );
1871 // load and insert all factories specified by the registry
1872 sal_Int32 i;
1873 OUString aImplName;
1874 for( i = 0; i < aImpls.getLength(); i++ )
1875 {
1876 aImplName = aImpls.getConstArray()[i];
1877 if ( !haveFactoryWithThisImplementation(aImplName) )
1878 {
1879 loadWithImplementationName( aImplName, xContext );
1880 }
1881 }
1882 // call the superclass to enumerate all contents
1883 return OServiceManager::createContentEnumeration( aServiceName, xContext );
1884 }
createContentEnumeration(const OUString & aServiceName)1885 Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
1886 const OUString& aServiceName )
1887 {
1888 return createContentEnumeration( aServiceName, m_xContext );
1889 }
1890
1891 // OServiceManager
getPropertySetInfo()1892 Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo()
1893 {
1894 check_undisposed();
1895 if (! m_xPropertyInfo.is())
1896 {
1897 Sequence< beans::Property > seq( 2 );
1898 seq[ 0 ] = beans::Property(
1899 OUSTR("DefaultContext"), -1, ::getCppuType( &m_xContext ), 0 );
1900 seq[ 1 ] = beans::Property(
1901 OUSTR("Registry"), -1, ::getCppuType( &m_xRegistry ),
1902 beans::PropertyAttribute::READONLY );
1903 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
1904
1905 MutexGuard aGuard( m_mutex );
1906 if (! m_xPropertyInfo.is())
1907 {
1908 m_xPropertyInfo = xInfo;
1909 }
1910 }
1911 return m_xPropertyInfo;
1912 }
1913
getPropertyValue(const OUString & PropertyName)1914 Any ORegistryServiceManager::getPropertyValue(const OUString& PropertyName)
1915 {
1916 check_undisposed();
1917 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Registry") ))
1918 {
1919 MutexGuard aGuard( m_mutex );
1920 if( m_xRegistry.is() )
1921 return makeAny( m_xRegistry );
1922 else
1923 return Any();
1924 }
1925 return OServiceManager::getPropertyValue( PropertyName );
1926 }
1927
1928 /* This is the listener function used by the service manager in order
1929 to implement the unloading mechanism, id is the this pointer of the
1930 service manager instances. On notification, that is the function is being called
1931 by rtl_unloadUnusedModules, the cached factroies are being removed from the
1932 service manager ( except manually inserted factories).
1933 */
smgrUnloadingListener(void * id)1934 extern "C" void SAL_CALL smgrUnloadingListener(void* id)
1935 {
1936 stoc_smgr::OServiceManager* pMgr= reinterpret_cast<stoc_smgr::OServiceManager*>( id);
1937 pMgr->onUnloadingNotify();
1938 }
1939
1940 } // namespace
1941
1942 namespace stoc_bootstrap
1943 {
1944 /**
1945 * Create the ServiceManager
1946 */
OServiceManager_CreateInstance(const Reference<XComponentContext> & xContext)1947 Reference<XInterface > SAL_CALL OServiceManager_CreateInstance(
1948 const Reference< XComponentContext > & xContext )
1949 {
1950 return Reference<XInterface >(
1951 SAL_STATIC_CAST(
1952 XInterface *, SAL_STATIC_CAST(
1953 OWeakObject *, new stoc_smgr::OServiceManager( xContext ) ) ) );
1954 }
1955
1956 /**
1957 * Create the ServiceManager
1958 */
ORegistryServiceManager_CreateInstance(const Reference<XComponentContext> & xContext)1959 Reference<XInterface > SAL_CALL ORegistryServiceManager_CreateInstance(
1960 const Reference< XComponentContext > & xContext )
1961 {
1962 return Reference<XInterface >(
1963 SAL_STATIC_CAST(
1964 XInterface *, SAL_STATIC_CAST(
1965 OWeakObject *, new stoc_smgr::ORegistryServiceManager( xContext ) ) ) );
1966 }
1967
OServiceManagerWrapper_CreateInstance(const Reference<XComponentContext> & xContext)1968 Reference<XInterface > SAL_CALL OServiceManagerWrapper_CreateInstance(
1969 const Reference< XComponentContext > & xContext )
1970 {
1971 return (OWeakObject *)new stoc_smgr::OServiceManagerWrapper( xContext );
1972 }
1973 }
1974