Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/cppuhelper/source/servicemanager.hxx
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
10
#pragma once
11
12
#include <sal/config.h>
13
14
#include <cassert>
15
#include <functional>
16
#include <memory>
17
#include <mutex>
18
#include <string_view>
19
#include <unordered_map>
20
#include <utility>
21
#include <vector>
22
23
#include <com/sun/star/beans/XPropertySet.hpp>
24
#include <com/sun/star/beans/XPropertySetInfo.hpp>
25
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
26
#include <com/sun/star/container/XSet.hpp>
27
#include <com/sun/star/lang/XEventListener.hpp>
28
#include <com/sun/star/lang/XInitialization.hpp>
29
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
30
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
31
#include <com/sun/star/lang/XServiceInfo.hpp>
32
#include <com/sun/star/uno/Reference.hxx>
33
#include <compbase2.hxx>
34
#include <rtl/ustring.hxx>
35
#include <boost/container/small_vector.hpp>
36
37
namespace com::sun::star::lang {
38
    class XSingleComponentFactory;
39
}
40
namespace cppu { struct ContextEntry_Init; }
41
namespace com :: sun :: star :: lang { class XSingleServiceFactory; }
42
namespace com :: sun :: star :: uno { class XComponentContext; }
43
44
class RegistryKey;
45
46
namespace cppuhelper {
47
48
extern "C" {
49
50
typedef css::uno::XInterface * ImplementationConstructorFn(
51
    css::uno::XComponentContext *, css::uno::Sequence<css::uno::Any> const &);
52
53
}
54
55
typedef std::function<css::uno::XInterface * (css::uno::XComponentContext *, css::uno::Sequence<css::uno::Any> const&)> WrapperConstructorFn;
56
57
typedef WeakComponentImplHelper2<
58
    css::lang::XServiceInfo, css::lang::XMultiServiceFactory,
59
    css::lang::XMultiComponentFactory, css::container::XSet,
60
    css::container::XContentEnumerationAccess, css::beans::XPropertySet,
61
    css::beans::XPropertySetInfo, css::lang::XEventListener,
62
    css::lang::XInitialization>
63
ServiceManagerBase;
64
65
class ServiceManager : public ServiceManagerBase
66
{
67
public:
68
    struct Data {
69
258
        Data() = default;
70
        Data(const Data&) = delete;
71
        const Data& operator=(const Data&) = delete;
72
73
        struct Implementation {
74
            Implementation(
75
                OUString theName, OUString theLoader,
76
                OUString theUri, OUString theEnvironment,
77
                OUString theConstructorName,
78
                OUString thePrefix,
79
                bool theIsSingleInstance,
80
                css::uno::Reference< css::uno::XComponentContext > theAlienContext,
81
                OUString theRdbFile):
82
94.6k
                name(std::move(theName)), loader(std::move(theLoader)), uri(std::move(theUri)), environment(std::move(theEnvironment)),
83
94.6k
                constructorName(std::move(theConstructorName)), prefix(std::move(thePrefix)),
84
94.6k
                isSingleInstance(theIsSingleInstance),
85
94.6k
                alienContext(std::move(theAlienContext)), rdbFile(std::move(theRdbFile)),
86
94.6k
                constructorFn(nullptr), status(STATUS_NEW), dispose(true)
87
94.6k
            {}
88
89
            Implementation(
90
                OUString theName,
91
                css::uno::Reference< css::lang::XSingleComponentFactory >
92
                    const & theFactory1,
93
                css::uno::Reference< css::lang::XSingleServiceFactory > const &
94
                    theFactory2,
95
                css::uno::Reference< css::lang::XComponent > theComponent):
96
150
                name(std::move(theName)), isSingleInstance(false), constructorFn(nullptr),
97
150
                factory1(theFactory1), factory2(theFactory2),
98
150
                component(std::move(theComponent)), status(STATUS_LOADED), dispose(true)
99
150
            { assert(theFactory1.is() || theFactory2.is()); }
100
101
            Implementation(const Implementation&) = delete;
102
            const Implementation& operator=(const Implementation&) = delete;
103
104
            css::uno::Reference<css::uno::XInterface> createInstance(
105
                css::uno::Reference<css::uno::XComponentContext> const &
106
                    context,
107
                bool singletonRequest);
108
109
            css::uno::Reference<css::uno::XInterface>
110
            createInstanceWithArguments(
111
                css::uno::Reference<css::uno::XComponentContext> const &
112
                    context,
113
                bool singletonRequest,
114
                css::uno::Sequence<css::uno::Any> const & arguments);
115
116
16.9M
            bool shallDispose() const { return isSingleInstance || !singletons.empty(); }
117
118
            enum Status { STATUS_NEW, STATUS_WRAPPER, STATUS_LOADED };
119
120
            // Logically, exactly one of constructorFn, factory1, factory2 should
121
            // be set.  However, there are two exceptions:  For one, when
122
            // constructorFn is set, ServiceManager::createContentEnumeration will
123
            // store the necessary ImplementationWrapper in factory1 (so that
124
            // multiple calls to createContentEnumeration will return the same
125
            // wrapper).  For another, when factory1 should be set but status is
126
            // STATUS_NEW, factory1 is not yet set (and when status is
127
            // STATUS_WRAPPER, factory1 is merely set to an
128
            // ImplementationWrapper---also due to a
129
            // ServiceManager::createContentEnumeration call---and will be
130
            // loaded later).
131
            OUString name;
132
            OUString loader;
133
            OUString uri;
134
            OUString environment;
135
            OUString constructorName;
136
            OUString prefix;
137
            bool isSingleInstance;
138
            css::uno::Reference< css::uno::XComponentContext > alienContext;
139
            OUString rdbFile;
140
            std::vector< OUString > services;
141
            std::vector< OUString > singletons;
142
            WrapperConstructorFn constructorFn;
143
            css::uno::Reference< css::lang::XSingleComponentFactory > factory1;
144
            css::uno::Reference< css::lang::XSingleServiceFactory > factory2;
145
            css::uno::Reference< css::lang::XComponent > component;
146
            Status status;
147
148
            std::mutex mutex;
149
            css::uno::Reference<css::uno::XInterface> singleInstance;
150
            css::uno::Reference< css::lang::XComponent > disposeInstance;
151
            bool dispose;
152
153
        private:
154
            css::uno::Reference<css::uno::XInterface> doCreateInstance(
155
                css::uno::Reference<css::uno::XComponentContext> const & context);
156
157
            css::uno::Reference<css::uno::XInterface> doCreateInstanceWithArguments(
158
                css::uno::Reference<css::uno::XComponentContext> const & context,
159
                css::uno::Sequence<css::uno::Any> const & arguments);
160
161
            void updateDisposeInstance(
162
                bool singletonRequest,
163
                css::uno::Reference<css::uno::XInterface> const & instance);
164
        };
165
166
        typedef std::unordered_map< OUString, std::shared_ptr< Implementation > >
167
            NamedImplementations;
168
169
        typedef
170
            std::unordered_map<
171
                css::uno::Reference< css::lang::XServiceInfo >,
172
                std::shared_ptr< Implementation > >
173
            DynamicImplementations;
174
175
        typedef
176
            std::unordered_map<
177
                OUString,
178
                boost::container::small_vector< std::shared_ptr< Implementation >, 2 > >
179
            ImplementationMap;
180
181
        NamedImplementations namedImplementations;
182
        DynamicImplementations dynamicImplementations;
183
        ImplementationMap services;
184
        ImplementationMap singletons;
185
    };
186
187
108
    ServiceManager() {}
cppuhelper::ServiceManager::ServiceManager()
Line
Count
Source
187
108
    ServiceManager() {}
Unexecuted instantiation: cppuhelper::ServiceManager::ServiceManager()
188
189
    ServiceManager(const ServiceManager&) = delete;
190
    const ServiceManager& operator=(const ServiceManager&) = delete;
191
192
    using ServiceManagerBase::acquire;
193
    using ServiceManagerBase::release;
194
195
    void init(std::u16string_view rdbUris);
196
197
    void setContext(
198
        css::uno::Reference< css::uno::XComponentContext > const & context)
199
108
    {
200
108
        assert(context.is());
201
108
        assert(!context_.is());
202
108
        context_ = context;
203
108
    }
204
205
    void addSingletonContextEntries(
206
        std::vector< cppu::ContextEntry_Init > * entries);
207
208
    css::uno::Reference< css::uno::XComponentContext > const & getContext()
209
        const
210
0
    {
211
        assert(context_.is());
212
0
        return context_;
213
0
    }
214
215
    void loadImplementation(
216
        css::uno::Reference< css::uno::XComponentContext > const & context,
217
        std::shared_ptr< Data::Implementation > const & implementation);
218
219
private:
220
    virtual ~ServiceManager() override;
221
222
    virtual void disposing(std::unique_lock<std::mutex>&) override;
223
224
    virtual OUString SAL_CALL getImplementationName() override;
225
226
    virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override;
227
228
    virtual css::uno::Sequence< OUString > SAL_CALL
229
    getSupportedServiceNames() override;
230
231
    virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
232
        OUString const & aServiceSpecifier) override;
233
234
    virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
235
    createInstanceWithArguments(
236
        OUString const & ServiceSpecifier,
237
        css::uno::Sequence< css::uno::Any > const & Arguments) override;
238
239
    virtual css::uno::Sequence< OUString > SAL_CALL
240
    getAvailableServiceNames() override;
241
242
    virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
243
    createInstanceWithContext(
244
        OUString const & aServiceSpecifier,
245
        css::uno::Reference< css::uno::XComponentContext > const & Context) override;
246
247
    virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
248
    createInstanceWithArgumentsAndContext(
249
        OUString const & ServiceSpecifier,
250
        css::uno::Sequence< css::uno::Any > const & Arguments,
251
        css::uno::Reference< css::uno::XComponentContext > const & Context) override;
252
253
    virtual css::uno::Type SAL_CALL getElementType() override;
254
255
    virtual sal_Bool SAL_CALL hasElements() override;
256
257
    virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL
258
    createEnumeration() override;
259
260
    virtual sal_Bool SAL_CALL has(css::uno::Any const & aElement) override;
261
262
    virtual void SAL_CALL insert(css::uno::Any const & aElement) override;
263
264
    virtual void SAL_CALL remove(css::uno::Any const & aElement) override;
265
266
    virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL
267
    createContentEnumeration(OUString const & aServiceName) override;
268
269
    virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
270
    getPropertySetInfo() override;
271
272
    virtual void SAL_CALL setPropertyValue(
273
        OUString const & aPropertyName, css::uno::Any const & aValue) override;
274
275
    virtual css::uno::Any SAL_CALL getPropertyValue(
276
        OUString const & PropertyName) override;
277
278
    virtual void SAL_CALL addPropertyChangeListener(
279
        OUString const & aPropertyName,
280
        css::uno::Reference< css::beans::XPropertyChangeListener > const &
281
            xListener) override;
282
283
    virtual void SAL_CALL removePropertyChangeListener(
284
        OUString const & aPropertyName,
285
        css::uno::Reference< css::beans::XPropertyChangeListener > const &
286
            aListener) override;
287
288
    virtual void SAL_CALL addVetoableChangeListener(
289
        OUString const & PropertyName,
290
        css::uno::Reference< css::beans::XVetoableChangeListener > const &
291
            aListener) override;
292
293
    virtual void SAL_CALL removeVetoableChangeListener(
294
        OUString const & PropertyName,
295
        css::uno::Reference< css::beans::XVetoableChangeListener > const &
296
            aListener) override;
297
298
    virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties() override;
299
300
    virtual css::beans::Property SAL_CALL getPropertyByName(
301
        OUString const & aName) override;
302
303
    virtual sal_Bool SAL_CALL hasPropertyByName(OUString const & Name) override;
304
305
    virtual void SAL_CALL disposing(css::lang::EventObject const & Source) override;
306
307
    virtual void SAL_CALL initialize(
308
        css::uno::Sequence<css::uno::Any> const & aArguments)
309
        override;
310
311
    void removeEventListenerFromComponent(
312
        css::uno::Reference< css::lang::XComponent > const & component);
313
314
    void readRdbDirectory(std::u16string_view uri, bool optional);
315
316
    void readRdbFile(OUString const & uri, bool optional);
317
318
    bool readLegacyRdbFile(OUString const & uri);
319
320
    OUString readLegacyRdbString(
321
        std::u16string_view uri, RegistryKey & key,
322
        OUString const & path);
323
324
    void readLegacyRdbStrings(
325
        std::u16string_view uri, RegistryKey & key,
326
        OUString const & path, std::vector< OUString > * strings);
327
328
    void insertRdbFiles(
329
        std::vector< OUString > const & uris,
330
        css::uno::Reference< css::uno::XComponentContext > const &
331
            alientContext);
332
333
    void insertLegacyFactory(
334
        css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo);
335
336
    bool insertExtraData(Data const & extra);
337
338
    void removeRdbFiles(std::vector< OUString > const & uris);
339
340
    bool removeLegacyFactory(
341
        css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo,
342
        bool removeListener);
343
344
    void removeImplementation(const OUString & name);
345
346
    std::shared_ptr< Data::Implementation > findServiceImplementation(
347
        css::uno::Reference< css::uno::XComponentContext > const & context,
348
        OUString const & specifier);
349
350
    void preloadImplementations();
351
352
    css::uno::Reference< css::uno::XComponentContext > context_;
353
    Data data_;
354
};
355
356
}
357
358
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */