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/.
10 #ifndef INCLUDED_CPPUHELPER_SOURCE_SERVICEMANAGER_HXX
11 #define INCLUDED_CPPUHELPER_SOURCE_SERVICEMANAGER_HXX
13 #include <sal/config.h>
20 #include <com/sun/star/beans/XPropertySet.hpp>
21 #include <com/sun/star/beans/XPropertySetInfo.hpp>
22 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
23 #include <com/sun/star/container/XSet.hpp>
24 #include <com/sun/star/lang/XEventListener.hpp>
25 #include <com/sun/star/lang/XInitialization.hpp>
26 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 #include <com/sun/star/lang/XServiceInfo.hpp>
29 #include <com/sun/star/uno/Reference.hxx>
30 #include <cppuhelper/basemutex.hxx>
31 #include <cppuhelper/compbase.hxx>
32 #include <osl/mutex.hxx>
33 #include <rtl/ustring.hxx>
35 namespace com
{ namespace sun
{ namespace star
{ namespace lang
{
36 class XSingleComponentFactory
;
38 namespace cppu
{ struct ContextEntry_Init
; }
39 namespace com :: sun :: star :: lang
{ class XSingleServiceFactory
; }
40 namespace com :: sun :: star :: uno
{ class XComponentContext
; }
44 namespace cppuhelper
{
48 typedef css::uno::XInterface
* ImplementationConstructorFn(
49 css::uno::XComponentContext
*, css::uno::Sequence
<css::uno::Any
> const &);
53 typedef std::function
<css::uno::XInterface
* (css::uno::XComponentContext
*, css::uno::Sequence
<css::uno::Any
> const&)> WrapperConstructorFn
;
55 typedef cppu::WeakComponentImplHelper
<
56 css::lang::XServiceInfo
, css::lang::XMultiServiceFactory
,
57 css::lang::XMultiComponentFactory
, css::container::XSet
,
58 css::container::XContentEnumerationAccess
, css::beans::XPropertySet
,
59 css::beans::XPropertySetInfo
, css::lang::XEventListener
,
60 css::lang::XInitialization
>
64 private cppu::BaseMutex
, public ServiceManagerBase
69 Data(const Data
&) = delete;
70 const Data
& operator=(const Data
&) = delete;
72 struct ImplementationInfo
{
74 OUString
const & theName
, OUString
const & theLoader
,
75 OUString
const & theUri
,
76 OUString
const & theEnvironment
,
77 OUString
const & theConstructor
,
78 OUString
const & thePrefix
,
79 css::uno::Reference
< css::uno::XComponentContext
> const &
81 OUString
const & theRdbFile
):
82 name(theName
), loader(theLoader
), uri(theUri
),
83 environment(theEnvironment
), constructor(theConstructor
),
84 prefix(thePrefix
), alienContext(theAlienContext
),
88 explicit ImplementationInfo(OUString
const & theName
):
91 ImplementationInfo(const ImplementationInfo
&) = delete;
92 const ImplementationInfo
& operator=(const ImplementationInfo
&) = delete;
95 OUString
const loader
;
97 OUString
const environment
;
98 OUString
const constructor
;
99 OUString
const prefix
;
100 css::uno::Reference
< css::uno::XComponentContext
> const
102 OUString
const rdbFile
;
103 std::vector
< OUString
> services
;
104 std::vector
< OUString
> singletons
;
107 struct Implementation
{
109 OUString
const & name
, OUString
const & loader
,
110 OUString
const & uri
, OUString
const & environment
,
111 OUString
const & constructorName
,
112 OUString
const & prefix
,
113 css::uno::Reference
< css::uno::XComponentContext
> const &
115 OUString
const & rdbFile
):
117 new ImplementationInfo(
118 name
, loader
, uri
, environment
, constructorName
, prefix
,
119 alienContext
, rdbFile
)),
120 constructor(nullptr), status(STATUS_NEW
), dispose(true)
124 OUString
const & name
,
125 css::uno::Reference
< css::lang::XSingleComponentFactory
>
127 css::uno::Reference
< css::lang::XSingleServiceFactory
> const &
129 css::uno::Reference
< css::lang::XComponent
> const &
131 info(new ImplementationInfo(name
)), constructor(nullptr),
132 factory1(theFactory1
), factory2(theFactory2
),
133 component(theComponent
), status(STATUS_LOADED
), dispose(true)
134 { assert(theFactory1
.is() || theFactory2
.is()); }
136 Implementation(const Implementation
&) = delete;
137 const Implementation
& operator=(const Implementation
&) = delete;
139 css::uno::Reference
<css::uno::XInterface
> createInstance(
140 css::uno::Reference
<css::uno::XComponentContext
> const &
142 bool singletonRequest
);
144 css::uno::Reference
<css::uno::XInterface
>
145 createInstanceWithArguments(
146 css::uno::Reference
<css::uno::XComponentContext
> const &
148 bool singletonRequest
,
149 css::uno::Sequence
<css::uno::Any
> const & arguments
);
151 enum Status
{ STATUS_NEW
, STATUS_WRAPPER
, STATUS_LOADED
};
153 // Logically, exactly one of constructor, factory1, factory2 should
154 // be set. However, there are two exceptions: For one, when
155 // constructor is set, ServiceManager::createContentEnumeration will
156 // store the necessary ImplementationWrapper in factory1 (so that
157 // multiple calls to createContentEnumeration will return the same
158 // wrapper). For another, when factory1 should be set but status is
159 // STATUS_NEW, factory1 is not yet set (and when status is
160 // STATUS_WRAPPER, factory1 is merely set to an
161 // ImplementationWrapper---also due to a
162 // ServiceManager::createContentEnumeration call---and will be
164 std::shared_ptr
< ImplementationInfo
> info
;
165 WrapperConstructorFn constructor
;
166 css::uno::Reference
< css::lang::XSingleComponentFactory
> factory1
;
167 css::uno::Reference
< css::lang::XSingleServiceFactory
> factory2
;
168 css::uno::Reference
< css::lang::XComponent
> component
;
172 css::uno::Reference
< css::lang::XComponent
> disposeSingleton
;
176 void updateDisposeSingleton(
177 bool singletonRequest
,
178 css::uno::Reference
<css::uno::XInterface
> const & instance
);
181 typedef std::map
< OUString
, std::shared_ptr
< Implementation
> >
182 NamedImplementations
;
186 css::uno::Reference
< css::lang::XServiceInfo
>,
187 std::shared_ptr
< Implementation
> >
188 DynamicImplementations
;
193 std::vector
< std::shared_ptr
< Implementation
> > >
196 NamedImplementations namedImplementations
;
197 DynamicImplementations dynamicImplementations
;
198 ImplementationMap services
;
199 ImplementationMap singletons
;
202 ServiceManager(): ServiceManagerBase(m_aMutex
) {}
204 ServiceManager(const ServiceManager
&) = delete;
205 const ServiceManager
& operator=(const ServiceManager
&) = delete;
207 using ServiceManagerBase::acquire
;
208 using ServiceManagerBase::release
;
210 void init(OUString
const & rdbUris
);
213 css::uno::Reference
< css::uno::XComponentContext
> const & context
)
215 assert(context
.is());
216 assert(!context_
.is());
220 void addSingletonContextEntries(
221 std::vector
< cppu::ContextEntry_Init
> * entries
);
223 css::uno::Reference
< css::uno::XComponentContext
> const & getContext()
226 assert(context_
.is());
230 void loadImplementation(
231 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
232 std::shared_ptr
< Data::Implementation
> const & implementation
);
235 virtual ~ServiceManager() override
;
237 virtual void SAL_CALL
disposing() override
;
239 virtual OUString SAL_CALL
getImplementationName() override
;
241 virtual sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
;
243 virtual css::uno::Sequence
< OUString
> SAL_CALL
244 getSupportedServiceNames() override
;
246 virtual css::uno::Reference
< css::uno::XInterface
> SAL_CALL
createInstance(
247 OUString
const & aServiceSpecifier
) override
;
249 virtual css::uno::Reference
< css::uno::XInterface
> SAL_CALL
250 createInstanceWithArguments(
251 OUString
const & ServiceSpecifier
,
252 css::uno::Sequence
< css::uno::Any
> const & Arguments
) override
;
254 virtual css::uno::Sequence
< OUString
> SAL_CALL
255 getAvailableServiceNames() override
;
257 virtual css::uno::Reference
< css::uno::XInterface
> SAL_CALL
258 createInstanceWithContext(
259 OUString
const & aServiceSpecifier
,
260 css::uno::Reference
< css::uno::XComponentContext
> const & Context
) override
;
262 virtual css::uno::Reference
< css::uno::XInterface
> SAL_CALL
263 createInstanceWithArgumentsAndContext(
264 OUString
const & ServiceSpecifier
,
265 css::uno::Sequence
< css::uno::Any
> const & Arguments
,
266 css::uno::Reference
< css::uno::XComponentContext
> const & Context
) override
;
268 virtual css::uno::Type SAL_CALL
getElementType() override
;
270 virtual sal_Bool SAL_CALL
hasElements() override
;
272 virtual css::uno::Reference
< css::container::XEnumeration
> SAL_CALL
273 createEnumeration() override
;
275 virtual sal_Bool SAL_CALL
has(css::uno::Any
const & aElement
) override
;
277 virtual void SAL_CALL
insert(css::uno::Any
const & aElement
) override
;
279 virtual void SAL_CALL
remove(css::uno::Any
const & aElement
) override
;
281 virtual css::uno::Reference
< css::container::XEnumeration
> SAL_CALL
282 createContentEnumeration(OUString
const & aServiceName
) override
;
284 virtual css::uno::Reference
< css::beans::XPropertySetInfo
> SAL_CALL
285 getPropertySetInfo() override
;
287 virtual void SAL_CALL
setPropertyValue(
288 OUString
const & aPropertyName
, css::uno::Any
const & aValue
) override
;
290 virtual css::uno::Any SAL_CALL
getPropertyValue(
291 OUString
const & PropertyName
) override
;
293 virtual void SAL_CALL
addPropertyChangeListener(
294 OUString
const & aPropertyName
,
295 css::uno::Reference
< css::beans::XPropertyChangeListener
> const &
298 virtual void SAL_CALL
removePropertyChangeListener(
299 OUString
const & aPropertyName
,
300 css::uno::Reference
< css::beans::XPropertyChangeListener
> const &
303 virtual void SAL_CALL
addVetoableChangeListener(
304 OUString
const & PropertyName
,
305 css::uno::Reference
< css::beans::XVetoableChangeListener
> const &
308 virtual void SAL_CALL
removeVetoableChangeListener(
309 OUString
const & PropertyName
,
310 css::uno::Reference
< css::beans::XVetoableChangeListener
> const &
313 virtual css::uno::Sequence
< css::beans::Property
> SAL_CALL
getProperties() override
;
315 virtual css::beans::Property SAL_CALL
getPropertyByName(
316 OUString
const & aName
) override
;
318 virtual sal_Bool SAL_CALL
hasPropertyByName(OUString
const & Name
) override
;
320 virtual void SAL_CALL
disposing(css::lang::EventObject
const & Source
) override
;
322 virtual void SAL_CALL
initialize(
323 css::uno::Sequence
<css::uno::Any
> const & aArguments
)
326 // needs to be called with rBHelper.rMutex locked:
327 bool isDisposed() const { return rBHelper
.bDisposed
|| rBHelper
.bInDispose
; }
329 void removeEventListenerFromComponent(
330 css::uno::Reference
< css::lang::XComponent
> const & component
);
332 void readRdbDirectory(OUString
const & uri
, bool optional
);
334 void readRdbFile(OUString
const & uri
, bool optional
);
336 bool readLegacyRdbFile(OUString
const & uri
);
338 OUString
readLegacyRdbString(
339 OUString
const & uri
, RegistryKey
& key
,
340 OUString
const & path
);
342 void readLegacyRdbStrings(
343 OUString
const & uri
, RegistryKey
& key
,
344 OUString
const & path
, std::vector
< OUString
> * strings
);
347 std::vector
< OUString
> const & uris
,
348 css::uno::Reference
< css::uno::XComponentContext
> const &
351 void insertLegacyFactory(
352 css::uno::Reference
< css::lang::XServiceInfo
> const & factoryInfo
);
354 bool insertExtraData(Data
const & extra
);
356 void removeRdbFiles(std::vector
< OUString
> const & uris
);
358 bool removeLegacyFactory(
359 css::uno::Reference
< css::lang::XServiceInfo
> const & factoryInfo
,
360 bool removeListener
);
362 void removeImplementation(const OUString
& name
);
364 std::shared_ptr
< Data::Implementation
> findServiceImplementation(
365 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
366 OUString
const & specifier
);
368 void preloadImplementations();
370 css::uno::Reference
< css::uno::XComponentContext
> context_
;
378 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */