LibreOffice Module cppuhelper (master)  1
servicemanager.hxx
Go to the documentation of this file.
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 <unordered_map>
16 #include <memory>
17 #include <string_view>
18 #include <vector>
19 
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>
34 
35 namespace com::sun::star::lang {
36  class XSingleComponentFactory;
37 }
38 namespace cppu { struct ContextEntry_Init; }
39 namespace com :: sun :: star :: lang { class XSingleServiceFactory; }
40 namespace com :: sun :: star :: uno { class XComponentContext; }
41 
42 class RegistryKey;
43 
44 namespace cppuhelper {
45 
46 extern "C" {
47 
48 typedef css::uno::XInterface * ImplementationConstructorFn(
49  css::uno::XComponentContext *, css::uno::Sequence<css::uno::Any> const &);
50 
51 }
52 
53 typedef std::function<css::uno::XInterface * (css::uno::XComponentContext *, css::uno::Sequence<css::uno::Any> const&)> WrapperConstructorFn;
54 
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>
62 
64  private cppu::BaseMutex, public ServiceManagerBase
65 {
66 public:
67  struct Data {
68  Data() = default;
69  Data(const Data&) = delete;
70  const Data& operator=(const Data&) = delete;
71 
72  struct Implementation {
74  OUString const & theName, OUString const & theLoader,
75  OUString const & theUri, OUString const & theEnvironment,
76  OUString const & theConstructorName,
77  OUString const & thePrefix,
78  bool theIsSingleInstance,
79  css::uno::Reference< css::uno::XComponentContext > const &
80  theAlienContext,
81  OUString const & theRdbFile):
82  name(theName), loader(theLoader), uri(theUri), environment(theEnvironment),
83  constructorName(theConstructorName), prefix(thePrefix),
84  isSingleInstance(theIsSingleInstance),
85  alienContext(theAlienContext), rdbFile(theRdbFile),
86  constructorFn(nullptr), status(STATUS_NEW), dispose(true)
87  {}
88 
90  OUString const & 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 > const &
96  theComponent):
97  name(theName), isSingleInstance(false), constructorFn(nullptr),
98  factory1(theFactory1), factory2(theFactory2),
99  component(theComponent), status(STATUS_LOADED), dispose(true)
100  { assert(theFactory1.is() || theFactory2.is()); }
101 
102  Implementation(const Implementation&) = delete;
103  const Implementation& operator=(const Implementation&) = delete;
104 
105  css::uno::Reference<css::uno::XInterface> createInstance(
106  css::uno::Reference<css::uno::XComponentContext> const &
107  context,
108  bool singletonRequest);
109 
110  css::uno::Reference<css::uno::XInterface>
112  css::uno::Reference<css::uno::XComponentContext> const &
113  context,
114  bool singletonRequest,
115  css::uno::Sequence<css::uno::Any> const & arguments);
116 
117  bool shallDispose() const { return isSingleInstance || !singletons.empty(); }
118 
120 
121  // Logically, exactly one of constructorFn, factory1, factory2 should
122  // be set. However, there are two exceptions: For one, when
123  // constructorFn is set, ServiceManager::createContentEnumeration will
124  // store the necessary ImplementationWrapper in factory1 (so that
125  // multiple calls to createContentEnumeration will return the same
126  // wrapper). For another, when factory1 should be set but status is
127  // STATUS_NEW, factory1 is not yet set (and when status is
128  // STATUS_WRAPPER, factory1 is merely set to an
129  // ImplementationWrapper---also due to a
130  // ServiceManager::createContentEnumeration call---and will be
131  // loaded later).
132  OUString name;
133  OUString loader;
134  OUString uri;
135  OUString environment;
136  OUString constructorName;
137  OUString prefix;
139  css::uno::Reference< css::uno::XComponentContext > alienContext;
140  OUString rdbFile;
141  std::vector< OUString > services;
142  std::vector< OUString > singletons;
144  css::uno::Reference< css::lang::XSingleComponentFactory > factory1;
145  css::uno::Reference< css::lang::XSingleServiceFactory > factory2;
146  css::uno::Reference< css::lang::XComponent > component;
148 
149  osl::Mutex mutex;
150  css::uno::Reference<css::uno::XInterface> singleInstance;
151  css::uno::Reference< css::lang::XComponent > disposeInstance;
152  bool dispose;
153 
154  private:
155  css::uno::Reference<css::uno::XInterface> doCreateInstance(
156  css::uno::Reference<css::uno::XComponentContext> const & context);
157 
158  css::uno::Reference<css::uno::XInterface> doCreateInstanceWithArguments(
159  css::uno::Reference<css::uno::XComponentContext> const & context,
160  css::uno::Sequence<css::uno::Any> const & arguments);
161 
163  bool singletonRequest,
164  css::uno::Reference<css::uno::XInterface> const & instance);
165  };
166 
167  typedef std::unordered_map< OUString, std::shared_ptr< Implementation > >
169 
170  typedef
171  std::unordered_map<
172  css::uno::Reference< css::lang::XServiceInfo >,
173  std::shared_ptr< Implementation > >
175 
176  typedef
177  std::unordered_map<
178  OUString,
179  std::vector< std::shared_ptr< Implementation > > >
181 
186  };
187 
189 
190  ServiceManager(const ServiceManager&) = delete;
191  const ServiceManager& operator=(const ServiceManager&) = delete;
192 
193  using ServiceManagerBase::acquire;
194  using ServiceManagerBase::release;
195 
196  void init(OUString const & rdbUris);
197 
199  css::uno::Reference< css::uno::XComponentContext > const & context)
200  {
201  assert(context.is());
202  assert(!context_.is());
203  context_ = context;
204  }
205 
207  std::vector< cppu::ContextEntry_Init > * entries);
208 
209  css::uno::Reference< css::uno::XComponentContext > const & getContext()
210  const
211  {
212  assert(context_.is());
213  return context_;
214  }
215 
216  void loadImplementation(
217  css::uno::Reference< css::uno::XComponentContext > const & context,
218  std::shared_ptr< Data::Implementation > const & implementation);
219 
220 private:
221  virtual ~ServiceManager() override;
222 
223  virtual void SAL_CALL disposing() override;
224 
225  virtual OUString SAL_CALL getImplementationName() override;
226 
227  virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override;
228 
229  virtual css::uno::Sequence< OUString > SAL_CALL
230  getSupportedServiceNames() override;
231 
232  virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
233  OUString const & aServiceSpecifier) override;
234 
235  virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
237  OUString const & ServiceSpecifier,
238  css::uno::Sequence< css::uno::Any > const & Arguments) override;
239 
240  virtual css::uno::Sequence< OUString > SAL_CALL
241  getAvailableServiceNames() override;
242 
243  virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
245  OUString const & aServiceSpecifier,
246  css::uno::Reference< css::uno::XComponentContext > const & Context) override;
247 
248  virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
250  OUString const & ServiceSpecifier,
251  css::uno::Sequence< css::uno::Any > const & Arguments,
252  css::uno::Reference< css::uno::XComponentContext > const & Context) override;
253 
254  virtual css::uno::Type SAL_CALL getElementType() override;
255 
256  virtual sal_Bool SAL_CALL hasElements() override;
257 
258  virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL
259  createEnumeration() override;
260 
261  virtual sal_Bool SAL_CALL has(css::uno::Any const & aElement) override;
262 
263  virtual void SAL_CALL insert(css::uno::Any const & aElement) override;
264 
265  virtual void SAL_CALL remove(css::uno::Any const & aElement) override;
266 
267  virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL
268  createContentEnumeration(OUString const & aServiceName) override;
269 
270  virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
271  getPropertySetInfo() override;
272 
273  virtual void SAL_CALL setPropertyValue(
274  OUString const & aPropertyName, css::uno::Any const & aValue) override;
275 
276  virtual css::uno::Any SAL_CALL getPropertyValue(
277  OUString const & PropertyName) override;
278 
279  virtual void SAL_CALL addPropertyChangeListener(
280  OUString const & aPropertyName,
281  css::uno::Reference< css::beans::XPropertyChangeListener > const &
282  xListener) override;
283 
284  virtual void SAL_CALL removePropertyChangeListener(
285  OUString const & aPropertyName,
286  css::uno::Reference< css::beans::XPropertyChangeListener > const &
287  aListener) override;
288 
289  virtual void SAL_CALL addVetoableChangeListener(
290  OUString const & PropertyName,
291  css::uno::Reference< css::beans::XVetoableChangeListener > const &
292  aListener) override;
293 
294  virtual void SAL_CALL removeVetoableChangeListener(
295  OUString const & PropertyName,
296  css::uno::Reference< css::beans::XVetoableChangeListener > const &
297  aListener) override;
298 
299  virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties() override;
300 
301  virtual css::beans::Property SAL_CALL getPropertyByName(
302  OUString const & aName) override;
303 
304  virtual sal_Bool SAL_CALL hasPropertyByName(OUString const & Name) override;
305 
306  virtual void SAL_CALL disposing(css::lang::EventObject const & Source) override;
307 
308  virtual void SAL_CALL initialize(
309  css::uno::Sequence<css::uno::Any> const & aArguments)
310  override;
311 
312  // needs to be called with rBHelper.rMutex locked:
313  bool isDisposed() const { return rBHelper.bDisposed || rBHelper.bInDispose; }
314 
316  css::uno::Reference< css::lang::XComponent > const & component);
317 
318  void readRdbDirectory(OUString const & uri, bool optional);
319 
320  void readRdbFile(OUString const & uri, bool optional);
321 
322  bool readLegacyRdbFile(OUString const & uri);
323 
324  OUString readLegacyRdbString(
325  std::u16string_view uri, RegistryKey & key,
326  OUString const & path);
327 
329  std::u16string_view uri, RegistryKey & key,
330  OUString const & path, std::vector< OUString > * strings);
331 
332  void insertRdbFiles(
333  std::vector< OUString > const & uris,
334  css::uno::Reference< css::uno::XComponentContext > const &
335  alientContext);
336 
337  void insertLegacyFactory(
338  css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo);
339 
340  bool insertExtraData(Data const & extra);
341 
342  void removeRdbFiles(std::vector< OUString > const & uris);
343 
344  bool removeLegacyFactory(
345  css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo,
346  bool removeListener);
347 
348  void removeImplementation(const OUString & name);
349 
350  std::shared_ptr< Data::Implementation > findServiceImplementation(
351  css::uno::Reference< css::uno::XComponentContext > const & context,
352  OUString const & specifier);
353 
354  void preloadImplementations();
355 
356  css::uno::Reference< css::uno::XComponentContext > context_;
358 };
359 
360 }
361 
362 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void SAL_CALL removeVetoableChangeListener(OUString const &PropertyName, css::uno::Reference< css::beans::XVetoableChangeListener > const &aListener) override
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
virtual void SAL_CALL disposing() override
const ServiceManager & operator=(const ServiceManager &)=delete
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(OUString const &aServiceSpecifier) override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArguments(OUString const &ServiceSpecifier, css::uno::Sequence< css::uno::Any > const &Arguments) override
css::uno::Reference< css::uno::XInterface > doCreateInstance(css::uno::Reference< css::uno::XComponentContext > const &context)
bool readLegacyRdbFile(OUString const &uri)
Implementation(OUString const &theName, OUString const &theLoader, OUString const &theUri, OUString const &theEnvironment, OUString const &theConstructorName, OUString const &thePrefix, bool theIsSingleInstance, css::uno::Reference< css::uno::XComponentContext > const &theAlienContext, OUString const &theRdbFile)
css::uno::Reference< css::uno::XComponentContext > alienContext
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual void SAL_CALL initialize(css::uno::Sequence< css::uno::Any > const &aArguments) override
std::shared_ptr< Data::Implementation > findServiceImplementation(css::uno::Reference< css::uno::XComponentContext > const &context, OUString const &specifier)
virtual sal_Bool SAL_CALL hasPropertyByName(OUString const &Name) override
void setContext(css::uno::Reference< css::uno::XComponentContext > const &context)
mutable::osl::Mutex m_aMutex
Definition: basemutex.hxx:42
virtual void SAL_CALL insert(css::uno::Any const &aElement) override
virtual css::uno::Type SAL_CALL getElementType() override
css::uno::Reference< css::uno::XInterface > doCreateInstanceWithArguments(css::uno::Reference< css::uno::XComponentContext > const &context, css::uno::Sequence< css::uno::Any > const &arguments)
virtual ~ServiceManager() override
css::uno::Reference< css::uno::XInterface > createInstance(css::uno::Reference< css::uno::XComponentContext > const &context, bool singletonRequest)
bool removeLegacyFactory(css::uno::Reference< css::lang::XServiceInfo > const &factoryInfo, bool removeListener)
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
OUString readLegacyRdbString(std::u16string_view uri, RegistryKey &key, OUString const &path)
virtual sal_Bool SAL_CALL hasElements() override
css::uno::Reference< css::lang::XSingleServiceFactory > factory2
void loadImplementation(css::uno::Reference< css::uno::XComponentContext > const &context, std::shared_ptr< Data::Implementation > const &implementation)
virtual css::beans::Property SAL_CALL getPropertyByName(OUString const &aName) override
void addSingletonContextEntries(std::vector< cppu::ContextEntry_Init > *entries)
bool insertExtraData(Data const &extra)
css::uno::XInterface * ImplementationConstructorFn(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithContext(OUString const &aServiceSpecifier, css::uno::Reference< css::uno::XComponentContext > const &Context) override
css::uno::Reference< css::uno::XComponentContext > context_
NamedImplementations namedImplementations
css::uno::Reference< css::uno::XInterface > createInstanceWithArguments(css::uno::Reference< css::uno::XComponentContext > const &context, bool singletonRequest, css::uno::Sequence< css::uno::Any > const &arguments)
virtual sal_Bool SAL_CALL has(css::uno::Any const &aElement) override
virtual void SAL_CALL addVetoableChangeListener(OUString const &PropertyName, css::uno::Reference< css::beans::XVetoableChangeListener > const &aListener) override
void updateDisposeInstance(bool singletonRequest, css::uno::Reference< css::uno::XInterface > const &instance)
void insertLegacyFactory(css::uno::Reference< css::lang::XServiceInfo > const &factoryInfo)
std::unordered_map< OUString, std::shared_ptr< Implementation > > NamedImplementations
virtual css::uno::Any SAL_CALL getPropertyValue(OUString const &PropertyName) override
base class for all classes who want derive from cppu::WeakComponentImplHelperXX.
Definition: basemutex.hxx:39
virtual void SAL_CALL addPropertyChangeListener(OUString const &aPropertyName, css::uno::Reference< css::beans::XPropertyChangeListener > const &xListener) override
virtual void SAL_CALL removePropertyChangeListener(OUString const &aPropertyName, css::uno::Reference< css::beans::XPropertyChangeListener > const &aListener) override
Implementation(OUString const &theName, css::uno::Reference< css::lang::XSingleComponentFactory > const &theFactory1, css::uno::Reference< css::lang::XSingleServiceFactory > const &theFactory2, css::uno::Reference< css::lang::XComponent > const &theComponent)
void readRdbFile(OUString const &uri, bool optional)
virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties() override
unsigned char sal_Bool
void removeImplementation(const OUString &name)
virtual css::uno::Sequence< OUString > SAL_CALL getAvailableServiceNames() override
void insertRdbFiles(std::vector< OUString > const &uris, css::uno::Reference< css::uno::XComponentContext > const &alientContext)
void removeEventListenerFromComponent(css::uno::Reference< css::lang::XComponent > const &component)
std::function< css::uno::XInterface *(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)> WrapperConstructorFn
css::uno::Reference< css::uno::XComponentContext > const & getContext() const
void removeRdbFiles(std::vector< OUString > const &uris)
virtual void SAL_CALL setPropertyValue(OUString const &aPropertyName, css::uno::Any const &aValue) override
const Data & operator=(const Data &)=delete
virtual sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
void init(OUString const &rdbUris)
std::unordered_map< OUString, std::vector< std::shared_ptr< Implementation > > > ImplementationMap
exports com.sun.star. lang
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArgumentsAndContext(OUString const &ServiceSpecifier, css::uno::Sequence< css::uno::Any > const &Arguments, css::uno::Reference< css::uno::XComponentContext > const &Context) override
void preloadImplementations()
Used only by LibreOfficeKit when used by Online to pre-initialize.
const Implementation & operator=(const Implementation &)=delete
css::uno::Reference< css::lang::XSingleComponentFactory > factory1
css::uno::Reference< css::lang::XComponent > component
std::unordered_map< css::uno::Reference< css::lang::XServiceInfo >, std::shared_ptr< Implementation > > DynamicImplementations
css::uno::Reference< css::lang::XComponent > disposeInstance
DynamicImplementations dynamicImplementations
void readRdbDirectory(OUString const &uri, bool optional)
virtual OUString SAL_CALL getImplementationName() override
void readLegacyRdbStrings(std::u16string_view uri, RegistryKey &key, OUString const &path, std::vector< OUString > *strings)
cppu::WeakComponentImplHelper< css::lang::XServiceInfo, css::lang::XMultiServiceFactory, css::lang::XMultiComponentFactory, css::container::XSet, css::container::XContentEnumerationAccess, css::beans::XPropertySet, css::beans::XPropertySetInfo, css::lang::XEventListener, css::lang::XInitialization > ServiceManagerBase
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createContentEnumeration(OUString const &aServiceName) override
css::uno::Reference< css::uno::XInterface > singleInstance