update credits
[LibreOffice.git] / cppuhelper / source / factory.cxx
blob160a17ace57675e15581de7d7fd54dd99fea5be0
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/diagnose.h>
21 #include <osl/mutex.hxx>
22 #include <cppuhelper/weak.hxx>
23 #include <cppuhelper/bootstrap.hxx>
24 #include <cppuhelper/component.hxx>
25 #include <cppuhelper/factory.hxx>
26 #include <cppuhelper/implbase3.hxx>
27 #include <cppuhelper/shlib.hxx>
28 #include <cppuhelper/supportsservice.hxx>
29 #include <cppuhelper/typeprovider.hxx>
30 #include <rtl/instance.hxx>
31 #include <rtl/unload.h>
33 #include "cppuhelper/propshlp.hxx"
35 #include <com/sun/star/lang/XServiceInfo.hpp>
36 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
37 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
38 #include <com/sun/star/lang/XInitialization.hpp>
39 #include <com/sun/star/loader/XImplementationLoader.hpp>
40 #include <com/sun/star/lang/XComponent.hpp>
41 #include <com/sun/star/lang/IllegalArgumentException.hpp>
42 #include <com/sun/star/uno/XUnloadingPreference.hpp>
43 #include "com/sun/star/beans/PropertyAttribute.hpp"
45 #include <memory>
48 using namespace osl;
49 using namespace com::sun::star;
50 using namespace com::sun::star::uno;
51 using namespace com::sun::star::lang;
52 using namespace com::sun::star::loader;
53 using namespace com::sun::star::registry;
55 using ::rtl::OUString;
57 namespace cppu
60 class OSingleFactoryHelper
61 : public XServiceInfo
62 , public XSingleServiceFactory
63 , public lang::XSingleComponentFactory
64 , public XUnloadingPreference
66 public:
67 OSingleFactoryHelper(
68 const Reference<XMultiServiceFactory > & rServiceManager,
69 const OUString & rImplementationName_,
70 ComponentInstantiation pCreateFunction_,
71 ComponentFactoryFunc fptr,
72 const Sequence< OUString > * pServiceNames_ )
73 SAL_THROW(())
74 : xSMgr( rServiceManager )
75 , pCreateFunction( pCreateFunction_ )
76 , m_fptr( fptr )
77 , aImplementationName( rImplementationName_ )
79 if( pServiceNames_ )
80 aServiceNames = *pServiceNames_;
83 // old function, only for backward compatibility
84 OSingleFactoryHelper(
85 const Reference<XMultiServiceFactory > & rServiceManager,
86 const OUString & rImplementationName_ )
87 SAL_THROW(())
88 : xSMgr( rServiceManager )
89 , pCreateFunction( NULL )
90 , m_fptr( 0 )
91 , aImplementationName( rImplementationName_ )
94 virtual ~OSingleFactoryHelper();
96 // XInterface
97 Any SAL_CALL queryInterface( const Type & rType )
98 throw(::com::sun::star::uno::RuntimeException);
100 // XSingleServiceFactory
101 Reference<XInterface > SAL_CALL createInstance()
102 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
103 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
104 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
105 // XSingleComponentFactory
106 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
107 Reference< XComponentContext > const & xContext )
108 throw (Exception, RuntimeException);
109 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
110 Sequence< Any > const & rArguments,
111 Reference< XComponentContext > const & xContext )
112 throw (Exception, RuntimeException);
114 // XServiceInfo
115 OUString SAL_CALL getImplementationName()
116 throw(::com::sun::star::uno::RuntimeException);
117 sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
118 throw(::com::sun::star::uno::RuntimeException);
119 Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
120 throw(::com::sun::star::uno::RuntimeException);
122 protected:
124 * Create an instance specified by the factory. The one instance logic is implemented
125 * in the createInstance and createInstanceWithArguments methods.
126 * @return the newly created instance. Do not return a previous (one instance) instance.
128 virtual Reference<XInterface > createInstanceEveryTime(
129 Reference< XComponentContext > const & xContext )
130 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
132 Reference<XMultiServiceFactory > xSMgr;
133 ComponentInstantiation pCreateFunction;
134 ComponentFactoryFunc m_fptr;
135 Sequence< OUString > aServiceNames;
136 OUString aImplementationName;
138 OSingleFactoryHelper::~OSingleFactoryHelper()
143 //-----------------------------------------------------------------------------
144 Any OSingleFactoryHelper::queryInterface( const Type & rType )
145 throw(::com::sun::star::uno::RuntimeException)
147 return ::cppu::queryInterface(
148 rType,
149 static_cast< XSingleComponentFactory * >( this ),
150 static_cast< XSingleServiceFactory * >( this ),
151 static_cast< XServiceInfo * >( this ) ,
152 static_cast< XUnloadingPreference * >( this ));
155 // OSingleFactoryHelper
156 Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime(
157 Reference< XComponentContext > const & xContext )
158 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
160 if (m_fptr)
162 return (*m_fptr)( xContext );
164 else if( pCreateFunction )
166 if (xContext.is())
168 Reference< lang::XMultiServiceFactory > xContextMgr(
169 xContext->getServiceManager(), UNO_QUERY );
170 if (xContextMgr.is())
171 return (*pCreateFunction)( xContextMgr );
173 return (*pCreateFunction)( xSMgr );
175 else
177 return Reference< XInterface >();
181 // XSingleServiceFactory
182 Reference<XInterface > OSingleFactoryHelper::createInstance()
183 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
185 return createInstanceWithContext( Reference< XComponentContext >() );
188 // XSingleServiceFactory
189 Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments(
190 const Sequence<Any>& Arguments )
191 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
193 return createInstanceWithArgumentsAndContext(
194 Arguments, Reference< XComponentContext >() );
197 // XSingleComponentFactory
198 //__________________________________________________________________________________________________
199 Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext(
200 Reference< XComponentContext > const & xContext )
201 throw (Exception, RuntimeException)
203 return createInstanceEveryTime( xContext );
205 //__________________________________________________________________________________________________
206 Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext(
207 Sequence< Any > const & rArguments,
208 Reference< XComponentContext > const & xContext )
209 throw (Exception, RuntimeException)
211 Reference< XInterface > xRet( createInstanceWithContext( xContext ) );
213 Reference< lang::XInitialization > xInit( xRet, UNO_QUERY );
214 // always call initialize, even if there are no arguments.
215 // #i63511# / 2006-03-27 / frank.schoenheit@sun.com
216 if (xInit.is())
218 xInit->initialize( rArguments );
220 else
222 if ( rArguments.getLength() )
224 // dispose the here created UNO object before throwing out exception
225 // to avoid risk of memory leaks #i113722#
226 Reference<XComponent> xComp( xRet, UNO_QUERY );
227 if (xComp.is())
228 xComp->dispose();
230 throw lang::IllegalArgumentException(
231 OUString("cannot pass arguments to component => no XInitialization implemented!"),
232 Reference< XInterface >(), 0 );
236 return xRet;
239 // XServiceInfo
240 OUString OSingleFactoryHelper::getImplementationName()
241 throw(::com::sun::star::uno::RuntimeException)
243 return aImplementationName;
246 // XServiceInfo
247 sal_Bool OSingleFactoryHelper::supportsService(
248 const OUString& ServiceName )
249 throw(::com::sun::star::uno::RuntimeException)
251 return cppu::supportsService(this, ServiceName);
254 // XServiceInfo
255 Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames(void)
256 throw(::com::sun::star::uno::RuntimeException)
258 return aServiceNames;
261 struct OFactoryComponentHelper_Mutex
263 Mutex aMutex;
266 class OFactoryComponentHelper
267 : public OFactoryComponentHelper_Mutex
268 , public OComponentHelper
269 , public OSingleFactoryHelper
271 public:
272 OFactoryComponentHelper(
273 const Reference<XMultiServiceFactory > & rServiceManager,
274 const OUString & rImplementationName_,
275 ComponentInstantiation pCreateFunction_,
276 ComponentFactoryFunc fptr,
277 const Sequence< OUString > * pServiceNames_,
278 sal_Bool bOneInstance_ = sal_False )
279 SAL_THROW(())
280 : OComponentHelper( aMutex )
281 , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ )
282 , bOneInstance( bOneInstance_ )
286 // XInterface
287 Any SAL_CALL queryInterface( const Type & rType )
288 throw(::com::sun::star::uno::RuntimeException);
289 void SAL_CALL acquire() throw()
290 { OComponentHelper::acquire(); }
291 void SAL_CALL release() throw()
292 { OComponentHelper::release(); }
294 // XSingleServiceFactory
295 Reference<XInterface > SAL_CALL createInstance()
296 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
297 Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments )
298 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
299 // XSingleComponentFactory
300 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
301 Reference< XComponentContext > const & xContext )
302 throw (Exception, RuntimeException);
303 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
304 Sequence< Any > const & rArguments,
305 Reference< XComponentContext > const & xContext )
306 throw (Exception, RuntimeException);
308 // XTypeProvider
309 virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
310 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
312 // XAggregation
313 Any SAL_CALL queryAggregation( const Type & rType )
314 throw(::com::sun::star::uno::RuntimeException);
316 // XUnloadingPreference
317 virtual sal_Bool SAL_CALL releaseOnNotification()
318 throw(::com::sun::star::uno::RuntimeException);
320 // OComponentHelper
321 void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
323 private:
324 Reference<XInterface > xTheInstance;
325 sal_Bool bOneInstance;
326 protected:
327 // needed for implementing XUnloadingPreference in inheriting classes
328 sal_Bool isOneInstance() {return bOneInstance;}
329 sal_Bool isInstance() {return xTheInstance.is();}
333 Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType )
334 throw(::com::sun::star::uno::RuntimeException)
336 if( rType == ::getCppuType( (Reference<XUnloadingPreference>*)0))
338 return makeAny(
339 Reference< XUnloadingPreference >(
340 static_cast< XUnloadingPreference * >(this) ) );
342 return OComponentHelper::queryInterface( rType );
345 // XAggregation
346 Any OFactoryComponentHelper::queryAggregation( const Type & rType )
347 throw(::com::sun::star::uno::RuntimeException)
349 Any aRet( OComponentHelper::queryAggregation( rType ) );
350 return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType ));
353 // XTypeProvider
354 Sequence< Type > OFactoryComponentHelper::getTypes()
355 throw (::com::sun::star::uno::RuntimeException)
357 Type ar[ 4 ];
358 ar[ 0 ] = ::getCppuType( (const Reference< XSingleServiceFactory > *)0 );
359 ar[ 1 ] = ::getCppuType( (const Reference< XServiceInfo > *)0 );
360 ar[ 2 ] = ::getCppuType( (const Reference< XUnloadingPreference > *)0 );
362 if (m_fptr)
363 ar[ 3 ] = ::getCppuType( (const Reference< XSingleComponentFactory > *)0 );
365 return Sequence< Type >( ar, m_fptr ? 4 : 3 );
368 namespace
370 class theOFactoryComponentHelperImplementationId :
371 public rtl::Static<OImplementationId, theOFactoryComponentHelperImplementationId>{};
374 Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId()
375 throw (::com::sun::star::uno::RuntimeException)
377 return theOFactoryComponentHelperImplementationId::get().getImplementationId();
380 // XSingleServiceFactory
381 Reference<XInterface > OFactoryComponentHelper::createInstance()
382 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
384 if( bOneInstance )
386 if( !xTheInstance.is() )
388 MutexGuard aGuard( aMutex );
389 if( !xTheInstance.is() )
390 xTheInstance = OSingleFactoryHelper::createInstance();
392 return xTheInstance;
394 return OSingleFactoryHelper::createInstance();
397 Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments(
398 const Sequence<Any>& Arguments )
399 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
401 if( bOneInstance )
403 if( !xTheInstance.is() )
405 MutexGuard aGuard( aMutex );
406 // OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" );
407 if( !xTheInstance.is() )
408 xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments );
410 return xTheInstance;
412 return OSingleFactoryHelper::createInstanceWithArguments( Arguments );
415 // XSingleComponentFactory
416 //__________________________________________________________________________________________________
417 Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext(
418 Reference< XComponentContext > const & xContext )
419 throw (Exception, RuntimeException)
421 if( bOneInstance )
423 if( !xTheInstance.is() )
425 MutexGuard aGuard( aMutex );
426 // OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" );
427 if( !xTheInstance.is() )
428 xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext );
430 return xTheInstance;
432 return OSingleFactoryHelper::createInstanceWithContext( xContext );
434 //__________________________________________________________________________________________________
435 Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext(
436 Sequence< Any > const & rArguments,
437 Reference< XComponentContext > const & xContext )
438 throw (Exception, RuntimeException)
440 if( bOneInstance )
442 if( !xTheInstance.is() )
444 MutexGuard aGuard( aMutex );
445 // OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" );
446 if( !xTheInstance.is() )
447 xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
449 return xTheInstance;
451 return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
455 // OComponentHelper
456 void OFactoryComponentHelper::dispose()
457 throw(::com::sun::star::uno::RuntimeException)
459 OComponentHelper::dispose();
461 Reference<XInterface > x;
463 // do not delete in the guard section
464 MutexGuard aGuard( aMutex );
465 x = xTheInstance;
466 xTheInstance = Reference<XInterface >();
468 // if it is a component call dispose at the component
469 Reference<XComponent > xComp( x, UNO_QUERY );
470 if( xComp.is() )
471 xComp->dispose();
474 // XUnloadingPreference
475 // This class is used for single factories, component factories and
476 // one-instance factories. Depending on the usage this function has
477 // to return different values.
478 // one-instance factory: sal_False
479 // single factory: sal_True
480 // component factory: sal_True
481 sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException)
483 if( bOneInstance)
484 return sal_False;
485 return sal_True;
488 class ORegistryFactoryHelper : public OFactoryComponentHelper,
489 public OPropertySetHelper
492 public:
493 ORegistryFactoryHelper(
494 const Reference<XMultiServiceFactory > & rServiceManager,
495 const OUString & rImplementationName_,
496 const Reference<XRegistryKey > & xImplementationKey_,
497 sal_Bool bOneInstance_ = sal_False ) SAL_THROW(())
498 : OFactoryComponentHelper(
499 rServiceManager, rImplementationName_, 0, 0, 0, bOneInstance_ ),
500 OPropertySetHelper( OComponentHelper::rBHelper ),
501 xImplementationKey( xImplementationKey_ )
504 // XInterface
505 virtual Any SAL_CALL queryInterface( Type const & type )
506 throw (RuntimeException);
507 virtual void SAL_CALL acquire() throw ();
508 virtual void SAL_CALL release() throw ();
509 // XTypeProvider
510 virtual Sequence< Type > SAL_CALL getTypes()
511 throw (RuntimeException);
512 // XPropertySet
513 virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo()
514 throw (RuntimeException);
516 // OPropertySetHelper
517 virtual IPropertyArrayHelper & SAL_CALL getInfoHelper();
518 virtual sal_Bool SAL_CALL convertFastPropertyValue(
519 Any & rConvertedValue, Any & rOldValue,
520 sal_Int32 nHandle, Any const & rValue )
521 throw (lang::IllegalArgumentException);
522 virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
523 sal_Int32 nHandle, Any const & rValue )
524 throw (Exception);
525 using OPropertySetHelper::getFastPropertyValue;
526 virtual void SAL_CALL getFastPropertyValue(
527 Any & rValue, sal_Int32 nHandle ) const;
529 // OSingleFactoryHelper
530 Reference<XInterface > createInstanceEveryTime(
531 Reference< XComponentContext > const & xContext )
532 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
534 // XSingleServiceFactory
535 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
536 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
537 // XSingleComponentFactory
538 Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
539 Sequence< Any > const & rArguments,
540 Reference< XComponentContext > const & xContext )
541 throw (Exception, RuntimeException);
543 // XServiceInfo
544 Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
545 throw(::com::sun::star::uno::RuntimeException);
546 // XUnloadingPreference
547 sal_Bool SAL_CALL releaseOnNotification()
548 throw( RuntimeException);
551 private:
552 Reference< XInterface > createModuleFactory()
553 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
555 /** The registry key of the implementation section */
556 Reference<XRegistryKey > xImplementationKey;
557 /** The factory created with the loader. */
558 Reference<XSingleComponentFactory > xModuleFactory;
559 Reference<XSingleServiceFactory > xModuleFactoryDepr;
560 Reference< beans::XPropertySetInfo > m_xInfo;
561 ::std::auto_ptr< IPropertyArrayHelper > m_property_array_helper;
562 protected:
563 using OPropertySetHelper::getTypes;
566 // XInterface
567 //______________________________________________________________________________
568 Any SAL_CALL ORegistryFactoryHelper::queryInterface(
569 Type const & type ) throw (RuntimeException)
571 Any ret( OFactoryComponentHelper::queryInterface( type ) );
572 if (ret.hasValue())
573 return ret;
574 else
575 return OPropertySetHelper::queryInterface( type );
578 //______________________________________________________________________________
579 void ORegistryFactoryHelper::acquire() throw ()
581 OFactoryComponentHelper::acquire();
584 //______________________________________________________________________________
585 void ORegistryFactoryHelper::release() throw ()
587 OFactoryComponentHelper::release();
590 // XTypeProvider
591 //______________________________________________________________________________
592 Sequence< Type > ORegistryFactoryHelper::getTypes() throw (RuntimeException)
594 Sequence< Type > types( OFactoryComponentHelper::getTypes() );
595 sal_Int32 pos = types.getLength();
596 types.realloc( pos + 3 );
597 Type * p = types.getArray();
598 p[ pos++ ] = ::getCppuType(
599 reinterpret_cast< Reference< beans::XMultiPropertySet > const * >(0) );
600 p[ pos++ ] = ::getCppuType(
601 reinterpret_cast< Reference< beans::XFastPropertySet > const * >(0) );
602 p[ pos++ ] = ::getCppuType(
603 reinterpret_cast< Reference< beans::XPropertySet > const * >(0) );
604 return types;
607 // XPropertySet
608 //______________________________________________________________________________
609 Reference< beans::XPropertySetInfo >
610 ORegistryFactoryHelper::getPropertySetInfo() throw (RuntimeException)
612 ::osl::MutexGuard guard( aMutex );
613 if (! m_xInfo.is())
614 m_xInfo = createPropertySetInfo( getInfoHelper() );
615 return m_xInfo;
618 // OPropertySetHelper
619 //______________________________________________________________________________
620 IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper()
622 ::osl::MutexGuard guard( aMutex );
623 if (m_property_array_helper.get() == 0)
625 beans::Property prop(
626 "ImplementationKey" /* name */,
627 0 /* handle */,
628 ::getCppuType( &xImplementationKey ),
629 beans::PropertyAttribute::READONLY |
630 beans::PropertyAttribute::OPTIONAL );
631 m_property_array_helper.reset(
632 new ::cppu::OPropertyArrayHelper( &prop, 1 ) );
634 return *m_property_array_helper.get();
637 //______________________________________________________________________________
638 sal_Bool ORegistryFactoryHelper::convertFastPropertyValue(
639 Any &, Any &, sal_Int32, Any const & )
640 throw (lang::IllegalArgumentException)
642 OSL_FAIL( "unexpected!" );
643 return false;
646 //______________________________________________________________________________
647 void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast(
648 sal_Int32, Any const & )
649 throw (Exception)
651 throw beans::PropertyVetoException(
652 "unexpected: only readonly properties!",
653 static_cast< OWeakObject * >(this) );
656 //______________________________________________________________________________
657 void ORegistryFactoryHelper::getFastPropertyValue(
658 Any & rValue, sal_Int32 nHandle ) const
660 if (nHandle == 0)
662 rValue <<= xImplementationKey;
664 else
666 rValue.clear();
667 throw beans::UnknownPropertyException(
668 "unknown property!", static_cast< OWeakObject * >(
669 const_cast< ORegistryFactoryHelper * >(this) ) );
673 Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime(
674 Reference< XComponentContext > const & xContext )
675 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
677 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
679 Reference< XInterface > x( createModuleFactory() );
680 if (x.is())
682 MutexGuard aGuard( aMutex );
683 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
685 xModuleFactory.set( x, UNO_QUERY );
686 xModuleFactoryDepr.set( x, UNO_QUERY );
690 if( xModuleFactory.is() )
692 return xModuleFactory->createInstanceWithContext( xContext );
694 else if( xModuleFactoryDepr.is() )
696 return xModuleFactoryDepr->createInstance();
699 return Reference<XInterface >();
702 Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments(
703 const Sequence<Any>& Arguments )
704 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
706 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
708 Reference< XInterface > x( createModuleFactory() );
709 if (x.is())
711 MutexGuard aGuard( aMutex );
712 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
714 xModuleFactory.set( x, UNO_QUERY );
715 xModuleFactoryDepr.set( x, UNO_QUERY );
719 if( xModuleFactoryDepr.is() )
721 return xModuleFactoryDepr->createInstanceWithArguments( Arguments );
723 else if( xModuleFactory.is() )
725 #if OSL_DEBUG_LEVEL > 1
726 OSL_TRACE( "### no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!" );
727 #endif
728 return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() );
731 return Reference<XInterface >();
734 Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext(
735 Sequence< Any > const & rArguments,
736 Reference< XComponentContext > const & xContext )
737 throw (Exception, RuntimeException)
739 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
741 Reference< XInterface > x( createModuleFactory() );
742 if (x.is())
744 MutexGuard aGuard( aMutex );
745 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
747 xModuleFactory.set( x, UNO_QUERY );
748 xModuleFactoryDepr.set( x, UNO_QUERY );
752 if( xModuleFactory.is() )
754 return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext );
756 else if( xModuleFactoryDepr.is() )
758 #if OSL_DEBUG_LEVEL > 1
759 if (xContext.is())
761 OSL_TRACE( "### ignoring context calling ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!" );
763 #endif
764 return xModuleFactoryDepr->createInstanceWithArguments( rArguments );
767 return Reference<XInterface >();
771 // OSingleFactoryHelper
772 Reference< XInterface > ORegistryFactoryHelper::createModuleFactory()
773 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
775 OUString aActivatorUrl;
776 OUString aActivatorName;
777 OUString aLocation;
779 Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey(
780 OUString("/UNO/ACTIVATOR") );
781 if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII )
783 aActivatorUrl = xActivatorKey->getAsciiValue();
785 OUString tmpActivator(aActivatorUrl.getStr());
786 sal_Int32 nIndex = 0;
787 aActivatorName = tmpActivator.getToken(0, ':', nIndex );
789 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
790 OUString("/UNO/LOCATION") );
791 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
792 aLocation = xLocationKey->getAsciiValue();
794 else
796 // old style"url"
797 // the location of the program code of the implementation
798 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
799 OUString("/UNO/URL") );
800 // is the key of the right type ?
801 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
803 // one implementation found -> try to activate
804 aLocation = xLocationKey->getAsciiValue();
806 // search protocol delimiter
807 sal_Int32 nPos = aLocation.indexOf(
808 OUString("://") );
809 if( nPos != -1 )
811 aActivatorName = aLocation.copy( 0, nPos );
812 if( aActivatorName.compareToAscii( "java" ) == 0 )
813 aActivatorName = OUString("com.sun.star.loader.Java");
814 else if( aActivatorName.compareToAscii( "module" ) == 0 )
815 aActivatorName = OUString("com.sun.star.loader.SharedLibrary");
816 aLocation = aLocation.copy( nPos + 3 );
821 Reference< XInterface > xFactory;
822 if( !aActivatorName.isEmpty() )
824 Reference<XInterface > x = xSMgr->createInstance( aActivatorName );
825 Reference<XImplementationLoader > xLoader( x, UNO_QUERY );
826 Reference<XInterface > xMF;
827 if (xLoader.is())
829 xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey );
832 return xFactory;
835 // XServiceInfo
836 Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames(void)
837 throw(::com::sun::star::uno::RuntimeException)
839 MutexGuard aGuard( aMutex );
840 if( aServiceNames.getLength() == 0 )
842 // not yet loaded
845 Reference<XRegistryKey > xKey = xImplementationKey->openKey(
846 OUString("UNO/SERVICES") );
848 if (xKey.is())
850 // length of prefix. +1 for the '/' at the end
851 sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1;
853 // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..."
854 Sequence<OUString> seqKeys = xKey->getKeyNames();
855 OUString* pKeys = seqKeys.getArray();
856 for( sal_Int32 i = 0; i < seqKeys.getLength(); i++ )
857 pKeys[i] = pKeys[i].copy(nPrefixLen);
859 aServiceNames = seqKeys;
862 catch (InvalidRegistryException &)
866 return aServiceNames;
869 sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException)
871 sal_Bool retVal= sal_True;
872 if( isOneInstance() && isInstance())
874 retVal= sal_False;
876 else if( ! isOneInstance())
878 // try to delegate
879 if( xModuleFactory.is())
881 Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY);
882 if( xunloading.is())
883 retVal= xunloading->releaseOnNotification();
885 else if( xModuleFactoryDepr.is())
887 Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY);
888 if( xunloading.is())
889 retVal= xunloading->releaseOnNotification();
892 return retVal;
895 class OFactoryProxyHelper : public WeakImplHelper3< XServiceInfo, XSingleServiceFactory,
896 XUnloadingPreference >
898 Reference<XSingleServiceFactory > xFactory;
900 public:
902 OFactoryProxyHelper( const Reference<XSingleServiceFactory > & rFactory )
903 SAL_THROW(())
904 : xFactory( rFactory )
907 // XSingleServiceFactory
908 Reference<XInterface > SAL_CALL createInstance()
909 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
910 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
911 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
913 // XServiceInfo
914 OUString SAL_CALL getImplementationName()
915 throw(::com::sun::star::uno::RuntimeException);
916 sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
917 throw(::com::sun::star::uno::RuntimeException);
918 Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
919 throw(::com::sun::star::uno::RuntimeException);
920 //XUnloadingPreference
921 sal_Bool SAL_CALL releaseOnNotification()
922 throw(::com::sun::star::uno::RuntimeException);
926 // XSingleServiceFactory
927 Reference<XInterface > OFactoryProxyHelper::createInstance()
928 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
930 return xFactory->createInstance();
933 // XSingleServiceFactory
934 Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments
936 const Sequence<Any>& Arguments
938 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
940 return xFactory->createInstanceWithArguments( Arguments );
943 // XServiceInfo
944 OUString OFactoryProxyHelper::getImplementationName()
945 throw(::com::sun::star::uno::RuntimeException)
947 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
948 if( xInfo.is() )
949 return xInfo->getImplementationName();
950 return OUString();
953 // XServiceInfo
954 sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName)
955 throw(::com::sun::star::uno::RuntimeException)
957 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
958 return xInfo.is() && xInfo->supportsService( ServiceName );
961 // XServiceInfo
962 Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames(void)
963 throw(::com::sun::star::uno::RuntimeException)
965 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
966 if( xInfo.is() )
967 return xInfo->getSupportedServiceNames();
968 return Sequence< OUString >();
971 sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException)
974 Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY);
975 if( pref.is())
976 return pref->releaseOnNotification();
977 return sal_True;
980 // global function
981 Reference<XSingleServiceFactory > SAL_CALL createSingleFactory(
982 const Reference<XMultiServiceFactory > & rServiceManager,
983 const OUString & rImplementationName,
984 ComponentInstantiation pCreateFunction,
985 const Sequence< OUString > & rServiceNames,
986 rtl_ModuleCount * )
987 SAL_THROW(())
989 return new OFactoryComponentHelper(
990 rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, sal_False );
993 // global function
994 Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy(
995 SAL_UNUSED_PARAMETER const Reference<XMultiServiceFactory > &,
996 const Reference<XSingleServiceFactory > & rFactory )
997 SAL_THROW(())
999 return new OFactoryProxyHelper( rFactory );
1002 // global function
1003 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory(
1004 const Reference<XMultiServiceFactory > & rServiceManager,
1005 const OUString & rImplementationName,
1006 ComponentInstantiation pCreateFunction,
1007 const Sequence< OUString > & rServiceNames,
1008 rtl_ModuleCount * )
1009 SAL_THROW(())
1011 return new OFactoryComponentHelper(
1012 rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, sal_True );
1015 // global function
1016 Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(
1017 const Reference<XMultiServiceFactory > & rServiceManager,
1018 const OUString & rImplementationName,
1019 const Reference<XRegistryKey > & rImplementationKey )
1020 SAL_THROW(())
1022 return new ORegistryFactoryHelper(
1023 rServiceManager, rImplementationName, rImplementationKey, sal_False );
1026 // global function
1027 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory(
1028 const Reference<XMultiServiceFactory > & rServiceManager,
1029 const OUString & rImplementationName,
1030 const Reference<XRegistryKey > & rImplementationKey )
1031 SAL_THROW(())
1033 return new ORegistryFactoryHelper(
1034 rServiceManager, rImplementationName, rImplementationKey, sal_True );
1037 //##################################################################################################
1038 Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory(
1039 ComponentFactoryFunc fptr,
1040 OUString const & rImplementationName,
1041 Sequence< OUString > const & rServiceNames,
1042 rtl_ModuleCount *)
1043 SAL_THROW(())
1045 return new OFactoryComponentHelper(
1046 Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, sal_False );
1049 Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory(
1050 ComponentFactoryFunc fptr,
1051 OUString const & rImplementationName,
1052 Sequence< OUString > const & rServiceNames,
1053 rtl_ModuleCount *)
1054 SAL_THROW(())
1056 return new OFactoryComponentHelper(
1057 Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, sal_True );
1063 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */