Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


On 04/03/2012 02:27 PM, Stephan Bergmann wrote:
I have a vague idea of placing yet another cppuhelper bootstrap
mechanism next to the existing ones, which will internally use
completely different (read: cheap) mechanisms to set up a component
context and associated service manager. That way, I would avoid most of
the hassle of having to whack improvements into a rotten framework.

I'll toy around with that in the next days/weeks. Hang on...

The attached defaultbootstrap.patch is work in progress along that way. It adds a new cppu::defaultBootstrap() to replace cppu::defaultBootstrap_initialComponentContext(), and hooks that up in desktop/source/app/appinit.cxx.

Internally, defaultBootstrap tries to be slim and streamlined and avoid to reach out into the overly generic world of UNO infrastructure services as much as possible. It is still completely unfinished, though:

* It can only read new style, XML service rdbs. This should not be a big problem, as all the service rdbs contained in a LO installation are in that format now, and extensions never bring along their own service rdbs. However, extension management still maintains extensions/*/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/common.rdb files in the old format. So the code that writes those must be converted to use the XML format, and upgrading LO must make sure that the data in existing user installations is converted. For now, I work around that problem by removing all extensions from the LO installation's share/extensions/ and starting with a fresh user installation.

* The ServiceManager implementation shortcuts loading of dynamic libraries, not going via an instance of the com.sun.star.loader.SharedLibrary loader. For one, this matches the spirit of not reaching out into the overly generic UNO infrastructure where possible. For another, this is necessary however to pass the new prefix attribute to the loader, as XImplementationLoader.activate passed that information indirectly via the XRegistryKey parameter -- which becomes an obsolete parameter now that we are no longer registry-based. (This is an example of the tight knitting here that causes so much pain when you want to change something.) Other loaders (for Java, Python, etc. components) are not yet hooked up.

* Much of the ServiceManager's additional UNO interface stuff is not yet implemented. Especially for live deployment of extensions, we'll need support of the XSet interface.

* Type information is still obtained the old way, via those dreaded nested registries.

As for hard performance data, I only tested with a recent master --enable-dbgutil build yet.

$ time .../soffice --terminate_after_init

went from 13.622s to 10.768s for the first (kind of "cold," but far from meaningful, esp. as I ran the old before the new, with no cache-cleaning in between) run, but subsequent runs always stay around 0.85s in both cases (all times wall clock).

$ time .../soffice # hit ^C when start center is up

did not show significant differences (but of course also suffers from the necessary manual activity). Using

diff --git a/sal/rtl/source/strimp.hxx b/sal/rtl/source/strimp.hxx
index 82f7f41..1c1f57a 100644
--- a/sal/rtl/source/strimp.hxx
+++ b/sal/rtl/source/strimp.hxx
@@ -55,7 +55,7 @@ sal_Int16 rtl_ImplGetDigit( sal_Unicode ch, sal_Int16 nRadix );
 sal_Bool rtl_ImplIsWhitespace( sal_Unicode c );

 // string lifetime instrumentation / diagnostics
-#if 0
+#if 1
 #  include <rtl/ustring.hxx>
 #  define RTL_LOG_STRING_NEW(s)                                              \
       do {

to enable Michael's string instantiation counts and then

$ .../soffice 2>&1 | grep '^+' | wc -l # hit ^C when start center is up

shows a decrease from 166452 to 127501, though, so I'm likely not on a completely wrong track.

Happy Easter,
Stephan
diff --git a/cppuhelper/Library_cppuhelper.mk b/cppuhelper/Library_cppuhelper.mk
index 2fa6d1a..342d432 100644
--- a/cppuhelper/Library_cppuhelper.mk
+++ b/cppuhelper/Library_cppuhelper.mk
@@ -45,6 +45,7 @@ $(eval $(call gb_Library_add_linked_libs,cppuhelper,\
        cppu \
        sal \
        salhelper \
+    xmlreader \
        $(gb_STDLIBS) \
 ))
 
diff --git a/cppuhelper/inc/cppuhelper/bootstrap.hxx b/cppuhelper/inc/cppuhelper/bootstrap.hxx
index 319854a..142a0ce 100644
--- a/cppuhelper/inc/cppuhelper/bootstrap.hxx
+++ b/cppuhelper/inc/cppuhelper/bootstrap.hxx
@@ -137,6 +137,11 @@ defaultBootstrap_InitialComponentContext() SAL_THROW( 
(::com::sun::star::uno::Ex
 CPPUHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > 
SAL_CALL
 defaultBootstrap_InitialComponentContext(const ::rtl::OUString & iniFile) SAL_THROW( 
(::com::sun::star::uno::Exception) );
 
+//TODO
+CPPUHELPER_DLLPUBLIC
+com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+defaultBootstrap();
+
 /**
  * An exception indicating a bootstrap error.
  *
diff --git a/cppuhelper/prj/build.lst b/cppuhelper/prj/build.lst
index 6e10408..4b5326d 100644
--- a/cppuhelper/prj/build.lst
+++ b/cppuhelper/prj/build.lst
@@ -1,3 +1,3 @@
-ch     cppuhelper      :       BOOST:boost LIBXSLT:libxslt DESKTOP:codemaker cppu offapi NULL
+ch     cppuhelper      :       BOOST:boost LIBXSLT:libxslt DESKTOP:codemaker cppu offapi salhelper 
xmlreader NULL
 ch     cppuhelper\prj                                                  nmake   -       all     
ch_prj NULL
 ch  cppuhelper\qa\propertysetmixin nmake - all ch_qa_propertysetmixin ch_prj NULL
diff --git a/cppuhelper/source/bootstrap.cxx b/cppuhelper/source/bootstrap.cxx
index 39e44fe..70a9f36 100644
--- a/cppuhelper/source/bootstrap.cxx
+++ b/cppuhelper/source/bootstrap.cxx
@@ -26,11 +26,19 @@
  *
  ************************************************************************/
 
+#include "sal/config.h"
 
+#include <cassert>
+#include <map>
 #include <string.h>
 #include <vector>
 
+#include "boost/noncopyable.hpp"
+#include "xmlreader/span.hxx"
+#include "xmlreader/xmlreader.hxx"
+
 #include "rtl/process.h"
+#include "rtl/ref.hxx"
 #include "rtl/bootstrap.hxx"
 #include "rtl/random.h"
 #include "rtl/string.hxx"
@@ -44,7 +52,9 @@
 
 #include "cppuhelper/shlib.hxx"
 #include "cppuhelper/bootstrap.hxx"
+#include "cppuhelper/compbase6.hxx"
 #include "cppuhelper/component_context.hxx"
+#include "cppuhelper/implbase1.hxx"
 #include "cppuhelper/access_control.hxx"
 #include "cppuhelper/findsofficepath.h"
 
@@ -56,8 +66,11 @@
 #include "com/sun/star/lang/XInitialization.hpp"
 #include "com/sun/star/lang/XServiceInfo.hpp"
 #include "com/sun/star/registry/XSimpleRegistry.hpp"
+#include "com/sun/star/container/XContentEnumerationAccess.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
 #include "com/sun/star/container/XSet.hpp"
 #include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
 #include "com/sun/star/io/IOException.hpp"
 #include "com/sun/star/bridge/UnoUrlResolver.hpp"
 #include "com/sun/star/bridge/XUnoUrlResolver.hpp"
@@ -128,24 +141,24 @@ Bootstrap const & get_unorc() SAL_THROW(())
 }
 
 // private forward decl
-Reference< lang::XMultiComponentFactory > bootstrapInitialSF(
+css::uno::Reference< lang::XMultiComponentFactory > bootstrapInitialSF(
     OUString const & rBootstrapPath )
     SAL_THROW( (Exception) );
 
-Reference< XComponentContext > bootstrapInitialContext(
-    Reference< lang::XMultiComponentFactory > const & xSF,
-    Reference< registry::XSimpleRegistry > const & types_xRegistry,
-    Reference< registry::XSimpleRegistry > const & services_xRegistry,
+css::uno::Reference< XComponentContext > bootstrapInitialContext(
+    css::uno::Reference< lang::XMultiComponentFactory > const & xSF,
+    css::uno::Reference< registry::XSimpleRegistry > const & types_xRegistry,
+    css::uno::Reference< registry::XSimpleRegistry > const & services_xRegistry,
     OUString const & rBootstrapPath, Bootstrap const & bootstrap )
     SAL_THROW( (Exception) );
 
-Reference< XComponentContext > SAL_CALL createInitialCfgComponentContext(
+css::uno::Reference< XComponentContext > SAL_CALL createInitialCfgComponentContext(
     ContextEntry_Init const * pEntries, sal_Int32 nEntries,
-    Reference< XComponentContext > const & xDelegate )
+    css::uno::Reference< XComponentContext > const & xDelegate )
     SAL_THROW(());
 
-Reference< registry::XSimpleRegistry > SAL_CALL createRegistryWrapper(
-    const Reference< XComponentContext >& xContext );
+css::uno::Reference< registry::XSimpleRegistry > SAL_CALL createRegistryWrapper(
+    const css::uno::Reference< XComponentContext >& xContext );
 
 namespace {
 
@@ -249,7 +262,7 @@ css::uno::Reference< css::registry::XSimpleRegistry > readRdbFile(
     }
 }
 
-Reference< registry::XSimpleRegistry > readRdbDirectory(
+css::uno::Reference< registry::XSimpleRegistry > readRdbDirectory(
     rtl::OUString const & url, bool fatalErrors,
     css::uno::Reference< css::registry::XSimpleRegistry > const & lastRegistry,
     css::uno::Reference< css::lang::XSingleServiceFactory > const &
@@ -315,10 +328,10 @@ Reference< registry::XSimpleRegistry > readRdbDirectory(
     }
 }
 
-Reference< registry::XSimpleRegistry > nestRegistries(
+css::uno::Reference< registry::XSimpleRegistry > nestRegistries(
     const OUString &baseDir,
-    const Reference< lang::XSingleServiceFactory > & xSimRegFac,
-    const Reference< lang::XSingleServiceFactory > & xNesRegFac,
+    const css::uno::Reference< lang::XSingleServiceFactory > & xSimRegFac,
+    const css::uno::Reference< lang::XSingleServiceFactory > & xNesRegFac,
     OUString csl_rdbs,
     const OUString & write_rdb,
     sal_Bool forceWrite_rdb,
@@ -326,7 +339,7 @@ Reference< registry::XSimpleRegistry > nestRegistries(
     SAL_THROW((Exception))
 {
     sal_Int32 index;
-    Reference< registry::XSimpleRegistry > lastRegistry;
+    css::uno::Reference< registry::XSimpleRegistry > lastRegistry;
 
     if(!write_rdb.isEmpty()) // is there a write registry given?
     {
@@ -385,7 +398,7 @@ Reference< registry::XSimpleRegistry > nestRegistries(
     return lastRegistry;
 }
 
-Reference< XComponentContext >
+css::uno::Reference< XComponentContext >
 SAL_CALL defaultBootstrap_InitialComponentContext(
     Bootstrap const & bootstrap )
     SAL_THROW( (Exception) )
@@ -401,13 +414,13 @@ SAL_CALL defaultBootstrap_InitialComponentContext(
     OUString iniDir;
     osl_getProcessWorkingDir(&iniDir.pData);
 
-    Reference<lang::XMultiComponentFactory> smgr_XMultiComponentFactory(
+    css::uno::Reference<lang::XMultiComponentFactory> smgr_XMultiComponentFactory(
         bootstrapInitialSF(bootstrapPath) );
-    Reference<lang::XMultiServiceFactory> smgr_XMultiServiceFactory(
+    css::uno::Reference<lang::XMultiServiceFactory> smgr_XMultiServiceFactory(
         smgr_XMultiComponentFactory, UNO_QUERY );
 
-    Reference<registry::XRegistryKey> xEmptyKey;
-    Reference<lang::XSingleServiceFactory> xSimRegFac(
+    css::uno::Reference<registry::XRegistryKey> xEmptyKey;
+    css::uno::Reference<lang::XSingleServiceFactory> xSimRegFac(
         loadSharedLibComponentFactory(
             OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrapPath,
             OUSTR("com.sun.star.comp.stoc.SimpleRegistry"),
@@ -415,7 +428,7 @@ SAL_CALL defaultBootstrap_InitialComponentContext(
             xEmptyKey),
         UNO_QUERY);
 
-    Reference<lang::XSingleServiceFactory> xNesRegFac(
+    css::uno::Reference<lang::XSingleServiceFactory> xNesRegFac(
         loadSharedLibComponentFactory(
             OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrapPath,
             OUSTR("com.sun.star.comp.stoc.NestedRegistry"),
@@ -427,7 +440,7 @@ SAL_CALL defaultBootstrap_InitialComponentContext(
     OUString cls_uno_types =
         findBootstrapArgument( bootstrap, OUSTR("TYPES"), &bFallenback_types );
 
-    Reference<registry::XSimpleRegistry> types_xRegistry =
+    css::uno::Reference<registry::XSimpleRegistry> types_xRegistry =
         nestRegistries(
             iniDir, xSimRegFac, xNesRegFac, cls_uno_types,
             OUString(), sal_False, bFallenback_types );
@@ -447,17 +460,17 @@ SAL_CALL defaultBootstrap_InitialComponentContext(
         write_rdb = OUString();
     }
 
-    Reference<registry::XSimpleRegistry> services_xRegistry = nestRegistries(
+    css::uno::Reference<registry::XSimpleRegistry> services_xRegistry = nestRegistries(
         iniDir, xSimRegFac, xNesRegFac, cls_uno_services, write_rdb,
         !fallenBackWriteRegistry, bFallenback_services );
 
-    Reference< XComponentContext > xContext(
+    css::uno::Reference< XComponentContext > xContext(
         bootstrapInitialContext(
             smgr_XMultiComponentFactory, types_xRegistry, services_xRegistry,
             bootstrapPath, bootstrap ) );
 
     // initialize sf
-    Reference< lang::XInitialization > xInit(
+    css::uno::Reference< lang::XInitialization > xInit(
         smgr_XMultiComponentFactory, UNO_QUERY );
     OSL_ASSERT( xInit.is() );
     Sequence< Any > aSFInit( 1 );
@@ -469,7 +482,7 @@ SAL_CALL defaultBootstrap_InitialComponentContext(
 
 }
 
-Reference< XComponentContext >
+css::uno::Reference< XComponentContext >
 SAL_CALL defaultBootstrap_InitialComponentContext(
     OUString const & iniFile )
     SAL_THROW( (Exception) )
@@ -480,13 +493,1100 @@ SAL_CALL defaultBootstrap_InitialComponentContext(
     return defaultBootstrap_InitialComponentContext( bootstrap );
 }
 
-Reference< XComponentContext >
+css::uno::Reference< XComponentContext >
 SAL_CALL defaultBootstrap_InitialComponentContext()
     SAL_THROW( (Exception) )
 {
     return defaultBootstrap_InitialComponentContext( get_unorc() );
 }
 
+#if 1 // SB
+
+css::uno::Reference< lang::XSingleComponentFactory >
+create_boostrap_macro_expander_factory() SAL_THROW(());
+
+void add_access_control_entries(
+    ::std::vector< ContextEntry_Init > * values,
+    Bootstrap const & bootstrap )
+    SAL_THROW( (Exception) );
+
+namespace {
+
+struct Implementation {
+    Implementation(): loaded(false) {}
+
+    rtl::OUString loader;
+    rtl::OUString uri;
+    rtl::OUString prefix;
+    std::vector< rtl::OUString > services; //TODO
+    std::vector< rtl::OUString > singletons; //TODO
+    bool loaded;
+    css::uno::Reference< css::lang::XSingleComponentFactory > factory1;
+    css::uno::Reference< css::lang::XSingleServiceFactory > factory2;
+};
+
+typedef std::map< rtl::OUString, Implementation > Implementations;
+
+typedef std::map< rtl::OUString, std::vector< rtl::OUString > >
+    ImplementationMap;
+
+struct Data: private boost::noncopyable {
+    Implementations implementations;
+    ImplementationMap services;
+    ImplementationMap singletons;
+};
+
+class Parser: private boost::noncopyable {
+public:
+    Parser(rtl::OUString const & uri, Data * data);
+
+private:
+    void handleComponent();
+
+    void handleImplementation();
+
+    void handleService();
+
+    void handleSingleton();
+
+    rtl::OUString getNameAttribute();
+
+    xmlreader::XmlReader reader_;
+    Data * data_;
+    rtl::OUString attrLoader_;
+    rtl::OUString attrUri_;
+    rtl::OUString attrPrefix_;
+    rtl::OUString attrImplementation_;
+};
+
+Parser::Parser(rtl::OUString const & uri, Data * data):
+    reader_(uri), data_(data)
+{
+    assert(data != 0);
+    int ucNsId = reader_.registerNamespaceIri(
+        xmlreader::Span(
+            RTL_CONSTASCII_STRINGPARAM(
+                "http://openoffice.org/2010/uno-components";)));
+    enum State {
+        STATE_BEGIN, STATE_END, STATE_COMPONENTS, STATE_COMPONENT_INITIAL,
+        STATE_COMPONENT, STATE_IMPLEMENTATION, STATE_SERVICE, STATE_SINGLETON };
+    for (State state = STATE_BEGIN;;) {
+        xmlreader::Span name;
+        int nsId;
+        xmlreader::XmlReader::Result res = reader_.nextItem(
+            xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
+        switch (state) {
+        case STATE_BEGIN:
+            if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
+                && name.equals(RTL_CONSTASCII_STRINGPARAM("components")))
+            {
+                state = STATE_COMPONENTS;
+                break;
+            }
+            throw css::uno::DeploymentException(
+                (reader_.getUrl()
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM(
+                         ": unexpected item in outer level"))),
+                css::uno::Reference< css::uno::XInterface >());
+        case STATE_END:
+            if (res == xmlreader::XmlReader::RESULT_DONE) {
+                return;
+            }
+            throw css::uno::DeploymentException(
+                (reader_.getUrl()
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM(
+                         ": unexpected item in outer level"))),
+                css::uno::Reference< css::uno::XInterface >());
+        case STATE_COMPONENTS:
+            if (res == xmlreader::XmlReader::RESULT_END) {
+                state = STATE_END;
+                break;
+            }
+            if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
+                && name.equals(RTL_CONSTASCII_STRINGPARAM("component")))
+            {
+                handleComponent();
+                state = STATE_COMPONENT_INITIAL;
+                break;
+            }
+            throw css::uno::DeploymentException(
+                (reader_.getUrl()
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM(
+                         ": unexpected item in <components>"))),
+                css::uno::Reference< css::uno::XInterface >());
+        case STATE_COMPONENT:
+            if (res == xmlreader::XmlReader::RESULT_END) {
+                state = STATE_COMPONENTS;
+                break;
+            }
+            // fall through
+        case STATE_COMPONENT_INITIAL:
+            if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
+                && name.equals(RTL_CONSTASCII_STRINGPARAM("implementation")))
+            {
+                handleImplementation();
+                state = STATE_IMPLEMENTATION;
+                break;
+            }
+            throw css::uno::DeploymentException(
+                (reader_.getUrl()
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM(
+                         ": unexpected item in <component>"))),
+                css::uno::Reference< css::uno::XInterface >());
+        case STATE_IMPLEMENTATION:
+            if (res == xmlreader::XmlReader::RESULT_END) {
+                state = STATE_COMPONENT;
+                break;
+            }
+            if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
+                && name.equals(RTL_CONSTASCII_STRINGPARAM("service")))
+            {
+                handleService();
+                state = STATE_SERVICE;
+                break;
+            }
+            if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId
+                && name.equals(RTL_CONSTASCII_STRINGPARAM("singleton")))
+            {
+                handleSingleton();
+                state = STATE_SINGLETON;
+                break;
+            }
+            throw css::uno::DeploymentException(
+                (reader_.getUrl()
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM(
+                         ": unexpected item in <implementation>"))),
+                css::uno::Reference< css::uno::XInterface >());
+        case STATE_SERVICE:
+            if (res == xmlreader::XmlReader::RESULT_END) {
+                state = STATE_IMPLEMENTATION;
+                break;
+            }
+            throw css::uno::DeploymentException(
+                (reader_.getUrl()
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM(
+                         ": unexpected item in <service>"))),
+                css::uno::Reference< css::uno::XInterface >());
+        case STATE_SINGLETON:
+            if (res == xmlreader::XmlReader::RESULT_END) {
+                state = STATE_IMPLEMENTATION;
+                break;
+            }
+            throw css::uno::DeploymentException(
+                (reader_.getUrl()
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM(
+                         ": unexpected item in <service>"))),
+                css::uno::Reference< css::uno::XInterface >());
+        }
+    }
+}
+
+void Parser::handleComponent() {
+    attrLoader_ = rtl::OUString();
+    attrUri_ = rtl::OUString();
+    attrPrefix_ = rtl::OUString();
+    xmlreader::Span name;
+    int nsId;
+    while (reader_.nextAttribute(&nsId, &name)) {
+        if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
+            && name.equals(RTL_CONSTASCII_STRINGPARAM("loader")))
+        {
+            if (!attrLoader_.isEmpty()) {
+                throw css::uno::DeploymentException(
+                    (reader_.getUrl()
+                     + rtl::OUString(
+                         RTL_CONSTASCII_USTRINGPARAM(
+                             ": <component> has multiple \"loader\""
+                             " attributes"))),
+                    css::uno::Reference< css::uno::XInterface >());
+            }
+            attrLoader_ = reader_.getAttributeValue(false).convertFromUtf8();
+            if (attrLoader_.isEmpty()) {
+                throw css::uno::DeploymentException(
+                    (reader_.getUrl()
+                     + rtl::OUString(
+                         RTL_CONSTASCII_USTRINGPARAM(
+                             ": <component> has empty \"loader\" attribute"))),
+                    css::uno::Reference< css::uno::XInterface >());
+            }
+        } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
+                   && name.equals(RTL_CONSTASCII_STRINGPARAM("uri")))
+        {
+            if (!attrUri_.isEmpty()) {
+                throw css::uno::DeploymentException(
+                    (reader_.getUrl()
+                     + rtl::OUString(
+                         RTL_CONSTASCII_USTRINGPARAM(
+                             ": <component> has multiple \"uri\" attributes"))),
+                    css::uno::Reference< css::uno::XInterface >());
+            }
+            attrUri_ = reader_.getAttributeValue(false).convertFromUtf8();
+            if (attrUri_.isEmpty()) {
+                throw css::uno::DeploymentException(
+                    (reader_.getUrl()
+                     + rtl::OUString(
+                         RTL_CONSTASCII_USTRINGPARAM(
+                             ": <component> has empty \"uri\" attribute"))),
+                    css::uno::Reference< css::uno::XInterface >());
+            }
+        } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
+                   && name.equals(RTL_CONSTASCII_STRINGPARAM("prefix")))
+        {
+            if (!attrPrefix_.isEmpty()) {
+                throw css::uno::DeploymentException(
+                    (reader_.getUrl() +
+                     rtl::OUString(
+                         RTL_CONSTASCII_USTRINGPARAM(
+                             ": <component> has multiple \"prefix\""
+                             " attributes"))),
+                    css::uno::Reference< css::uno::XInterface >());
+            }
+            attrPrefix_ = reader_.getAttributeValue(false).convertFromUtf8();
+            if (attrPrefix_.isEmpty()) {
+                throw css::uno::DeploymentException(
+                    (reader_.getUrl() +
+                     rtl::OUString(
+                         RTL_CONSTASCII_USTRINGPARAM(
+                             ": <component> has empty \"prefix\" attribute"))),
+                    css::uno::Reference< css::uno::XInterface >());
+            }
+        } else {
+            throw css::uno::DeploymentException(
+                (reader_.getUrl()
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM(": unexpected attribute \""))
+                 + name.convertFromUtf8()
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM("\" in <component>"))),
+                css::uno::Reference< css::uno::XInterface >());
+        }
+    }
+    if (attrLoader_.isEmpty()) {
+        throw css::uno::DeploymentException(
+            (reader_.getUrl() +
+             rtl::OUString(
+                 RTL_CONSTASCII_USTRINGPARAM(
+                     ": <component> is missing \"loader\" attribute"))),
+            css::uno::Reference< css::uno::XInterface >());
+    }
+    if (attrUri_.isEmpty()) {
+        throw css::uno::DeploymentException(
+            (reader_.getUrl() +
+             rtl::OUString(
+                 RTL_CONSTASCII_USTRINGPARAM(
+                     ": <component> is missing \"uri\" attribute"))),
+            css::uno::Reference< css::uno::XInterface >());
+    }
+#ifndef DISABLE_DYNLOADING
+    try {
+        attrUri_ = rtl::Uri::convertRelToAbs(reader_.getUrl(), attrUri_);
+    } catch (const rtl::MalformedUriException & e) {
+        throw css::uno::DeploymentException(
+            (reader_.getUrl() +
+             rtl::OUString(
+                 RTL_CONSTASCII_USTRINGPARAM(": bad \"uri\" attribute: ")) +
+             e.getMessage()),
+            css::uno::Reference< css::uno::XInterface >());
+    }
+#endif
+}
+
+void Parser::handleImplementation() {
+    attrImplementation_ = getNameAttribute();
+    if (data_->implementations.find(attrImplementation_)
+        != data_->implementations.end())
+    {
+        throw css::uno::DeploymentException(
+            (reader_.getUrl()
+             + rtl::OUString(
+                 RTL_CONSTASCII_USTRINGPARAM(
+                     ": duplicate <implementation name=\""))
+             + attrImplementation_
+             + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\">"))),
+            css::uno::Reference< css::uno::XInterface >());
+    }
+    data_->implementations[attrImplementation_].loader = attrLoader_;
+    data_->implementations[attrImplementation_].uri = attrUri_;
+    data_->implementations[attrImplementation_].prefix = attrPrefix_;
+}
+
+void Parser::handleService() {
+    rtl::OUString name = getNameAttribute();
+    data_->implementations[attrImplementation_].services.push_back(name);
+    data_->services[name].push_back(attrImplementation_);
+}
+
+void Parser::handleSingleton() {
+    rtl::OUString name = getNameAttribute();
+    data_->implementations[attrImplementation_].singletons.push_back(name);
+    data_->singletons[name].push_back(attrImplementation_);
+}
+
+rtl::OUString Parser::getNameAttribute() {
+    rtl::OUString attrName;
+    xmlreader::Span name;
+    int nsId;
+    while (reader_.nextAttribute(&nsId, &name)) {
+        if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
+            && name.equals(RTL_CONSTASCII_STRINGPARAM("name")))
+        {
+            if (!attrName.isEmpty()) {
+                throw css::uno::DeploymentException(
+                    (reader_.getUrl()
+                     + rtl::OUString(
+                         RTL_CONSTASCII_USTRINGPARAM(
+                             ": element has multiple \"name\" attributes"))),
+                    css::uno::Reference< css::uno::XInterface >());
+            }
+            attrName = reader_.getAttributeValue(false).convertFromUtf8();
+            if (attrName.isEmpty()) {
+                throw css::uno::DeploymentException(
+                    (reader_.getUrl()
+                     + rtl::OUString(
+                         RTL_CONSTASCII_USTRINGPARAM(
+                             ": element has empty \"name\" attribute"))),
+                    css::uno::Reference< css::uno::XInterface >());
+            }
+        } else {
+            throw css::uno::DeploymentException(
+                (reader_.getUrl()
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM(
+                         ": expected element attribute \"name\""))),
+                css::uno::Reference< css::uno::XInterface >());
+        }
+    }
+    if (attrName.isEmpty()) {
+        throw css::uno::DeploymentException(
+            (reader_.getUrl()
+             + rtl::OUString(
+                 RTL_CONSTASCII_USTRINGPARAM(
+                     ": element is missing \"name\" attribute"))),
+            css::uno::Reference< css::uno::XInterface >());
+    }
+    return attrName;
+}
+
+class ContentEnumeration:
+    public cppu::WeakImplHelper1< css::container::XEnumeration >,
+    private boost::noncopyable
+{
+public:
+    explicit ContentEnumeration(std::vector< css::uno::Any > const & factories):
+        factories_(factories), iterator_(factories_.begin()) {}
+
+private:
+    virtual ~ContentEnumeration() {}
+
+    virtual sal_Bool SAL_CALL hasMoreElements()
+        throw (css::uno::RuntimeException)
+    {
+        osl::MutexGuard g(mutex_);
+        return iterator_ != factories_.end();
+    }
+
+    virtual css::uno::Any SAL_CALL nextElement()
+        throw (
+            css::container::NoSuchElementException,
+            css::lang::WrappedTargetException, css::uno::RuntimeException)
+    {
+        osl::MutexGuard g(mutex_);
+        if (iterator_ == factories_.end()) {
+            throw css::container::NoSuchElementException(
+                rtl::OUString(
+                    RTL_CONSTASCII_USTRINGPARAM(
+                        "Bootstrap service manager service enumerator has no"
+                        " more elements")),
+                static_cast< cppu::OWeakObject * >(this));
+        }
+        return *iterator_++;
+    }
+
+    osl::Mutex mutex_;
+    std::vector< css::uno::Any > factories_;
+    std::vector< css::uno::Any >::const_iterator iterator_;
+};
+
+typedef cppu::WeakComponentImplHelper6<
+    css::lang::XServiceInfo, css::lang::XMultiServiceFactory,
+    css::lang::XMultiComponentFactory, css::container::XSet,
+    css::container::XContentEnumerationAccess, css::beans::XPropertySet >
+ServiceManagerBase;
+
+class ServiceManager:
+    private osl::Mutex, public ServiceManagerBase, private boost::noncopyable
+{
+public:
+    explicit ServiceManager(rtl::OUString const & uris):
+        ServiceManagerBase(*static_cast< osl::Mutex * >(this))
+    { readUris(uris); }
+
+    using ServiceManagerBase::acquire;
+    using ServiceManagerBase::release;
+
+    virtual void SAL_CALL disposing() { /*TODO*/ };
+
+    virtual rtl::OUString SAL_CALL getImplementationName()
+        throw (css::uno::RuntimeException)
+    {
+        return rtl::OUString(
+            RTL_CONSTASCII_USTRINGPARAM(
+                "com.sun.star.comp.cppuhelper.bootstrap.ServiceManager"));
+    }
+
+    virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
+        throw (css::uno::RuntimeException)
+    { return ServiceName == getSupportedServiceNames()[0]; } //TODO
+
+    virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+    getSupportedServiceNames() throw (css::uno::RuntimeException)
+    {
+        //TODO: css.lang.MultiServiceFactory?
+        rtl::OUString name(
+            RTL_CONSTASCII_USTRINGPARAM(
+                "com.sun.star.lang.ServiceManager"));
+        return css::uno::Sequence< rtl::OUString >(&name, 1);
+    }
+
+    virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
+        rtl::OUString const & aServiceSpecifier)
+        throw (css::uno::Exception, css::uno::RuntimeException)
+    {
+        //SAL_DEBUG("ServiceManager::createInstance("<<aServiceSpecifier<<")");
+        assert(context_.is());
+        return createInstanceWithContext(aServiceSpecifier, context_);
+    }
+
+    virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
+    createInstanceWithArguments(
+        rtl::OUString const & ServiceSpecifier,
+        css::uno::Sequence< css::uno::Any > const & Arguments)
+        throw (css::uno::Exception, css::uno::RuntimeException)
+    {
+        //SAL_DEBUG("ServiceManager::createInstanceWithArguments("<<ServiceSpecifier<<")");
+        assert(context_.is());
+        return createInstanceWithArgumentsAndContext(
+            ServiceSpecifier, Arguments, context_);
+    }
+
+    virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+    getAvailableServiceNames() throw (css::uno::RuntimeException)
+    {
+        //SAL_DEBUG("ServiceManager::getAvailableServiceNames");
+        return css::uno::Sequence< rtl::OUString >(); //TODO
+    }
+
+    virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
+    createInstanceWithContext(
+        rtl::OUString const & aServiceSpecifier,
+        css::uno::Reference< css::uno::XComponentContext > const & Context)
+        throw (css::uno::Exception, css::uno::RuntimeException)
+    {
+        //SAL_DEBUG("ServiceManager::createInstanceWithContext("<<aServiceSpecifier<<")");
+        Implementation const * impl = findServiceImplementation(
+            aServiceSpecifier);
+        if (impl == 0) {
+            return css::uno::Reference< css::uno::XInterface >();
+        }
+        if (impl->factory1.is()) {
+            return impl->factory1->createInstanceWithContext(Context);
+        }
+        if (impl->factory2.is()) {
+            return impl->factory2->createInstance();
+        }
+        SAL_DEBUG("throw6");
+        throw css::uno::DeploymentException(
+            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TODO")),
+            static_cast< cppu::OWeakObject * >(this));
+    }
+
+    virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
+    createInstanceWithArgumentsAndContext(
+        rtl::OUString const & ServiceSpecifier,
+        css::uno::Sequence< css::uno::Any > const & Arguments,
+        css::uno::Reference< css::uno::XComponentContext > const & Context)
+        throw (css::uno::Exception, css::uno::RuntimeException)
+    {
+        
//SAL_DEBUG("ServiceManager::createInstanceWithArgumentsAndContext("<<ServiceSpecifier<<")");
+        Implementation const * impl = findServiceImplementation(
+            ServiceSpecifier);
+        if (impl == 0) {
+            return css::uno::Reference< css::uno::XInterface >();
+        }
+        if (impl->factory1.is()) {
+            return impl->factory1->createInstanceWithArgumentsAndContext(
+                Arguments, Context);
+        }
+        if (impl->factory2.is()) {
+            return impl->factory2->createInstanceWithArguments(Arguments);
+        }
+        SAL_DEBUG("throw7");
+        throw css::uno::DeploymentException(
+            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TODO")),
+            static_cast< cppu::OWeakObject * >(this));
+    }
+
+    css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException)
+    { return css::uno::Type(); }
+
+    sal_Bool SAL_CALL hasElements() throw (css::uno::RuntimeException)
+    {
+        //SAL_DEBUG("ServiceManager::hasElements");
+        return false; //TODO
+    }
+
+    css::uno::Reference< css::container::XEnumeration > SAL_CALL
+    createEnumeration() throw (css::uno::RuntimeException)
+    {
+        SAL_DEBUG("ServiceManager::createEnumeration");
+        return 0; //TODO
+    }
+
+    sal_Bool SAL_CALL has(css::uno::Any const & /*aElement*/)
+        throw (css::uno::RuntimeException)
+    {
+        //SAL_DEBUG("ServiceManager::has");
+        return false; //TODO
+    }
+
+    void SAL_CALL insert(css::uno::Any const & /*aElement*/)
+        throw (
+            css::lang::IllegalArgumentException,
+            css::container::ElementExistException, css::uno::RuntimeException)
+    {
+        SAL_DEBUG("ServiceManager::insert");
+        //TODO
+    }
+
+    void SAL_CALL remove(css::uno::Any const & /*aElement*/)
+        throw (
+            css::lang::IllegalArgumentException,
+            css::container::NoSuchElementException, css::uno::RuntimeException)
+    {
+        //SAL_DEBUG("ServiceManager::remove");
+        //TODO
+    }
+
+    css::uno::Reference< css::container::XEnumeration > SAL_CALL
+    createContentEnumeration(rtl::OUString const & aServiceName)
+        throw (css::uno::RuntimeException)
+    {
+        SAL_DEBUG("ServiceManager::createContentEnumeration("<<aServiceName<<")");
+        std::vector< rtl::OUString > implNames;
+        {
+            osl::MutexGuard g(*this);
+            ImplementationMap::const_iterator i(
+                data_.services.find(aServiceName));
+            if (i != data_.services.end()) {
+                implNames = i->second;
+            }
+        }
+        //TODO: There is a race here, as implemenation names for the given
+        // service can disappear while the mutex is unlocked (which the below
+        // continue silently takes care of), but can also reappear referencing
+        // implementations that do not implement the given service.
+        std::vector< css::uno::Any > factories;
+        for (std::vector< rtl::OUString >::const_iterator i(implNames.begin());
+             i != implNames.end(); ++i)
+        {
+            Implementations::iterator impl;
+            bool loaded;
+            {
+                osl::MutexGuard g(*this);
+                impl = data_.implementations.find(*i);
+                if (impl == data_.implementations.end()) {
+                    SAL_INFO(
+                        "cppuhelper",
+                        "implementation " << *i << " lost in race");
+                    continue;
+                }
+                loaded = impl->second.loaded;
+            }
+            //TODO: There is a race here, as the relevant service factory can be
+            // removed while the mutex is unlocked and loading can thus fail, as
+            // the entity from which to load can disappear once the service
+            // factory is removed.
+            if (!loaded) {
+                loadImplementation(impl);
+            }
+            if (impl->second.factory1.is()) {
+                factories.push_back(css::uno::makeAny(impl->second.factory1));
+            } else if (impl->second.factory2.is()) {
+                factories.push_back(css::uno::makeAny(impl->second.factory2));
+            } else {
+                SAL_DEBUG("throw8");
+                throw css::uno::DeploymentException(
+                    rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TODO")),
+                    static_cast< cppu::OWeakObject * >(this));
+            }
+        }
+        return new ContentEnumeration(factories);
+    }
+
+    virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
+    getPropertySetInfo() throw (css::uno::RuntimeException)
+    {
+        //SAL_DEBUG("ServiceManager::getPropertySetInfo");
+        return 0;//TODO
+    }
+
+    virtual void SAL_CALL setPropertyValue(
+        rtl::OUString const & aPropertyName, css::uno::Any const &)
+        throw (
+            css::beans::UnknownPropertyException,
+            css::beans::PropertyVetoException,
+            css::lang::IllegalArgumentException,
+            css::lang::WrappedTargetException)
+    {
+        //SAL_DEBUG("ServiceManager::setPropertyValue("<<aPropertyName<<")");
+        throw css::beans::UnknownPropertyException(
+            aPropertyName, static_cast< cppu::OWeakObject * >(this));
+    }
+
+    virtual css::uno::Any SAL_CALL getPropertyValue(
+        rtl::OUString const & PropertyName)
+        throw (
+            css::beans::UnknownPropertyException,
+            css::lang::WrappedTargetException)
+    {
+        //SAL_DEBUG("ServiceManager::getPropertyValue("<<PropertyName<<")");
+        if (!PropertyName.equalsAsciiL(
+                RTL_CONSTASCII_STRINGPARAM("DefaultContext")))
+        {
+            throw css::beans::UnknownPropertyException(
+                PropertyName, static_cast< cppu::OWeakObject * >(this));
+        }
+        assert(context_.is());
+        return css::uno::makeAny(context_);
+    }
+
+    virtual void SAL_CALL addPropertyChangeListener(
+        rtl::OUString const & /*aPropertyName*/,
+        css::uno::Reference< css::beans::XPropertyChangeListener > const &
+            /*xListener*/)
+        throw (
+            css::beans::UnknownPropertyException,
+            css::lang::WrappedTargetException)
+    {
+        //SAL_DEBUG("ServiceManager::addPropertyChangeListener");
+        //TODO
+    }
+
+    virtual void SAL_CALL removePropertyChangeListener(
+        rtl::OUString const & /*aPropertyName*/,
+        css::uno::Reference< css::beans::XPropertyChangeListener > const &
+            /*aListener*/)
+        throw (
+            css::beans::UnknownPropertyException,
+            css::lang::WrappedTargetException)
+    {
+        //SAL_DEBUG("ServiceManager::removePropertyChangeListener");
+        //TODO
+    }
+
+    virtual void SAL_CALL addVetoableChangeListener(
+        rtl::OUString const & /*PropertyName*/,
+        css::uno::Reference< css::beans::XVetoableChangeListener > const &
+            /*aListener*/)
+        throw (
+            css::beans::UnknownPropertyException,
+            css::lang::WrappedTargetException)
+    {
+        //SAL_DEBUG("ServiceManager::addVetoableChangeListener");
+        //TODO
+    }
+
+    virtual void SAL_CALL removeVetoableChangeListener(
+        rtl::OUString const & /*PropertyName*/,
+        css::uno::Reference< css::beans::XVetoableChangeListener > const &
+            /*aListener*/)
+        throw (
+            css::beans::UnknownPropertyException,
+            css::lang::WrappedTargetException)
+    {
+        //SAL_DEBUG("ServiceManager::removeVetoableChangeListener");
+        //TODO
+    }
+
+    void setContext(
+        css::uno::Reference< css::uno::XComponentContext > const & context)
+    {
+        assert(context.is());
+        assert(!context_.is());
+        context_ = context;
+    }
+
+    Data const & getData() const { return data_; }
+
+private:
+    virtual ~ServiceManager() {}
+
+    void readUris(rtl::OUString const & uris);
+
+    void readDirectory(rtl::OUString const & uri, bool optional);
+
+    void readFile(rtl::OUString const & uri, bool optional);
+
+    Implementation const * findServiceImplementation(
+        rtl::OUString const & specifier);
+
+    void loadImplementation(Implementations::iterator const & implementation);
+
+    css::uno::Reference< css::uno::XComponentContext > context_;
+    Data data_;
+};
+
+void ServiceManager::readUris(rtl::OUString const & uris) {
+    for (sal_Int32 i = 0; i != -1;) {
+        rtl::OUString uri(uris.getToken(0, ' ', i));
+        if (uri.isEmpty()) {
+            continue;
+        }
+        bool optional = uri[0] == '?';
+        if (optional) {
+            uri = uri.copy(1);
+            optional = true;
+        }
+        if (uri.getLength() >= 3 && uri[0] == '<'
+            && uri[uri.getLength() - 2] == '>'
+            && uri[uri.getLength() - 1] == '*')
+        {
+            readDirectory(uri.copy(1, uri.getLength() - 3), optional);
+        } else {
+            readFile(uri, optional);
+        }
+    }
+}
+
+void ServiceManager::readDirectory(rtl::OUString const & uri, bool optional) {
+    osl::Directory dir(uri);
+    switch (dir.open()) {
+    case osl::FileBase::E_None:
+        break;
+    case osl::FileBase::E_NOENT:
+        if (optional) {
+            SAL_INFO("cppu", "ignored optional " << uri);
+            return;
+        }
+        // fall through
+    default:
+        throw css::uno::DeploymentException(
+            (rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM("Cannot open directory ")) +
+             uri),
+            css::uno::Reference< css::uno::XInterface >());
+    }
+    for (;;) {
+        osl::DirectoryItem i;
+        switch (dir.getNextItem(i, SAL_MAX_UINT32)) {
+        case osl::FileBase::E_None:
+            break;
+        case osl::FileBase::E_NOENT:
+            return;
+        default:
+            throw css::uno::DeploymentException(
+                (rtl::OUString(
+                    RTL_CONSTASCII_USTRINGPARAM("Cannot iterate directory ")) +
+                 uri),
+                css::uno::Reference< css::uno::XInterface >());
+        }
+        osl::FileStatus stat(
+            osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileName |
+            osl_FileStatus_Mask_FileURL);
+        if (i.getFileStatus(stat) != osl::FileBase::E_None) {
+            throw css::uno::DeploymentException(
+                (rtl::OUString(
+                    RTL_CONSTASCII_USTRINGPARAM("Cannot stat in directory ")) +
+                 uri),
+                css::uno::Reference< css::uno::XInterface >());
+        }
+        if (stat.getFileType() != osl::FileStatus::Directory) { //TODO: symlinks
+            // Ignore backup files:
+            rtl::OUString name(stat.getFileName());
+            if (!name.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("."))
+                && !name.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM("~")))
+            {
+                readFile(stat.getFileURL(), false);
+            }
+        }
+    }
+}
+
+void ServiceManager::readFile(rtl::OUString const & uri, bool optional) {
+    try {
+        Parser(uri, &data_);
+    } catch (css::container::NoSuchElementException &) {
+        if (!optional) {
+            throw css::uno::DeploymentException(
+                (uri
+                 + rtl::OUString(
+                     RTL_CONSTASCII_USTRINGPARAM(": no such file"))),
+                css::uno::Reference< css::uno::XInterface >());
+        }
+        SAL_INFO("cppu", "ignored optional " << uri);
+    }
+}
+
+Implementation const * ServiceManager::findServiceImplementation(
+    rtl::OUString const & specifier)
+{
+    Implementations::iterator impl;
+    bool loaded;
+    {
+        osl::MutexGuard g(*this);
+        ImplementationMap::const_iterator i(data_.services.find(specifier));
+        if (i == data_.services.end()) {
+            impl = data_.implementations.find(specifier);
+            if (impl == data_.implementations.end()) {
+                SAL_INFO("cppuhelper", "no implementation for " << specifier);
+                return 0;
+            }
+        } else {
+            assert(!i->second.empty());
+            SAL_INFO_IF(
+                i->second.size() > 1, "cppuhelper",
+                "arbitrarily chosing \"" << i->second[0]
+                    << "\" among multiple implementations for \"" << i->first
+                    << "\"");
+            impl = data_.implementations.find(i->second[0]);
+        }
+        assert(impl != data_.implementations.end());
+        loaded = impl->second.loaded;
+    }
+    //TODO: There is a race here, as the relevant service factory can be removed
+    // while the mutex is unlocked and loading can thus fail, as the entity from
+    // which to load can disappear once the service factory is removed.
+    if (!loaded) {
+        loadImplementation(impl);
+    }
+    return &impl->second;
+}
+
+void ServiceManager::loadImplementation(
+    Implementations::iterator const & implementation)
+{
+    rtl::OUString uri;
+    try {
+        uri = cppu::bootstrap_expandUri(implementation->second.uri);
+    } catch (css::lang::IllegalArgumentException & e) {
+        SAL_DEBUG("throw3");
+        throw css::uno::DeploymentException(
+            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TODO")) + e.Message,
+            static_cast< cppu::OWeakObject * >(this));
+    }
+    css::uno::Reference< css::uno::XInterface > f0;
+    // Shortcut loading via SharedLibrary loader, to pass in prefix argument
+    // (which the loader's activate implementation would normally obtain through
+    // the legacy xKey argument):
+    if (implementation->second.loader.equalsAsciiL(
+            RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary")))
+    {
+        rtl::OUString prefix(implementation->second.prefix);
+        if (!prefix.isEmpty()) {
+            prefix += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_"));
+        }
+        try {
+            f0 = cppu::loadSharedLibComponentFactory(
+                uri, rtl::OUString(), implementation->first, this,
+                css::uno::Reference< css::registry::XRegistryKey >(), prefix);
+        } catch (css::loader::CannotActivateFactoryException & e) {
+            SAL_DEBUG("throw4: "<<e.Message);
+            throw css::uno::DeploymentException(
+                rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TODO")) + e.Message,
+                static_cast< cppu::OWeakObject * >(this));
+        }
+    } else {
+        //TODO
+        SAL_DEBUG("throw5");
+        throw css::uno::DeploymentException(
+            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TODO")),
+            static_cast< cppu::OWeakObject * >(this));
+    }
+    css::uno::Reference< css::lang::XSingleComponentFactory > f1(
+        f0, css::uno::UNO_QUERY);
+    css::uno::Reference< css::lang::XSingleServiceFactory > f2;
+    if (!f1.is()) {
+        f2 = css::uno::Reference< css::lang::XSingleServiceFactory >(
+            f0, css::uno::UNO_QUERY);
+    }
+    osl::MutexGuard g(*this);
+    if (!implementation->second.loaded) {
+        implementation->second.loaded = true;
+        implementation->second.factory1 = f1;
+        implementation->second.factory2 = f2;
+    }
+}
+
+css::uno::Reference< XComponentContext > bootstrapComponentContext(
+    css::uno::Reference< registry::XSimpleRegistry > const & typeRegistry,
+    rtl::OUString const & serviceUris, Bootstrap const & bootstrap)
+{
+    rtl::Reference< ServiceManager > smgr(new ServiceManager(serviceUris));
+
+    ContextEntry_Init entry;
+    std::vector< ContextEntry_Init > context_values;
+    context_values.push_back(
+        ContextEntry_Init(
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM(
+                    "/singletons/com.sun.star.lang.theServiceManager")),
+            css::uno::makeAny(
+                css::uno::Reference< css::uno::XInterface >(
+                    static_cast< cppu::OWeakObject * >(smgr.get()))),
+            false));
+    context_values.push_back( //TODO: from services.rdb?
+        ContextEntry_Init(
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM(
+                    "/singletons/com.sun.star.reflection"
+                    ".theTypeDescriptionManager")),
+            css::uno::makeAny(
+                rtl::OUString(
+                    RTL_CONSTASCII_USTRINGPARAM(
+                        "com.sun.star.comp.stoc.TypeDescriptionManager"))),
+            true /*TODO: false?*/));
+    context_values.push_back( //TODO: from services.rdb?
+        ContextEntry_Init(
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM(
+                    "/singletons/com.sun.star.util.theMacroExpander")),
+            css::uno::makeAny(create_boostrap_macro_expander_factory()), true));
+    Data const & data = smgr->getData();
+    for (ImplementationMap::const_iterator i(data.singletons.begin());
+         i != data.singletons.end(); ++i)
+    {
+        assert(!i->second.empty());
+        SAL_INFO_IF(
+            i->second.size() > 1, "cppuhelper",
+            "arbitrarily chosing \"" << i->second[0]
+                << "\" among multiple implementations for \"" << i->first
+                << "\"");
+        context_values.push_back(
+            ContextEntry_Init(
+                (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/singletons/"))
+                 + i->first),
+                css::uno::makeAny(i->second[0]), true));
+    }
+    add_access_control_entries(&context_values, bootstrap);
+
+    assert(!context_values.empty());
+    css::uno::Reference< XComponentContext > context(
+        createComponentContext(
+            &context_values[0], context_values.size(),
+            css::uno::Reference< css::uno::XComponentContext >()));
+
+    smgr->setContext(context);
+
+    css::uno::Reference< container::XHierarchicalNameAccess > tdmgr(
+        context->getValueByName(
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM(
+                    "/singletons/com.sun.star.reflection"
+                    ".theTypeDescriptionManager"))),
+        css::uno::UNO_QUERY_THROW);
+    if (typeRegistry.is()) {
+        css::uno::Sequence< css::uno::Any > arg(1);
+        arg[0] <<= typeRegistry;
+        css::uno::Reference< css::container::XSet >(
+            tdmgr, css::uno::UNO_QUERY_THROW)->
+            insert(
+                css::uno::makeAny(
+                    smgr->createInstanceWithArgumentsAndContext(
+                        rtl::OUString(
+                            RTL_CONSTASCII_USTRINGPARAM(
+                                "com.sun.star.comp.stoc"
+                                ".RegistryTypeDescriptionProvider")),
+                        arg, context)));
+    }
+    installTypeDescriptionManager(tdmgr);
+
+    return context;
+}
+
+}
+
+css::uno::Reference< css::uno::XComponentContext > defaultBootstrap() {
+    rtl::Bootstrap const & bs = get_unorc();
+    if (bs.getHandle() == 0) {
+        throw css::uno::DeploymentException(
+            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot open uno ini")),
+            css::uno::Reference< css::uno::XInterface >());
+    }
+    rtl::OUString typeUris;
+    if (!bs.getFrom(
+            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UNO_TYPES")), typeUris))
+    {
+        throw css::uno::DeploymentException(
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM(
+                    "Cannot obtain UNO_TYPES from uno ini")),
+            css::uno::Reference< css::uno::XInterface >());
+    }
+    rtl::OUString serviceUris;
+    if (!bs.getFrom(
+            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UNO_SERVICES")),
+            serviceUris))
+    {
+        throw css::uno::DeploymentException(
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM(
+                    "Cannot obtain UNO_SERVICES from uno ini")),
+            css::uno::Reference< css::uno::XInterface >());
+    }
+    OUString libDir;
+    if (!bs.getFrom(
+            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URE_INTERNAL_LIB_DIR")),
+            libDir))
+    {
+        throw css::uno::DeploymentException(
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM(
+                    "Cannot obtain URE_INTERNAL_LIB_DIR from uno ini")),
+            css::uno::Reference< css::uno::XInterface >());
+    }
+    css::uno::Reference< css::lang::XMultiComponentFactory > factory(
+        bootstrapInitialSF(libDir));
+    css::uno::Reference< css::registry::XRegistryKey > emptyKey;
+    css::uno::Reference< css::lang::XSingleServiceFactory > simpleRegs(
+        loadSharedLibComponentFactory(
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM("bootstrap.uno" SAL_DLLEXTENSION)),
+            libDir,
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM(
+                    "com.sun.star.comp.stoc.SimpleRegistry")),
+            css::uno::Reference< css::lang::XMultiServiceFactory >(
+                factory, css::uno::UNO_QUERY_THROW),
+            emptyKey),
+        css::uno::UNO_QUERY_THROW);
+    css::uno::Reference< css::lang::XSingleServiceFactory > nestedRegs(
+        loadSharedLibComponentFactory(
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM("bootstrap.uno" SAL_DLLEXTENSION)),
+            libDir,
+            rtl::OUString(
+                RTL_CONSTASCII_USTRINGPARAM(
+                    "com.sun.star.comp.stoc.NestedRegistry")),
+            css::uno::Reference< css::lang::XMultiServiceFactory >(
+                factory, css::uno::UNO_QUERY_THROW),
+            emptyKey),
+        css::uno::UNO_QUERY_THROW);
+    return bootstrapComponentContext(
+        nestRegistries(
+            rtl::OUString(), simpleRegs, nestedRegs, typeUris, rtl::OUString(),
+            false, false),
+        serviceUris, bs);
+}
+
+#endif // SB
+
 BootstrapException::BootstrapException()
 {
 }
@@ -516,9 +1616,9 @@ const ::rtl::OUString & BootstrapException::getMessage() const
     return m_aMessage;
 }
 
-Reference< XComponentContext > SAL_CALL bootstrap()
+css::uno::Reference< XComponentContext > SAL_CALL bootstrap()
 {
-    Reference< XComponentContext > xRemoteContext;
+    css::uno::Reference< XComponentContext > xRemoteContext;
 
     try
     {
@@ -556,7 +1656,7 @@ Reference< XComponentContext > SAL_CALL bootstrap()
         }
 
         // create default local component context
-        Reference< XComponentContext > xLocalContext(
+        css::uno::Reference< XComponentContext > xLocalContext(
             defaultBootstrap_InitialComponentContext() );
         if ( !xLocalContext.is() )
             throw BootstrapException( OUSTR( "no local component context!" ) );
@@ -629,7 +1729,7 @@ Reference< XComponentContext > SAL_CALL bootstrap()
         }
 
         // create a URL resolver
-        Reference< bridge::XUnoUrlResolver > xUrlResolver(
+        css::uno::Reference< bridge::XUnoUrlResolver > xUrlResolver(
             bridge::UnoUrlResolver::create( xLocalContext ) );
 
         // connection string
diff --git a/cppuhelper/source/gcc3.map b/cppuhelper/source/gcc3.map
index 6ce6cf1..17e895e 100644
--- a/cppuhelper/source/gcc3.map
+++ b/cppuhelper/source/gcc3.map
@@ -408,6 +408,11 @@ global:
         _ZThn*_N4cppu19OPropertySetHelper232enableChangeListenerNotificationEh;
 } UDK_3.7;
 
+UDK_TODO {
+global:
+    _ZN4cppu16defaultBootstrapEv; # cppu::defaultBootstrap()
+} UDK_3.8;
+
 # Unique libstdc++ symbols:
 GLIBCXX_3.4 {
     global:
diff --git a/cppuhelper/source/servicefactory.cxx b/cppuhelper/source/servicefactory.cxx
index ff4f417..b3f03d3 100644
--- a/cppuhelper/source/servicefactory.cxx
+++ b/cppuhelper/source/servicefactory.cxx
@@ -183,7 +183,7 @@ Reference< registry::XSimpleRegistry > SAL_CALL createNestedRegistry(
     UNO_AC_POLICYFILE=<file_url> [optional]
       -- read policy out of simple text file
 */
-static void add_access_control_entries(
+void add_access_control_entries(
     ::std::vector< ContextEntry_Init > * values,
     Bootstrap const & bootstrap )
     SAL_THROW( (Exception) )
diff --git a/cppuhelper/unotypes/Makefile b/cppuhelper/unotypes/Makefile
index c92ad45..605a87f 100644
--- a/cppuhelper/unotypes/Makefile
+++ b/cppuhelper/unotypes/Makefile
@@ -65,6 +65,7 @@ UNOTYPES := \
        com.sun.star.bridge.UnoUrlResolver \
        com.sun.star.bridge.XUnoUrlResolver \
        com.sun.star.connection.SocketPermission \
+       com.sun.star.container.XContentEnumerationAccess \
        com.sun.star.container.XElementAccess \
        com.sun.star.container.XEnumerationAccess \
        com.sun.star.container.XHierarchicalNameAccess \
diff --git a/desktop/source/app/appinit.cxx b/desktop/source/app/appinit.cxx
index 92da668..34cd97b 100644
--- a/desktop/source/app/appinit.cxx
+++ b/desktop/source/app/appinit.cxx
@@ -187,8 +187,7 @@ Reference< XMultiServiceFactory > Desktop::CreateApplicationServiceManager()
         UNO_QUERY_THROW);
 #else
     return Reference<XMultiServiceFactory>(
-        cppu::defaultBootstrap_InitialComponentContext()->getServiceManager(),
-        UNO_QUERY_THROW);
+        cppu::defaultBootstrap()->getServiceManager(), UNO_QUERY_THROW);
 #endif
 }
 

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.