Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License or as specified alternatively below. You may obtain a copy of
8 : * the License at http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * Major Contributor(s):
16 : * [ Copyright (C) 2012 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
17 : * (initial developer) ]
18 : *
19 : * All Rights Reserved.
20 : *
21 : * For minor contributions see the git repository.
22 : *
23 : * Alternatively, the contents of this file may be used under the terms of
24 : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
25 : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
26 : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
27 : * instead of those above.
28 : */
29 :
30 : #include "sal/config.h"
31 :
32 : #include <algorithm>
33 : #include <cassert>
34 : #include <cstring>
35 : #include <map>
36 : #include <vector>
37 :
38 : #include "boost/noncopyable.hpp"
39 : #include "boost/shared_ptr.hpp"
40 : #include "com/sun/star/beans/NamedValue.hpp"
41 : #include "com/sun/star/beans/PropertyAttribute.hpp"
42 : #include "com/sun/star/beans/XPropertySet.hpp"
43 : #include "com/sun/star/container/ElementExistException.hpp"
44 : #include "com/sun/star/container/XContentEnumerationAccess.hpp"
45 : #include "com/sun/star/container/XEnumeration.hpp"
46 : #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
47 : #include "com/sun/star/container/XNameContainer.hpp"
48 : #include "com/sun/star/container/XSet.hpp"
49 : #include "com/sun/star/lang/XInitialization.hpp"
50 : #include "com/sun/star/lang/XServiceInfo.hpp"
51 : #include "com/sun/star/lang/XSingleComponentFactory.hpp"
52 : #include "com/sun/star/lang/XSingleServiceFactory.hpp"
53 : #include "com/sun/star/loader/XImplementationLoader.hpp"
54 : #include "com/sun/star/registry/InvalidRegistryException.hpp"
55 : #include "com/sun/star/registry/XSimpleRegistry.hpp"
56 : #include "com/sun/star/uno/DeploymentException.hpp"
57 : #include "com/sun/star/uno/Reference.hxx"
58 : #include "com/sun/star/uno/XComponentContext.hpp"
59 : #include "cppuhelper/bootstrap.hxx"
60 : #include "cppuhelper/compbase8.hxx"
61 : #include "cppuhelper/component_context.hxx"
62 : #include "cppuhelper/implbase1.hxx"
63 : #include "cppuhelper/implbase3.hxx"
64 : #include "cppuhelper/shlib.hxx"
65 : #include "cppuhelper/supportsservice.hxx"
66 : #include "osl/file.hxx"
67 : #include "registry/registry.hxx"
68 : #include "rtl/bootstrap.hxx"
69 : #include "rtl/ref.hxx"
70 : #include "rtl/uri.hxx"
71 : #include "rtl/ustring.hxx"
72 : #include "xmlreader/xmlreader.hxx"
73 :
74 : #include "macro_expander.hxx"
75 : #include "paths.hxx"
76 : #include "servicefactory_detail.hxx"
77 :
78 : namespace {
79 :
80 72 : bool nextDirectoryItem(osl::Directory & directory, rtl::OUString * url) {
81 : assert(url != 0);
82 0 : for (;;) {
83 72 : osl::DirectoryItem i;
84 72 : switch (directory.getNextItem(i, SAL_MAX_UINT32)) {
85 : case osl::FileBase::E_None:
86 56 : break;
87 : case osl::FileBase::E_NOENT:
88 16 : return false;
89 : default:
90 : throw css::uno::DeploymentException(
91 : "Cannot iterate directory",
92 0 : css::uno::Reference< css::uno::XInterface >());
93 : }
94 : osl::FileStatus stat(
95 : osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileName |
96 56 : osl_FileStatus_Mask_FileURL);
97 56 : if (i.getFileStatus(stat) != osl::FileBase::E_None) {
98 : throw css::uno::DeploymentException(
99 : "Cannot stat in directory",
100 0 : css::uno::Reference< css::uno::XInterface >());
101 : }
102 56 : if (stat.getFileType() != osl::FileStatus::Directory) { //TODO: symlinks
103 : // Ignore backup files:
104 56 : rtl::OUString name(stat.getFileName());
105 56 : if (!(name.match(".") || name.endsWith("~"))) {
106 56 : *url = stat.getFileURL();
107 56 : return true;
108 56 : }
109 : }
110 56 : }
111 : }
112 :
113 2244 : void decodeRdbUri(rtl::OUString * uri, bool * optional, bool * directory) {
114 : assert(uri != 0 && optional != 0 && directory != 0);
115 2244 : *optional = (*uri)[0] == '?';
116 2244 : if (*optional) {
117 32 : *uri = uri->copy(1);
118 : }
119 4488 : *directory = uri->getLength() >= 3 && (*uri)[0] == '<'
120 16 : && (*uri)[uri->getLength() - 2] == '>'
121 4504 : && (*uri)[uri->getLength() - 1] == '*';
122 2244 : if (*directory) {
123 16 : *uri = uri->copy(1, uri->getLength() - 3);
124 : }
125 2244 : }
126 :
127 45838 : struct ImplementationInfo: private boost::noncopyable {
128 45534 : ImplementationInfo(
129 : rtl::OUString const & theName, rtl::OUString const & theLoader,
130 : rtl::OUString const & theUri, rtl::OUString const & thePrefix,
131 : css::uno::Reference< css::uno::XComponentContext > const &
132 : theAlienContext,
133 : rtl::OUString const & theRdbFile):
134 : name(theName), loader(theLoader), uri(theUri), prefix(thePrefix),
135 45534 : alienContext(theAlienContext), rdbFile(theRdbFile)
136 45534 : {}
137 :
138 384 : explicit ImplementationInfo(rtl::OUString const & theName): name(theName) {}
139 :
140 : rtl::OUString const name;
141 : rtl::OUString const loader;
142 : rtl::OUString const uri;
143 : rtl::OUString const prefix;
144 : css::uno::Reference< css::uno::XComponentContext > const alienContext;
145 : rtl::OUString const rdbFile;
146 : std::vector< rtl::OUString > services;
147 : std::vector< rtl::OUString > singletons;
148 : };
149 :
150 45838 : struct Implementation: private boost::noncopyable {
151 45534 : Implementation(
152 : rtl::OUString const & name, rtl::OUString const & loader,
153 : rtl::OUString const & uri, rtl::OUString const & prefix,
154 : css::uno::Reference< css::uno::XComponentContext > const & alienContext,
155 : rtl::OUString const & rdbFile):
156 : info(
157 : new ImplementationInfo(
158 45534 : name, loader, uri, prefix, alienContext, rdbFile)),
159 91068 : loaded(false)
160 45534 : {}
161 :
162 384 : Implementation(
163 : rtl::OUString const & name,
164 : css::uno::Reference< css::lang::XSingleComponentFactory > const &
165 : theFactory1,
166 : css::uno::Reference< css::lang::XSingleServiceFactory > const &
167 : theFactory2,
168 : css::uno::Reference< css::lang::XComponent > const & theComponent):
169 384 : info(new ImplementationInfo(name)), factory1(theFactory1),
170 768 : factory2(theFactory2), component(theComponent), loaded(true)
171 384 : {}
172 :
173 : boost::shared_ptr< ImplementationInfo > info;
174 : css::uno::Reference< css::lang::XSingleComponentFactory > factory1;
175 : css::uno::Reference< css::lang::XSingleServiceFactory > factory2;
176 : css::uno::Reference< css::lang::XComponent > component;
177 : bool loaded;
178 : };
179 :
180 : typedef std::map< rtl::OUString, boost::shared_ptr< Implementation > >
181 : NamedImplementations;
182 :
183 : typedef
184 : std::map<
185 : css::uno::Reference< css::lang::XServiceInfo >,
186 : boost::shared_ptr< Implementation > >
187 : DynamicImplementations;
188 :
189 : typedef
190 : std::map<
191 : rtl::OUString, std::vector< boost::shared_ptr< Implementation > > >
192 : ImplementationMap;
193 :
194 768 : void insertImplementationMap(
195 : ImplementationMap * destination, ImplementationMap const & source)
196 : {
197 : assert(destination != 0);
198 1152 : for (ImplementationMap::const_iterator i(source.begin()); i != source.end();
199 : ++i)
200 : {
201 : std::vector< boost::shared_ptr< Implementation > > & impls
202 384 : = (*destination)[i->first];
203 384 : impls.insert(impls.end(), i->second.begin(), i->second.end());
204 : }
205 768 : }
206 :
207 0 : void removeFromImplementationMap(
208 : ImplementationMap * map, std::vector< rtl::OUString > const & elements,
209 : boost::shared_ptr< Implementation > const & implementation)
210 : {
211 : // The underlying data structures make this function somewhat inefficient,
212 : // but the assumption is that it is rarely called:
213 : assert(map != 0);
214 0 : for (std::vector< rtl::OUString >::const_iterator i(elements.begin());
215 0 : i != elements.end(); ++i)
216 : {
217 0 : ImplementationMap::iterator j(map->find(*i));
218 : assert(j != map->end());
219 : std::vector< boost::shared_ptr< Implementation > >::iterator k(
220 0 : std::find(j->second.begin(), j->second.end(), implementation));
221 : assert(k != j->second.end());
222 0 : j->second.erase(k);
223 0 : if (j->second.empty()) {
224 0 : map->erase(j);
225 : }
226 : }
227 0 : }
228 :
229 1172 : struct Data: private boost::noncopyable {
230 : NamedImplementations namedImplementations;
231 : DynamicImplementations dynamicImplementations;
232 : ImplementationMap services;
233 : ImplementationMap singletons;
234 : };
235 :
236 : // This is largely a copy from stoc/source/simpleregistry/textualservices.cxx
237 : // (which it obsoletes); cppuhelper's published interface concept makes it
238 : // difficult to make both places use a shared Parser implementation, so I
239 : // created a copy for now (until the whole stoc/source/simpleregistry stuff can
240 : // be removed in an incompatible LibreOffice version). For simplicity, this
241 : // code keeps throwing css::registry::InvalidRegistryException for invalid XML
242 : // rdbs (even though that does not fit the exception's name):
243 2010 : class Parser: private boost::noncopyable {
244 : public:
245 : Parser(
246 : rtl::OUString const & uri,
247 : css::uno::Reference< css::uno::XComponentContext > const & alienContext,
248 : Data * data);
249 :
250 : private:
251 : void handleComponent();
252 :
253 : void handleImplementation();
254 :
255 : void handleService();
256 :
257 : void handleSingleton();
258 :
259 : rtl::OUString getNameAttribute();
260 :
261 : xmlreader::XmlReader reader_;
262 : css::uno::Reference< css::uno::XComponentContext > alienContext_;
263 : Data * data_;
264 : rtl::OUString attrLoader_;
265 : rtl::OUString attrUri_;
266 : rtl::OUString attrPrefix_;
267 : rtl::OUString attrImplementation_;
268 : boost::shared_ptr< Implementation > implementation_;
269 : };
270 :
271 2026 : Parser::Parser(
272 : rtl::OUString const & uri,
273 : css::uno::Reference< css::uno::XComponentContext > const & alienContext,
274 : Data * data):
275 2042 : reader_(uri), alienContext_(alienContext), data_(data)
276 : {
277 : assert(data != 0);
278 : int ucNsId = reader_.registerNamespaceIri(
279 : xmlreader::Span(
280 : RTL_CONSTASCII_STRINGPARAM(
281 2026 : "http://openoffice.org/2010/uno-components")));
282 : enum State {
283 : STATE_BEGIN, STATE_END, STATE_COMPONENTS, STATE_COMPONENT_INITIAL,
284 : STATE_COMPONENT, STATE_IMPLEMENTATION, STATE_SERVICE, STATE_SINGLETON };
285 221762 : for (State state = STATE_BEGIN;;) {
286 221762 : xmlreader::Span name;
287 : int nsId;
288 : xmlreader::XmlReader::Result res = reader_.nextItem(
289 221762 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
290 221746 : switch (state) {
291 : case STATE_BEGIN:
292 4020 : if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
293 2010 : && name.equals(RTL_CONSTASCII_STRINGPARAM("components")))
294 : {
295 2010 : state = STATE_COMPONENTS;
296 2010 : break;
297 : }
298 : throw css::registry::InvalidRegistryException(
299 0 : reader_.getUrl() + ": unexpected item in outer level",
300 0 : css::uno::Reference< css::uno::XInterface >());
301 : case STATE_END:
302 2010 : if (res == xmlreader::XmlReader::RESULT_DONE) {
303 2010 : return;
304 : }
305 : throw css::registry::InvalidRegistryException(
306 0 : reader_.getUrl() + ": unexpected item in outer level",
307 0 : css::uno::Reference< css::uno::XInterface >());
308 : case STATE_COMPONENTS:
309 7492 : if (res == xmlreader::XmlReader::RESULT_END) {
310 2010 : state = STATE_END;
311 2010 : break;
312 : }
313 10964 : if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
314 5482 : && name.equals(RTL_CONSTASCII_STRINGPARAM("component")))
315 : {
316 5482 : handleComponent();
317 5482 : state = STATE_COMPONENT_INITIAL;
318 5482 : break;
319 : }
320 : throw css::registry::InvalidRegistryException(
321 0 : reader_.getUrl() + ": unexpected item in <components>",
322 0 : css::uno::Reference< css::uno::XInterface >());
323 : case STATE_COMPONENT:
324 45518 : if (res == xmlreader::XmlReader::RESULT_END) {
325 5482 : state = STATE_COMPONENTS;
326 5482 : break;
327 : }
328 : // fall through
329 : case STATE_COMPONENT_INITIAL:
330 91036 : if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
331 45518 : && name.equals(RTL_CONSTASCII_STRINGPARAM("implementation")))
332 : {
333 45518 : handleImplementation();
334 45518 : state = STATE_IMPLEMENTATION;
335 45518 : break;
336 : }
337 : throw css::registry::InvalidRegistryException(
338 0 : reader_.getUrl() + ": unexpected item in <component>",
339 0 : css::uno::Reference< css::uno::XInterface >());
340 : case STATE_IMPLEMENTATION:
341 102376 : if (res == xmlreader::XmlReader::RESULT_END) {
342 45518 : state = STATE_COMPONENT;
343 45518 : break;
344 : }
345 113716 : if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
346 56858 : && name.equals(RTL_CONSTASCII_STRINGPARAM("service")))
347 : {
348 56040 : handleService();
349 56040 : state = STATE_SERVICE;
350 56040 : break;
351 : }
352 1636 : if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
353 818 : && name.equals(RTL_CONSTASCII_STRINGPARAM("singleton")))
354 : {
355 818 : handleSingleton();
356 818 : state = STATE_SINGLETON;
357 818 : break;
358 : }
359 : throw css::registry::InvalidRegistryException(
360 0 : reader_.getUrl() + ": unexpected item in <implementation>",
361 0 : css::uno::Reference< css::uno::XInterface >());
362 : case STATE_SERVICE:
363 56040 : if (res == xmlreader::XmlReader::RESULT_END) {
364 56040 : state = STATE_IMPLEMENTATION;
365 56040 : break;
366 : }
367 : throw css::registry::InvalidRegistryException(
368 0 : reader_.getUrl() + ": unexpected item in <service>",
369 0 : css::uno::Reference< css::uno::XInterface >());
370 : case STATE_SINGLETON:
371 818 : if (res == xmlreader::XmlReader::RESULT_END) {
372 818 : state = STATE_IMPLEMENTATION;
373 818 : break;
374 : }
375 : throw css::registry::InvalidRegistryException(
376 0 : reader_.getUrl() + ": unexpected item in <service>",
377 0 : css::uno::Reference< css::uno::XInterface >());
378 : }
379 : }
380 : }
381 :
382 5482 : void Parser::handleComponent() {
383 5482 : attrLoader_ = rtl::OUString();
384 5482 : attrUri_ = rtl::OUString();
385 5482 : attrPrefix_ = rtl::OUString();
386 5482 : xmlreader::Span name;
387 : int nsId;
388 5482 : while (reader_.nextAttribute(&nsId, &name)) {
389 32072 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
390 16036 : && name.equals(RTL_CONSTASCII_STRINGPARAM("loader")))
391 : {
392 5482 : if (!attrLoader_.isEmpty()) {
393 : throw css::registry::InvalidRegistryException(
394 : (reader_.getUrl()
395 0 : + ": <component> has multiple \"loader\" attributes"),
396 0 : css::uno::Reference< css::uno::XInterface >());
397 : }
398 5482 : attrLoader_ = reader_.getAttributeValue(false).convertFromUtf8();
399 5482 : if (attrLoader_.isEmpty()) {
400 : throw css::registry::InvalidRegistryException(
401 : (reader_.getUrl()
402 0 : + ": <component> has empty \"loader\" attribute"),
403 0 : css::uno::Reference< css::uno::XInterface >());
404 : }
405 21108 : } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
406 10554 : && name.equals(RTL_CONSTASCII_STRINGPARAM("uri")))
407 : {
408 5482 : if (!attrUri_.isEmpty()) {
409 : throw css::registry::InvalidRegistryException(
410 : (reader_.getUrl()
411 0 : + ": <component> has multiple \"uri\" attributes"),
412 0 : css::uno::Reference< css::uno::XInterface >());
413 : }
414 5482 : attrUri_ = reader_.getAttributeValue(false).convertFromUtf8();
415 5482 : if (attrUri_.isEmpty()) {
416 : throw css::registry::InvalidRegistryException(
417 : (reader_.getUrl()
418 0 : + ": <component> has empty \"uri\" attribute"),
419 0 : css::uno::Reference< css::uno::XInterface >());
420 : }
421 10144 : } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
422 5072 : && name.equals(RTL_CONSTASCII_STRINGPARAM("prefix")))
423 : {
424 5072 : if (!attrPrefix_.isEmpty()) {
425 : throw css::registry::InvalidRegistryException(
426 : (reader_.getUrl() +
427 0 : ": <component> has multiple \"prefix\" attributes"),
428 0 : css::uno::Reference< css::uno::XInterface >());
429 : }
430 5072 : attrPrefix_ = reader_.getAttributeValue(false).convertFromUtf8();
431 5072 : if (attrPrefix_.isEmpty()) {
432 : throw css::registry::InvalidRegistryException(
433 : (reader_.getUrl() +
434 0 : ": <component> has empty \"prefix\" attribute"),
435 0 : css::uno::Reference< css::uno::XInterface >());
436 : }
437 : } else {
438 : throw css::registry::InvalidRegistryException(
439 0 : (reader_.getUrl() + ": unexpected attribute \""
440 0 : + name.convertFromUtf8() + "\" in <component>"),
441 0 : css::uno::Reference< css::uno::XInterface >());
442 : }
443 : }
444 5482 : if (attrLoader_.isEmpty()) {
445 : throw css::registry::InvalidRegistryException(
446 0 : reader_.getUrl() + ": <component> is missing \"loader\" attribute",
447 0 : css::uno::Reference< css::uno::XInterface >());
448 : }
449 5482 : if (attrUri_.isEmpty()) {
450 : throw css::registry::InvalidRegistryException(
451 0 : reader_.getUrl() + ": <component> is missing \"uri\" attribute",
452 0 : css::uno::Reference< css::uno::XInterface >());
453 : }
454 : #ifndef DISABLE_DYNLOADING
455 : try {
456 5482 : attrUri_ = rtl::Uri::convertRelToAbs(reader_.getUrl(), attrUri_);
457 0 : } catch (const rtl::MalformedUriException & e) {
458 : throw css::registry::InvalidRegistryException(
459 0 : reader_.getUrl() + ": bad \"uri\" attribute: " + e.getMessage(),
460 0 : css::uno::Reference< css::uno::XInterface >());
461 : }
462 : #endif
463 5482 : }
464 :
465 45518 : void Parser::handleImplementation() {
466 45518 : attrImplementation_ = getNameAttribute();
467 : implementation_.reset(
468 : new Implementation(
469 : attrImplementation_, attrLoader_, attrUri_, attrPrefix_,
470 45518 : alienContext_, reader_.getUrl()));
471 91036 : if (!data_->namedImplementations.insert(
472 : NamedImplementations::value_type(
473 91036 : attrImplementation_, implementation_)).
474 91036 : second)
475 : {
476 : throw css::registry::InvalidRegistryException(
477 0 : (reader_.getUrl() + ": duplicate <implementation name=\""
478 0 : + attrImplementation_ + "\">"),
479 0 : css::uno::Reference< css::uno::XInterface >());
480 : }
481 45518 : }
482 :
483 56040 : void Parser::handleService() {
484 56040 : rtl::OUString name(getNameAttribute());
485 56040 : implementation_->info->services.push_back(name);
486 56040 : data_->services[name].push_back(implementation_);
487 56040 : }
488 :
489 818 : void Parser::handleSingleton() {
490 818 : rtl::OUString name(getNameAttribute());
491 818 : implementation_->info->singletons.push_back(name);
492 818 : data_->singletons[name].push_back(implementation_);
493 818 : }
494 :
495 102376 : rtl::OUString Parser::getNameAttribute() {
496 102376 : rtl::OUString attrName;
497 102376 : xmlreader::Span name;
498 : int nsId;
499 102376 : while (reader_.nextAttribute(&nsId, &name)) {
500 204752 : if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
501 102376 : && name.equals(RTL_CONSTASCII_STRINGPARAM("name")))
502 : {
503 102376 : if (!attrName.isEmpty()) {
504 : throw css::registry::InvalidRegistryException(
505 : (reader_.getUrl()
506 0 : + ": element has multiple \"name\" attributes"),
507 0 : css::uno::Reference< css::uno::XInterface >());
508 : }
509 102376 : attrName = reader_.getAttributeValue(false).convertFromUtf8();
510 102376 : if (attrName.isEmpty()) {
511 : throw css::registry::InvalidRegistryException(
512 0 : reader_.getUrl() + ": element has empty \"name\" attribute",
513 0 : css::uno::Reference< css::uno::XInterface >());
514 : }
515 : } else {
516 : throw css::registry::InvalidRegistryException(
517 0 : reader_.getUrl() + ": expected element attribute \"name\"",
518 0 : css::uno::Reference< css::uno::XInterface >());
519 : }
520 : }
521 102376 : if (attrName.isEmpty()) {
522 : throw css::registry::InvalidRegistryException(
523 0 : reader_.getUrl() + ": element is missing \"name\" attribute",
524 0 : css::uno::Reference< css::uno::XInterface >());
525 : }
526 102376 : return attrName;
527 : }
528 :
529 : class ContentEnumeration:
530 : public cppu::WeakImplHelper1< css::container::XEnumeration >,
531 : private boost::noncopyable
532 : {
533 : public:
534 170 : explicit ContentEnumeration(std::vector< css::uno::Any > const & factories):
535 170 : factories_(factories), iterator_(factories_.begin()) {}
536 :
537 : private:
538 340 : virtual ~ContentEnumeration() {}
539 :
540 : virtual sal_Bool SAL_CALL hasMoreElements()
541 : throw (css::uno::RuntimeException);
542 :
543 : virtual css::uno::Any SAL_CALL nextElement()
544 : throw (
545 : css::container::NoSuchElementException,
546 : css::lang::WrappedTargetException, css::uno::RuntimeException);
547 :
548 : osl::Mutex mutex_;
549 : std::vector< css::uno::Any > factories_;
550 : std::vector< css::uno::Any >::const_iterator iterator_;
551 : };
552 :
553 230 : sal_Bool ContentEnumeration::hasMoreElements()
554 : throw (css::uno::RuntimeException)
555 : {
556 230 : osl::MutexGuard g(mutex_);
557 230 : return iterator_ != factories_.end();
558 : }
559 :
560 60 : css::uno::Any ContentEnumeration::nextElement()
561 : throw (
562 : css::container::NoSuchElementException,
563 : css::lang::WrappedTargetException, css::uno::RuntimeException)
564 : {
565 60 : osl::MutexGuard g(mutex_);
566 60 : if (iterator_ == factories_.end()) {
567 : throw css::container::NoSuchElementException(
568 : "Bootstrap service manager service enumerator has no more elements",
569 0 : static_cast< cppu::OWeakObject * >(this));
570 : }
571 60 : return *iterator_++;
572 : }
573 :
574 1 : css::beans::Property getDefaultContextProperty() {
575 : return css::beans::Property(
576 : "DefaultContext", -1,
577 1 : cppu::UnoType< css::uno::XComponentContext >::get(),
578 1 : css::beans::PropertyAttribute::READONLY);
579 : }
580 :
581 : typedef cppu::WeakComponentImplHelper8<
582 : css::lang::XServiceInfo, css::lang::XMultiServiceFactory,
583 : css::lang::XMultiComponentFactory, css::container::XSet,
584 : css::container::XContentEnumerationAccess, css::beans::XPropertySet,
585 : css::beans::XPropertySetInfo, css::lang::XEventListener >
586 : ServiceManagerBase;
587 :
588 : class ServiceManager:
589 : private osl::Mutex, public ServiceManagerBase, private boost::noncopyable
590 : {
591 : public:
592 120 : explicit ServiceManager(rtl::OUString const & rdbUris):
593 120 : ServiceManagerBase(*static_cast< osl::Mutex * >(this))
594 120 : { readRdbs(rdbUris); }
595 :
596 : using ServiceManagerBase::acquire;
597 : using ServiceManagerBase::release;
598 :
599 120 : void setContext(
600 : css::uno::Reference< css::uno::XComponentContext > const & context)
601 : {
602 : assert(context.is());
603 : assert(!context_.is());
604 120 : context_ = context;
605 120 : }
606 :
607 0 : css::uno::Reference< css::uno::XComponentContext > getContext() const {
608 : assert(context_.is());
609 0 : return context_;
610 : }
611 :
612 120 : Data const & getData() const { return data_; }
613 :
614 : void loadImplementation(
615 : css::uno::Reference< css::uno::XComponentContext > const & context,
616 : boost::shared_ptr< ImplementationInfo > const & info,
617 : css::uno::Reference< css::lang::XSingleComponentFactory > * factory1,
618 : css::uno::Reference< css::lang::XSingleServiceFactory > * factory2);
619 :
620 : virtual rtl::OUString SAL_CALL getImplementationName()
621 : throw (css::uno::RuntimeException);
622 :
623 : virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
624 : throw (css::uno::RuntimeException);
625 :
626 : virtual css::uno::Sequence< rtl::OUString > SAL_CALL
627 : getSupportedServiceNames() throw (css::uno::RuntimeException);
628 :
629 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
630 : rtl::OUString const & aServiceSpecifier)
631 : throw (css::uno::Exception, css::uno::RuntimeException);
632 :
633 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
634 : createInstanceWithArguments(
635 : rtl::OUString const & ServiceSpecifier,
636 : css::uno::Sequence< css::uno::Any > const & Arguments)
637 : throw (css::uno::Exception, css::uno::RuntimeException);
638 :
639 : virtual css::uno::Sequence< rtl::OUString > SAL_CALL
640 : getAvailableServiceNames() throw (css::uno::RuntimeException);
641 :
642 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
643 : createInstanceWithContext(
644 : rtl::OUString const & aServiceSpecifier,
645 : css::uno::Reference< css::uno::XComponentContext > const & Context)
646 : throw (css::uno::Exception, css::uno::RuntimeException);
647 :
648 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
649 : createInstanceWithArgumentsAndContext(
650 : rtl::OUString const & ServiceSpecifier,
651 : css::uno::Sequence< css::uno::Any > const & Arguments,
652 : css::uno::Reference< css::uno::XComponentContext > const & Context)
653 : throw (css::uno::Exception, css::uno::RuntimeException);
654 :
655 : virtual css::uno::Type SAL_CALL getElementType()
656 : throw (css::uno::RuntimeException);
657 :
658 : virtual sal_Bool SAL_CALL hasElements() throw (css::uno::RuntimeException);
659 :
660 : virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL
661 : createEnumeration() throw (css::uno::RuntimeException);
662 :
663 : virtual sal_Bool SAL_CALL has(css::uno::Any const & aElement)
664 : throw (css::uno::RuntimeException);
665 :
666 : virtual void SAL_CALL insert(css::uno::Any const & aElement)
667 : throw (
668 : css::lang::IllegalArgumentException,
669 : css::container::ElementExistException, css::uno::RuntimeException);
670 :
671 : virtual void SAL_CALL remove(css::uno::Any const & aElement)
672 : throw (
673 : css::lang::IllegalArgumentException,
674 : css::container::NoSuchElementException, css::uno::RuntimeException);
675 :
676 : virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL
677 : createContentEnumeration(rtl::OUString const & aServiceName)
678 : throw (css::uno::RuntimeException);
679 :
680 : virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
681 : getPropertySetInfo() throw (css::uno::RuntimeException);
682 :
683 : virtual void SAL_CALL setPropertyValue(
684 : rtl::OUString const & aPropertyName, css::uno::Any const & aValue)
685 : throw (
686 : css::beans::UnknownPropertyException,
687 : css::beans::PropertyVetoException,
688 : css::lang::IllegalArgumentException,
689 : css::lang::WrappedTargetException, css::uno::RuntimeException);
690 :
691 : virtual css::uno::Any SAL_CALL getPropertyValue(
692 : rtl::OUString const & PropertyName)
693 : throw (
694 : css::beans::UnknownPropertyException,
695 : css::lang::WrappedTargetException, css::uno::RuntimeException);
696 :
697 : virtual void SAL_CALL addPropertyChangeListener(
698 : rtl::OUString const & aPropertyName,
699 : css::uno::Reference< css::beans::XPropertyChangeListener > const &
700 : xListener)
701 : throw (
702 : css::beans::UnknownPropertyException,
703 : css::lang::WrappedTargetException, css::uno::RuntimeException);
704 :
705 : virtual void SAL_CALL removePropertyChangeListener(
706 : rtl::OUString const & aPropertyName,
707 : css::uno::Reference< css::beans::XPropertyChangeListener > const &
708 : aListener)
709 : throw (
710 : css::beans::UnknownPropertyException,
711 : css::lang::WrappedTargetException, css::uno::RuntimeException);
712 :
713 : virtual void SAL_CALL addVetoableChangeListener(
714 : rtl::OUString const & PropertyName,
715 : css::uno::Reference< css::beans::XVetoableChangeListener > const &
716 : aListener)
717 : throw (
718 : css::beans::UnknownPropertyException,
719 : css::lang::WrappedTargetException, css::uno::RuntimeException);
720 :
721 : virtual void SAL_CALL removeVetoableChangeListener(
722 : rtl::OUString const & PropertyName,
723 : css::uno::Reference< css::beans::XVetoableChangeListener > const &
724 : aListener)
725 : throw (
726 : css::beans::UnknownPropertyException,
727 : css::lang::WrappedTargetException, css::uno::RuntimeException);
728 :
729 : virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties()
730 : throw (css::uno::RuntimeException);
731 :
732 : virtual css::beans::Property SAL_CALL getPropertyByName(
733 : rtl::OUString const & aName)
734 : throw (
735 : css::beans::UnknownPropertyException, css::uno::RuntimeException);
736 :
737 : virtual sal_Bool SAL_CALL hasPropertyByName(rtl::OUString const & Name)
738 : throw (css::uno::RuntimeException);
739 :
740 : virtual void SAL_CALL disposing(css::lang::EventObject const & Source)
741 : throw (css::uno::RuntimeException);
742 :
743 : private:
744 96 : virtual ~ServiceManager() {}
745 :
746 : virtual void SAL_CALL disposing();
747 :
748 : // needs to be called with rBHelper.rMutex locked:
749 5325 : bool isDisposed() { return rBHelper.bDisposed || rBHelper.bInDispose; }
750 :
751 : void removeEventListenerFromComponent(
752 : css::uno::Reference< css::lang::XComponent > const & component);
753 :
754 : void readRdbs(rtl::OUString const & uris);
755 :
756 : void readRdbDirectory(rtl::OUString const & uri, bool optional);
757 :
758 : void readRdbFile(rtl::OUString const & uri, bool optional);
759 :
760 : bool readLegacyRdbFile(rtl::OUString const & uri);
761 :
762 : rtl::OUString readLegacyRdbString(
763 : rtl::OUString const & uri, RegistryKey & key,
764 : rtl::OUString const & path);
765 :
766 : void readLegacyRdbStrings(
767 : rtl::OUString const & uri, RegistryKey & key,
768 : rtl::OUString const & path, std::vector< rtl::OUString > * strings);
769 :
770 : void insertRdbFiles(
771 : std::vector< rtl::OUString > const & uris,
772 : css::uno::Reference< css::uno::XComponentContext > const &
773 : alientContext);
774 :
775 : void insertLegacyFactory(
776 : css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo);
777 :
778 : bool insertExtraData(Data const & extra);
779 :
780 : void removeRdbFiles(std::vector< rtl::OUString > const & uris);
781 :
782 : bool removeLegacyFactory(
783 : css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo,
784 : bool removeListener);
785 :
786 : void removeImplementation(rtl::OUString name);
787 :
788 : boost::shared_ptr< Implementation > findServiceImplementation(
789 : css::uno::Reference< css::uno::XComponentContext > const & context,
790 : rtl::OUString const & specifier);
791 :
792 : css::uno::Reference< css::uno::XComponentContext > context_;
793 : Data data_;
794 : };
795 :
796 : class FactoryWrapper:
797 : public cppu::WeakImplHelper3<
798 : css::lang::XSingleComponentFactory, css::lang::XSingleServiceFactory,
799 : css::lang::XServiceInfo >,
800 : private boost::noncopyable
801 : {
802 : public:
803 32 : FactoryWrapper(
804 : rtl::Reference< ServiceManager > const & manager,
805 : boost::shared_ptr< ImplementationInfo > const & info):
806 32 : manager_(manager), info_(info), loaded_(false)
807 32 : { assert(manager.is() && info.get() != 0); }
808 :
809 : private:
810 64 : virtual ~FactoryWrapper() {}
811 :
812 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
813 : createInstanceWithContext(
814 : css::uno::Reference< css::uno::XComponentContext > const & Context)
815 : throw (css::uno::Exception, css::uno::RuntimeException);
816 :
817 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
818 : createInstanceWithArgumentsAndContext(
819 : css::uno::Sequence< css::uno::Any > const & Arguments,
820 : css::uno::Reference< css::uno::XComponentContext > const & Context)
821 : throw (css::uno::Exception, css::uno::RuntimeException);
822 :
823 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
824 : createInstance() throw (css::uno::Exception, css::uno::RuntimeException);
825 :
826 : virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
827 : createInstanceWithArguments(
828 : css::uno::Sequence< css::uno::Any > const & Arguments)
829 : throw (css::uno::Exception, css::uno::RuntimeException);
830 :
831 : virtual rtl::OUString SAL_CALL getImplementationName()
832 : throw (css::uno::RuntimeException);
833 :
834 : virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
835 : throw (css::uno::RuntimeException);
836 :
837 : virtual css::uno::Sequence< rtl::OUString > SAL_CALL
838 : getSupportedServiceNames() throw (css::uno::RuntimeException);
839 :
840 : void loadImplementation(
841 : css::uno::Reference< css::uno::XComponentContext > const & context);
842 :
843 : rtl::Reference< ServiceManager > manager_;
844 : boost::shared_ptr< ImplementationInfo > info_;
845 :
846 : osl::Mutex mutex_;
847 : bool loaded_;
848 : css::uno::Reference< css::lang::XSingleComponentFactory > factory1_;
849 : css::uno::Reference< css::lang::XSingleServiceFactory > factory2_;
850 : };
851 :
852 4913 : void ServiceManager::loadImplementation(
853 : css::uno::Reference< css::uno::XComponentContext > const & context,
854 : boost::shared_ptr< ImplementationInfo > const & info,
855 : css::uno::Reference< css::lang::XSingleComponentFactory > * factory1,
856 : css::uno::Reference< css::lang::XSingleServiceFactory > * factory2)
857 : {
858 : assert(
859 : info.get() != 0 && factory1 != 0 && !factory1->is() && factory2 != 0
860 : && !factory2->is());
861 4913 : rtl::OUString uri;
862 : try {
863 4913 : uri = cppu::bootstrap_expandUri(info->uri);
864 0 : } catch (css::lang::IllegalArgumentException & e) {
865 : throw css::uno::DeploymentException(
866 0 : "Cannot expand URI" + info->uri + ": " + e.Message,
867 0 : static_cast< cppu::OWeakObject * >(this));
868 : }
869 4913 : css::uno::Reference< css::uno::XInterface > f0;
870 : // Shortcut loading via SharedLibrary loader, to pass in prefix argument
871 : // (which the loader's activate implementation would normally obtain through
872 : // the legacy xKey argument):
873 9826 : if (!info->alienContext.is()
874 4913 : && info->loader == "com.sun.star.loader.SharedLibrary")
875 : {
876 4912 : rtl::OUString prefix(info->prefix);
877 4912 : if (!prefix.isEmpty()) {
878 4666 : prefix += "_";
879 : }
880 : f0 = cppu::loadSharedLibComponentFactory(
881 4912 : uri, rtl::OUString(), info->name, this,
882 9824 : css::uno::Reference< css::registry::XRegistryKey >(), prefix);
883 : } else {
884 : SAL_INFO_IF(
885 : !info->prefix.isEmpty(), "cppuhelper",
886 : "Loader " << info->loader << " and non-empty prefix "
887 : << info->prefix);
888 1 : css::uno::Reference< css::uno::XComponentContext > ctxt;
889 1 : css::uno::Reference< css::lang::XMultiComponentFactory > smgr;
890 1 : if (info->alienContext.is()) {
891 0 : ctxt = info->alienContext;
892 : smgr = css::uno::Reference< css::lang::XMultiComponentFactory >(
893 0 : ctxt->getServiceManager(), css::uno::UNO_SET_THROW);
894 : } else {
895 : assert(context.is());
896 1 : ctxt = context;
897 1 : smgr = this;
898 : }
899 : css::uno::Reference< css::loader::XImplementationLoader > loader(
900 1 : smgr->createInstanceWithContext(info->loader, ctxt),
901 1 : css::uno::UNO_QUERY_THROW);
902 1 : f0 = loader->activate(
903 1 : info->name, rtl::OUString(), uri,
904 2 : css::uno::Reference< css::registry::XRegistryKey >());
905 : }
906 4913 : factory1->set(f0, css::uno::UNO_QUERY);
907 4913 : if (!factory1->is()) {
908 62 : factory2->set(f0, css::uno::UNO_QUERY);
909 4913 : }
910 4913 : }
911 :
912 0 : rtl::OUString ServiceManager::getImplementationName()
913 : throw (css::uno::RuntimeException)
914 : {
915 : return rtl::OUString(
916 0 : "com.sun.star.comp.cppuhelper.bootstrap.ServiceManager");
917 : }
918 :
919 0 : sal_Bool ServiceManager::supportsService(rtl::OUString const & ServiceName)
920 : throw (css::uno::RuntimeException)
921 : {
922 0 : return cppu::supportsService(this, ServiceName);
923 : }
924 :
925 0 : css::uno::Sequence< rtl::OUString > ServiceManager::getSupportedServiceNames()
926 : throw (css::uno::RuntimeException)
927 : {
928 0 : css::uno::Sequence< rtl::OUString > names(2);
929 0 : names[0] = "com.sun.star.lang.MultiServiceFactory";
930 0 : names[1] = "com.sun.star.lang.ServiceManager";
931 0 : return names;
932 : }
933 :
934 156242 : css::uno::Reference< css::uno::XInterface > ServiceManager::createInstance(
935 : rtl::OUString const & aServiceSpecifier)
936 : throw (css::uno::Exception, css::uno::RuntimeException)
937 : {
938 : assert(context_.is());
939 156242 : return createInstanceWithContext(aServiceSpecifier, context_);
940 : }
941 :
942 : css::uno::Reference< css::uno::XInterface >
943 17569 : ServiceManager::createInstanceWithArguments(
944 : rtl::OUString const & ServiceSpecifier,
945 : css::uno::Sequence< css::uno::Any > const & Arguments)
946 : throw (css::uno::Exception, css::uno::RuntimeException)
947 : {
948 : assert(context_.is());
949 : return createInstanceWithArgumentsAndContext(
950 17569 : ServiceSpecifier, Arguments, context_);
951 : }
952 :
953 0 : css::uno::Sequence< rtl::OUString > ServiceManager::getAvailableServiceNames()
954 : throw (css::uno::RuntimeException)
955 : {
956 0 : osl::MutexGuard g(rBHelper.rMutex);
957 0 : if (isDisposed()) {
958 0 : return css::uno::Sequence< rtl::OUString >();
959 : }
960 0 : ImplementationMap::size_type n = data_.services.size();
961 0 : if (n > static_cast< sal_uInt32 >(SAL_MAX_INT32)) {
962 : throw css::uno::RuntimeException(
963 : "getAvailableServiceNames: too many services",
964 0 : static_cast< cppu::OWeakObject * >(this));
965 : }
966 0 : css::uno::Sequence< rtl::OUString > names(static_cast< sal_Int32 >(n));
967 0 : sal_Int32 i = 0;
968 0 : for (ImplementationMap::const_iterator j(data_.services.begin());
969 0 : j != data_.services.end(); ++j)
970 : {
971 0 : names[i++] = j->first;
972 : }
973 : assert(i == names.getLength());
974 0 : return names;
975 : }
976 :
977 : css::uno::Reference< css::uno::XInterface >
978 364556 : ServiceManager::createInstanceWithContext(
979 : rtl::OUString const & aServiceSpecifier,
980 : css::uno::Reference< css::uno::XComponentContext > const & Context)
981 : throw (css::uno::Exception, css::uno::RuntimeException)
982 : {
983 : boost::shared_ptr< Implementation > impl(
984 364556 : findServiceImplementation(Context, aServiceSpecifier));
985 364556 : if (impl.get() == 0) {
986 62768 : return css::uno::Reference< css::uno::XInterface >();
987 : }
988 301788 : if (impl->factory1.is()) {
989 300992 : return impl->factory1->createInstanceWithContext(Context);
990 : }
991 796 : if (impl->factory2.is()) {
992 796 : return impl->factory2->createInstance();
993 : }
994 : throw css::uno::DeploymentException(
995 0 : "Implementation " + impl->info->name + " does not provide a factory",
996 0 : static_cast< cppu::OWeakObject * >(this));
997 : }
998 :
999 : css::uno::Reference< css::uno::XInterface >
1000 77385 : ServiceManager::createInstanceWithArgumentsAndContext(
1001 : rtl::OUString const & ServiceSpecifier,
1002 : css::uno::Sequence< css::uno::Any > const & Arguments,
1003 : css::uno::Reference< css::uno::XComponentContext > const & Context)
1004 : throw (css::uno::Exception, css::uno::RuntimeException)
1005 : {
1006 : boost::shared_ptr< Implementation > impl(
1007 77385 : findServiceImplementation(Context, ServiceSpecifier));
1008 77385 : if (impl.get() == 0) {
1009 13582 : return css::uno::Reference< css::uno::XInterface >();
1010 : }
1011 63803 : if (impl->factory1.is()) {
1012 63519 : return impl->factory1->createInstanceWithArgumentsAndContext(
1013 63519 : Arguments, Context);
1014 : }
1015 284 : if (impl->factory2.is()) {
1016 284 : return impl->factory2->createInstanceWithArguments(Arguments);
1017 : }
1018 : throw css::uno::DeploymentException(
1019 0 : "Implementation " + impl->info->name + " does not provide a factory",
1020 0 : static_cast< cppu::OWeakObject * >(this));
1021 : }
1022 :
1023 0 : css::uno::Type ServiceManager::getElementType()
1024 : throw (css::uno::RuntimeException)
1025 : {
1026 0 : return css::uno::Type();
1027 : }
1028 :
1029 0 : sal_Bool ServiceManager::hasElements() throw (css::uno::RuntimeException) {
1030 0 : osl::MutexGuard g(rBHelper.rMutex);
1031 : return
1032 0 : !(data_.namedImplementations.empty()
1033 0 : && data_.dynamicImplementations.empty());
1034 : }
1035 :
1036 : css::uno::Reference< css::container::XEnumeration >
1037 0 : ServiceManager::createEnumeration() throw (css::uno::RuntimeException) {
1038 : throw css::uno::RuntimeException(
1039 : "ServiceManager createEnumeration: method not supported",
1040 0 : static_cast< cppu::OWeakObject * >(this));
1041 : }
1042 :
1043 0 : sal_Bool ServiceManager::has(css::uno::Any const &)
1044 : throw (css::uno::RuntimeException)
1045 : {
1046 : throw css::uno::RuntimeException(
1047 : "ServiceManager has: method not supported",
1048 0 : static_cast< cppu::OWeakObject * >(this));
1049 : }
1050 :
1051 384 : void ServiceManager::insert(css::uno::Any const & aElement)
1052 : throw (
1053 : css::lang::IllegalArgumentException,
1054 : css::container::ElementExistException, css::uno::RuntimeException)
1055 : {
1056 384 : css::uno::Sequence< css::beans::NamedValue > args;
1057 384 : if (aElement >>= args) {
1058 0 : std::vector< rtl::OUString > uris;
1059 0 : css::uno::Reference< css::uno::XComponentContext > alienContext;
1060 0 : for (sal_Int32 i = 0; i < args.getLength(); ++i) {
1061 0 : if (args[i].Name == "uri") {
1062 0 : rtl::OUString uri;
1063 0 : if (!(args[i].Value >>= uri)) {
1064 : throw css::lang::IllegalArgumentException(
1065 : "Bad uri argument",
1066 0 : static_cast< cppu::OWeakObject * >(this), 0);
1067 : }
1068 0 : uris.push_back(uri);
1069 0 : } else if (args[i].Name == "component-context") {
1070 0 : if (alienContext.is()) {
1071 : throw css::lang::IllegalArgumentException(
1072 : "Multiple component-context arguments",
1073 0 : static_cast< cppu::OWeakObject * >(this), 0);
1074 : }
1075 0 : if (!(args[i].Value >>= alienContext) || !alienContext.is()) {
1076 : throw css::lang::IllegalArgumentException(
1077 : "Bad component-context argument",
1078 0 : static_cast< cppu::OWeakObject * >(this), 0);
1079 : }
1080 : } else {
1081 : throw css::lang::IllegalArgumentException(
1082 0 : "Bad argument " + args[i].Name,
1083 0 : static_cast< cppu::OWeakObject * >(this), 0);
1084 : }
1085 : }
1086 0 : insertRdbFiles(uris, alienContext);
1087 0 : return;
1088 : }
1089 384 : css::uno::Reference< css::lang::XServiceInfo > info;
1090 384 : if ((aElement >>= info) && info.is()) {
1091 384 : insertLegacyFactory(info);
1092 : return;
1093 : }
1094 : // At least revisions up to 1.7 of LanguageTool.oxt (incl. the bundled 1.4.0 in
1095 : // module languagetool) contain an (actively registered) factory that does not
1096 : // implement XServiceInfo (see <http://sourceforge.net/tracker/?
1097 : // func=detail&aid=3526635&group_id=110216&atid=655717> "SingletonFactory should
1098 : // implement XServiceInfo"); the old OServiceManager::insert
1099 : // (stoc/source/servicemanager/servicemanager.cxx) silently did not add such
1100 : // broken factories to its m_ImplementationNameMap, so ignore them here for
1101 : // backwards compatibility of live-insertion of extensions, too.
1102 :
1103 : // (The plan was that this warning would go away (and we would do the
1104 : // throw instead) for the incompatible LO 4, but we changed our mind):
1105 0 : css::uno::Reference< css::lang::XSingleComponentFactory > legacy;
1106 0 : if ((aElement >>= legacy) && legacy.is()) {
1107 : SAL_WARN(
1108 : "cppuhelper",
1109 : "Ignored XSingleComponentFactory not implementing XServiceInfo");
1110 : return;
1111 : }
1112 :
1113 : throw css::lang::IllegalArgumentException(
1114 0 : "Bad insert element", static_cast< cppu::OWeakObject * >(this), 0);
1115 : }
1116 :
1117 0 : void ServiceManager::remove(css::uno::Any const & aElement)
1118 : throw (
1119 : css::lang::IllegalArgumentException,
1120 : css::container::NoSuchElementException, css::uno::RuntimeException)
1121 : {
1122 0 : css::uno::Sequence< css::beans::NamedValue > args;
1123 0 : if (aElement >>= args) {
1124 0 : std::vector< rtl::OUString > uris;
1125 0 : for (sal_Int32 i = 0; i < args.getLength(); ++i) {
1126 0 : if (args[i].Name == "uri") {
1127 0 : rtl::OUString uri;
1128 0 : if (!(args[i].Value >>= uri)) {
1129 : throw css::lang::IllegalArgumentException(
1130 : "Bad uri argument",
1131 0 : static_cast< cppu::OWeakObject * >(this), 0);
1132 : }
1133 0 : uris.push_back(uri);
1134 : } else {
1135 : throw css::lang::IllegalArgumentException(
1136 0 : "Bad argument " + args[i].Name,
1137 0 : static_cast< cppu::OWeakObject * >(this), 0);
1138 : }
1139 : }
1140 0 : removeRdbFiles(uris);
1141 0 : return;
1142 : }
1143 0 : css::uno::Reference< css::lang::XServiceInfo > info;
1144 0 : if ((aElement >>= info) && info.is()) {
1145 0 : if (!removeLegacyFactory(info, true)) {
1146 : throw css::container::NoSuchElementException(
1147 : "Remove non-inserted factory object",
1148 0 : static_cast< cppu::OWeakObject * >(this));
1149 : }
1150 : return;
1151 : }
1152 0 : rtl::OUString impl;
1153 0 : if (aElement >>= impl) {
1154 : // For live-removal of extensions:
1155 0 : removeImplementation(impl);
1156 : return;
1157 : }
1158 : throw css::lang::IllegalArgumentException(
1159 0 : "Bad remove element", static_cast< cppu::OWeakObject * >(this), 0);
1160 : }
1161 :
1162 : css::uno::Reference< css::container::XEnumeration >
1163 170 : ServiceManager::createContentEnumeration(rtl::OUString const & aServiceName)
1164 : throw (css::uno::RuntimeException)
1165 : {
1166 170 : std::vector< boost::shared_ptr< Implementation > > impls;
1167 : {
1168 170 : osl::MutexGuard g(rBHelper.rMutex);
1169 170 : ImplementationMap::const_iterator i(data_.services.find(aServiceName));
1170 170 : if (i != data_.services.end()) {
1171 24 : impls = i->second;
1172 170 : }
1173 : }
1174 170 : std::vector< css::uno::Any > factories;
1175 690 : for (std::vector< boost::shared_ptr< Implementation > >::const_iterator i(
1176 170 : impls.begin());
1177 460 : i != impls.end(); ++i)
1178 : {
1179 60 : Implementation * impl = i->get();
1180 : assert(impl != 0);
1181 : {
1182 60 : osl::MutexGuard g(rBHelper.rMutex);
1183 60 : if (isDisposed()) {
1184 0 : factories.clear();
1185 : break;
1186 : }
1187 60 : if (!impl->loaded) {
1188 : // Postpone actual factory instantiation as long as possible (so
1189 : // that e.g. opening LO's "Tools - Macros" menu does not try to
1190 : // instantiate a JVM, which can lead to a synchronous error
1191 : // dialog when no JVM is specified, and showing the dialog while
1192 : // hovering over a menu can cause trouble):
1193 32 : impl->factory1 = new FactoryWrapper(this, impl->info);
1194 32 : impl->loaded = true;
1195 60 : }
1196 : }
1197 60 : if (impl->factory1.is()) {
1198 60 : factories.push_back(css::uno::makeAny(impl->factory1));
1199 0 : } else if (impl->factory2.is()) {
1200 0 : factories.push_back(css::uno::makeAny(impl->factory2));
1201 : } else {
1202 : throw css::uno::DeploymentException(
1203 0 : ("Implementation " + impl->info->name
1204 0 : + " does not provide a factory"),
1205 0 : static_cast< cppu::OWeakObject * >(this));
1206 : }
1207 : }
1208 170 : return new ContentEnumeration(factories);
1209 : }
1210 :
1211 : css::uno::Reference< css::beans::XPropertySetInfo >
1212 7 : ServiceManager::getPropertySetInfo() throw (css::uno::RuntimeException) {
1213 7 : return this;
1214 : }
1215 :
1216 0 : void ServiceManager::setPropertyValue(
1217 : rtl::OUString const & aPropertyName, css::uno::Any const &)
1218 : throw (
1219 : css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1220 : css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1221 : css::uno::RuntimeException)
1222 : {
1223 0 : if (aPropertyName == "DefaultContext") {
1224 : throw css::beans::PropertyVetoException(
1225 0 : aPropertyName, static_cast< cppu::OWeakObject * >(this));
1226 : } else {
1227 : throw css::beans::UnknownPropertyException(
1228 0 : aPropertyName, static_cast< cppu::OWeakObject * >(this));
1229 : }
1230 : }
1231 :
1232 297248 : css::uno::Any ServiceManager::getPropertyValue(
1233 : rtl::OUString const & PropertyName)
1234 : throw (
1235 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1236 : css::uno::RuntimeException)
1237 : {
1238 297248 : if (PropertyName != "DefaultContext") {
1239 : throw css::beans::UnknownPropertyException(
1240 0 : PropertyName, static_cast< cppu::OWeakObject * >(this));
1241 : }
1242 : assert(context_.is());
1243 297248 : return css::uno::makeAny(context_);
1244 : }
1245 :
1246 0 : void ServiceManager::addPropertyChangeListener(
1247 : rtl::OUString const & aPropertyName,
1248 : css::uno::Reference< css::beans::XPropertyChangeListener > const &
1249 : xListener)
1250 : throw (
1251 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1252 : css::uno::RuntimeException)
1253 : {
1254 0 : if (!aPropertyName.isEmpty() && aPropertyName != "DefaultContext") {
1255 : throw css::beans::UnknownPropertyException(
1256 0 : aPropertyName, static_cast< cppu::OWeakObject * >(this));
1257 : }
1258 : // DefaultContext does not change, so just treat it as an event listener:
1259 0 : return addEventListener(xListener.get());
1260 : }
1261 :
1262 0 : void ServiceManager::removePropertyChangeListener(
1263 : rtl::OUString const & aPropertyName,
1264 : css::uno::Reference< css::beans::XPropertyChangeListener > const &
1265 : aListener)
1266 : throw (
1267 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1268 : css::uno::RuntimeException)
1269 : {
1270 0 : if (!aPropertyName.isEmpty() && aPropertyName != "DefaultContext") {
1271 : throw css::beans::UnknownPropertyException(
1272 0 : aPropertyName, static_cast< cppu::OWeakObject * >(this));
1273 : }
1274 : // DefaultContext does not change, so just treat it as an event listener:
1275 0 : return removeEventListener(aListener.get());
1276 : }
1277 :
1278 0 : void ServiceManager::addVetoableChangeListener(
1279 : rtl::OUString const & PropertyName,
1280 : css::uno::Reference< css::beans::XVetoableChangeListener > const &
1281 : aListener)
1282 : throw (
1283 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1284 : css::uno::RuntimeException)
1285 : {
1286 0 : if (!PropertyName.isEmpty() && PropertyName != "DefaultContext") {
1287 : throw css::beans::UnknownPropertyException(
1288 0 : PropertyName, static_cast< cppu::OWeakObject * >(this));
1289 : }
1290 : // DefaultContext does not change, so just treat it as an event listener:
1291 0 : return addEventListener(aListener.get());
1292 : }
1293 :
1294 0 : void ServiceManager::removeVetoableChangeListener(
1295 : rtl::OUString const & PropertyName,
1296 : css::uno::Reference< css::beans::XVetoableChangeListener > const &
1297 : aListener)
1298 : throw (
1299 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1300 : css::uno::RuntimeException)
1301 : {
1302 0 : if (!PropertyName.isEmpty() && PropertyName != "DefaultContext") {
1303 : throw css::beans::UnknownPropertyException(
1304 0 : PropertyName, static_cast< cppu::OWeakObject * >(this));
1305 : }
1306 : // DefaultContext does not change, so just treat it as an event listener:
1307 0 : return removeEventListener(aListener.get());
1308 : }
1309 :
1310 1 : css::uno::Sequence< css::beans::Property > ServiceManager::getProperties()
1311 : throw (css::uno::RuntimeException)
1312 : {
1313 1 : css::uno::Sequence< css::beans::Property > props(1);
1314 1 : props[0] = getDefaultContextProperty();
1315 1 : return props;
1316 : }
1317 :
1318 0 : css::beans::Property ServiceManager::getPropertyByName(
1319 : rtl::OUString const & aName)
1320 : throw (css::beans::UnknownPropertyException, css::uno::RuntimeException)
1321 : {
1322 0 : if (aName != "DefaultContext") {
1323 : throw css::beans::UnknownPropertyException(
1324 0 : aName, static_cast< cppu::OWeakObject * >(this));
1325 : }
1326 0 : return getDefaultContextProperty();
1327 : }
1328 :
1329 0 : sal_Bool ServiceManager::hasPropertyByName(rtl::OUString const & Name)
1330 : throw (css::uno::RuntimeException)
1331 : {
1332 0 : return Name == "DefaultContext";
1333 : }
1334 :
1335 0 : void ServiceManager::disposing(css::lang::EventObject const & Source)
1336 : throw (css::uno::RuntimeException)
1337 : {
1338 : removeLegacyFactory(
1339 : css::uno::Reference< css::lang::XServiceInfo >(
1340 : Source.Source, css::uno::UNO_QUERY_THROW),
1341 0 : false);
1342 0 : }
1343 :
1344 118 : void ServiceManager::disposing() {
1345 118 : std::vector< css::uno::Reference< css::lang::XComponent > > comps;
1346 118 : Data clear;
1347 : {
1348 118 : osl::MutexGuard g(rBHelper.rMutex);
1349 1506 : for (DynamicImplementations::const_iterator i(
1350 118 : data_.dynamicImplementations.begin());
1351 1004 : i != data_.dynamicImplementations.end(); ++i)
1352 : {
1353 : assert(i->second.get() != 0);
1354 384 : if (i->second->component.is()) {
1355 384 : comps.push_back(i->second->component);
1356 : }
1357 : }
1358 118 : data_.namedImplementations.swap(clear.namedImplementations);
1359 118 : data_.dynamicImplementations.swap(clear.dynamicImplementations);
1360 118 : data_.services.swap(clear.services);
1361 118 : data_.singletons.swap(clear.singletons);
1362 : }
1363 1506 : for (std::vector<
1364 : css::uno::Reference< css::lang::XComponent > >::const_iterator i(
1365 118 : comps.begin());
1366 1004 : i != comps.end(); ++i)
1367 : {
1368 384 : removeEventListenerFromComponent(*i);
1369 118 : }
1370 118 : }
1371 :
1372 384 : void ServiceManager::removeEventListenerFromComponent(
1373 : css::uno::Reference< css::lang::XComponent > const & component)
1374 : {
1375 : assert(component.is());
1376 : try {
1377 384 : component->removeEventListener(this);
1378 0 : } catch (css::uno::RuntimeException & e) {
1379 : SAL_INFO(
1380 : "cppuhelper",
1381 : "Ignored removeEventListener RuntimeException " + e.Message);
1382 : }
1383 384 : }
1384 :
1385 120 : void ServiceManager::readRdbs(rtl::OUString const & uris) {
1386 2250 : for (sal_Int32 i = 0; i != -1;) {
1387 2010 : rtl::OUString uri(uris.getToken(0, ' ', i));
1388 2010 : if (uri.isEmpty()) {
1389 16 : continue;
1390 : }
1391 : bool optional;
1392 : bool directory;
1393 1994 : decodeRdbUri(&uri, &optional, &directory);
1394 1994 : if (directory) {
1395 8 : readRdbDirectory(uri, optional);
1396 : } else {
1397 1986 : readRdbFile(uri, optional);
1398 : }
1399 2010 : }
1400 120 : }
1401 :
1402 8 : void ServiceManager::readRdbDirectory(rtl::OUString const & uri, bool optional)
1403 : {
1404 8 : osl::Directory dir(uri);
1405 8 : switch (dir.open()) {
1406 : case osl::FileBase::E_None:
1407 8 : break;
1408 : case osl::FileBase::E_NOENT:
1409 0 : if (optional) {
1410 : SAL_INFO("cppuhelper", "Ignored optional " << uri);
1411 8 : return;
1412 : }
1413 : // fall through
1414 : default:
1415 : throw css::uno::DeploymentException(
1416 : "Cannot open directory " + uri,
1417 0 : static_cast< cppu::OWeakObject * >(this));
1418 : }
1419 40 : for (;;) {
1420 48 : rtl::OUString url;
1421 48 : if (!nextDirectoryItem(dir, &url)) {
1422 : break;
1423 : }
1424 40 : readRdbFile(url, false);
1425 56 : }
1426 : }
1427 :
1428 2026 : void ServiceManager::readRdbFile(rtl::OUString const & uri, bool optional) {
1429 : try {
1430 : Parser(
1431 2042 : uri, css::uno::Reference< css::uno::XComponentContext >(), &data_);
1432 0 : } catch (css::container::NoSuchElementException &) {
1433 0 : if (!optional) {
1434 : throw css::uno::DeploymentException(
1435 : uri + ": no such file",
1436 0 : static_cast< cppu::OWeakObject * >(this));
1437 : }
1438 : SAL_INFO("cppuhelper", "Ignored optional " << uri);
1439 0 : } catch (css::registry::InvalidRegistryException & e) {
1440 0 : if (!readLegacyRdbFile(uri)) {
1441 : throw css::uno::DeploymentException(
1442 0 : "InvalidRegistryException: " + e.Message,
1443 0 : static_cast< cppu::OWeakObject * >(this));
1444 : }
1445 32 : } catch (css::uno::RuntimeException &) {
1446 16 : if (!readLegacyRdbFile(uri)) {
1447 0 : throw;
1448 : }
1449 : }
1450 2026 : }
1451 :
1452 16 : bool ServiceManager::readLegacyRdbFile(rtl::OUString const & uri) {
1453 16 : Registry reg;
1454 16 : switch (reg.open(uri, REG_READONLY)) {
1455 : case REG_NO_ERROR:
1456 16 : break;
1457 : case REG_REGISTRY_NOT_EXISTS:
1458 : case REG_INVALID_REGISTRY:
1459 : {
1460 : // Ignore empty rdb files (which are at least seen by subordinate
1461 : // uno processes during extension registration; Registry::open can
1462 : // fail on them if mmap(2) returns EINVAL for a zero length):
1463 0 : osl::DirectoryItem item;
1464 0 : if (osl::DirectoryItem::get(uri, item) == osl::FileBase::E_None) {
1465 0 : osl::FileStatus status(osl_FileStatus_Mask_FileSize);
1466 0 : if (item.getFileStatus(status) == osl::FileBase::E_None
1467 0 : && status.getFileSize() == 0)
1468 : {
1469 0 : return true;
1470 0 : }
1471 0 : }
1472 : }
1473 : // fall through
1474 : default:
1475 0 : return false;
1476 : }
1477 16 : RegistryKey rootKey;
1478 16 : if (reg.openRootKey(rootKey) != REG_NO_ERROR) {
1479 : throw css::uno::DeploymentException(
1480 : "Failure reading legacy rdb file " + uri,
1481 0 : static_cast< cppu::OWeakObject * >(this));
1482 : }
1483 16 : RegistryKeyArray impls;
1484 16 : switch (rootKey.openSubKeys("IMPLEMENTATIONS", impls)) {
1485 : case REG_NO_ERROR:
1486 8 : break;
1487 : case REG_KEY_NOT_EXISTS:
1488 8 : return true;
1489 : default:
1490 : throw css::uno::DeploymentException(
1491 : "Failure reading legacy rdb file " + uri,
1492 0 : static_cast< cppu::OWeakObject * >(this));
1493 : }
1494 24 : for (sal_uInt32 i = 0; i != impls.getLength(); ++i) {
1495 16 : RegistryKey implKey(impls.getElement(i));
1496 : assert(implKey.getName().match("/IMPLEMENTATIONS/"));
1497 : rtl::OUString name(
1498 16 : implKey.getName().copy(RTL_CONSTASCII_LENGTH("/IMPLEMENTATIONS/")));
1499 : boost::shared_ptr< Implementation > impl(
1500 : new Implementation(
1501 : name, readLegacyRdbString(uri, implKey, "UNO/ACTIVATOR"),
1502 : readLegacyRdbString(uri, implKey, "UNO/LOCATION"),
1503 : rtl::OUString(),
1504 16 : css::uno::Reference< css::uno::XComponentContext >(), uri));
1505 32 : if (!data_.namedImplementations.insert(
1506 32 : NamedImplementations::value_type(name, impl)).
1507 32 : second)
1508 : {
1509 : throw css::registry::InvalidRegistryException(
1510 0 : uri + ": duplicate <implementation name=\"" + name + "\">",
1511 0 : css::uno::Reference< css::uno::XInterface >());
1512 : }
1513 : readLegacyRdbStrings(
1514 16 : uri, implKey, "UNO/SERVICES", &impl->info->services);
1515 96 : for (std::vector< rtl::OUString >::const_iterator j(
1516 16 : impl->info->services.begin());
1517 64 : j != impl->info->services.end(); ++j)
1518 : {
1519 16 : data_.services[*j].push_back(impl);
1520 : }
1521 : readLegacyRdbStrings(
1522 16 : uri, implKey, "UNO/SINGLETONS", &impl->info->singletons);
1523 48 : for (std::vector< rtl::OUString >::const_iterator j(
1524 16 : impl->info->singletons.begin());
1525 32 : j != impl->info->singletons.end(); ++j)
1526 : {
1527 0 : data_.singletons[*j].push_back(impl);
1528 : }
1529 16 : }
1530 8 : return true;
1531 : }
1532 :
1533 32 : rtl::OUString ServiceManager::readLegacyRdbString(
1534 : rtl::OUString const & uri, RegistryKey & key, rtl::OUString const & path)
1535 : {
1536 32 : RegistryKey subkey;
1537 : RegValueType t;
1538 32 : sal_uInt32 s(0);
1539 128 : if (key.openKey(path, subkey) != REG_NO_ERROR
1540 96 : || subkey.getValueInfo(rtl::OUString(), &t, &s) != REG_NO_ERROR
1541 : || t != RG_VALUETYPE_STRING
1542 : || s == 0 || s > static_cast< sal_uInt32 >(SAL_MAX_INT32))
1543 : {
1544 : throw css::uno::DeploymentException(
1545 : "Failure reading legacy rdb file " + uri,
1546 0 : static_cast< cppu::OWeakObject * >(this));
1547 : }
1548 32 : rtl::OUString val;
1549 32 : std::vector< char > v(s); // assuming sal_uInt32 fits into vector::size_type
1550 96 : if (subkey.getValue(rtl::OUString(), &v[0]) != REG_NO_ERROR
1551 32 : || v.back() != '\0'
1552 : || !rtl_convertStringToUString(
1553 32 : &val.pData, &v[0], static_cast< sal_Int32 >(s - 1),
1554 : RTL_TEXTENCODING_UTF8,
1555 : (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
1556 : | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
1557 64 : | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
1558 : {
1559 : throw css::uno::DeploymentException(
1560 : "Failure reading legacy rdb file " + uri,
1561 0 : static_cast< cppu::OWeakObject * >(this));
1562 : }
1563 32 : return val;
1564 : }
1565 :
1566 32 : void ServiceManager::readLegacyRdbStrings(
1567 : rtl::OUString const & uri, RegistryKey & key, rtl::OUString const & path,
1568 : std::vector< rtl::OUString > * strings)
1569 : {
1570 : assert(strings != 0);
1571 32 : RegistryKey subkey;
1572 32 : switch (key.openKey(path, subkey)) {
1573 : case REG_NO_ERROR:
1574 16 : break;
1575 : case REG_KEY_NOT_EXISTS:
1576 32 : return;
1577 : default:
1578 : throw css::uno::DeploymentException(
1579 : "Failure reading legacy rdb file " + uri,
1580 0 : static_cast< cppu::OWeakObject * >(this));
1581 : }
1582 16 : rtl::OUString prefix(subkey.getName() + "/");
1583 16 : RegistryKeyNames names;
1584 16 : if (subkey.getKeyNames(rtl::OUString(), names) != REG_NO_ERROR) {
1585 : throw css::uno::DeploymentException(
1586 : "Failure reading legacy rdb file " + uri,
1587 0 : static_cast< cppu::OWeakObject * >(this));
1588 : }
1589 32 : for (sal_uInt32 i = 0; i != names.getLength(); ++i) {
1590 : assert(names.getElement(i).match(prefix));
1591 16 : strings->push_back(names.getElement(i).copy(prefix.getLength()));
1592 16 : }
1593 : }
1594 :
1595 0 : void ServiceManager::insertRdbFiles(
1596 : std::vector< rtl::OUString > const & uris,
1597 : css::uno::Reference< css::uno::XComponentContext > const & alienContext)
1598 : {
1599 0 : Data extra;
1600 0 : for (std::vector< rtl::OUString >::const_iterator i(uris.begin());
1601 0 : i != uris.end(); ++i)
1602 : {
1603 : try {
1604 0 : Parser(*i, alienContext, &extra);
1605 0 : } catch (css::container::NoSuchElementException &) {
1606 : throw css::lang::IllegalArgumentException(
1607 0 : *i + ": no such file", static_cast< cppu::OWeakObject * >(this),
1608 0 : 0);
1609 0 : } catch (css::registry::InvalidRegistryException & e) {
1610 : throw css::lang::IllegalArgumentException(
1611 0 : "InvalidRegistryException: " + e.Message,
1612 0 : static_cast< cppu::OWeakObject * >(this), 0);
1613 : }
1614 : }
1615 0 : insertExtraData(extra);
1616 0 : }
1617 :
1618 384 : void ServiceManager::insertLegacyFactory(
1619 : css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo)
1620 : {
1621 : assert(factoryInfo.is());
1622 384 : rtl::OUString name(factoryInfo->getImplementationName());
1623 : css::uno::Reference< css::lang::XSingleComponentFactory > f1(
1624 384 : factoryInfo, css::uno::UNO_QUERY);
1625 384 : css::uno::Reference< css::lang::XSingleServiceFactory > f2;
1626 384 : if (!f1.is()) {
1627 : f2 = css::uno::Reference< css::lang::XSingleServiceFactory >(
1628 0 : factoryInfo, css::uno::UNO_QUERY);
1629 : }
1630 : css::uno::Reference< css::lang::XComponent > comp(
1631 384 : factoryInfo, css::uno::UNO_QUERY);
1632 : boost::shared_ptr< Implementation > impl(
1633 384 : new Implementation(name, f1, f2, comp));
1634 384 : Data extra;
1635 384 : if (!name.isEmpty()) {
1636 : extra.namedImplementations.insert(
1637 64 : NamedImplementations::value_type(name, impl));
1638 : }
1639 : extra.dynamicImplementations.insert(
1640 384 : DynamicImplementations::value_type(factoryInfo, impl));
1641 : css::uno::Sequence< rtl::OUString > services(
1642 384 : factoryInfo->getSupportedServiceNames());
1643 768 : for (sal_Int32 i = 0; i != services.getLength(); ++i) {
1644 384 : impl->info->services.push_back(services[i]);
1645 384 : extra.services[services[i]].push_back(impl);
1646 : }
1647 384 : if (insertExtraData(extra) && comp.is()) {
1648 384 : comp->addEventListener(this);
1649 384 : }
1650 384 : }
1651 :
1652 384 : bool ServiceManager::insertExtraData(Data const & extra) {
1653 : {
1654 384 : osl::MutexGuard g(rBHelper.rMutex);
1655 384 : if (isDisposed()) {
1656 0 : return false;
1657 : }
1658 1344 : for (NamedImplementations::const_iterator i(
1659 384 : extra.namedImplementations.begin());
1660 896 : i != extra.namedImplementations.end(); ++i)
1661 : {
1662 192 : if (data_.namedImplementations.find(i->first)
1663 192 : != data_.namedImplementations.end())
1664 : {
1665 : throw css::lang::IllegalArgumentException(
1666 0 : "Insert duplicate implementation name " + i->first,
1667 0 : static_cast< cppu::OWeakObject * >(this), 0);
1668 : }
1669 : }
1670 2304 : for (DynamicImplementations::const_iterator i(
1671 384 : extra.dynamicImplementations.begin());
1672 1536 : i != extra.dynamicImplementations.end(); ++i)
1673 : {
1674 1152 : if (data_.dynamicImplementations.find(i->first)
1675 1152 : != data_.dynamicImplementations.end())
1676 : {
1677 : throw css::lang::IllegalArgumentException(
1678 : "Insert duplicate factory object",
1679 0 : static_cast< cppu::OWeakObject * >(this), 0);
1680 : }
1681 : }
1682 : //TODO: The below leaves data_ in an inconsistent state upon exceptions:
1683 : data_.namedImplementations.insert(
1684 : extra.namedImplementations.begin(),
1685 384 : extra.namedImplementations.end());
1686 : data_.dynamicImplementations.insert(
1687 : extra.dynamicImplementations.begin(),
1688 384 : extra.dynamicImplementations.end());
1689 384 : insertImplementationMap(&data_.services, extra.services);
1690 384 : insertImplementationMap(&data_.singletons, extra.singletons);
1691 : }
1692 : //TODO: Updating the component context singleton data should be part of the
1693 : // atomic service manager update:
1694 384 : if (!extra.singletons.empty()) {
1695 : assert(context_.is());
1696 : css::uno::Reference< css::container::XNameContainer > cont(
1697 0 : context_, css::uno::UNO_QUERY_THROW);
1698 0 : for (ImplementationMap::const_iterator i(extra.singletons.begin());
1699 0 : i != extra.singletons.end(); ++i)
1700 : {
1701 0 : rtl::OUString name("/singletons/" + i->first);
1702 : //TODO: Update should be atomic:
1703 : try {
1704 0 : cont->removeByName(name + "/arguments");
1705 0 : } catch (const css::container::NoSuchElementException &) {}
1706 : assert(!i->second.empty());
1707 : assert(i->second[0].get() != 0);
1708 : SAL_INFO_IF(
1709 : i->second.size() > 1, "cppuhelper",
1710 : "Arbitrarily chosing " << i->second[0]->info->name
1711 : << " among multiple implementations for singleton "
1712 : << i->first);
1713 : try {
1714 0 : cont->insertByName(
1715 0 : name + "/service", css::uno::Any(i->second[0]->info->name));
1716 0 : } catch (css::container::ElementExistException &) {
1717 0 : cont->replaceByName(
1718 0 : name + "/service", css::uno::Any(i->second[0]->info->name));
1719 : }
1720 : try {
1721 0 : cont->insertByName(name, css::uno::Any());
1722 0 : } catch (css::container::ElementExistException &) {
1723 : SAL_INFO("cppuhelper", "Overwriting singleton " << i->first);
1724 0 : cont->replaceByName(name, css::uno::Any());
1725 : }
1726 0 : }
1727 : }
1728 384 : return true;
1729 : }
1730 :
1731 0 : void ServiceManager::removeRdbFiles(std::vector< rtl::OUString > const & uris) {
1732 : // The underlying data structures make this function somewhat inefficient,
1733 : // but the assumption is that it is rarely called (and that if it is called,
1734 : // it is called with a uris vector of size one):
1735 0 : std::vector< boost::shared_ptr< Implementation > > clear;
1736 : {
1737 0 : osl::MutexGuard g(rBHelper.rMutex);
1738 0 : for (std::vector< rtl::OUString >::const_iterator i(uris.begin());
1739 0 : i != uris.end(); ++i)
1740 : {
1741 0 : for (NamedImplementations::iterator j(
1742 0 : data_.namedImplementations.begin());
1743 0 : j != data_.namedImplementations.end();)
1744 : {
1745 : assert(j->second.get() != 0);
1746 0 : if (j->second->info->rdbFile == *i) {
1747 0 : clear.push_back(j->second);
1748 : //TODO: The below leaves data_ in an inconsistent state upon
1749 : // exceptions:
1750 : removeFromImplementationMap(
1751 0 : &data_.services, j->second->info->services, j->second);
1752 : removeFromImplementationMap(
1753 0 : &data_.singletons, j->second->info->singletons,
1754 0 : j->second);
1755 0 : data_.namedImplementations.erase(j++);
1756 : } else {
1757 0 : ++j;
1758 : }
1759 : }
1760 0 : }
1761 0 : }
1762 : //TODO: Update the component context singleton data
1763 0 : }
1764 :
1765 0 : bool ServiceManager::removeLegacyFactory(
1766 : css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo,
1767 : bool removeListener)
1768 : {
1769 : assert(factoryInfo.is());
1770 0 : boost::shared_ptr< Implementation > clear;
1771 0 : css::uno::Reference< css::lang::XComponent > comp;
1772 : {
1773 0 : osl::MutexGuard g(rBHelper.rMutex);
1774 : DynamicImplementations::iterator i(
1775 0 : data_.dynamicImplementations.find(factoryInfo));
1776 0 : if (i == data_.dynamicImplementations.end()) {
1777 0 : return isDisposed();
1778 : }
1779 : assert(i->second.get() != 0);
1780 0 : clear = i->second;
1781 : //TODO: The below leaves data_ in an inconsistent state upon exceptions:
1782 : removeFromImplementationMap(
1783 0 : &data_.services, i->second->info->services, i->second);
1784 : removeFromImplementationMap(
1785 0 : &data_.singletons, i->second->info->singletons, i->second);
1786 0 : if (!i->second->info->name.isEmpty()) {
1787 0 : data_.namedImplementations.erase(i->second->info->name);
1788 : }
1789 0 : data_.dynamicImplementations.erase(i);
1790 0 : if (removeListener) {
1791 0 : comp = i->second->component;
1792 0 : }
1793 : }
1794 0 : if (comp.is()) {
1795 0 : removeEventListenerFromComponent(comp);
1796 : }
1797 0 : return true;
1798 : }
1799 :
1800 0 : void ServiceManager::removeImplementation(rtl::OUString name) {
1801 : // The underlying data structures make this function somewhat inefficient,
1802 : // but the assumption is that it is rarely called:
1803 0 : boost::shared_ptr< Implementation > clear;
1804 : {
1805 0 : osl::MutexGuard g(rBHelper.rMutex);
1806 0 : if (isDisposed()) {
1807 0 : return;
1808 : }
1809 0 : NamedImplementations::iterator i(data_.namedImplementations.find(name));
1810 0 : if (i == data_.namedImplementations.end()) {
1811 : throw css::container::NoSuchElementException(
1812 : "Remove non-inserted implementation " + name,
1813 0 : static_cast< cppu::OWeakObject * >(this));
1814 : }
1815 : assert(i->second.get() != 0);
1816 0 : clear = i->second;
1817 : //TODO: The below leaves data_ in an inconsistent state upon exceptions:
1818 : removeFromImplementationMap(
1819 0 : &data_.services, i->second->info->services, i->second);
1820 : removeFromImplementationMap(
1821 0 : &data_.singletons, i->second->info->singletons, i->second);
1822 0 : for (DynamicImplementations::iterator j(
1823 0 : data_.dynamicImplementations.begin());
1824 0 : j != data_.dynamicImplementations.end(); ++j)
1825 : {
1826 0 : if (j->second == i->second) {
1827 0 : data_.dynamicImplementations.erase(j);
1828 0 : break;
1829 : }
1830 : }
1831 0 : data_.namedImplementations.erase(i);
1832 0 : }
1833 : }
1834 :
1835 441941 : boost::shared_ptr< Implementation > ServiceManager::findServiceImplementation(
1836 : css::uno::Reference< css::uno::XComponentContext > const & context,
1837 : rtl::OUString const & specifier)
1838 : {
1839 441941 : boost::shared_ptr< Implementation > impl;
1840 : bool loaded;
1841 : {
1842 441941 : osl::MutexGuard g(rBHelper.rMutex);
1843 441941 : ImplementationMap::const_iterator i(data_.services.find(specifier));
1844 441941 : if (i == data_.services.end()) {
1845 : NamedImplementations::const_iterator j(
1846 85839 : data_.namedImplementations.find(specifier));
1847 85839 : if (j == data_.namedImplementations.end()) {
1848 : SAL_INFO("cppuhelper", "No implementation for " << specifier);
1849 76350 : return boost::shared_ptr< Implementation >();
1850 : }
1851 9489 : impl = j->second;
1852 : } else {
1853 : assert(!i->second.empty());
1854 : SAL_INFO_IF(
1855 : i->second.size() > 1, "cppuhelper",
1856 : "Arbitrarily chosing " << i->second[0]->info->name
1857 : << " among multiple implementations for " << i->first);
1858 356102 : impl = i->second[0];
1859 : }
1860 : assert(impl.get() != 0);
1861 365591 : loaded = impl->loaded;
1862 : }
1863 : //TODO: There is a race here, as the relevant service factory can be removed
1864 : // while the mutex is unlocked and loading can thus fail, as the entity from
1865 : // which to load can disappear once the service factory is removed.
1866 365591 : if (!loaded) {
1867 4881 : css::uno::Reference< css::lang::XSingleComponentFactory > f1;
1868 4881 : css::uno::Reference< css::lang::XSingleServiceFactory > f2;
1869 4881 : loadImplementation(context, impl->info, &f1, &f2);
1870 4881 : osl::MutexGuard g(rBHelper.rMutex);
1871 4881 : if (!(isDisposed() || impl->loaded)) {
1872 4881 : impl->loaded = true;
1873 4881 : impl->factory1 = f1;
1874 4881 : impl->factory2 = f2;
1875 4881 : }
1876 : }
1877 365591 : return impl;
1878 : }
1879 :
1880 : css::uno::Reference< css::uno::XInterface >
1881 20 : FactoryWrapper::createInstanceWithContext(
1882 : css::uno::Reference< css::uno::XComponentContext > const & Context)
1883 : throw (css::uno::Exception, css::uno::RuntimeException)
1884 : {
1885 20 : loadImplementation(Context);
1886 20 : return factory1_.is()
1887 20 : ? factory1_->createInstanceWithContext(Context)
1888 40 : : factory2_->createInstance();
1889 : }
1890 :
1891 : css::uno::Reference< css::uno::XInterface >
1892 49 : FactoryWrapper::createInstanceWithArgumentsAndContext(
1893 : css::uno::Sequence< css::uno::Any > const & Arguments,
1894 : css::uno::Reference< css::uno::XComponentContext > const & Context)
1895 : throw (css::uno::Exception, css::uno::RuntimeException)
1896 : {
1897 49 : loadImplementation(Context);
1898 49 : return factory1_.is()
1899 49 : ? factory1_->createInstanceWithArgumentsAndContext(Arguments, Context)
1900 98 : : factory2_->createInstanceWithArguments(Arguments);
1901 : }
1902 :
1903 0 : css::uno::Reference< css::uno::XInterface > FactoryWrapper::createInstance()
1904 : throw (css::uno::Exception, css::uno::RuntimeException)
1905 : {
1906 0 : loadImplementation(manager_->getContext());
1907 0 : return factory1_.is()
1908 0 : ? factory1_->createInstanceWithContext(manager_->getContext())
1909 0 : : factory2_->createInstance();
1910 : }
1911 :
1912 : css::uno::Reference< css::uno::XInterface >
1913 0 : FactoryWrapper::createInstanceWithArguments(
1914 : css::uno::Sequence< css::uno::Any > const & Arguments)
1915 : throw (css::uno::Exception, css::uno::RuntimeException)
1916 : {
1917 0 : loadImplementation(manager_->getContext());
1918 0 : return factory1_.is()
1919 0 : ? factory1_->createInstanceWithArgumentsAndContext(
1920 0 : Arguments, manager_->getContext())
1921 0 : : factory2_->createInstanceWithArguments(Arguments);
1922 : }
1923 :
1924 36 : rtl::OUString FactoryWrapper::getImplementationName()
1925 : throw (css::uno::RuntimeException)
1926 : {
1927 36 : return info_->name;
1928 : }
1929 :
1930 0 : sal_Bool FactoryWrapper::supportsService(rtl::OUString const & ServiceName)
1931 : throw (css::uno::RuntimeException)
1932 : {
1933 0 : return cppu::supportsService(this, ServiceName);
1934 : }
1935 :
1936 8 : css::uno::Sequence< rtl::OUString > FactoryWrapper::getSupportedServiceNames()
1937 : throw (css::uno::RuntimeException)
1938 : {
1939 8 : if (info_->services.size() > static_cast< sal_uInt32 >(SAL_MAX_INT32)) {
1940 : throw css::uno::RuntimeException(
1941 0 : "Implementation " + info_->name + " supports too many services",
1942 0 : static_cast< cppu::OWeakObject * >(this));
1943 : }
1944 : css::uno::Sequence< rtl::OUString > names(
1945 8 : static_cast< sal_Int32 >(info_->services.size()));
1946 8 : sal_Int32 i = 0;
1947 120 : for (std::vector< rtl::OUString >::const_iterator j(
1948 8 : info_->services.begin());
1949 80 : j != info_->services.end(); ++j)
1950 : {
1951 32 : names[i++] = *j;
1952 : }
1953 8 : return names;
1954 : }
1955 :
1956 69 : void FactoryWrapper::loadImplementation(
1957 : css::uno::Reference< css::uno::XComponentContext > const & context)
1958 : {
1959 : {
1960 69 : osl::MutexGuard g(mutex_);
1961 69 : if (loaded_) {
1962 69 : return;
1963 69 : }
1964 : }
1965 32 : css::uno::Reference< css::lang::XSingleComponentFactory > f1;
1966 32 : css::uno::Reference< css::lang::XSingleServiceFactory > f2;
1967 : //TODO: There is a race here, as the relevant service factory can already
1968 : // have been removed and loading can thus fail, as the entity from which to
1969 : // load can disappear once the service factory is removed:
1970 32 : manager_->loadImplementation(context, info_, &f1, &f2);
1971 32 : if (!(f1.is() || f2.is())) {
1972 : throw css::uno::DeploymentException(
1973 0 : "Implementation " + info_->name + " does not provide a factory",
1974 0 : static_cast< cppu::OWeakObject * >(this));
1975 : }
1976 32 : osl::MutexGuard g(mutex_);
1977 32 : if (!loaded_) {
1978 32 : loaded_ = true;
1979 32 : factory1_ = f1;
1980 32 : factory2_ = f2;
1981 32 : }
1982 : }
1983 :
1984 120 : css::uno::Reference< css::uno::XComponentContext > bootstrapComponentContext(
1985 : css::uno::Reference< css::registry::XSimpleRegistry > const & typeRegistry,
1986 : rtl::OUString const & serviceUris, rtl::Bootstrap const & bootstrap)
1987 : {
1988 120 : rtl::Reference< ServiceManager > smgr(new ServiceManager(serviceUris));
1989 120 : cppu::ContextEntry_Init entry;
1990 120 : std::vector< cppu::ContextEntry_Init > context_values;
1991 : context_values.push_back(
1992 : cppu::ContextEntry_Init(
1993 : "/singletons/com.sun.star.lang.theServiceManager",
1994 : css::uno::makeAny(
1995 : css::uno::Reference< css::uno::XInterface >(
1996 120 : static_cast< cppu::OWeakObject * >(smgr.get()))),
1997 120 : false));
1998 : context_values.push_back( //TODO: from services.rdb?
1999 : cppu::ContextEntry_Init(
2000 : "/singletons/com.sun.star.reflection.theTypeDescriptionManager",
2001 : css::uno::makeAny(
2002 : rtl::OUString("com.sun.star.comp.stoc.TypeDescriptionManager")),
2003 120 : true /*TODO: false?*/));
2004 : context_values.push_back( //TODO: from services.rdb?
2005 : cppu::ContextEntry_Init(
2006 : "/singletons/com.sun.star.util.theMacroExpander",
2007 : css::uno::makeAny(
2008 : cppuhelper::detail::create_bootstrap_macro_expander_factory()),
2009 120 : true));
2010 120 : Data const & data = smgr->getData();
2011 2814 : for (ImplementationMap::const_iterator i(data.singletons.begin());
2012 1876 : i != data.singletons.end(); ++i)
2013 : {
2014 : assert(!i->second.empty());
2015 : assert(i->second[0].get() != 0);
2016 : SAL_INFO_IF(
2017 : i->second.size() > 1, "cppuhelper",
2018 : "Arbitrarily chosing " << i->second[0]->info->name
2019 : << " among multiple implementations for " << i->first);
2020 : context_values.push_back(
2021 : cppu::ContextEntry_Init(
2022 818 : "/singletons/" + i->first,
2023 1636 : css::uno::makeAny(i->second[0]->info->name), true));
2024 : }
2025 120 : cppu::add_access_control_entries(&context_values, bootstrap);
2026 : assert(!context_values.empty());
2027 : css::uno::Reference< css::uno::XComponentContext > context(
2028 : createComponentContext(
2029 240 : &context_values[0], context_values.size(),
2030 360 : css::uno::Reference< css::uno::XComponentContext >()));
2031 120 : smgr->setContext(context);
2032 : css::uno::Reference< css::container::XHierarchicalNameAccess > tdmgr(
2033 120 : context->getValueByName(
2034 120 : "/singletons/com.sun.star.reflection.theTypeDescriptionManager"),
2035 120 : css::uno::UNO_QUERY_THROW);
2036 120 : if (typeRegistry.is()) {
2037 120 : css::uno::Sequence< css::uno::Any > arg(1);
2038 120 : arg[0] <<= typeRegistry;
2039 : css::uno::Reference< css::container::XSet >(
2040 240 : tdmgr, css::uno::UNO_QUERY_THROW)->
2041 : insert(
2042 : css::uno::makeAny(
2043 120 : smgr->createInstanceWithArgumentsAndContext(
2044 : ("com.sun.star.comp.stoc"
2045 : ".RegistryTypeDescriptionProvider"),
2046 360 : arg, context)));
2047 : }
2048 120 : cppu::installTypeDescriptionManager(tdmgr);
2049 120 : return context;
2050 : }
2051 :
2052 360 : rtl::OUString getBootstrapVariable(
2053 : rtl::Bootstrap const & bootstrap, rtl::OUString const & name)
2054 : {
2055 360 : rtl::OUString v;
2056 360 : if (!bootstrap.getFrom(name, v)) {
2057 : throw css::uno::DeploymentException(
2058 0 : "Cannot obtain " + name + " from uno ini",
2059 0 : css::uno::Reference< css::uno::XInterface >());
2060 : }
2061 360 : return v;
2062 : }
2063 :
2064 258 : css::uno::Reference< css::registry::XSimpleRegistry > readTypeRdbFile(
2065 : rtl::OUString const & uri, bool optional,
2066 : css::uno::Reference< css::registry::XSimpleRegistry > const & lastRegistry,
2067 : css::uno::Reference< css::lang::XSingleServiceFactory > const &
2068 : simpleRegistryFactory,
2069 : css::uno::Reference< css::lang::XSingleServiceFactory > const &
2070 : nestedRegistryFactory)
2071 : {
2072 : assert(simpleRegistryFactory.is() && nestedRegistryFactory.is());
2073 : try {
2074 : css::uno::Reference< css::registry::XSimpleRegistry > simple(
2075 258 : simpleRegistryFactory->createInstance(), css::uno::UNO_QUERY_THROW);
2076 258 : simple->open(uri, true, false);
2077 258 : if (lastRegistry.is()) {
2078 : css::uno::Reference< css::registry::XSimpleRegistry > nested(
2079 138 : nestedRegistryFactory->createInstance(),
2080 138 : css::uno::UNO_QUERY_THROW);
2081 138 : css::uno::Sequence< css::uno::Any > args(2);
2082 138 : args[0] <<= lastRegistry;
2083 138 : args[1] <<= simple;
2084 : css::uno::Reference< css::lang::XInitialization >(
2085 276 : nested, css::uno::UNO_QUERY_THROW)->
2086 138 : initialize(args);
2087 138 : return nested;
2088 : } else {
2089 120 : return simple;
2090 258 : }
2091 0 : } catch (css::registry::InvalidRegistryException & e) {
2092 0 : if (!optional) {
2093 : throw css::uno::DeploymentException(
2094 0 : "Invalid registry " + uri + ":" + e.Message,
2095 0 : css::uno::Reference< css::uno::XInterface >());
2096 : }
2097 : SAL_INFO("cppuhelper", "Ignored optional " << uri);
2098 0 : return lastRegistry;
2099 : }
2100 : }
2101 :
2102 8 : css::uno::Reference< css::registry::XSimpleRegistry > readTypeRdbDirectory(
2103 : rtl::OUString const & uri, bool optional,
2104 : css::uno::Reference< css::registry::XSimpleRegistry > const & lastRegistry,
2105 : css::uno::Reference< css::lang::XSingleServiceFactory > const &
2106 : simpleRegistryFactory,
2107 : css::uno::Reference< css::lang::XSingleServiceFactory > const &
2108 : nestedRegistryFactory)
2109 : {
2110 : assert(simpleRegistryFactory.is() && nestedRegistryFactory.is());
2111 8 : osl::Directory dir(uri);
2112 8 : switch (dir.open()) {
2113 : case osl::FileBase::E_None:
2114 8 : break;
2115 : case osl::FileBase::E_NOENT:
2116 0 : if (optional) {
2117 : SAL_INFO("cppuhelper", "Ignored optional " << uri);
2118 0 : return lastRegistry;
2119 : }
2120 : // fall through
2121 : default:
2122 : throw css::uno::DeploymentException(
2123 : "Cannot open directory " + uri,
2124 0 : css::uno::Reference< css::uno::XInterface >());
2125 : }
2126 8 : css::uno::Reference< css::registry::XSimpleRegistry > last(lastRegistry);
2127 16 : for (;;) {
2128 24 : rtl::OUString fileUri;
2129 24 : if (!nextDirectoryItem(dir, &fileUri)) {
2130 : break;
2131 : }
2132 : last = readTypeRdbFile(
2133 : fileUri, optional, last, simpleRegistryFactory,
2134 16 : nestedRegistryFactory);
2135 24 : }
2136 8 : return last;
2137 : }
2138 :
2139 120 : css::uno::Reference< css::registry::XSimpleRegistry > createTypeRegistry(
2140 : rtl::OUString const & uris, rtl::OUString const & libraryDirectoryUri)
2141 : {
2142 : css::uno::Reference< css::lang::XMultiComponentFactory > factory(
2143 120 : cppu::bootstrapInitialSF(libraryDirectoryUri));
2144 : css::uno::Reference< css::lang::XSingleServiceFactory > simpleRegs(
2145 : cppu::loadSharedLibComponentFactory(
2146 : "bootstrap.uno" SAL_DLLEXTENSION, libraryDirectoryUri,
2147 : "com.sun.star.comp.stoc.SimpleRegistry",
2148 : css::uno::Reference< css::lang::XMultiServiceFactory >(
2149 : factory, css::uno::UNO_QUERY_THROW),
2150 : css::uno::Reference< css::registry::XRegistryKey >()),
2151 120 : css::uno::UNO_QUERY_THROW);
2152 : css::uno::Reference< css::lang::XSingleServiceFactory > nestedRegs(
2153 : cppu::loadSharedLibComponentFactory(
2154 : "bootstrap.uno" SAL_DLLEXTENSION, libraryDirectoryUri,
2155 : "com.sun.star.comp.stoc.NestedRegistry",
2156 : css::uno::Reference< css::lang::XMultiServiceFactory >(
2157 : factory, css::uno::UNO_QUERY_THROW),
2158 : css::uno::Reference< css::registry::XRegistryKey >()),
2159 120 : css::uno::UNO_QUERY_THROW);
2160 120 : css::uno::Reference< css::registry::XSimpleRegistry > reg;
2161 514 : for (sal_Int32 i = 0; i != -1;) {
2162 274 : rtl::OUString uri(uris.getToken(0, ' ', i));
2163 274 : if (uri.isEmpty()) {
2164 24 : continue;
2165 : }
2166 : bool optional;
2167 : bool directory;
2168 250 : decodeRdbUri(&uri, &optional, &directory);
2169 : reg = directory
2170 : ? readTypeRdbDirectory(uri, optional, reg, simpleRegs, nestedRegs)
2171 250 : : readTypeRdbFile(uri, optional, reg, simpleRegs, nestedRegs);
2172 274 : }
2173 120 : return reg;
2174 : }
2175 :
2176 : }
2177 :
2178 : css::uno::Reference< css::uno::XComponentContext >
2179 120 : cppu::defaultBootstrap_InitialComponentContext(rtl::OUString const & iniUri)
2180 : SAL_THROW((css::uno::Exception))
2181 : {
2182 120 : rtl::Bootstrap bs(iniUri);
2183 120 : if (bs.getHandle() == 0) {
2184 : throw css::uno::DeploymentException(
2185 : "Cannot open uno ini " + iniUri,
2186 0 : css::uno::Reference< css::uno::XInterface >());
2187 : }
2188 : return bootstrapComponentContext(
2189 : createTypeRegistry(
2190 : getBootstrapVariable(bs, "UNO_TYPES"),
2191 : getBootstrapVariable(bs, "URE_INTERNAL_LIB_DIR")),
2192 120 : getBootstrapVariable(bs, "UNO_SERVICES"), bs);
2193 : }
2194 :
2195 : css::uno::Reference< css::uno::XComponentContext >
2196 120 : cppu::defaultBootstrap_InitialComponentContext()
2197 : SAL_THROW((css::uno::Exception))
2198 : {
2199 120 : return defaultBootstrap_InitialComponentContext(getUnoIniUri());
2200 : }
2201 :
2202 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|