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