/************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_stoc.hxx" #include #include #include #include "com/sun/star/uno/RuntimeException.hpp" #include "registry/reader.hxx" #include "registry/version.h" #include "base.hxx" #include "methoddescription.hxx" #include 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 > 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; } } } }