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