use boost::small_vector in cppuhelper
[libreoffice.git] / cppuhelper / source / servicemanager.hxx
blob8ab144b115eedcbffc0c8309287b8c87121ac6be
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #pragma once
12 #include <sal/config.h>
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>
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>
37 namespace com::sun::star::lang {
38 class XSingleComponentFactory;
40 namespace cppu { struct ContextEntry_Init; }
41 namespace com :: sun :: star :: lang { class XSingleServiceFactory; }
42 namespace com :: sun :: star :: uno { class XComponentContext; }
44 class RegistryKey;
46 namespace cppuhelper {
48 extern "C" {
50 typedef css::uno::XInterface * ImplementationConstructorFn(
51 css::uno::XComponentContext *, css::uno::Sequence<css::uno::Any> const &);
55 typedef std::function<css::uno::XInterface * (css::uno::XComponentContext *, css::uno::Sequence<css::uno::Any> const&)> WrapperConstructorFn;
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;
65 class ServiceManager : public ServiceManagerBase
67 public:
68 struct Data {
69 Data() = default;
70 Data(const Data&) = delete;
71 const Data& operator=(const Data&) = delete;
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 name(std::move(theName)), loader(std::move(theLoader)), uri(std::move(theUri)), environment(std::move(theEnvironment)),
83 constructorName(std::move(theConstructorName)), prefix(std::move(thePrefix)),
84 isSingleInstance(theIsSingleInstance),
85 alienContext(std::move(theAlienContext)), rdbFile(std::move(theRdbFile)),
86 constructorFn(nullptr), status(STATUS_NEW), dispose(true)
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 name(std::move(theName)), isSingleInstance(false), constructorFn(nullptr),
97 factory1(theFactory1), factory2(theFactory2),
98 component(std::move(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 &
106 context,
107 bool singletonRequest);
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);
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
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;
148 std::mutex mutex;
149 css::uno::Reference<css::uno::XInterface> singleInstance;
150 css::uno::Reference< css::lang::XComponent > disposeInstance;
151 bool dispose;
153 private:
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::unordered_map< OUString, std::shared_ptr< Implementation > >
167 NamedImplementations;
169 typedef
170 std::unordered_map<
171 css::uno::Reference< css::lang::XServiceInfo >,
172 std::shared_ptr< Implementation > >
173 DynamicImplementations;
175 typedef
176 std::unordered_map<
177 OUString,
178 boost::container::small_vector< std::shared_ptr< Implementation >, 2 > >
179 ImplementationMap;
181 NamedImplementations namedImplementations;
182 DynamicImplementations dynamicImplementations;
183 ImplementationMap services;
184 ImplementationMap singletons;
187 ServiceManager() {}
189 ServiceManager(const ServiceManager&) = delete;
190 const ServiceManager& operator=(const ServiceManager&) = delete;
192 using ServiceManagerBase::acquire;
193 using ServiceManagerBase::release;
195 void init(std::u16string_view rdbUris);
197 void setContext(
198 css::uno::Reference< css::uno::XComponentContext > const & context)
200 assert(context.is());
201 assert(!context_.is());
202 context_ = context;
205 void addSingletonContextEntries(
206 std::vector< cppu::ContextEntry_Init > * entries);
208 css::uno::Reference< css::uno::XComponentContext > const & getContext()
209 const
211 assert(context_.is());
212 return context_;
215 void loadImplementation(
216 css::uno::Reference< css::uno::XComponentContext > const & context,
217 std::shared_ptr< Data::Implementation > const & implementation);
219 private:
220 virtual ~ServiceManager() override;
222 virtual void disposing(std::unique_lock<std::mutex>&) 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 &
281 xListener) override;
283 virtual void SAL_CALL removePropertyChangeListener(
284 OUString const & aPropertyName,
285 css::uno::Reference< css::beans::XPropertyChangeListener > const &
286 aListener) override;
288 virtual void SAL_CALL addVetoableChangeListener(
289 OUString const & PropertyName,
290 css::uno::Reference< css::beans::XVetoableChangeListener > const &
291 aListener) override;
293 virtual void SAL_CALL removeVetoableChangeListener(
294 OUString const & PropertyName,
295 css::uno::Reference< css::beans::XVetoableChangeListener > const &
296 aListener) override;
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)
309 override;
311 void removeEventListenerFromComponent(
312 css::uno::Reference< css::lang::XComponent > const & component);
314 void readRdbDirectory(std::u16string_view uri, bool optional);
316 void readRdbFile(OUString const & uri, bool optional);
318 bool readLegacyRdbFile(OUString const & uri);
320 OUString readLegacyRdbString(
321 std::u16string_view uri, RegistryKey & key,
322 OUString const & path);
324 void readLegacyRdbStrings(
325 std::u16string_view uri, RegistryKey & key,
326 OUString const & path, std::vector< OUString > * strings);
328 void insertRdbFiles(
329 std::vector< OUString > const & uris,
330 css::uno::Reference< css::uno::XComponentContext > const &
331 alientContext);
333 void insertLegacyFactory(
334 css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo);
336 bool insertExtraData(Data const & extra);
338 void removeRdbFiles(std::vector< OUString > const & uris);
340 bool removeLegacyFactory(
341 css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo,
342 bool removeListener);
344 void removeImplementation(const OUString & name);
346 std::shared_ptr< Data::Implementation > findServiceImplementation(
347 css::uno::Reference< css::uno::XComponentContext > const & context,
348 OUString const & specifier);
350 void preloadImplementations();
352 css::uno::Reference< css::uno::XComponentContext > context_;
353 Data data_;
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */