Bump version to 4.3-4
[LibreOffice.git] / cppuhelper / source / factory.cxx
blob460f11929d18865a39354e4fa6605469446bd990
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 virtual ~OSingleFactoryHelper();
85 // XInterface
86 Any SAL_CALL queryInterface( const Type & rType )
87 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
89 // XSingleServiceFactory
90 Reference<XInterface > SAL_CALL createInstance()
91 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
92 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
93 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
94 // XSingleComponentFactory
95 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
96 Reference< XComponentContext > const & xContext )
97 throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
98 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
99 Sequence< Any > const & rArguments,
100 Reference< XComponentContext > const & xContext )
101 throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
103 // XServiceInfo
104 OUString SAL_CALL getImplementationName()
105 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
106 sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
107 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
108 Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
109 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
111 protected:
113 * Create an instance specified by the factory. The one instance logic is implemented
114 * in the createInstance and createInstanceWithArguments methods.
115 * @return the newly created instance. Do not return a previous (one instance) instance.
117 virtual Reference<XInterface > createInstanceEveryTime(
118 Reference< XComponentContext > const & xContext )
119 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
121 Reference<XMultiServiceFactory > xSMgr;
122 ComponentInstantiation pCreateFunction;
123 ComponentFactoryFunc m_fptr;
124 Sequence< OUString > aServiceNames;
125 OUString aImplementationName;
127 OSingleFactoryHelper::~OSingleFactoryHelper()
133 Any OSingleFactoryHelper::queryInterface( const Type & rType )
134 throw(::com::sun::star::uno::RuntimeException, std::exception)
136 return ::cppu::queryInterface(
137 rType,
138 static_cast< XSingleComponentFactory * >( this ),
139 static_cast< XSingleServiceFactory * >( this ),
140 static_cast< XServiceInfo * >( this ) ,
141 static_cast< XUnloadingPreference * >( this ));
144 // OSingleFactoryHelper
145 Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime(
146 Reference< XComponentContext > const & xContext )
147 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
149 if (m_fptr)
151 return (*m_fptr)( xContext );
153 else if( pCreateFunction )
155 if (xContext.is())
157 Reference< lang::XMultiServiceFactory > xContextMgr(
158 xContext->getServiceManager(), UNO_QUERY );
159 if (xContextMgr.is())
160 return (*pCreateFunction)( xContextMgr );
162 return (*pCreateFunction)( xSMgr );
164 else
166 return Reference< XInterface >();
170 // XSingleServiceFactory
171 Reference<XInterface > OSingleFactoryHelper::createInstance()
172 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
174 return createInstanceWithContext( Reference< XComponentContext >() );
177 // XSingleServiceFactory
178 Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments(
179 const Sequence<Any>& Arguments )
180 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
182 return createInstanceWithArgumentsAndContext(
183 Arguments, Reference< XComponentContext >() );
186 // XSingleComponentFactory
188 Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext(
189 Reference< XComponentContext > const & xContext )
190 throw (Exception, RuntimeException, std::exception)
192 return createInstanceEveryTime( xContext );
195 Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext(
196 Sequence< Any > const & rArguments,
197 Reference< XComponentContext > const & xContext )
198 throw (Exception, RuntimeException, std::exception)
200 Reference< XInterface > xRet( createInstanceWithContext( xContext ) );
202 Reference< lang::XInitialization > xInit( xRet, UNO_QUERY );
203 // always call initialize, even if there are no arguments.
204 // #i63511# / 2006-03-27 / frank.schoenheit@sun.com
205 if (xInit.is())
207 xInit->initialize( rArguments );
209 else
211 if ( rArguments.getLength() )
213 // dispose the here created UNO object before throwing out exception
214 // to avoid risk of memory leaks #i113722#
215 Reference<XComponent> xComp( xRet, UNO_QUERY );
216 if (xComp.is())
217 xComp->dispose();
219 throw lang::IllegalArgumentException(
220 OUString("cannot pass arguments to component => no XInitialization implemented!"),
221 Reference< XInterface >(), 0 );
225 return xRet;
228 // XServiceInfo
229 OUString OSingleFactoryHelper::getImplementationName()
230 throw(::com::sun::star::uno::RuntimeException, std::exception)
232 return aImplementationName;
235 // XServiceInfo
236 sal_Bool OSingleFactoryHelper::supportsService(
237 const OUString& ServiceName )
238 throw(::com::sun::star::uno::RuntimeException, std::exception)
240 return cppu::supportsService(this, ServiceName);
243 // XServiceInfo
244 Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames(void)
245 throw(::com::sun::star::uno::RuntimeException, std::exception)
247 return aServiceNames;
250 struct OFactoryComponentHelper_Mutex
252 Mutex aMutex;
255 class OFactoryComponentHelper
256 : public OFactoryComponentHelper_Mutex
257 , public OComponentHelper
258 , public OSingleFactoryHelper
260 public:
261 OFactoryComponentHelper(
262 const Reference<XMultiServiceFactory > & rServiceManager,
263 const OUString & rImplementationName_,
264 ComponentInstantiation pCreateFunction_,
265 ComponentFactoryFunc fptr,
266 const Sequence< OUString > * pServiceNames_,
267 bool bOneInstance_ = false )
268 SAL_THROW(())
269 : OComponentHelper( aMutex )
270 , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ )
271 , bOneInstance( bOneInstance_ )
275 // XInterface
276 Any SAL_CALL queryInterface( const Type & rType )
277 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
278 void SAL_CALL acquire() throw() SAL_OVERRIDE
279 { OComponentHelper::acquire(); }
280 void SAL_CALL release() throw() SAL_OVERRIDE
281 { OComponentHelper::release(); }
283 // XSingleServiceFactory
284 Reference<XInterface > SAL_CALL createInstance()
285 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
286 Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments )
287 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
288 // XSingleComponentFactory
289 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
290 Reference< XComponentContext > const & xContext )
291 throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
292 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
293 Sequence< Any > const & rArguments,
294 Reference< XComponentContext > const & xContext )
295 throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
297 // XTypeProvider
298 virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
299 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
301 // XAggregation
302 Any SAL_CALL queryAggregation( const Type & rType )
303 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
305 // XUnloadingPreference
306 virtual sal_Bool SAL_CALL releaseOnNotification()
307 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
309 // OComponentHelper
310 void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
312 private:
313 Reference<XInterface > xTheInstance;
314 bool bOneInstance;
315 protected:
316 // needed for implementing XUnloadingPreference in inheriting classes
317 bool isOneInstance() {return bOneInstance;}
318 bool isInstance() {return xTheInstance.is();}
322 Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType )
323 throw(::com::sun::star::uno::RuntimeException, std::exception)
325 if( rType == ::getCppuType( (Reference<XUnloadingPreference>*)0))
327 return makeAny(
328 Reference< XUnloadingPreference >(
329 static_cast< XUnloadingPreference * >(this) ) );
331 return OComponentHelper::queryInterface( rType );
334 // XAggregation
335 Any OFactoryComponentHelper::queryAggregation( const Type & rType )
336 throw(::com::sun::star::uno::RuntimeException, std::exception)
338 Any aRet( OComponentHelper::queryAggregation( rType ) );
339 return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType ));
342 // XTypeProvider
343 Sequence< Type > OFactoryComponentHelper::getTypes()
344 throw (::com::sun::star::uno::RuntimeException, std::exception)
346 Type ar[ 4 ];
347 ar[ 0 ] = ::getCppuType( (const Reference< XSingleServiceFactory > *)0 );
348 ar[ 1 ] = ::getCppuType( (const Reference< XServiceInfo > *)0 );
349 ar[ 2 ] = ::getCppuType( (const Reference< XUnloadingPreference > *)0 );
351 if (m_fptr)
352 ar[ 3 ] = ::getCppuType( (const Reference< XSingleComponentFactory > *)0 );
354 return Sequence< Type >( ar, m_fptr ? 4 : 3 );
357 Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId()
358 throw (::com::sun::star::uno::RuntimeException, std::exception)
360 return css::uno::Sequence<sal_Int8>();
363 // XSingleServiceFactory
364 Reference<XInterface > OFactoryComponentHelper::createInstance()
365 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
367 if( bOneInstance )
369 if( !xTheInstance.is() )
371 MutexGuard aGuard( aMutex );
372 if( !xTheInstance.is() )
373 xTheInstance = OSingleFactoryHelper::createInstance();
375 return xTheInstance;
377 return OSingleFactoryHelper::createInstance();
380 Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments(
381 const Sequence<Any>& Arguments )
382 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
384 if( bOneInstance )
386 if( !xTheInstance.is() )
388 MutexGuard aGuard( aMutex );
389 // OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" );
390 if( !xTheInstance.is() )
391 xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments );
393 return xTheInstance;
395 return OSingleFactoryHelper::createInstanceWithArguments( Arguments );
398 // XSingleComponentFactory
400 Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext(
401 Reference< XComponentContext > const & xContext )
402 throw (Exception, RuntimeException, std::exception)
404 if( bOneInstance )
406 if( !xTheInstance.is() )
408 MutexGuard aGuard( aMutex );
409 // OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" );
410 if( !xTheInstance.is() )
411 xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext );
413 return xTheInstance;
415 return OSingleFactoryHelper::createInstanceWithContext( xContext );
418 Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext(
419 Sequence< Any > const & rArguments,
420 Reference< XComponentContext > const & xContext )
421 throw (Exception, RuntimeException, std::exception)
423 if( bOneInstance )
425 if( !xTheInstance.is() )
427 MutexGuard aGuard( aMutex );
428 // OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" );
429 if( !xTheInstance.is() )
430 xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
432 return xTheInstance;
434 return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
438 // OComponentHelper
439 void OFactoryComponentHelper::dispose()
440 throw(::com::sun::star::uno::RuntimeException, std::exception)
442 OComponentHelper::dispose();
444 Reference<XInterface > x;
446 // do not delete in the guard section
447 MutexGuard aGuard( aMutex );
448 x = xTheInstance;
449 xTheInstance.clear();
451 // if it is a component call dispose at the component
452 Reference<XComponent > xComp( x, UNO_QUERY );
453 if( xComp.is() )
454 xComp->dispose();
457 // XUnloadingPreference
458 // This class is used for single factories, component factories and
459 // one-instance factories. Depending on the usage this function has
460 // to return different values.
461 // one-instance factory: sal_False
462 // single factory: sal_True
463 // component factory: sal_True
464 sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException, std::exception)
466 if( bOneInstance)
467 return sal_False;
468 return sal_True;
471 class ORegistryFactoryHelper : public OFactoryComponentHelper,
472 public OPropertySetHelper
475 public:
476 ORegistryFactoryHelper(
477 const Reference<XMultiServiceFactory > & rServiceManager,
478 const OUString & rImplementationName_,
479 const Reference<XRegistryKey > & xImplementationKey_,
480 bool bOneInstance_ = false ) SAL_THROW(())
481 : OFactoryComponentHelper(
482 rServiceManager, rImplementationName_, 0, 0, 0, bOneInstance_ ),
483 OPropertySetHelper( OComponentHelper::rBHelper ),
484 xImplementationKey( xImplementationKey_ )
487 // XInterface
488 virtual Any SAL_CALL queryInterface( Type const & type )
489 throw (RuntimeException, std::exception) SAL_OVERRIDE;
490 virtual void SAL_CALL acquire() throw () SAL_OVERRIDE;
491 virtual void SAL_CALL release() throw () SAL_OVERRIDE;
492 // XTypeProvider
493 virtual Sequence< Type > SAL_CALL getTypes()
494 throw (RuntimeException, std::exception) SAL_OVERRIDE;
495 // XPropertySet
496 virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo()
497 throw (RuntimeException, std::exception) SAL_OVERRIDE;
499 // OPropertySetHelper
500 virtual IPropertyArrayHelper & SAL_CALL getInfoHelper() SAL_OVERRIDE;
501 virtual sal_Bool SAL_CALL convertFastPropertyValue(
502 Any & rConvertedValue, Any & rOldValue,
503 sal_Int32 nHandle, Any const & rValue )
504 throw (lang::IllegalArgumentException) SAL_OVERRIDE;
505 virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
506 sal_Int32 nHandle, Any const & rValue )
507 throw (Exception, std::exception) SAL_OVERRIDE;
508 using OPropertySetHelper::getFastPropertyValue;
509 virtual void SAL_CALL getFastPropertyValue(
510 Any & rValue, sal_Int32 nHandle ) const SAL_OVERRIDE;
512 // OSingleFactoryHelper
513 Reference<XInterface > createInstanceEveryTime(
514 Reference< XComponentContext > const & xContext )
515 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) SAL_OVERRIDE;
517 // XSingleServiceFactory
518 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
519 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
520 // XSingleComponentFactory
521 Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
522 Sequence< Any > const & rArguments,
523 Reference< XComponentContext > const & xContext )
524 throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
526 // XServiceInfo
527 Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
528 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
529 // XUnloadingPreference
530 sal_Bool SAL_CALL releaseOnNotification()
531 throw( RuntimeException, std::exception) SAL_OVERRIDE;
534 private:
535 Reference< XInterface > createModuleFactory()
536 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
538 /** The registry key of the implementation section */
539 Reference<XRegistryKey > xImplementationKey;
540 /** The factory created with the loader. */
541 Reference<XSingleComponentFactory > xModuleFactory;
542 Reference<XSingleServiceFactory > xModuleFactoryDepr;
543 Reference< beans::XPropertySetInfo > m_xInfo;
544 ::std::auto_ptr< IPropertyArrayHelper > m_property_array_helper;
545 protected:
546 using OPropertySetHelper::getTypes;
549 // XInterface
551 Any SAL_CALL ORegistryFactoryHelper::queryInterface(
552 Type const & type ) throw (RuntimeException, std::exception)
554 Any ret( OFactoryComponentHelper::queryInterface( type ) );
555 if (ret.hasValue())
556 return ret;
557 else
558 return OPropertySetHelper::queryInterface( type );
562 void ORegistryFactoryHelper::acquire() throw ()
564 OFactoryComponentHelper::acquire();
568 void ORegistryFactoryHelper::release() throw ()
570 OFactoryComponentHelper::release();
573 // XTypeProvider
575 Sequence< Type > ORegistryFactoryHelper::getTypes() throw (RuntimeException, std::exception)
577 Sequence< Type > types( OFactoryComponentHelper::getTypes() );
578 sal_Int32 pos = types.getLength();
579 types.realloc( pos + 3 );
580 Type * p = types.getArray();
581 p[ pos++ ] = ::getCppuType(
582 reinterpret_cast< Reference< beans::XMultiPropertySet > const * >(0) );
583 p[ pos++ ] = ::getCppuType(
584 reinterpret_cast< Reference< beans::XFastPropertySet > const * >(0) );
585 p[ pos++ ] = ::getCppuType(
586 reinterpret_cast< Reference< beans::XPropertySet > const * >(0) );
587 return types;
590 // XPropertySet
592 Reference< beans::XPropertySetInfo >
593 ORegistryFactoryHelper::getPropertySetInfo() throw (RuntimeException, std::exception)
595 ::osl::MutexGuard guard( aMutex );
596 if (! m_xInfo.is())
597 m_xInfo = createPropertySetInfo( getInfoHelper() );
598 return m_xInfo;
601 // OPropertySetHelper
603 IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper()
605 ::osl::MutexGuard guard( aMutex );
606 if (m_property_array_helper.get() == 0)
608 beans::Property prop(
609 "ImplementationKey" /* name */,
610 0 /* handle */,
611 ::getCppuType( &xImplementationKey ),
612 beans::PropertyAttribute::READONLY |
613 beans::PropertyAttribute::OPTIONAL );
614 m_property_array_helper.reset(
615 new ::cppu::OPropertyArrayHelper( &prop, 1 ) );
617 return *m_property_array_helper.get();
621 sal_Bool ORegistryFactoryHelper::convertFastPropertyValue(
622 Any &, Any &, sal_Int32, Any const & )
623 throw (lang::IllegalArgumentException)
625 OSL_FAIL( "unexpected!" );
626 return false;
630 void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast(
631 sal_Int32, Any const & )
632 throw (Exception, std::exception)
634 throw beans::PropertyVetoException(
635 "unexpected: only readonly properties!",
636 static_cast< OWeakObject * >(this) );
640 void ORegistryFactoryHelper::getFastPropertyValue(
641 Any & rValue, sal_Int32 nHandle ) const
643 if (nHandle == 0)
645 rValue <<= xImplementationKey;
647 else
649 rValue.clear();
650 throw beans::UnknownPropertyException(
651 "unknown property!", static_cast< OWeakObject * >(
652 const_cast< ORegistryFactoryHelper * >(this) ) );
656 Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime(
657 Reference< XComponentContext > const & xContext )
658 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
660 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
662 Reference< XInterface > x( createModuleFactory() );
663 if (x.is())
665 MutexGuard aGuard( aMutex );
666 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
668 xModuleFactory.set( x, UNO_QUERY );
669 xModuleFactoryDepr.set( x, UNO_QUERY );
673 if( xModuleFactory.is() )
675 return xModuleFactory->createInstanceWithContext( xContext );
677 else if( xModuleFactoryDepr.is() )
679 return xModuleFactoryDepr->createInstance();
682 return Reference<XInterface >();
685 Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments(
686 const Sequence<Any>& Arguments )
687 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
689 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
691 Reference< XInterface > x( createModuleFactory() );
692 if (x.is())
694 MutexGuard aGuard( aMutex );
695 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
697 xModuleFactory.set( x, UNO_QUERY );
698 xModuleFactoryDepr.set( x, UNO_QUERY );
702 if( xModuleFactoryDepr.is() )
704 return xModuleFactoryDepr->createInstanceWithArguments( Arguments );
706 else if( xModuleFactory.is() )
708 #if OSL_DEBUG_LEVEL > 1
709 OSL_TRACE( "### no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!" );
710 #endif
711 return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() );
714 return Reference<XInterface >();
717 Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext(
718 Sequence< Any > const & rArguments,
719 Reference< XComponentContext > const & xContext )
720 throw (Exception, RuntimeException, std::exception)
722 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
724 Reference< XInterface > x( createModuleFactory() );
725 if (x.is())
727 MutexGuard aGuard( aMutex );
728 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
730 xModuleFactory.set( x, UNO_QUERY );
731 xModuleFactoryDepr.set( x, UNO_QUERY );
735 if( xModuleFactory.is() )
737 return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext );
739 else if( xModuleFactoryDepr.is() )
741 #if OSL_DEBUG_LEVEL > 1
742 if (xContext.is())
744 OSL_TRACE( "### ignoring context calling ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!" );
746 #endif
747 return xModuleFactoryDepr->createInstanceWithArguments( rArguments );
750 return Reference<XInterface >();
754 // OSingleFactoryHelper
755 Reference< XInterface > ORegistryFactoryHelper::createModuleFactory()
756 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
758 OUString aActivatorUrl;
759 OUString aActivatorName;
760 OUString aLocation;
762 Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey(
763 OUString("/UNO/ACTIVATOR") );
764 if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII )
766 aActivatorUrl = xActivatorKey->getAsciiValue();
768 OUString tmpActivator(aActivatorUrl.getStr());
769 sal_Int32 nIndex = 0;
770 aActivatorName = tmpActivator.getToken(0, ':', nIndex );
772 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
773 OUString("/UNO/LOCATION") );
774 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
775 aLocation = xLocationKey->getAsciiValue();
777 else
779 // old style"url"
780 // the location of the program code of the implementation
781 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
782 OUString("/UNO/URL") );
783 // is the key of the right type ?
784 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
786 // one implementation found -> try to activate
787 aLocation = xLocationKey->getAsciiValue();
789 // search protocol delimiter
790 sal_Int32 nPos = aLocation.indexOf(
791 OUString("://") );
792 if( nPos != -1 )
794 aActivatorName = aLocation.copy( 0, nPos );
795 if( aActivatorName.equalsAscii( "java" ) )
796 aActivatorName = "com.sun.star.loader.Java";
797 else if( aActivatorName.equalsAscii( "module" ) )
798 aActivatorName = "com.sun.star.loader.SharedLibrary";
799 aLocation = aLocation.copy( nPos + 3 );
804 Reference< XInterface > xFactory;
805 if( !aActivatorName.isEmpty() )
807 Reference<XInterface > x = xSMgr->createInstance( aActivatorName );
808 Reference<XImplementationLoader > xLoader( x, UNO_QUERY );
809 Reference<XInterface > xMF;
810 if (xLoader.is())
812 xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey );
815 return xFactory;
818 // XServiceInfo
819 Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames(void)
820 throw(::com::sun::star::uno::RuntimeException, std::exception)
822 MutexGuard aGuard( aMutex );
823 if( aServiceNames.getLength() == 0 )
825 // not yet loaded
828 Reference<XRegistryKey > xKey = xImplementationKey->openKey(
829 OUString("UNO/SERVICES") );
831 if (xKey.is())
833 // length of prefix. +1 for the '/' at the end
834 sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1;
836 // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..."
837 Sequence<OUString> seqKeys = xKey->getKeyNames();
838 OUString* pKeys = seqKeys.getArray();
839 for( sal_Int32 i = 0; i < seqKeys.getLength(); i++ )
840 pKeys[i] = pKeys[i].copy(nPrefixLen);
842 aServiceNames = seqKeys;
845 catch (InvalidRegistryException &)
849 return aServiceNames;
852 sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException, std::exception)
854 bool retVal= true;
855 if( isOneInstance() && isInstance())
857 retVal= false;
859 else if( ! isOneInstance())
861 // try to delegate
862 if( xModuleFactory.is())
864 Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY);
865 if( xunloading.is())
866 retVal= xunloading->releaseOnNotification();
868 else if( xModuleFactoryDepr.is())
870 Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY);
871 if( xunloading.is())
872 retVal= xunloading->releaseOnNotification();
875 return retVal;
878 class OFactoryProxyHelper : public WeakImplHelper3< XServiceInfo, XSingleServiceFactory,
879 XUnloadingPreference >
881 Reference<XSingleServiceFactory > xFactory;
883 public:
885 OFactoryProxyHelper( const Reference<XSingleServiceFactory > & rFactory )
886 SAL_THROW(())
887 : xFactory( rFactory )
890 // XSingleServiceFactory
891 Reference<XInterface > SAL_CALL createInstance()
892 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
893 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
894 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
896 // XServiceInfo
897 OUString SAL_CALL getImplementationName()
898 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
899 sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
900 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
901 Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
902 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
903 //XUnloadingPreference
904 sal_Bool SAL_CALL releaseOnNotification()
905 throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
909 // XSingleServiceFactory
910 Reference<XInterface > OFactoryProxyHelper::createInstance()
911 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
913 return xFactory->createInstance();
916 // XSingleServiceFactory
917 Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments
919 const Sequence<Any>& Arguments
921 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
923 return xFactory->createInstanceWithArguments( Arguments );
926 // XServiceInfo
927 OUString OFactoryProxyHelper::getImplementationName()
928 throw(::com::sun::star::uno::RuntimeException, std::exception)
930 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
931 if( xInfo.is() )
932 return xInfo->getImplementationName();
933 return OUString();
936 // XServiceInfo
937 sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName)
938 throw(::com::sun::star::uno::RuntimeException, std::exception)
940 return cppu::supportsService(this, ServiceName);
943 // XServiceInfo
944 Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames(void)
945 throw(::com::sun::star::uno::RuntimeException, std::exception)
947 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
948 if( xInfo.is() )
949 return xInfo->getSupportedServiceNames();
950 return Sequence< OUString >();
953 sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException, std::exception)
956 Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY);
957 if( pref.is())
958 return pref->releaseOnNotification();
959 return sal_True;
962 // global function
963 Reference<XSingleServiceFactory > SAL_CALL createSingleFactory(
964 const Reference<XMultiServiceFactory > & rServiceManager,
965 const OUString & rImplementationName,
966 ComponentInstantiation pCreateFunction,
967 const Sequence< OUString > & rServiceNames,
968 rtl_ModuleCount * )
969 SAL_THROW(())
971 return new OFactoryComponentHelper(
972 rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, false );
975 // global function
976 Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy(
977 SAL_UNUSED_PARAMETER const Reference<XMultiServiceFactory > &,
978 const Reference<XSingleServiceFactory > & rFactory )
979 SAL_THROW(())
981 return new OFactoryProxyHelper( rFactory );
984 // global function
985 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory(
986 const Reference<XMultiServiceFactory > & rServiceManager,
987 const OUString & rImplementationName,
988 ComponentInstantiation pCreateFunction,
989 const Sequence< OUString > & rServiceNames,
990 rtl_ModuleCount * )
991 SAL_THROW(())
993 return new OFactoryComponentHelper(
994 rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, true );
997 // global function
998 Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(
999 const Reference<XMultiServiceFactory > & rServiceManager,
1000 const OUString & rImplementationName,
1001 const Reference<XRegistryKey > & rImplementationKey )
1002 SAL_THROW(())
1004 return new ORegistryFactoryHelper(
1005 rServiceManager, rImplementationName, rImplementationKey, false );
1008 // global function
1009 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory(
1010 const Reference<XMultiServiceFactory > & rServiceManager,
1011 const OUString & rImplementationName,
1012 const Reference<XRegistryKey > & rImplementationKey )
1013 SAL_THROW(())
1015 return new ORegistryFactoryHelper(
1016 rServiceManager, rImplementationName, rImplementationKey, true );
1020 Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory(
1021 ComponentFactoryFunc fptr,
1022 OUString const & rImplementationName,
1023 Sequence< OUString > const & rServiceNames,
1024 rtl_ModuleCount *)
1025 SAL_THROW(())
1027 return new OFactoryComponentHelper(
1028 Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, false );
1031 Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory(
1032 ComponentFactoryFunc fptr,
1033 OUString const & rImplementationName,
1034 Sequence< OUString > const & rServiceNames,
1035 rtl_ModuleCount *)
1036 SAL_THROW(())
1038 return new OFactoryComponentHelper(
1039 Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, true );
1045 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */