1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
12 #include <sal/config.h>
19 #include <com/sun/star/beans/XPropertySet.hpp>
20 #include <com/sun/star/beans/XPropertySetInfo.hpp>
21 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
22 #include <com/sun/star/container/XSet.hpp>
23 #include <com/sun/star/lang/XEventListener.hpp>
24 #include <com/sun/star/lang/XInitialization.hpp>
25 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
28 #include <com/sun/star/uno/Reference.hxx>
29 #include <cppuhelper/basemutex.hxx>
30 #include <cppuhelper/compbase.hxx>
31 #include <osl/mutex.hxx>
32 #include <rtl/ustring.hxx>
34 namespace com::sun::star::lang
{
35 class XSingleComponentFactory
;
37 namespace cppu
{ struct ContextEntry_Init
; }
38 namespace com :: sun :: star :: lang
{ class XSingleServiceFactory
; }
39 namespace com :: sun :: star :: uno
{ class XComponentContext
; }
43 namespace cppuhelper
{
47 typedef css::uno::XInterface
* ImplementationConstructorFn(
48 css::uno::XComponentContext
*, css::uno::Sequence
<css::uno::Any
> const &);
52 typedef std::function
<css::uno::XInterface
* (css::uno::XComponentContext
*, css::uno::Sequence
<css::uno::Any
> const&)> WrapperConstructorFn
;
54 typedef cppu::WeakComponentImplHelper
<
55 css::lang::XServiceInfo
, css::lang::XMultiServiceFactory
,
56 css::lang::XMultiComponentFactory
, css::container::XSet
,
57 css::container::XContentEnumerationAccess
, css::beans::XPropertySet
,
58 css::beans::XPropertySetInfo
, css::lang::XEventListener
,
59 css::lang::XInitialization
>
63 private cppu::BaseMutex
, public ServiceManagerBase
68 Data(const Data
&) = delete;
69 const Data
& operator=(const Data
&) = delete;
71 struct Implementation
{
73 OUString
const & theName
, OUString
const & theLoader
,
74 OUString
const & theUri
, OUString
const & theEnvironment
,
75 OUString
const & theConstructorName
,
76 OUString
const & thePrefix
,
77 bool theIsSingleInstance
,
78 css::uno::Reference
< css::uno::XComponentContext
> const &
80 OUString
const & theRdbFile
):
81 name(theName
), loader(theLoader
), uri(theUri
), environment(theEnvironment
),
82 constructorName(theConstructorName
), prefix(thePrefix
),
83 isSingleInstance(theIsSingleInstance
),
84 alienContext(theAlienContext
), rdbFile(theRdbFile
),
85 constructorFn(nullptr), status(STATUS_NEW
), dispose(true)
89 OUString
const & theName
,
90 css::uno::Reference
< css::lang::XSingleComponentFactory
>
92 css::uno::Reference
< css::lang::XSingleServiceFactory
> const &
94 css::uno::Reference
< css::lang::XComponent
> const &
96 name(theName
), isSingleInstance(false), constructorFn(nullptr),
97 factory1(theFactory1
), factory2(theFactory2
),
98 component(theComponent
), status(STATUS_LOADED
), dispose(true)
99 { assert(theFactory1
.is() || theFactory2
.is()); }
101 Implementation(const Implementation
&) = delete;
102 const Implementation
& operator=(const Implementation
&) = delete;
104 css::uno::Reference
<css::uno::XInterface
> createInstance(
105 css::uno::Reference
<css::uno::XComponentContext
> const &
107 bool singletonRequest
);
109 css::uno::Reference
<css::uno::XInterface
>
110 createInstanceWithArguments(
111 css::uno::Reference
<css::uno::XComponentContext
> const &
113 bool singletonRequest
,
114 css::uno::Sequence
<css::uno::Any
> const & arguments
);
116 bool shallDispose() const { return isSingleInstance
|| !singletons
.empty(); }
118 enum Status
{ STATUS_NEW
, STATUS_WRAPPER
, STATUS_LOADED
};
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
134 OUString environment
;
135 OUString constructorName
;
137 bool isSingleInstance
;
138 css::uno::Reference
< css::uno::XComponentContext
> alienContext
;
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
;
149 css::uno::Reference
<css::uno::XInterface
> singleInstance
;
150 css::uno::Reference
< css::lang::XComponent
> disposeInstance
;
154 css::uno::Reference
<css::uno::XInterface
> doCreateInstance(
155 css::uno::Reference
<css::uno::XComponentContext
> const & context
);
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
);
161 void updateDisposeInstance(
162 bool singletonRequest
,
163 css::uno::Reference
<css::uno::XInterface
> const & instance
);
166 typedef std::map
< OUString
, std::shared_ptr
< Implementation
> >
167 NamedImplementations
;
171 css::uno::Reference
< css::lang::XServiceInfo
>,
172 std::shared_ptr
< Implementation
> >
173 DynamicImplementations
;
178 std::vector
< std::shared_ptr
< Implementation
> > >
181 NamedImplementations namedImplementations
;
182 DynamicImplementations dynamicImplementations
;
183 ImplementationMap services
;
184 ImplementationMap singletons
;
187 ServiceManager(): ServiceManagerBase(m_aMutex
) {}
189 ServiceManager(const ServiceManager
&) = delete;
190 const ServiceManager
& operator=(const ServiceManager
&) = delete;
192 using ServiceManagerBase::acquire
;
193 using ServiceManagerBase::release
;
195 void init(OUString
const & rdbUris
);
198 css::uno::Reference
< css::uno::XComponentContext
> const & context
)
200 assert(context
.is());
201 assert(!context_
.is());
205 void addSingletonContextEntries(
206 std::vector
< cppu::ContextEntry_Init
> * entries
);
208 css::uno::Reference
< css::uno::XComponentContext
> const & getContext()
211 assert(context_
.is());
215 void loadImplementation(
216 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
217 std::shared_ptr
< Data::Implementation
> const & implementation
);
220 virtual ~ServiceManager() override
;
222 virtual void SAL_CALL
disposing() override
;
224 virtual OUString SAL_CALL
getImplementationName() override
;
226 virtual sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
;
228 virtual css::uno::Sequence
< OUString
> SAL_CALL
229 getSupportedServiceNames() override
;
231 virtual css::uno::Reference
< css::uno::XInterface
> SAL_CALL
createInstance(
232 OUString
const & aServiceSpecifier
) override
;
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
;
239 virtual css::uno::Sequence
< OUString
> SAL_CALL
240 getAvailableServiceNames() override
;
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
;
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
;
253 virtual css::uno::Type SAL_CALL
getElementType() override
;
255 virtual sal_Bool SAL_CALL
hasElements() override
;
257 virtual css::uno::Reference
< css::container::XEnumeration
> SAL_CALL
258 createEnumeration() override
;
260 virtual sal_Bool SAL_CALL
has(css::uno::Any
const & aElement
) override
;
262 virtual void SAL_CALL
insert(css::uno::Any
const & aElement
) override
;
264 virtual void SAL_CALL
remove(css::uno::Any
const & aElement
) override
;
266 virtual css::uno::Reference
< css::container::XEnumeration
> SAL_CALL
267 createContentEnumeration(OUString
const & aServiceName
) override
;
269 virtual css::uno::Reference
< css::beans::XPropertySetInfo
> SAL_CALL
270 getPropertySetInfo() override
;
272 virtual void SAL_CALL
setPropertyValue(
273 OUString
const & aPropertyName
, css::uno::Any
const & aValue
) override
;
275 virtual css::uno::Any SAL_CALL
getPropertyValue(
276 OUString
const & PropertyName
) override
;
278 virtual void SAL_CALL
addPropertyChangeListener(
279 OUString
const & aPropertyName
,
280 css::uno::Reference
< css::beans::XPropertyChangeListener
> const &
283 virtual void SAL_CALL
removePropertyChangeListener(
284 OUString
const & aPropertyName
,
285 css::uno::Reference
< css::beans::XPropertyChangeListener
> const &
288 virtual void SAL_CALL
addVetoableChangeListener(
289 OUString
const & PropertyName
,
290 css::uno::Reference
< css::beans::XVetoableChangeListener
> const &
293 virtual void SAL_CALL
removeVetoableChangeListener(
294 OUString
const & PropertyName
,
295 css::uno::Reference
< css::beans::XVetoableChangeListener
> const &
298 virtual css::uno::Sequence
< css::beans::Property
> SAL_CALL
getProperties() override
;
300 virtual css::beans::Property SAL_CALL
getPropertyByName(
301 OUString
const & aName
) override
;
303 virtual sal_Bool SAL_CALL
hasPropertyByName(OUString
const & Name
) override
;
305 virtual void SAL_CALL
disposing(css::lang::EventObject
const & Source
) override
;
307 virtual void SAL_CALL
initialize(
308 css::uno::Sequence
<css::uno::Any
> const & aArguments
)
311 // needs to be called with rBHelper.rMutex locked:
312 bool isDisposed() const { return rBHelper
.bDisposed
|| rBHelper
.bInDispose
; }
314 void removeEventListenerFromComponent(
315 css::uno::Reference
< css::lang::XComponent
> const & component
);
317 void readRdbDirectory(OUString
const & uri
, bool optional
);
319 void readRdbFile(OUString
const & uri
, bool optional
);
321 bool readLegacyRdbFile(OUString
const & uri
);
323 OUString
readLegacyRdbString(
324 OUString
const & uri
, RegistryKey
& key
,
325 OUString
const & path
);
327 void readLegacyRdbStrings(
328 OUString
const & uri
, RegistryKey
& key
,
329 OUString
const & path
, std::vector
< OUString
> * strings
);
332 std::vector
< OUString
> const & uris
,
333 css::uno::Reference
< css::uno::XComponentContext
> const &
336 void insertLegacyFactory(
337 css::uno::Reference
< css::lang::XServiceInfo
> const & factoryInfo
);
339 bool insertExtraData(Data
const & extra
);
341 void removeRdbFiles(std::vector
< OUString
> const & uris
);
343 bool removeLegacyFactory(
344 css::uno::Reference
< css::lang::XServiceInfo
> const & factoryInfo
,
345 bool removeListener
);
347 void removeImplementation(const OUString
& name
);
349 std::shared_ptr
< Data::Implementation
> findServiceImplementation(
350 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
351 OUString
const & specifier
);
353 void preloadImplementations();
355 css::uno::Reference
< css::uno::XComponentContext
> context_
;
361 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */