LibreOffice Module cppuhelper (master)  1
factory.cxx
Go to the documentation of this file.
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 <sal/log.hxx>
21 #include <osl/diagnose.h>
22 #include <osl/mutex.hxx>
23 #include <cppuhelper/weak.hxx>
24 #include <cppuhelper/component.hxx>
25 #include <cppuhelper/factory.hxx>
26 #include <cppuhelper/implbase.hxx>
29 #include <rtl/unload.h>
30 
31 #include <cppuhelper/propshlp.hxx>
32 
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
36 #include <com/sun/star/lang/XInitialization.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/loader/XImplementationLoader.hpp>
39 #include <com/sun/star/lang/XComponent.hpp>
40 #include <com/sun/star/lang/IllegalArgumentException.hpp>
41 #include <com/sun/star/uno/XUnloadingPreference.hpp>
42 #include <com/sun/star/beans/PropertyAttribute.hpp>
43 
44 #include <memory>
45 
46 
47 using namespace osl;
48 using namespace com::sun::star;
49 using namespace com::sun::star::uno;
50 using namespace com::sun::star::lang;
51 using namespace com::sun::star::loader;
52 using namespace com::sun::star::registry;
53 
54 namespace cppu
55 {
56 
57 namespace {
58 
59 class OSingleFactoryHelper
60  : public XServiceInfo
61  , public XSingleServiceFactory
62  , public lang::XSingleComponentFactory
63  , public XUnloadingPreference
64 {
65 public:
66  OSingleFactoryHelper(
67  const Reference<XMultiServiceFactory > & rServiceManager,
68  const OUString & rImplementationName_,
69  ComponentInstantiation pCreateFunction_,
70  ComponentFactoryFunc fptr,
71  const Sequence< OUString > * pServiceNames_ )
72  : xSMgr( rServiceManager )
73  , pCreateFunction( pCreateFunction_ )
74  , m_fptr( fptr )
75  , aImplementationName( rImplementationName_ )
76  {
77  if( pServiceNames_ )
78  aServiceNames = *pServiceNames_;
79  }
80 
81  virtual ~OSingleFactoryHelper();
82 
83  // XInterface
84  Any SAL_CALL queryInterface( const Type & rType ) override;
85 
86  // XSingleServiceFactory
87  Reference<XInterface > SAL_CALL createInstance() override;
88  virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) override;
89  // XSingleComponentFactory
90  virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
91  Reference< XComponentContext > const & xContext ) override;
92  virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
93  Sequence< Any > const & rArguments,
94  Reference< XComponentContext > const & xContext ) override;
95 
96  // XServiceInfo
97  OUString SAL_CALL getImplementationName() override;
98  sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
100 
101 protected:
109  virtual Reference<XInterface > createInstanceEveryTime(
110  Reference< XComponentContext > const & xContext );
111 
113  ComponentInstantiation pCreateFunction;
114  ComponentFactoryFunc m_fptr;
117 };
118 
119 }
120 
121 OSingleFactoryHelper::~OSingleFactoryHelper()
122 {
123 }
124 
125 
127 {
129  rType,
130  static_cast< XSingleComponentFactory * >( this ),
131  static_cast< XSingleServiceFactory * >( this ),
132  static_cast< XServiceInfo * >( this ) ,
133  static_cast< XUnloadingPreference * >( this ));
134 }
135 
136 // OSingleFactoryHelper
137 Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime(
138  Reference< XComponentContext > const & xContext )
139 {
140  if (m_fptr)
141  {
142  return (*m_fptr)( xContext );
143  }
144  if( pCreateFunction )
145  {
146  if (xContext.is())
147  {
149  xContext->getServiceManager(), UNO_QUERY );
150  if (xContextMgr.is())
151  return (*pCreateFunction)( xContextMgr );
152  }
153  return (*pCreateFunction)( xSMgr );
154  }
155  return Reference< XInterface >();
156 }
157 
158 // XSingleServiceFactory
159 Reference<XInterface > OSingleFactoryHelper::createInstance()
160 {
161  return createInstanceWithContext( Reference< XComponentContext >() );
162 }
163 
164 // XSingleServiceFactory
165 Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments(
166  const Sequence<Any>& Arguments )
167 {
168  return createInstanceWithArgumentsAndContext(
169  Arguments, Reference< XComponentContext >() );
170 }
171 
172 // XSingleComponentFactory
173 
174 Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext(
175  Reference< XComponentContext > const & xContext )
176 {
177  return createInstanceEveryTime( xContext );
178 }
179 
180 Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext(
181  Sequence< Any > const & rArguments,
182  Reference< XComponentContext > const & xContext )
183 {
184  Reference< XInterface > xRet( createInstanceWithContext( xContext ) );
185 
186  Reference< lang::XInitialization > xInit( xRet, UNO_QUERY );
187  // always call initialize, even if there are no arguments. #i63511#
188  if (xInit.is())
189  {
190  xInit->initialize( rArguments );
191  }
192  else
193  {
194  if ( rArguments.hasElements() )
195  {
196  // dispose the here created UNO object before throwing out exception
197  // to avoid risk of memory leaks #i113722#
198  Reference<XComponent> xComp( xRet, UNO_QUERY );
199  if (xComp.is())
200  xComp->dispose();
201 
202  throw lang::IllegalArgumentException(
203  "cannot pass arguments to component => no XInitialization implemented!",
205  }
206  }
207 
208  return xRet;
209 }
210 
211 // XServiceInfo
212 OUString OSingleFactoryHelper::getImplementationName()
213 {
214  return aImplementationName;
215 }
216 
217 // XServiceInfo
219  const OUString& ServiceName )
220 {
221  return cppu::supportsService(this, ServiceName);
222 }
223 
224 // XServiceInfo
225 Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames()
226 {
227  return aServiceNames;
228 }
229 
230 namespace {
231 
232 struct OFactoryComponentHelper_Mutex
233 {
234  Mutex aMutex;
235 };
236 
237 class OFactoryComponentHelper
238  : public OFactoryComponentHelper_Mutex
239  , public OComponentHelper
240  , public OSingleFactoryHelper
241 {
242 public:
243  OFactoryComponentHelper(
244  const Reference<XMultiServiceFactory > & rServiceManager,
245  const OUString & rImplementationName_,
246  ComponentInstantiation pCreateFunction_,
247  ComponentFactoryFunc fptr,
248  const Sequence< OUString > * pServiceNames_,
249  bool bOneInstance_ )
250  : OComponentHelper( aMutex )
251  , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ )
252  , bOneInstance( bOneInstance_ )
253  {
254  }
255 
256  // XInterface
257  Any SAL_CALL queryInterface( const Type & rType ) override;
258  void SAL_CALL acquire() noexcept override
259  { OComponentHelper::acquire(); }
260  void SAL_CALL release() noexcept override
261  { OComponentHelper::release(); }
262 
263  // XSingleServiceFactory
264  Reference<XInterface > SAL_CALL createInstance() override;
265  Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments ) override;
266  // XSingleComponentFactory
267  virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
268  Reference< XComponentContext > const & xContext ) override;
269  virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
270  Sequence< Any > const & rArguments,
271  Reference< XComponentContext > const & xContext ) override;
272 
273  // XTypeProvider
274  virtual Sequence< Type > SAL_CALL getTypes() override;
275  virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
276 
277  // XAggregation
278  Any SAL_CALL queryAggregation( const Type & rType ) override;
279 
280  // XUnloadingPreference
281  virtual sal_Bool SAL_CALL releaseOnNotification() override;
282 
283  // OComponentHelper
284  void SAL_CALL dispose() override;
285 
286 private:
289 protected:
290  // needed for implementing XUnloadingPreference in inheriting classes
291  bool isOneInstance() const {return bOneInstance;}
292  bool isInstance() const {return xTheInstance.is();}
293 };
294 
295 }
296 
297 Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType )
298 {
300  {
301  return Any(
303  static_cast< XUnloadingPreference * >(this) ) );
304  }
305  return OComponentHelper::queryInterface( rType );
306 }
307 
308 // XAggregation
309 Any OFactoryComponentHelper::queryAggregation( const Type & rType )
310 {
311  Any aRet( OComponentHelper::queryAggregation( rType ) );
312  return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType ));
313 }
314 
315 // XTypeProvider
316 Sequence< Type > OFactoryComponentHelper::getTypes()
317 {
318  Type ar[ 4 ];
322 
323  if (m_fptr)
325 
326  return Sequence< Type >( ar, m_fptr ? 4 : 3 );
327 }
328 
329 Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId()
330 {
331  return css::uno::Sequence<sal_Int8>();
332 }
333 
334 // XSingleServiceFactory
335 Reference<XInterface > OFactoryComponentHelper::createInstance()
336 {
337  if( bOneInstance )
338  {
339  if( !xTheInstance.is() )
340  {
341  MutexGuard aGuard( aMutex );
342  if( !xTheInstance.is() )
343  xTheInstance = OSingleFactoryHelper::createInstance();
344  }
345  return xTheInstance;
346  }
347  return OSingleFactoryHelper::createInstance();
348 }
349 
350 Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments(
351  const Sequence<Any>& Arguments )
352 {
353  if( bOneInstance )
354  {
355  if( !xTheInstance.is() )
356  {
357  MutexGuard aGuard( aMutex );
358 // OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" );
359  if( !xTheInstance.is() )
360  xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments );
361  }
362  return xTheInstance;
363  }
364  return OSingleFactoryHelper::createInstanceWithArguments( Arguments );
365 }
366 
367 // XSingleComponentFactory
368 
369 Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext(
370  Reference< XComponentContext > const & xContext )
371 {
372  if( bOneInstance )
373  {
374  if( !xTheInstance.is() )
375  {
376  MutexGuard aGuard( aMutex );
377 // OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" );
378  if( !xTheInstance.is() )
379  xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext );
380  }
381  return xTheInstance;
382  }
383  return OSingleFactoryHelper::createInstanceWithContext( xContext );
384 }
385 
386 Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext(
387  Sequence< Any > const & rArguments,
388  Reference< XComponentContext > const & xContext )
389 {
390  if( bOneInstance )
391  {
392  if( !xTheInstance.is() )
393  {
394  MutexGuard aGuard( aMutex );
395 // OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" );
396  if( !xTheInstance.is() )
397  xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
398  }
399  return xTheInstance;
400  }
401  return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
402 }
403 
404 
405 // OComponentHelper
406 void OFactoryComponentHelper::dispose()
407 {
408  OComponentHelper::dispose();
409 
411  {
412  // do not delete in the guard section
413  MutexGuard aGuard( aMutex );
414  x = xTheInstance;
415  xTheInstance.clear();
416  }
417  // if it is a component call dispose at the component
418  Reference<XComponent > xComp( x, UNO_QUERY );
419  if( xComp.is() )
420  xComp->dispose();
421 }
422 
423 // XUnloadingPreference
424 // This class is used for single factories, component factories and
425 // one-instance factories. Depending on the usage this function has
426 // to return different values.
427 // one-instance factory: sal_False
428 // single factory: sal_True
429 // component factory: sal_True
430 sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification()
431 {
432  if( bOneInstance)
433  return false;
434  return true;
435 }
436 
437 namespace {
438 
439 class ORegistryFactoryHelper : public OFactoryComponentHelper,
440  public OPropertySetHelper
441 
442 {
443 public:
444  ORegistryFactoryHelper(
445  const Reference<XMultiServiceFactory > & rServiceManager,
446  const OUString & rImplementationName_,
447  const Reference<XRegistryKey > & xImplementationKey_,
448  bool bOneInstance_ )
449  : OFactoryComponentHelper(
450  rServiceManager, rImplementationName_, nullptr, nullptr, nullptr, bOneInstance_ ),
451  OPropertySetHelper( OComponentHelper::rBHelper ),
452  xImplementationKey( xImplementationKey_ )
453  {}
454 
455  // XInterface
456  virtual Any SAL_CALL queryInterface( Type const & type ) override;
457  virtual void SAL_CALL acquire() noexcept override;
458  virtual void SAL_CALL release() noexcept override;
459  // XTypeProvider
460  virtual Sequence< Type > SAL_CALL getTypes() override;
461  // XPropertySet
462  virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
463 
464  // OPropertySetHelper
465  virtual IPropertyArrayHelper & SAL_CALL getInfoHelper() override;
466  virtual sal_Bool SAL_CALL convertFastPropertyValue(
467  Any & rConvertedValue, Any & rOldValue,
468  sal_Int32 nHandle, Any const & rValue ) override;
469  virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
470  sal_Int32 nHandle, Any const & rValue ) override;
471  using OPropertySetHelper::getFastPropertyValue;
472  virtual void SAL_CALL getFastPropertyValue(
473  Any & rValue, sal_Int32 nHandle ) const override;
474 
475  // OSingleFactoryHelper
476  Reference<XInterface > createInstanceEveryTime(
477  Reference< XComponentContext > const & xContext ) override;
478 
479  // XSingleServiceFactory
480  Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) override;
481  // XSingleComponentFactory
482  Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
483  Sequence< Any > const & rArguments,
484  Reference< XComponentContext > const & xContext ) override;
485 
486  // XServiceInfo
487  Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
488  // XUnloadingPreference
489  sal_Bool SAL_CALL releaseOnNotification() override;
490 
491 
492 private:
495  Reference< XInterface > createModuleFactory();
496 
500  Reference<XSingleComponentFactory > xModuleFactory;
501  Reference<XSingleServiceFactory > xModuleFactoryDepr;
502  Reference< beans::XPropertySetInfo > m_xInfo;
503  std::unique_ptr< IPropertyArrayHelper > m_property_array_helper;
504 protected:
505  using OPropertySetHelper::getTypes;
506 };
507 
508 }
509 
510 // XInterface
511 
512 Any SAL_CALL ORegistryFactoryHelper::queryInterface(
513  Type const & type )
514 {
516  if (ret.hasValue())
517  return ret;
518  return OPropertySetHelper::queryInterface( type );
519 }
520 
521 
522 void ORegistryFactoryHelper::acquire() noexcept
523 {
524  OFactoryComponentHelper::acquire();
525 }
526 
527 
528 void ORegistryFactoryHelper::release() noexcept
529 {
530  OFactoryComponentHelper::release();
531 }
532 
533 // XTypeProvider
534 
535 Sequence< Type > ORegistryFactoryHelper::getTypes()
536 {
537  Sequence< Type > types( OFactoryComponentHelper::getTypes() );
538  sal_Int32 pos = types.getLength();
539  types.realloc( pos + 3 );
540  Type * p = types.getArray();
544  return types;
545 }
546 
547 // XPropertySet
548 
550 ORegistryFactoryHelper::getPropertySetInfo()
551 {
552  ::osl::MutexGuard guard( aMutex );
553  if (! m_xInfo.is())
554  m_xInfo = createPropertySetInfo( getInfoHelper() );
555  return m_xInfo;
556 }
557 
558 // OPropertySetHelper
559 
560 IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper()
561 {
562  ::osl::MutexGuard guard( aMutex );
563  if (m_property_array_helper == nullptr)
564  {
565  beans::Property prop(
566  "ImplementationKey" /* name */,
567  0 /* handle */,
568  cppu::UnoType<decltype(xImplementationKey)>::get(),
569  beans::PropertyAttribute::READONLY |
570  beans::PropertyAttribute::OPTIONAL );
572  new ::cppu::OPropertyArrayHelper( &prop, 1 ) );
573  }
574  return *m_property_array_helper;
575 }
576 
577 
578 sal_Bool ORegistryFactoryHelper::convertFastPropertyValue(
579  Any &, Any &, sal_Int32, Any const & )
580 {
581  OSL_FAIL( "unexpected!" );
582  return false;
583 }
584 
585 
586 void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast(
587  sal_Int32, Any const & )
588 {
589  throw beans::PropertyVetoException(
590  "unexpected: only readonly properties!",
591  static_cast< OWeakObject * >(this) );
592 }
593 
594 
595 void ORegistryFactoryHelper::getFastPropertyValue(
596  Any & rValue, sal_Int32 nHandle ) const
597 {
598  if (nHandle == 0)
599  {
600  rValue <<= xImplementationKey;
601  }
602  else
603  {
604  rValue.clear();
605  throw beans::UnknownPropertyException(
606  "unknown property!", static_cast< OWeakObject * >(
607  const_cast< ORegistryFactoryHelper * >(this) ) );
608  }
609 }
610 
611 Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime(
612  Reference< XComponentContext > const & xContext )
613 {
614  if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
615  {
616  Reference< XInterface > x( createModuleFactory() );
617  if (x.is())
618  {
619  MutexGuard aGuard( aMutex );
620  if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
621  {
622  xModuleFactory.set( x, UNO_QUERY );
623  xModuleFactoryDepr.set( x, UNO_QUERY );
624  }
625  }
626  }
627  if( xModuleFactory.is() )
628  {
629  return xModuleFactory->createInstanceWithContext( xContext );
630  }
631  if( xModuleFactoryDepr.is() )
632  {
633  return xModuleFactoryDepr->createInstance();
634  }
635 
636  return Reference<XInterface >();
637 }
638 
639 Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments(
640  const Sequence<Any>& Arguments )
641 {
642  if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
643  {
644  Reference< XInterface > x( createModuleFactory() );
645  if (x.is())
646  {
647  MutexGuard aGuard( aMutex );
648  if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
649  {
650  xModuleFactory.set( x, UNO_QUERY );
651  xModuleFactoryDepr.set( x, UNO_QUERY );
652  }
653  }
654  }
655  if( xModuleFactoryDepr.is() )
656  {
657  return xModuleFactoryDepr->createInstanceWithArguments( Arguments );
658  }
659  if( xModuleFactory.is() )
660  {
661  SAL_INFO("cppuhelper", "no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!");
662  return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() );
663  }
664 
665  return Reference<XInterface >();
666 }
667 
668 Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext(
669  Sequence< Any > const & rArguments,
670  Reference< XComponentContext > const & xContext )
671 {
672  if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
673  {
674  Reference< XInterface > x( createModuleFactory() );
675  if (x.is())
676  {
677  MutexGuard aGuard( aMutex );
678  if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
679  {
680  xModuleFactory.set( x, UNO_QUERY );
681  xModuleFactoryDepr.set( x, UNO_QUERY );
682  }
683  }
684  }
685  if( xModuleFactory.is() )
686  {
687  return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext );
688  }
689  if( xModuleFactoryDepr.is() )
690  {
691  SAL_INFO_IF(xContext.is(), "cppuhelper", "ignoring context calling ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!");
692  return xModuleFactoryDepr->createInstanceWithArguments( rArguments );
693  }
694 
695  return Reference<XInterface >();
696 }
697 
698 
699 // OSingleFactoryHelper
700 Reference< XInterface > ORegistryFactoryHelper::createModuleFactory()
701 {
702  OUString aActivatorUrl;
703  OUString aActivatorName;
704  OUString aLocation;
705 
706  Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey(
707  "/UNO/ACTIVATOR" );
708  if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII )
709  {
710  aActivatorUrl = xActivatorKey->getAsciiValue();
711 
712  aActivatorName = aActivatorUrl.getToken(0, ':');
713 
714  Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
715  "/UNO/LOCATION" );
716  if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
717  aLocation = xLocationKey->getAsciiValue();
718  }
719  else
720  {
721  // old style"url"
722  // the location of the program code of the implementation
723  Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
724  "/UNO/URL" );
725  // is the key of the right type ?
726  if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
727  {
728  // one implementation found -> try to activate
729  aLocation = xLocationKey->getAsciiValue();
730 
731  // search protocol delimiter
732  sal_Int32 nPos = aLocation.indexOf("://");
733  if( nPos != -1 )
734  {
735  aActivatorName = aLocation.copy( 0, nPos );
736  if( aActivatorName == "java" )
737  aActivatorName = "com.sun.star.loader.Java";
738  else if( aActivatorName == "module" )
739  aActivatorName = "com.sun.star.loader.SharedLibrary";
740  aLocation = aLocation.copy( nPos + 3 );
741  }
742  }
743  }
744 
746  if( !aActivatorName.isEmpty() )
747  {
748  Reference<XInterface > x = xSMgr->createInstance( aActivatorName );
749  Reference<XImplementationLoader > xLoader( x, UNO_QUERY );
750  if (xLoader.is())
751  {
752  xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey );
753  }
754  }
755  return xFactory;
756 }
757 
758 // XServiceInfo
759 Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames()
760 {
761  MutexGuard aGuard( aMutex );
762  if( !aServiceNames.hasElements() )
763  {
764  // not yet loaded
765  try
766  {
767  Reference<XRegistryKey > xKey = xImplementationKey->openKey( "UNO/SERVICES" );
768 
769  if (xKey.is())
770  {
771  // length of prefix. +1 for the '/' at the end
772  sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1;
773 
774  // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..."
775  Sequence<OUString> seqKeys = xKey->getKeyNames();
776  for( OUString & key : seqKeys )
777  key = key.copy(nPrefixLen);
778 
779  aServiceNames = seqKeys;
780  }
781  }
782  catch (InvalidRegistryException &)
783  {
784  }
785  }
786  return aServiceNames;
787 }
788 
789 sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification()
790 {
791  bool retVal= true;
792  if( isOneInstance() && isInstance())
793  {
794  retVal= false;
795  }
796  else if( ! isOneInstance())
797  {
798  // try to delegate
799  if( xModuleFactory.is())
800  {
801  Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY);
802  if( xunloading.is())
803  retVal= xunloading->releaseOnNotification();
804  }
805  else if( xModuleFactoryDepr.is())
806  {
807  Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY);
808  if( xunloading.is())
809  retVal= xunloading->releaseOnNotification();
810  }
811  }
812  return retVal;
813 }
814 
815 namespace {
816 
817 class OFactoryProxyHelper : public WeakImplHelper< XServiceInfo, XSingleServiceFactory,
818  XUnloadingPreference >
819 {
821 
822 public:
823 
824  explicit OFactoryProxyHelper( const Reference<XSingleServiceFactory > & rFactory )
825  : xFactory( rFactory )
826  {}
827 
828  // XSingleServiceFactory
829  Reference<XInterface > SAL_CALL createInstance() override;
830  Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) override;
831 
832  // XServiceInfo
833  OUString SAL_CALL getImplementationName() override;
834  sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
836  //XUnloadingPreference
837  sal_Bool SAL_CALL releaseOnNotification() override;
838 
839 };
840 
841 }
842 
843 // XSingleServiceFactory
844 Reference<XInterface > OFactoryProxyHelper::createInstance()
845 {
846  return xFactory->createInstance();
847 }
848 
849 // XSingleServiceFactory
850 Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments
851 (
852  const Sequence<Any>& Arguments
853 )
854 {
855  return xFactory->createInstanceWithArguments( Arguments );
856 }
857 
858 // XServiceInfo
859 OUString OFactoryProxyHelper::getImplementationName()
860 {
861  Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
862  if( xInfo.is() )
863  return xInfo->getImplementationName();
864  return OUString();
865 }
866 
867 // XServiceInfo
868 sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName)
869 {
870  return cppu::supportsService(this, ServiceName);
871 }
872 
873 // XServiceInfo
874 Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames()
875 {
876  Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
877  if( xInfo.is() )
878  return xInfo->getSupportedServiceNames();
879  return Sequence< OUString >();
880 }
881 
882 sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification()
883 {
884 
885  Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY);
886  if( pref.is())
887  return pref->releaseOnNotification();
888  return true;
889 }
890 
891 // global function
893  const Reference<XMultiServiceFactory > & rServiceManager,
894  const OUString & rImplementationName,
895  ComponentInstantiation pCreateFunction,
896  const Sequence< OUString > & rServiceNames,
897  rtl_ModuleCount * )
898 {
899  return new OFactoryComponentHelper(
900  rServiceManager, rImplementationName, pCreateFunction, nullptr, &rServiceNames, false );
901 }
902 
903 // global function
905  SAL_UNUSED_PARAMETER const Reference<XMultiServiceFactory > &,
906  const Reference<XSingleServiceFactory > & rFactory )
907 {
908  return new OFactoryProxyHelper( rFactory );
909 }
910 
911 // global function
913  const Reference<XMultiServiceFactory > & rServiceManager,
914  const OUString & rImplementationName,
915  ComponentInstantiation pCreateFunction,
916  const Sequence< OUString > & rServiceNames,
917  rtl_ModuleCount * )
918 {
919  return new OFactoryComponentHelper(
920  rServiceManager, rImplementationName, pCreateFunction, nullptr, &rServiceNames, true );
921 }
922 
923 // global function
925  const Reference<XMultiServiceFactory > & rServiceManager,
926  const OUString & rImplementationName,
927  const Reference<XRegistryKey > & rImplementationKey )
928 {
929  return new ORegistryFactoryHelper(
930  rServiceManager, rImplementationName, rImplementationKey, false );
931 }
932 
933 // global function
935  const Reference<XMultiServiceFactory > & rServiceManager,
936  const OUString & rImplementationName,
937  const Reference<XRegistryKey > & rImplementationKey )
938 {
939  return new ORegistryFactoryHelper(
940  rServiceManager, rImplementationName, rImplementationKey, true );
941 }
942 
943 
945  ComponentFactoryFunc fptr,
946  OUString const & rImplementationName,
947  Sequence< OUString > const & rServiceNames,
948  rtl_ModuleCount *)
949 {
950  return new OFactoryComponentHelper(
951  Reference< XMultiServiceFactory >(), rImplementationName, nullptr, fptr, &rServiceNames, false );
952 }
953 
955  ComponentFactoryFunc fptr,
956  OUString const & rImplementationName,
957  Sequence< OUString > const & rServiceNames,
958  rtl_ModuleCount *)
959 {
960  return new OFactoryComponentHelper(
961  Reference< XMultiServiceFactory >(), rImplementationName, nullptr, fptr, &rServiceNames, true );
962 }
963 
964 }
965 
966 
967 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Type
Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory(ComponentFactoryFunc fptr, OUString const &rImplementationName, Sequence< OUString > const &rServiceNames, rtl_ModuleCount *)
Definition: factory.cxx:954
#define SAL_INFO_IF(condition, area, stream)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
Reference< XRegistryKey > xImplementationKey
The registry key of the implementation section.
Definition: factory.cxx:498
Sequence< OUString > aServiceNames
Definition: factory.cxx:115
Reference< XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(const Reference< XMultiServiceFactory > &rServiceManager, const OUString &rImplementationName, const Reference< XRegistryKey > &rImplementationKey)
Definition: factory.cxx:924
float x
Reference< XSingleServiceFactory > SAL_CALL createFactoryProxy(SAL_UNUSED_PARAMETER const Reference< XMultiServiceFactory > &, const Reference< XSingleServiceFactory > &rFactory)
Definition: factory.cxx:904
Reference< XSingleServiceFactory > SAL_CALL createSingleFactory(const Reference< XMultiServiceFactory > &rServiceManager, const OUString &rImplementationName, ComponentInstantiation pCreateFunction, const Sequence< OUString > &rServiceNames, rtl_ModuleCount *)
Definition: factory.cxx:892
Reference< XInterface > xTheInstance
Definition: factory.cxx:287
size_t pos
ComponentFactoryFunc m_fptr
Definition: factory.cxx:114
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
A helper for implementations of com.sun.star.lang.XServiceInfo.
Reference< XSingleComponentFactory > xModuleFactory
The factory created with the loader.
Definition: factory.cxx:500
Mutex aMutex
Definition: factory.cxx:234
Reference< beans::XPropertySetInfo > m_xInfo
Definition: factory.cxx:502
OUString aImplementationName
Definition: factory.cxx:116
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
unsigned char sal_Bool
std::unique_ptr< IPropertyArrayHelper > m_property_array_helper
Definition: factory.cxx:503
css::uno::Type const & get()
Reference< XSingleServiceFactory > SAL_CALL createOneInstanceFactory(const Reference< XMultiServiceFactory > &rServiceManager, const OUString &rImplementationName, ComponentInstantiation pCreateFunction, const Sequence< OUString > &rServiceNames, rtl_ModuleCount *)
Definition: factory.cxx:912
Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory(ComponentFactoryFunc fptr, OUString const &rImplementationName, Sequence< OUString > const &rServiceNames, rtl_ModuleCount *)
Definition: factory.cxx:944
Reference< XMultiServiceFactory > xSMgr
Definition: factory.cxx:112
#define SAL_INFO(area, stream)
Reference< XSingleServiceFactory > xModuleFactoryDepr
Definition: factory.cxx:501
void * p
bool bOneInstance
Definition: factory.cxx:288
Reference< XSingleServiceFactory > xFactory
Definition: factory.cxx:820
void dispose()
ComponentInstantiation pCreateFunction
Definition: factory.cxx:113
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
Compares demanded type to given template argument types.
Reference< XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory(const Reference< XMultiServiceFactory > &rServiceManager, const OUString &rImplementationName, const Reference< XRegistryKey > &rImplementationKey)
Definition: factory.cxx:934
sal_uInt16 nPos