diff options
-rw-r--r-- | cppuhelper/Library_cppuhelper.mk | 2 | ||||
-rw-r--r-- | cppuhelper/source/defaultbootstrap.cxx | 27 | ||||
-rw-r--r-- | cppuhelper/source/typedescriptionprovider.cxx (renamed from cppuhelper/source/typemanager.cxx) | 1393 | ||||
-rw-r--r-- | cppuhelper/source/typedescriptionprovider.hxx | 39 | ||||
-rw-r--r-- | cppuhelper/source/typemanager.hxx | 151 | ||||
-rw-r--r-- | desktop/source/deployment/registry/component/dp_component.cxx | 57 | ||||
-rw-r--r-- | stoc/Library_bootstrap.mk | 3 | ||||
-rw-r--r-- | stoc/inc/bootstrapservices.hxx | 7 | ||||
-rw-r--r-- | stoc/source/bootstrap/services.cxx | 6 | ||||
-rw-r--r-- | stoc/source/tdmanager/lrucache.hxx | 242 | ||||
-rw-r--r-- | stoc/source/tdmanager/tdmgr.cxx | 1152 | ||||
-rw-r--r-- | stoc/source/tdmanager/tdmgr_common.hxx | 51 | ||||
-rw-r--r-- | stoc/source/tdmanager/tdmgr_tdenumeration.cxx | 176 | ||||
-rw-r--r-- | stoc/source/tdmanager/tdmgr_tdenumeration.hxx | 82 | ||||
-rw-r--r-- | stoc/util/bootstrap.component | 4 | ||||
-rw-r--r-- | unoidl/inc/unoidl/unoidl.hxx | 2 | ||||
-rw-r--r-- | unoidl/source/unoidl.cxx | 5 |
17 files changed, 2372 insertions, 1027 deletions
diff --git a/cppuhelper/Library_cppuhelper.mk b/cppuhelper/Library_cppuhelper.mk index b594b533aea1..577efbcf942d 100644 --- a/cppuhelper/Library_cppuhelper.mk +++ b/cppuhelper/Library_cppuhelper.mk @@ -75,7 +75,7 @@ $(eval $(call gb_Library_add_exception_objects,cppuhelper,\ cppuhelper/source/shlib \ cppuhelper/source/supportsservice \ cppuhelper/source/tdmgr \ - cppuhelper/source/typemanager \ + cppuhelper/source/typedescriptionprovider \ cppuhelper/source/typeprovider \ cppuhelper/source/unourl \ cppuhelper/source/weak \ diff --git a/cppuhelper/source/defaultbootstrap.cxx b/cppuhelper/source/defaultbootstrap.cxx index 54516ea59174..39d5b22326e7 100644 --- a/cppuhelper/source/defaultbootstrap.cxx +++ b/cppuhelper/source/defaultbootstrap.cxx @@ -32,6 +32,8 @@ #include <cassert> #include <vector> +#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" @@ -45,7 +47,7 @@ #include "macro_expander.hxx" #include "paths.hxx" #include "servicemanager.hxx" -#include "typemanager.hxx" +#include "typedescriptionprovider.hxx" namespace { @@ -76,9 +78,6 @@ cppu::defaultBootstrap_InitialComponentContext(rtl::OUString const & iniUri) rtl::Reference< cppuhelper::ServiceManager > smgr( new cppuhelper::ServiceManager( getBootstrapVariable(bs, "UNO_SERVICES"))); - rtl::Reference< cppuhelper::TypeManager > tmgr( - new cppuhelper::TypeManager( - getBootstrapVariable(bs, "UNO_TYPES"))); cppu::ContextEntry_Init entry; std::vector< cppu::ContextEntry_Init > context_values; context_values.push_back( @@ -88,13 +87,6 @@ cppu::defaultBootstrap_InitialComponentContext(rtl::OUString const & iniUri) css::uno::Reference< css::uno::XInterface >( static_cast< cppu::OWeakObject * >(smgr.get()))), false)); - context_values.push_back( - cppu::ContextEntry_Init( - "/singletons/com.sun.star.reflection.theTypeDescriptionManager", - css::uno::makeAny( - css::uno::Reference< css::uno::XInterface >( - static_cast< cppu::OWeakObject * >(tmgr.get()))), - false)); context_values.push_back( //TODO: from services.rdb? cppu::ContextEntry_Init( "/singletons/com.sun.star.util.theMacroExpander", @@ -118,7 +110,18 @@ cppu::defaultBootstrap_InitialComponentContext(rtl::OUString const & iniUri) &context_values[0], context_values.size(), css::uno::Reference< css::uno::XComponentContext >())); smgr->setContext(context); - cppu::installTypeDescriptionManager(tmgr.get()); + css::uno::Reference< css::container::XHierarchicalNameAccess > tdmgr( + context->getValueByName( + "/singletons/com.sun.star.reflection.theTypeDescriptionManager"), + css::uno::UNO_QUERY_THROW); + css::uno::Reference< css::container::XSet >( + tdmgr, css::uno::UNO_QUERY_THROW)-> + insert( + css::uno::makeAny( + cppuhelper::createTypeDescriptionProviders( + getBootstrapVariable(bs, "UNO_TYPES"), smgr.get(), + context))); + cppu::installTypeDescriptionManager(tdmgr); return context; } diff --git a/cppuhelper/source/typemanager.cxx b/cppuhelper/source/typedescriptionprovider.cxx index 721d5975b985..7dbe5e590b88 100644 --- a/cppuhelper/source/typemanager.cxx +++ b/cppuhelper/source/typedescriptionprovider.cxx @@ -10,17 +10,16 @@ #include "sal/config.h" #include <cassert> -#include <cstddef> #include <cstdlib> -#include <cstring> #include <set> #include <stack> #include <vector> #include "boost/noncopyable.hpp" -#include "com/sun/star/container/ElementExistException.hpp" #include "com/sun/star/container/NoSuchElementException.hpp" -#include "com/sun/star/lang/IllegalArgumentException.hpp" +#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/reflection/InvalidTypeNameException.hpp" #include "com/sun/star/reflection/NoSuchTypeNameException.hpp" #include "com/sun/star/reflection/TypeDescriptionSearchDepth.hpp" @@ -36,96 +35,58 @@ #include "com/sun/star/reflection/XServiceTypeDescription2.hpp" #include "com/sun/star/reflection/XSingletonTypeDescription2.hpp" #include "com/sun/star/reflection/XStructTypeDescription.hpp" -#include "com/sun/star/reflection/XTypeDescription.hpp" +#include "com/sun/star/reflection/XTypeDescriptionEnumeration.hpp" +#include "com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp" +#include "com/sun/star/registry/InvalidRegistryException.hpp" +#include "com/sun/star/registry/XSimpleRegistry.hpp" #include "com/sun/star/uno/Any.hxx" #include "com/sun/star/uno/DeploymentException.hpp" #include "com/sun/star/uno/Reference.hxx" #include "com/sun/star/uno/RuntimeException.hpp" #include "com/sun/star/uno/Sequence.hxx" -#include "com/sun/star/uno/Type.hxx" #include "com/sun/star/uno/TypeClass.hpp" -#include "cppu/unotype.hxx" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/uno/XInterface.hpp" +#include "cppuhelper/compbase2.hxx" #include "cppuhelper/implbase1.hxx" -#include "cppuhelper/supportsservice.hxx" #include "osl/file.hxx" #include "osl/mutex.hxx" #include "rtl/ref.hxx" -#include "rtl/string.h" #include "rtl/ustring.hxx" -#include "sal/macros.h" #include "sal/types.h" #include "unoidl/unoidl.hxx" +#include "unoidl/unoidlprovider.hxx" #include "paths.hxx" -#include "typemanager.hxx" +#include "typedescriptionprovider.hxx" namespace { -css::uno::Any resolveTypedefs(css::uno::Any const & type) { - for (css::uno::Any t(type);;) { - css::uno::Reference< css::reflection::XIndirectTypeDescription > ind( - type, css::uno::UNO_QUERY); - if (!ind.is() || ind->getTypeClass() != css::uno::TypeClass_TYPEDEF) { - return t; - } - t = css::uno::makeAny(ind->getReferencedType()); +css::uno::Reference< css::reflection::XTypeDescription > resolve( + css::uno::Reference< css::uno::XComponentContext > const & context, + rtl::OUString const & name) +{ + assert(context.is()); + try { + return css::uno::Reference< css::reflection::XTypeDescription >( + (css::uno::Reference< css::container::XHierarchicalNameAccess >( + context->getValueByName( + "/singletons/" + "com.sun.star.reflection.theTypeDescriptionManager"), + css::uno::UNO_QUERY_THROW)-> + getByHierarchicalName(name)), + css::uno::UNO_QUERY_THROW); + } catch (css::container::NoSuchElementException & e) { + throw css::uno::DeploymentException( + ("cannot resolve type \"" + name + "\"; NoSuchElementException: " + + e.Message), + e.Context); } } -class SimpleTypeDescription: - public cppu::WeakImplHelper1< css::reflection::XTypeDescription > -{ -public: - SimpleTypeDescription( - css::uno::TypeClass typeClass, rtl::OUString const & name): - typeClass_(typeClass), name_(name) - {} - -private: - virtual ~SimpleTypeDescription() {} - - virtual css::uno::TypeClass SAL_CALL getTypeClass() - throw (css::uno::RuntimeException) - { return typeClass_; } - - virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException) - { return name_; } - - css::uno::TypeClass typeClass_; - rtl::OUString name_; -}; - -class SequenceTypeDescription: - public cppu::WeakImplHelper1< css::reflection::XIndirectTypeDescription > -{ -public: - SequenceTypeDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, - rtl::OUString const & name, rtl::OUString const & componentType): - manager_(manager), name_(name), componentType_(componentType) - { assert(manager.is()); } - -private: - virtual ~SequenceTypeDescription() {} - - virtual css::uno::TypeClass SAL_CALL getTypeClass() - throw (css::uno::RuntimeException) - { return css::uno::TypeClass_SEQUENCE; } - - virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException) - { return name_; } - - virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL - getReferencedType() throw (css::uno::RuntimeException) - { return manager_->resolve(componentType_); } - - rtl::Reference< cppuhelper::TypeManager > manager_; - rtl::OUString name_; - rtl::OUString componentType_; -}; - class PublishableDescription: - public cppu::WeakImplHelper1< css::reflection::XPublished > + public cppu::WeakImplHelper1< css::reflection::XPublished >, + private boost::noncopyable { protected: PublishableDescription(bool published): published_(published) {} @@ -140,15 +101,16 @@ private: }; class ModuleDescription: - public cppu::WeakImplHelper1< css::reflection::XModuleTypeDescription > + public cppu::WeakImplHelper1< css::reflection::XModuleTypeDescription >, + private boost::noncopyable { public: ModuleDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::ModuleEntity > const & entity): - manager_(manager), name_(name), entity_(entity) - { assert(manager.is()); assert(entity.is()); } + context_(context), name_(name), entity_(entity) + { assert(entity.is()); } private: virtual ~ModuleDescription() {} @@ -165,7 +127,7 @@ private: css::uno::Reference< css::reflection::XTypeDescription > > SAL_CALL getMembers() throw (css::uno::RuntimeException); - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::ModuleEntity > entity_; }; @@ -179,7 +141,7 @@ ModuleDescription::getMembers() throw (css::uno::RuntimeException) { css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { - s[i] = manager_->resolve(name_ + "." + names[i]); + s[i] = resolve(context_, name_ + "." + names[i]); } return s; } catch (unoidl::FileFormatException & e) { @@ -257,12 +219,12 @@ PlainStructTypeDescription_Base; class PlainStructTypeDescription: public PlainStructTypeDescription_Base { public: PlainStructTypeDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::PlainStructTypeEntity > const & entity): PlainStructTypeDescription_Base(entity->isPublished()), - manager_(manager), name_(name), entity_(entity) - { assert(manager.is()); assert(entity.is()); } + context_(context), name_(name), entity_(entity) + { assert(entity.is()); } private: virtual ~PlainStructTypeDescription() {} @@ -278,7 +240,7 @@ private: getBaseType() throw (css::uno::RuntimeException) { return entity_->getDirectBase().isEmpty() ? css::uno::Reference< css::reflection::XTypeDescription >() - : manager_->resolve(entity_->getDirectBase()); + : resolve(context_, entity_->getDirectBase()); } virtual @@ -301,7 +263,7 @@ private: css::uno::Reference< css::reflection::XTypeDescription > >(); } - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::PlainStructTypeEntity > entity_; }; @@ -314,7 +276,7 @@ PlainStructTypeDescription::getMemberTypes() throw (css::uno::RuntimeException) css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { - s[i] = manager_->resolve(entity_->getDirectMembers()[i].type); + s[i] = resolve(context_, entity_->getDirectMembers()[i].type); } return s; } @@ -332,7 +294,8 @@ css::uno::Sequence< rtl::OUString > PlainStructTypeDescription::getMemberNames() } class ParameterizedMemberTypeDescription: - public cppu::WeakImplHelper1< css::reflection::XTypeDescription > + public cppu::WeakImplHelper1< css::reflection::XTypeDescription >, + private boost::noncopyable { public: explicit ParameterizedMemberTypeDescription( @@ -362,13 +325,13 @@ class PolymorphicStructTypeTemplateDescription: { public: PolymorphicStructTypeTemplateDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > const & entity): PolymorphicStructTypeTemplateDescription_Base(entity->isPublished()), - manager_(manager), name_(name), entity_(entity) - { assert(manager.is()); assert(entity.is()); } + context_(context), name_(name), entity_(entity) + { assert(entity.is()); } private: virtual ~PolymorphicStructTypeTemplateDescription() {} @@ -403,7 +366,7 @@ private: css::uno::Reference< css::reflection::XTypeDescription > >(); } - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > entity_; }; @@ -420,7 +383,7 @@ PolymorphicStructTypeTemplateDescription::getMemberTypes() s[i] = entity_->getMembers()[i].parameterized ? new ParameterizedMemberTypeDescription( entity_->getMembers()[i].type) - : manager_->resolve(entity_->getMembers()[i].type); + : resolve(context_, entity_->getMembers()[i].type); } return s; } @@ -451,114 +414,6 @@ PolymorphicStructTypeTemplateDescription::getTypeParameters() return s; } -class InstantiatedPolymorphicStructTypeDescription: - public cppu::WeakImplHelper1< css::reflection::XStructTypeDescription > -{ -public: - InstantiatedPolymorphicStructTypeDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, - rtl::OUString const & name, - rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > const & - entity, - std::vector< rtl::OUString > const & arguments): - manager_(manager), name_(name), entity_(entity), arguments_(arguments) - { - assert(manager.is()); - assert(entity.is()); - assert(arguments.size() == entity->getTypeParameters().size()); - } - -private: - virtual ~InstantiatedPolymorphicStructTypeDescription() {} - - virtual css::uno::TypeClass SAL_CALL getTypeClass() - throw (css::uno::RuntimeException) - { return css::uno::TypeClass_STRUCT; } - - virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException) - { return name_; } - - virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL - getBaseType() throw (css::uno::RuntimeException) - { return css::uno::Reference< css::reflection::XTypeDescription >(); } - - virtual - css::uno::Sequence< - css::uno::Reference< css::reflection::XTypeDescription > > - SAL_CALL getMemberTypes() throw (css::uno::RuntimeException); - - virtual css::uno::Sequence< rtl::OUString > SAL_CALL getMemberNames() - throw (css::uno::RuntimeException); - - virtual css::uno::Sequence< rtl::OUString > SAL_CALL getTypeParameters() - throw (css::uno::RuntimeException) - { return css::uno::Sequence< rtl::OUString >(); } - - virtual - css::uno::Sequence< - css::uno::Reference< css::reflection::XTypeDescription > > - SAL_CALL getTypeArguments() throw (css::uno::RuntimeException); - - rtl::Reference< cppuhelper::TypeManager > manager_; - rtl::OUString name_; - rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > entity_; - std::vector< rtl::OUString > arguments_; -}; - -css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > > -InstantiatedPolymorphicStructTypeDescription::getMemberTypes() - throw (css::uno::RuntimeException) -{ - assert(entity_->getMembers().size() <= SAL_MAX_INT32); - sal_Int32 n = static_cast< sal_Int32 >(entity_->getMembers().size()); - css::uno::Sequence< - css::uno::Reference< css::reflection::XTypeDescription > > s(n); - for (sal_Int32 i = 0; i != n; ++i) { - rtl::OUString type(entity_->getMembers()[i].type); - if (entity_->getMembers()[i].parameterized) { - for (std::vector< rtl::OUString >::const_iterator j( - entity_->getTypeParameters().begin()); - j != entity_->getTypeParameters().end(); ++j) - { - if (*j == type) { - type = arguments_[j - entity_->getTypeParameters().begin()]; - goto found; - } - } - assert(false); // this cannot happen //TODO! - found:; - } - s[i] = manager_->resolve(type); - } - return s; -} - -css::uno::Sequence< rtl::OUString > -InstantiatedPolymorphicStructTypeDescription::getMemberNames() - throw (css::uno::RuntimeException) -{ - assert(entity_->getMembers().size() <= SAL_MAX_INT32); - sal_Int32 n = static_cast< sal_Int32 >(entity_->getMembers().size()); - css::uno::Sequence< rtl::OUString > s(n); - for (sal_Int32 i = 0; i != n; ++i) { - s[i] = entity_->getMembers()[i].name; - } - return s; -} -css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > > -InstantiatedPolymorphicStructTypeDescription::getTypeArguments() - throw (css::uno::RuntimeException) -{ - assert(arguments_.size() <= SAL_MAX_INT32); - sal_Int32 n = static_cast< sal_Int32 >(arguments_.size()); - css::uno::Sequence< - css::uno::Reference< css::reflection::XTypeDescription > > s(n); - for (sal_Int32 i = 0; i != n; ++i) { - s[i] = manager_->resolve(arguments_[i]); - } - return s; -} - typedef cppu::ImplInheritanceHelper1< PublishableDescription, css::reflection::XCompoundTypeDescription > ExceptionTypeDescription_Base; @@ -566,12 +421,12 @@ ExceptionTypeDescription_Base; class ExceptionTypeDescription: public ExceptionTypeDescription_Base { public: ExceptionTypeDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::ExceptionTypeEntity > const & entity): - ExceptionTypeDescription_Base(entity->isPublished()), manager_(manager), + ExceptionTypeDescription_Base(entity->isPublished()), context_(context), name_(name), entity_(entity) - { assert(manager.is()); assert(entity.is()); } + { assert(entity.is()); } private: virtual ~ExceptionTypeDescription() {} @@ -587,7 +442,7 @@ private: getBaseType() throw (css::uno::RuntimeException) { return entity_->getDirectBase().isEmpty() ? css::uno::Reference< css::reflection::XTypeDescription >() - : manager_->resolve(entity_->getDirectBase()); + : resolve(context_, entity_->getDirectBase()); } virtual @@ -598,7 +453,7 @@ private: virtual css::uno::Sequence< rtl::OUString > SAL_CALL getMemberNames() throw (css::uno::RuntimeException); - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::ExceptionTypeEntity > entity_; }; @@ -610,7 +465,7 @@ ExceptionTypeDescription::getMemberTypes() throw (css::uno::RuntimeException) { css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { - s[i] = manager_->resolve(entity_->getDirectMembers()[i].type); + s[i] = resolve(context_, entity_->getDirectMembers()[i].type); } return s; } @@ -627,19 +482,86 @@ css::uno::Sequence< rtl::OUString > ExceptionTypeDescription::getMemberNames() return s; } +css::uno::Reference< css::reflection::XTypeDescription > resolveTypedefs( + css::uno::Reference< css::reflection::XTypeDescription > const & type) +{ + css::uno::Reference< css::reflection::XTypeDescription > resolved(type); + while (resolved->getTypeClass() == css::uno::TypeClass_TYPEDEF) { + resolved + = (css::uno::Reference< css::reflection::XIndirectTypeDescription >( + resolved, css::uno::UNO_QUERY_THROW)-> + getReferencedType()); + } + return resolved; +} + +class BaseOffset: private boost::noncopyable { +public: + BaseOffset( + css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > + const & description); + + sal_Int32 get() const { return offset_; } + +private: + void calculateBases( + css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > + const & description); + + void calculate( + css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > + const & description); + + std::set< rtl::OUString > set_; + sal_Int32 offset_; +}; + +BaseOffset::BaseOffset( + css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > const & + description): + offset_(0) +{ + calculateBases(description); +} + +void BaseOffset::calculateBases( + css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > const & + description) +{ + css::uno::Sequence< + css::uno::Reference < css::reflection::XTypeDescription > > bases( + description->getBaseTypes()); + for (sal_Int32 i = 0; i != bases.getLength(); ++i) { + calculate( + css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >( + resolveTypedefs(bases[i]), css::uno::UNO_QUERY_THROW)); + } +} + +void BaseOffset::calculate( + css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > const & + description) +{ + if (set_.insert(description->getName()).second) { + calculateBases(description); + offset_ += description->getMembers().getLength(); + } +} + class AttributeDescription: public cppu::WeakImplHelper1< - css::reflection::XInterfaceAttributeTypeDescription2 > + css::reflection::XInterfaceAttributeTypeDescription2 >, + private boost::noncopyable { public: AttributeDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, unoidl::InterfaceTypeEntity::Attribute const & attribute, sal_Int32 position): - manager_(manager), name_(name), attribute_(attribute), + context_(context), name_(name), attribute_(attribute), position_(position) - { assert(manager.is()); } + {} private: virtual ~AttributeDescription() {} @@ -663,7 +585,7 @@ private: virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL getType() throw (css::uno::RuntimeException) - { return manager_->resolve(attribute_.type); } + { return resolve(context_, attribute_.type); } virtual sal_Bool SAL_CALL isBound() throw (css::uno::RuntimeException) { return attribute_.bound; } @@ -678,7 +600,7 @@ private: css::uno::Reference< css::reflection::XCompoundTypeDescription > > SAL_CALL getSetExceptions() throw (css::uno::RuntimeException); - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; unoidl::InterfaceTypeEntity::Attribute attribute_; sal_Int32 position_; @@ -693,7 +615,7 @@ AttributeDescription::getGetExceptions() throw (css::uno::RuntimeException) { css::uno::Reference< css::reflection::XCompoundTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { s[i].set( - manager_->resolve(attribute_.getExceptions[i]), + resolve(context_, attribute_.getExceptions[i]), css::uno::UNO_QUERY_THROW); } return s; @@ -708,22 +630,23 @@ AttributeDescription::getSetExceptions() throw (css::uno::RuntimeException) { css::uno::Reference< css::reflection::XCompoundTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { s[i].set( - manager_->resolve(attribute_.setExceptions[i]), + resolve(context_, attribute_.setExceptions[i]), css::uno::UNO_QUERY_THROW); } return s; } class MethodParameter: - public cppu::WeakImplHelper1< css::reflection::XMethodParameter > + public cppu::WeakImplHelper1< css::reflection::XMethodParameter >, + private boost::noncopyable { public: MethodParameter( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, unoidl::InterfaceTypeEntity::Method::Parameter const & parameter, sal_Int32 position): - manager_(manager), parameter_(parameter), position_(position) - { assert(manager.is()); } + context_(context), parameter_(parameter), position_(position) + {} private: virtual ~MethodParameter() {} @@ -733,7 +656,7 @@ private: virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL getType() throw (css::uno::RuntimeException) - { return manager_->resolve(parameter_.type); } + { return resolve(context_, parameter_.type); } virtual sal_Bool SAL_CALL isIn() throw (css::uno::RuntimeException) { return @@ -756,22 +679,23 @@ private: virtual sal_Int32 SAL_CALL getPosition() throw (css::uno::RuntimeException) { return position_; } - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; unoidl::InterfaceTypeEntity::Method::Parameter parameter_; sal_Int32 position_; }; class MethodDescription: public cppu::WeakImplHelper1< - css::reflection::XInterfaceMethodTypeDescription > + css::reflection::XInterfaceMethodTypeDescription >, + private boost::noncopyable { public: MethodDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, unoidl::InterfaceTypeEntity::Method const & method, sal_Int32 position): - manager_(manager), name_(name), method_(method), position_(position) - { assert(manager.is()); } + context_(context), name_(name), method_(method), position_(position) + {} private: virtual ~MethodDescription() {} @@ -792,7 +716,7 @@ private: virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL getReturnType() throw (css::uno::RuntimeException) - { return manager_->resolve(method_.returnType); } + { return resolve(context_, method_.returnType); } virtual sal_Bool SAL_CALL isOneway() throw (css::uno::RuntimeException) { return false; } @@ -807,7 +731,7 @@ private: css::uno::Reference< css::reflection::XTypeDescription > > SAL_CALL getExceptions() throw (css::uno::RuntimeException); - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; unoidl::InterfaceTypeEntity::Method method_; sal_Int32 position_; @@ -820,7 +744,7 @@ MethodDescription::getParameters() throw (css::uno::RuntimeException) { css::uno::Sequence< css::uno::Reference< css::reflection::XMethodParameter > > s(n); for (sal_Int32 i = 0; i != n; ++i) { - s[i] = new MethodParameter(manager_, method_.parameters[i], i); + s[i] = new MethodParameter(context_, method_.parameters[i], i); } return s; } @@ -832,65 +756,11 @@ MethodDescription::getExceptions() throw (css::uno::RuntimeException) { css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { - s[i] = manager_->resolve(method_.exceptions[i]); + s[i] = resolve(context_, method_.exceptions[i]); } return s; } -class BaseOffset: private boost::noncopyable { -public: - BaseOffset( - css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > - const & description); - - sal_Int32 get() const { return offset_; } - -private: - void calculateBases( - css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > - const & description); - - void calculate( - css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > - const & description); - - std::set< rtl::OUString > set_; - sal_Int32 offset_; -}; - -BaseOffset::BaseOffset( - css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > const & - description): - offset_(0) -{ - calculateBases(description); -} - -void BaseOffset::calculateBases( - css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > const & - description) -{ - css::uno::Sequence< - css::uno::Reference < css::reflection::XTypeDescription > > bases( - description->getBaseTypes()); - for (sal_Int32 i = 0; i != bases.getLength(); ++i) { - calculate( - css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >( - resolveTypedefs(css::uno::makeAny(bases[i])), - css::uno::UNO_QUERY_THROW)); - } -} - -void BaseOffset::calculate( - css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > const & - description) -{ - if (set_.insert(description->getName()).second) { - calculateBases(description); - offset_ += description->getMembers().getLength(); - } -} - typedef cppu::ImplInheritanceHelper1< PublishableDescription, css::reflection::XInterfaceTypeDescription2 > InterfaceTypeDescription_Base; @@ -898,12 +768,12 @@ InterfaceTypeDescription_Base; class InterfaceTypeDescription: public InterfaceTypeDescription_Base { public: InterfaceTypeDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::InterfaceTypeEntity > const & entity): - InterfaceTypeDescription_Base(entity->isPublished()), manager_(manager), + InterfaceTypeDescription_Base(entity->isPublished()), context_(context), name_(name), entity_(entity) - { assert(manager.is()); assert(entity.is()); } + { assert(entity.is()); } private: virtual ~InterfaceTypeDescription() {} @@ -919,7 +789,7 @@ private: getBaseType() throw (css::uno::RuntimeException) { return entity_->getDirectMandatoryBases().empty() ? css::uno::Reference< css::reflection::XTypeDescription >() - : manager_->resolve(entity_->getDirectMandatoryBases()[0]); + : resolve(context_, entity_->getDirectMandatoryBases()[0]); } virtual css::uno::Uik SAL_CALL getUik() throw (css::uno::RuntimeException) @@ -941,7 +811,7 @@ private: css::uno::Reference< css::reflection::XTypeDescription > > SAL_CALL getOptionalBaseTypes() throw (css::uno::RuntimeException); - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::InterfaceTypeEntity > entity_; }; @@ -962,12 +832,12 @@ InterfaceTypeDescription::getMembers() throw (css::uno::RuntimeException) { sal_Int32 off = BaseOffset(this).get(); for (sal_Int32 i = 0; i != n1; ++i) { s[i] = new AttributeDescription( - manager_, name_ + "::" + entity_->getDirectAttributes()[i].name, + context_, name_ + "::" + entity_->getDirectAttributes()[i].name, entity_->getDirectAttributes()[i], off + i); } for (sal_Int32 i = 0; i != n2; ++i) { s[n1 + i] = new MethodDescription( - manager_, name_ + "::" + entity_->getDirectMethods()[i].name, + context_, name_ + "::" + entity_->getDirectMethods()[i].name, entity_->getDirectMethods()[i], off + n1 + i); } return s; @@ -981,7 +851,7 @@ InterfaceTypeDescription::getBaseTypes() throw (css::uno::RuntimeException) { css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { - s[i] = manager_->resolve(entity_->getDirectMandatoryBases()[i]); + s[i] = resolve(context_, entity_->getDirectMandatoryBases()[i]); } return s; } @@ -996,17 +866,20 @@ InterfaceTypeDescription::getOptionalBaseTypes() css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { - s[i] = manager_->resolve(entity_->getDirectOptionalBases()[i]); + s[i] = resolve(context_, entity_->getDirectOptionalBases()[i]); } return s; } class ConstantDescription: - public cppu::WeakImplHelper1< css::reflection::XConstantTypeDescription > + public cppu::WeakImplHelper1< css::reflection::XConstantTypeDescription >, + private boost::noncopyable { public: - explicit ConstantDescription( - unoidl::ConstantGroupEntity::Member const & member); + ConstantDescription( + rtl::OUString const & name, css::uno::Any const & value): + name_(name), value_(value) + {} private: virtual ~ConstantDescription() {} @@ -1026,46 +899,6 @@ private: css::uno::Any value_; }; -ConstantDescription::ConstantDescription( - unoidl::ConstantGroupEntity::Member const & member): - name_(member.name) -{ - switch (member.value.type) { - case unoidl::ConstantValue::TYPE_BOOLEAN: - value_ <<= member.value.booleanValue; - break; - case unoidl::ConstantValue::TYPE_BYTE: - value_ <<= member.value.byteValue; - break; - case unoidl::ConstantValue::TYPE_SHORT: - value_ <<= member.value.shortValue; - break; - case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT: - value_ <<= member.value.unsignedShortValue; - break; - case unoidl::ConstantValue::TYPE_LONG: - value_ <<= member.value.longValue; - break; - case unoidl::ConstantValue::TYPE_UNSIGNED_LONG: - value_ <<= member.value.unsignedLongValue; - break; - case unoidl::ConstantValue::TYPE_HYPER: - value_ <<= member.value.hyperValue; - break; - case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER: - value_ <<= member.value.unsignedHyperValue; - break; - case unoidl::ConstantValue::TYPE_FLOAT: - value_ <<= member.value.floatValue; - break; - case unoidl::ConstantValue::TYPE_DOUBLE: - value_ <<= member.value.doubleValue; - break; - default: - for (;;) { std::abort(); } // this cannot happen - } -} - typedef cppu::ImplInheritanceHelper1< PublishableDescription, css::reflection::XConstantsTypeDescription > ConstantGroupDescription_Base; @@ -1073,10 +906,11 @@ ConstantGroupDescription_Base; class ConstantGroupDescription: public ConstantGroupDescription_Base { public: ConstantGroupDescription( + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::ConstantGroupEntity > const & entity): - ConstantGroupDescription_Base(entity->isPublished()), name_(name), - entity_(entity) + ConstantGroupDescription_Base(entity->isPublished()), context_(context), + name_(name), entity_(entity) { assert(entity.is()); } private: @@ -1094,6 +928,7 @@ private: css::uno::Reference< css::reflection::XConstantTypeDescription > > SAL_CALL getConstants() throw (css::uno::RuntimeException); + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::ConstantGroupEntity > entity_; }; @@ -1106,7 +941,10 @@ ConstantGroupDescription::getConstants() throw (css::uno::RuntimeException) { css::uno::Sequence< css::uno::Reference< css::reflection::XConstantTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { - s[i] = new ConstantDescription(entity_->getMembers()[i]); + //TODO: use entity_->getMembers()[i].value directly? + s[i].set( + resolve(context_, name_ + "." + entity_->getMembers()[i].name), + css::uno::UNO_QUERY_THROW); } return s; } @@ -1118,12 +956,12 @@ TypedefDescription_Base; class TypedefDescription: public TypedefDescription_Base { public: TypedefDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::TypedefEntity > const & entity): - TypedefDescription_Base(entity->isPublished()), manager_(manager), + TypedefDescription_Base(entity->isPublished()), context_(context), name_(name), entity_(entity) - { assert(manager.is()); assert(entity.is()); } + { assert(entity.is()); } private: virtual ~TypedefDescription() {} @@ -1137,24 +975,25 @@ private: virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL getReferencedType() throw (css::uno::RuntimeException) - { return manager_->resolve(entity_->getType()); } + { return resolve(context_, entity_->getType()); } - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::TypedefEntity > entity_; }; class ConstructorParameter: - public cppu::WeakImplHelper1< css::reflection::XParameter > + public cppu::WeakImplHelper1< css::reflection::XParameter >, + private boost::noncopyable { public: ConstructorParameter( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter const & parameter, sal_Int32 position): - manager_(manager), parameter_(parameter), position_(position) - { assert(manager.is()); } + context_(context), parameter_(parameter), position_(position) + {} private: virtual ~ConstructorParameter() {} @@ -1164,7 +1003,7 @@ private: virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL getType() throw (css::uno::RuntimeException) - { return manager_->resolve(parameter_.type); } + { return resolve(context_, parameter_.type); } virtual sal_Bool SAL_CALL isIn() throw (css::uno::RuntimeException) { return true; } @@ -1179,7 +1018,7 @@ private: throw (css::uno::RuntimeException) { return parameter_.rest; } - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter parameter_; sal_Int32 position_; @@ -1187,15 +1026,16 @@ private: class ConstructorDescription: public cppu::WeakImplHelper1< - css::reflection::XServiceConstructorDescription > + css::reflection::XServiceConstructorDescription >, + private boost::noncopyable { public: ConstructorDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, unoidl::SingleInterfaceBasedServiceEntity::Constructor const & constructor): - manager_(manager), constructor_(constructor) - { assert(manager.is()); } + context_(context), constructor_(constructor) + {} private: virtual ~ConstructorDescription() {} @@ -1217,7 +1057,7 @@ private: css::uno::Reference< css::reflection::XCompoundTypeDescription > > SAL_CALL getExceptions() throw (css::uno::RuntimeException); - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; unoidl::SingleInterfaceBasedServiceEntity::Constructor constructor_; }; @@ -1229,7 +1069,7 @@ ConstructorDescription::getParameters() throw (css::uno::RuntimeException) { n); for (sal_Int32 i = 0; i != n; ++i) { s[i] = new ConstructorParameter( - manager_, constructor_.parameters[i], i); + context_, constructor_.parameters[i], i); } return s; } @@ -1243,7 +1083,7 @@ ConstructorDescription::getExceptions() throw (css::uno::RuntimeException) { css::uno::Reference< css::reflection::XCompoundTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { s[i].set( - manager_->resolve(constructor_.exceptions[i]), + resolve(context_, constructor_.exceptions[i]), css::uno::UNO_QUERY_THROW); } return s; @@ -1258,13 +1098,13 @@ class SingleInterfaceBasedServiceDescription: { public: SingleInterfaceBasedServiceDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > const & entity): SingleInterfaceBasedServiceDescription_Base(entity->isPublished()), - manager_(manager), name_(name), entity_(entity) - { assert(manager.is()); assert(entity.is()); } + context_(context), name_(name), entity_(entity) + { assert(entity.is()); } private: virtual ~SingleInterfaceBasedServiceDescription() {} @@ -1330,14 +1170,14 @@ private: virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL getInterface() throw (css::uno::RuntimeException) - { return manager_->resolve(entity_->getBase()); } + { return resolve(context_, entity_->getBase()); } virtual css::uno::Sequence< css::uno::Reference< css::reflection::XServiceConstructorDescription > > SAL_CALL getConstructors() throw (css::uno::RuntimeException); - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > entity_; }; @@ -1354,20 +1194,21 @@ SingleInterfaceBasedServiceDescription::getConstructors() s(n); for (sal_Int32 i = 0; i != n; ++i) { s[i] = new ConstructorDescription( - manager_, entity_->getConstructors()[i]); + context_, entity_->getConstructors()[i]); } return s; } class PropertyDescription: - public cppu::WeakImplHelper1< css::reflection::XPropertyTypeDescription > + public cppu::WeakImplHelper1< css::reflection::XPropertyTypeDescription >, + private boost::noncopyable { public: PropertyDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, unoidl::AccumulationBasedServiceEntity::Property const & property): - manager_(manager), property_(property) - { assert(manager.is()); } + context_(context), property_(property) + {} private: virtual ~PropertyDescription() {} @@ -1385,9 +1226,9 @@ private: virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL getPropertyTypeDescription() throw (css::uno::RuntimeException) - { return manager_->resolve(property_.type); } + { return resolve(context_, property_.type); } - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; unoidl::AccumulationBasedServiceEntity::Property property_; }; @@ -1400,13 +1241,13 @@ class AccumulationBasedServiceDescription: { public: AccumulationBasedServiceDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::AccumulationBasedServiceEntity > const & entity): AccumulationBasedServiceDescription_Base(entity->isPublished()), - manager_(manager), name_(name), entity_(entity) - { assert(manager.is()); assert(entity.is()); } + context_(context), name_(name), entity_(entity) + { assert(entity.is()); } private: virtual ~AccumulationBasedServiceDescription() {} @@ -1461,7 +1302,7 @@ private: css::reflection::XServiceConstructorDescription > >(); } - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::AccumulationBasedServiceEntity > entity_; }; @@ -1478,7 +1319,7 @@ AccumulationBasedServiceDescription::getMandatoryServices() css::uno::Reference< css::reflection::XServiceTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { s[i].set( - manager_->resolve(entity_->getDirectMandatoryBaseServices()[i]), + resolve(context_, entity_->getDirectMandatoryBaseServices()[i]), css::uno::UNO_QUERY_THROW); } return s; @@ -1496,7 +1337,7 @@ AccumulationBasedServiceDescription::getOptionalServices() css::uno::Reference< css::reflection::XServiceTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { s[i].set( - manager_->resolve(entity_->getDirectOptionalBaseServices()[i]), + resolve(context_, entity_->getDirectOptionalBaseServices()[i]), css::uno::UNO_QUERY_THROW); } return s; @@ -1516,8 +1357,8 @@ AccumulationBasedServiceDescription::getMandatoryInterfaces() for (sal_Int32 i = 0; i != n; ++i) { s[i].set( resolveTypedefs( - manager_->find( - entity_->getDirectMandatoryBaseInterfaces()[i])), + resolve( + context_, entity_->getDirectMandatoryBaseInterfaces()[i])), css::uno::UNO_QUERY_THROW); } return s; @@ -1537,8 +1378,8 @@ AccumulationBasedServiceDescription::getOptionalInterfaces() for (sal_Int32 i = 0; i != n; ++i) { s[i].set( resolveTypedefs( - manager_->find( - entity_->getDirectOptionalBaseInterfaces()[i])), + resolve( + context_, entity_->getDirectOptionalBaseInterfaces()[i])), css::uno::UNO_QUERY_THROW); } return s; @@ -1556,7 +1397,7 @@ AccumulationBasedServiceDescription::getProperties() css::uno::Reference< css::reflection::XPropertyTypeDescription > > s(n); for (sal_Int32 i = 0; i != n; ++i) { s[i] = new PropertyDescription( - manager_, entity_->getDirectProperties()[i]); + context_, entity_->getDirectProperties()[i]); } return s; } @@ -1570,12 +1411,12 @@ class InterfaceBasedSingletonDescription: { public: InterfaceBasedSingletonDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::InterfaceBasedSingletonEntity > const & entity): InterfaceBasedSingletonDescription_Base(entity->isPublished()), - manager_(manager), name_(name), entity_(entity) - { assert(manager.is()); assert(entity.is()); } + context_(context), name_(name), entity_(entity) + { assert(entity.is()); } private: virtual ~InterfaceBasedSingletonDescription() {} @@ -1600,9 +1441,9 @@ private: virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL getInterface() throw (css::uno::RuntimeException) - { return manager_->resolve(entity_->getBase()); } + { return resolve(context_, entity_->getBase()); } - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::InterfaceBasedSingletonEntity > entity_; }; @@ -1616,12 +1457,12 @@ class ServiceBasedSingletonDescription: { public: ServiceBasedSingletonDescription( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & name, rtl::Reference< unoidl::ServiceBasedSingletonEntity > const & entity): ServiceBasedSingletonDescription_Base(entity_->isPublished()), - manager_(manager), name_(name), entity_(entity) - { assert(manager.is()); assert(entity.is()); } + context_(context), name_(name), entity_(entity) + { assert(entity.is()); } private: virtual ~ServiceBasedSingletonDescription() {} @@ -1637,7 +1478,7 @@ private: SAL_CALL getService() throw (css::uno::RuntimeException) { return css::uno::Reference< css::reflection::XServiceTypeDescription >( - manager_->resolve(entity_->getBase()), css::uno::UNO_QUERY_THROW); + resolve(context_, entity_->getBase()), css::uno::UNO_QUERY_THROW); } virtual sal_Bool SAL_CALL isInterfaceBased() @@ -1648,23 +1489,24 @@ private: SAL_CALL getInterface() throw (css::uno::RuntimeException) { return css::uno::Reference< css::reflection::XTypeDescription >(); } - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString name_; rtl::Reference< unoidl::ServiceBasedSingletonEntity > entity_; }; class Enumeration: - public cppu::WeakImplHelper1< css::reflection::XTypeDescriptionEnumeration > + public cppu::WeakImplHelper1< + css::reflection::XTypeDescriptionEnumeration >, + private boost::noncopyable { public: Enumeration( - rtl::Reference< cppuhelper::TypeManager > const & manager, + css::uno::Reference< css::uno::XComponentContext > const & context, rtl::OUString const & prefix, rtl::Reference< unoidl::MapCursor > const & cursor, css::uno::Sequence< css::uno::TypeClass > const & types, bool deep): - manager_(manager), types_(types), deep_(deep) + context_(context), types_(types), deep_(deep) { - assert(manager.is()); positions_.push(Position(prefix, cursor)); findNextMatch(); } @@ -1713,7 +1555,7 @@ private: constantGroupIndex; }; - rtl::Reference< cppuhelper::TypeManager > manager_; + css::uno::Reference< css::uno::XComponentContext > context_; css::uno::Sequence< css::uno::TypeClass > types_; bool deep_; @@ -1737,7 +1579,7 @@ Enumeration::nextTypeDescription() name = current_; findNextMatch(); } - return manager_->resolve(name); + return resolve(context_, name); } bool Enumeration::matches(css::uno::TypeClass tc) const { @@ -1843,259 +1685,324 @@ void Enumeration::findNextMatch() { } } -} +typedef cppu::WeakComponentImplHelper2< + css::container::XHierarchicalNameAccess, + css::reflection::XTypeDescriptionEnumerationAccess > +Provider_Base; -cppuhelper::TypeManager::TypeManager(rtl::OUString const & rdbUris): - TypeManager_Base(*static_cast< osl::Mutex * >(this)), - manager_(new unoidl::Manager) +class Provider: + private osl::Mutex, public Provider_Base, private boost::noncopyable { - readRdbs(rdbUris); -} +public: + // throws unoidl::FileFormatException, unoidl::NoSuchFileException: + Provider( + css::uno::Reference< css::uno::XComponentContext > const & context, + rtl::OUString const & uri): + Provider_Base(*static_cast< osl::Mutex * >(this)), context_(context), + provider_(new unoidl::UnoidlProvider(uri)) + {} -css::uno::Any cppuhelper::TypeManager::find(rtl::OUString const & name) { - //TODO: caching? (here or in unoidl::Manager?) - struct Simple { - char const * name; sal_Int32 length; - css::uno::TypeClass typeClass; - }; - static Simple const simple[] = { - { RTL_CONSTASCII_STRINGPARAM("void"), css::uno::TypeClass_VOID }, - { RTL_CONSTASCII_STRINGPARAM("boolean"), css::uno::TypeClass_BOOLEAN }, - { RTL_CONSTASCII_STRINGPARAM("byte"), css::uno::TypeClass_BYTE }, - { RTL_CONSTASCII_STRINGPARAM("short"), css::uno::TypeClass_SHORT }, - { RTL_CONSTASCII_STRINGPARAM("unsigned short"), - css::uno::TypeClass_UNSIGNED_SHORT }, - { RTL_CONSTASCII_STRINGPARAM("long"), css::uno::TypeClass_LONG }, - { RTL_CONSTASCII_STRINGPARAM("unsigned long"), - css::uno::TypeClass_UNSIGNED_LONG }, - { RTL_CONSTASCII_STRINGPARAM("hyper"), css::uno::TypeClass_HYPER }, - { RTL_CONSTASCII_STRINGPARAM("unsigned hyper"), - css::uno::TypeClass_UNSIGNED_HYPER }, - { RTL_CONSTASCII_STRINGPARAM("float"), css::uno::TypeClass_FLOAT }, - { RTL_CONSTASCII_STRINGPARAM("double"), css::uno::TypeClass_DOUBLE }, - { RTL_CONSTASCII_STRINGPARAM("char"), css::uno::TypeClass_CHAR }, - { RTL_CONSTASCII_STRINGPARAM("string"), css::uno::TypeClass_STRING }, - { RTL_CONSTASCII_STRINGPARAM("type"), css::uno::TypeClass_TYPE }, - { RTL_CONSTASCII_STRINGPARAM("any"), css::uno::TypeClass_ANY } }; - for (std::size_t i = 0; i != SAL_N_ELEMENTS(simple); ++i) { - if (name.equalsAsciiL(simple[i].name, simple[i].length)) { + using Provider_Base::acquire; + using Provider_Base::release; + +private: + virtual ~Provider() {} + + virtual void SAL_CALL disposing() {} //TODO + + virtual css::uno::Any SAL_CALL getByHierarchicalName( + rtl::OUString const & aName) + throw ( + css::container::NoSuchElementException, css::uno::RuntimeException); + + virtual sal_Bool SAL_CALL hasByHierarchicalName( + rtl::OUString const & aName) throw (css::uno::RuntimeException); + + virtual css::uno::Reference< css::reflection::XTypeDescriptionEnumeration > + SAL_CALL createTypeDescriptionEnumeration( + rtl::OUString const & moduleName, + css::uno::Sequence< css::uno::TypeClass > const & types, + css::reflection::TypeDescriptionSearchDepth depth) + throw( + css::reflection::NoSuchTypeNameException, + css::reflection::InvalidTypeNameException, + css::uno::RuntimeException); + + css::uno::Reference< css::uno::XComponentContext > context_; + rtl::Reference< unoidl::UnoidlProvider > provider_; +}; + +css::uno::Any Provider::getByHierarchicalName(rtl::OUString const & aName) + throw (css::container::NoSuchElementException, css::uno::RuntimeException) +{ + try { + bool cnst; + sal_uInt32 off = provider_->find(aName, &cnst); + if (off == 0) { + throw css::container::NoSuchElementException( + aName, static_cast< cppu::OWeakObject * >(this)); + } + if (cnst) { + unoidl::ConstantValue val1(provider_->getConstant(off)); + css::uno::Any val2; + switch (val1.type) { + case unoidl::ConstantValue::TYPE_BOOLEAN: + val2 <<= val1.booleanValue; + break; + case unoidl::ConstantValue::TYPE_BYTE: + val2 <<= val1.byteValue; + break; + case unoidl::ConstantValue::TYPE_SHORT: + val2 <<= val1.shortValue; + break; + case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT: + val2 <<= val1.unsignedShortValue; + break; + case unoidl::ConstantValue::TYPE_LONG: + val2 <<= val1.longValue; + break; + case unoidl::ConstantValue::TYPE_UNSIGNED_LONG: + val2 <<= val1.unsignedLongValue; + break; + case unoidl::ConstantValue::TYPE_HYPER: + val2 <<= val1.hyperValue; + break; + case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER: + val2 <<= val1.unsignedHyperValue; + break; + case unoidl::ConstantValue::TYPE_FLOAT: + val2 <<= val1.floatValue; + break; + case unoidl::ConstantValue::TYPE_DOUBLE: + val2 <<= val1.doubleValue; + break; + default: + for (;;) { std::abort(); } // this cannot happen + } return css::uno::makeAny< css::uno::Reference< css::reflection::XTypeDescription > >( - new SimpleTypeDescription(simple[i].typeClass, name)); - } - } - if (name.match("[]")) { - return getSequenceType(name); - } - sal_Int32 i = name.indexOf('<'); - if (i != -1) { - return getInstantiatedStruct(name, i); - } - i = name.indexOf("::"); - if (i != -1) { - return getInterfaceMember(name, i); - } - rtl::Reference< unoidl::Entity > ent(findEntity(name)); - if (ent.is()) { - return getNamed(name, ent); - } - i = name.lastIndexOf('.'); - if (i != -1) { - ent = findEntity(name.copy(0, i)); - if (ent.is()) { + new ConstantDescription(aName, val2)); + } else { + rtl::Reference< unoidl::Entity > ent(provider_->getEntity(off)); switch (ent->getSort()) { + case unoidl::Entity::SORT_MODULE: + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new ModuleDescription( + context_, aName, + static_cast< unoidl::ModuleEntity * >(ent.get()))); case unoidl::Entity::SORT_ENUM_TYPE: - return getEnumMember( - static_cast< unoidl::EnumTypeEntity * >(ent.get()), - name.copy(i + 1)); + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new EnumTypeDescription( + aName, + static_cast< unoidl::EnumTypeEntity * >( + ent.get()))); + case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE: + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new PlainStructTypeDescription( + context_, aName, + static_cast< unoidl::PlainStructTypeEntity * >( + ent.get()))); + case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE: + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new PolymorphicStructTypeTemplateDescription( + context_, aName, + static_cast< + unoidl::PolymorphicStructTypeTemplateEntity * >( + ent.get()))); + case unoidl::Entity::SORT_EXCEPTION_TYPE: + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new ExceptionTypeDescription( + context_, aName, + static_cast< unoidl::ExceptionTypeEntity * >( + ent.get()))); + case unoidl::Entity::SORT_INTERFACE_TYPE: + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new InterfaceTypeDescription( + context_, aName, + static_cast< unoidl::InterfaceTypeEntity * >( + ent.get()))); + case unoidl::Entity::SORT_TYPEDEF: + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new TypedefDescription( + context_, aName, + static_cast< unoidl::TypedefEntity * >(ent.get()))); case unoidl::Entity::SORT_CONSTANT_GROUP: - return getConstant( - static_cast< unoidl::ConstantGroupEntity * >(ent.get()), - name.copy(i + 1)); + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new ConstantGroupDescription( + context_, aName, + static_cast< unoidl::ConstantGroupEntity * >( + ent.get()))); + case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE: + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new SingleInterfaceBasedServiceDescription( + context_, aName, + static_cast< + unoidl::SingleInterfaceBasedServiceEntity * >( + ent.get()))); + case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE: + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new AccumulationBasedServiceDescription( + context_, aName, + static_cast< + unoidl::AccumulationBasedServiceEntity * >( + ent.get()))); + case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON: + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new InterfaceBasedSingletonDescription( + context_, aName, + static_cast< + unoidl::InterfaceBasedSingletonEntity * >( + ent.get()))); + case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON: + return css::uno::makeAny< + css::uno::Reference< css::reflection::XTypeDescription > >( + new ServiceBasedSingletonDescription( + context_, aName, + static_cast< + unoidl::ServiceBasedSingletonEntity * >( + ent.get()))); default: - break; + for (;;) { std::abort(); } // this cannot happen } } - } - return css::uno::Any(); -} - -css::uno::Reference< css::reflection::XTypeDescription > -cppuhelper::TypeManager::resolve(rtl::OUString const & name) { - css::uno::Reference< css::reflection::XTypeDescription > desc( - find(name), css::uno::UNO_QUERY); - if (!desc.is()) { + } catch (unoidl::FileFormatException & e) { throw css::uno::DeploymentException( - "cannot resolve type \"" + name + "\"", + e.getUri() + ": " + e.getDetail(), static_cast< cppu::OWeakObject * >(this)); } - return desc; } -cppuhelper::TypeManager::~TypeManager() throw () {} - -void cppuhelper::TypeManager::disposing() {} //TODO - -rtl::OUString cppuhelper::TypeManager::getImplementationName() - throw (css::uno::RuntimeException) -{ - return rtl::OUString( - "com.sun.star.comp.cppuhelper.bootstrap.TypeManager"); -} - -sal_Bool cppuhelper::TypeManager::supportsService( - rtl::OUString const & ServiceName) - throw (css::uno::RuntimeException) -{ - return cppu::supportsService(this, ServiceName); -} - -css::uno::Sequence< rtl::OUString > -cppuhelper::TypeManager::getSupportedServiceNames() - throw (css::uno::RuntimeException) -{ - css::uno::Sequence< rtl::OUString > names(1); - names[0] = "com.sun.star.reflection.TypeDescriptionManager"; //TODO - return names; -} - -css::uno::Any cppuhelper::TypeManager::getByHierarchicalName( - rtl::OUString const & aName) - throw (css::container::NoSuchElementException, css::uno::RuntimeException) -{ - css::uno::Any desc(find(aName)); - if (!desc.hasValue()) { - throw css::container::NoSuchElementException( - aName, static_cast< cppu::OWeakObject * >(this)); - } - return desc; -} - -sal_Bool cppuhelper::TypeManager::hasByHierarchicalName( - rtl::OUString const & aName) - throw (css::uno::RuntimeException) -{ - return find(aName).hasValue(); -} - -css::uno::Type cppuhelper::TypeManager::getElementType() - throw (css::uno::RuntimeException) -{ - return cppu::UnoType< rtl::OUString >::get(); -} - -sal_Bool cppuhelper::TypeManager::hasElements() - throw (css::uno::RuntimeException) -{ - throw css::uno::RuntimeException( - "TypeManager hasElements: method not supported", - static_cast< cppu::OWeakObject * >(this)); -} - -css::uno::Reference< css::container::XEnumeration > -cppuhelper::TypeManager::createEnumeration() - throw (css::uno::RuntimeException) +sal_Bool Provider::hasByHierarchicalName( + rtl::OUString const & aName) throw (css::uno::RuntimeException) { - throw css::uno::RuntimeException( - "TypeManager createEnumeration: method not supported", - static_cast< cppu::OWeakObject * >(this)); -} - -sal_Bool cppuhelper::TypeManager::has(css::uno::Any const &) - throw (css::uno::RuntimeException) -{ - throw css::uno::RuntimeException( - "TypeManager has: method not supported", - static_cast< cppu::OWeakObject * >(this)); -} - -void cppuhelper::TypeManager::insert(css::uno::Any const & aElement) - throw ( - css::lang::IllegalArgumentException, - css::container::ElementExistException, css::uno::RuntimeException) -{ - rtl::OUString uri; - if (!(aElement >>= uri)) { - throw css::lang::IllegalArgumentException( - ("css.uno.theTypeDescriptionManager.insert expects a string URI" - " argument"), - static_cast< cppu::OWeakObject * >(this), 0); - } - //TODO: check for ElementExistException - //TODO: check for consistency with existing data - readRdbFile(uri, false); -} - -void cppuhelper::TypeManager::remove(css::uno::Any const & aElement) - throw ( - css::lang::IllegalArgumentException, - css::container::NoSuchElementException, css::uno::RuntimeException) -{ - rtl::OUString uri; - if (!(aElement >>= uri)) { - throw css::lang::IllegalArgumentException( - ("css.uno.theTypeDescriptionManager.remove expects a string URI" - " argument"), - static_cast< cppu::OWeakObject * >(this), 0); + try { + return provider_->find(aName) != 0; + } catch (unoidl::FileFormatException & e) { + throw css::uno::DeploymentException( + e.getUri() + ": " + e.getDetail(), + static_cast< cppu::OWeakObject * >(this)); } - //TODO: remove requests are silently ignored for now } css::uno::Reference< css::reflection::XTypeDescriptionEnumeration > -cppuhelper::TypeManager::createTypeDescriptionEnumeration( +Provider::createTypeDescriptionEnumeration( rtl::OUString const & moduleName, css::uno::Sequence< css::uno::TypeClass > const & types, css::reflection::TypeDescriptionSearchDepth depth) - throw ( + throw( css::reflection::NoSuchTypeNameException, - css::reflection::InvalidTypeNameException, - css::uno::RuntimeException) + css::reflection::InvalidTypeNameException, css::uno::RuntimeException) { - //TODO: This fails for modules spread across multiple providers, esp. for - // the empty moduleName - rtl::Reference< unoidl::Entity > ent(findEntity(moduleName)); - if (!ent.is()) { - throw css::reflection::NoSuchTypeNameException( - moduleName, static_cast< cppu::OWeakObject * >(this)); - } - if (ent->getSort() != unoidl::Entity::SORT_MODULE) { - throw css::reflection::InvalidTypeNameException( - moduleName, static_cast< cppu::OWeakObject * >(this)); - } - rtl::Reference< unoidl::MapCursor > cursor; try { - cursor = static_cast< unoidl::ModuleEntity * >(ent.get())-> - createCursor(); + rtl::OUString prefix; + rtl::Reference< unoidl::MapCursor > cursor; + if (moduleName.isEmpty()) { + cursor = provider_->createRootCursor(); + } else { + prefix = moduleName + "."; + bool cnst; + sal_uInt32 off = provider_->find(moduleName, &cnst); + if (off == 0) { + throw css::reflection::NoSuchTypeNameException( + moduleName, static_cast< cppu::OWeakObject * >(this)); + } + if (cnst) { + throw css::reflection::InvalidTypeNameException( + moduleName, static_cast< cppu::OWeakObject * >(this)); + } + rtl::Reference< unoidl::Entity > ent(provider_->getEntity(off)); + if (ent->getSort() != unoidl::Entity::SORT_MODULE) { + throw css::reflection::InvalidTypeNameException( + moduleName, static_cast< cppu::OWeakObject * >(this)); + } + cursor = static_cast< unoidl::ModuleEntity * >(ent.get())-> + createCursor(); + } + return new Enumeration( + context_, prefix, cursor, types, + depth == css::reflection::TypeDescriptionSearchDepth_INFINITE); } catch (unoidl::FileFormatException & e) { throw css::uno::DeploymentException( - ("unoidl::FileFormatException for <" + e.getUri() + ">: " - + e.getDetail()), + e.getUri() + ": " + e.getDetail(), static_cast< cppu::OWeakObject * >(this)); } - return new Enumeration( - this, moduleName + ".", cursor, types, - depth == css::reflection::TypeDescriptionSearchDepth_INFINITE); } -void cppuhelper::TypeManager::readRdbs(rtl::OUString const & uris) { - for (sal_Int32 i = 0; i != -1;) { - rtl::OUString uri(uris.getToken(0, ' ', i)); - if (uri.isEmpty()) { - continue; - } - bool optional; - bool directory; - cppu::decodeRdbUri(&uri, &optional, &directory); - if (directory) { - readRdbDirectory(uri, optional); - } else { - readRdbFile(uri, optional); +css::uno::Reference< css::container::XHierarchicalNameAccess > +readLegacyRdbFile( + rtl::OUString const & uri, + css::uno::Reference< css::lang::XMultiComponentFactory > const & + serviceManager, + css::uno::Reference< css::uno::XComponentContext > const & context) +{ + assert(serviceManager.is()); + css::uno::Reference< css::registry::XSimpleRegistry > reg( + serviceManager->createInstanceWithContext( + "com.sun.star.comp.stoc.SimpleRegistry", context), + css::uno::UNO_QUERY_THROW); + try { + reg->open(uri, true, false); + } catch (css::registry::InvalidRegistryException & e) { + 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; + return css::uno::Reference< css::container::XHierarchicalNameAccess >( + serviceManager->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider", arg, + context), + css::uno::UNO_QUERY_THROW); +} + +void readRdbFile( + rtl::OUString const & uri, bool optional, + css::uno::Reference< css::lang::XMultiComponentFactory > const & + serviceManager, + css::uno::Reference< css::uno::XComponentContext > const & context, + std::vector< + css::uno::Reference< css::container::XHierarchicalNameAccess > > * + providers) +{ + assert(providers != 0); + css::uno::Reference< css::container::XHierarchicalNameAccess > prov; + try { + prov = new Provider(context, uri); + } catch (unoidl::NoSuchFileException &) { + if (optional) { + SAL_INFO("cppuhelper", "Ignored optional " << uri); + return; } + throw css::uno::DeploymentException( + uri + ": no such file", + css::uno::Reference< css::uno::XInterface >()); + } catch (unoidl::FileFormatException &) { + prov = readLegacyRdbFile(uri, serviceManager, context); } + assert(prov.is()); + providers->push_back(prov); } -void cppuhelper::TypeManager::readRdbDirectory( - rtl::OUString const & uri, bool optional) +void readRdbDirectory( + rtl::OUString const & uri, bool optional, + css::uno::Reference< css::lang::XMultiComponentFactory > const & + serviceManager, + css::uno::Reference< css::uno::XComponentContext > const & context, + std::vector< + css::uno::Reference< css::container::XHierarchicalNameAccess > > * + providers) { osl::Directory dir(uri); switch (dir.open()) { @@ -2110,258 +2017,54 @@ void cppuhelper::TypeManager::readRdbDirectory( default: throw css::uno::DeploymentException( "Cannot open directory " + uri, - static_cast< cppu::OWeakObject * >(this)); + css::uno::Reference< css::uno::XInterface >()); } for (;;) { - rtl::OUString url; - if (!cppu::nextDirectoryItem(dir, &url)) { + rtl::OUString fileUri; + if (!cppu::nextDirectoryItem(dir, &fileUri)) { break; } - readRdbFile(url, false); + readRdbFile(fileUri, optional, serviceManager, context, providers); } } -void cppuhelper::TypeManager::readRdbFile( - rtl::OUString const & uri, bool optional) -{ - rtl::Reference< unoidl::Provider > prov; - try { - prov = unoidl::loadProvider(manager_, uri); - } catch (unoidl::NoSuchFileException &) { - if (!optional) { - throw css::uno::DeploymentException( - uri + ": no such file", - static_cast< cppu::OWeakObject * >(this)); - } - SAL_INFO("cppuhelper", "Ignored optional " << uri); - } catch (unoidl::FileFormatException & e) { - throw css::uno::DeploymentException( - ("unoidl::FileFormatException for <" + e.getUri() + ">: " - + e.getDetail()), - static_cast< cppu::OWeakObject * >(this)); - } - manager_->addProvider(prov); } -css::uno::Any cppuhelper::TypeManager::getSequenceType( - rtl::OUString const & name) -{ - assert(name.match("[]")); - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new SequenceTypeDescription( - this, name, name.copy(std::strlen("[]")))); -} - -css::uno::Any cppuhelper::TypeManager::getInstantiatedStruct( - rtl::OUString const & name, sal_Int32 separator) -{ - assert(name.indexOf('<') == separator && separator != -1); - rtl::Reference< unoidl::Entity > ent(findEntity(name.copy(0, separator))); - if (!ent.is() - || (ent->getSort() - != unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)) - { - return css::uno::Any(); - } - rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > ent2( - static_cast< unoidl::PolymorphicStructTypeTemplateEntity * >( - ent.get())); - std::vector< rtl::OUString > args; - sal_Int32 i = separator; - do { - ++i; // skip '<' or ',' - sal_Int32 j = i; - for (sal_Int32 level = 0; j != name.getLength(); ++j) { - sal_Unicode c = name[j]; - if (c == ',') { - if (level == 0) { - break; - } - } else if (c == '<') { - ++level; - } else if (c == '>') { - if (level == 0) { - break; - } - --level; - } +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) +{ + 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()) { + continue; } - if (j != name.getLength()) { - args.push_back(name.copy(i, j - i)); + bool optional; + bool directory; + cppu::decodeRdbUri(&uri, &optional, &directory); + if (directory) { + readRdbDirectory(uri, optional, serviceManager, context, &provs); + } else { + readRdbFile(uri, optional, serviceManager, context, &provs); } - i = j; - } while (i != name.getLength() && name[i] != '>'); - if (i != name.getLength() - 1 || name[i] != '>' - || args.size() != ent2->getTypeParameters().size()) - { - return css::uno::Any(); } - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new InstantiatedPolymorphicStructTypeDescription( - this, name, ent2, args)); -} - -css::uno::Any cppuhelper::TypeManager::getInterfaceMember( - rtl::OUString const & name, sal_Int32 separator) -{ - assert(name.indexOf("::") == separator && separator != -1); - css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > ifc( - resolveTypedefs(find(name.copy(0, separator))), css::uno::UNO_QUERY); - if (!ifc.is()) { - return css::uno::Any(); - } - rtl::OUString member(name.copy(separator + std::strlen("::"))); 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::reflection::XInterfaceMemberTypeDescription > > mems( - ifc->getMembers()); - for (sal_Int32 i = 0; i != mems.getLength(); ++i) { - if (mems[i]->getMemberName() == member) { - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - mems[i].get()); - } - } - return css::uno::Any(); -} - -css::uno::Any cppuhelper::TypeManager::getNamed( - rtl::OUString const & name, rtl::Reference< unoidl::Entity > entity) -{ - assert(entity.is()); - switch (entity->getSort()) { - case unoidl::Entity::SORT_MODULE: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new ModuleDescription( - this, name, - static_cast< unoidl::ModuleEntity * >(entity.get()))); - case unoidl::Entity::SORT_ENUM_TYPE: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new EnumTypeDescription( - name, - static_cast< unoidl::EnumTypeEntity * >(entity.get()))); - case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new PlainStructTypeDescription( - this, name, - static_cast< unoidl::PlainStructTypeEntity * >( - entity.get()))); - case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new PolymorphicStructTypeTemplateDescription( - this, name, - static_cast< - unoidl::PolymorphicStructTypeTemplateEntity * >( - entity.get()))); - case unoidl::Entity::SORT_EXCEPTION_TYPE: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new ExceptionTypeDescription( - this, name, - static_cast< unoidl::ExceptionTypeEntity * >( - entity.get()))); - case unoidl::Entity::SORT_INTERFACE_TYPE: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new InterfaceTypeDescription( - this, name, - static_cast< unoidl::InterfaceTypeEntity * >( - entity.get()))); - case unoidl::Entity::SORT_TYPEDEF: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new TypedefDescription( - this, name, - static_cast< unoidl::TypedefEntity * >(entity.get()))); - case unoidl::Entity::SORT_CONSTANT_GROUP: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new ConstantGroupDescription( - name, - static_cast< unoidl::ConstantGroupEntity * >( - entity.get()))); - case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new SingleInterfaceBasedServiceDescription( - this, name, - static_cast< unoidl::SingleInterfaceBasedServiceEntity * >( - entity.get()))); - case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new AccumulationBasedServiceDescription( - this, name, - static_cast< unoidl::AccumulationBasedServiceEntity * >( - entity.get()))); - case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new InterfaceBasedSingletonDescription( - this, name, - static_cast< unoidl::InterfaceBasedSingletonEntity * >( - entity.get()))); - case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON: - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new ServiceBasedSingletonDescription( - this, name, - static_cast< unoidl::ServiceBasedSingletonEntity * >( - entity.get()))); - default: - for (;;) { std::abort(); } // this cannot happen - } -} - -css::uno::Any cppuhelper::TypeManager::getEnumMember( - rtl::Reference< unoidl::EnumTypeEntity > entity, - rtl::OUString const & member) -{ - for (std::vector< unoidl::EnumTypeEntity::Member >::const_iterator i( - entity->getMembers().begin()); - i != entity->getMembers().end(); ++i) - { - if (i->name == member) { - return css::uno::makeAny(i->value); - } - } - return css::uno::Any(); -} - -css::uno::Any cppuhelper::TypeManager::getConstant( - rtl::Reference< unoidl::ConstantGroupEntity > entity, - rtl::OUString const & member) -{ - for (std::vector< unoidl::ConstantGroupEntity::Member >::const_iterator i( - entity->getMembers().begin()); - i != entity->getMembers().end(); ++i) - { - if (i->name == member) { - return css::uno::makeAny< - css::uno::Reference< css::reflection::XTypeDescription > >( - new ConstantDescription(*i)); - } - } - return css::uno::Any(); -} - -rtl::Reference< unoidl::Entity > cppuhelper::TypeManager::findEntity( - rtl::OUString const & name) -{ - try { - return manager_->findEntity(name); - } catch (unoidl::FileFormatException & e) { - throw css::uno::DeploymentException( - ("unoidl::FileFormatException for <" + e.getUri() + ">: " - + e.getDetail()), - static_cast< cppu::OWeakObject * >(this)); + css::container::XHierarchicalNameAccess > >::iterator i( + provs.begin()); + for (sal_Int32 j = 0; j != provs2.getLength(); ++j) { + provs2[j] = *i++; } + return provs2; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cppuhelper/source/typedescriptionprovider.hxx b/cppuhelper/source/typedescriptionprovider.hxx new file mode 100644 index 000000000000..93336e8982f6 --- /dev/null +++ b/cppuhelper/source/typedescriptionprovider.hxx @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_CPPUHELPER_SOURCE_TYPEDESCRIPTIONPROVIDER_HXX +#define INCLUDED_CPPUHELPER_SOURCE_TYPEDESCRIPTIONPROVIDER_HXX + +#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; } +} } } +namespace rtl { class OUString; } + +namespace cppuhelper { + +css::uno::Sequence< + css::uno::Reference< css::container::XHierarchicalNameAccess > > +createTypeDescriptionProviders( + rtl::OUString const & uris, + css::uno::Reference< css::lang::XMultiComponentFactory > const & + serviceManager, + css::uno::Reference< css::uno::XComponentContext > const & context); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cppuhelper/source/typemanager.hxx b/cppuhelper/source/typemanager.hxx deleted file mode 100644 index a84a2319f3a0..000000000000 --- a/cppuhelper/source/typemanager.hxx +++ /dev/null @@ -1,151 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#ifndef INCLUDED_CPPUHELPER_SOURCE_TYPEMANAGER_HXX -#define INCLUDED_CPPUHELPER_SOURCE_TYPEMANAGER_HXX - -#include "sal/config.h" - -#include "com/sun/star/container/ElementExistException.hpp" -#include "com/sun/star/container/NoSuchElementException.hpp" -#include "com/sun/star/container/XHierarchicalNameAccess.hpp" -#include "com/sun/star/container/XSet.hpp" -#include "com/sun/star/lang/IllegalArgumentException.hpp" -#include "com/sun/star/lang/XServiceInfo.hpp" -#include "com/sun/star/reflection/InvalidTypeNameException.hpp" -#include "com/sun/star/reflection/NoSuchTypeNameException.hpp" -#include "com/sun/star/reflection/TypeDescriptionSearchDepth.hpp" -#include "com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp" -#include "com/sun/star/uno/Reference.hxx" -#include "com/sun/star/uno/RuntimeException.hpp" -#include "com/sun/star/uno/Sequence.hxx" -#include "cppuhelper/compbase4.hxx" -#include "osl/mutex.hxx" -#include "rtl/ref.hxx" -#include "sal/types.h" - -namespace com { namespace sun { namespace star { - namespace uno { class Any; } - namespace reflection { class XTypeDescription; } -} } } -namespace rtl { class OUString; } -namespace unoidl { - class ConstantGroupEntity; - class Entity; - class EnumTypeEntity; - class Manager; -} - -namespace cppuhelper { - -typedef cppu::WeakComponentImplHelper4< - css::lang::XServiceInfo, css::container::XHierarchicalNameAccess, - css::container::XSet, css::reflection::XTypeDescriptionEnumerationAccess > -TypeManager_Base; - -class TypeManager: private osl::Mutex, public TypeManager_Base { -public: - explicit TypeManager(rtl::OUString const & rdbUris); - - using TypeManager_Base::acquire; - using TypeManager_Base::release; - - css::uno::Any find(rtl::OUString const & name); - - css::uno::Reference< css::reflection::XTypeDescription > resolve( - rtl::OUString const & name); - -private: - virtual ~TypeManager() throw (); - - virtual void SAL_CALL disposing(); - - virtual rtl::OUString SAL_CALL getImplementationName() - throw (css::uno::RuntimeException); - - virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName) - throw (css::uno::RuntimeException); - - virtual css::uno::Sequence< rtl::OUString > SAL_CALL - getSupportedServiceNames() throw (css::uno::RuntimeException); - - virtual css::uno::Any SAL_CALL getByHierarchicalName( - rtl::OUString const & aName) - throw ( - css::container::NoSuchElementException, css::uno::RuntimeException); - - virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName) - throw (css::uno::RuntimeException); - - virtual css::uno::Type SAL_CALL getElementType() - throw (css::uno::RuntimeException); - - virtual sal_Bool SAL_CALL hasElements() throw (css::uno::RuntimeException); - - virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL - createEnumeration() throw (css::uno::RuntimeException); - - virtual sal_Bool SAL_CALL has(css::uno::Any const & aElement) - throw (css::uno::RuntimeException); - - virtual void SAL_CALL insert(css::uno::Any const & aElement) - throw ( - css::lang::IllegalArgumentException, - css::container::ElementExistException, css::uno::RuntimeException); - - virtual void SAL_CALL remove(css::uno::Any const & aElement) - throw ( - css::lang::IllegalArgumentException, - css::container::NoSuchElementException, css::uno::RuntimeException); - - virtual css::uno::Reference< css::reflection::XTypeDescriptionEnumeration > - SAL_CALL createTypeDescriptionEnumeration( - rtl::OUString const & moduleName, - css::uno::Sequence< css::uno::TypeClass > const & types, - css::reflection::TypeDescriptionSearchDepth depth) - throw ( - css::reflection::NoSuchTypeNameException, - css::reflection::InvalidTypeNameException, - css::uno::RuntimeException); - - void readRdbs(rtl::OUString const & uris); - - void readRdbDirectory(rtl::OUString const & uri, bool optional); - - void readRdbFile(rtl::OUString const & uri, bool optional); - - css::uno::Any getSequenceType(rtl::OUString const & name); - - css::uno::Any getInstantiatedStruct( - rtl::OUString const & name, sal_Int32 separator); - - css::uno::Any getInterfaceMember( - rtl::OUString const & name, sal_Int32 separator); - - css::uno::Any getNamed( - rtl::OUString const & name, rtl::Reference< unoidl::Entity > entity); - - css::uno::Any getEnumMember( - rtl::Reference< unoidl::EnumTypeEntity > entity, - rtl::OUString const & member); - - css::uno::Any getConstant( - rtl::Reference< unoidl::ConstantGroupEntity > entity, - rtl::OUString const & member); - - rtl::Reference< unoidl::Entity > findEntity(rtl::OUString const & name); - - rtl::Reference< unoidl::Manager > manager_; -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/source/deployment/registry/component/dp_component.cxx b/desktop/source/deployment/registry/component/dp_component.cxx index 4fd9f495ce35..991c5782c214 100644 --- a/desktop/source/deployment/registry/component/dp_component.cxx +++ b/desktop/source/deployment/registry/component/dp_component.cxx @@ -35,6 +35,7 @@ #include "svl/inettype.hxx" #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp" #include "com/sun/star/container/XNameContainer.hpp" +#include "com/sun/star/container/XHierarchicalNameAccess.hpp" #include "com/sun/star/container/XSet.hpp" #include "com/sun/star/registry/XSimpleRegistry.hpp" #include "com/sun/star/registry/XImplementationRegistration.hpp" @@ -183,6 +184,7 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend BackendImpl * getMyBackend() const; const bool m_jarFile; + Reference<container::XHierarchicalNameAccess> m_xTDprov; virtual void SAL_CALL disposing(); @@ -399,6 +401,7 @@ void BackendImpl::ComponentPackageImpl::disposing() //______________________________________________________________________________ void BackendImpl::TypelibraryPackageImpl::disposing() { + m_xTDprov.clear(); Package::disposing(); } @@ -1530,12 +1533,37 @@ void BackendImpl::TypelibraryPackageImpl::processPackage_( } else // RDB: { - css::uno::Reference< css::container::XSet >( - that->getComponentContext()->getValueByName( - "/singletons" - "/com.sun.star.reflection.theTypeDescriptionManager"), - css::uno::UNO_QUERY_THROW)->insert( - css::uno::makeAny(expandUnoRcUrl(url))); + Reference<XComponentContext> const & xContext = + that->getComponentContext(); + if (! m_xTDprov.is()) + { + m_xTDprov.set( that->getObject( url ), UNO_QUERY ); + if (! m_xTDprov.is()) + { + const Reference<registry::XSimpleRegistry> xReg( + xContext->getServiceManager() + ->createInstanceWithContext("com.sun.star.registry.SimpleRegistry", + xContext ), UNO_QUERY_THROW ); + xReg->open( expandUnoRcUrl(url), + true /* read-only */, false /* ! create */ ); + const Any arg(xReg); + Reference<container::XHierarchicalNameAccess> xTDprov( + xContext->getServiceManager() + ->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider", + Sequence<Any>( &arg, 1 ), xContext ), UNO_QUERY ); + OSL_ASSERT( xTDprov.is() ); + if (xTDprov.is()) + m_xTDprov.set( that->insertObject( url, xTDprov ), + UNO_QUERY_THROW ); + } + } + if (m_xTDprov.is()) { + Reference<container::XSet> xSet( + xContext->getValueByName( "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ), + UNO_QUERY_THROW ); + xSet->insert( Any(m_xTDprov) ); + } } that->addToUnoRc( m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, @@ -1547,13 +1575,18 @@ void BackendImpl::TypelibraryPackageImpl::processPackage_( m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, url, xCmdEnv ); // revoking types at runtime, possible, sensible? - if (!m_jarFile) { - css::uno::Reference< css::container::XSet >( + if (!m_xTDprov.is()) + m_xTDprov.set( that->getObject( url ), UNO_QUERY ); + if (m_xTDprov.is()) { + // remove live: + const Reference<container::XSet> xSet( that->getComponentContext()->getValueByName( - "/singletons" - "/com.sun.star.reflection.theTypeDescriptionManager"), - css::uno::UNO_QUERY_THROW)->remove( - css::uno::makeAny(expandUnoRcUrl(url))); + "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ), + UNO_QUERY_THROW ); + xSet->remove( Any(m_xTDprov) ); + + that->releaseObject( url ); + m_xTDprov.clear(); } } } diff --git a/stoc/Library_bootstrap.mk b/stoc/Library_bootstrap.mk index ab97a98d56fb..01e086b4c1c9 100644 --- a/stoc/Library_bootstrap.mk +++ b/stoc/Library_bootstrap.mk @@ -85,6 +85,9 @@ $(eval $(call gb_Library_add_exception_objects,bootstrap,\ stoc/source/security/permissions \ stoc/source/servicemanager/servicemanager \ stoc/source/simpleregistry/simpleregistry \ + stoc/source/tdmanager/tdmgr \ + stoc/source/tdmanager/tdmgr_check \ + stoc/source/tdmanager/tdmgr_tdenumeration \ )) # vim:set noet sw=4 ts=4: diff --git a/stoc/inc/bootstrapservices.hxx b/stoc/inc/bootstrapservices.hxx index f476b3e19e0c..fb25ade9cc93 100644 --- a/stoc/inc/bootstrapservices.hxx +++ b/stoc/inc/bootstrapservices.hxx @@ -91,6 +91,13 @@ namespace stoc_bootstrap throw(::com::sun::star::uno::Exception); ::com::sun::star::uno::Sequence< ::rtl::OUString > rdbtdp_getSupportedServiceNames(); ::rtl::OUString rdbtdp_getImplementationName(); + + //tdmanager + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL ManagerImpl_create( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& ) + SAL_THROW( (::com::sun::star::uno::Exception) ); + ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL tdmgr_getSupportedServiceNames(); + ::rtl::OUString SAL_CALL tdmgr_getImplementationName(); } // namespace /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/source/bootstrap/services.cxx b/stoc/source/bootstrap/services.cxx index 25fef5a2b1df..56bcd1c87e33 100644 --- a/stoc/source/bootstrap/services.cxx +++ b/stoc/source/bootstrap/services.cxx @@ -96,6 +96,12 @@ static struct ImplementationEntry g_entries[] = rdbtdp_getSupportedServiceNames, createSingleComponentFactory, &g_moduleCount.modCnt , 0 }, + //tdmanager + { + ManagerImpl_create, tdmgr_getImplementationName, + tdmgr_getSupportedServiceNames, createSingleComponentFactory, + &g_moduleCount.modCnt , 0 + }, //end { 0, 0, 0, 0, 0, 0 } }; diff --git a/stoc/source/tdmanager/lrucache.hxx b/stoc/source/tdmanager/lrucache.hxx new file mode 100644 index 000000000000..b7a6895a5808 --- /dev/null +++ b/stoc/source/tdmanager/lrucache.hxx @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef _LRU_CACHE_HXX_ +#define _LRU_CACHE_HXX_ + +// __CACHE_DIAGNOSE forces cache size to 4 and works only for OUString keys +// #define __CACHE_DIAGNOSE 1 + +#include <osl/mutex.hxx> +#include "rtl/ustring.hxx" +#include "sal/log.hxx" + +#include <boost/unordered_map.hpp> + + +/** Implementation of a least recently used (lru) cache. + <br> + @author Daniel Boelzle +*/ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +class LRU_Cache +{ + struct CacheEntry + { + t_Key aKey; + t_Val aVal; + CacheEntry * pPred; + CacheEntry * pSucc; + }; + typedef ::boost::unordered_map< t_Key, CacheEntry *, t_KeyHash, t_KeyEqual > t_Key2Element; + + mutable ::osl::Mutex _aCacheMutex; + sal_Int32 _nCachedElements; + t_Key2Element _aKey2Element; + + CacheEntry * _pBlock; + mutable CacheEntry * _pHead; + mutable CacheEntry * _pTail; + inline void toFront( CacheEntry * pEntry ) const; + +public: + /** Constructor: + <br> + @param nCachedElements number of elements to be cached; default param set to 128 + */ + inline LRU_Cache( sal_Int32 nCachedElements = 128 ); + /** Destructor: releases all cached elements and keys. + <br> + */ + inline ~LRU_Cache(); + + /** Retrieves a value from the cache. Returns default constructed value, + if none was found. + <br> + @param rKey a key + @return value + */ + inline t_Val getValue( t_Key const & rKey ) const; + /** Sets a value to be cached for given key. + <br> + @param rKey a key + @param rValue a value + */ + inline void setValue( t_Key const & rKey, t_Val const & rValue ); + /** Tests whether a value is cached for given key. + <br> + @param rKey a key + @return true, if value is cached + */ + inline sal_Bool hasValue( t_Key const & rKey ) const; + /** Clears the cache, thus releasing all cached elements and keys. + <br> + */ + inline void clear(); +}; +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::LRU_Cache( sal_Int32 nCachedElements ) +#ifdef __CACHE_DIAGNOSE + : _nCachedElements( 4 ) +#else + : _nCachedElements( nCachedElements ) +#endif + , _pBlock( 0 ) +{ + if (_nCachedElements > 0) + { + _pBlock = new CacheEntry[_nCachedElements]; + _pHead = _pBlock; + _pTail = _pBlock + _nCachedElements -1; + for ( sal_Int32 nPos = _nCachedElements; nPos--; ) + { + _pBlock[nPos].pPred = _pBlock + nPos -1; + _pBlock[nPos].pSucc = _pBlock + nPos +1; + } + } +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::~LRU_Cache() +{ + delete [] _pBlock; +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::toFront( + CacheEntry * pEntry ) const +{ + if (pEntry != _pHead) + { + // cut out element + if (pEntry == _pTail) + { + _pTail = pEntry->pPred; + } + else + { + pEntry->pSucc->pPred = pEntry->pPred; + pEntry->pPred->pSucc = pEntry->pSucc; + } + // push to front + _pHead->pPred = pEntry; + pEntry->pSucc = _pHead; + _pHead = pEntry; + } +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline sal_Bool LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::hasValue( + t_Key const & rKey ) const +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + typename t_Key2Element::const_iterator const iFind( _aKey2Element.find( rKey ) ); + return (iFind != _aKey2Element.end()); +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline t_Val LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::getValue( + t_Key const & rKey ) const +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + const typename t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) ); + if (iFind != _aKey2Element.end()) + { + CacheEntry * pEntry = (*iFind).second; + toFront( pEntry ); +#ifdef __CACHE_DIAGNOSE + SAL_INFO("stoc.tdmanager", "> retrieved element \"" ); + SAL_INFO("stoc.tdmanager", "" << pEntry->aKey); + SAL_INFO("stoc.tdmanager", "\" from cache <" ); +#endif + return pEntry->aVal; + } + return t_Val(); +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::setValue( + t_Key const & rKey, t_Val const & rValue ) +{ + if (_nCachedElements > 0) + { + ::osl::MutexGuard aGuard( _aCacheMutex ); + typename t_Key2Element::const_iterator const iFind( _aKey2Element.find( rKey ) ); + + CacheEntry * pEntry; + if (iFind == _aKey2Element.end()) + { + pEntry = _pTail; // erase last element +#ifdef __CACHE_DIAGNOSE + if (pEntry->aKey.getLength()) + { + SAL_INFO("stoc.tdmanager", "> kicking element \"" ); + SAL_INFO("stoc.tdmanager", "" << pEntry->aKey); + SAL_INFO("stoc.tdmanager", "\" from cache <" ); + } +#endif + _aKey2Element.erase( pEntry->aKey ); + _aKey2Element[ pEntry->aKey = rKey ] = pEntry; + } + else + { + pEntry = (*iFind).second; +#ifdef __CACHE_DIAGNOSE + SAL_INFO("stoc.tdmanager", "> replacing element \"" ); + SAL_INFO("stoc.tdmanager", "" << pEntry->aKey); + SAL_INFO("stoc.tdmanager", "\" in cache <" ); +#endif + } + pEntry->aVal = rValue; + toFront( pEntry ); + } +} +//__________________________________________________________________________________________________ +template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual > +inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::clear() +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + _aKey2Element.clear(); + for ( sal_Int32 nPos = _nCachedElements; nPos--; ) + { + _pBlock[nPos].aKey = t_Key(); + _pBlock[nPos].aVal = t_Val(); + } +#ifdef __CACHE_DIAGNOSE + SAL_INFO("stoc.tdmanager", "> cleared cache <" ); +#endif +} + +//================================================================================================== +struct FctHashOUString : public ::std::unary_function< ::rtl::OUString const &, size_t > +{ + size_t operator()( ::rtl::OUString const & rKey ) const + { return (size_t)rKey.hashCode(); } +}; + +/** Template instance for OUString keys, Any values.<br> +*/ +typedef LRU_Cache< ::rtl::OUString, ::com::sun::star::uno::Any, + FctHashOUString, ::std::equal_to< ::rtl::OUString > > + LRU_CacheAnyByOUString; + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/source/tdmanager/tdmgr.cxx b/stoc/source/tdmanager/tdmgr.cxx new file mode 100644 index 000000000000..51af243c0c62 --- /dev/null +++ b/stoc/source/tdmanager/tdmgr.cxx @@ -0,0 +1,1152 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <osl/diagnose.h> +#include <osl/mutex.hxx> +#include "rtl/ustrbuf.hxx" +#include <cppuhelper/factory.hxx> +#include <cppuhelper/compbase5.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implementationentry.hxx> +#include "tdmgr_common.hxx" +#include "tdmgr_tdenumeration.hxx" +#include "lrucache.hxx" + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XSet.hpp> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/reflection/XTypeDescription.hpp> +#include <com/sun/star/reflection/XArrayTypeDescription.hpp> +#include <com/sun/star/reflection/XIndirectTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceTypeDescription.hpp> +#include "com/sun/star/reflection/XStructTypeDescription.hpp" +#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include "com/sun/star/uno/RuntimeException.hpp" + +#include <algorithm> +#include <vector> + +using namespace std; +using namespace cppu; +using namespace osl; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::reflection; +using namespace com::sun::star::container; +using namespace com::sun::star::registry; + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +static const sal_Int32 CACHE_SIZE = 512; + +#define SERVICENAME "com.sun.star.reflection.TypeDescriptionManager" +#define IMPLNAME "com.sun.star.comp.stoc.TypeDescriptionManager" + +//-------------------------------------------------------------------------------------------------- +// exported via tdmgr_common.hxx +extern rtl_StandardModuleCount g_moduleCount; + +namespace stoc_bootstrap +{ +Sequence< OUString > SAL_CALL tdmgr_getSupportedServiceNames() +{ + Sequence< OUString > seqNames(1); + seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME)); + return seqNames; +} + +OUString SAL_CALL tdmgr_getImplementationName() +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM(IMPLNAME)); +} +} + +namespace stoc_tdmgr +{ +typedef vector< Reference< XHierarchicalNameAccess > > ProviderVector; + +class EnumerationImpl; +class ManagerImpl; + +//================================================================================================== +class EventListenerImpl : public ImplHelper1< XEventListener > +{ + ManagerImpl * _pMgr; + +public: + EventListenerImpl( ManagerImpl * pMgr ) + : _pMgr( pMgr ) + { + ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt ); + } + virtual ~EventListenerImpl(); + + // lifetime delegated to manager + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XEventListener + virtual void SAL_CALL disposing( const EventObject & rEvt ) throw(::com::sun::star::uno::RuntimeException); +}; + +EventListenerImpl::~EventListenerImpl() +{ + ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt ); +} + +//================================================================================================== +class ManagerImpl + : public WeakComponentImplHelper5< XServiceInfo, + XSet, + XHierarchicalNameAccess, + XTypeDescriptionEnumerationAccess, + XInitialization > +{ + friend class EnumerationImpl; + friend class EventListenerImpl; + + Mutex _aComponentMutex; + Reference< XComponentContext > _xContext; + EventListenerImpl _aEventListener; + + // elements + sal_Bool _bCaching; + LRU_CacheAnyByOUString _aElements; + // provider chain + ProviderVector _aProviders; + + inline Any getSimpleType( const OUString & rName ); + + Reference< XTypeDescription > getInstantiatedStruct(OUString const & name); + +protected: + virtual void SAL_CALL disposing(); + +public: + ManagerImpl( Reference< XComponentContext > const & xContext, sal_Int32 nCacheSize ); + virtual ~ManagerImpl(); + + // XInitialization + virtual void SAL_CALL initialize( const Sequence< Any > & args ) throw (Exception, RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // XElementAccess + virtual Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException); + + // XEnumerationAccess + virtual Reference< XEnumeration > SAL_CALL createEnumeration() throw(::com::sun::star::uno::RuntimeException); + + // XSet + virtual sal_Bool SAL_CALL has( const Any & rElement ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL insert( const Any & rElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL remove( const Any & rElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException); + + // XHierarchicalNameAccess + virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + + // XTypeDescriptionEnumerationAccess + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::reflection::XTypeDescriptionEnumeration > SAL_CALL + createTypeDescriptionEnumeration( + const ::rtl::OUString& moduleName, + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::TypeClass >& types, + ::com::sun::star::reflection::TypeDescriptionSearchDepth depth ) + throw ( ::com::sun::star::reflection::NoSuchTypeNameException, + ::com::sun::star::reflection::InvalidTypeNameException, + ::com::sun::star::uno::RuntimeException ); +}; + +//================================================================================================== +class EnumerationImpl + : public WeakImplHelper1< XEnumeration > +{ + ManagerImpl * _pMgr; + size_t _nPos; + +public: + EnumerationImpl( ManagerImpl * pManager ); + virtual ~EnumerationImpl(); + + // XEnumeration + virtual sal_Bool SAL_CALL hasMoreElements() throw(::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL nextElement() throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); +}; + +//################################################################################################## + +// lifetime delegated to manager +//__________________________________________________________________________________________________ +void EventListenerImpl::acquire() throw() +{ + _pMgr->acquire(); +} +//__________________________________________________________________________________________________ +void EventListenerImpl::release() throw() +{ + _pMgr->release(); +} + +// XEventListener +//__________________________________________________________________________________________________ +void EventListenerImpl::disposing( const EventObject & rEvt ) + throw(::com::sun::star::uno::RuntimeException) +{ + _pMgr->remove( makeAny( rEvt.Source ) ); +} + +//################################################################################################## + +//__________________________________________________________________________________________________ +EnumerationImpl::EnumerationImpl( ManagerImpl * pManager ) + : _pMgr( pManager ) + , _nPos( 0 ) +{ + _pMgr->acquire(); +} +//__________________________________________________________________________________________________ +EnumerationImpl::~EnumerationImpl() +{ + _pMgr->release(); +} + +// XEnumeration +//__________________________________________________________________________________________________ +sal_Bool EnumerationImpl::hasMoreElements() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( _pMgr->_aComponentMutex ); + return (_nPos < _pMgr->_aProviders.size()); +} +//__________________________________________________________________________________________________ +Any EnumerationImpl::nextElement() + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( _pMgr->_aComponentMutex ); + if (_nPos >= _pMgr->_aProviders.size()) + { + throw NoSuchElementException( + OUString( RTL_CONSTASCII_USTRINGPARAM("there is no further element!") ), + (XWeak *)(OWeakObject *)this ); + } + return makeAny( _pMgr->_aProviders[_nPos++] ); +} + +//################################################################################################## + +//__________________________________________________________________________________________________ +ManagerImpl::ManagerImpl( + Reference< XComponentContext > const & xContext, sal_Int32 nCacheSize ) + : WeakComponentImplHelper5< + XServiceInfo, XSet, XHierarchicalNameAccess, + XTypeDescriptionEnumerationAccess, XInitialization >( _aComponentMutex ) + , _xContext( xContext ) + , _aEventListener( this ) + , _bCaching( sal_True ) + , _aElements( nCacheSize ) +{ + ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt ); +} +//__________________________________________________________________________________________________ +ManagerImpl::~ManagerImpl() +{ + OSL_ENSURE( _aProviders.empty(), "### still providers left!" ); + OSL_TRACE( "> TypeDescriptionManager shut down. <" ); + ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt ); +} +//__________________________________________________________________________________________________ +void ManagerImpl::disposing() +{ + // called on disposing the tdmgr instance (supposedly from context) + _bCaching = sal_False; + _aElements.clear(); + _xContext.clear(); + _aProviders.clear(); +} + +// XInitialization +//__________________________________________________________________________________________________ +void ManagerImpl::initialize( + const Sequence< Any > & args ) + throw (Exception, RuntimeException) +{ + // additional providers + Any const * pProviders = args.getConstArray(); + for ( sal_Int32 nPos = 0; nPos < args.getLength(); ++nPos ) + { + Reference< XHierarchicalNameAccess > xHA( pProviders[ nPos ], UNO_QUERY ); + OSL_ENSURE( xHA.is(), "### no td provider!" ); + + if (xHA.is()) + { + try + { + insert( makeAny( xHA ) ); + } + catch (const IllegalArgumentException &) + { + } + catch (const ElementExistException &) + { + } + } + } +} + +// XServiceInfo +//__________________________________________________________________________________________________ +OUString ManagerImpl::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return stoc_bootstrap::tdmgr_getImplementationName(); +} +//__________________________________________________________________________________________________ +sal_Bool ManagerImpl::supportsService( const OUString & rServiceName ) + throw(::com::sun::star::uno::RuntimeException) +{ + const Sequence< OUString > & rSNL = getSupportedServiceNames(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + { + if (pArray[nPos] == rServiceName) + return sal_True; + } + return sal_False; +} +//__________________________________________________________________________________________________ +Sequence< OUString > ManagerImpl::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + return stoc_bootstrap::tdmgr_getSupportedServiceNames(); +} + +// XElementAccess +//__________________________________________________________________________________________________ +Type ManagerImpl::getElementType() + throw(::com::sun::star::uno::RuntimeException) +{ + return ::getCppuType( (const Reference< XHierarchicalNameAccess > *)0 ); +} +//__________________________________________________________________________________________________ +sal_Bool ManagerImpl::hasElements() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( _aComponentMutex ); + return (!_aProviders.empty()); +} + +// XEnumerationAccess +//__________________________________________________________________________________________________ +Reference< XEnumeration > ManagerImpl::createEnumeration() + throw(::com::sun::star::uno::RuntimeException) +{ + return new EnumerationImpl( this ); +} + +// XSet +//__________________________________________________________________________________________________ +sal_Bool SAL_CALL ManagerImpl::has( const Any & rElement ) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XHierarchicalNameAccess > xElem; + if (rElement >>= xElem) + { + MutexGuard aGuard( _aComponentMutex ); + return (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end()); + } + return sal_False; +} + +//__________________________________________________________________________________________________ +void SAL_CALL ManagerImpl::insert( const Any & rElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException) +{ + // 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 ); + 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 (doCheck) { + if (find( newProvs.begin(), newProvs.end(), xElem ) != newProvs.end()) + { + 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 + { + 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()) + { + Reference<reflection::XTypeDescription> xNewTD; + try + { + xNewTD = xTDEnum->nextTypeDescription(); + } + catch (const container::NoSuchElementException & exc) + { + throw lang::IllegalArgumentException( + "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 + { + check( xNewTD, xExistingTD ); + } + catch (const IncompatibleTypeException & exc) + { + throw lang::IllegalArgumentException( + "Rejecting types due to " + "incompatibility! " + exc.m_cause, + static_cast<OWeakObject *>(this), 0 ); + } + } + } + catch (const container::NoSuchElementException &) + { + // type not in: ok + } + } + } + catch (const reflection::NoSuchTypeNameException & exc) + { + throw lang::IllegalArgumentException( + "NoSuchTypeNameException occurred: " + exc.Message, + static_cast<OWeakObject *>(this), -1 /* unknown */ ); + } + catch (const reflection::InvalidTypeNameException & exc) + { + throw lang::IllegalArgumentException( + "InvalidTypeNameException occurred: " + exc.Message, + static_cast<OWeakObject *>(this), -1 /* unknown */ ); + } + } + } + newProvs.push_back( xElem ); + } + + _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 ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException) +{ + if (!rBHelper.bDisposed && !rBHelper.bInDispose) + { + Reference< XHierarchicalNameAccess > xElem; + if (! (rElement >>= xElem)) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no type description provider given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + + MutexGuard aGuard( _aComponentMutex ); + ProviderVector::iterator iFind( find( _aProviders.begin(), _aProviders.end(), xElem ) ); + if (iFind == _aProviders.end()) + { + throw NoSuchElementException( + OUString( RTL_CONSTASCII_USTRINGPARAM("provider not found!") ), + (XWeak *)(OWeakObject *)this ); + } + _aProviders.erase( iFind ); + } + + Reference< XComponent > xComp; + if (rElement >>= xComp) + xComp->removeEventListener( &_aEventListener ); +} + +// XTypeDescriptionEnumerationAccess +//__________________________________________________________________________________________________ +// virtual +Reference< XTypeDescriptionEnumeration > SAL_CALL +ManagerImpl::createTypeDescriptionEnumeration( + const OUString & moduleName, + const Sequence< TypeClass > & types, + TypeDescriptionSearchDepth depth ) + throw ( NoSuchTypeNameException, + InvalidTypeNameException, + RuntimeException ) +{ + MutexGuard aGuard( _aComponentMutex ); + + TDEnumerationAccessStack aStack; + ProviderVector::const_iterator it = _aProviders.begin(); + const ProviderVector::const_iterator end = _aProviders.end(); + while ( it != end ) + { + Reference< XTypeDescriptionEnumerationAccess >xEnumAccess( + (*it), UNO_QUERY ); + OSL_ENSURE( xEnumAccess.is(), + "### no XTypeDescriptionEnumerationAccess!" ); + if ( xEnumAccess.is() ) + aStack.push( xEnumAccess ); + + ++it; + } + + return Reference< XTypeDescriptionEnumeration >( + new TypeDescriptionEnumerationImpl( moduleName, + types, + depth, + aStack ) ); +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//================================================================================================== +class SimpleTypeDescriptionImpl + : public WeakImplHelper1< XTypeDescription > +{ + TypeClass _eTC; + OUString _aName; + +public: + SimpleTypeDescriptionImpl( TypeClass eTC, const OUString & rName ) + : _eTC( eTC ) + , _aName( rName ) + {} + + // XTypeDescription + virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); +}; + +// XTypeDescription +//__________________________________________________________________________________________________ +TypeClass SimpleTypeDescriptionImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return _eTC; +} +//__________________________________________________________________________________________________ +OUString SimpleTypeDescriptionImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} + +//================================================================================================== +class SequenceTypeDescriptionImpl + : public WeakImplHelper1< XIndirectTypeDescription > +{ + Reference< XTypeDescription > _xElementTD; + +public: + SequenceTypeDescriptionImpl( const Reference< XTypeDescription > & xElementTD ) + : _xElementTD( xElementTD ) + {} + + // XTypeDescription + virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + + // XIndirectTypeDescription + virtual Reference< XTypeDescription > SAL_CALL getReferencedType() throw(::com::sun::star::uno::RuntimeException); +}; + +// XTypeDescription +//__________________________________________________________________________________________________ +TypeClass SequenceTypeDescriptionImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return TypeClass_SEQUENCE; +} +//__________________________________________________________________________________________________ +OUString SequenceTypeDescriptionImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return (OUString( RTL_CONSTASCII_USTRINGPARAM("[]") ) + _xElementTD->getName()); +} + +// XIndirectTypeDescription +//__________________________________________________________________________________________________ +Reference< XTypeDescription > SequenceTypeDescriptionImpl::getReferencedType() + throw(::com::sun::star::uno::RuntimeException) +{ + return _xElementTD; +} + +//================================================================================================== +class ArrayTypeDescriptionImpl + : public WeakImplHelper1< XArrayTypeDescription > +{ + Reference< XTypeDescription > _xElementTD; + Mutex _aDimensionMutex; + sal_Int32 _nDimensions; + Sequence< sal_Int32 > _seqDimensions; + OUString _sDimensions; + + void initDimensions(const OUString& rSDimensions); +public: + ArrayTypeDescriptionImpl( const Reference< XTypeDescription > & xElementTD, + sal_Int32 nDimensions, const OUString& rSDimensions ) + : _xElementTD( xElementTD ) + , _nDimensions( nDimensions ) + , _seqDimensions( Sequence< sal_Int32 >(nDimensions) ) + , _sDimensions( rSDimensions ) + { + initDimensions( rSDimensions ); + } + virtual ~ArrayTypeDescriptionImpl() {} + + // XTypeDescription + virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + + // XArrayTypeDescription + virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getNumberOfDimensions() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int32 > SAL_CALL getDimensions() throw(::com::sun::star::uno::RuntimeException); +}; +//__________________________________________________________________________________________________ +static sal_Int32 unicodeToInteger( sal_Int8 base, const sal_Unicode *s ) +{ + sal_Int32 r = 0; + sal_Int32 negative = 0; + + if (*s == '-') + { + negative = 1; + s++; + } + if (base == 8 && *s == '0') + s++; + else if (base == 16 && *s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) + s += 2; + + for (; *s; s++) + { + if (*s <= '9' && *s >= '0') + r = (r * base) + (*s - '0'); + else if (base > 10 && *s <= 'f' && *s >= 'a') + r = (r * base) + (*s - 'a' + 10); + else if (base > 10 && *s <= 'F' && *s >= 'A') + r = (r * base) + (*s - 'A' + 10); + else + break; + } + if (negative) r *= -1; + return r; +} +//__________________________________________________________________________________________________ +void ArrayTypeDescriptionImpl::initDimensions(const OUString& rSDimensions) +{ + MutexGuard aGuard( _aDimensionMutex ); + + sal_Int32 * pDimensions = _seqDimensions.getArray(); + OUString tmp(rSDimensions); + sal_Unicode* p = (sal_Unicode*)tmp.getStr()+1; + sal_Unicode* pOffset = p; + sal_Int32 len = tmp.getLength() - 1 ; + sal_Int32 i = 0; + + while ( len > 0) + { + pOffset++; + if (*pOffset == ']') + { + *pOffset = '\0'; + pOffset += 2; + len -= 3; + pDimensions[i++] = unicodeToInteger(10, p); + p = pOffset; + } else + len--; + } +} + +// XTypeDescription +//__________________________________________________________________________________________________ +TypeClass ArrayTypeDescriptionImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return TypeClass_ARRAY; +} +//__________________________________________________________________________________________________ +OUString ArrayTypeDescriptionImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return (_xElementTD->getName() + _sDimensions); +} + +// XArrayTypeDescription +//__________________________________________________________________________________________________ +Reference< XTypeDescription > ArrayTypeDescriptionImpl::getType() + throw(::com::sun::star::uno::RuntimeException) +{ + return _xElementTD; +} + +//__________________________________________________________________________________________________ +sal_Int32 ArrayTypeDescriptionImpl::getNumberOfDimensions() + throw(::com::sun::star::uno::RuntimeException) +{ + return _nDimensions; +} + +//__________________________________________________________________________________________________ +Sequence< sal_Int32 > ArrayTypeDescriptionImpl::getDimensions() + throw(::com::sun::star::uno::RuntimeException) +{ + return _seqDimensions; +} + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +inline Any ManagerImpl::getSimpleType( const OUString & rName ) +{ + Any aRet; + + if ( rName == "string" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_STRING, rName ) ); + else if ( rName == "long" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_LONG, rName ) ); + else if ( rName == "unsigned long" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_LONG, rName ) ); + else if ( rName == "boolean" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BOOLEAN, rName ) ); + else if ( rName == "char" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_CHAR, rName ) ); + else if ( rName == "byte" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BYTE, rName ) ); + else if ( rName == "short" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_SHORT, rName ) ); + else if ( rName == "unsigned short" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_SHORT, rName ) ); + else if ( rName == "hyper" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_HYPER, rName ) ); + else if ( rName == "unsigned hyper" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_HYPER, rName ) ); + else if ( rName == "float" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_FLOAT, rName ) ); + else if ( rName == "double" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_DOUBLE, rName ) ); + else if ( rName == "any" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_ANY, rName ) ); + else if ( rName == "void" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_VOID, rName ) ); + else if ( rName == "type" ) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_TYPE, rName ) ); + + return aRet; +} + +namespace { + +Reference< XTypeDescription > resolveTypedefs( + Reference< XTypeDescription > const & type) +{ + Reference< XTypeDescription > resolved(type); + while (resolved->getTypeClass() == TypeClass_TYPEDEF) { + resolved = Reference< XIndirectTypeDescription >( + type, UNO_QUERY_THROW)->getReferencedType(); + } + return resolved; +} + +bool isNonVoidNonExceptionType(Reference< XTypeDescription > const & type) { + switch (type->getTypeClass()) { + case TypeClass_BOOLEAN: + case TypeClass_BYTE: + case TypeClass_SHORT: + case TypeClass_UNSIGNED_SHORT: + case TypeClass_LONG: + case TypeClass_UNSIGNED_LONG: + case TypeClass_HYPER: + case TypeClass_UNSIGNED_HYPER: + case TypeClass_FLOAT: + case TypeClass_DOUBLE: + case TypeClass_CHAR: + case TypeClass_STRING: + case TypeClass_TYPE: + case TypeClass_ANY: + case TypeClass_SEQUENCE: + case TypeClass_ENUM: + case TypeClass_STRUCT: + case TypeClass_INTERFACE: + return true; + + default: + return false; + } +} + +class InstantiatedStruct: public WeakImplHelper1< XStructTypeDescription > { +public: + InstantiatedStruct( + Reference< XStructTypeDescription > const & structType, + std::vector< Reference< XTypeDescription > > const & arguments); + + virtual TypeClass SAL_CALL getTypeClass() throw (RuntimeException) + { return TypeClass_STRUCT; } + + virtual OUString SAL_CALL getName() throw (RuntimeException); + + virtual Reference< XTypeDescription > SAL_CALL getBaseType() + throw (RuntimeException) + { return m_struct->getBaseType(); } + + virtual Sequence< Reference< XTypeDescription > > SAL_CALL getMemberTypes() + throw (RuntimeException); + + virtual Sequence< OUString > SAL_CALL getMemberNames() + throw (RuntimeException) + { return m_struct->getMemberNames(); } + + virtual Sequence< OUString > SAL_CALL getTypeParameters() + throw (RuntimeException) + { return Sequence< OUString >(); } + + virtual Sequence< Reference< XTypeDescription > > SAL_CALL + getTypeArguments() throw (RuntimeException) + { return m_arguments; } + +private: + Reference< XStructTypeDescription > m_struct; + Sequence< Reference< XTypeDescription > > m_arguments; +}; + +InstantiatedStruct::InstantiatedStruct( + Reference< XStructTypeDescription > const & structType, + std::vector< Reference< XTypeDescription > > const & arguments): + m_struct(structType), + m_arguments(static_cast< sal_Int32 >(arguments.size())) +{ + for (std::vector< Reference< XTypeDescription > >::size_type i = 0; + i < arguments.size(); ++i) + { + m_arguments[static_cast< sal_Int32 >(i)] = arguments[i]; + } +} + +OUString InstantiatedStruct::getName() throw (RuntimeException) { + OUStringBuffer buf(m_struct->getName()); + buf.append(static_cast< sal_Unicode >('<')); + for (sal_Int32 i = 0; i < m_arguments.getLength(); ++i) { + if (i != 0) { + buf.append(static_cast< sal_Unicode >(',')); + } + buf.append(m_arguments[i]->getName()); + } + buf.append(static_cast< sal_Unicode >('>')); + return buf.makeStringAndClear(); +} + +Sequence< Reference< XTypeDescription > > InstantiatedStruct::getMemberTypes() + throw (RuntimeException) +{ + Sequence< Reference< XTypeDescription > > types(m_struct->getMemberTypes()); + for (sal_Int32 i = 0; i < types.getLength(); ++i) { + if (types[i]->getTypeClass() == TypeClass_UNKNOWN) { + Sequence< OUString > parameters(m_struct->getTypeParameters()); + OSL_ASSERT(parameters.getLength() == m_arguments.getLength()); + for (sal_Int32 j = 0; j < parameters.getLength(); ++j) { + if (parameters[j] == types[i]->getName()) { + types[i] = m_arguments[j]; + break; + } + } + } + } + return types; +} + +} + +Reference< XTypeDescription > ManagerImpl::getInstantiatedStruct( + OUString const & name) +{ + sal_Int32 i = name.indexOf('<'); + OSL_ASSERT(i >= 0); + Reference< XStructTypeDescription > structType( + getByHierarchicalName(name.copy(0, i)), UNO_QUERY); + std::vector< Reference< XTypeDescription > > args; + bool good = structType.is(); + if (good) { + do { + ++i; // skip '<' or ',' + sal_Int32 j = i; + for (sal_Int32 level = 0; j != name.getLength(); ++j) { + sal_Unicode c = name[j]; + if (c == ',') { + if (level == 0) { + break; + } + } else if (c == '<') { + ++level; + } else if (c == '>') { + if (level == 0) { + break; + } + --level; + } + } + if (j != name.getLength()) { + Reference< XTypeDescription > type( + getByHierarchicalName(name.copy(i, j - i)), UNO_QUERY); + if (isNonVoidNonExceptionType(resolveTypedefs(type))) { + args.push_back(type); + } else { + good = false; + break; + } + } + i = j; + } while (i != name.getLength() && name[i] != '>'); + good = good && i == name.getLength() - 1 + && name[i] == '>' && !args.empty(); + } + // args.size() cannot exceed SAL_MAX_INT32, as each argument consumes at + // least one position within an rtl::OUString (which is no longer than + // SAL_MAX_INT32): + if (!good + || (args.size() + != sal::static_int_cast< sal_uInt32 >( + structType->getTypeParameters().getLength()))) + { + throw NoSuchElementException(name, static_cast< OWeakObject * >(this)); + } + return new InstantiatedStruct(structType, args); +} + +// XHierarchicalNameAccess +//__________________________________________________________________________________________________ +Any ManagerImpl::getByHierarchicalName( const OUString & rName ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException) +{ + Any aRet; + if (_bCaching) + aRet = _aElements.getValue( rName ); + if (!rName.isEmpty() && !aRet.hasValue()) + { + sal_Int32 nIndex; + if (rName[0] == '[') // test for sequence + { + Reference< XTypeDescription > xElemType( + getByHierarchicalName( rName.copy( 2 ) ), + UNO_QUERY_THROW ); + aRet <<= Reference< XTypeDescription >( + new SequenceTypeDescriptionImpl( xElemType ) ); + } + else if (rName[rName.getLength()-1] == ']') // test for array + { + sal_Int32 nIndex2 = 0, nTokens = 0; + do { rName.getToken( 0, '[', nIndex2 ); nTokens++; } while( nIndex2 != -1 ); + sal_Int32 nDims = nTokens - 1; + sal_Int32 dimOffset = rName.indexOf('['); + Reference< XTypeDescription > xElemType( + getByHierarchicalName( rName.copy( 0, dimOffset ) ), + UNO_QUERY_THROW ); + aRet <<= Reference< XTypeDescription >( + new ArrayTypeDescriptionImpl( + xElemType, nDims, rName.copy(dimOffset) ) ); + } + // test for interface member names: + else if ((nIndex = rName.indexOf( ':' )) >= 0) + { + Reference< XInterfaceTypeDescription > xIfaceTD( + getByHierarchicalName( rName.copy( 0, nIndex ) ), + UNO_QUERY_THROW ); + const Sequence< Reference< XInterfaceMemberTypeDescription > > & + rMembers = xIfaceTD->getMembers(); + const Reference< XInterfaceMemberTypeDescription > * pMembers = + rMembers.getConstArray(); + + for ( sal_Int32 nPos = rMembers.getLength(); nPos--; ) + { + if (rName == pMembers[nPos]->getName()) + { + aRet <<= Reference< XTypeDescription >( + pMembers[nPos], UNO_QUERY_THROW ); + break; + } + } + if (! aRet.hasValue()) + { + // member not found: + throw NoSuchElementException( + rName, static_cast< OWeakObject * >(this) ); + } + } + // test for instantiated polymorphic struct types: + else if (rName.indexOf('<') >= 0) + { + aRet <<= getInstantiatedStruct(rName); + } + else if (rName.indexOf( '.' ) < 0) // test for simple/ build in types + { + aRet = getSimpleType( rName ); + } + + if (! aRet.hasValue()) + { + // last, try callback chain + for ( ProviderVector::const_iterator iPos( _aProviders.begin() ); + iPos != _aProviders.end(); ++iPos ) + { + try + { + if ((aRet = (*iPos)->getByHierarchicalName( + rName )).hasValue()) + { + break; + } + } + catch (const NoSuchElementException &) + { + } + } + } + + // update cache + if (_bCaching && aRet.hasValue()) + _aElements.setValue( rName, aRet ); + } + + if (! aRet.hasValue()) + { + throw NoSuchElementException( + rName, static_cast< OWeakObject * >(this) ); + } + return aRet; +} +//__________________________________________________________________________________________________ +sal_Bool ManagerImpl::hasByHierarchicalName( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + try + { + return getByHierarchicalName( rName ).hasValue(); + } + catch (const NoSuchElementException &) + { + } + return sal_False; +} +} + +namespace stoc_bootstrap +{ +//================================================================================================== +Reference< XInterface > SAL_CALL ManagerImpl_create( + Reference< XComponentContext > const & xContext ) + SAL_THROW( (::com::sun::star::uno::Exception) ) +{ + sal_Int32 nCacheSize = CACHE_SIZE; + if (xContext.is()) { + xContext->getValueByName( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "/implementations/" IMPLNAME "/CacheSize"))) >>= + nCacheSize; + } + + return Reference< XInterface >( *new stoc_tdmgr::ManagerImpl( xContext, nCacheSize ) ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/source/tdmanager/tdmgr_common.hxx b/stoc/source/tdmanager/tdmgr_common.hxx new file mode 100644 index 000000000000..33f1a2ad307b --- /dev/null +++ b/stoc/source/tdmanager/tdmgr_common.hxx @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef _STOC_TDMGR_COMMON_HXX +#define _STOC_TDMGR_COMMON_HXX + +#include <rtl/unload.h> + +#include "com/sun/star/reflection/XTypeDescription.hpp" + +#define ARLEN(x) (sizeof (x) / sizeof *(x)) + + +namespace stoc_tdmgr +{ + extern rtl_StandardModuleCount g_moduleCount; + +struct IncompatibleTypeException +{ + ::rtl::OUString m_cause; + IncompatibleTypeException( ::rtl::OUString const & cause ) + : m_cause( cause ) {} +}; + +void check( + css::uno::Reference<css::reflection::XTypeDescription> const & xNewTD, + css::uno::Reference<css::reflection::XTypeDescription> const & xExistingTD, + ::rtl::OUString const & context = ::rtl::OUString() ); +/* throw (css::uno::RuntimeException, IncompatibleTypeException) */ + +} // namespace stoc_tdmgr + +#endif /* _STOC_TDMGR_COMMON_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/source/tdmanager/tdmgr_tdenumeration.cxx b/stoc/source/tdmanager/tdmgr_tdenumeration.cxx new file mode 100644 index 000000000000..7433d11b84cc --- /dev/null +++ b/stoc/source/tdmanager/tdmgr_tdenumeration.cxx @@ -0,0 +1,176 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <osl/diagnose.h> +#include "tdmgr_common.hxx" +#include "tdmgr_tdenumeration.hxx" + +using namespace com::sun::star; + +extern rtl_StandardModuleCount g_moduleCount; + +namespace stoc_tdmgr +{ + +//========================================================================= +//========================================================================= +// +// TypeDescriptionEnumerationImpl Implementation. +// +//========================================================================= +//========================================================================= + +TypeDescriptionEnumerationImpl::TypeDescriptionEnumerationImpl( + const rtl::OUString & rModuleName, + const com::sun::star::uno::Sequence< + com::sun::star::uno::TypeClass > & rTypes, + com::sun::star::reflection::TypeDescriptionSearchDepth eDepth, + const TDEnumerationAccessStack & rTDEAS ) +: m_aModuleName( rModuleName ), + m_aTypes( rTypes ), + m_eDepth( eDepth ), + m_aChildren( rTDEAS ) +{ + ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt ); +} + +//========================================================================= +// virtual +TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl() +{ + ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt ); +} + +//========================================================================= +// +// XEnumeration (base of XTypeDescriptionEnumeration) methods +// +//========================================================================= + +// virtual +sal_Bool SAL_CALL TypeDescriptionEnumerationImpl::hasMoreElements() + throw ( uno::RuntimeException ) +{ + uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum + = queryCurrentChildEnumeration(); + if ( xEnum.is() ) + return xEnum->hasMoreElements(); + + return sal_False; +} + +//========================================================================= +// virtual +uno::Any SAL_CALL TypeDescriptionEnumerationImpl::nextElement() + throw ( container::NoSuchElementException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum + = queryCurrentChildEnumeration(); + if ( xEnum.is() ) + return xEnum->nextElement(); + + throw container::NoSuchElementException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("No further elements in enumeration!") ), + static_cast< cppu::OWeakObject * >( this ) ); +} + +//========================================================================= +// +// XTypeDescriptionEnumeration methods +// +//========================================================================= + +// virtual +uno::Reference< reflection::XTypeDescription > SAL_CALL +TypeDescriptionEnumerationImpl::nextTypeDescription() + throw ( container::NoSuchElementException, + uno::RuntimeException ) +{ + uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum + = queryCurrentChildEnumeration(); + if ( xEnum.is() ) + return xEnum->nextTypeDescription(); + + throw container::NoSuchElementException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("No further elements in enumeration!") ), + static_cast< cppu::OWeakObject * >( this ) ); +} + +//========================================================================= +uno::Reference< reflection::XTypeDescriptionEnumeration > +TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration() +{ + osl::MutexGuard aGuard( m_aMutex ); + + for (;;) + { + if ( m_xEnum.is() ) + { + if ( m_xEnum->hasMoreElements() ) + { + return m_xEnum; + } + else + { + // Forget about enumeration without further elements. Try next. + m_xEnum.clear(); + } + } + + // Note: m_xEnum is always null here. + + if ( m_aChildren.empty() ) + { + // No child enumerations left. + return m_xEnum; + } + + try + { + m_xEnum = + m_aChildren.top()->createTypeDescriptionEnumeration( + m_aModuleName, m_aTypes, m_eDepth ); + } + catch ( reflection::NoSuchTypeNameException const & ) + { + OSL_FAIL( "TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration " + "- Caught NoSuchTypeNameException!" ); + } + catch ( reflection::InvalidTypeNameException const & ) + { + OSL_FAIL( "TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration " + "- Caught InvalidTypeNameException!" ); + } + + // We're done with this enumeration access in any case (Either + // enumeration was successfully created or creation failed for some + // reason). + m_aChildren.pop(); + } + + // unreachable +} + +} // namespace stoc_tdmgr + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/source/tdmanager/tdmgr_tdenumeration.hxx b/stoc/source/tdmanager/tdmgr_tdenumeration.hxx new file mode 100644 index 000000000000..d8ad3ffffb7b --- /dev/null +++ b/stoc/source/tdmanager/tdmgr_tdenumeration.hxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef _STOC_TDMGR_TDENUMERATION_HXX +#define _STOC_TDMGR_TDENUMERATION_HXX + +#include <stack> +#include <osl/mutex.hxx> +#include <com/sun/star/reflection/XTypeDescriptionEnumeration.hpp> +#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp> +#include <cppuhelper/implbase1.hxx> + +namespace stoc_tdmgr +{ + +typedef std::stack< com::sun::star::uno::Reference< + com::sun::star::reflection::XTypeDescriptionEnumerationAccess > > + TDEnumerationAccessStack; + +class TypeDescriptionEnumerationImpl + : public cppu::WeakImplHelper1< + com::sun::star::reflection::XTypeDescriptionEnumeration > +{ +public: + TypeDescriptionEnumerationImpl( + const rtl::OUString & rModuleName, + const com::sun::star::uno::Sequence< + com::sun::star::uno::TypeClass > & rTypes, + com::sun::star::reflection::TypeDescriptionSearchDepth eDepth, + const TDEnumerationAccessStack & rTDEAS ); + virtual ~TypeDescriptionEnumerationImpl(); + + // XEnumeration (base of XTypeDescriptionEnumeration) + virtual sal_Bool SAL_CALL hasMoreElements() + throw ( ::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Any SAL_CALL nextElement() + throw ( ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + // XTypeDescriptionEnumeration + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::reflection::XTypeDescription > SAL_CALL + nextTypeDescription() + throw ( ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException ); + +private: + com::sun::star::uno::Reference< + com::sun::star::reflection::XTypeDescriptionEnumeration > + queryCurrentChildEnumeration(); + + osl::Mutex m_aMutex; + rtl::OUString m_aModuleName; + com::sun::star::uno::Sequence< com::sun::star::uno::TypeClass > m_aTypes; + com::sun::star::reflection::TypeDescriptionSearchDepth m_eDepth; + TDEnumerationAccessStack m_aChildren; + com::sun::star::uno::Reference< + com::sun::star::reflection::XTypeDescriptionEnumeration > m_xEnum; +}; + +} // namespace stoc_tdmgr + +#endif /* _STOC_TDMGR_TDENUMERATION_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/util/bootstrap.component b/stoc/util/bootstrap.component index 6642ebdead26..d6e9b0c4f03f 100644 --- a/stoc/util/bootstrap.component +++ b/stoc/util/bootstrap.component @@ -41,6 +41,10 @@ <implementation name="com.sun.star.comp.stoc.SimpleRegistry"> <service name="com.sun.star.registry.SimpleRegistry"/> </implementation> + <implementation name="com.sun.star.comp.stoc.TypeDescriptionManager"> + <service name="com.sun.star.reflection.TypeDescriptionManager"/> + <singleton name="com.sun.star.reflection.theTypeDescriptionManager"/> + </implementation> <implementation name="com.sun.star.security.comp.stoc.AccessController"> <service name="com.sun.star.security.AccessController"/> </implementation> diff --git a/unoidl/inc/unoidl/unoidl.hxx b/unoidl/inc/unoidl/unoidl.hxx index 203df47be94c..5597227c16e0 100644 --- a/unoidl/inc/unoidl/unoidl.hxx +++ b/unoidl/inc/unoidl/unoidl.hxx @@ -15,7 +15,6 @@ #include <cassert> #include <vector> -#include "osl/mutex.hxx" #include "rtl/ref.hxx" #include "rtl/ustring.hxx" #include "sal/types.h" @@ -624,7 +623,6 @@ public: private: virtual SAL_DLLPRIVATE ~Manager() throw (); - mutable osl::Mutex mutex_; std::vector< rtl::Reference< Provider > > providers_; }; diff --git a/unoidl/source/unoidl.cxx b/unoidl/source/unoidl.cxx index 07aabcd70c46..0ffeb6bdd014 100644 --- a/unoidl/source/unoidl.cxx +++ b/unoidl/source/unoidl.cxx @@ -11,7 +11,6 @@ #include <vector> -#include "osl/mutex.hxx" #include "rtl/ref.hxx" #include "rtl/ustring.hxx" #include "unoidl/legacyprovider.hxx" @@ -75,13 +74,11 @@ rtl::Reference< Provider > loadProvider( void Manager::addProvider(rtl::Reference< Provider > const & provider) { assert(provider.is()); - osl::MutexGuard g(mutex_); providers_.push_back(provider); } rtl::Reference< Entity > Manager::findEntity(rtl::OUString const & name) const { - //TODO: caching? (here or in cppuhelper::TypeManager?) - osl::MutexGuard g(mutex_); + //TODO: add caching for (std::vector< rtl::Reference< Provider > >::const_iterator i( providers_.begin()); i != providers_.end(); ++i) |