LibreOffice Module cppuhelper (master) 1
servicemanager.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <sal/config.h>
11
12#include <algorithm>
13#include <cassert>
14#include <iostream>
15#include <mutex>
16#include <string_view>
17#include <utility>
18#include <vector>
19
20#include <com/sun/star/beans/NamedValue.hpp>
21#include <com/sun/star/beans/PropertyAttribute.hpp>
22#include <com/sun/star/container/ElementExistException.hpp>
23#include <com/sun/star/container/XEnumeration.hpp>
24#include <com/sun/star/container/XNameContainer.hpp>
25#include <com/sun/star/lang/XInitialization.hpp>
26#include <com/sun/star/lang/XServiceInfo.hpp>
27#include <com/sun/star/lang/XSingleComponentFactory.hpp>
28#include <com/sun/star/lang/XSingleServiceFactory.hpp>
29#include <com/sun/star/loader/XImplementationLoader.hpp>
30#include <com/sun/star/registry/InvalidRegistryException.hpp>
31#include <com/sun/star/uno/DeploymentException.hpp>
32#include <com/sun/star/uno/Reference.hxx>
33#include <com/sun/star/uno/XComponentContext.hpp>
40#include <o3tl/safeint.hxx>
41#include <osl/file.hxx>
42#include <osl/module.hxx>
43#include <rtl/ref.hxx>
44#include <rtl/uri.hxx>
45#include <rtl/ustring.hxx>
46#include <rtl/ustrbuf.hxx>
47#include <sal/log.hxx>
48#include <uno/environment.hxx>
49#include <uno/mapping.hxx>
50#include <o3tl/string_view.hxx>
51
53
54#include <registry/registry.hxx>
56
57#include "paths.hxx"
58#include "servicemanager.hxx"
59
60namespace {
61
62void insertImplementationMap(
65{
66 assert(destination != nullptr);
67 for (const auto& [rName, rImpls] : source)
68 {
69 std::vector<
70 std::shared_ptr<
72 = (*destination)[rName];
73 impls.insert(impls.end(), rImpls.begin(), rImpls.end());
74 }
75}
76
77void removeFromImplementationMap(
79 std::vector< OUString > const & elements,
80 std::shared_ptr< cppuhelper::ServiceManager::Data::Implementation >
81 const & implementation)
82{
83 // The underlying data structures make this function somewhat inefficient,
84 // but the assumption is that it is rarely called:
85 assert(map != nullptr);
86 for (const auto& rElement : elements)
87 {
88 cppuhelper::ServiceManager::Data::ImplementationMap::iterator j(
89 map->find(rElement));
90 assert(j != map->end());
91 std::vector<
92 std::shared_ptr<
94 k(std::find(j->second.begin(), j->second.end(), implementation));
95 assert(k != j->second.end());
96 j->second.erase(k);
97 if (j->second.empty()) {
98 map->erase(j);
99 }
100 }
101}
102
103// For simplicity, this code keeps throwing
104// css::registry::InvalidRegistryException for invalid XML rdbs (even though
105// that does not fit the exception's name):
106class Parser {
107public:
108 Parser(
109 OUString const & uri,
110 css::uno::Reference< css::uno::XComponentContext > alienContext,
112
113 Parser(const Parser&) = delete;
114 const Parser& operator=(const Parser&) = delete;
115
116private:
117 void handleComponent();
118
119 void handleImplementation();
120
121 void handleService();
122
123 void handleSingleton();
124
125 OUString getNameAttribute();
126
127 xmlreader::XmlReader reader_;
128 css::uno::Reference< css::uno::XComponentContext > alienContext_;
130 OUString attrLoader_;
131 OUString attrUri_;
132 OUString attrEnvironment_;
133 OUString attrPrefix_;
134 std::shared_ptr< cppuhelper::ServiceManager::Data::Implementation >
135 implementation_;
136};
137
138Parser::Parser(
139 OUString const & uri,
140 css::uno::Reference< css::uno::XComponentContext > alienContext,
142 reader_(uri), alienContext_(std::move(alienContext)), data_(data)
143{
144 assert(data != nullptr);
145 int ucNsId = reader_.registerNamespaceIri(
147 RTL_CONSTASCII_STRINGPARAM(
148 "http://openoffice.org/2010/uno-components")));
149 enum State {
150 STATE_BEGIN, STATE_END, STATE_COMPONENTS, STATE_COMPONENT_INITIAL,
151 STATE_COMPONENT, STATE_IMPLEMENTATION, STATE_SERVICE, STATE_SINGLETON };
152 for (State state = STATE_BEGIN;;) {
154 int nsId;
155 xmlreader::XmlReader::Result res = reader_.nextItem(
156 xmlreader::XmlReader::Text::NONE, &name, &nsId);
157 switch (state) {
158 case STATE_BEGIN:
159 if (res == xmlreader::XmlReader::Result::Begin && nsId == ucNsId
160 && name.equals(RTL_CONSTASCII_STRINGPARAM("components")))
161 {
162 state = STATE_COMPONENTS;
163 break;
164 }
165 throw css::registry::InvalidRegistryException(
166 reader_.getUrl() + ": unexpected item in outer level");
167 case STATE_END:
168 if (res == xmlreader::XmlReader::Result::Done) {
169 return;
170 }
171 throw css::registry::InvalidRegistryException(
172 reader_.getUrl() + ": unexpected item in outer level");
173 case STATE_COMPONENTS:
174 if (res == xmlreader::XmlReader::Result::End) {
175 state = STATE_END;
176 break;
177 }
178 if (res == xmlreader::XmlReader::Result::Begin && nsId == ucNsId
179 && name.equals(RTL_CONSTASCII_STRINGPARAM("component")))
180 {
181 handleComponent();
182 state = STATE_COMPONENT_INITIAL;
183 break;
184 }
185 throw css::registry::InvalidRegistryException(
186 reader_.getUrl() + ": unexpected item in <components>");
187 case STATE_COMPONENT:
188 if (res == xmlreader::XmlReader::Result::End) {
189 state = STATE_COMPONENTS;
190 break;
191 }
192 [[fallthrough]];
193 case STATE_COMPONENT_INITIAL:
194 if (res == xmlreader::XmlReader::Result::Begin && nsId == ucNsId
195 && name.equals(RTL_CONSTASCII_STRINGPARAM("implementation")))
196 {
197 handleImplementation();
198 state = STATE_IMPLEMENTATION;
199 break;
200 }
201 throw css::registry::InvalidRegistryException(
202 reader_.getUrl() + ": unexpected item in <component>");
203 case STATE_IMPLEMENTATION:
204 if (res == xmlreader::XmlReader::Result::End) {
205 state = STATE_COMPONENT;
206 break;
207 }
208 if (res == xmlreader::XmlReader::Result::Begin && nsId == ucNsId
209 && name.equals(RTL_CONSTASCII_STRINGPARAM("service")))
210 {
211 handleService();
212 state = STATE_SERVICE;
213 break;
214 }
215 if (res == xmlreader::XmlReader::Result::Begin && nsId == ucNsId
216 && name.equals(RTL_CONSTASCII_STRINGPARAM("singleton")))
217 {
218 handleSingleton();
219 state = STATE_SINGLETON;
220 break;
221 }
222 throw css::registry::InvalidRegistryException(
223 reader_.getUrl() + ": unexpected item in <implementation>");
224 case STATE_SERVICE:
225 if (res == xmlreader::XmlReader::Result::End) {
226 state = STATE_IMPLEMENTATION;
227 break;
228 }
229 throw css::registry::InvalidRegistryException(
230 reader_.getUrl() + ": unexpected item in <service>");
231 case STATE_SINGLETON:
232 if (res == xmlreader::XmlReader::Result::End) {
233 state = STATE_IMPLEMENTATION;
234 break;
235 }
236 throw css::registry::InvalidRegistryException(
237 reader_.getUrl() + ": unexpected item in <service>");
238 }
239 }
240}
241
242void Parser::handleComponent() {
243 attrLoader_ = OUString();
244 attrUri_ = OUString();
245 attrEnvironment_ = OUString();
246 attrPrefix_ = OUString();
248 int nsId;
249 while (reader_.nextAttribute(&nsId, &name)) {
251 && name.equals(RTL_CONSTASCII_STRINGPARAM("loader")))
252 {
253 if (!attrLoader_.isEmpty()) {
254 throw css::registry::InvalidRegistryException(
255 reader_.getUrl()
256 + ": <component> has multiple \"loader\" attributes");
257 }
258 attrLoader_ = reader_.getAttributeValue(false).convertFromUtf8();
259 if (attrLoader_.isEmpty()) {
260 throw css::registry::InvalidRegistryException(
261 reader_.getUrl()
262 + ": <component> has empty \"loader\" attribute");
263 }
264 } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
265 && name.equals(RTL_CONSTASCII_STRINGPARAM("uri")))
266 {
267 if (!attrUri_.isEmpty()) {
268 throw css::registry::InvalidRegistryException(
269 reader_.getUrl()
270 + ": <component> has multiple \"uri\" attributes");
271 }
272 attrUri_ = reader_.getAttributeValue(false).convertFromUtf8();
273 if (attrUri_.isEmpty()) {
274 throw css::registry::InvalidRegistryException(
275 reader_.getUrl()
276 + ": <component> has empty \"uri\" attribute");
277 }
278 } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
279 && name.equals(RTL_CONSTASCII_STRINGPARAM("environment")))
280 {
281 if (!attrEnvironment_.isEmpty()) {
282 throw css::registry::InvalidRegistryException(
283 reader_.getUrl() +
284 ": <component> has multiple \"environment\" attributes");
285 }
286 attrEnvironment_ = reader_.getAttributeValue(false)
287 .convertFromUtf8();
288 if (attrEnvironment_.isEmpty()) {
289 throw css::registry::InvalidRegistryException(
290 reader_.getUrl() +
291 ": <component> has empty \"environment\" attribute");
292 }
293 } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
294 && name.equals(RTL_CONSTASCII_STRINGPARAM("prefix")))
295 {
296 if (!attrPrefix_.isEmpty()) {
297 throw css::registry::InvalidRegistryException(
298 reader_.getUrl() +
299 ": <component> has multiple \"prefix\" attributes");
300 }
301 attrPrefix_ = reader_.getAttributeValue(false).convertFromUtf8();
302 if (attrPrefix_.isEmpty()) {
303 throw css::registry::InvalidRegistryException(
304 reader_.getUrl() +
305 ": <component> has empty \"prefix\" attribute");
306 }
307 } else {
308 throw css::registry::InvalidRegistryException(
309 reader_.getUrl() + ": unexpected attribute \""
310 + name.convertFromUtf8() + "\" in <component>");
311 }
312 }
313 if (attrLoader_.isEmpty()) {
314 throw css::registry::InvalidRegistryException(
315 reader_.getUrl() + ": <component> is missing \"loader\" attribute");
316 }
317 if (attrUri_.isEmpty()) {
318 throw css::registry::InvalidRegistryException(
319 reader_.getUrl() + ": <component> is missing \"uri\" attribute");
320 }
321#ifndef DISABLE_DYNLOADING
322 try {
323 attrUri_ = rtl::Uri::convertRelToAbs(reader_.getUrl(), attrUri_);
324 } catch (const rtl::MalformedUriException & e) {
325 throw css::registry::InvalidRegistryException(
326 reader_.getUrl() + ": bad \"uri\" attribute: " + e.getMessage());
327 }
328#endif
329}
330
331void Parser::handleImplementation() {
332 OUString attrName;
333 OUString attrConstructor;
334 bool attrSingleInstance = false;
336 int nsId;
337 while (reader_.nextAttribute(&nsId, &name)) {
339 && name.equals(RTL_CONSTASCII_STRINGPARAM("name")))
340 {
341 if (!attrName.isEmpty()) {
342 throw css::registry::InvalidRegistryException(
343 reader_.getUrl()
344 + ": <implementation> has multiple \"name\" attributes");
345 }
346 attrName = reader_.getAttributeValue(false).convertFromUtf8();
347 if (attrName.isEmpty()) {
348 throw css::registry::InvalidRegistryException(
349 reader_.getUrl()
350 + ": <implementation> has empty \"name\" attribute");
351 }
352 } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
353 && name.equals(RTL_CONSTASCII_STRINGPARAM("constructor")))
354 {
355 if (!attrConstructor.isEmpty()) {
356 throw css::registry::InvalidRegistryException(
357 reader_.getUrl()
358 + ": <implementation> has multiple \"constructor\""
359 " attributes");
360 }
361 attrConstructor = reader_.getAttributeValue(false)
362 .convertFromUtf8();
363 if (attrConstructor.isEmpty()) {
364 throw css::registry::InvalidRegistryException(
365 reader_.getUrl()
366 + ": element has empty \"constructor\" attribute");
367 }
368 if (attrEnvironment_.isEmpty()) {
369 throw css::registry::InvalidRegistryException(
370 reader_.getUrl()
371 + ": <implementation> has \"constructor\" attribute but"
372 " <component> has no \"environment\" attribute");
373 }
374 } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
375 && name.equals(RTL_CONSTASCII_STRINGPARAM("single-instance")))
376 {
377 if (attrSingleInstance) {
378 throw css::registry::InvalidRegistryException(
379 reader_.getUrl()
380 + ": <implementation> has multiple \"single-instance\" attributes");
381 }
382 if (!reader_.getAttributeValue(false).equals(RTL_CONSTASCII_STRINGPARAM("true"))) {
383 throw css::registry::InvalidRegistryException(
384 reader_.getUrl() + ": <implementation> has bad \"single-instance\" attribute");
385 }
386 attrSingleInstance = true;
387 } else {
388 throw css::registry::InvalidRegistryException(
389 reader_.getUrl() + ": unexpected element attribute \""
390 + name.convertFromUtf8() + "\" in <implementation>");
391 }
392 }
393 if (attrName.isEmpty()) {
394 throw css::registry::InvalidRegistryException(
395 reader_.getUrl()
396 + ": <implementation> is missing \"name\" attribute");
397 }
398 implementation_ =
399 std::make_shared<cppuhelper::ServiceManager::Data::Implementation>(
400 attrName, attrLoader_, attrUri_, attrEnvironment_, attrConstructor,
401 attrPrefix_, attrSingleInstance, alienContext_, reader_.getUrl());
402 if (!data_->namedImplementations.emplace(attrName, implementation_).
403 second)
404 {
405 throw css::registry::InvalidRegistryException(
406 reader_.getUrl() + ": duplicate <implementation name=\"" + attrName
407 + "\">");
408 }
409}
410
411void Parser::handleService() {
412 OUString name(getNameAttribute());
413 implementation_->services.push_back(name);
414 data_->services[name].push_back(implementation_);
415}
416
417void Parser::handleSingleton() {
418 OUString name(getNameAttribute());
419 implementation_->singletons.push_back(name);
420 data_->singletons[name].push_back(implementation_);
421}
422
423OUString Parser::getNameAttribute() {
424 OUString attrName;
426 int nsId;
427 while (reader_.nextAttribute(&nsId, &name)) {
429 || !name.equals(RTL_CONSTASCII_STRINGPARAM("name")))
430 {
431 throw css::registry::InvalidRegistryException(
432 reader_.getUrl() + ": expected element attribute \"name\"");
433 }
434 if (!attrName.isEmpty()) {
435 throw css::registry::InvalidRegistryException(
436 reader_.getUrl()
437 + ": element has multiple \"name\" attributes");
438 }
439 attrName = reader_.getAttributeValue(false).convertFromUtf8();
440 if (attrName.isEmpty()) {
441 throw css::registry::InvalidRegistryException(
442 reader_.getUrl() + ": element has empty \"name\" attribute");
443 }
444 }
445 if (attrName.isEmpty()) {
446 throw css::registry::InvalidRegistryException(
447 reader_.getUrl() + ": element is missing \"name\" attribute");
448 }
449 return attrName;
450}
451
452class ContentEnumeration:
453 public cppu::WeakImplHelper< css::container::XEnumeration >
454{
455public:
456 explicit ContentEnumeration(std::vector< css::uno::Any >&& factories):
457 factories_(std::move(factories)), iterator_(factories_.begin()) {}
458
459 ContentEnumeration(const ContentEnumeration&) = delete;
460 const ContentEnumeration& operator=(const ContentEnumeration&) = delete;
461
462private:
463 virtual ~ContentEnumeration() override {}
464
465 virtual sal_Bool SAL_CALL hasMoreElements() override;
466
467 virtual css::uno::Any SAL_CALL nextElement() override;
468
469 std::mutex mutex_;
470 std::vector< css::uno::Any > factories_;
471 std::vector< css::uno::Any >::const_iterator iterator_;
472};
473
474sal_Bool ContentEnumeration::hasMoreElements()
475{
476 std::scoped_lock g(mutex_);
477 return iterator_ != factories_.end();
478}
479
480css::uno::Any ContentEnumeration::nextElement()
481{
482 std::scoped_lock g(mutex_);
483 if (iterator_ == factories_.end()) {
484 throw css::container::NoSuchElementException(
485 "Bootstrap service manager service enumerator has no more elements",
486 static_cast< cppu::OWeakObject * >(this));
487 }
488 return *iterator_++;
489}
490
491css::beans::Property getDefaultContextProperty() {
492 return css::beans::Property(
493 "DefaultContext", -1,
495 css::beans::PropertyAttribute::READONLY);
496}
497
498class SingletonFactory:
499 public cppu::WeakImplHelper<css::lang::XSingleComponentFactory>
500{
501public:
502 SingletonFactory(
504 std::shared_ptr<
506 implementation):
507 manager_(manager), implementation_(implementation)
508 { assert(manager.is()); assert(implementation); }
509
510 SingletonFactory(const SingletonFactory&) = delete;
511 const SingletonFactory& operator=(const SingletonFactory&) = delete;
512
513private:
514 virtual ~SingletonFactory() override {}
515
516 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
517 createInstanceWithContext(
518 css::uno::Reference< css::uno::XComponentContext > const & Context) override;
519
520 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
521 createInstanceWithArgumentsAndContext(
522 css::uno::Sequence< css::uno::Any > const & Arguments,
523 css::uno::Reference< css::uno::XComponentContext > const & Context) override;
524
526 std::shared_ptr< cppuhelper::ServiceManager::Data::Implementation >
527 implementation_;
528};
529
530css::uno::Reference< css::uno::XInterface >
531SingletonFactory::createInstanceWithContext(
532 css::uno::Reference< css::uno::XComponentContext > const & Context)
533{
534 manager_->loadImplementation(Context, implementation_);
535 return implementation_->createInstance(Context, true);
536}
537
538css::uno::Reference< css::uno::XInterface >
539SingletonFactory::createInstanceWithArgumentsAndContext(
540 css::uno::Sequence< css::uno::Any > const & Arguments,
541 css::uno::Reference< css::uno::XComponentContext > const & Context)
542{
543 manager_->loadImplementation(Context, implementation_);
544 return implementation_->createInstanceWithArguments(
545 Context, true, Arguments);
546}
547
548class ImplementationWrapper:
549 public cppu::WeakImplHelper<
550 css::lang::XSingleComponentFactory, css::lang::XSingleServiceFactory,
551 css::lang::XServiceInfo >
552{
553public:
554 ImplementationWrapper(
556 std::shared_ptr<
558 implementation):
559 manager_(manager), implementation_(implementation)
560 { assert(manager.is()); assert(implementation); }
561
562 ImplementationWrapper(const ImplementationWrapper&) = delete;
563 const ImplementationWrapper& operator=(const ImplementationWrapper&) = delete;
564
565private:
566 virtual ~ImplementationWrapper() override {}
567
568 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
569 createInstanceWithContext(
570 css::uno::Reference< css::uno::XComponentContext > const & Context) override;
571
572 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
573 createInstanceWithArgumentsAndContext(
574 css::uno::Sequence< css::uno::Any > const & Arguments,
575 css::uno::Reference< css::uno::XComponentContext > const & Context) override;
576
577 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
578 createInstance() override;
579
580 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
581 createInstanceWithArguments(
582 css::uno::Sequence< css::uno::Any > const & Arguments) override;
583
584 virtual OUString SAL_CALL getImplementationName() override;
585
586 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override;
587
588 virtual css::uno::Sequence< OUString > SAL_CALL
589 getSupportedServiceNames() override;
590
592 std::weak_ptr< cppuhelper::ServiceManager::Data::Implementation >
593 implementation_;
594};
595
596css::uno::Reference< css::uno::XInterface >
597ImplementationWrapper::createInstanceWithContext(
598 css::uno::Reference< css::uno::XComponentContext > const & Context)
599{
600 std::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > impl = implementation_.lock();
601 assert(impl);
602 manager_->loadImplementation(Context, impl);
603 return impl->createInstance(Context, false);
604}
605
606css::uno::Reference< css::uno::XInterface >
607ImplementationWrapper::createInstanceWithArgumentsAndContext(
608 css::uno::Sequence< css::uno::Any > const & Arguments,
609 css::uno::Reference< css::uno::XComponentContext > const & Context)
610{
611 std::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > impl = implementation_.lock();
612 assert(impl);
613 manager_->loadImplementation(Context, impl);
614 return impl->createInstanceWithArguments(
615 Context, false, Arguments);
616}
617
618css::uno::Reference< css::uno::XInterface >
619ImplementationWrapper::createInstance()
620{
621 return createInstanceWithContext(manager_->getContext());
622}
623
624css::uno::Reference< css::uno::XInterface >
625ImplementationWrapper::createInstanceWithArguments(
626 css::uno::Sequence< css::uno::Any > const & Arguments)
627{
628 return createInstanceWithArgumentsAndContext(
629 Arguments, manager_->getContext());
630}
631
632OUString ImplementationWrapper::getImplementationName()
633{
634 std::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > impl = implementation_.lock();
635 assert(impl);
636 return impl->name;
637}
638
639sal_Bool ImplementationWrapper::supportsService(OUString const & ServiceName)
640{
641 return cppu::supportsService(this, ServiceName);
642}
643
644css::uno::Sequence< OUString >
645ImplementationWrapper::getSupportedServiceNames()
646{
647 std::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > impl = implementation_.lock();
648 assert(impl);
649 if (impl->services.size()
650 > o3tl::make_unsigned(SAL_MAX_INT32))
651 {
652 throw css::uno::RuntimeException(
653 ("Implementation " + impl->name
654 + " supports too many services"),
655 static_cast< cppu::OWeakObject * >(this));
656 }
657 return comphelper::containerToSequence(impl->services);
658}
659
660}
661
662css::uno::Reference<css::uno::XInterface>
664 css::uno::Reference<css::uno::XComponentContext> const & context,
665 bool singletonRequest)
666{
667 css::uno::Reference<css::uno::XInterface> inst;
668 if (isSingleInstance) {
669 std::unique_lock g(mutex);
670 if (!singleInstance.is()) {
672 }
673 inst = singleInstance;
674 } else {
675 inst = doCreateInstance(context);
676 }
677 updateDisposeInstance(singletonRequest, inst);
678 return inst;
679}
680
681css::uno::Reference<css::uno::XInterface>
683 css::uno::Reference<css::uno::XComponentContext> const & context,
684 bool singletonRequest, css::uno::Sequence<css::uno::Any> const & arguments)
685{
686 css::uno::Reference<css::uno::XInterface> inst;
687 if (isSingleInstance) {
688 std::unique_lock g(mutex);
689 if (!singleInstance.is()) {
690 singleInstance = doCreateInstanceWithArguments(context, arguments);
691 }
692 inst = singleInstance;
693 } else {
694 inst = doCreateInstanceWithArguments(context, arguments);
695 }
696 updateDisposeInstance(singletonRequest, inst);
697 return inst;
698}
699
700css::uno::Reference<css::uno::XInterface>
702 css::uno::Reference<css::uno::XComponentContext> const & context)
703{
704 if (constructorFn) {
705 return css::uno::Reference<css::uno::XInterface>(
706 constructorFn(context.get(), css::uno::Sequence<css::uno::Any>()),
707 SAL_NO_ACQUIRE);
708 } else if (factory1.is()) {
709 return factory1->createInstanceWithContext(context);
710 } else {
711 assert(factory2.is());
712 return factory2->createInstance();
713 }
714}
715
716css::uno::Reference<css::uno::XInterface>
718 css::uno::Reference<css::uno::XComponentContext> const & context,
719 css::uno::Sequence<css::uno::Any> const & arguments)
720{
721 if (constructorFn) {
722 css::uno::Reference<css::uno::XInterface> inst(
723 constructorFn(context.get(), arguments), SAL_NO_ACQUIRE);
724 //HACK: The constructor will either observe arguments and return inst
725 // that does not implement XInitialization (or null), or ignore
726 // arguments and return inst that implements XInitialization; this
727 // should be removed again once XInitialization-based implementations
728 // have become rare:
729 css::uno::Reference<css::lang::XInitialization> init(
730 inst, css::uno::UNO_QUERY);
731 if (init.is()) {
732 init->initialize(arguments);
733 }
734 return inst;
735 } else if (factory1.is()) {
736 return factory1->createInstanceWithArgumentsAndContext(
737 arguments, context);
738 } else {
739 assert(factory2.is());
740 return factory2->createInstanceWithArguments(arguments);
741 }
742}
743
745 bool singletonRequest,
746 css::uno::Reference<css::uno::XInterface> const & instance)
747{
748 // This is an optimization, to only call dispose once (from the component
749 // context) on a singleton that is obtained both via the component context
750 // and via the service manager; however, there is a harmless race here that
751 // may cause two calls to dispose nevertheless (also, this calls dispose on
752 // at most one of the instances obtained via the service manager, in case
753 // the implementation hands out different instances):
754 if (singletonRequest) {
755 std::unique_lock g(mutex);
756 disposeInstance.clear();
757 dispose = false;
758 } else if (shallDispose()) {
759 css::uno::Reference<css::lang::XComponent> comp(
760 instance, css::uno::UNO_QUERY);
761 if (comp.is()) {
762 std::unique_lock g(mutex);
763 if (dispose) {
764 disposeInstance = comp;
765 }
766 }
767 }
768}
769
771 std::vector< cppu::ContextEntry_Init > * entries)
772{
773 assert(entries != nullptr);
774 for (const auto& [rName, rImpls] : data_.singletons)
775 {
776 assert(!rImpls.empty());
777 assert(rImpls[0]);
779 rImpls.size() > 1, "cppuhelper",
780 "Arbitrarily choosing " << rImpls[0]->name
781 << " among multiple implementations for " << rName);
782 entries->push_back(
784 "/singletons/" + rName,
785 css::uno::Any(
786 css::uno::Reference<css::lang::XSingleComponentFactory>(
787 new SingletonFactory(this, rImpls[0]))),
788 true));
789 }
790}
791
793 css::uno::Reference< css::uno::XComponentContext > const & context,
794 std::shared_ptr< Data::Implementation > const & implementation)
795{
796 assert(implementation);
797 {
798 osl::MutexGuard g(rBHelper.rMutex);
799 if (implementation->status == Data::Implementation::STATUS_LOADED) {
800 return;
801 }
802 }
803 OUString uri;
804 try {
805 uri = cppu::bootstrap_expandUri(implementation->uri);
806 } catch (css::lang::IllegalArgumentException & e) {
807 throw css::uno::DeploymentException(
808 "Cannot expand URI" + implementation->uri + ": " + e.Message,
809 static_cast< cppu::OWeakObject * >(this));
810 }
812 css::uno::Reference< css::uno::XInterface > f0;
813 // Special handling of SharedLibrary loader, with support for environment,
814 // constructor, and prefix arguments:
815 if (!implementation->alienContext.is()
816 && implementation->loader == "com.sun.star.loader.SharedLibrary")
817 {
819 uri, implementation->environment,
820 implementation->prefix, implementation->name,
821 implementation->constructorName, this, &ctor, &f0);
822 if (ctor) {
823 assert(!implementation->environment.isEmpty());
824 }
825 } else {
827 !implementation->environment.isEmpty(), "cppuhelper",
828 "Loader " << implementation->loader
829 << " and non-empty environment "
830 << implementation->environment);
832 !implementation->prefix.isEmpty(), "cppuhelper",
833 "Loader " << implementation->loader
834 << " and non-empty constructor "
835 << implementation->constructorName);
837 !implementation->prefix.isEmpty(), "cppuhelper",
838 "Loader " << implementation->loader
839 << " and non-empty prefix " << implementation->prefix);
840 css::uno::Reference< css::uno::XComponentContext > ctxt;
841 css::uno::Reference< css::lang::XMultiComponentFactory > smgr;
842 if (implementation->alienContext.is()) {
843 ctxt = implementation->alienContext;
844 smgr.set(ctxt->getServiceManager(), css::uno::UNO_SET_THROW);
845 } else {
846 assert(context.is());
847 ctxt = context;
848 smgr = this;
849 }
850 css::uno::Reference< css::loader::XImplementationLoader > loader(
851 smgr->createInstanceWithContext(implementation->loader, ctxt),
852 css::uno::UNO_QUERY_THROW);
853 f0 = loader->activate(
854 implementation->name, OUString(), uri,
855 css::uno::Reference< css::registry::XRegistryKey >());
856 }
857 css::uno::Reference<css::lang::XSingleComponentFactory> f1;
858 css::uno::Reference<css::lang::XSingleServiceFactory> f2;
859 if (!ctor) {
860 f1.set(f0, css::uno::UNO_QUERY);
861 if (!f1.is()) {
862 f2.set(f0, css::uno::UNO_QUERY);
863 if (!f2.is()) {
864 throw css::uno::DeploymentException(
865 ("Implementation " + implementation->name
866 + " does not provide a constructor or factory"),
867 static_cast< cppu::OWeakObject * >(this));
868 }
869 }
870 }
871 //TODO: There is a race here, as the relevant service factory can be removed
872 // while the mutex is unlocked and loading can thus fail, as the entity from
873 // which to load can disappear once the service factory is removed.
874 osl::MutexGuard g(rBHelper.rMutex);
875 if (!(isDisposed()
876 || implementation->status == Data::Implementation::STATUS_LOADED))
877 {
878 implementation->status = Data::Implementation::STATUS_LOADED;
879 implementation->constructorFn = ctor;
880 implementation->factory1 = f1;
881 implementation->factory2 = f2;
882 }
883}
884
886 std::vector< css::uno::Reference<css::lang::XComponent> > sngls;
887 std::vector< css::uno::Reference< css::lang::XComponent > > comps;
888 Data clear;
889 {
890 osl::MutexGuard g(rBHelper.rMutex);
891 for (const auto& rEntry : data_.namedImplementations)
892 {
893 assert(rEntry.second);
894 if (rEntry.second->shallDispose()) {
895 std::unique_lock g2(rEntry.second->mutex);
896 if (rEntry.second->disposeInstance.is()) {
897 sngls.push_back(rEntry.second->disposeInstance);
898 }
899 }
900 }
901 for (const auto& rEntry : data_.dynamicImplementations)
902 {
903 assert(rEntry.second);
904 if (rEntry.second->shallDispose()) {
905 std::unique_lock g2(rEntry.second->mutex);
906 if (rEntry.second->disposeInstance.is()) {
907 sngls.push_back(rEntry.second->disposeInstance);
908 }
909 }
910 if (rEntry.second->component.is()) {
911 comps.push_back(rEntry.second->component);
912 }
913 }
916 data_.services.swap(clear.services);
917 data_.singletons.swap(clear.singletons);
918 }
919 for (const auto& rxSngl : sngls)
920 {
921 try {
922 rxSngl->dispose();
923 } catch (css::uno::RuntimeException & e) {
924 SAL_WARN("cppuhelper", "Ignoring " << e << " while disposing singleton");
925 }
926 }
927 for (const auto& rxComp : comps)
928 {
930 }
931}
932
934 css::uno::Sequence<css::uno::Any> const & aArguments)
935{
936 OUString arg;
937 if (aArguments.getLength() != 1 || !(aArguments[0] >>= arg)
938 || arg != "preload")
939 {
940 throw css::lang::IllegalArgumentException(
941 "invalid ServiceManager::initialize argument",
942 css::uno::Reference<css::uno::XInterface>(), 0);
943 }
945}
946
948{
949 return
950 "com.sun.star.comp.cppuhelper.bootstrap.ServiceManager";
951}
952
954 OUString const & ServiceName)
955{
957}
958
959css::uno::Sequence< OUString >
961{
962 return { "com.sun.star.lang.MultiServiceFactory", "com.sun.star.lang.ServiceManager" };
963}
964
965css::uno::Reference< css::uno::XInterface >
967 OUString const & aServiceSpecifier)
968{
969 assert(context_.is());
970 return createInstanceWithContext(aServiceSpecifier, context_);
971}
972
973css::uno::Reference< css::uno::XInterface >
975 OUString const & ServiceSpecifier,
976 css::uno::Sequence< css::uno::Any > const & Arguments)
977{
978 assert(context_.is());
980 ServiceSpecifier, Arguments, context_);
981}
982
983css::uno::Sequence< OUString >
985{
986 osl::MutexGuard g(rBHelper.rMutex);
987 if (isDisposed()) {
988 return css::uno::Sequence< OUString >();
989 }
991 throw css::uno::RuntimeException(
992 "getAvailableServiceNames: too many services",
993 static_cast< cppu::OWeakObject * >(this));
994 }
996}
997
998css::uno::Reference< css::uno::XInterface >
1000 OUString const & aServiceSpecifier,
1001 css::uno::Reference< css::uno::XComponentContext > const & Context)
1002{
1003 std::shared_ptr< Data::Implementation > impl(
1004 findServiceImplementation(Context, aServiceSpecifier));
1005 return impl == nullptr ? css::uno::Reference<css::uno::XInterface>()
1006 : impl->createInstance(Context, false);
1007}
1008
1009css::uno::Reference< css::uno::XInterface >
1011 OUString const & ServiceSpecifier,
1012 css::uno::Sequence< css::uno::Any > const & Arguments,
1013 css::uno::Reference< css::uno::XComponentContext > const & Context)
1014{
1015 std::shared_ptr< Data::Implementation > impl(
1016 findServiceImplementation(Context, ServiceSpecifier));
1017 return impl == nullptr ? css::uno::Reference<css::uno::XInterface>()
1018 : impl->createInstanceWithArguments(Context, false, Arguments);
1019}
1020
1022{
1023 return css::uno::Type();
1024}
1025
1027{
1028 osl::MutexGuard g(rBHelper.rMutex);
1029 return
1030 !(data_.namedImplementations.empty()
1031 && data_.dynamicImplementations.empty());
1032}
1033
1034css::uno::Reference< css::container::XEnumeration >
1036{
1037 throw css::uno::RuntimeException(
1038 "ServiceManager createEnumeration: method not supported",
1039 static_cast< cppu::OWeakObject * >(this));
1040}
1041
1043{
1044 throw css::uno::RuntimeException(
1045 "ServiceManager has: method not supported",
1046 static_cast< cppu::OWeakObject * >(this));
1047}
1048
1049void cppuhelper::ServiceManager::insert(css::uno::Any const & aElement)
1050{
1051 css::uno::Sequence< css::beans::NamedValue > args;
1052 if (aElement >>= args) {
1053 std::vector< OUString > uris;
1054 css::uno::Reference< css::uno::XComponentContext > alienContext;
1055 for (const auto & arg : std::as_const(args)) {
1056 if (arg.Name == "uri") {
1057 OUString uri;
1058 if (!(arg.Value >>= uri)) {
1059 throw css::lang::IllegalArgumentException(
1060 "Bad uri argument",
1061 static_cast< cppu::OWeakObject * >(this), 0);
1062 }
1063 uris.push_back(uri);
1064 } else if (arg.Name == "component-context") {
1065 if (alienContext.is()) {
1066 throw css::lang::IllegalArgumentException(
1067 "Multiple component-context arguments",
1068 static_cast< cppu::OWeakObject * >(this), 0);
1069 }
1070 if (!(arg.Value >>= alienContext) || !alienContext.is()) {
1071 throw css::lang::IllegalArgumentException(
1072 "Bad component-context argument",
1073 static_cast< cppu::OWeakObject * >(this), 0);
1074 }
1075 } else {
1076 throw css::lang::IllegalArgumentException(
1077 "Bad argument " + arg.Name,
1078 static_cast< cppu::OWeakObject * >(this), 0);
1079 }
1080 }
1081 insertRdbFiles(uris, alienContext);
1082 return;
1083 }
1084 css::uno::Reference< css::lang::XServiceInfo > info;
1085 if ((aElement >>= info) && info.is()) {
1086 insertLegacyFactory(info);
1087 return;
1088 }
1089
1090 throw css::lang::IllegalArgumentException(
1091 "Bad insert element", static_cast< cppu::OWeakObject * >(this), 0);
1092}
1093
1094void cppuhelper::ServiceManager::remove(css::uno::Any const & aElement)
1095{
1096 css::uno::Sequence< css::beans::NamedValue > args;
1097 if (aElement >>= args) {
1098 std::vector< OUString > uris;
1099 for (const auto & i : std::as_const(args)) {
1100 if (i.Name != "uri") {
1101 throw css::lang::IllegalArgumentException(
1102 "Bad argument " + i.Name,
1103 static_cast< cppu::OWeakObject * >(this), 0);
1104 }
1105 OUString uri;
1106 if (!(i.Value >>= uri)) {
1107 throw css::lang::IllegalArgumentException(
1108 "Bad uri argument",
1109 static_cast< cppu::OWeakObject * >(this), 0);
1110 }
1111 uris.push_back(uri);
1112 }
1113 removeRdbFiles(uris);
1114 return;
1115 }
1116 css::uno::Reference< css::lang::XServiceInfo > info;
1117 if ((aElement >>= info) && info.is()) {
1118 if (!removeLegacyFactory(info, true)) {
1119 throw css::container::NoSuchElementException(
1120 "Remove non-inserted factory object",
1121 static_cast< cppu::OWeakObject * >(this));
1122 }
1123 return;
1124 }
1125 OUString impl;
1126 if (aElement >>= impl) {
1127 // For live-removal of extensions:
1129 return;
1130 }
1131 throw css::lang::IllegalArgumentException(
1132 "Bad remove element", static_cast< cppu::OWeakObject * >(this), 0);
1133}
1134
1135css::uno::Reference< css::container::XEnumeration >
1137 OUString const & aServiceName)
1138{
1139 std::vector< std::shared_ptr< Data::Implementation > > impls;
1140 {
1141 osl::MutexGuard g(rBHelper.rMutex);
1142 Data::ImplementationMap::const_iterator i(
1143 data_.services.find(aServiceName));
1144 if (i != data_.services.end()) {
1145 impls = i->second;
1146 }
1147 }
1148 std::vector< css::uno::Any > factories;
1149 for (const auto& rxImpl : impls)
1150 {
1151 Data::Implementation * impl = rxImpl.get();
1152 assert(impl != nullptr);
1153 {
1154 osl::MutexGuard g(rBHelper.rMutex);
1155 if (isDisposed()) {
1156 factories.clear();
1157 break;
1158 }
1159 if (impl->status == Data::Implementation::STATUS_NEW) {
1160 // Postpone actual implementation instantiation as long as
1161 // possible (so that e.g. opening LO's "Tools - Macros" menu
1162 // does not try to instantiate a JVM, which can lead to a
1163 // synchronous error dialog when no JVM is specified, and
1164 // showing the dialog while hovering over a menu can cause
1165 // trouble):
1166 impl->factory1 = new ImplementationWrapper(this, rxImpl);
1168 }
1169 if (impl->constructorFn != nullptr && !impl->factory1.is()) {
1170 impl->factory1 = new ImplementationWrapper(this, rxImpl);
1171 }
1172 }
1173 if (impl->factory1.is()) {
1174 factories.push_back(css::uno::Any(impl->factory1));
1175 } else {
1176 assert(impl->factory2.is());
1177 factories.push_back(css::uno::Any(impl->factory2));
1178 }
1179 }
1180 return new ContentEnumeration(std::move(factories));
1181}
1182
1183css::uno::Reference< css::beans::XPropertySetInfo >
1185{
1186 return this;
1187}
1188
1190 OUString const & aPropertyName, css::uno::Any const &)
1191{
1192 if (aPropertyName == "DefaultContext") {
1193 throw css::beans::PropertyVetoException(
1194 aPropertyName, static_cast< cppu::OWeakObject * >(this));
1195 } else {
1196 throw css::beans::UnknownPropertyException(
1197 aPropertyName, static_cast< cppu::OWeakObject * >(this));
1198 }
1199}
1200
1202 OUString const & PropertyName)
1203{
1204 if (PropertyName != "DefaultContext") {
1205 throw css::beans::UnknownPropertyException(
1206 PropertyName, static_cast< cppu::OWeakObject * >(this));
1207 }
1208 assert(context_.is());
1209 return css::uno::Any(context_);
1210}
1211
1213 OUString const & aPropertyName,
1214 css::uno::Reference< css::beans::XPropertyChangeListener > const &
1215 xListener)
1216{
1217 if (!aPropertyName.isEmpty() && aPropertyName != "DefaultContext") {
1218 throw css::beans::UnknownPropertyException(
1219 aPropertyName, static_cast< cppu::OWeakObject * >(this));
1220 }
1221 // DefaultContext does not change, so just treat it as an event listener:
1222 return addEventListener(xListener);
1223}
1224
1226 OUString const & aPropertyName,
1227 css::uno::Reference< css::beans::XPropertyChangeListener > const &
1228 aListener)
1229{
1230 if (!aPropertyName.isEmpty() && aPropertyName != "DefaultContext") {
1231 throw css::beans::UnknownPropertyException(
1232 aPropertyName, static_cast< cppu::OWeakObject * >(this));
1233 }
1234 // DefaultContext does not change, so just treat it as an event listener:
1235 return removeEventListener(aListener);
1236}
1237
1239 OUString const & PropertyName,
1240 css::uno::Reference< css::beans::XVetoableChangeListener > const &
1241 aListener)
1242{
1243 if (!PropertyName.isEmpty() && PropertyName != "DefaultContext") {
1244 throw css::beans::UnknownPropertyException(
1245 PropertyName, static_cast< cppu::OWeakObject * >(this));
1246 }
1247 // DefaultContext does not change, so just treat it as an event listener:
1248 return addEventListener(aListener);
1249}
1250
1252 OUString const & PropertyName,
1253 css::uno::Reference< css::beans::XVetoableChangeListener > const &
1254 aListener)
1255{
1256 if (!PropertyName.isEmpty() && PropertyName != "DefaultContext") {
1257 throw css::beans::UnknownPropertyException(
1258 PropertyName, static_cast< cppu::OWeakObject * >(this));
1259 }
1260 // DefaultContext does not change, so just treat it as an event listener:
1261 return removeEventListener(aListener);
1262}
1263
1264css::uno::Sequence< css::beans::Property >
1266 return { getDefaultContextProperty() };
1267}
1268
1270 OUString const & aName)
1271{
1272 if (aName != "DefaultContext") {
1273 throw css::beans::UnknownPropertyException(
1274 aName, static_cast< cppu::OWeakObject * >(this));
1275 }
1276 return getDefaultContextProperty();
1277}
1278
1280 OUString const & Name)
1281{
1282 return Name == "DefaultContext";
1283}
1284
1286
1288 css::lang::EventObject const & Source)
1289{
1291 css::uno::Reference< css::lang::XServiceInfo >(
1292 Source.Source, css::uno::UNO_QUERY_THROW),
1293 false);
1294}
1295
1297 css::uno::Reference< css::lang::XComponent > const & component)
1298{
1299 assert(component.is());
1300 try {
1301 component->removeEventListener(this);
1302 } catch (css::uno::RuntimeException & e) {
1303 SAL_INFO(
1304 "cppuhelper",
1305 "Ignored removeEventListener RuntimeException " + e.Message);
1306 }
1307}
1308
1309void cppuhelper::ServiceManager::init(std::u16string_view rdbUris) {
1310 for (sal_Int32 i = 0; i != -1;) {
1311 std::u16string_view uri(o3tl::getToken(rdbUris, 0, ' ', i));
1312 if (uri.empty()) {
1313 continue;
1314 }
1315 bool optional;
1316 bool directory;
1317 cppu::decodeRdbUri(&uri, &optional, &directory);
1318 if (directory) {
1319 readRdbDirectory(uri, optional);
1320 } else {
1321 readRdbFile(OUString(uri), optional);
1322 }
1323 }
1324}
1325
1327 std::u16string_view uri, bool optional)
1328{
1329 osl::Directory dir = OUString(uri);
1330 switch (dir.open()) {
1331 case osl::FileBase::E_None:
1332 break;
1333 case osl::FileBase::E_NOENT:
1334 if (optional) {
1335 SAL_INFO("cppuhelper", "Ignored optional " << OUString(uri));
1336 return;
1337 }
1338 [[fallthrough]];
1339 default:
1340 throw css::uno::DeploymentException(
1341 OUString::Concat("Cannot open directory ") + uri,
1342 static_cast< cppu::OWeakObject * >(this));
1343 }
1344 for (;;) {
1345 OUString url;
1346 if (!cppu::nextDirectoryItem(dir, &url)) {
1347 break;
1348 }
1349 readRdbFile(url, false);
1350 }
1351}
1352
1354 OUString const & uri, bool optional)
1355{
1356 try {
1357 Parser(
1358 uri, css::uno::Reference< css::uno::XComponentContext >(), &data_);
1359 } catch (css::container::NoSuchElementException &) {
1360 if (!optional) {
1361 throw css::uno::DeploymentException(
1362 uri + ": no such file",
1363 static_cast< cppu::OWeakObject * >(this));
1364 }
1365 SAL_INFO("cppuhelper", "Ignored optional " << uri);
1366 } catch (css::registry::InvalidRegistryException & e) {
1367 if (!readLegacyRdbFile(uri)) {
1368 throw css::uno::DeploymentException(
1369 "InvalidRegistryException: " + e.Message,
1370 static_cast< cppu::OWeakObject * >(this));
1371 }
1372 } catch (css::uno::RuntimeException &) {
1373 if (!readLegacyRdbFile(uri)) {
1374 throw;
1375 }
1376 }
1377}
1378
1380 Registry reg;
1381 switch (reg.open(uri, RegAccessMode::READONLY)) {
1382 case RegError::NO_ERROR:
1383 break;
1384 case RegError::REGISTRY_NOT_EXISTS:
1385 case RegError::INVALID_REGISTRY:
1386 {
1387 // Ignore empty rdb files (which are at least seen by subordinate
1388 // uno processes during extension registration; Registry::open can
1389 // fail on them if mmap(2) returns EINVAL for a zero length):
1390 osl::DirectoryItem item;
1391 if (osl::DirectoryItem::get(uri, item) == osl::FileBase::E_None) {
1392 osl::FileStatus status(osl_FileStatus_Mask_FileSize);
1393 if (item.getFileStatus(status) == osl::FileBase::E_None
1394 && status.getFileSize() == 0)
1395 {
1396 return true;
1397 }
1398 }
1399 }
1400 [[fallthrough]];
1401 default:
1402 return false;
1403 }
1404 RegistryKey rootKey;
1405 if (reg.openRootKey(rootKey) != RegError::NO_ERROR) {
1406 throw css::uno::DeploymentException(
1407 "Failure reading legacy rdb file " + uri,
1408 static_cast< cppu::OWeakObject * >(this));
1409 }
1410 RegistryKeyArray impls;
1411 switch (rootKey.openSubKeys("IMPLEMENTATIONS", impls)) {
1412 case RegError::NO_ERROR:
1413 break;
1414 case RegError::KEY_NOT_EXISTS:
1415 return true;
1416 default:
1417 throw css::uno::DeploymentException(
1418 "Failure reading legacy rdb file " + uri,
1419 static_cast< cppu::OWeakObject * >(this));
1420 }
1421 for (sal_uInt32 i = 0; i != impls.getLength(); ++i) {
1422 RegistryKey implKey(impls.getElement(i));
1423 assert(implKey.getName().match("/IMPLEMENTATIONS/"));
1424 OUString name(
1425 implKey.getName().copy(RTL_CONSTASCII_LENGTH("/IMPLEMENTATIONS/")));
1426 std::shared_ptr< Data::Implementation > impl =
1427 std::make_shared<Data::Implementation>(
1428 name, readLegacyRdbString(uri, implKey, "UNO/ACTIVATOR"),
1429 readLegacyRdbString(uri, implKey, "UNO/LOCATION"), "", "", "", false,
1430 css::uno::Reference< css::uno::XComponentContext >(), uri);
1431 if (!data_.namedImplementations.emplace(name, impl).second)
1432 {
1433 throw css::registry::InvalidRegistryException(
1434 uri + ": duplicate <implementation name=\"" + name + "\">");
1435 }
1437 uri, implKey, "UNO/SERVICES", &impl->services);
1438 for (const auto& rService : impl->services)
1439 {
1440 data_.services[rService].push_back(impl);
1441 }
1443 uri, implKey, "UNO/SINGLETONS", &impl->singletons);
1444 for (const auto& rSingleton : impl->singletons)
1445 {
1446 data_.singletons[rSingleton].push_back(impl);
1447 }
1448 }
1449 return true;
1450}
1451
1453 std::u16string_view uri, RegistryKey & key, OUString const & path)
1454{
1455 RegistryKey subkey;
1457 sal_uInt32 s(0);
1458 if (key.openKey(path, subkey) != RegError::NO_ERROR
1459 || subkey.getValueInfo(OUString(), &t, &s) != RegError::NO_ERROR
1460 || t != RegValueType::STRING
1461 || s == 0 || s > o3tl::make_unsigned(SAL_MAX_INT32))
1462 {
1463 throw css::uno::DeploymentException(
1464 OUString::Concat("Failure reading legacy rdb file ") + uri,
1465 static_cast< cppu::OWeakObject * >(this));
1466 }
1467 OUString val;
1468 std::vector< char > v(s); // assuming sal_uInt32 fits into vector::size_type
1469 if (subkey.getValue(OUString(), v.data()) != RegError::NO_ERROR
1470 || v.back() != '\0'
1471 || !rtl_convertStringToUString(
1472 &val.pData, v.data(), static_cast< sal_Int32 >(s - 1),
1473 RTL_TEXTENCODING_UTF8,
1474 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
1475 | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
1476 | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
1477 {
1478 throw css::uno::DeploymentException(
1479 OUString::Concat("Failure reading legacy rdb file ") + uri,
1480 static_cast< cppu::OWeakObject * >(this));
1481 }
1482 return val;
1483}
1484
1486 std::u16string_view uri, RegistryKey & key, OUString const & path,
1487 std::vector< OUString > * strings)
1488{
1489 assert(strings != nullptr);
1490 RegistryKey subkey;
1491 switch (key.openKey(path, subkey)) {
1492 case RegError::NO_ERROR:
1493 break;
1494 case RegError::KEY_NOT_EXISTS:
1495 return;
1496 default:
1497 throw css::uno::DeploymentException(
1498 OUString::Concat("Failure reading legacy rdb file ") + uri,
1499 static_cast< cppu::OWeakObject * >(this));
1500 }
1501 OUString prefix(subkey.getName() + "/");
1502 RegistryKeyNames names;
1503 if (subkey.getKeyNames(OUString(), names) != RegError::NO_ERROR) {
1504 throw css::uno::DeploymentException(
1505 OUString::Concat("Failure reading legacy rdb file ") + uri,
1506 static_cast< cppu::OWeakObject * >(this));
1507 }
1508 for (sal_uInt32 i = 0; i != names.getLength(); ++i) {
1509 assert(names.getElement(i).match(prefix));
1510 strings->push_back(names.getElement(i).copy(prefix.getLength()));
1511 }
1512}
1513
1515 std::vector< OUString > const & uris,
1516 css::uno::Reference< css::uno::XComponentContext > const & alienContext)
1517{
1518 Data extra;
1519 for (const auto& rUri : uris)
1520 {
1521 try {
1522 Parser(rUri, alienContext, &extra);
1523 } catch (css::container::NoSuchElementException &) {
1524 throw css::lang::IllegalArgumentException(
1525 rUri + ": no such file", static_cast< cppu::OWeakObject * >(this),
1526 0);
1527 } catch (css::registry::InvalidRegistryException & e) {
1528 throw css::lang::IllegalArgumentException(
1529 "InvalidRegistryException: " + e.Message,
1530 static_cast< cppu::OWeakObject * >(this), 0);
1531 }
1532 }
1533 insertExtraData(extra);
1534}
1535
1537 css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo)
1538{
1539 assert(factoryInfo.is());
1540 OUString name(factoryInfo->getImplementationName());
1541 css::uno::Reference< css::lang::XSingleComponentFactory > f1(
1542 factoryInfo, css::uno::UNO_QUERY);
1543 css::uno::Reference< css::lang::XSingleServiceFactory > f2;
1544 if (!f1.is()) {
1545 f2.set(factoryInfo, css::uno::UNO_QUERY);
1546 if (!f2.is()) {
1547 throw css::lang::IllegalArgumentException(
1548 ("Bad XServiceInfo argument implements neither"
1549 " XSingleComponentFactory nor XSingleServiceFactory"),
1550 static_cast< cppu::OWeakObject * >(this), 0);
1551 }
1552 }
1553 css::uno::Reference< css::lang::XComponent > comp(
1554 factoryInfo, css::uno::UNO_QUERY);
1555 std::shared_ptr< Data::Implementation > impl =
1556 std::make_shared<Data::Implementation>(name, f1, f2, comp);
1557 Data extra;
1558 if (!name.isEmpty()) {
1559 extra.namedImplementations.emplace(name, impl);
1560 }
1561 extra.dynamicImplementations.emplace(factoryInfo, impl);
1562 const css::uno::Sequence< OUString > services(
1563 factoryInfo->getSupportedServiceNames());
1564 for (const auto & i : services) {
1565 impl->services.push_back(i);
1566 extra.services[i].push_back(impl);
1567 }
1568 if (insertExtraData(extra) && comp.is()) {
1569 comp->addEventListener(this);
1570 }
1571}
1572
1574 {
1575 osl::MutexGuard g(rBHelper.rMutex);
1576 if (isDisposed()) {
1577 return false;
1578 }
1579 auto i = std::find_if(extra.namedImplementations.begin(), extra.namedImplementations.end(),
1580 [this](const Data::NamedImplementations::value_type& rEntry) {
1581 return data_.namedImplementations.find(rEntry.first) != data_.namedImplementations.end(); });
1582 if (i != extra.namedImplementations.end())
1583 {
1584 throw css::lang::IllegalArgumentException(
1585 "Insert duplicate implementation name " + i->first,
1586 static_cast< cppu::OWeakObject * >(this), 0);
1587 }
1588 bool bDuplicate = std::any_of(extra.dynamicImplementations.begin(), extra.dynamicImplementations.end(),
1589 [this](const Data::DynamicImplementations::value_type& rEntry) {
1590 return data_.dynamicImplementations.find(rEntry.first) != data_.dynamicImplementations.end(); });
1591 if (bDuplicate)
1592 {
1593 throw css::lang::IllegalArgumentException(
1594 "Insert duplicate factory object",
1595 static_cast< cppu::OWeakObject * >(this), 0);
1596 }
1597 //TODO: The below leaves data_ in an inconsistent state upon exceptions:
1599 extra.namedImplementations.begin(),
1600 extra.namedImplementations.end());
1602 extra.dynamicImplementations.begin(),
1603 extra.dynamicImplementations.end());
1604 insertImplementationMap(&data_.services, extra.services);
1605 insertImplementationMap(&data_.singletons, extra.singletons);
1606 }
1607 //TODO: Updating the component context singleton data should be part of the
1608 // atomic service manager update:
1609 if (extra.singletons.empty())
1610 return true;
1611
1612 assert(context_.is());
1613 css::uno::Reference< css::container::XNameContainer > cont(
1614 context_, css::uno::UNO_QUERY_THROW);
1615 for (const auto& [rName, rImpls] : extra.singletons)
1616 {
1617 OUString name("/singletons/" + rName);
1618 //TODO: Update should be atomic:
1619 try {
1620 cont->removeByName(name + "/arguments");
1621 } catch (const css::container::NoSuchElementException &) {}
1622 assert(!rImpls.empty());
1623 assert(rImpls[0]);
1625 rImpls.size() > 1, "cppuhelper",
1626 "Arbitrarily choosing " << rImpls[0]->name
1627 << " among multiple implementations for singleton "
1628 << rName);
1629 try {
1630 cont->insertByName(
1631 name + "/service", css::uno::Any(rImpls[0]->name));
1632 } catch (css::container::ElementExistException &) {
1633 cont->replaceByName(
1634 name + "/service", css::uno::Any(rImpls[0]->name));
1635 }
1636 try {
1637 cont->insertByName(name, css::uno::Any());
1638 } catch (css::container::ElementExistException &) {
1639 SAL_INFO("cppuhelper", "Overwriting singleton " << rName);
1640 cont->replaceByName(name, css::uno::Any());
1641 }
1642 }
1643 return true;
1644}
1645
1647 std::vector< OUString > const & uris)
1648{
1649 // The underlying data structures make this function somewhat inefficient,
1650 // but the assumption is that it is rarely called (and that if it is called,
1651 // it is called with a uris vector of size one):
1652 std::vector< std::shared_ptr< Data::Implementation > > clear;
1653 {
1654 osl::MutexGuard g(rBHelper.rMutex);
1655 for (const auto& rUri : uris)
1656 {
1657 for (Data::NamedImplementations::iterator j(
1658 data_.namedImplementations.begin());
1659 j != data_.namedImplementations.end();)
1660 {
1661 assert(j->second);
1662 if (j->second->rdbFile == rUri) {
1663 clear.push_back(j->second);
1664 //TODO: The below leaves data_ in an inconsistent state upon
1665 // exceptions:
1666 removeFromImplementationMap(
1667 &data_.services, j->second->services, j->second);
1668 removeFromImplementationMap(
1669 &data_.singletons, j->second->singletons,
1670 j->second);
1671 j = data_.namedImplementations.erase(j);
1672 } else {
1673 ++j;
1674 }
1675 }
1676 }
1677 }
1678 //TODO: Update the component context singleton data
1679}
1680
1682 css::uno::Reference< css::lang::XServiceInfo > const & factoryInfo,
1683 bool removeListener)
1684{
1685 assert(factoryInfo.is());
1686 std::shared_ptr< Data::Implementation > clear;
1687 css::uno::Reference< css::lang::XComponent > comp;
1688 {
1689 osl::MutexGuard g(rBHelper.rMutex);
1690 Data::DynamicImplementations::iterator i(
1691 data_.dynamicImplementations.find(factoryInfo));
1692 if (i == data_.dynamicImplementations.end()) {
1693 return isDisposed();
1694 }
1695 assert(i->second);
1696 clear = i->second;
1697 if (removeListener) {
1698 comp = i->second->component;
1699 }
1700 //TODO: The below leaves data_ in an inconsistent state upon exceptions:
1701 removeFromImplementationMap(
1702 &data_.services, i->second->services, i->second);
1703 removeFromImplementationMap(
1704 &data_.singletons, i->second->singletons, i->second);
1705 if (!i->second->name.isEmpty()) {
1706 data_.namedImplementations.erase(i->second->name);
1707 }
1709 }
1710 if (comp.is()) {
1712 }
1713 return true;
1714}
1715
1717 // The underlying data structures make this function somewhat inefficient,
1718 // but the assumption is that it is rarely called:
1719 std::shared_ptr< Data::Implementation > clear;
1720 {
1721 osl::MutexGuard g(rBHelper.rMutex);
1722 if (isDisposed()) {
1723 return;
1724 }
1725 Data::NamedImplementations::iterator i(
1727 if (i == data_.namedImplementations.end()) {
1728 throw css::container::NoSuchElementException(
1729 "Remove non-inserted implementation " + name,
1730 static_cast< cppu::OWeakObject * >(this));
1731 }
1732 assert(i->second);
1733 clear = i->second;
1734 //TODO: The below leaves data_ in an inconsistent state upon exceptions:
1735 removeFromImplementationMap(
1736 &data_.services, i->second->services, i->second);
1737 removeFromImplementationMap(
1738 &data_.singletons, i->second->singletons, i->second);
1739 auto j = std::find_if(data_.dynamicImplementations.begin(), data_.dynamicImplementations.end(),
1740 [&i](const Data::DynamicImplementations::value_type& rEntry) { return rEntry.second == i->second; });
1741 if (j != data_.dynamicImplementations.end())
1744 }
1745}
1746
1747std::shared_ptr< cppuhelper::ServiceManager::Data::Implementation >
1749 css::uno::Reference< css::uno::XComponentContext > const & context,
1750 OUString const & specifier)
1751{
1752 std::shared_ptr< Data::Implementation > impl;
1753 bool loaded;
1754 {
1755 osl::MutexGuard g(rBHelper.rMutex);
1756 Data::ImplementationMap::const_iterator i(
1757 data_.services.find(specifier));
1758 if (i == data_.services.end()) {
1759 Data::NamedImplementations::const_iterator j(
1760 data_.namedImplementations.find(specifier));
1761 if (j == data_.namedImplementations.end()) {
1762 SAL_INFO("cppuhelper", "No implementation for " << specifier);
1763 return std::shared_ptr< Data::Implementation >();
1764 }
1765 impl = j->second;
1766 } else {
1767 assert(!i->second.empty());
1769 i->second.size() > 1, "cppuhelper",
1770 "Arbitrarily choosing " << i->second[0]->name
1771 << " among multiple implementations for " << i->first);
1772 impl = i->second[0];
1773 }
1774 assert(impl);
1775 loaded = impl->status == Data::Implementation::STATUS_LOADED;
1776 }
1777 if (!loaded) {
1778 loadImplementation(context, impl);
1779 }
1780 return impl;
1781}
1782
1784#ifndef DISABLE_DYNLOADING
1785static OUString simplifyModule(std::u16string_view uri)
1786{
1787 sal_Int32 nIdx;
1788 OUStringBuffer edit(uri);
1789 if ((nIdx = edit.lastIndexOf('/')) > 0)
1790 edit.remove(0,nIdx+1);
1791 if ((nIdx = edit.lastIndexOf(':')) > 0)
1792 edit.remove(0,nIdx+1);
1793 if ((nIdx = edit.lastIndexOf("lo.so")) > 0)
1794 edit.truncate(nIdx);
1795 if ((nIdx = edit.lastIndexOf(".3")) > 0)
1796 edit.truncate(nIdx);
1797 if ((nIdx = edit.lastIndexOf("gcc3.so")) > 0)
1798 edit.truncate(nIdx);
1799 if ((nIdx = edit.lastIndexOf(".so")) > 0)
1800 edit.truncate(nIdx);
1801 if ((nIdx = edit.lastIndexOf("_uno")) > 0)
1802 edit.truncate(nIdx);
1803 if ((nIdx = edit.lastIndexOf(".jar")) > 0)
1804 edit.truncate(nIdx);
1805 if (edit.indexOf("lib") == 0)
1806 edit.remove(0,3);
1807 return edit.makeStringAndClear();
1808}
1809#endif
1810
1813#ifdef DISABLE_DYNLOADING
1814 abort();
1815#else
1816 OUString aUri;
1817 osl::MutexGuard g(rBHelper.rMutex);
1818 css::uno::Environment aSourceEnv(css::uno::Environment::getCurrent());
1819
1820 std::cerr << "preload:";
1821 std::vector<OUString> aReported;
1822 std::vector<OUString> aDisabled;
1823 OUStringBuffer aDisabledMsg;
1824 OUStringBuffer aMissingMsg;
1825
1827 const char *pDisable = getenv("UNODISABLELIBRARY");
1828 if (pDisable)
1829 {
1830 OUString aDisable(pDisable, strlen(pDisable), RTL_TEXTENCODING_UTF8);
1831 for (sal_Int32 i = 0; i >= 0; )
1832 {
1833 OUString tok( aDisable.getToken(0, ' ', i) );
1834 tok = tok.trim();
1835 if (!tok.isEmpty())
1836 aDisabled.push_back(tok);
1837 }
1838 }
1839
1840 // loop all implementations
1841 for (const auto& rEntry : data_.namedImplementations)
1842 {
1843 if (rEntry.second->loader != "com.sun.star.loader.SharedLibrary" ||
1844 rEntry.second->status == Data::Implementation::STATUS_LOADED)
1845 continue;
1846
1847 OUString simplified;
1848 try
1849 {
1850 const OUString &aLibrary = rEntry.second->uri;
1851
1852 if (aLibrary.isEmpty())
1853 continue;
1854
1855 simplified = simplifyModule(aLibrary);
1856
1857 bool bDisabled =
1858 std::find(aDisabled.begin(), aDisabled.end(), simplified) != aDisabled.end();
1859
1860 if (std::find(aReported.begin(), aReported.end(), aLibrary) == aReported.end())
1861 {
1862 if (bDisabled)
1863 {
1864 aDisabledMsg.append(simplified);
1865 aDisabledMsg.append(" ");
1866 }
1867 else
1868 {
1869 std::cerr << " " << simplified;
1870 std::cerr.flush();
1871 }
1872 aReported.push_back(aLibrary);
1873 }
1874
1875 if (bDisabled)
1876 continue;
1877
1878 // expand absolute URI implementation component library
1879 aUri = cppu::bootstrap_expandUri(aLibrary);
1880 }
1881 catch (css::lang::IllegalArgumentException& aError)
1882 {
1883 throw css::uno::DeploymentException(
1884 "Cannot expand URI" + rEntry.second->uri + ": " + aError.Message,
1885 static_cast< cppu::OWeakObject * >(this));
1886 }
1887
1888 // load component library
1889 osl::Module aModule(aUri, SAL_LOADMODULE_NOW | SAL_LOADMODULE_GLOBAL);
1890
1891 if (!aModule.is())
1892 {
1893 aMissingMsg.append(simplified);
1894 aMissingMsg.append(" ");
1895 }
1896
1897 if (aModule.is() &&
1898 !rEntry.second->environment.isEmpty())
1899 {
1900 oslGenericFunction fpFactory;
1901 css::uno::Environment aTargetEnv;
1902 css::uno::Reference<css::uno::XInterface> xFactory;
1903
1904 if(rEntry.second->constructorName.isEmpty())
1905 {
1906 OUString aSymFactory;
1907 // expand full name component factory symbol
1908 if (rEntry.second->prefix == "direct")
1909 aSymFactory = rEntry.second->name.replace('.', '_') + "_" COMPONENT_GETFACTORY;
1910 else if (!rEntry.second->prefix.isEmpty())
1911 aSymFactory = rEntry.second->prefix + "_" COMPONENT_GETFACTORY;
1912 else
1913 aSymFactory = COMPONENT_GETFACTORY;
1914
1915 // get function symbol component factory
1916 fpFactory = aModule.getFunctionSymbol(aSymFactory);
1917 if (fpFactory == nullptr)
1918 {
1919 throw css::loader::CannotActivateFactoryException(
1920 ("no factory symbol \"" + aSymFactory + "\" in component library :" + aUri),
1921 css::uno::Reference<css::uno::XInterface>());
1922 }
1923
1924 aTargetEnv = cppuhelper::detail::getEnvironment(rEntry.second->environment, rEntry.second->name);
1925 component_getFactoryFunc fpComponentFactory = reinterpret_cast<component_getFactoryFunc>(fpFactory);
1926
1927 if (aSourceEnv.get() == aTargetEnv.get())
1928 {
1929 // invoke function component factory
1930 OString aImpl(OUStringToOString(rEntry.second->name, RTL_TEXTENCODING_ASCII_US));
1931 xFactory.set(css::uno::Reference<css::uno::XInterface>(static_cast<css::uno::XInterface *>(
1932 (*fpComponentFactory)(aImpl.getStr(), this, nullptr)), SAL_NO_ACQUIRE));
1933 }
1934 }
1935 else
1936 {
1937 // get function symbol component factory
1938 aTargetEnv = cppuhelper::detail::getEnvironment(rEntry.second->environment, rEntry.second->name);
1939 fpFactory = (aSourceEnv.get() == aTargetEnv.get()) ?
1940 aModule.getFunctionSymbol(rEntry.second->constructorName) : nullptr;
1941 }
1942
1943 css::uno::Reference<css::lang::XSingleComponentFactory> xSCFactory;
1944 css::uno::Reference<css::lang::XSingleServiceFactory> xSSFactory;
1945
1946 // query interface XSingleComponentFactory or XSingleServiceFactory
1947 if (xFactory.is())
1948 {
1949 xSCFactory.set(xFactory, css::uno::UNO_QUERY);
1950 if (!xSCFactory.is())
1951 {
1952 xSSFactory.set(xFactory, css::uno::UNO_QUERY);
1953 if (!xSSFactory.is())
1954 throw css::uno::DeploymentException(
1955 ("Implementation " + rEntry.second->name
1956 + " does not provide a constructor or factory"),
1957 static_cast< cppu::OWeakObject * >(this));
1958 }
1959 }
1960
1961 if (!rEntry.second->constructorName.isEmpty() && fpFactory)
1962 rEntry.second->constructorFn = WrapperConstructorFn(reinterpret_cast<ImplementationConstructorFn *>(fpFactory));
1963
1964 rEntry.second->factory1 = xSCFactory;
1965 rEntry.second->factory2 = xSSFactory;
1966 rEntry.second->status = Data::Implementation::STATUS_LOADED;
1967
1968 }
1969
1970 // Some libraries use other (non-UNO) libraries requiring preinit
1971 oslGenericFunction fpPreload = aModule.getFunctionSymbol( "lok_preload_hook" );
1972 if (fpPreload)
1973 {
1974 static std::vector<oslGenericFunction> aPreloaded;
1975 if (std::find(aPreloaded.begin(), aPreloaded.end(), fpPreload) == aPreloaded.end())
1976 {
1977 aPreloaded.push_back(fpPreload);
1978 fpPreload();
1979 }
1980 }
1981
1982 // leak aModule
1983 aModule.release();
1984 }
1985 std::cerr << std::endl;
1986
1987 if (aMissingMsg.getLength() > 0)
1988 {
1989 OUString aMsg = aMissingMsg.makeStringAndClear();
1990 std::cerr << "Absent (often optional): " << aMsg << "\n";
1991 }
1992 if (aDisabledMsg.getLength() > 0)
1993 {
1994 OUString aMsg = aDisabledMsg.makeStringAndClear();
1995 std::cerr << "Disabled: " << aMsg << "\n";
1996 }
1997 std::cerr.flush();
1998
1999 // Various rather important uno mappings.
2000 static struct {
2001 const char *mpFrom;
2002 const char *mpTo;
2003 const char *mpPurpose;
2004 } const aMappingLoad[] = {
2005 { "gcc3", "uno", "" },
2006 { "uno", "gcc3", "" },
2007 };
2008
2009 static std::vector<css::uno::Mapping> maMaps;
2010 for (auto &it : aMappingLoad)
2011 {
2012 maMaps.push_back(css::uno::Mapping(
2013 OUString::createFromAscii(it.mpFrom),
2014 OUString::createFromAscii(it.mpTo),
2015 OUString::createFromAscii(it.mpPurpose)));
2016 }
2017#endif
2018}
2019
2020/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
sal_uInt32 getLength() const
RegistryKey getElement(sal_uInt32 index)
OUString getElement(sal_uInt32 index)
sal_uInt32 getLength() const
RegError getKeyNames(const OUString &keyName, RegistryKeyNames &rSubKeyNames)
RegError openKey(const OUString &keyName, RegistryKey &rOpenKey)
OUString getName()
RegError getValueInfo(const OUString &keyName, RegValueType *pValueType, sal_uInt32 *pValueSize)
RegError getValue(const OUString &keyName, RegValue pValue)
RegError openSubKeys(const OUString &keyName, RegistryKeyArray &rSubKeys)
RegError openRootKey(RegistryKey &rRootKey)
RegError open(const OUString &registryName, RegAccessMode accessMode)
Base class to implement a UNO object supporting weak references, i.e.
Definition: weak.hxx:48
virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties() override
bool readLegacyRdbFile(OUString const &uri)
virtual css::uno::Sequence< OUString > SAL_CALL getAvailableServiceNames() override
virtual void SAL_CALL removeVetoableChangeListener(OUString const &PropertyName, css::uno::Reference< css::beans::XVetoableChangeListener > const &aListener) override
void loadImplementation(css::uno::Reference< css::uno::XComponentContext > const &context, std::shared_ptr< Data::Implementation > const &implementation)
bool insertExtraData(Data const &extra)
void addSingletonContextEntries(std::vector< cppu::ContextEntry_Init > *entries)
void removeEventListenerFromComponent(css::uno::Reference< css::lang::XComponent > const &component)
virtual void SAL_CALL setPropertyValue(OUString const &aPropertyName, css::uno::Any const &aValue) override
virtual sal_Bool SAL_CALL hasPropertyByName(OUString const &Name) override
virtual void SAL_CALL insert(css::uno::Any const &aElement) override
void insertLegacyFactory(css::uno::Reference< css::lang::XServiceInfo > const &factoryInfo)
virtual sal_Bool SAL_CALL hasElements() override
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual void SAL_CALL removePropertyChangeListener(OUString const &aPropertyName, css::uno::Reference< css::beans::XPropertyChangeListener > const &aListener) override
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
virtual ~ServiceManager() override
virtual void SAL_CALL disposing() override
void readRdbDirectory(std::u16string_view uri, bool optional)
virtual css::beans::Property SAL_CALL getPropertyByName(OUString const &aName) override
virtual void SAL_CALL addVetoableChangeListener(OUString const &PropertyName, css::uno::Reference< css::beans::XVetoableChangeListener > const &aListener) override
void insertRdbFiles(std::vector< OUString > const &uris, css::uno::Reference< css::uno::XComponentContext > const &alientContext)
void readLegacyRdbStrings(std::u16string_view uri, RegistryKey &key, OUString const &path, std::vector< OUString > *strings)
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArgumentsAndContext(OUString const &ServiceSpecifier, css::uno::Sequence< css::uno::Any > const &Arguments, css::uno::Reference< css::uno::XComponentContext > const &Context) override
std::shared_ptr< Data::Implementation > findServiceImplementation(css::uno::Reference< css::uno::XComponentContext > const &context, OUString const &specifier)
void removeImplementation(const OUString &name)
bool removeLegacyFactory(css::uno::Reference< css::lang::XServiceInfo > const &factoryInfo, bool removeListener)
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
virtual sal_Bool SAL_CALL has(css::uno::Any const &aElement) override
virtual void SAL_CALL remove(css::uno::Any const &aElement) override
void removeRdbFiles(std::vector< OUString > const &uris)
virtual css::uno::Any SAL_CALL getPropertyValue(OUString const &PropertyName) override
void preloadImplementations()
Used only by LibreOfficeKit when used by Online to pre-initialize.
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(OUString const &aServiceSpecifier) override
virtual OUString SAL_CALL getImplementationName() override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithContext(OUString const &aServiceSpecifier, css::uno::Reference< css::uno::XComponentContext > const &Context) override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArguments(OUString const &ServiceSpecifier, css::uno::Sequence< css::uno::Any > const &Arguments) override
virtual void SAL_CALL initialize(css::uno::Sequence< css::uno::Any > const &aArguments) override
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createContentEnumeration(OUString const &aServiceName) override
virtual sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
void readRdbFile(OUString const &uri, bool optional)
css::uno::Reference< css::uno::XComponentContext > context_
OUString readLegacyRdbString(std::u16string_view uri, RegistryKey &key, OUString const &path)
virtual css::uno::Type SAL_CALL getElementType() override
virtual void SAL_CALL addPropertyChangeListener(OUString const &aPropertyName, css::uno::Reference< css::beans::XPropertyChangeListener > const &xListener) override
void init(std::u16string_view rdbUris)
rtl::Reference< ParseManager > manager
std::mutex mutex_
float v
Reference< XSingleServiceFactory > xFactory
Definition: factory.cxx:822
#define COMPONENT_GETFACTORY
Definition: factory.hxx:47
void *(SAL_CALL * component_getFactoryFunc)(const char *pImplName, void *pServiceManager, void *pRegistryKey)
Function pointer declaration.
Definition: factory.hxx:120
const char * name
Sequence< PropertyValue > aArguments
OUString aName
rtl::Reference< Manager > manager_
#define SAL_INFO_IF(condition, area, stream)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
const char * attrName
void removeListener(const InterfaceRef &xObject, const css::uno::Reference< css::lang::XEventListener > &xListener)
css::uno::Sequence< typename M::key_type > mapKeysToSequence(M const &map)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
OUString bootstrap_expandUri(OUString const &uri)
Definition: bootstrap.cxx:231
void decodeRdbUri(std::u16string_view *uri, bool *optional, bool *directory)
Definition: paths.cxx:112
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
A helper for implementations of com.sun.star.lang.XServiceInfo.
bool nextDirectoryItem(osl::Directory &directory, OUString *url)
Definition: paths.cxx:81
css::uno::Environment getEnvironment(OUString const &name, std::u16string_view implementation)
Definition: shlib.cxx:49
void loadSharedLibComponentFactory(OUString const &uri, OUString const &environment, OUString const &prefix, OUString const &implementation, OUString const &constructor, css::uno::Reference< css::lang::XMultiServiceFactory > const &serviceManager, WrapperConstructorFn *constructorFunction, css::uno::Reference< css::uno::XInterface > *factory)
Definition: shlib.cxx:240
css::uno::XInterface * ImplementationConstructorFn(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
std::function< css::uno::XInterface *(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)> WrapperConstructorFn
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
enumrange< T >::Iterator begin(enumrange< T >)
args
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
void dispose()
loader
comp
State
enum SAL_DLLPUBLIC_RTTI RegValueType
static OUString simplifyModule(std::u16string_view uri)
Make a simpler unique name for preload / progress reporting.
std::map< OUString, rtl::Reference< Entity > >::const_iterator iterator_
std::map< OUString, rtl::Reference< Entity > > map
Context entries init struct calling createComponentContext().
css::uno::Reference< css::uno::XInterface > createInstanceWithArguments(css::uno::Reference< css::uno::XComponentContext > const &context, bool singletonRequest, css::uno::Sequence< css::uno::Any > const &arguments)
css::uno::Reference< css::uno::XInterface > doCreateInstanceWithArguments(css::uno::Reference< css::uno::XComponentContext > const &context, css::uno::Sequence< css::uno::Any > const &arguments)
css::uno::Reference< css::uno::XInterface > createInstance(css::uno::Reference< css::uno::XComponentContext > const &context, bool singletonRequest)
css::uno::Reference< css::uno::XInterface > doCreateInstance(css::uno::Reference< css::uno::XComponentContext > const &context)
css::uno::Reference< css::uno::XInterface > singleInstance
void updateDisposeInstance(bool singletonRequest, css::uno::Reference< css::uno::XInterface > const &instance)
DynamicImplementations dynamicImplementations
NamedImplementations namedImplementations
std::unordered_map< OUString, std::vector< std::shared_ptr< Implementation > > > ImplementationMap
std::mutex mutex
OUString Name
#define SAL_MAX_INT32
unsigned char sal_Bool