Coverage Report

Created: 2025-07-07 10:01

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