summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2013-01-18 12:46:16 +0100
committerStephan Bergmann <sbergman@redhat.com>2013-01-18 16:55:04 +0100
commit36e8d5d137260decabb7d2436fff2d3a93278f9d (patch)
treed1c644a9de73ac9f80ad89bf515c463d5d74acfa
parenteed249f55522f3a9df0742430d1f738efafa00f4 (diff)
Insert type rdbs individually into theTypeDescriptionManager
...to make it easier in the future to replace the binary rdb format with something else, but also keep support for the old format for backwards compatibility (extensions). This should have no performance impact, as the type description manager (a) caches information about requested type descriptions, and (b) has been changed to process the bootstrap rdbs en bloc without doing costly consistency checks (which are useful though when inserting an rdb when installing an extension, but which would exhaustively read all type descriptions from the inserted rdb, so would negate any benefit of constructing any type descriptions on demand only). Change-Id: I80b22770bd9a5e0ab686f04d9c70295f2e3d0bf6
-rw-r--r--cppuhelper/source/defaultbootstrap.cxx3
-rw-r--r--cppuhelper/source/typedescriptionprovider.cxx124
-rw-r--r--cppuhelper/source/typedescriptionprovider.hxx11
-rw-r--r--stoc/source/tdmanager/tdmgr.cxx195
4 files changed, 174 insertions, 159 deletions
diff --git a/cppuhelper/source/defaultbootstrap.cxx b/cppuhelper/source/defaultbootstrap.cxx
index 9f0cb52d32e9..39d5b22326e7 100644
--- a/cppuhelper/source/defaultbootstrap.cxx
+++ b/cppuhelper/source/defaultbootstrap.cxx
@@ -35,6 +35,7 @@
#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
#include "com/sun/star/container/XSet.hpp"
#include "com/sun/star/uno/DeploymentException.hpp"
+#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/XComponentContext.hpp"
#include "cppuhelper/bootstrap.hxx"
@@ -117,7 +118,7 @@ cppu::defaultBootstrap_InitialComponentContext(rtl::OUString const & iniUri)
tdmgr, css::uno::UNO_QUERY_THROW)->
insert(
css::uno::makeAny(
- cppuhelper::createTypeDescriptionProvider(
+ cppuhelper::createTypeDescriptionProviders(
getBootstrapVariable(bs, "UNO_TYPES"), smgr.get(),
context)));
cppu::installTypeDescriptionManager(tdmgr);
diff --git a/cppuhelper/source/typedescriptionprovider.cxx b/cppuhelper/source/typedescriptionprovider.cxx
index d99650b6bb17..17e447f6f80d 100644
--- a/cppuhelper/source/typedescriptionprovider.cxx
+++ b/cppuhelper/source/typedescriptionprovider.cxx
@@ -10,13 +10,16 @@
#include "sal/config.h"
#include <cassert>
+#include <vector>
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
#include "com/sun/star/lang/XInitialization.hpp"
#include "com/sun/star/lang/XMultiComponentFactory.hpp"
#include "com/sun/star/registry/InvalidRegistryException.hpp"
#include "com/sun/star/registry/XSimpleRegistry.hpp"
#include "com/sun/star/uno/DeploymentException.hpp"
#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/XComponentContext.hpp"
#include "com/sun/star/uno/XInterface.hpp"
#include "osl/file.hxx"
@@ -27,52 +30,50 @@
namespace {
-css::uno::Reference< css::registry::XSimpleRegistry > readTypeRdbFile(
+void readTypeRdbFile(
rtl::OUString const & uri, bool optional,
- css::uno::Reference< css::registry::XSimpleRegistry > const & lastRegistry,
css::uno::Reference< css::lang::XMultiComponentFactory > const &
serviceManager,
- css::uno::Reference< css::uno::XComponentContext > const & context)
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ std::vector<
+ css::uno::Reference< css::container::XHierarchicalNameAccess > > *
+ providers)
{
assert(serviceManager.is());
+ assert(providers != 0);
+ css::uno::Reference< css::registry::XSimpleRegistry > reg(
+ serviceManager->createInstanceWithContext(
+ "com.sun.star.comp.stoc.SimpleRegistry", context),
+ css::uno::UNO_QUERY_THROW);
try {
- css::uno::Reference< css::registry::XSimpleRegistry > simple(
- serviceManager->createInstanceWithContext(
- "com.sun.star.comp.stoc.SimpleRegistry", context),
- css::uno::UNO_QUERY_THROW);
- simple->open(uri, true, false);
- if (lastRegistry.is()) {
- css::uno::Reference< css::registry::XSimpleRegistry > nested(
- serviceManager->createInstanceWithContext(
- "com.sun.star.comp.stoc.NestedRegistry", context),
- css::uno::UNO_QUERY_THROW);
- css::uno::Sequence< css::uno::Any > args(2);
- args[0] <<= lastRegistry;
- args[1] <<= simple;
- css::uno::Reference< css::lang::XInitialization >(
- nested, css::uno::UNO_QUERY_THROW)->
- initialize(args);
- return nested;
- } else {
- return simple;
- }
+ reg->open(uri, true, false);
} catch (css::registry::InvalidRegistryException & e) {
- if (!optional) {
- throw css::uno::DeploymentException(
- "Invalid registry " + uri + ":" + e.Message,
- css::uno::Reference< css::uno::XInterface >());
+ if (optional) {
+ SAL_INFO("cppuhelper", "Ignored optional " << uri);
+ return;
}
- SAL_INFO("cppuhelper", "Ignored optional " << uri);
- return lastRegistry;
+ throw css::uno::DeploymentException(
+ "Invalid registry " + uri + ":" + e.Message,
+ css::uno::Reference< css::uno::XInterface >());
}
+ css::uno::Sequence< css::uno::Any > arg(1);
+ arg[0] <<= reg;
+ providers->push_back(
+ css::uno::Reference< css::container::XHierarchicalNameAccess >(
+ serviceManager->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider", arg,
+ context),
+ css::uno::UNO_QUERY_THROW));
}
-css::uno::Reference< css::registry::XSimpleRegistry > readTypeRdbDirectory(
+void readTypeRdbDirectory(
rtl::OUString const & uri, bool optional,
- css::uno::Reference< css::registry::XSimpleRegistry > const & lastRegistry,
css::uno::Reference< css::lang::XMultiComponentFactory > const &
serviceManager,
- css::uno::Reference< css::uno::XComponentContext > const & context)
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ std::vector<
+ css::uno::Reference< css::container::XHierarchicalNameAccess > > *
+ providers)
{
osl::Directory dir(uri);
switch (dir.open()) {
@@ -81,7 +82,7 @@ css::uno::Reference< css::registry::XSimpleRegistry > readTypeRdbDirectory(
case osl::FileBase::E_NOENT:
if (optional) {
SAL_INFO("cppuhelper", "Ignored optional " << uri);
- return lastRegistry;
+ return;
}
// fall through
default:
@@ -89,25 +90,27 @@ css::uno::Reference< css::registry::XSimpleRegistry > readTypeRdbDirectory(
"Cannot open directory " + uri,
css::uno::Reference< css::uno::XInterface >());
}
- css::uno::Reference< css::registry::XSimpleRegistry > last(lastRegistry);
for (;;) {
rtl::OUString fileUri;
if (!cppu::nextDirectoryItem(dir, &fileUri)) {
break;
}
- last = readTypeRdbFile(
- fileUri, optional, last, serviceManager, context);
+ readTypeRdbFile(fileUri, optional, serviceManager, context, providers);
}
- return last;
}
-css::uno::Reference< css::registry::XSimpleRegistry > createTypeRegistry(
+}
+
+css::uno::Sequence<
+ css::uno::Reference< css::container::XHierarchicalNameAccess > >
+cppuhelper::createTypeDescriptionProviders(
rtl::OUString const & uris,
css::uno::Reference< css::lang::XMultiComponentFactory > const &
serviceManager,
css::uno::Reference< css::uno::XComponentContext > const & context)
{
- css::uno::Reference< css::registry::XSimpleRegistry > reg;
+ std::vector<
+ css::uno::Reference< css::container::XHierarchicalNameAccess > > provs;
for (sal_Int32 i = 0; i != -1;) {
rtl::OUString uri(uris.getToken(0, ' ', i));
if (uri.isEmpty()) {
@@ -116,35 +119,24 @@ css::uno::Reference< css::registry::XSimpleRegistry > createTypeRegistry(
bool optional;
bool directory;
cppu::decodeRdbUri(&uri, &optional, &directory);
- reg = directory
- ? readTypeRdbDirectory(uri, optional, reg, serviceManager, context)
- : readTypeRdbFile(uri, optional, reg, serviceManager, context);
+ if (directory) {
+ readTypeRdbDirectory(
+ uri, optional, serviceManager, context, &provs);
+ } else {
+ readTypeRdbFile(uri, optional, serviceManager, context, &provs);
+ }
}
- return reg;
-}
-
-}
-
-css::uno::Reference< css::uno::XInterface >
-cppuhelper::createTypeDescriptionProvider(
- rtl::OUString const & uris,
- css::uno::Reference< css::lang::XMultiComponentFactory > const &
- serviceManager,
- css::uno::Reference< css::uno::XComponentContext > const & context)
-{
- assert(serviceManager.is());
- css::uno::Sequence< css::uno::Any > args;
- css::uno::Reference< css::registry::XSimpleRegistry > typereg(
- createTypeRegistry(uris, serviceManager, context));
- if (typereg.is()) {
- args.realloc(1);
- args[0] <<= typereg;
+ css::uno::Sequence<
+ css::uno::Reference< css::container::XHierarchicalNameAccess > > provs2(
+ static_cast< sal_Int32 >(provs.size())); //TODO: check overflow
+ std::vector<
+ css::uno::Reference<
+ css::container::XHierarchicalNameAccess > >::iterator i(
+ provs.begin());
+ for (sal_Int32 j = 0; j != provs2.getLength(); ++j) {
+ provs2[j] = *i++;
}
- return css::uno::Reference< css::uno::XInterface >(
- serviceManager->createInstanceWithArgumentsAndContext(
- "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider",
- args, context),
- css::uno::UNO_SET_THROW);
+ return provs2;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cppuhelper/source/typedescriptionprovider.hxx b/cppuhelper/source/typedescriptionprovider.hxx
index f3715e621698..93336e8982f6 100644
--- a/cppuhelper/source/typedescriptionprovider.hxx
+++ b/cppuhelper/source/typedescriptionprovider.hxx
@@ -13,19 +13,20 @@
#include "sal/config.h"
#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
namespace com { namespace sun { namespace star {
+ namespace container { class XHierarchicalNameAccess; }
namespace lang { class XMultiComponentFactory; }
- namespace uno {
- class XComponentContext;
- class XInterface;
- }
+ namespace uno { class XComponentContext; }
} } }
namespace rtl { class OUString; }
namespace cppuhelper {
-css::uno::Reference< css::uno::XInterface > createTypeDescriptionProvider(
+css::uno::Sequence<
+ css::uno::Reference< css::container::XHierarchicalNameAccess > >
+createTypeDescriptionProviders(
rtl::OUString const & uris,
css::uno::Reference< css::lang::XMultiComponentFactory > const &
serviceManager,
diff --git a/stoc/source/tdmanager/tdmgr.cxx b/stoc/source/tdmanager/tdmgr.cxx
index b246e30ee648..2047f4a69042 100644
--- a/stoc/source/tdmanager/tdmgr.cxx
+++ b/stoc/source/tdmanager/tdmgr.cxx
@@ -392,112 +392,133 @@ sal_Bool SAL_CALL ManagerImpl::has( const Any & rElement )
void SAL_CALL ManagerImpl::insert( const Any & rElement )
throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException)
{
- Reference< XHierarchicalNameAccess > xElem;
- if (! (rElement >>= xElem) || !xElem.is())
- {
- throw IllegalArgumentException(
- OUString( RTL_CONSTASCII_USTRINGPARAM("no valid type description provider given!") ),
- (XWeak *)(OWeakObject *)this, 0 );
+ // Passing in a sequence of type providers instead of a single one bypasses
+ // the consistency checks; it is used during bootstrap:
+ bool doCheck = false;
+ css::uno::Sequence<
+ css::uno::Reference< css::container::XHierarchicalNameAccess > > provs;
+ if (!(rElement >>= provs)) {
+ css::uno::Reference< css::container::XHierarchicalNameAccess > prov;
+ if (!(rElement >>= prov)) {
+ throw css::lang::IllegalArgumentException(
+ "no type description provider (or sequence thereof)",
+ static_cast< cppu::OWeakObject * >(this), 0);
+ }
+ doCheck = true;
+ provs.realloc(1);
+ provs[0] = prov;
}
MutexGuard aGuard( _aComponentMutex );
- if (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end())
- {
- throw ElementExistException(
- OUString( RTL_CONSTASCII_USTRINGPARAM("provider already inserted!") ),
- (XWeak *)(OWeakObject *)this );
- }
+ ProviderVector newProvs(_aProviders);
+ for (sal_Int32 i = 0; i != provs.getLength(); ++i) {
+ Reference< XHierarchicalNameAccess > xElem(provs[i]);
+ if (!xElem.is()) {
+ throw css::lang::IllegalArgumentException(
+ "null type description provider",
+ static_cast< cppu::OWeakObject * >(this), 0);
+ }
- if (! _aProviders.empty())
- {
- // check whether all types are compatible, if possible:
- Reference<reflection::XTypeDescriptionEnumerationAccess> xTDEnumAccess(
- xElem, UNO_QUERY );
- OSL_ENSURE( xTDEnumAccess.is(),
- "### providers ought to implement "
- "reflection::XTypeDescriptionEnumerationAccess!" );
- if (xTDEnumAccess.is())
- {
- try
+ if (doCheck) {
+ if (find( newProvs.begin(), newProvs.end(), xElem ) != newProvs.end())
{
- TypeClass ar [] = {
- TypeClass_ENUM, TypeClass_TYPEDEF, TypeClass_SEQUENCE,
- TypeClass_STRUCT, TypeClass_EXCEPTION,
- /* TypeClass_UNION, TypeClass_ARRAY not supported */
- TypeClass_INTERFACE,
- TypeClass_SERVICE,
- TypeClass_INTERFACE_METHOD, TypeClass_INTERFACE_ATTRIBUTE,
- TypeClass_PROPERTY, TypeClass_CONSTANT, TypeClass_CONSTANTS,
- TypeClass_SINGLETON
- };
- Reference<reflection::XTypeDescriptionEnumeration> xTDEnum(
- xTDEnumAccess->createTypeDescriptionEnumeration(
- OUString() /* all modules */,
- Sequence<TypeClass>( ar, ARLEN(ar) ),
- reflection::TypeDescriptionSearchDepth_INFINITE ) );
-
- while (xTDEnum->hasMoreElements())
+ throw ElementExistException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("provider already inserted!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+
+ // check whether all types are compatible, if possible:
+ Reference<reflection::XTypeDescriptionEnumerationAccess> xTDEnumAccess(
+ xElem, UNO_QUERY );
+ OSL_ENSURE( xTDEnumAccess.is(),
+ "### providers ought to implement "
+ "reflection::XTypeDescriptionEnumerationAccess!" );
+ if (xTDEnumAccess.is())
+ {
+ try
{
- Reference<reflection::XTypeDescription> xNewTD;
- try
+ TypeClass ar [] = {
+ TypeClass_ENUM, TypeClass_TYPEDEF, TypeClass_SEQUENCE,
+ TypeClass_STRUCT, TypeClass_EXCEPTION,
+ /* TypeClass_UNION, TypeClass_ARRAY not supported */
+ TypeClass_INTERFACE,
+ TypeClass_SERVICE,
+ TypeClass_INTERFACE_METHOD, TypeClass_INTERFACE_ATTRIBUTE,
+ TypeClass_PROPERTY, TypeClass_CONSTANT, TypeClass_CONSTANTS,
+ TypeClass_SINGLETON
+ };
+ Reference<reflection::XTypeDescriptionEnumeration> xTDEnum(
+ xTDEnumAccess->createTypeDescriptionEnumeration(
+ OUString() /* all modules */,
+ Sequence<TypeClass>( ar, ARLEN(ar) ),
+ reflection::TypeDescriptionSearchDepth_INFINITE ) );
+
+ while (xTDEnum->hasMoreElements())
{
- xNewTD = xTDEnum->nextTypeDescription();
- }
- catch (const container::NoSuchElementException & exc)
- {
- throw lang::IllegalArgumentException(
- OUSTR("NoSuchElementException occurred: ") +
- exc.Message, static_cast<OWeakObject *>(this),
- -1 /* unknown */ );
- }
+ Reference<reflection::XTypeDescription> xNewTD;
+ try
+ {
+ xNewTD = xTDEnum->nextTypeDescription();
+ }
+ catch (const container::NoSuchElementException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("NoSuchElementException occurred: ") +
+ exc.Message, static_cast<OWeakObject *>(this),
+ -1 /* unknown */ );
+ }
- try
- {
- OUString newName( xNewTD->getName() );
- Reference<reflection::XTypeDescription> xExistingTD(
- getByHierarchicalName( newName ), UNO_QUERY );
- OSL_ASSERT( xExistingTD.is() );
- // existing, check whether compatible:
- if (xExistingTD.is())
+ try
{
- try
+ OUString newName( xNewTD->getName() );
+ Reference<reflection::XTypeDescription> xExistingTD(
+ getByHierarchicalName( newName ), UNO_QUERY );
+ OSL_ASSERT( xExistingTD.is() );
+ // existing, check whether compatible:
+ if (xExistingTD.is())
{
- check( xNewTD, xExistingTD );
- }
- catch (const IncompatibleTypeException & exc)
- {
- throw lang::IllegalArgumentException(
- OUSTR("Rejecting types due to "
- "incompatibility! ") + exc.m_cause,
- static_cast<OWeakObject *>(this), 0 );
+ try
+ {
+ check( xNewTD, xExistingTD );
+ }
+ catch (const IncompatibleTypeException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("Rejecting types due to "
+ "incompatibility! ") + exc.m_cause,
+ static_cast<OWeakObject *>(this), 0 );
+ }
}
}
- }
- catch (container::NoSuchElementException &)
- {
- // type not in: ok
+ catch (container::NoSuchElementException &)
+ {
+ // type not in: ok
+ }
}
}
+ catch (const reflection::NoSuchTypeNameException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("NoSuchTypeNameException occurred: ") + exc.Message,
+ static_cast<OWeakObject *>(this), -1 /* unknown */ );
}
- catch (const reflection::NoSuchTypeNameException & exc)
- {
- throw lang::IllegalArgumentException(
- OUSTR("NoSuchTypeNameException occurred: ") + exc.Message,
- static_cast<OWeakObject *>(this), -1 /* unknown */ );
- }
- catch (const reflection::InvalidTypeNameException & exc)
- {
- throw lang::IllegalArgumentException(
- OUSTR("InvalidTypeNameException occurred: ") + exc.Message,
- static_cast<OWeakObject *>(this), -1 /* unknown */ );
+ catch (const reflection::InvalidTypeNameException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("InvalidTypeNameException occurred: ") + exc.Message,
+ static_cast<OWeakObject *>(this), -1 /* unknown */ );
+ }
}
}
+ newProvs.push_back( xElem );
}
- _aProviders.push_back( xElem );
- Reference< XComponent > xComp( xElem, UNO_QUERY );
- if (xComp.is())
- xComp->addEventListener( &_aEventListener );
+ _aProviders = newProvs;
+ for (sal_Int32 i = 0; i != provs.getLength(); ++i) {
+ Reference< XComponent > xComp( provs[i], UNO_QUERY );
+ if (xComp.is())
+ xComp->addEventListener( &_aEventListener );
+ }
}
//__________________________________________________________________________________________________
void SAL_CALL ManagerImpl::remove( const Any & rElement )