diff options
Diffstat (limited to 'stoc/source/registry_tdprovider/tdservice.cxx')
-rw-r--r-- | stoc/source/registry_tdprovider/tdservice.cxx | 565 |
1 files changed, 565 insertions, 0 deletions
diff --git a/stoc/source/registry_tdprovider/tdservice.cxx b/stoc/source/registry_tdprovider/tdservice.cxx new file mode 100644 index 000000000000..b8a1de58b1aa --- /dev/null +++ b/stoc/source/registry_tdprovider/tdservice.cxx @@ -0,0 +1,565 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_stoc.hxx" +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include "com/sun/star/uno/RuntimeException.hpp" + +#include "registry/reader.hxx" +#include "registry/version.h" +#include "base.hxx" +#include "methoddescription.hxx" + +#include <memory> + +using namespace com::sun::star; + +namespace { + +class Constructor: + public cppu::WeakImplHelper1< XServiceConstructorDescription > +{ +public: + Constructor( + Reference< XHierarchicalNameAccess > const & manager, + rtl::OUString const & name, Sequence< sal_Int8 > const & bytes, + sal_uInt16 index): + m_desc(manager, name, bytes, index) {} + + virtual ~Constructor() {} + + virtual sal_Bool SAL_CALL isDefaultConstructor() throw (RuntimeException) + { return m_desc.getName().getLength() == 0; } + + virtual rtl::OUString SAL_CALL getName() throw (RuntimeException) + { return m_desc.getName(); } + + virtual Sequence< Reference< XParameter > > SAL_CALL getParameters() + throw (RuntimeException) + { return m_desc.getParameters(); } + + virtual Sequence< Reference<XCompoundTypeDescription > > SAL_CALL + getExceptions() throw (RuntimeException) + { return m_desc.getExceptions(); } + +private: + Constructor(Constructor &); // not implemented + void operator =(Constructor); // not implemented + + stoc::registry_tdprovider::MethodDescription m_desc; +}; + +} + +namespace stoc_rdbtdp +{ + +//================================================================================================== +// +// class PropertyTypeDescriptionImpl +// +//================================================================================================== +class PropertyTypeDescriptionImpl : public WeakImplHelper1< XPropertyTypeDescription > +{ + OUString _aName; + Reference< XTypeDescription > _xTD; + sal_Int16 _nFlags; + +public: + PropertyTypeDescriptionImpl( const OUString & rName, + const Reference< XTypeDescription > & xTD, + sal_Int16 nFlags ) + : _aName( rName ), _xTD( xTD ), _nFlags( nFlags ) + { + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + } + virtual ~PropertyTypeDescriptionImpl(); + + // XTypeDescription + virtual TypeClass SAL_CALL getTypeClass() + throw( RuntimeException ); + virtual OUString SAL_CALL getName() + throw( RuntimeException ); + + // XPropertyTypeDescription + virtual sal_Int16 SAL_CALL getPropertyFlags() + throw ( RuntimeException ); + virtual Reference< XTypeDescription > SAL_CALL getPropertyTypeDescription() + throw ( RuntimeException ); +}; + +//__________________________________________________________________________________________________ +// virtual +PropertyTypeDescriptionImpl::~PropertyTypeDescriptionImpl() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +// XTypeDescription +//__________________________________________________________________________________________________ +// virtual +TypeClass PropertyTypeDescriptionImpl::getTypeClass() + throw ( RuntimeException ) +{ + return TypeClass_PROPERTY; +} +//__________________________________________________________________________________________________ +// virtual +OUString PropertyTypeDescriptionImpl::getName() + throw ( RuntimeException ) +{ + return _aName; +} + +// XPropertyTypeDescription +//__________________________________________________________________________________________________ +// virtual +sal_Int16 SAL_CALL PropertyTypeDescriptionImpl::getPropertyFlags() + throw ( RuntimeException ) +{ + return _nFlags; +} + +//__________________________________________________________________________________________________ +// virtual +Reference< XTypeDescription > SAL_CALL +PropertyTypeDescriptionImpl::getPropertyTypeDescription() + throw ( RuntimeException ) +{ + return _xTD; +} + +//================================================================================================== +// +// ServiceTypeDescriptionImpl implementation +// +//================================================================================================== + +//__________________________________________________________________________________________________ +// virtual +ServiceTypeDescriptionImpl::~ServiceTypeDescriptionImpl() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +// XTypeDescription +//__________________________________________________________________________________________________ +// virtual +TypeClass ServiceTypeDescriptionImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return TypeClass_SERVICE; +} +//__________________________________________________________________________________________________ +// virtual +OUString ServiceTypeDescriptionImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} + +// XServiceTypeDescription +//__________________________________________________________________________________________________ +// virtual +Sequence< Reference< XServiceTypeDescription > > SAL_CALL +ServiceTypeDescriptionImpl::getMandatoryServices() + throw ( RuntimeException ) +{ + getReferences(); + return _aMandatoryServices; +} + +//__________________________________________________________________________________________________ +// virtual +Sequence< Reference< XServiceTypeDescription > > SAL_CALL +ServiceTypeDescriptionImpl::getOptionalServices() + throw ( RuntimeException ) +{ + getReferences(); + return _aOptionalServices; +} + +//__________________________________________________________________________________________________ +// virtual +Sequence< Reference< XInterfaceTypeDescription > > SAL_CALL +ServiceTypeDescriptionImpl::getMandatoryInterfaces() + throw ( RuntimeException ) +{ + getReferences(); + return _aMandatoryInterfaces; +} + +//__________________________________________________________________________________________________ +// virtual +Sequence< Reference< XInterfaceTypeDescription > > SAL_CALL +ServiceTypeDescriptionImpl::getOptionalInterfaces() + throw ( RuntimeException ) +{ + getReferences(); + return _aOptionalInterfaces; +} + +//__________________________________________________________________________________________________ +// virtual +Sequence< Reference< XPropertyTypeDescription > > SAL_CALL +ServiceTypeDescriptionImpl::getProperties() + throw ( RuntimeException ) +{ + { + MutexGuard guard(getMutex()); + if (_pProps.get() != 0) { + return *_pProps; + } + } + + typereg::Reader aReader( + _aBytes.getConstArray(), _aBytes.getLength(), false, TYPEREG_VERSION_1); + + sal_uInt16 nFields = (sal_uInt16)aReader.getFieldCount(); + std::auto_ptr< Sequence< Reference< XPropertyTypeDescription > > > + pTempProps( + new Sequence< Reference< XPropertyTypeDescription > >(nFields)); + Reference< XPropertyTypeDescription > * pProps = pTempProps->getArray(); + + while ( nFields-- ) + { + // name + OUStringBuffer aName( _aName ); + aName.appendAscii( "." ); + aName.append( aReader.getFieldName( nFields ) ); + + // type description + Reference< XTypeDescription > xTD; + try + { + _xTDMgr->getByHierarchicalName( + aReader.getFieldTypeName( nFields ).replace( '/', '.' ) ) + >>= xTD; + } + catch ( NoSuchElementException const & ) + { + } + OSL_ENSURE( xTD.is(), "### no type description for property!" ); + + // flags + RTFieldAccess nFlags = aReader.getFieldFlags( nFields ); + + sal_Int16 nAttribs = 0; + if ( nFlags & RT_ACCESS_READONLY ) + nAttribs |= beans::PropertyAttribute::READONLY; + if ( nFlags & RT_ACCESS_OPTIONAL ) + nAttribs |= beans::PropertyAttribute::OPTIONAL; + if ( nFlags & RT_ACCESS_MAYBEVOID ) + nAttribs |= beans::PropertyAttribute::MAYBEVOID; + if ( nFlags & RT_ACCESS_BOUND ) + nAttribs |= beans::PropertyAttribute::BOUND; + if ( nFlags & RT_ACCESS_CONSTRAINED ) + nAttribs |= beans::PropertyAttribute::CONSTRAINED; + if ( nFlags & RT_ACCESS_TRANSIENT ) + nAttribs |= beans::PropertyAttribute::TRANSIENT; + if ( nFlags & RT_ACCESS_MAYBEAMBIGUOUS ) + nAttribs |= beans::PropertyAttribute::MAYBEAMBIGUOUS; + if ( nFlags & RT_ACCESS_MAYBEDEFAULT ) + nAttribs |= beans::PropertyAttribute::MAYBEDEFAULT; + if ( nFlags & RT_ACCESS_REMOVEABLE ) + nAttribs |= beans::PropertyAttribute::REMOVEABLE; + + OSL_ENSURE( !(nFlags & RT_ACCESS_PROPERTY), + "### RT_ACCESS_PROPERTY is unexpected here!" ); + OSL_ENSURE( !(nFlags & RT_ACCESS_ATTRIBUTE), + "### RT_ACCESS_ATTRIBUTE is unexpected here!" ); + OSL_ENSURE( !(nFlags & RT_ACCESS_CONST), + "### RT_ACCESS_CONST is unexpected here!" ); + // always set, unless RT_ACCESS_READONLY is set. + //OSL_ENSURE( !(nFlags & RT_ACCESS_READWRITE), + // "### RT_ACCESS_READWRITE is unexpected here" ); + OSL_ENSURE( !(nFlags & RT_ACCESS_DEFAULT), + "### RT_ACCESS_DEAFAULT is unexpected here" ); + + pProps[ nFields ] + = new PropertyTypeDescriptionImpl( aName.makeStringAndClear(), + xTD, + nAttribs ); + } + + MutexGuard guard(getMutex()); + if (_pProps.get() == 0) { + _pProps = pTempProps; + } + return *_pProps; +} + +sal_Bool ServiceTypeDescriptionImpl::isSingleInterfaceBased() + throw (RuntimeException) +{ + getReferences(); + return _xInterfaceTD.is(); +} + +Reference< XTypeDescription > ServiceTypeDescriptionImpl::getInterface() + throw (RuntimeException) +{ + getReferences(); + return _xInterfaceTD; +} + +Sequence< Reference< XServiceConstructorDescription > > +ServiceTypeDescriptionImpl::getConstructors() throw (RuntimeException) { + MutexGuard guard(getMutex()); + if (_pCtors.get() == 0) { + typereg::Reader reader( + _aBytes.getConstArray(), _aBytes.getLength(), false, + TYPEREG_VERSION_1); + sal_uInt16 ctorCount = reader.getMethodCount(); + std::auto_ptr< Sequence< Reference< XServiceConstructorDescription > > > + ctors( + new Sequence< Reference< XServiceConstructorDescription > >( + ctorCount)); + for (sal_uInt16 i = 0; i < ctorCount; ++i) { + rtl::OUString name(reader.getMethodName(i)); + if (reader.getMethodFlags(i) != RT_MODE_TWOWAY + || (!reader.getMethodReturnTypeName(i).equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("void"))) + || (name.getLength() == 0 + && (ctorCount != 1 || reader.getMethodParameterCount(i) != 0 + || reader.getMethodExceptionCount(i) != 0))) + { + throw RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "Service has bad constructors")), + static_cast< OWeakObject * >(this)); + } + (*ctors)[i] = new Constructor( + _xTDMgr, reader.getMethodName(i), _aBytes, i); + } + _pCtors = ctors; + } + return *_pCtors; +} + +//__________________________________________________________________________________________________ +void ServiceTypeDescriptionImpl::getReferences() + throw ( RuntimeException ) +{ + { + MutexGuard guard(getMutex()); + if (_bInitReferences) { + return; + } + } + typereg::Reader aReader( + _aBytes.getConstArray(), _aBytes.getLength(), false, TYPEREG_VERSION_1); + sal_uInt16 superTypes = aReader.getSuperTypeCount(); + if (superTypes > 1) { + throw RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "Service has more than one supertype")), + static_cast< OWeakObject * >(this)); + } + if (superTypes == 1) { + OUString aBaseName( aReader.getSuperTypeName(0).replace( '/', '.' ) ); + if ( aReader.getReferenceCount() != 0 + || aReader.getFieldCount() != 0 ) + throw RuntimeException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "Service is single-interface--based but also has" + " references and/or properties" ) ), + static_cast< OWeakObject * >( this ) ); + Reference< XTypeDescription > ifc; + try + { + _xTDMgr->getByHierarchicalName( aBaseName ) >>= ifc; + } + catch ( NoSuchElementException const & e ) + { + throw RuntimeException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.container.NoSuchElementException: " ) ) + + e.Message, + static_cast< OWeakObject * >( this ) ); + } + OSL_ASSERT(ifc.is()); + if (resolveTypedefs(ifc)->getTypeClass() != TypeClass_INTERFACE) { + throw RuntimeException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "Single-interface--based service is not based on" + " interface type" ) ), + static_cast< OWeakObject * >( this ) ); + } + MutexGuard guard(getMutex()); + if (!_bInitReferences) { + _xInterfaceTD = ifc; + _bInitReferences = true; + } + } + else + { + sal_uInt16 nRefs = aReader.getReferenceCount(); + Sequence< Reference< XServiceTypeDescription > > aMandatoryServices( + nRefs); + Sequence< Reference< XServiceTypeDescription > > aOptionalServices( + nRefs); + Sequence< Reference< XInterfaceTypeDescription > > aMandatoryInterfaces( + nRefs); + Sequence< Reference< XInterfaceTypeDescription > > aOptionalInterfaces( + nRefs); + sal_uInt32 nMS = 0; + sal_uInt32 nOS = 0; + sal_uInt32 nMI = 0; + sal_uInt32 nOI = 0; + + for ( sal_uInt16 nPos = 0; nPos < nRefs; ++nPos ) + { + RTReferenceType eType = aReader.getReferenceSort( nPos ); + switch ( eType ) + { + case RT_REF_EXPORTS: // service + { + uno::Any aTypeDesc; + try + { + aTypeDesc = _xTDMgr->getByHierarchicalName( + aReader.getReferenceTypeName( nPos ).replace( + '/', '.' ) ); + } + catch ( NoSuchElementException const & e ) + { + throw RuntimeException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.container." + "NoSuchElementException: " ) ) + + e.Message, + static_cast< OWeakObject * >( this ) ); + } + + RTFieldAccess nAccess = aReader.getReferenceFlags( nPos ); + if ( nAccess & RT_ACCESS_OPTIONAL ) + { + // optional service + if ( !( aTypeDesc >>= aOptionalServices[ nOS ] ) ) + throw RuntimeException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "Service 'export' is not a service" ) ), + static_cast< OWeakObject * >( this ) ); + nOS++; + } + else + { + // mandatory service + if ( !( aTypeDesc >>= aMandatoryServices[ nMS ] ) ) + throw RuntimeException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "Service 'export' is not a service" ) ), + static_cast< OWeakObject * >( this ) ); + nMS++; + } + break; + } + case RT_REF_SUPPORTS: // interface + { + uno::Any aTypeDesc; + try + { + aTypeDesc = _xTDMgr->getByHierarchicalName( + aReader.getReferenceTypeName( nPos ).replace( + '/', '.' ) ); + } + catch ( NoSuchElementException const & e ) + { + throw RuntimeException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.container." + "NoSuchElementException: " ) ) + + e.Message, + static_cast< OWeakObject * >( this ) ); + } + + RTFieldAccess nAccess = aReader.getReferenceFlags( nPos ); + if ( nAccess & RT_ACCESS_OPTIONAL ) + { + // optional interface + if ( !( aTypeDesc >>= aOptionalInterfaces[ nOI ] ) ) + throw RuntimeException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "Service 'supports' is not an" + " interface" ) ), + static_cast< OWeakObject * >( this ) ); + nOI++; + } + else + { + // mandatory interface + if ( !( aTypeDesc >>= aMandatoryInterfaces[ nMI ] ) ) + throw RuntimeException( + OUString( + RTL_CONSTASCII_USTRINGPARAM( + "Service 'supports' is not an" + " interface" ) ), + static_cast< OWeakObject * >( this ) ); + nMI++; + } + break; + } + case RT_REF_OBSERVES: + case RT_REF_NEEDS: + break; + default: + OSL_ENSURE( sal_False, "### unsupported reference type!" ); + break; + } + } + aMandatoryServices.realloc( nMS ); + aOptionalServices.realloc( nOS ); + aMandatoryInterfaces.realloc( nMI ); + aOptionalInterfaces.realloc( nOI ); + + MutexGuard guard(getMutex()); + if (!_bInitReferences) { + _aMandatoryServices = aMandatoryServices; + _aOptionalServices = aOptionalServices; + _aMandatoryInterfaces = aMandatoryInterfaces; + _aOptionalInterfaces = aOptionalInterfaces; + _bInitReferences = true; + } + } +} + + +} |