Coverage Report

Created: 2025-12-08 09:28

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