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