Bump version to 5.0-43
[LibreOffice.git] / cppuhelper / source / factory.cxx
bloba634086fd33b0310889ba987e9faa5b2cf3ebf53
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/implbase.hxx>
27 #include <cppuhelper/queryinterface.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 : xSMgr( rServiceManager )
74 , pCreateFunction( pCreateFunction_ )
75 , m_fptr( fptr )
76 , aImplementationName( rImplementationName_ )
78 if( pServiceNames_ )
79 aServiceNames = *pServiceNames_;
82 virtual ~OSingleFactoryHelper();
84 // XInterface
85 Any SAL_CALL queryInterface( const Type & rType )
86 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
88 // XSingleServiceFactory
89 Reference<XInterface > SAL_CALL createInstance()
90 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
91 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
92 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
93 // XSingleComponentFactory
94 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
95 Reference< XComponentContext > const & xContext )
96 throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
97 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
98 Sequence< Any > const & rArguments,
99 Reference< XComponentContext > const & xContext )
100 throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
102 // XServiceInfo
103 OUString SAL_CALL getImplementationName()
104 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
105 sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
106 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
107 Sequence< OUString > SAL_CALL getSupportedServiceNames()
108 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
110 protected:
112 * Create an instance specified by the factory. The one instance logic is implemented
113 * in the createInstance and createInstanceWithArguments methods.
114 * @return the newly created instance. Do not return a previous (one instance) instance.
116 virtual Reference<XInterface > createInstanceEveryTime(
117 Reference< XComponentContext > const & xContext )
118 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
120 Reference<XMultiServiceFactory > xSMgr;
121 ComponentInstantiation pCreateFunction;
122 ComponentFactoryFunc m_fptr;
123 Sequence< OUString > aServiceNames;
124 OUString aImplementationName;
126 OSingleFactoryHelper::~OSingleFactoryHelper()
132 Any OSingleFactoryHelper::queryInterface( const Type & rType )
133 throw(::com::sun::star::uno::RuntimeException, std::exception)
135 return ::cppu::queryInterface(
136 rType,
137 static_cast< XSingleComponentFactory * >( this ),
138 static_cast< XSingleServiceFactory * >( this ),
139 static_cast< XServiceInfo * >( this ) ,
140 static_cast< XUnloadingPreference * >( this ));
143 // OSingleFactoryHelper
144 Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime(
145 Reference< XComponentContext > const & xContext )
146 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
148 if (m_fptr)
150 return (*m_fptr)( xContext );
152 else if( pCreateFunction )
154 if (xContext.is())
156 Reference< lang::XMultiServiceFactory > xContextMgr(
157 xContext->getServiceManager(), UNO_QUERY );
158 if (xContextMgr.is())
159 return (*pCreateFunction)( xContextMgr );
161 return (*pCreateFunction)( xSMgr );
163 else
165 return Reference< XInterface >();
169 // XSingleServiceFactory
170 Reference<XInterface > OSingleFactoryHelper::createInstance()
171 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
173 return createInstanceWithContext( Reference< XComponentContext >() );
176 // XSingleServiceFactory
177 Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments(
178 const Sequence<Any>& Arguments )
179 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
181 return createInstanceWithArgumentsAndContext(
182 Arguments, Reference< XComponentContext >() );
185 // XSingleComponentFactory
187 Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext(
188 Reference< XComponentContext > const & xContext )
189 throw (Exception, RuntimeException, std::exception)
191 return createInstanceEveryTime( xContext );
194 Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext(
195 Sequence< Any > const & rArguments,
196 Reference< XComponentContext > const & xContext )
197 throw (Exception, RuntimeException, std::exception)
199 Reference< XInterface > xRet( createInstanceWithContext( xContext ) );
201 Reference< lang::XInitialization > xInit( xRet, UNO_QUERY );
202 // always call initialize, even if there are no arguments.
203 // #i63511# / 2006-03-27 / frank.schoenheit@sun.com
204 if (xInit.is())
206 xInit->initialize( rArguments );
208 else
210 if ( rArguments.getLength() )
212 // dispose the here created UNO object before throwing out exception
213 // to avoid risk of memory leaks #i113722#
214 Reference<XComponent> xComp( xRet, UNO_QUERY );
215 if (xComp.is())
216 xComp->dispose();
218 throw lang::IllegalArgumentException(
219 OUString("cannot pass arguments to component => no XInitialization implemented!"),
220 Reference< XInterface >(), 0 );
224 return xRet;
227 // XServiceInfo
228 OUString OSingleFactoryHelper::getImplementationName()
229 throw(::com::sun::star::uno::RuntimeException, std::exception)
231 return aImplementationName;
234 // XServiceInfo
235 sal_Bool OSingleFactoryHelper::supportsService(
236 const OUString& ServiceName )
237 throw(::com::sun::star::uno::RuntimeException, std::exception)
239 return cppu::supportsService(this, ServiceName);
242 // XServiceInfo
243 Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames()
244 throw(::com::sun::star::uno::RuntimeException, std::exception)
246 return aServiceNames;
249 struct OFactoryComponentHelper_Mutex
251 Mutex aMutex;
254 class OFactoryComponentHelper
255 : public OFactoryComponentHelper_Mutex
256 , public OComponentHelper
257 , public OSingleFactoryHelper
259 public:
260 OFactoryComponentHelper(
261 const Reference<XMultiServiceFactory > & rServiceManager,
262 const OUString & rImplementationName_,
263 ComponentInstantiation pCreateFunction_,
264 ComponentFactoryFunc fptr,
265 const Sequence< OUString > * pServiceNames_,
266 bool bOneInstance_ = false )
267 : OComponentHelper( aMutex )
268 , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ )
269 , bOneInstance( bOneInstance_ )
273 // XInterface
274 Any SAL_CALL queryInterface( const Type & rType )
275 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
276 void SAL_CALL acquire() throw() SAL_OVERRIDE
277 { OComponentHelper::acquire(); }
278 void SAL_CALL release() throw() SAL_OVERRIDE
279 { OComponentHelper::release(); }
281 // XSingleServiceFactory
282 Reference<XInterface > SAL_CALL createInstance()
283 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
284 Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments )
285 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
286 // XSingleComponentFactory
287 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
288 Reference< XComponentContext > const & xContext )
289 throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
290 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
291 Sequence< Any > const & rArguments,
292 Reference< XComponentContext > const & xContext )
293 throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
295 // XTypeProvider
296 virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
297 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
299 // XAggregation
300 Any SAL_CALL queryAggregation( const Type & rType )
301 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
303 // XUnloadingPreference
304 virtual sal_Bool SAL_CALL releaseOnNotification()
305 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
307 // OComponentHelper
308 void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
310 private:
311 Reference<XInterface > xTheInstance;
312 bool bOneInstance;
313 protected:
314 // needed for implementing XUnloadingPreference in inheriting classes
315 bool isOneInstance() {return bOneInstance;}
316 bool isInstance() {return xTheInstance.is();}
320 Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType )
321 throw(::com::sun::star::uno::RuntimeException, std::exception)
323 if( rType == cppu::UnoType<XUnloadingPreference>::get() )
325 return makeAny(
326 Reference< XUnloadingPreference >(
327 static_cast< XUnloadingPreference * >(this) ) );
329 return OComponentHelper::queryInterface( rType );
332 // XAggregation
333 Any OFactoryComponentHelper::queryAggregation( const Type & rType )
334 throw(::com::sun::star::uno::RuntimeException, std::exception)
336 Any aRet( OComponentHelper::queryAggregation( rType ) );
337 return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType ));
340 // XTypeProvider
341 Sequence< Type > OFactoryComponentHelper::getTypes()
342 throw (::com::sun::star::uno::RuntimeException, std::exception)
344 Type ar[ 4 ];
345 ar[ 0 ] = cppu::UnoType<XSingleServiceFactory>::get();
346 ar[ 1 ] = cppu::UnoType<XServiceInfo>::get();
347 ar[ 2 ] = cppu::UnoType<XUnloadingPreference>::get();
349 if (m_fptr)
350 ar[ 3 ] = cppu::UnoType<XSingleComponentFactory>::get();
352 return Sequence< Type >( ar, m_fptr ? 4 : 3 );
355 Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId()
356 throw (::com::sun::star::uno::RuntimeException, std::exception)
358 return css::uno::Sequence<sal_Int8>();
361 // XSingleServiceFactory
362 Reference<XInterface > OFactoryComponentHelper::createInstance()
363 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
365 if( bOneInstance )
367 if( !xTheInstance.is() )
369 MutexGuard aGuard( aMutex );
370 if( !xTheInstance.is() )
371 xTheInstance = OSingleFactoryHelper::createInstance();
373 return xTheInstance;
375 return OSingleFactoryHelper::createInstance();
378 Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments(
379 const Sequence<Any>& Arguments )
380 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
382 if( bOneInstance )
384 if( !xTheInstance.is() )
386 MutexGuard aGuard( aMutex );
387 // OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" );
388 if( !xTheInstance.is() )
389 xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments );
391 return xTheInstance;
393 return OSingleFactoryHelper::createInstanceWithArguments( Arguments );
396 // XSingleComponentFactory
398 Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext(
399 Reference< XComponentContext > const & xContext )
400 throw (Exception, RuntimeException, std::exception)
402 if( bOneInstance )
404 if( !xTheInstance.is() )
406 MutexGuard aGuard( aMutex );
407 // OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" );
408 if( !xTheInstance.is() )
409 xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext );
411 return xTheInstance;
413 return OSingleFactoryHelper::createInstanceWithContext( xContext );
416 Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext(
417 Sequence< Any > const & rArguments,
418 Reference< XComponentContext > const & xContext )
419 throw (Exception, RuntimeException, std::exception)
421 if( bOneInstance )
423 if( !xTheInstance.is() )
425 MutexGuard aGuard( aMutex );
426 // OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" );
427 if( !xTheInstance.is() )
428 xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
430 return xTheInstance;
432 return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
436 // OComponentHelper
437 void OFactoryComponentHelper::dispose()
438 throw(::com::sun::star::uno::RuntimeException, std::exception)
440 OComponentHelper::dispose();
442 Reference<XInterface > x;
444 // do not delete in the guard section
445 MutexGuard aGuard( aMutex );
446 x = xTheInstance;
447 xTheInstance.clear();
449 // if it is a component call dispose at the component
450 Reference<XComponent > xComp( x, UNO_QUERY );
451 if( xComp.is() )
452 xComp->dispose();
455 // XUnloadingPreference
456 // This class is used for single factories, component factories and
457 // one-instance factories. Depending on the usage this function has
458 // to return different values.
459 // one-instance factory: sal_False
460 // single factory: sal_True
461 // component factory: sal_True
462 sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException, std::exception)
464 if( bOneInstance)
465 return sal_False;
466 return sal_True;
469 class ORegistryFactoryHelper : public OFactoryComponentHelper,
470 public OPropertySetHelper
473 public:
474 ORegistryFactoryHelper(
475 const Reference<XMultiServiceFactory > & rServiceManager,
476 const OUString & rImplementationName_,
477 const Reference<XRegistryKey > & xImplementationKey_,
478 bool bOneInstance_ = false )
479 : OFactoryComponentHelper(
480 rServiceManager, rImplementationName_, 0, 0, 0, bOneInstance_ ),
481 OPropertySetHelper( OComponentHelper::rBHelper ),
482 xImplementationKey( xImplementationKey_ )
485 // XInterface
486 virtual Any SAL_CALL queryInterface( Type const & type )
487 throw (RuntimeException, std::exception) SAL_OVERRIDE;
488 virtual void SAL_CALL acquire() throw () SAL_OVERRIDE;
489 virtual void SAL_CALL release() throw () SAL_OVERRIDE;
490 // XTypeProvider
491 virtual Sequence< Type > SAL_CALL getTypes()
492 throw (RuntimeException, std::exception) SAL_OVERRIDE;
493 // XPropertySet
494 virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo()
495 throw (RuntimeException, std::exception) SAL_OVERRIDE;
497 // OPropertySetHelper
498 virtual IPropertyArrayHelper & SAL_CALL getInfoHelper() SAL_OVERRIDE;
499 virtual sal_Bool SAL_CALL convertFastPropertyValue(
500 Any & rConvertedValue, Any & rOldValue,
501 sal_Int32 nHandle, Any const & rValue )
502 throw (lang::IllegalArgumentException) SAL_OVERRIDE;
503 virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
504 sal_Int32 nHandle, Any const & rValue )
505 throw (Exception, std::exception) SAL_OVERRIDE;
506 using OPropertySetHelper::getFastPropertyValue;
507 virtual void SAL_CALL getFastPropertyValue(
508 Any & rValue, sal_Int32 nHandle ) const SAL_OVERRIDE;
510 // OSingleFactoryHelper
511 Reference<XInterface > createInstanceEveryTime(
512 Reference< XComponentContext > const & xContext )
513 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) SAL_OVERRIDE;
515 // XSingleServiceFactory
516 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
517 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
518 // XSingleComponentFactory
519 Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
520 Sequence< Any > const & rArguments,
521 Reference< XComponentContext > const & xContext )
522 throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
524 // XServiceInfo
525 Sequence< OUString > SAL_CALL getSupportedServiceNames()
526 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
527 // XUnloadingPreference
528 sal_Bool SAL_CALL releaseOnNotification()
529 throw( RuntimeException, std::exception) SAL_OVERRIDE;
532 private:
533 Reference< XInterface > createModuleFactory()
534 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
536 /** The registry key of the implementation section */
537 Reference<XRegistryKey > xImplementationKey;
538 /** The factory created with the loader. */
539 Reference<XSingleComponentFactory > xModuleFactory;
540 Reference<XSingleServiceFactory > xModuleFactoryDepr;
541 Reference< beans::XPropertySetInfo > m_xInfo;
542 ::std::unique_ptr< IPropertyArrayHelper > m_property_array_helper;
543 protected:
544 using OPropertySetHelper::getTypes;
547 // XInterface
549 Any SAL_CALL ORegistryFactoryHelper::queryInterface(
550 Type const & type ) throw (RuntimeException, std::exception)
552 Any ret( OFactoryComponentHelper::queryInterface( type ) );
553 if (ret.hasValue())
554 return ret;
555 else
556 return OPropertySetHelper::queryInterface( type );
560 void ORegistryFactoryHelper::acquire() throw ()
562 OFactoryComponentHelper::acquire();
566 void ORegistryFactoryHelper::release() throw ()
568 OFactoryComponentHelper::release();
571 // XTypeProvider
573 Sequence< Type > ORegistryFactoryHelper::getTypes() throw (RuntimeException, std::exception)
575 Sequence< Type > types( OFactoryComponentHelper::getTypes() );
576 sal_Int32 pos = types.getLength();
577 types.realloc( pos + 3 );
578 Type * p = types.getArray();
579 p[ pos++ ] = cppu::UnoType<beans::XMultiPropertySet>::get();
580 p[ pos++ ] = cppu::UnoType<beans::XFastPropertySet>::get();
581 p[ pos++ ] = cppu::UnoType<beans::XPropertySet>::get();
582 return types;
585 // XPropertySet
587 Reference< beans::XPropertySetInfo >
588 ORegistryFactoryHelper::getPropertySetInfo() throw (RuntimeException, std::exception)
590 ::osl::MutexGuard guard( aMutex );
591 if (! m_xInfo.is())
592 m_xInfo = createPropertySetInfo( getInfoHelper() );
593 return m_xInfo;
596 // OPropertySetHelper
598 IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper()
600 ::osl::MutexGuard guard( aMutex );
601 if (m_property_array_helper.get() == 0)
603 beans::Property prop(
604 "ImplementationKey" /* name */,
605 0 /* handle */,
606 cppu::UnoType<decltype(xImplementationKey)>::get(),
607 beans::PropertyAttribute::READONLY |
608 beans::PropertyAttribute::OPTIONAL );
609 m_property_array_helper.reset(
610 new ::cppu::OPropertyArrayHelper( &prop, 1 ) );
612 return *m_property_array_helper.get();
616 sal_Bool ORegistryFactoryHelper::convertFastPropertyValue(
617 Any &, Any &, sal_Int32, Any const & )
618 throw (lang::IllegalArgumentException)
620 OSL_FAIL( "unexpected!" );
621 return false;
625 void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast(
626 sal_Int32, Any const & )
627 throw (Exception, std::exception)
629 throw beans::PropertyVetoException(
630 "unexpected: only readonly properties!",
631 static_cast< OWeakObject * >(this) );
635 void ORegistryFactoryHelper::getFastPropertyValue(
636 Any & rValue, sal_Int32 nHandle ) const
638 if (nHandle == 0)
640 rValue <<= xImplementationKey;
642 else
644 rValue.clear();
645 throw beans::UnknownPropertyException(
646 "unknown property!", static_cast< OWeakObject * >(
647 const_cast< ORegistryFactoryHelper * >(this) ) );
651 Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime(
652 Reference< XComponentContext > const & xContext )
653 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
655 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
657 Reference< XInterface > x( createModuleFactory() );
658 if (x.is())
660 MutexGuard aGuard( aMutex );
661 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
663 xModuleFactory.set( x, UNO_QUERY );
664 xModuleFactoryDepr.set( x, UNO_QUERY );
668 if( xModuleFactory.is() )
670 return xModuleFactory->createInstanceWithContext( xContext );
672 else if( xModuleFactoryDepr.is() )
674 return xModuleFactoryDepr->createInstance();
677 return Reference<XInterface >();
680 Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments(
681 const Sequence<Any>& Arguments )
682 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
684 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
686 Reference< XInterface > x( createModuleFactory() );
687 if (x.is())
689 MutexGuard aGuard( aMutex );
690 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
692 xModuleFactory.set( x, UNO_QUERY );
693 xModuleFactoryDepr.set( x, UNO_QUERY );
697 if( xModuleFactoryDepr.is() )
699 return xModuleFactoryDepr->createInstanceWithArguments( Arguments );
701 else if( xModuleFactory.is() )
703 #if OSL_DEBUG_LEVEL > 1
704 OSL_TRACE( "### no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!" );
705 #endif
706 return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() );
709 return Reference<XInterface >();
712 Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext(
713 Sequence< Any > const & rArguments,
714 Reference< XComponentContext > const & xContext )
715 throw (Exception, RuntimeException, std::exception)
717 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
719 Reference< XInterface > x( createModuleFactory() );
720 if (x.is())
722 MutexGuard aGuard( aMutex );
723 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
725 xModuleFactory.set( x, UNO_QUERY );
726 xModuleFactoryDepr.set( x, UNO_QUERY );
730 if( xModuleFactory.is() )
732 return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext );
734 else if( xModuleFactoryDepr.is() )
736 #if OSL_DEBUG_LEVEL > 1
737 if (xContext.is())
739 OSL_TRACE( "### ignoring context calling ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!" );
741 #endif
742 return xModuleFactoryDepr->createInstanceWithArguments( rArguments );
745 return Reference<XInterface >();
749 // OSingleFactoryHelper
750 Reference< XInterface > ORegistryFactoryHelper::createModuleFactory()
751 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
753 OUString aActivatorUrl;
754 OUString aActivatorName;
755 OUString aLocation;
757 Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey(
758 OUString("/UNO/ACTIVATOR") );
759 if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII )
761 aActivatorUrl = xActivatorKey->getAsciiValue();
763 OUString tmpActivator(aActivatorUrl.getStr());
764 sal_Int32 nIndex = 0;
765 aActivatorName = tmpActivator.getToken(0, ':', nIndex );
767 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
768 OUString("/UNO/LOCATION") );
769 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
770 aLocation = xLocationKey->getAsciiValue();
772 else
774 // old style"url"
775 // the location of the program code of the implementation
776 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
777 OUString("/UNO/URL") );
778 // is the key of the right type ?
779 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
781 // one implementation found -> try to activate
782 aLocation = xLocationKey->getAsciiValue();
784 // search protocol delimiter
785 sal_Int32 nPos = aLocation.indexOf(
786 OUString("://") );
787 if( nPos != -1 )
789 aActivatorName = aLocation.copy( 0, nPos );
790 if( aActivatorName == "java" )
791 aActivatorName = "com.sun.star.loader.Java";
792 else if( aActivatorName == "module" )
793 aActivatorName = "com.sun.star.loader.SharedLibrary";
794 aLocation = aLocation.copy( nPos + 3 );
799 Reference< XInterface > xFactory;
800 if( !aActivatorName.isEmpty() )
802 Reference<XInterface > x = xSMgr->createInstance( aActivatorName );
803 Reference<XImplementationLoader > xLoader( x, UNO_QUERY );
804 Reference<XInterface > xMF;
805 if (xLoader.is())
807 xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey );
810 return xFactory;
813 // XServiceInfo
814 Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames()
815 throw(::com::sun::star::uno::RuntimeException, std::exception)
817 MutexGuard aGuard( aMutex );
818 if( aServiceNames.getLength() == 0 )
820 // not yet loaded
823 Reference<XRegistryKey > xKey = xImplementationKey->openKey(
824 OUString("UNO/SERVICES") );
826 if (xKey.is())
828 // length of prefix. +1 for the '/' at the end
829 sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1;
831 // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..."
832 Sequence<OUString> seqKeys = xKey->getKeyNames();
833 OUString* pKeys = seqKeys.getArray();
834 for( sal_Int32 i = 0; i < seqKeys.getLength(); i++ )
835 pKeys[i] = pKeys[i].copy(nPrefixLen);
837 aServiceNames = seqKeys;
840 catch (InvalidRegistryException &)
844 return aServiceNames;
847 sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException, std::exception)
849 bool retVal= true;
850 if( isOneInstance() && isInstance())
852 retVal= false;
854 else if( ! isOneInstance())
856 // try to delegate
857 if( xModuleFactory.is())
859 Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY);
860 if( xunloading.is())
861 retVal= xunloading->releaseOnNotification();
863 else if( xModuleFactoryDepr.is())
865 Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY);
866 if( xunloading.is())
867 retVal= xunloading->releaseOnNotification();
870 return retVal;
873 class OFactoryProxyHelper : public WeakImplHelper< XServiceInfo, XSingleServiceFactory,
874 XUnloadingPreference >
876 Reference<XSingleServiceFactory > xFactory;
878 public:
880 OFactoryProxyHelper( const Reference<XSingleServiceFactory > & rFactory )
881 : xFactory( rFactory )
884 // XSingleServiceFactory
885 Reference<XInterface > SAL_CALL createInstance()
886 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
887 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
888 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
890 // XServiceInfo
891 OUString SAL_CALL getImplementationName()
892 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
893 sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
894 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
895 Sequence< OUString > SAL_CALL getSupportedServiceNames()
896 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
897 //XUnloadingPreference
898 sal_Bool SAL_CALL releaseOnNotification()
899 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
903 // XSingleServiceFactory
904 Reference<XInterface > OFactoryProxyHelper::createInstance()
905 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
907 return xFactory->createInstance();
910 // XSingleServiceFactory
911 Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments
913 const Sequence<Any>& Arguments
915 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
917 return xFactory->createInstanceWithArguments( Arguments );
920 // XServiceInfo
921 OUString OFactoryProxyHelper::getImplementationName()
922 throw(::com::sun::star::uno::RuntimeException, std::exception)
924 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
925 if( xInfo.is() )
926 return xInfo->getImplementationName();
927 return OUString();
930 // XServiceInfo
931 sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName)
932 throw(::com::sun::star::uno::RuntimeException, std::exception)
934 return cppu::supportsService(this, ServiceName);
937 // XServiceInfo
938 Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames()
939 throw(::com::sun::star::uno::RuntimeException, std::exception)
941 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
942 if( xInfo.is() )
943 return xInfo->getSupportedServiceNames();
944 return Sequence< OUString >();
947 sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException, std::exception)
950 Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY);
951 if( pref.is())
952 return pref->releaseOnNotification();
953 return sal_True;
956 // global function
957 Reference<XSingleServiceFactory > SAL_CALL createSingleFactory(
958 const Reference<XMultiServiceFactory > & rServiceManager,
959 const OUString & rImplementationName,
960 ComponentInstantiation pCreateFunction,
961 const Sequence< OUString > & rServiceNames,
962 rtl_ModuleCount * )
964 return new OFactoryComponentHelper(
965 rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, false );
968 // global function
969 Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy(
970 SAL_UNUSED_PARAMETER const Reference<XMultiServiceFactory > &,
971 const Reference<XSingleServiceFactory > & rFactory )
973 return new OFactoryProxyHelper( rFactory );
976 // global function
977 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory(
978 const Reference<XMultiServiceFactory > & rServiceManager,
979 const OUString & rImplementationName,
980 ComponentInstantiation pCreateFunction,
981 const Sequence< OUString > & rServiceNames,
982 rtl_ModuleCount * )
984 return new OFactoryComponentHelper(
985 rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, true );
988 // global function
989 Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(
990 const Reference<XMultiServiceFactory > & rServiceManager,
991 const OUString & rImplementationName,
992 const Reference<XRegistryKey > & rImplementationKey )
994 return new ORegistryFactoryHelper(
995 rServiceManager, rImplementationName, rImplementationKey, false );
998 // global function
999 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory(
1000 const Reference<XMultiServiceFactory > & rServiceManager,
1001 const OUString & rImplementationName,
1002 const Reference<XRegistryKey > & rImplementationKey )
1004 return new ORegistryFactoryHelper(
1005 rServiceManager, rImplementationName, rImplementationKey, true );
1009 Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory(
1010 ComponentFactoryFunc fptr,
1011 OUString const & rImplementationName,
1012 Sequence< OUString > const & rServiceNames,
1013 rtl_ModuleCount *)
1015 return new OFactoryComponentHelper(
1016 Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, false );
1019 Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory(
1020 ComponentFactoryFunc fptr,
1021 OUString const & rImplementationName,
1022 Sequence< OUString > const & rServiceNames,
1023 rtl_ModuleCount *)
1025 return new OFactoryComponentHelper(
1026 Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, true );
1032 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */