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