fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / stoc / source / servicemanager / servicemanager.cxx
blob5caa90e95645b397d1a6caeda4b7c0631b69920c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <osl/mutex.hxx>
21 #include <osl/diagnose.h>
22 #include <rtl/ustrbuf.hxx>
24 #include <boost/unordered_map.hpp>
25 #include <boost/unordered_set.hpp>
26 #include <uno/mapping.hxx>
27 #include <uno/dispatcher.h>
28 #include <cppuhelper/queryinterface.hxx>
29 #include <cppuhelper/weakref.hxx>
30 #include <cppuhelper/component.hxx>
31 #include <cppuhelper/factory.hxx>
32 #include <cppuhelper/implbase1.hxx>
33 #include <cppuhelper/implementationentry.hxx>
34 #include <cppuhelper/component_context.hxx>
35 #include <cppuhelper/bootstrap.hxx>
36 #include <cppuhelper/compbase6.hxx>
37 #include <cppuhelper/compbase7.hxx>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
42 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
44 #include <com/sun/star/lang/XInitialization.hpp>
45 #include <com/sun/star/lang/XEventListener.hpp>
46 #include <com/sun/star/lang/DisposedException.hpp>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 #include <com/sun/star/beans/PropertyAttribute.hpp>
49 #include <com/sun/star/registry/XRegistryKey.hpp>
50 #include <com/sun/star/registry/XSimpleRegistry.hpp>
51 #include <com/sun/star/container/XSet.hpp>
52 #include <com/sun/star/container/XElementAccess.hpp>
53 #include <com/sun/star/container/XEnumeration.hpp>
54 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
55 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
56 #include <com/sun/star/uno/XUnloadingPreference.hpp>
58 #include <bootstrapservices.hxx>
61 using namespace com::sun::star;
62 using namespace com::sun::star::uno;
63 using namespace com::sun::star::beans;
64 using namespace com::sun::star::registry;
65 using namespace com::sun::star::lang;
66 using namespace com::sun::star::container;
67 using namespace cppu;
68 using namespace osl;
69 using namespace std;
71 namespace stoc_bootstrap
73 Sequence< OUString > smgr_wrapper_getSupportedServiceNames()
75 Sequence< OUString > seqNames(1);
76 seqNames.getArray()[0] = OUString("com.sun.star.lang.MultiServiceFactory");
77 return seqNames;
80 OUString smgr_wrapper_getImplementationName()
82 return OUString("com.sun.star.comp.stoc.OServiceManagerWrapper");
85 Sequence< OUString > smgr_getSupportedServiceNames()
87 Sequence< OUString > seqNames(2);
88 seqNames.getArray()[0] = OUString("com.sun.star.lang.MultiServiceFactory");
89 seqNames.getArray()[1] = OUString("com.sun.star.lang.ServiceManager");
90 return seqNames;
93 OUString smgr_getImplementationName()
95 return OUString("com.sun.star.comp.stoc.OServiceManager");
98 Sequence< OUString > regsmgr_getSupportedServiceNames()
100 Sequence< OUString > seqNames(2);
101 seqNames.getArray()[0] = OUString("com.sun.star.lang.MultiServiceFactory");
102 seqNames.getArray()[1] = OUString("com.sun.star.lang.RegistryServiceManager");
103 return seqNames;
106 OUString regsmgr_getImplementationName()
108 return OUString( "com.sun.star.comp.stoc.ORegistryServiceManager" );
112 namespace stoc_smgr
115 static Sequence< OUString > retrieveAsciiValueList(
116 const Reference< XSimpleRegistry > &xReg, const OUString &keyName )
118 Reference< XEnumerationAccess > xAccess( xReg, UNO_QUERY );
119 Sequence< OUString > seq;
120 if( xAccess.is() )
122 Reference< XEnumeration > xEnum = xAccess->createEnumeration();
123 while( xEnum.is() && xEnum->hasMoreElements() )
125 Reference< XSimpleRegistry > xTempReg;
126 xEnum->nextElement() >>= xTempReg;
127 if( xTempReg.is() )
129 Sequence< OUString > seq2 = retrieveAsciiValueList( xTempReg, keyName );
131 if( seq2.getLength() )
133 sal_Int32 n1Len = seq.getLength();
134 sal_Int32 n2Len = seq2.getLength();
136 seq.realloc( n1Len + n2Len );
137 const OUString *pSource = seq2.getConstArray();
138 OUString *pTarget = seq.getArray();
139 for( int i = 0 ; i < n2Len ; i ++ )
141 pTarget[i+n1Len] = pSource[i];
147 else if( xReg.is () )
151 Reference< XRegistryKey > rRootKey = xReg->getRootKey();
152 if( rRootKey.is() )
154 Reference<XRegistryKey > xKey = rRootKey->openKey(keyName);
155 if( xKey.is() )
157 seq = xKey->getAsciiListValue();
161 catch( InvalidRegistryException & )
164 catch (InvalidValueException &)
168 return seq;
171 /*****************************************************************************
172 Enumeration by ServiceName
173 *****************************************************************************/
174 struct hashRef_Impl
176 size_t operator()(const Reference<XInterface > & rName) const
178 // query to XInterface. The cast to XInterface* must be the same for the same object
179 Reference<XInterface > x( Reference<XInterface >::query( rName ) );
180 return (size_t)x.get();
184 struct equaltoRef_Impl
186 size_t operator()(const Reference<XInterface > & rName1, const Reference<XInterface > & rName2 ) const
187 { return rName1 == rName2; }
190 typedef boost::unordered_set
192 Reference<XInterface >,
193 hashRef_Impl,
194 equaltoRef_Impl
195 > HashSet_Ref;
198 class ServiceEnumeration_Impl : public WeakImplHelper1< XEnumeration >
200 public:
201 ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories )
202 : aFactories( rFactories )
203 , nIt( 0 )
205 virtual ~ServiceEnumeration_Impl() {}
207 // XEnumeration
208 sal_Bool SAL_CALL hasMoreElements()
209 throw(::com::sun::star::uno::RuntimeException);
210 Any SAL_CALL nextElement()
211 throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
212 private:
213 Mutex aMutex;
214 Sequence< Reference<XInterface > > aFactories;
215 sal_Int32 nIt;
218 // XEnumeration
219 sal_Bool ServiceEnumeration_Impl::hasMoreElements() throw(::com::sun::star::uno::RuntimeException)
221 MutexGuard aGuard( aMutex );
222 return nIt != aFactories.getLength();
225 // XEnumeration
226 Any ServiceEnumeration_Impl::nextElement()
227 throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
229 MutexGuard aGuard( aMutex );
230 if( nIt == aFactories.getLength() )
231 throw NoSuchElementException();
233 return Any( &aFactories.getConstArray()[nIt++], ::getCppuType( (const Reference<XInterface > *)0 ) );
236 //==================================================================================================
237 class PropertySetInfo_Impl : public WeakImplHelper1< beans::XPropertySetInfo >
239 Sequence< beans::Property > m_properties;
241 public:
242 inline PropertySetInfo_Impl( Sequence< beans::Property > const & properties ) SAL_THROW(())
243 : m_properties( properties )
246 // XPropertySetInfo impl
247 virtual Sequence< beans::Property > SAL_CALL getProperties()
248 throw (RuntimeException);
249 virtual beans::Property SAL_CALL getPropertyByName( OUString const & name )
250 throw (beans::UnknownPropertyException, RuntimeException);
251 virtual sal_Bool SAL_CALL hasPropertyByName( OUString const & name )
252 throw (RuntimeException);
254 //__________________________________________________________________________________________________
255 Sequence< beans::Property > PropertySetInfo_Impl::getProperties()
256 throw (RuntimeException)
258 return m_properties;
260 //__________________________________________________________________________________________________
261 beans::Property PropertySetInfo_Impl::getPropertyByName( OUString const & name )
262 throw (beans::UnknownPropertyException, RuntimeException)
264 beans::Property const * p = m_properties.getConstArray();
265 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
267 if (p[ nPos ].Name.equals( name ))
268 return p[ nPos ];
270 throw beans::UnknownPropertyException(
271 "unknown property: " + name, Reference< XInterface >() );
273 //__________________________________________________________________________________________________
274 sal_Bool PropertySetInfo_Impl::hasPropertyByName( OUString const & name )
275 throw (RuntimeException)
277 beans::Property const * p = m_properties.getConstArray();
278 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
280 if (p[ nPos ].Name.equals( name ))
281 return sal_True;
283 return sal_False;
287 /*****************************************************************************
288 Enumeration by implementation
289 *****************************************************************************/
290 class ImplementationEnumeration_Impl : public WeakImplHelper1< XEnumeration >
292 public:
293 ImplementationEnumeration_Impl( const HashSet_Ref & rImplementationMap )
294 : aImplementationMap( rImplementationMap )
295 , aIt( aImplementationMap.begin() )
297 virtual ~ImplementationEnumeration_Impl();
299 // XEnumeration
300 virtual sal_Bool SAL_CALL hasMoreElements()
301 throw(::com::sun::star::uno::RuntimeException);
302 virtual Any SAL_CALL nextElement()
303 throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
305 private:
306 Mutex aMutex;
307 HashSet_Ref aImplementationMap;
308 HashSet_Ref::iterator aIt;
309 Reference<XInterface > xNext;
312 ImplementationEnumeration_Impl::~ImplementationEnumeration_Impl() {}
314 // XEnumeration
315 sal_Bool ImplementationEnumeration_Impl::hasMoreElements()
316 throw(::com::sun::star::uno::RuntimeException)
318 MutexGuard aGuard( aMutex );
319 return aIt != aImplementationMap.end();
322 // XEnumeration
323 Any ImplementationEnumeration_Impl::nextElement()
324 throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
326 MutexGuard aGuard( aMutex );
327 if( aIt == aImplementationMap.end() )
328 throw NoSuchElementException();
330 Any ret( &(*aIt), ::getCppuType( (const Reference<XInterface > *)0 ) );
331 ++aIt;
332 return ret;
335 /*****************************************************************************
336 Hash tables
337 *****************************************************************************/
338 struct equalOWString_Impl
340 sal_Bool operator()(const OUString & s1, const OUString & s2) const
341 { return s1 == s2; }
344 struct hashOWString_Impl
346 size_t operator()(const OUString & rName) const
347 { return rName.hashCode(); }
350 typedef boost::unordered_set
352 OUString,
353 hashOWString_Impl,
354 equalOWString_Impl
355 > HashSet_OWString;
357 typedef boost::unordered_multimap
359 OUString,
360 Reference<XInterface >,
361 hashOWString_Impl,
362 equalOWString_Impl
363 > HashMultimap_OWString_Interface;
365 typedef boost::unordered_map
367 OUString,
368 Reference<XInterface >,
369 hashOWString_Impl,
370 equalOWString_Impl
371 > HashMap_OWString_Interface;
373 /*****************************************************************************
374 class OServiceManager_Listener
375 *****************************************************************************/
376 class OServiceManager_Listener : public WeakImplHelper1< XEventListener >
378 private:
379 WeakReference<XSet > xSMgr;
381 public:
382 OServiceManager_Listener( const Reference<XSet > & rSMgr )
383 : xSMgr( rSMgr )
386 // XEventListener
387 virtual void SAL_CALL disposing(const EventObject & rEvt ) throw(::com::sun::star::uno::RuntimeException);
390 void OServiceManager_Listener::disposing(const EventObject & rEvt )
391 throw(::com::sun::star::uno::RuntimeException)
393 Reference<XSet > x( xSMgr );
394 if( x.is() )
398 x->remove( Any( &rEvt.Source, ::getCppuType( (const Reference<XInterface > *)0 ) ) );
400 catch( const IllegalArgumentException & )
402 OSL_FAIL( "IllegalArgumentException caught" );
404 catch( const NoSuchElementException & )
406 OSL_FAIL( "NoSuchElementException caught" );
412 /*****************************************************************************
413 class OServiceManager
414 *****************************************************************************/
415 struct OServiceManagerMutex
417 Mutex m_mutex;
420 typedef WeakComponentImplHelper7<
421 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
422 lang::XInitialization,
423 container::XSet, container::XContentEnumerationAccess,
424 beans::XPropertySet > t_OServiceManager_impl;
426 class OServiceManager
427 : public OServiceManagerMutex
428 , public t_OServiceManager_impl
430 public:
431 OServiceManager( Reference< XComponentContext > const & xContext );
432 virtual ~OServiceManager();
434 // XInitialization
435 void SAL_CALL initialize( Sequence< Any > const & args )
436 throw (Exception);
438 // XServiceInfo
439 virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
440 static OUString getImplementationName_Static() throw(::com::sun::star::uno::RuntimeException)
441 { return stoc_bootstrap::smgr_getImplementationName(); }
442 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(::com::sun::star::uno::RuntimeException);
443 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
445 // XMultiComponentFactory
446 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
447 OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext )
448 throw (Exception, RuntimeException);
449 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
450 OUString const & rServiceSpecifier,
451 Sequence< Any > const & rArguments,
452 Reference< XComponentContext > const & xContext )
453 throw (Exception, RuntimeException);
454 // virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
455 // throw (RuntimeException);
457 // XMultiServiceFactory
458 virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(::com::sun::star::uno::RuntimeException);
459 virtual Reference<XInterface > SAL_CALL createInstance(const OUString &) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
460 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString &, const Sequence<Any >& Arguments) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
462 // The same as the getAvailableServiceNames, but only uique names
463 Sequence< OUString > getUniqueAvailableServiceNames(
464 HashSet_OWString & aNameSet );
466 // XElementAccess
467 virtual Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException);
468 virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);
470 // XEnumerationAccess
471 virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw(::com::sun::star::uno::RuntimeException);
473 // XSet
474 virtual sal_Bool SAL_CALL has( const Any & Element ) throw(::com::sun::star::uno::RuntimeException);
475 virtual void SAL_CALL insert( const Any & Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
476 virtual void SAL_CALL remove( const Any & Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
478 // XContentEnumerationAccess
479 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
480 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(::com::sun::star::uno::RuntimeException);
482 // XComponent
483 virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
485 // XPropertySet
486 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
487 throw(::com::sun::star::uno::RuntimeException);
488 void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue)
489 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);
490 Any SAL_CALL getPropertyValue(const OUString& PropertyName)
491 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
492 void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
493 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
494 void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
495 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
496 void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
497 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
498 void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
499 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
501 protected:
502 inline bool is_disposed() const SAL_THROW( (lang::DisposedException) );
503 inline void check_undisposed() const SAL_THROW( (lang::DisposedException) );
504 virtual void SAL_CALL disposing();
506 sal_Bool haveFactoryWithThisImplementation(const OUString& aImplName);
508 virtual Sequence< Reference< XInterface > > queryServiceFactories(
509 const OUString& aServiceName, Reference< XComponentContext > const & xContext );
511 Reference< XComponentContext > m_xContext;
513 Reference< beans::XPropertySetInfo > m_xPropertyInfo;
515 // factories which have been loaded and not inserted( by XSet::insert)
516 // are remembered by this set.
517 HashSet_Ref m_SetLoadedFactories;
518 private:
520 Reference<XEventListener > getFactoryListener();
523 HashMultimap_OWString_Interface m_ServiceMap;
524 HashSet_Ref m_ImplementationMap;
525 HashMap_OWString_Interface m_ImplementationNameMap;
526 Reference<XEventListener > xFactoryListener;
527 bool m_bInDisposing;
531 //______________________________________________________________________________
532 inline bool OServiceManager::is_disposed() const
533 SAL_THROW( (lang::DisposedException) )
535 // ought to be guarded by m_mutex:
536 return (m_bInDisposing || rBHelper.bDisposed);
539 //______________________________________________________________________________
540 inline void OServiceManager::check_undisposed() const
541 SAL_THROW( (lang::DisposedException) )
543 if (is_disposed())
545 throw lang::DisposedException(
546 "service manager instance has already been disposed!",
547 (OWeakObject *)this );
551 //##################################################################################################
552 //##################################################################################################
553 //##################################################################################################
555 typedef WeakComponentImplHelper6<
556 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
557 container::XSet, container::XContentEnumerationAccess,
558 beans::XPropertySet > t_OServiceManagerWrapper_impl;
560 class OServiceManagerWrapper : public OServiceManagerMutex, public t_OServiceManagerWrapper_impl
562 Reference< XComponentContext > m_xContext;
563 Reference< XMultiComponentFactory > m_root;
564 inline Reference< XMultiComponentFactory > getRoot() SAL_THROW( (RuntimeException) )
566 if (! m_root.is())
568 throw lang::DisposedException(
569 "service manager instance has already been disposed!",
570 Reference< XInterface >() );
572 return m_root;
575 protected:
576 virtual void SAL_CALL disposing();
578 public:
579 OServiceManagerWrapper(
580 Reference< XComponentContext > const & xContext )
581 SAL_THROW( (RuntimeException) );
582 virtual ~OServiceManagerWrapper() SAL_THROW(());
584 // XServiceInfo
585 virtual OUString SAL_CALL getImplementationName() throw (RuntimeException)
586 { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getImplementationName(); }
587 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (RuntimeException)
588 { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->supportsService( ServiceName ); }
589 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException)
590 { return Reference< XServiceInfo >(getRoot(), UNO_QUERY_THROW)->getSupportedServiceNames(); }
592 // XMultiComponentFactory
593 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
594 OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext )
595 throw (Exception, RuntimeException)
596 { return getRoot()->createInstanceWithContext( rServiceSpecifier, xContext ); }
597 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
598 OUString const & rServiceSpecifier,
599 Sequence< Any > const & rArguments,
600 Reference< XComponentContext > const & xContext )
601 throw (Exception, RuntimeException)
602 { return getRoot()->createInstanceWithArgumentsAndContext( rServiceSpecifier, rArguments, xContext ); }
603 // virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
604 // throw (RuntimeException);
606 // XMultiServiceFactory
607 virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw (RuntimeException)
608 { return getRoot()->getAvailableServiceNames(); }
609 virtual Reference<XInterface > SAL_CALL createInstance(const OUString & name) throw (Exception)
610 { return getRoot()->createInstanceWithContext( name, m_xContext ); }
611 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString & name, const Sequence<Any >& Arguments) throw (Exception)
612 { return getRoot()->createInstanceWithArgumentsAndContext( name, Arguments, m_xContext ); }
614 // XElementAccess
615 virtual Type SAL_CALL getElementType() throw (RuntimeException)
616 { return Reference< XElementAccess >(getRoot(), UNO_QUERY_THROW)->getElementType(); }
617 virtual sal_Bool SAL_CALL hasElements() throw (RuntimeException)
618 { return Reference< XElementAccess >(getRoot(), UNO_QUERY_THROW)->hasElements(); }
620 // XEnumerationAccess
621 virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw (RuntimeException)
622 { return Reference< XEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createEnumeration(); }
624 // XSet
625 virtual sal_Bool SAL_CALL has( const Any & Element ) throw (RuntimeException)
626 { return Reference< XSet >(getRoot(), UNO_QUERY_THROW)->has( Element ); }
627 virtual void SAL_CALL insert( const Any & Element ) throw (lang::IllegalArgumentException, container::ElementExistException, RuntimeException)
628 { Reference< XSet >(getRoot(), UNO_QUERY_THROW)->insert( Element ); }
629 virtual void SAL_CALL remove( const Any & Element ) throw (lang::IllegalArgumentException, container::NoSuchElementException, RuntimeException)
630 { Reference< XSet >(getRoot(), UNO_QUERY_THROW)->remove( Element ); }
632 // XContentEnumerationAccess
633 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
634 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw (RuntimeException)
635 { return Reference< XContentEnumerationAccess >(getRoot(), UNO_QUERY_THROW)->createContentEnumeration( aServiceName ); }
637 // XPropertySet
638 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() throw (RuntimeException)
639 { return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertySetInfo(); }
641 void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue)
642 throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException);
643 Any SAL_CALL getPropertyValue(const OUString& PropertyName)
644 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException);
646 void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
647 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
648 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->addPropertyChangeListener( PropertyName, aListener ); }
649 void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
650 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
651 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->removePropertyChangeListener( PropertyName, aListener ); }
652 void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
653 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
654 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->addVetoableChangeListener( PropertyName, aListener ); }
655 void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
656 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
657 { Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->removeVetoableChangeListener( PropertyName, aListener ); }
659 //__________________________________________________________________________________________________
660 void SAL_CALL OServiceManagerWrapper::setPropertyValue(
661 const OUString& PropertyName, const Any& aValue )
662 throw (beans::UnknownPropertyException, beans::PropertyVetoException,
663 lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException)
665 if ( PropertyName == "DefaultContext" )
667 Reference< XComponentContext > xContext;
668 if (aValue >>= xContext)
670 MutexGuard aGuard( m_mutex );
671 m_xContext = xContext;
673 else
675 throw IllegalArgumentException(
676 OUString("no XComponentContext given!"),
677 (OWeakObject *)this, 1 );
680 else
682 Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->setPropertyValue( PropertyName, aValue );
685 //__________________________________________________________________________________________________
686 Any SAL_CALL OServiceManagerWrapper::getPropertyValue(
687 const OUString& PropertyName )
688 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
690 if ( PropertyName == "DefaultContext" )
692 MutexGuard aGuard( m_mutex );
693 if( m_xContext.is() )
694 return makeAny( m_xContext );
695 else
696 return Any();
698 else
700 return Reference< XPropertySet >(getRoot(), UNO_QUERY_THROW)->getPropertyValue( PropertyName );
703 //__________________________________________________________________________________________________
704 void OServiceManagerWrapper::disposing()
706 m_xContext.clear();
708 // no m_root->dispose(), because every context disposes its service manager...
709 m_root.clear();
711 //__________________________________________________________________________________________________
712 OServiceManagerWrapper::~OServiceManagerWrapper() SAL_THROW(()) {}
713 //__________________________________________________________________________________________________
714 OServiceManagerWrapper::OServiceManagerWrapper(
715 Reference< XComponentContext > const & xContext )
716 SAL_THROW( (RuntimeException) )
717 : t_OServiceManagerWrapper_impl( m_mutex )
718 , m_xContext( xContext )
719 , m_root( xContext->getServiceManager() )
721 if (! m_root.is())
723 throw RuntimeException(
724 OUString("no service manager to wrap"),
725 Reference< XInterface >() );
729 //##################################################################################################
730 //##################################################################################################
731 //##################################################################################################
734 * Create a ServiceManager
736 OServiceManager::OServiceManager( Reference< XComponentContext > const & xContext )
737 : t_OServiceManager_impl( m_mutex )
738 , m_xContext( xContext )
739 , m_bInDisposing( false )
743 * Destroy the ServiceManager
745 OServiceManager::~OServiceManager() {}
747 // XComponent
748 void OServiceManager::dispose()
749 throw(::com::sun::star::uno::RuntimeException)
751 if (rBHelper.bDisposed || rBHelper.bInDispose)
752 return;
753 t_OServiceManager_impl::dispose();
756 void OServiceManager::disposing()
758 // dispose all factories
759 HashSet_Ref aImpls;
761 MutexGuard aGuard( m_mutex );
762 m_bInDisposing = true;
763 aImpls = m_ImplementationMap;
765 HashSet_Ref::iterator aIt = aImpls.begin();
766 while( aIt != aImpls.end() )
770 Reference<XComponent > xComp( Reference<XComponent >::query( *aIt++ ) );
771 if( xComp.is() )
772 xComp->dispose();
774 catch (const RuntimeException & exc)
776 #if OSL_DEBUG_LEVEL > 1
777 OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
778 OSL_TRACE( "### RuntimeException occurred upon disposing factory: %s", str.getStr() );
779 #else
780 (void) exc; // unused
781 #endif
785 // dispose
786 HashSet_Ref aImplMap;
788 MutexGuard aGuard( m_mutex );
789 // erase all members
790 m_ServiceMap = HashMultimap_OWString_Interface();
791 aImplMap = m_ImplementationMap;
792 m_ImplementationMap = HashSet_Ref();
793 m_ImplementationNameMap = HashMap_OWString_Interface();
794 m_SetLoadedFactories= HashSet_Ref();
797 m_xContext.clear();
799 // not only the Event should hold the object
800 OSL_ASSERT( m_refCount != 1 );
803 // XPropertySet
804 Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo()
805 throw(::com::sun::star::uno::RuntimeException)
807 check_undisposed();
808 if (! m_xPropertyInfo.is())
810 Sequence< beans::Property > seq( 1 );
811 seq[ 0 ] = beans::Property(
812 "DefaultContext", -1, ::getCppuType( &m_xContext ), 0 );
813 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
815 MutexGuard aGuard( m_mutex );
816 if (! m_xPropertyInfo.is())
818 m_xPropertyInfo = xInfo;
821 return m_xPropertyInfo;
824 void OServiceManager::setPropertyValue(
825 const OUString& PropertyName, const Any& aValue )
826 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)
828 check_undisposed();
829 if ( PropertyName == "DefaultContext" )
831 Reference< XComponentContext > xContext;
832 if (aValue >>= xContext)
834 MutexGuard aGuard( m_mutex );
835 m_xContext = xContext;
837 else
839 throw IllegalArgumentException(
840 OUString("no XComponentContext given!"),
841 (OWeakObject *)this, 1 );
844 else
846 throw UnknownPropertyException(
847 OUString("unknown property ") + PropertyName,
848 (OWeakObject *)this );
852 Any OServiceManager::getPropertyValue(const OUString& PropertyName)
853 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
855 check_undisposed();
856 if ( PropertyName == "DefaultContext" )
858 MutexGuard aGuard( m_mutex );
859 if( m_xContext.is() )
860 return makeAny( m_xContext );
861 else
862 return Any();
864 else
866 UnknownPropertyException except;
867 except.Message = OUString( "ServiceManager : unknown property " );
868 except.Message += PropertyName;
869 throw except;
873 void OServiceManager::addPropertyChangeListener(
874 const OUString&, const Reference<XPropertyChangeListener >&)
875 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
877 check_undisposed();
878 throw UnknownPropertyException();
881 void OServiceManager::removePropertyChangeListener(
882 const OUString&, const Reference<XPropertyChangeListener >&)
883 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
885 check_undisposed();
886 throw UnknownPropertyException();
889 void OServiceManager::addVetoableChangeListener(
890 const OUString&, const Reference<XVetoableChangeListener >&)
891 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
893 check_undisposed();
894 throw UnknownPropertyException();
897 void OServiceManager::removeVetoableChangeListener(
898 const OUString&, const Reference<XVetoableChangeListener >&)
899 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
901 check_undisposed();
902 throw UnknownPropertyException();
905 // OServiceManager
906 Reference<XEventListener > OServiceManager::getFactoryListener()
908 check_undisposed();
909 MutexGuard aGuard( m_mutex );
910 if( !xFactoryListener.is() )
911 xFactoryListener = new OServiceManager_Listener( this );
912 return xFactoryListener;
915 // XMultiServiceFactory, XContentEnumeration
916 Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames(
917 HashSet_OWString & aNameSet )
919 check_undisposed();
920 MutexGuard aGuard( m_mutex );
921 HashMultimap_OWString_Interface::iterator aSIt = m_ServiceMap.begin();
922 while( aSIt != m_ServiceMap.end() )
923 aNameSet.insert( (*aSIt++).first );
925 /* do not return the implementation names
926 HashMap_OWString_Interface m_ImplementationNameMap;
927 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.begin();
928 while( aIt != m_ImplementationNameMap.end() )
929 aNameSet.insert( (*aIt++).first );
932 Sequence< OUString > aNames( aNameSet.size() );
933 OUString * pArray = aNames.getArray();
934 sal_Int32 i = 0;
935 HashSet_OWString::iterator next = aNameSet.begin();
936 while( next != aNameSet.end() )
937 pArray[i++] = (*next++);
939 return aNames;
942 // XMultiComponentFactory
943 Reference< XInterface > OServiceManager::createInstanceWithContext(
944 OUString const & rServiceSpecifier,
945 Reference< XComponentContext > const & xContext )
946 throw (Exception, RuntimeException)
948 check_undisposed();
949 #if OSL_DEBUG_LEVEL > 0
950 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
951 OSL_ASSERT( xProps.is() );
952 if (xProps.is())
954 Reference< XComponentContext > xDefContext;
955 xProps->getPropertyValue(
956 OUString("DefaultContext") ) >>= xDefContext;
957 OSL_ENSURE(
958 xContext == xDefContext,
959 "### default context of service manager singleton differs from context holding it!" );
961 #endif
963 Sequence< Reference< XInterface > > factories(
964 queryServiceFactories( rServiceSpecifier, xContext ) );
965 Reference< XInterface > const * p = factories.getConstArray();
966 for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos )
970 Reference< XInterface > const & xFactory = p[ nPos ];
971 if (xFactory.is())
973 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
974 if (xFac.is())
976 return xFac->createInstanceWithContext( xContext );
978 else
980 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
981 if (xFac2.is())
983 #if OSL_DEBUG_LEVEL > 1
984 OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) );
985 OSL_TRACE( "### ignoring given context raising service %s !!!", aStr.getStr() );
986 #endif
987 return xFac2->createInstance();
992 catch (const lang::DisposedException & exc)
994 #if OSL_DEBUG_LEVEL > 1
995 OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
996 OSL_TRACE( "### DisposedException occurred: %s", str.getStr() );
997 #else
998 (void) exc; // unused
999 #endif
1003 return Reference< XInterface >();
1005 // XMultiComponentFactory
1006 Reference< XInterface > OServiceManager::createInstanceWithArgumentsAndContext(
1007 OUString const & rServiceSpecifier,
1008 Sequence< Any > const & rArguments,
1009 Reference< XComponentContext > const & xContext )
1010 throw (Exception, RuntimeException)
1012 check_undisposed();
1013 #if OSL_DEBUG_LEVEL > 0
1014 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
1015 OSL_ASSERT( xProps.is() );
1016 if (xProps.is())
1018 Reference< XComponentContext > xDefContext;
1019 xProps->getPropertyValue(
1020 OUString("DefaultContext") ) >>= xDefContext;
1021 OSL_ENSURE(
1022 xContext == xDefContext,
1023 "### default context of service manager singleton differs from context holding it!" );
1025 #endif
1027 Sequence< Reference< XInterface > > factories(
1028 queryServiceFactories( rServiceSpecifier, xContext ) );
1029 Reference< XInterface > const * p = factories.getConstArray();
1030 for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos )
1034 Reference< XInterface > const & xFactory = p[ nPos ];
1035 if (xFactory.is())
1037 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
1038 if (xFac.is())
1040 return xFac->createInstanceWithArgumentsAndContext( rArguments, xContext );
1042 else
1044 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
1045 if (xFac2.is())
1047 #if OSL_DEBUG_LEVEL > 1
1048 OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) );
1049 OSL_TRACE( "### ignoring given context raising service %s !!!", aStr.getStr() );
1050 #endif
1051 return xFac2->createInstanceWithArguments( rArguments );
1056 catch (const lang::DisposedException & exc)
1058 #if OSL_DEBUG_LEVEL > 1
1059 OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
1060 OSL_TRACE( "### DisposedException occurred: %s", str.getStr() );
1061 #else
1062 (void) exc; // unused
1063 #endif
1067 return Reference< XInterface >();
1070 // XMultiServiceFactory, XMultiComponentFactory, XContentEnumeration
1071 Sequence< OUString > OServiceManager::getAvailableServiceNames()
1072 throw(::com::sun::star::uno::RuntimeException)
1074 check_undisposed();
1075 // all names
1076 HashSet_OWString aNameSet;
1077 return getUniqueAvailableServiceNames( aNameSet );
1080 // XMultibleServiceFactory
1081 Reference<XInterface > OServiceManager::createInstance(
1082 const OUString& rServiceSpecifier )
1083 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1085 return createInstanceWithContext(
1086 rServiceSpecifier, m_xContext );
1089 // XMultibleServiceFactory
1090 Reference<XInterface > OServiceManager::createInstanceWithArguments(
1091 const OUString& rServiceSpecifier,
1092 const Sequence<Any >& rArguments )
1093 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1095 return createInstanceWithArgumentsAndContext(
1096 rServiceSpecifier, rArguments, m_xContext );
1099 // XInitialization
1100 void OServiceManager::initialize( Sequence< Any > const & )
1101 throw (Exception)
1103 check_undisposed();
1104 OSL_FAIL( "not impl!" );
1107 // XServiceInfo
1108 OUString OServiceManager::getImplementationName()
1109 throw(::com::sun::star::uno::RuntimeException)
1111 check_undisposed();
1112 return getImplementationName_Static();
1115 // XServiceInfo
1116 sal_Bool OServiceManager::supportsService(const OUString& ServiceName)
1117 throw(::com::sun::star::uno::RuntimeException)
1119 check_undisposed();
1120 Sequence< OUString > aSNL = getSupportedServiceNames();
1121 const OUString * pArray = aSNL.getConstArray();
1122 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1123 if( pArray[i] == ServiceName )
1124 return sal_True;
1125 return sal_False;
1128 // XServiceInfo
1129 Sequence< OUString > OServiceManager::getSupportedServiceNames()
1130 throw(::com::sun::star::uno::RuntimeException)
1132 check_undisposed();
1133 return stoc_bootstrap::smgr_getSupportedServiceNames();
1137 Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories(
1138 const OUString& aServiceName, Reference< XComponentContext > const & )
1140 Sequence< Reference< XInterface > > ret;
1142 MutexGuard aGuard( m_mutex );
1143 ::std::pair<
1144 HashMultimap_OWString_Interface::iterator,
1145 HashMultimap_OWString_Interface::iterator> p(
1146 m_ServiceMap.equal_range( aServiceName ) );
1148 if (p.first == p.second) // no factories
1150 // no service found, look for an implementation
1151 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.find( aServiceName );
1152 if( aIt != m_ImplementationNameMap.end() )
1154 Reference< XInterface > const & x = aIt->second;
1155 // an implementation found
1156 ret = Sequence< Reference< XInterface > >( &x, 1 );
1159 else
1161 ::std::vector< Reference< XInterface > > vec;
1162 vec.reserve( 4 );
1163 while (p.first != p.second)
1165 vec.push_back( p.first->second );
1166 ++p.first;
1168 ret = Sequence< Reference< XInterface > >(
1169 vec.empty() ? 0 : &vec[ 0 ], vec.size() );
1172 return ret;
1175 // XContentEnumerationAccess
1176 Reference<XEnumeration > OServiceManager::createContentEnumeration(
1177 const OUString& aServiceName )
1178 throw(::com::sun::star::uno::RuntimeException)
1180 check_undisposed();
1181 Sequence< Reference< XInterface > > factories(
1182 OServiceManager::queryServiceFactories( aServiceName, m_xContext ) );
1183 if (factories.getLength())
1184 return new ServiceEnumeration_Impl( factories );
1185 else
1186 return Reference< XEnumeration >();
1189 // XEnumeration
1190 Reference<XEnumeration > OServiceManager::createEnumeration() throw(::com::sun::star::uno::RuntimeException)
1192 check_undisposed();
1193 MutexGuard aGuard( m_mutex );
1194 return new ImplementationEnumeration_Impl( m_ImplementationMap );
1197 // XElementAccess
1198 Type OServiceManager::getElementType()
1199 throw(::com::sun::star::uno::RuntimeException)
1201 check_undisposed();
1202 return ::getCppuType( (const Reference< XInterface > *)0 );
1205 // XElementAccess
1206 sal_Bool OServiceManager::hasElements()
1207 throw(::com::sun::star::uno::RuntimeException)
1209 check_undisposed();
1210 MutexGuard aGuard( m_mutex );
1211 return !m_ImplementationMap.empty();
1214 // XSet
1215 sal_Bool OServiceManager::has( const Any & Element )
1216 throw(::com::sun::star::uno::RuntimeException)
1218 check_undisposed();
1219 if( Element.getValueTypeClass() == TypeClass_INTERFACE )
1221 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
1222 MutexGuard aGuard( m_mutex );
1223 return m_ImplementationMap.find( xEle ) !=
1224 m_ImplementationMap.end();
1226 else if (Element.getValueTypeClass() == TypeClass_STRING)
1228 OUString const & implName =
1229 *reinterpret_cast< OUString const * >(Element.getValue());
1230 MutexGuard aGuard( m_mutex );
1231 return m_ImplementationNameMap.find( implName ) !=
1232 m_ImplementationNameMap.end();
1234 return sal_False;
1237 // XSet
1238 void OServiceManager::insert( const Any & Element )
1239 throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException)
1241 check_undisposed();
1242 if( Element.getValueTypeClass() != TypeClass_INTERFACE )
1244 throw IllegalArgumentException(
1245 OUString("no interface given!"),
1246 Reference< XInterface >(), 0 );
1248 Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
1251 MutexGuard aGuard( m_mutex );
1252 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1253 if( aIt != m_ImplementationMap.end() )
1255 throw ElementExistException(
1256 OUString("element already exists!"),
1257 Reference< XInterface >() );
1260 // put into the implementation hashmap
1261 m_ImplementationMap.insert( xEle );
1263 // put into the implementation name hashmap
1264 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1265 if( xInfo.is() )
1267 OUString aImplName = xInfo->getImplementationName();
1268 if( !aImplName.isEmpty() )
1269 m_ImplementationNameMap[ aImplName ] = xEle;
1271 //put into the service map
1272 Sequence< OUString > aServiceNames = xInfo->getSupportedServiceNames();
1273 const OUString * pArray = aServiceNames.getConstArray();
1274 for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ )
1276 m_ServiceMap.insert( HashMultimap_OWString_Interface::value_type(
1277 pArray[i], *(Reference<XInterface > *)Element.getValue() ) );
1281 // add the disposing listener to the factory
1282 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1283 if( xComp.is() )
1284 xComp->addEventListener( getFactoryListener() );
1287 // helper function
1288 sal_Bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName)
1290 return ( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end());
1293 // XSet
1294 void OServiceManager::remove( const Any & Element )
1295 throw(::com::sun::star::lang::IllegalArgumentException,
1296 ::com::sun::star::container::NoSuchElementException,
1297 ::com::sun::star::uno::RuntimeException)
1299 if (is_disposed())
1300 return;
1302 Reference<XInterface > xEle;
1303 if (Element.getValueTypeClass() == TypeClass_INTERFACE)
1305 xEle.set( Element, UNO_QUERY_THROW );
1307 else if (Element.getValueTypeClass() == TypeClass_STRING)
1309 OUString const & implName =
1310 *reinterpret_cast< OUString const * >(Element.getValue());
1311 MutexGuard aGuard( m_mutex );
1312 HashMap_OWString_Interface::const_iterator const iFind(
1313 m_ImplementationNameMap.find( implName ) );
1314 if (iFind == m_ImplementationNameMap.end())
1316 throw NoSuchElementException(
1317 OUString("element is not in: ")
1318 + implName, static_cast< OWeakObject * >(this) );
1320 xEle = iFind->second;
1322 else
1324 throw IllegalArgumentException(
1325 OUString(
1326 "neither interface nor string given!"),
1327 Reference< XInterface >(), 0 );
1330 // remove the disposing listener from the factory
1331 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
1332 if( xComp.is() )
1333 xComp->removeEventListener( getFactoryListener() );
1335 MutexGuard aGuard( m_mutex );
1336 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
1337 if( aIt == m_ImplementationMap.end() )
1339 throw NoSuchElementException(
1340 OUString("element is not in!"),
1341 static_cast< OWeakObject * >(this) );
1343 //First remove all factories which have been loaded by ORegistryServiceManager.
1344 m_SetLoadedFactories.erase( *aIt);
1345 //Remove from the implementation map. It contains all factories of m_SetLoadedFactories
1346 //which have been added directly through XSet, that is not via ORegistryServiceManager
1347 m_ImplementationMap.erase( aIt );
1349 // remove from the implementation name hashmap
1350 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
1351 if( xInfo.is() )
1353 OUString aImplName = xInfo->getImplementationName();
1354 if( !aImplName.isEmpty() )
1355 m_ImplementationNameMap.erase( aImplName );
1358 //remove from the service map
1359 Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) );
1360 if( xSF.is() )
1362 Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames();
1363 const OUString * pArray = aServiceNames.getConstArray();
1364 for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ )
1366 pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> p =
1367 m_ServiceMap.equal_range( pArray[i] );
1369 while( p.first != p.second )
1371 if( xEle == (*p.first).second )
1373 m_ServiceMap.erase( p.first );
1374 break;
1376 ++p.first;
1382 /*****************************************************************************
1383 class ORegistryServiceManager
1384 *****************************************************************************/
1385 class ORegistryServiceManager : public OServiceManager
1387 public:
1388 ORegistryServiceManager( Reference< XComponentContext > const & xContext );
1389 virtual ~ORegistryServiceManager();
1391 // XInitialization
1392 void SAL_CALL initialize(const Sequence< Any >& Arguments)
1393 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
1395 // XServiceInfo
1396 OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException)
1397 { return stoc_bootstrap::regsmgr_getImplementationName(); }
1399 Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
1401 // XMultiServiceFactory
1402 Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(::com::sun::star::uno::RuntimeException);
1404 // XContentEnumerationAccess
1405 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
1406 Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(::com::sun::star::uno::RuntimeException);
1408 // XComponent
1409 void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
1411 // OServiceManager
1412 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
1413 throw(::com::sun::star::uno::RuntimeException);
1414 Any SAL_CALL getPropertyValue(const OUString& PropertyName)
1415 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
1417 protected:
1418 //OServiceManager
1419 Sequence< Reference< XInterface > > queryServiceFactories(
1420 const OUString& aServiceName, Reference< XComponentContext > const & xContext );
1421 private:
1422 Reference<XRegistryKey > getRootKey();
1423 Reference<XInterface > loadWithImplementationName(
1424 const OUString & rImplName, Reference< XComponentContext > const & xContext );
1425 Sequence<OUString> getFromServiceName(const OUString& serviceName);
1426 Reference<XInterface > loadWithServiceName(
1427 const OUString & rImplName, Reference< XComponentContext > const & xContext );
1428 void fillAllNamesFromRegistry( HashSet_OWString & );
1430 sal_Bool m_searchedRegistry;
1431 Reference<XSimpleRegistry > m_xRegistry; // readonly property Registry
1432 Reference<XRegistryKey > m_xRootKey;
1434 #if OSL_DEBUG_LEVEL > 0
1435 bool m_init;
1436 #endif
1440 * Create a ServiceManager
1442 ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext > const & xContext )
1443 : OServiceManager( xContext )
1444 , m_searchedRegistry(sal_False)
1445 #if OSL_DEBUG_LEVEL > 0
1446 , m_init( false )
1447 #endif
1452 * Destroy the ServiceManager
1454 ORegistryServiceManager::~ORegistryServiceManager()
1458 // XComponent
1459 void ORegistryServiceManager::dispose()
1460 throw(::com::sun::star::uno::RuntimeException)
1462 if (rBHelper.bDisposed || rBHelper.bInDispose)
1463 return;
1464 OServiceManager::dispose();
1465 // dispose
1466 MutexGuard aGuard( m_mutex );
1467 // erase all members
1468 m_xRegistry = Reference<XSimpleRegistry >();
1469 m_xRootKey = Reference<XRegistryKey >();
1473 * Return the root key of the registry. The Default registry service is ordered
1474 * if no registry is set.
1476 //Reference<XServiceProvider > create_DefaultRegistry_ServiceProvider();
1478 Reference<XRegistryKey > ORegistryServiceManager::getRootKey()
1480 if( !m_xRootKey.is() )
1482 MutexGuard aGuard( m_mutex );
1483 // DefaultRegistry suchen !!!!
1484 if( !m_xRegistry.is() && !m_searchedRegistry )
1486 // merken, es wird nur einmal gesucht
1487 m_searchedRegistry = sal_True;
1489 m_xRegistry.set(
1490 createInstanceWithContext(
1491 OUString("com.sun.star.registry.DefaultRegistry"),
1492 m_xContext ),
1493 UNO_QUERY );
1495 if( m_xRegistry.is() && !m_xRootKey.is() )
1496 m_xRootKey = m_xRegistry->getRootKey();
1499 return m_xRootKey;
1503 * Create a service provider from the registry with an implementation name
1505 Reference<XInterface > ORegistryServiceManager::loadWithImplementationName(
1506 const OUString& name, Reference< XComponentContext > const & xContext )
1508 Reference<XInterface > ret;
1510 Reference<XRegistryKey > xRootKey = getRootKey();
1511 if( !xRootKey.is() )
1512 return ret;
1516 OUString implementationName = OUString("/IMPLEMENTATIONS/") + name;
1517 Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName);
1519 if( xImpKey.is() )
1521 Reference< lang::XMultiServiceFactory > xMgr;
1522 if (xContext.is())
1523 xMgr.set( xContext->getServiceManager(), UNO_QUERY_THROW );
1524 else
1525 xMgr.set( this );
1526 ret = createSingleRegistryFactory( xMgr, name, xImpKey );
1527 insert( makeAny( ret ) );
1528 // Remember this factory as loaded in contrast to inserted ( XSet::insert)
1529 // factories. Those loaded factories in this set are candidates for being
1530 // released on an unloading notification.
1531 m_SetLoadedFactories.insert( ret);
1534 catch (InvalidRegistryException &)
1538 return ret;
1542 * Return all implementation out of the registry.
1544 Sequence<OUString> ORegistryServiceManager::getFromServiceName(
1545 const OUString& serviceName )
1547 OUStringBuffer buf;
1548 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/SERVICES/" ) );
1549 buf.append( serviceName );
1550 return retrieveAsciiValueList( m_xRegistry, buf.makeStringAndClear() );
1554 * Create a service provider from the registry
1556 Reference<XInterface > ORegistryServiceManager::loadWithServiceName(
1557 const OUString& serviceName, Reference< XComponentContext > const & xContext )
1559 Sequence<OUString> implEntries = getFromServiceName( serviceName );
1560 for (sal_Int32 i = 0; i < implEntries.getLength(); i++)
1562 Reference< XInterface > x(
1563 loadWithImplementationName( implEntries.getConstArray()[i], xContext ) );
1564 if (x.is())
1565 return x;
1568 return Reference<XInterface >();
1572 * Return a sequence of all service names from the registry.
1574 void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet )
1576 Reference<XRegistryKey > xRootKey = getRootKey();
1577 if( !xRootKey.is() )
1578 return;
1582 Reference<XRegistryKey > xServicesKey = xRootKey->openKey(
1583 OUString("SERVICES") );
1584 // root + /Services + /
1585 if( xServicesKey.is() )
1587 sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1;
1588 Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys();
1589 for( sal_Int32 i = 0; i < aKeys.getLength(); i++ )
1590 rSet.insert( aKeys.getConstArray()[i]->getKeyName().copy( nPrefix ) );
1593 catch (InvalidRegistryException &)
1598 // XInitialization
1599 void ORegistryServiceManager::initialize(const Sequence< Any >& Arguments)
1600 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1602 check_undisposed();
1603 MutexGuard aGuard( m_mutex );
1604 if (Arguments.getLength() > 0)
1606 m_xRootKey.clear();
1607 Arguments[ 0 ] >>= m_xRegistry;
1609 #if OSL_DEBUG_LEVEL > 0
1610 // to find all bootstrapping processes to be fixed...
1611 OSL_ENSURE( !m_init, "### second init of service manager instance!" );
1612 m_init = true;
1613 #endif
1616 // XMultiServiceFactory, XContentEnumeration
1617 Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames()
1618 throw(::com::sun::star::uno::RuntimeException)
1620 check_undisposed();
1621 MutexGuard aGuard( m_mutex );
1622 // all names
1623 HashSet_OWString aNameSet;
1625 // all names from the registry
1626 fillAllNamesFromRegistry( aNameSet );
1628 return OServiceManager::getUniqueAvailableServiceNames( aNameSet );
1631 // XServiceInfo
1632 Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames()
1633 throw(::com::sun::star::uno::RuntimeException)
1635 check_undisposed();
1636 return stoc_bootstrap::regsmgr_getSupportedServiceNames();
1640 // OServiceManager
1641 Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories(
1642 const OUString& aServiceName, Reference< XComponentContext > const & xContext )
1644 Sequence< Reference< XInterface > > ret(
1645 OServiceManager::queryServiceFactories( aServiceName, xContext ) );
1646 if (ret.getLength())
1648 return ret;
1650 else
1652 MutexGuard aGuard( m_mutex );
1653 Reference< XInterface > x( loadWithServiceName( aServiceName, xContext ) );
1654 if (! x.is())
1655 x = loadWithImplementationName( aServiceName, xContext );
1656 return Sequence< Reference< XInterface > >( &x, 1 );
1660 // XContentEnumerationAccess
1661 Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
1662 const OUString& aServiceName )
1663 throw(::com::sun::star::uno::RuntimeException)
1665 check_undisposed();
1666 MutexGuard aGuard( ((ORegistryServiceManager *)this)->m_mutex );
1667 // get all implementation names registered under this service name from the registry
1668 Sequence<OUString> aImpls = ((ORegistryServiceManager *)this)->getFromServiceName( aServiceName );
1669 // load and insert all factories specified by the registry
1670 sal_Int32 i;
1671 OUString aImplName;
1672 for( i = 0; i < aImpls.getLength(); i++ )
1674 aImplName = aImpls.getConstArray()[i];
1675 if ( !haveFactoryWithThisImplementation(aImplName) )
1677 loadWithImplementationName( aImplName, m_xContext );
1680 // call the superclass to enumerate all contents
1681 return OServiceManager::createContentEnumeration( aServiceName );
1684 // OServiceManager
1685 Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo()
1686 throw(::com::sun::star::uno::RuntimeException)
1688 check_undisposed();
1689 if (! m_xPropertyInfo.is())
1691 Sequence< beans::Property > seq( 2 );
1692 seq[ 0 ] = beans::Property(
1693 "DefaultContext", -1, ::getCppuType( &m_xContext ), 0 );
1694 seq[ 1 ] = beans::Property(
1695 "Registry", -1, ::getCppuType( &m_xRegistry ),
1696 beans::PropertyAttribute::READONLY );
1697 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
1699 MutexGuard aGuard( m_mutex );
1700 if (! m_xPropertyInfo.is())
1702 m_xPropertyInfo = xInfo;
1705 return m_xPropertyInfo;
1708 Any ORegistryServiceManager::getPropertyValue(const OUString& PropertyName)
1709 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1711 check_undisposed();
1712 if ( PropertyName == "Registry" )
1714 MutexGuard aGuard( m_mutex );
1715 if( m_xRegistry.is() )
1716 return makeAny( m_xRegistry );
1717 else
1718 return Any();
1720 return OServiceManager::getPropertyValue( PropertyName );
1723 } // namespace
1725 namespace stoc_bootstrap
1728 * Create the ServiceManager
1730 Reference<XInterface > SAL_CALL OServiceManager_CreateInstance(
1731 const Reference< XComponentContext > & xContext )
1733 return Reference<XInterface >(
1734 static_cast< XInterface * >(
1735 static_cast< OWeakObject * >( new stoc_smgr::OServiceManager( xContext ) ) ) );
1739 * Create the ServiceManager
1741 Reference<XInterface > SAL_CALL ORegistryServiceManager_CreateInstance(
1742 const Reference< XComponentContext > & xContext )
1743 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1745 return Reference<XInterface >(
1746 static_cast< XInterface * >(
1747 static_cast< OWeakObject * >( new stoc_smgr::ORegistryServiceManager( xContext ) ) ) );
1750 Reference<XInterface > SAL_CALL OServiceManagerWrapper_CreateInstance(
1751 const Reference< XComponentContext > & xContext )
1752 throw (Exception)
1754 return (OWeakObject *)new stoc_smgr::OServiceManagerWrapper( xContext );
1758 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */