Line data Source code
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 : #ifndef INCLUDED_CPPUHELPER_SOURCE_SERVICEMANAGER_HXX
11 : #define INCLUDED_CPPUHELPER_SOURCE_SERVICEMANAGER_HXX
12 :
13 : #include <sal/config.h>
14 :
15 : #include <cassert>
16 : #include <map>
17 : #include <vector>
18 :
19 : #include <boost/noncopyable.hpp>
20 : #include <boost/shared_ptr.hpp>
21 : #include <com/sun/star/beans/XPropertySet.hpp>
22 : #include <com/sun/star/beans/XPropertySetInfo.hpp>
23 : #include <com/sun/star/container/XContentEnumerationAccess.hpp>
24 : #include <com/sun/star/container/XSet.hpp>
25 : #include <com/sun/star/lang/XEventListener.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/lang/XSingleServiceFactory.hpp>
30 : #include <com/sun/star/uno/XComponentContext.hpp>
31 : #include <com/sun/star/uno/Reference.hxx>
32 : #include <cppuhelper/basemutex.hxx>
33 : #include <cppuhelper/compbase8.hxx>
34 : #include <osl/mutex.hxx>
35 : #include <registry/registry.hxx>
36 : #include <rtl/ustring.hxx>
37 : #include <cppuhelper/weak.hxx>
38 :
39 : namespace com { namespace sun { namespace star { namespace lang {
40 : class XSingleComponentFactory;
41 : } } } }
42 : namespace cppu { struct ContextEntry_Init; }
43 :
44 : namespace cppuhelper {
45 :
46 : extern "C" {
47 :
48 : typedef css::uno::XInterface * SAL_CALL ImplementationConstructorFn(
49 : css::uno::XComponentContext *, css::uno::Sequence<css::uno::Any> const &);
50 :
51 : }
52 :
53 : typedef cppu::WeakComponentImplHelper8<
54 : css::lang::XServiceInfo, css::lang::XMultiServiceFactory,
55 : css::lang::XMultiComponentFactory, css::container::XSet,
56 : css::container::XContentEnumerationAccess, css::beans::XPropertySet,
57 : css::beans::XPropertySetInfo, css::lang::XEventListener >
58 : ServiceManagerBase;
59 :
60 : class ServiceManager:
61 : private cppu::BaseMutex, public ServiceManagerBase,
62 : private boost::noncopyable
63 : {
64 : public:
65 3395 : struct Data: private boost::noncopyable {
66 198650 : struct ImplementationInfo: private boost::noncopyable {
67 201185 : ImplementationInfo(
68 : rtl::OUString const & theName, rtl::OUString const & theLoader,
69 : rtl::OUString const & theUri,
70 : rtl::OUString const & theEnvironment,
71 : rtl::OUString const & theConstructor,
72 : rtl::OUString const & thePrefix,
73 : css::uno::Reference< css::uno::XComponentContext > const &
74 : theAlienContext,
75 : rtl::OUString const & theRdbFile):
76 : name(theName), loader(theLoader), uri(theUri),
77 : environment(theEnvironment), constructor(theConstructor),
78 : prefix(thePrefix), alienContext(theAlienContext),
79 201185 : rdbFile(theRdbFile)
80 201185 : {}
81 :
82 691 : explicit ImplementationInfo(rtl::OUString const & theName):
83 691 : name(theName) {}
84 :
85 : rtl::OUString const name;
86 : rtl::OUString const loader;
87 : rtl::OUString const uri;
88 : rtl::OUString const environment;
89 : rtl::OUString const constructor;
90 : rtl::OUString const prefix;
91 : css::uno::Reference< css::uno::XComponentContext > const
92 : alienContext;
93 : rtl::OUString const rdbFile;
94 : std::vector< rtl::OUString > services;
95 : std::vector< rtl::OUString > singletons;
96 : };
97 :
98 198650 : struct Implementation: private boost::noncopyable {
99 201185 : Implementation(
100 : rtl::OUString const & name, rtl::OUString const & loader,
101 : rtl::OUString const & uri, rtl::OUString const & environment,
102 : rtl::OUString const & constructorName,
103 : rtl::OUString const & prefix,
104 : css::uno::Reference< css::uno::XComponentContext > const &
105 : alienContext,
106 : rtl::OUString const & rdbFile):
107 : info(
108 : new ImplementationInfo(
109 : name, loader, uri, environment, constructorName, prefix,
110 201185 : alienContext, rdbFile)),
111 402370 : constructor(0), status(STATUS_NEW), dispose(true)
112 201185 : {}
113 :
114 691 : Implementation(
115 : rtl::OUString const & name,
116 : css::uno::Reference< css::lang::XSingleComponentFactory >
117 : const & theFactory1,
118 : css::uno::Reference< css::lang::XSingleServiceFactory > const &
119 : theFactory2,
120 : css::uno::Reference< css::lang::XComponent > const &
121 : theComponent):
122 691 : info(new ImplementationInfo(name)), constructor(0),
123 : factory1(theFactory1), factory2(theFactory2),
124 1382 : component(theComponent), status(STATUS_LOADED), dispose(true)
125 691 : { assert(theFactory1.is() || theFactory2.is()); }
126 :
127 : css::uno::Reference<css::uno::XInterface> createInstance(
128 : css::uno::Reference<css::uno::XComponentContext> const &
129 : context,
130 : bool singletonRequest);
131 :
132 : css::uno::Reference<css::uno::XInterface>
133 : createInstanceWithArguments(
134 : css::uno::Reference<css::uno::XComponentContext> const &
135 : context,
136 : bool singletonRequest,
137 : css::uno::Sequence<css::uno::Any> const & arguments);
138 :
139 : enum Status { STATUS_NEW, STATUS_WRAPPER, STATUS_LOADED };
140 :
141 : boost::shared_ptr< ImplementationInfo > info;
142 : ImplementationConstructorFn * constructor;
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 : osl::Mutex mutex;
149 : css::uno::Reference< css::lang::XComponent > disposeSingleton;
150 : bool dispose;
151 :
152 : private:
153 : void updateDisposeSingleton(
154 : bool singletonRequest,
155 : css::uno::Reference<css::uno::XInterface> const & instance);
156 : };
157 :
158 : typedef std::map< rtl::OUString, boost::shared_ptr< Implementation > >
159 : NamedImplementations;
160 :
161 : typedef
162 : std::map<
163 : css::uno::Reference< css::lang::XServiceInfo >,
164 : boost::shared_ptr< Implementation > >
165 : DynamicImplementations;
166 :
167 : typedef
168 : std::map<
169 : rtl::OUString,
170 : std::vector< boost::shared_ptr< Implementation > > >
171 : ImplementationMap;
172 :
173 : NamedImplementations namedImplementations;
174 : DynamicImplementations dynamicImplementations;
175 : ImplementationMap services;
176 : ImplementationMap singletons;
177 : };
178 :
179 519 : ServiceManager(): ServiceManagerBase(m_aMutex) {}
180 :
181 : using ServiceManagerBase::acquire;
182 : using ServiceManagerBase::release;
183 :
184 519 : void init(rtl::OUString const & rdbUris) { readRdbs(rdbUris); }
185 :
186 519 : void setContext(
187 : css::uno::Reference< css::uno::XComponentContext > const & context)
188 : {
189 : assert(context.is());
190 : assert(!context_.is());
191 519 : context_ = context;
192 519 : }
193 :
194 : void addSingletonContextEntries(
195 : std::vector< cppu::ContextEntry_Init > * entries);
196 :
197 0 : css::uno::Reference< css::uno::XComponentContext > getContext() const {
198 : assert(context_.is());
199 0 : return context_;
200 : }
201 :
202 : void loadImplementation(
203 : css::uno::Reference< css::uno::XComponentContext > const & context,
204 : boost::shared_ptr< Data::Implementation > & implementation);
205 :
206 : private:
207 928 : virtual ~ServiceManager() {}
208 :
209 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
210 :
211 : virtual rtl::OUString SAL_CALL getImplementationName()
212 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
213 :
214 : virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
215 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
216 :
217 : virtual css::uno::Sequence< rtl::OUString > SAL_CALL
218 : getSupportedServiceNames() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
219 :
220 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
221 : rtl::OUString const & aServiceSpecifier)
222 : throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
223 :
224 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
225 : createInstanceWithArguments(
226 : rtl::OUString const & ServiceSpecifier,
227 : css::uno::Sequence< css::uno::Any > const & Arguments)
228 : throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
229 :
230 : virtual css::uno::Sequence< rtl::OUString > SAL_CALL
231 : getAvailableServiceNames() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
232 :
233 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
234 : createInstanceWithContext(
235 : rtl::OUString const & aServiceSpecifier,
236 : css::uno::Reference< css::uno::XComponentContext > const & Context)
237 : throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
238 :
239 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
240 : createInstanceWithArgumentsAndContext(
241 : rtl::OUString const & ServiceSpecifier,
242 : css::uno::Sequence< css::uno::Any > const & Arguments,
243 : css::uno::Reference< css::uno::XComponentContext > const & Context)
244 : throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
245 :
246 : virtual css::uno::Type SAL_CALL getElementType()
247 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
248 :
249 : virtual sal_Bool SAL_CALL hasElements() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
250 :
251 : virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL
252 : createEnumeration() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
253 :
254 : virtual sal_Bool SAL_CALL has(css::uno::Any const & aElement)
255 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
256 :
257 : virtual void SAL_CALL insert(css::uno::Any const & aElement)
258 : throw (
259 : css::lang::IllegalArgumentException,
260 : css::container::ElementExistException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
261 :
262 : virtual void SAL_CALL remove(css::uno::Any const & aElement)
263 : throw (
264 : css::lang::IllegalArgumentException,
265 : css::container::NoSuchElementException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
266 :
267 : virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL
268 : createContentEnumeration(rtl::OUString const & aServiceName)
269 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
270 :
271 : virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
272 : getPropertySetInfo() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
273 :
274 : virtual void SAL_CALL setPropertyValue(
275 : rtl::OUString const & aPropertyName, css::uno::Any const & aValue)
276 : throw (
277 : css::beans::UnknownPropertyException,
278 : css::beans::PropertyVetoException,
279 : css::lang::IllegalArgumentException,
280 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
281 :
282 : virtual css::uno::Any SAL_CALL getPropertyValue(
283 : rtl::OUString const & PropertyName)
284 : throw (
285 : css::beans::UnknownPropertyException,
286 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
287 :
288 : virtual void SAL_CALL addPropertyChangeListener(
289 : rtl::OUString const & aPropertyName,
290 : css::uno::Reference< css::beans::XPropertyChangeListener > const &
291 : xListener)
292 : throw (
293 : css::beans::UnknownPropertyException,
294 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
295 :
296 : virtual void SAL_CALL removePropertyChangeListener(
297 : rtl::OUString const & aPropertyName,
298 : css::uno::Reference< css::beans::XPropertyChangeListener > const &
299 : aListener)
300 : throw (
301 : css::beans::UnknownPropertyException,
302 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
303 :
304 : virtual void SAL_CALL addVetoableChangeListener(
305 : rtl::OUString const & PropertyName,
306 : css::uno::Reference< css::beans::XVetoableChangeListener > const &
307 : aListener)
308 : throw (
309 : css::beans::UnknownPropertyException,
310 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
311 :
312 : virtual void SAL_CALL removeVetoableChangeListener(
313 : rtl::OUString const & PropertyName,
314 : css::uno::Reference< css::beans::XVetoableChangeListener > const &
315 : aListener)
316 : throw (
317 : css::beans::UnknownPropertyException,
318 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
319 :
320 : virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties()
321 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
322 :
323 : virtual css::beans::Property SAL_CALL getPropertyByName(
324 : rtl::OUString const & aName)
325 : throw (
326 : css::beans::UnknownPropertyException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
327 :
328 : virtual sal_Bool SAL_CALL hasPropertyByName(rtl::OUString const & Name)
329 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
330 :
331 : virtual void SAL_CALL disposing(css::lang::EventObject const & Source)
332 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
333 :
334 : // needs to be called with rBHelper.rMutex locked:
335 21425 : bool isDisposed() { return rBHelper.bDisposed || rBHelper.bInDispose; }
336 :
337 : void removeEventListenerFromComponent(
338 : css::uno::Reference< css::lang::XComponent > const & component);
339 :
340 : void readRdbs(rtl::OUString const & uris);
341 :
342 : void readRdbDirectory(rtl::OUString const & uri, bool optional);
343 :
344 : void readRdbFile(rtl::OUString const & uri, bool optional);
345 :
346 : bool readLegacyRdbFile(rtl::OUString const & uri);
347 :
348 : rtl::OUString readLegacyRdbString(
349 : rtl::OUString const & uri, RegistryKey & key,
350 : rtl::OUString const & path);
351 :
352 : void readLegacyRdbStrings(
353 : rtl::OUString const & uri, RegistryKey & key,
354 : rtl::OUString const & path, std::vector< rtl::OUString > * strings);
355 :
356 : void insertRdbFiles(
357 : std::vector< rtl::OUString > const & uris,
358 : css::uno::Reference< css::uno::XComponentContext > const &
359 : alientContext);
360 :
361 : void insertLegacyFactory(
362 : css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo);
363 :
364 : bool insertExtraData(Data const & extra);
365 :
366 : void removeRdbFiles(std::vector< rtl::OUString > const & uris);
367 :
368 : bool removeLegacyFactory(
369 : css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo,
370 : bool removeListener);
371 :
372 : void removeImplementation(const rtl::OUString & name);
373 :
374 : boost::shared_ptr< Data::Implementation > findServiceImplementation(
375 : css::uno::Reference< css::uno::XComponentContext > const & context,
376 : rtl::OUString const & specifier);
377 :
378 : css::uno::Reference< css::uno::XComponentContext > context_;
379 : Data data_;
380 : };
381 :
382 : }
383 :
384 : #endif
385 :
386 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|