Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <osl/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>
32 :
33 : #include "cppuhelper/propshlp.hxx"
34 :
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"
44 :
45 : #include <memory>
46 :
47 :
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;
54 :
55 : using ::rtl::OUString;
56 :
57 : namespace cppu
58 : {
59 :
60 : class OSingleFactoryHelper
61 : : public XServiceInfo
62 : , public XSingleServiceFactory
63 : , public lang::XSingleComponentFactory
64 : , public XUnloadingPreference
65 : {
66 : public:
67 5 : 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 5 : , aImplementationName( rImplementationName_ )
78 : {
79 5 : if( pServiceNames_ )
80 5 : aServiceNames = *pServiceNames_;
81 5 : }
82 :
83 : virtual ~OSingleFactoryHelper();
84 :
85 : // XInterface
86 : Any SAL_CALL queryInterface( const Type & rType )
87 : throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
88 :
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;
102 :
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;
110 :
111 : protected:
112 : /**
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.
116 : */
117 : virtual Reference<XInterface > createInstanceEveryTime(
118 : Reference< XComponentContext > const & xContext )
119 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
120 :
121 : Reference<XMultiServiceFactory > xSMgr;
122 : ComponentInstantiation pCreateFunction;
123 : ComponentFactoryFunc m_fptr;
124 : Sequence< OUString > aServiceNames;
125 : OUString aImplementationName;
126 : };
127 5 : OSingleFactoryHelper::~OSingleFactoryHelper()
128 : {
129 5 : }
130 :
131 :
132 :
133 4 : Any OSingleFactoryHelper::queryInterface( const Type & rType )
134 : throw(::com::sun::star::uno::RuntimeException, std::exception)
135 : {
136 : return ::cppu::queryInterface(
137 : rType,
138 : static_cast< XSingleComponentFactory * >( this ),
139 : static_cast< XSingleServiceFactory * >( this ),
140 : static_cast< XServiceInfo * >( this ) ,
141 4 : static_cast< XUnloadingPreference * >( this ));
142 : }
143 :
144 : // OSingleFactoryHelper
145 5 : Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime(
146 : Reference< XComponentContext > const & xContext )
147 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
148 : {
149 5 : if (m_fptr)
150 : {
151 5 : return (*m_fptr)( xContext );
152 : }
153 0 : else if( pCreateFunction )
154 : {
155 0 : if (xContext.is())
156 : {
157 : Reference< lang::XMultiServiceFactory > xContextMgr(
158 0 : xContext->getServiceManager(), UNO_QUERY );
159 0 : if (xContextMgr.is())
160 0 : return (*pCreateFunction)( xContextMgr );
161 : }
162 0 : return (*pCreateFunction)( xSMgr );
163 : }
164 : else
165 : {
166 0 : return Reference< XInterface >();
167 : }
168 : }
169 :
170 : // XSingleServiceFactory
171 0 : Reference<XInterface > OSingleFactoryHelper::createInstance()
172 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
173 : {
174 0 : return createInstanceWithContext( Reference< XComponentContext >() );
175 : }
176 :
177 : // XSingleServiceFactory
178 0 : Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments(
179 : const Sequence<Any>& Arguments )
180 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
181 : {
182 : return createInstanceWithArgumentsAndContext(
183 0 : Arguments, Reference< XComponentContext >() );
184 : }
185 :
186 : // XSingleComponentFactory
187 :
188 5 : Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext(
189 : Reference< XComponentContext > const & xContext )
190 : throw (Exception, RuntimeException, std::exception)
191 : {
192 5 : return createInstanceEveryTime( xContext );
193 : }
194 :
195 3 : Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext(
196 : Sequence< Any > const & rArguments,
197 : Reference< XComponentContext > const & xContext )
198 : throw (Exception, RuntimeException, std::exception)
199 : {
200 3 : Reference< XInterface > xRet( createInstanceWithContext( xContext ) );
201 :
202 6 : 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 3 : if (xInit.is())
206 : {
207 3 : xInit->initialize( rArguments );
208 : }
209 : else
210 : {
211 0 : if ( rArguments.getLength() )
212 : {
213 : // dispose the here created UNO object before throwing out exception
214 : // to avoid risk of memory leaks #i113722#
215 0 : Reference<XComponent> xComp( xRet, UNO_QUERY );
216 0 : if (xComp.is())
217 0 : xComp->dispose();
218 :
219 : throw lang::IllegalArgumentException(
220 : OUString("cannot pass arguments to component => no XInitialization implemented!"),
221 0 : Reference< XInterface >(), 0 );
222 : }
223 : }
224 :
225 6 : return xRet;
226 : }
227 :
228 : // XServiceInfo
229 0 : OUString OSingleFactoryHelper::getImplementationName()
230 : throw(::com::sun::star::uno::RuntimeException, std::exception)
231 : {
232 0 : return aImplementationName;
233 : }
234 :
235 : // XServiceInfo
236 0 : sal_Bool OSingleFactoryHelper::supportsService(
237 : const OUString& ServiceName )
238 : throw(::com::sun::star::uno::RuntimeException, std::exception)
239 : {
240 0 : return cppu::supportsService(this, ServiceName);
241 : }
242 :
243 : // XServiceInfo
244 0 : Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames(void)
245 : throw(::com::sun::star::uno::RuntimeException, std::exception)
246 : {
247 0 : return aServiceNames;
248 : }
249 :
250 10 : struct OFactoryComponentHelper_Mutex
251 : {
252 : Mutex aMutex;
253 : };
254 :
255 10 : class OFactoryComponentHelper
256 : : public OFactoryComponentHelper_Mutex
257 : , public OComponentHelper
258 : , public OSingleFactoryHelper
259 : {
260 : public:
261 5 : 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 5 : , bOneInstance( bOneInstance_ )
272 : {
273 5 : }
274 :
275 : // XInterface
276 : Any SAL_CALL queryInterface( const Type & rType )
277 : throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
278 60 : void SAL_CALL acquire() throw() SAL_OVERRIDE
279 60 : { OComponentHelper::acquire(); }
280 60 : void SAL_CALL release() throw() SAL_OVERRIDE
281 60 : { OComponentHelper::release(); }
282 :
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;
296 :
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;
300 :
301 : // XAggregation
302 : Any SAL_CALL queryAggregation( const Type & rType )
303 : throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
304 :
305 : // XUnloadingPreference
306 : virtual sal_Bool SAL_CALL releaseOnNotification()
307 : throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
308 :
309 : // OComponentHelper
310 : void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
311 :
312 : private:
313 : Reference<XInterface > xTheInstance;
314 : bool bOneInstance;
315 : protected:
316 : // needed for implementing XUnloadingPreference in inheriting classes
317 0 : bool isOneInstance() {return bOneInstance;}
318 0 : bool isInstance() {return xTheInstance.is();}
319 : };
320 :
321 :
322 10 : Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType )
323 : throw(::com::sun::star::uno::RuntimeException, std::exception)
324 : {
325 10 : if( rType == ::getCppuType( (Reference<XUnloadingPreference>*)0))
326 : {
327 : return makeAny(
328 : Reference< XUnloadingPreference >(
329 0 : static_cast< XUnloadingPreference * >(this) ) );
330 : }
331 10 : return OComponentHelper::queryInterface( rType );
332 : }
333 :
334 : // XAggregation
335 10 : Any OFactoryComponentHelper::queryAggregation( const Type & rType )
336 : throw(::com::sun::star::uno::RuntimeException, std::exception)
337 : {
338 10 : Any aRet( OComponentHelper::queryAggregation( rType ) );
339 10 : return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType ));
340 : }
341 :
342 : // XTypeProvider
343 0 : Sequence< Type > OFactoryComponentHelper::getTypes()
344 : throw (::com::sun::star::uno::RuntimeException, std::exception)
345 : {
346 0 : Type ar[ 4 ];
347 0 : ar[ 0 ] = ::getCppuType( (const Reference< XSingleServiceFactory > *)0 );
348 0 : ar[ 1 ] = ::getCppuType( (const Reference< XServiceInfo > *)0 );
349 0 : ar[ 2 ] = ::getCppuType( (const Reference< XUnloadingPreference > *)0 );
350 :
351 0 : if (m_fptr)
352 0 : ar[ 3 ] = ::getCppuType( (const Reference< XSingleComponentFactory > *)0 );
353 :
354 0 : return Sequence< Type >( ar, m_fptr ? 4 : 3 );
355 : }
356 :
357 0 : Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId()
358 : throw (::com::sun::star::uno::RuntimeException, std::exception)
359 : {
360 0 : return css::uno::Sequence<sal_Int8>();
361 : }
362 :
363 : // XSingleServiceFactory
364 0 : Reference<XInterface > OFactoryComponentHelper::createInstance()
365 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
366 : {
367 0 : if( bOneInstance )
368 : {
369 0 : if( !xTheInstance.is() )
370 : {
371 0 : MutexGuard aGuard( aMutex );
372 0 : if( !xTheInstance.is() )
373 0 : xTheInstance = OSingleFactoryHelper::createInstance();
374 : }
375 0 : return xTheInstance;
376 : }
377 0 : return OSingleFactoryHelper::createInstance();
378 : }
379 :
380 0 : Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments(
381 : const Sequence<Any>& Arguments )
382 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
383 : {
384 0 : if( bOneInstance )
385 : {
386 0 : if( !xTheInstance.is() )
387 : {
388 0 : MutexGuard aGuard( aMutex );
389 : // OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" );
390 0 : if( !xTheInstance.is() )
391 0 : xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments );
392 : }
393 0 : return xTheInstance;
394 : }
395 0 : return OSingleFactoryHelper::createInstanceWithArguments( Arguments );
396 : }
397 :
398 : // XSingleComponentFactory
399 :
400 5 : Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext(
401 : Reference< XComponentContext > const & xContext )
402 : throw (Exception, RuntimeException, std::exception)
403 : {
404 5 : if( bOneInstance )
405 : {
406 0 : if( !xTheInstance.is() )
407 : {
408 0 : MutexGuard aGuard( aMutex );
409 : // OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" );
410 0 : if( !xTheInstance.is() )
411 0 : xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext );
412 : }
413 0 : return xTheInstance;
414 : }
415 5 : return OSingleFactoryHelper::createInstanceWithContext( xContext );
416 : }
417 :
418 3 : Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext(
419 : Sequence< Any > const & rArguments,
420 : Reference< XComponentContext > const & xContext )
421 : throw (Exception, RuntimeException, std::exception)
422 : {
423 3 : if( bOneInstance )
424 : {
425 0 : if( !xTheInstance.is() )
426 : {
427 0 : MutexGuard aGuard( aMutex );
428 : // OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" );
429 0 : if( !xTheInstance.is() )
430 0 : xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
431 : }
432 0 : return xTheInstance;
433 : }
434 3 : return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
435 : }
436 :
437 :
438 : // OComponentHelper
439 5 : void OFactoryComponentHelper::dispose()
440 : throw(::com::sun::star::uno::RuntimeException, std::exception)
441 : {
442 5 : OComponentHelper::dispose();
443 :
444 5 : Reference<XInterface > x;
445 : {
446 : // do not delete in the guard section
447 5 : MutexGuard aGuard( aMutex );
448 5 : x = xTheInstance;
449 5 : xTheInstance.clear();
450 : }
451 : // if it is a component call dispose at the component
452 10 : Reference<XComponent > xComp( x, UNO_QUERY );
453 5 : if( xComp.is() )
454 5 : xComp->dispose();
455 5 : }
456 :
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 0 : sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException, std::exception)
465 : {
466 0 : if( bOneInstance)
467 0 : return sal_False;
468 0 : return sal_True;
469 : }
470 :
471 0 : class ORegistryFactoryHelper : public OFactoryComponentHelper,
472 : public OPropertySetHelper
473 :
474 : {
475 : public:
476 0 : 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 0 : xImplementationKey( xImplementationKey_ )
485 0 : {}
486 :
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;
498 :
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;
511 :
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;
516 :
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;
525 :
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;
532 :
533 :
534 : private:
535 : Reference< XInterface > createModuleFactory()
536 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
537 :
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;
547 : };
548 :
549 : // XInterface
550 :
551 0 : Any SAL_CALL ORegistryFactoryHelper::queryInterface(
552 : Type const & type ) throw (RuntimeException, std::exception)
553 : {
554 0 : Any ret( OFactoryComponentHelper::queryInterface( type ) );
555 0 : if (ret.hasValue())
556 0 : return ret;
557 : else
558 0 : return OPropertySetHelper::queryInterface( type );
559 : }
560 :
561 :
562 0 : void ORegistryFactoryHelper::acquire() throw ()
563 : {
564 0 : OFactoryComponentHelper::acquire();
565 0 : }
566 :
567 :
568 0 : void ORegistryFactoryHelper::release() throw ()
569 : {
570 0 : OFactoryComponentHelper::release();
571 0 : }
572 :
573 : // XTypeProvider
574 :
575 0 : Sequence< Type > ORegistryFactoryHelper::getTypes() throw (RuntimeException, std::exception)
576 : {
577 0 : Sequence< Type > types( OFactoryComponentHelper::getTypes() );
578 0 : sal_Int32 pos = types.getLength();
579 0 : types.realloc( pos + 3 );
580 0 : Type * p = types.getArray();
581 0 : p[ pos++ ] = ::getCppuType(
582 0 : reinterpret_cast< Reference< beans::XMultiPropertySet > const * >(0) );
583 0 : p[ pos++ ] = ::getCppuType(
584 0 : reinterpret_cast< Reference< beans::XFastPropertySet > const * >(0) );
585 0 : p[ pos++ ] = ::getCppuType(
586 0 : reinterpret_cast< Reference< beans::XPropertySet > const * >(0) );
587 0 : return types;
588 : }
589 :
590 : // XPropertySet
591 :
592 : Reference< beans::XPropertySetInfo >
593 0 : ORegistryFactoryHelper::getPropertySetInfo() throw (RuntimeException, std::exception)
594 : {
595 0 : ::osl::MutexGuard guard( aMutex );
596 0 : if (! m_xInfo.is())
597 0 : m_xInfo = createPropertySetInfo( getInfoHelper() );
598 0 : return m_xInfo;
599 : }
600 :
601 : // OPropertySetHelper
602 :
603 0 : IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper()
604 : {
605 0 : ::osl::MutexGuard guard( aMutex );
606 0 : if (m_property_array_helper.get() == 0)
607 : {
608 : beans::Property prop(
609 : "ImplementationKey" /* name */,
610 : 0 /* handle */,
611 0 : ::getCppuType( &xImplementationKey ),
612 : beans::PropertyAttribute::READONLY |
613 0 : beans::PropertyAttribute::OPTIONAL );
614 : m_property_array_helper.reset(
615 0 : new ::cppu::OPropertyArrayHelper( &prop, 1 ) );
616 : }
617 0 : return *m_property_array_helper.get();
618 : }
619 :
620 :
621 0 : sal_Bool ORegistryFactoryHelper::convertFastPropertyValue(
622 : Any &, Any &, sal_Int32, Any const & )
623 : throw (lang::IllegalArgumentException)
624 : {
625 : OSL_FAIL( "unexpected!" );
626 0 : return false;
627 : }
628 :
629 :
630 0 : void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast(
631 : sal_Int32, Any const & )
632 : throw (Exception, std::exception)
633 : {
634 : throw beans::PropertyVetoException(
635 : "unexpected: only readonly properties!",
636 0 : static_cast< OWeakObject * >(this) );
637 : }
638 :
639 :
640 0 : void ORegistryFactoryHelper::getFastPropertyValue(
641 : Any & rValue, sal_Int32 nHandle ) const
642 : {
643 0 : if (nHandle == 0)
644 : {
645 0 : rValue <<= xImplementationKey;
646 : }
647 : else
648 : {
649 0 : rValue.clear();
650 : throw beans::UnknownPropertyException(
651 : "unknown property!", static_cast< OWeakObject * >(
652 0 : const_cast< ORegistryFactoryHelper * >(this) ) );
653 : }
654 0 : }
655 :
656 0 : Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime(
657 : Reference< XComponentContext > const & xContext )
658 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
659 : {
660 0 : if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
661 : {
662 0 : Reference< XInterface > x( createModuleFactory() );
663 0 : if (x.is())
664 : {
665 0 : MutexGuard aGuard( aMutex );
666 0 : if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
667 : {
668 0 : xModuleFactory.set( x, UNO_QUERY );
669 0 : xModuleFactoryDepr.set( x, UNO_QUERY );
670 0 : }
671 0 : }
672 : }
673 0 : if( xModuleFactory.is() )
674 : {
675 0 : return xModuleFactory->createInstanceWithContext( xContext );
676 : }
677 0 : else if( xModuleFactoryDepr.is() )
678 : {
679 0 : return xModuleFactoryDepr->createInstance();
680 : }
681 :
682 0 : return Reference<XInterface >();
683 : }
684 :
685 0 : 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)
688 : {
689 0 : if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
690 : {
691 0 : Reference< XInterface > x( createModuleFactory() );
692 0 : if (x.is())
693 : {
694 0 : MutexGuard aGuard( aMutex );
695 0 : if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
696 : {
697 0 : xModuleFactory.set( x, UNO_QUERY );
698 0 : xModuleFactoryDepr.set( x, UNO_QUERY );
699 0 : }
700 0 : }
701 : }
702 0 : if( xModuleFactoryDepr.is() )
703 : {
704 0 : return xModuleFactoryDepr->createInstanceWithArguments( Arguments );
705 : }
706 0 : else if( xModuleFactory.is() )
707 : {
708 : #if OSL_DEBUG_LEVEL > 1
709 : OSL_TRACE( "### no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!" );
710 : #endif
711 0 : return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() );
712 : }
713 :
714 0 : return Reference<XInterface >();
715 : }
716 :
717 0 : Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext(
718 : Sequence< Any > const & rArguments,
719 : Reference< XComponentContext > const & xContext )
720 : throw (Exception, RuntimeException, std::exception)
721 : {
722 0 : if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
723 : {
724 0 : Reference< XInterface > x( createModuleFactory() );
725 0 : if (x.is())
726 : {
727 0 : MutexGuard aGuard( aMutex );
728 0 : if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
729 : {
730 0 : xModuleFactory.set( x, UNO_QUERY );
731 0 : xModuleFactoryDepr.set( x, UNO_QUERY );
732 0 : }
733 0 : }
734 : }
735 0 : if( xModuleFactory.is() )
736 : {
737 0 : return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext );
738 : }
739 0 : else if( xModuleFactoryDepr.is() )
740 : {
741 : #if OSL_DEBUG_LEVEL > 1
742 : if (xContext.is())
743 : {
744 : OSL_TRACE( "### ignoring context calling ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!" );
745 : }
746 : #endif
747 0 : return xModuleFactoryDepr->createInstanceWithArguments( rArguments );
748 : }
749 :
750 0 : return Reference<XInterface >();
751 : }
752 :
753 :
754 : // OSingleFactoryHelper
755 0 : Reference< XInterface > ORegistryFactoryHelper::createModuleFactory()
756 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
757 : {
758 0 : OUString aActivatorUrl;
759 0 : OUString aActivatorName;
760 0 : OUString aLocation;
761 :
762 0 : Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey(
763 0 : OUString("/UNO/ACTIVATOR") );
764 0 : if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII )
765 : {
766 0 : aActivatorUrl = xActivatorKey->getAsciiValue();
767 :
768 0 : OUString tmpActivator(aActivatorUrl.getStr());
769 0 : sal_Int32 nIndex = 0;
770 0 : aActivatorName = tmpActivator.getToken(0, ':', nIndex );
771 :
772 0 : Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
773 0 : OUString("/UNO/LOCATION") );
774 0 : if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
775 0 : aLocation = xLocationKey->getAsciiValue();
776 : }
777 : else
778 : {
779 : // old style"url"
780 : // the location of the program code of the implementation
781 0 : Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
782 0 : OUString("/UNO/URL") );
783 : // is the key of the right type ?
784 0 : if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
785 : {
786 : // one implementation found -> try to activate
787 0 : aLocation = xLocationKey->getAsciiValue();
788 :
789 : // search protocol delimiter
790 : sal_Int32 nPos = aLocation.indexOf(
791 0 : OUString("://") );
792 0 : if( nPos != -1 )
793 : {
794 0 : aActivatorName = aLocation.copy( 0, nPos );
795 0 : if( aActivatorName.equalsAscii( "java" ) )
796 0 : aActivatorName = "com.sun.star.loader.Java";
797 0 : else if( aActivatorName.equalsAscii( "module" ) )
798 0 : aActivatorName = "com.sun.star.loader.SharedLibrary";
799 0 : aLocation = aLocation.copy( nPos + 3 );
800 : }
801 0 : }
802 : }
803 :
804 0 : Reference< XInterface > xFactory;
805 0 : if( !aActivatorName.isEmpty() )
806 : {
807 0 : Reference<XInterface > x = xSMgr->createInstance( aActivatorName );
808 0 : Reference<XImplementationLoader > xLoader( x, UNO_QUERY );
809 0 : Reference<XInterface > xMF;
810 0 : if (xLoader.is())
811 : {
812 0 : xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey );
813 0 : }
814 : }
815 0 : return xFactory;
816 : }
817 :
818 : // XServiceInfo
819 0 : Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames(void)
820 : throw(::com::sun::star::uno::RuntimeException, std::exception)
821 : {
822 0 : MutexGuard aGuard( aMutex );
823 0 : if( aServiceNames.getLength() == 0 )
824 : {
825 : // not yet loaded
826 : try
827 : {
828 0 : Reference<XRegistryKey > xKey = xImplementationKey->openKey(
829 0 : OUString("UNO/SERVICES") );
830 :
831 0 : if (xKey.is())
832 : {
833 : // length of prefix. +1 for the '/' at the end
834 0 : sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1;
835 :
836 : // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..."
837 0 : Sequence<OUString> seqKeys = xKey->getKeyNames();
838 0 : OUString* pKeys = seqKeys.getArray();
839 0 : for( sal_Int32 i = 0; i < seqKeys.getLength(); i++ )
840 0 : pKeys[i] = pKeys[i].copy(nPrefixLen);
841 :
842 0 : aServiceNames = seqKeys;
843 0 : }
844 : }
845 0 : catch (InvalidRegistryException &)
846 : {
847 : }
848 : }
849 0 : return aServiceNames;
850 : }
851 :
852 0 : sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException, std::exception)
853 : {
854 0 : bool retVal= true;
855 0 : if( isOneInstance() && isInstance())
856 : {
857 0 : retVal= false;
858 : }
859 0 : else if( ! isOneInstance())
860 : {
861 : // try to delegate
862 0 : if( xModuleFactory.is())
863 : {
864 0 : Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY);
865 0 : if( xunloading.is())
866 0 : retVal= xunloading->releaseOnNotification();
867 : }
868 0 : else if( xModuleFactoryDepr.is())
869 : {
870 0 : Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY);
871 0 : if( xunloading.is())
872 0 : retVal= xunloading->releaseOnNotification();
873 : }
874 : }
875 0 : return retVal;
876 : }
877 :
878 0 : class OFactoryProxyHelper : public WeakImplHelper3< XServiceInfo, XSingleServiceFactory,
879 : XUnloadingPreference >
880 : {
881 : Reference<XSingleServiceFactory > xFactory;
882 :
883 : public:
884 :
885 0 : OFactoryProxyHelper( const Reference<XSingleServiceFactory > & rFactory )
886 : SAL_THROW(())
887 0 : : xFactory( rFactory )
888 0 : {}
889 :
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;
895 :
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;
906 :
907 : };
908 :
909 : // XSingleServiceFactory
910 0 : Reference<XInterface > OFactoryProxyHelper::createInstance()
911 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
912 : {
913 0 : return xFactory->createInstance();
914 : }
915 :
916 : // XSingleServiceFactory
917 0 : Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments
918 : (
919 : const Sequence<Any>& Arguments
920 : )
921 : throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
922 : {
923 0 : return xFactory->createInstanceWithArguments( Arguments );
924 : }
925 :
926 : // XServiceInfo
927 0 : OUString OFactoryProxyHelper::getImplementationName()
928 : throw(::com::sun::star::uno::RuntimeException, std::exception)
929 : {
930 0 : Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
931 0 : if( xInfo.is() )
932 0 : return xInfo->getImplementationName();
933 0 : return OUString();
934 : }
935 :
936 : // XServiceInfo
937 0 : sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName)
938 : throw(::com::sun::star::uno::RuntimeException, std::exception)
939 : {
940 0 : return cppu::supportsService(this, ServiceName);
941 : }
942 :
943 : // XServiceInfo
944 0 : Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames(void)
945 : throw(::com::sun::star::uno::RuntimeException, std::exception)
946 : {
947 0 : Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
948 0 : if( xInfo.is() )
949 0 : return xInfo->getSupportedServiceNames();
950 0 : return Sequence< OUString >();
951 : }
952 :
953 0 : sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException, std::exception)
954 : {
955 :
956 0 : Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY);
957 0 : if( pref.is())
958 0 : return pref->releaseOnNotification();
959 0 : return sal_True;
960 : }
961 :
962 : // global function
963 0 : 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(())
970 : {
971 : return new OFactoryComponentHelper(
972 0 : rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, false );
973 : }
974 :
975 : // global function
976 0 : Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy(
977 : SAL_UNUSED_PARAMETER const Reference<XMultiServiceFactory > &,
978 : const Reference<XSingleServiceFactory > & rFactory )
979 : SAL_THROW(())
980 : {
981 0 : return new OFactoryProxyHelper( rFactory );
982 : }
983 :
984 : // global function
985 0 : 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(())
992 : {
993 : return new OFactoryComponentHelper(
994 0 : rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, true );
995 : }
996 :
997 : // global function
998 0 : Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(
999 : const Reference<XMultiServiceFactory > & rServiceManager,
1000 : const OUString & rImplementationName,
1001 : const Reference<XRegistryKey > & rImplementationKey )
1002 : SAL_THROW(())
1003 : {
1004 : return new ORegistryFactoryHelper(
1005 0 : rServiceManager, rImplementationName, rImplementationKey, false );
1006 : }
1007 :
1008 : // global function
1009 0 : Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory(
1010 : const Reference<XMultiServiceFactory > & rServiceManager,
1011 : const OUString & rImplementationName,
1012 : const Reference<XRegistryKey > & rImplementationKey )
1013 : SAL_THROW(())
1014 : {
1015 : return new ORegistryFactoryHelper(
1016 0 : rServiceManager, rImplementationName, rImplementationKey, true );
1017 : }
1018 :
1019 :
1020 5 : Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory(
1021 : ComponentFactoryFunc fptr,
1022 : OUString const & rImplementationName,
1023 : Sequence< OUString > const & rServiceNames,
1024 : rtl_ModuleCount *)
1025 : SAL_THROW(())
1026 : {
1027 : return new OFactoryComponentHelper(
1028 5 : Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, false );
1029 : }
1030 :
1031 0 : Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory(
1032 : ComponentFactoryFunc fptr,
1033 : OUString const & rImplementationName,
1034 : Sequence< OUString > const & rServiceNames,
1035 : rtl_ModuleCount *)
1036 : SAL_THROW(())
1037 : {
1038 : return new OFactoryComponentHelper(
1039 0 : Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, true );
1040 : }
1041 :
1042 : }
1043 :
1044 :
1045 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|