diff options
Diffstat (limited to 'stoc')
82 files changed, 32664 insertions, 0 deletions
diff --git a/stoc/prj/d.lst b/stoc/prj/d.lst new file mode 100644 index 000000000000..ae5dbff4a6de --- /dev/null +++ b/stoc/prj/d.lst @@ -0,0 +1,25 @@ +mkdir: %_DEST%\inc%_EXT%\stoc + +..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%\* +..\%__SRC%\lib\*.so %_DEST%\lib%_EXT%\* + +..\%__SRC%\bin\*.rdb %_DEST%\rdb%_EXT%\* + +..\source\componentdescription.dtd %_DEST%\xml%_EXT%\componentdescription.dtd + +..\source\corereflection\corefl.xml %_DEST%\xml%_EXT%\corefl.xml +..\source\defaultregistry\defreg.xml %_DEST%\xml%_EXT%\defreg.xml +..\source\implementationregistration\impreg.xml %_DEST%\xml%_EXT%\impreg.xml +..\source\inspect\insp.xml %_DEST%\xml%_EXT%\insp.xml +..\source\invocation\inv.xml %_DEST%\xml%_EXT%\inv.xml +..\source\invocation_adapterfactory\invadp.xml %_DEST%\xml%_EXT%\invadp.xml +..\source\io\io.xml %_DEST%\xml%_EXT%\io.xml +..\source\javavm\jen.xml %_DEST%\xml%_EXT%\jen.xml +..\source\loader\cpld.xml %_DEST%\xml%_EXT%\cpld.xml +..\source\namingservice\namingservice.xml %_DEST%\xml%_EXT%\namingservice.xml +..\source\proxy_factory\proxyfac.xml %_DEST%\xml%_EXT%\proxyfac.xml +..\source\registry_tdprovider\rdbtdp.xml %_DEST%\xml%_EXT%\rdbtdp.xml +..\source\servicemanager\smgr.xml %_DEST%\xml%_EXT%\smgr.xml +..\source\simpleregistry\simreg.xml %_DEST%\xml%_EXT%\simreg.xml +..\source\tdmanager\tdmgr.xml %_DEST%\xml%_EXT%\tdmgr.xml +..\source\typeconv\tcv.xml %_DEST%\xml%_EXT%\tcv.xml diff --git a/stoc/source/corereflection/base.hxx b/stoc/source/corereflection/base.hxx new file mode 100644 index 000000000000..671aec5306e6 --- /dev/null +++ b/stoc/source/corereflection/base.hxx @@ -0,0 +1,558 @@ +/************************************************************************* + * + * $RCSfile: base.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// #define TEST_LIST_CLASSES +// #define TRACE(x) OSL_TRACE(x) +#define TRACE(x) + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#ifndef _UNO_MAPPING_HXX_ +#include <uno/mapping.hxx> +#endif +#ifndef _UNO_DISPATCHER_H_ +#include <uno/dispatcher.h> +#endif + +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_COMPONENT_HXX_ +#include <cppuhelper/component.hxx> +#endif +#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ +#include <cppuhelper/typeprovider.hxx> +#endif + +#include "lrucache.hxx" + +#ifdef TEST_LIST_CLASSES +#include <stl/list> +#include <stl/algorithm> +#endif +#include <stl/hash_map> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> + +#include <com/sun/star/reflection/XIdlClass.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> +#include <com/sun/star/reflection/XIdlField.hpp> +#include <com/sun/star/reflection/XIdlMethod.hpp> + +using namespace std; +using namespace osl; +using namespace rtl; +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::reflection; +using namespace com::sun::star::container; + + +namespace stoc_corefl +{ + +#ifdef TEST_LIST_CLASSES +typedef list< OUString > ClassNameList; +extern ClassNameList g_aClassNames; +#endif + +//-------------------------------------------------------------------------------------------------- +Mutex & getMutexAccess(); + +//-------------------------------------------------------------------------------------------------- +inline td_equals( typelib_TypeDescription * pTD, + typelib_TypeDescriptionReference * pType ) +{ + return (pTD->pWeakRef == pType || + (pTD->pTypeName->length == pType->pTypeName->length && + rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0)); +} +//-------------------------------------------------------------------------------------------------- +inline typelib_TypeDescription * getTypeByName( const OUString & rName ) +{ + typelib_TypeDescription * pTypeDescr = 0; + typelib_typedescription_getByName( &pTypeDescr, rName.pData ); + if (! pTypeDescr->bComplete) + typelib_typedescription_complete( &pTypeDescr ); + return pTypeDescr; +} + +typedef std::hash_map< OUString, WeakReference< XIdlField >, + FctHashOUString, equal_to< OUString > > OUString2Field; +typedef std::hash_map< OUString, WeakReference< XIdlMethod >, + FctHashOUString, equal_to< OUString > > OUString2Method; + +//================================================================================================== +class IdlReflectionServiceImpl + : public OComponentHelper + , public XIdlReflection + , public XHierarchicalNameAccess + , public XServiceInfo +{ + Mutex _aComponentMutex; + Reference< XMultiServiceFactory > _xMgr; + Reference< XHierarchicalNameAccess > _xTDMgr; + + // caching + LRU_CacheAnyByOUString _aElements; + + inline Reference< XIdlClass > constructClass( typelib_TypeDescription * pTypeDescr ); +public: + Reference< XHierarchicalNameAccess > getTDMgr() const + { return _xTDMgr; } + Reference< XMultiServiceFactory > getSMgr() const + { return _xMgr; } + + // ctor/ dtor + IdlReflectionServiceImpl( const Reference< XMultiServiceFactory > & xMgr ); + virtual ~IdlReflectionServiceImpl(); + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // some XComponent part from OComponentHelper + virtual void SAL_CALL dispose() throw(::com::sun::star::uno::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); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XIdlReflection + virtual Reference< XIdlClass > SAL_CALL forName( const OUString & rTypeName ) throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlClass > SAL_CALL getType( const Any & rObj ) throw(::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); + + Reference< XIdlClass > forType( typelib_TypeDescription * pTypeDescr ) throw(::com::sun::star::uno::RuntimeException); + Reference< XIdlClass > forType( typelib_TypeDescriptionReference * pRef ) throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class IdlClassImpl + : public WeakImplHelper1< XIdlClass > +{ + IdlReflectionServiceImpl * _pReflection; + + OUString _aName; + TypeClass _eTypeClass; + + typelib_TypeDescription * _pTypeDescr; + +public: + typelib_TypeDescription * getTypeDescr() const + { return _pTypeDescr; } + IdlReflectionServiceImpl * getReflection() const + { return _pReflection; } + Reference< XMultiServiceFactory > getSMgr() const + { return _pReflection->getSMgr(); } + Reference< XHierarchicalNameAccess > getTDMgr() const + { return getReflection()->getTDMgr(); } + + // Ctor + IdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ); + virtual ~IdlClassImpl(); + + // XIdlClassImpl default implementation + virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL equals( const Reference< XIdlClass >& xType ) throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException); + + // def impl ???? + virtual Sequence< Reference< XIdlClass > > SAL_CALL getClasses() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlClass > SAL_CALL getClass( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlClass > > SAL_CALL getInterfaces() throw(::com::sun::star::uno::RuntimeException); + + // structs, interfaces + virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException); + // structs + virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException); + // interfaces + virtual Uik SAL_CALL getUik() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlMethod > SAL_CALL getMethod( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlMethod > > SAL_CALL getMethods() throw(::com::sun::star::uno::RuntimeException); + // array + virtual Reference< XIdlClass > SAL_CALL getComponentType() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlArray > SAL_CALL getArray() throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class InterfaceIdlClassImpl + : public IdlClassImpl +{ + typedef pair< OUString, typelib_TypeDescription * > MemberInit; + + Reference< XIdlClass > _xSuperClass; + + MemberInit * _pSortedMemberInit; // first methods, then attributes + OUString2Field _aName2Field; + OUString2Method _aName2Method; + sal_Int32 _nMethods; + sal_Int32 _nAttributes; + + void initMembers(); + +public: + typelib_InterfaceTypeDescription * getTypeDescr() const + { return (typelib_InterfaceTypeDescription *)IdlClassImpl::getTypeDescr(); } + + // ctor/ dtor + InterfaceIdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ) + : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr ) + , _pSortedMemberInit( 0 ) + , _nMethods( 0 ) + , _nAttributes( 0 ) + {} + virtual ~InterfaceIdlClassImpl(); + + // IdlClassImpl modifications + virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException); + virtual Uik SAL_CALL getUik() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlMethod > SAL_CALL getMethod( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlMethod > > SAL_CALL getMethods() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class CompoundIdlClassImpl + : public IdlClassImpl +{ + Reference< XIdlClass > _xSuperClass; + + Sequence< Reference< XIdlField > > * _pFields; + OUString2Field _aName2Field; + +public: + typelib_CompoundTypeDescription * getTypeDescr() const + { return (typelib_CompoundTypeDescription *)IdlClassImpl::getTypeDescr(); } + + // ctor/ dtor + CompoundIdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ) + : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr ) + , _pFields( 0 ) + {} + virtual ~CompoundIdlClassImpl(); + + // IdlClassImpl modifications + virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class ArrayIdlClassImpl + : public IdlClassImpl + , public XIdlArray +{ +public: + typelib_IndirectTypeDescription * getTypeDescr() const + { return (typelib_IndirectTypeDescription *)IdlClassImpl::getTypeDescr(); } + + // ctor + ArrayIdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ) + : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr ) + {} + + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // IdlClassImpl modifications + virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlClass > SAL_CALL getComponentType() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XIdlArray > SAL_CALL getArray() throw(::com::sun::star::uno::RuntimeException); + + // XIdlArray + virtual void SAL_CALL realloc( Any & rArray, sal_Int32 nLen ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getLen( const Any & rArray ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL get( const Any & rArray, sal_Int32 nIndex ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL set( Any & rArray, sal_Int32 nIndex, const Any & rNewValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class EnumIdlClassImpl + : public IdlClassImpl +{ + Sequence< Reference< XIdlField > > * _pFields; + OUString2Field _aName2Field; + +public: + typelib_EnumTypeDescription * getTypeDescr() const + { return (typelib_EnumTypeDescription *)IdlClassImpl::getTypeDescr(); } + + // ctor/ dtor + EnumIdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ) + : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr ) + , _pFields( 0 ) + {} + virtual ~EnumIdlClassImpl(); + + // IdlClassImpl modifications + virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class IdlMemberImpl + : public WeakImplHelper1< XIdlMember > +{ + Mapping _aCpp2Uno; + Mapping _aUno2Cpp; + + IdlReflectionServiceImpl * _pReflection; + OUString _aName; + + typelib_TypeDescription * _pTypeDescr; + typelib_TypeDescription * _pDeclTypeDescr; + +protected: + Reference< XIdlClass > _xDeclClass; + +public: + IdlReflectionServiceImpl * getReflection() const + { return _pReflection; } + Reference< XMultiServiceFactory > getSMgr() const + { return _pReflection->getSMgr(); } + typelib_TypeDescription * getTypeDescr() const + { return _pTypeDescr; } + typelib_TypeDescription * getDeclTypeDescr() const + { return _pDeclTypeDescr; } + + inline const Mapping & getCpp2Uno() throw(::com::sun::star::uno::RuntimeException); + inline const Mapping & getUno2Cpp() throw(::com::sun::star::uno::RuntimeException); + inline uno_Interface * mapToUno( const Any & rObj, typelib_InterfaceTypeDescription * pTo ) throw(::com::sun::star::uno::RuntimeException); + + // ctor/ dtor + IdlMemberImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr ); + virtual ~IdlMemberImpl(); + + // XIdlMember + virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); +}; +//__________________________________________________________________________________________________ +inline const Mapping & IdlMemberImpl::getCpp2Uno() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _aCpp2Uno.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _aCpp2Uno.is()) + { + _aCpp2Uno = Mapping( OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ), + OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ) ); + OSL_ENSHURE( _aCpp2Uno.is(), "### cannot c++ to uno mapping!" ); + if (! _aCpp2Uno.is()) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot c++ to uno mapping!") ), + (XWeak *)(OWeakObject *)this ); + } + } + } + return _aCpp2Uno; +} +//__________________________________________________________________________________________________ +inline const Mapping & IdlMemberImpl::getUno2Cpp() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _aUno2Cpp.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _aUno2Cpp.is()) + { + _aUno2Cpp = Mapping( OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ), + OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ) ); + OSL_ENSHURE( _aUno2Cpp.is(), "### cannot uno to c++ mapping!" ); + if (! _aUno2Cpp.is()) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot uno TO c++ mapping!") ), + (XWeak *)(OWeakObject *)this ); + } + } + } + return _aUno2Cpp; +} + +//-------------------------------------------------------------------------------------------------- +// coerces to type descr pTo else queries for it: the interface pointer is returned via rDest +// ## type to XidlClass coercion possible +inline sal_Bool extract( + const Any & rObj, typelib_InterfaceTypeDescription * pTo, + Reference< XInterface > & rDest, + IdlReflectionServiceImpl * pRefl ) +{ + rDest.clear(); + if (rObj.hasValue() && pTo) + { + if (rObj.getValueTypeClass() == TypeClass_INTERFACE) + { + return ::uno_type_assignData( + &rDest, ((typelib_TypeDescription *)pTo)->pWeakRef, + const_cast< void * >( rObj.getValue() ), rObj.getValueTypeRef(), + cpp_queryInterface, cpp_acquire, cpp_release ); + } + else if (rObj.getValueTypeClass() == TypeClass_TYPE) + { + rDest = pRefl->forType( reinterpret_cast< const Type * >( rObj.getValue() )->getTypeLibType() ); + return rDest.is(); + } + } + return sal_False; +} +//-------------------------------------------------------------------------------------------------- +inline sal_Bool coerce_assign( + void * pDest, typelib_TypeDescription * pTD, const Any & rSource, + IdlReflectionServiceImpl * pRefl ) +{ + if (rSource.hasValue()) + { + if (pTD->eTypeClass == typelib_TypeClass_INTERFACE) + { + Reference< XInterface > xVal; + if (extract( rSource, (typelib_InterfaceTypeDescription *)pTD, xVal, pRefl )) + { + if (*(XInterface **)pDest) + (*(XInterface **)pDest)->release(); + if (*(XInterface **)pDest = xVal.get()) + (*(XInterface **)pDest)->acquire(); + return sal_True; + } + } + else if (pTD->eTypeClass == typelib_TypeClass_ANY) + { + return uno_assignData( + pDest, pTD, + (void *)&rSource, pTD, + cpp_queryInterface, cpp_acquire, cpp_release ); + } + else + { + return uno_type_assignData( + pDest, pTD->pWeakRef, + (void *)rSource.getValue(), rSource.getValueTypeRef(), + cpp_queryInterface, cpp_acquire, cpp_release ); + } + } + return sal_False; +} + +//__________________________________________________________________________________________________ +inline uno_Interface * IdlMemberImpl::mapToUno( const Any & rObj, + typelib_InterfaceTypeDescription * pTo ) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XInterface > xObj; + if (extract( rObj, pTo, xObj, getReflection() )) + return (uno_Interface *)getCpp2Uno().mapInterface( xObj.get(), pTo ); + + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ), + (XWeak *)(OWeakObject *)this ); + return 0; // dummy +} + +} + + diff --git a/stoc/source/corereflection/corefl.xml b/stoc/source/corereflection/corefl.xml new file mode 100644 index 000000000000..657870225bc6 --- /dev/null +++ b/stoc/source/corereflection/corefl.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE COMPONENTDESCRIPTION PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "componentdescription.dtd"> + +<COMPONENTDESCRIPTION + xmlns:xlink="http://www.w3.org/1999/xlink/Namespace" > + +<Author> Daniel Boelzle </Author> +<Name> com.sun.star.comp.stoc.CoreReflection </Name> + +<Description> +This service is the implementation of XIdlClassProvider. +The service provides reflection and access to all uno types +(interfaces, structs, enums, ...). +</Description> + +<ModuleName> corefl </ModuleName> + +<LoaderName> com.sun.star.loader.SharedLibrary </LoaderName> + +<Language> C++ </Language> + +<Status StatusValue="final"/> + +<SupportedService> com.sun.star.reflection.CoreReflection </SupportedService> + +<ServiceDependency> +</ServiceDependency> + +<ProjectBuildDependency> cppuhelper </ProjectBuildDependency> +<ProjectBuildDependency> cppu </ProjectBuildDependency> +<ProjectBuildDependency> sal </ProjectBuildDependency> + +<RuntimeModuleDependency> cppuhelper </RuntimeModuleDependency> +<RuntimeModuleDependency> cppu </RuntimeModuleDependency> +<RuntimeModuleDependency> sal </RuntimeModuleDependency> + +<Type> com.sun.star.reflection.XTypeDescription </Type> +<Type> com.sun.star.reflection.XIdlReflection </Type> +<Type> com.sun.star.reflection.XIdlClass </Type> +<Type> com.sun.star.container.XHierarchicalNameAccess </Type> +<Type> com.sun.star.lang.XComponent </Type> +<Type> com.sun.star.lang.XTypeProvider </Type> +<Type> com.sun.star.lang.XServiceInfo </Type> +<Type> com.sun.star.lang.XSingleServiceFactory </Type> +<Type> com.sun.star.lang.XMultiServiceFactory </Type> +<Type> com.sun.star.registry.XRegistryKey </Type> +<Type> com.sun.star.uno.XAggregation </Type> +<Type> com.sun.star.uno.XWeak </Type> +<Type> com.sun.star.uno.TypeClass </Type> + +</COMPONENTDESCRIPTION> + diff --git a/stoc/source/corereflection/crarray.cxx b/stoc/source/corereflection/crarray.cxx new file mode 100644 index 000000000000..fba501bc6f24 --- /dev/null +++ b/stoc/source/corereflection/crarray.cxx @@ -0,0 +1,262 @@ +/************************************************************************* + * + * $RCSfile: crarray.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _TYPELIB_TYPEDESCRIPTION_H_ +#include <typelib/typedescription.h> +#endif +#ifndef _UNO_DATA_H_ +#include <uno/data.h> +#endif + +#include "base.hxx" + + +namespace stoc_corefl +{ + +// XInterface +//__________________________________________________________________________________________________ +Any ArrayIdlClassImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlArray * >( this ) ) ); + return (aRet.hasValue() ? aRet : IdlClassImpl::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void ArrayIdlClassImpl::acquire() throw() +{ + IdlClassImpl::acquire(); +} +//__________________________________________________________________________________________________ +void ArrayIdlClassImpl::release() throw() +{ + IdlClassImpl::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > ArrayIdlClassImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlArray > *)0 ), + IdlClassImpl::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > ArrayIdlClassImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XIdlArray +//__________________________________________________________________________________________________ +void ArrayIdlClassImpl::realloc( Any & rArray, sal_Int32 nLen ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + TypeClass eTC = rArray.getValueTypeClass(); + if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + if (nLen < 0) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal length given!") ), + (XWeak *)(OWeakObject *)this, 1 ); + } + + uno_Sequence ** ppSeq = (uno_Sequence **)rArray.getValue(); + uno_sequence_realloc( ppSeq, (typelib_TypeDescription *)getTypeDescr(), + nLen, cpp_acquire, cpp_release ); + rArray.pData = ppSeq; +} +//__________________________________________________________________________________________________ +sal_Int32 ArrayIdlClassImpl::getLen( const Any & rArray ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + TypeClass eTC = rArray.getValueTypeClass(); + if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + + return (*(uno_Sequence **)rArray.getValue())->nElements; +} +//__________________________________________________________________________________________________ +Any ArrayIdlClassImpl::get( const Any & rArray, sal_Int32 nIndex ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) +{ + TypeClass eTC = rArray.getValueTypeClass(); + if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + + uno_Sequence * pSeq = *(uno_Sequence **)rArray.getValue(); + if (pSeq->nElements <= nIndex) + { + throw ArrayIndexOutOfBoundsException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal index given!") ), + (XWeak *)(OWeakObject *)this ); + } + + Any aRet; + typelib_TypeDescription * pElemTypeDescr = 0; + TYPELIB_DANGER_GET( &pElemTypeDescr, getTypeDescr()->pType ); + uno_any_destruct( &aRet, cpp_release ); + uno_any_construct( &aRet, &pSeq->elements[nIndex * pElemTypeDescr->nSize], + pElemTypeDescr, cpp_acquire ); + TYPELIB_DANGER_RELEASE( pElemTypeDescr ); + return aRet; +} + +//__________________________________________________________________________________________________ +void ArrayIdlClassImpl::set( Any & rArray, sal_Int32 nIndex, const Any & rNewValue ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) +{ + TypeClass eTC = rArray.getValueTypeClass(); + if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + + uno_Sequence * pSeq = *(uno_Sequence **)rArray.getValue(); + if (pSeq->nElements <= nIndex) + { + throw ArrayIndexOutOfBoundsException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal index given!") ), + (XWeak *)(OWeakObject *)this ); + } + + uno_Sequence ** ppSeq = (uno_Sequence **)rArray.getValue(); + uno_sequence_reference2One( ppSeq, (typelib_TypeDescription *)getTypeDescr(), cpp_acquire, cpp_release ); + rArray.pData = ppSeq; + pSeq = *ppSeq; + + typelib_TypeDescription * pElemTypeDescr = 0; + TYPELIB_DANGER_GET( &pElemTypeDescr, getTypeDescr()->pType ); + + if (! coerce_assign( &pSeq->elements[nIndex * pElemTypeDescr->nSize], + pElemTypeDescr, rNewValue, getReflection() )) + { + TYPELIB_DANGER_RELEASE( pElemTypeDescr ); + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("sequence element is not assignable by given value!") ), + (XWeak *)(OWeakObject *)this, 2 ); + } + TYPELIB_DANGER_RELEASE( pElemTypeDescr ); +} + +// ArrayIdlClassImpl +//__________________________________________________________________________________________________ +sal_Bool ArrayIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType ) + throw(::com::sun::star::uno::RuntimeException) +{ + return (xType.is() && + (equals( xType ) || + (xType->getTypeClass() == getTypeClass() && // must be sequence|array + getComponentType()->isAssignableFrom( xType->getComponentType() )))); +} +//__________________________________________________________________________________________________ +Reference< XIdlClass > ArrayIdlClassImpl::getComponentType() + throw(::com::sun::star::uno::RuntimeException) +{ + return getReflection()->forType( getTypeDescr()->pType ); +} +//__________________________________________________________________________________________________ +Reference< XIdlArray > ArrayIdlClassImpl::getArray() + throw(::com::sun::star::uno::RuntimeException) +{ + return this; +} + +} + + diff --git a/stoc/source/corereflection/crbase.cxx b/stoc/source/corereflection/crbase.cxx new file mode 100644 index 000000000000..91250d0f4d4c --- /dev/null +++ b/stoc/source/corereflection/crbase.cxx @@ -0,0 +1,318 @@ +/************************************************************************* + * + * $RCSfile: crbase.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _UNO_ANY2_H_ +#include <uno/any2.h> +#endif + +#include "base.hxx" + +namespace stoc_corefl +{ + +#ifdef TEST_LIST_CLASSES +ClassNameList g_aClassNames; +#endif + +//-------------------------------------------------------------------------------------------------- +Mutex & getMutexAccess() +{ + static Mutex * s_pMutex = 0; + if (! s_pMutex) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pMutex) + { + static Mutex s_aMutex; + s_pMutex = &s_aMutex; + } + } + return *s_pMutex; +} + +//__________________________________________________________________________________________________ +IdlClassImpl::IdlClassImpl( IdlReflectionServiceImpl * pReflection, + const OUString & rName, typelib_TypeClass eTypeClass, + typelib_TypeDescription * pTypeDescr ) + : _pReflection( pReflection ) + , _aName( rName ) + , _eTypeClass( (TypeClass)eTypeClass ) + , _pTypeDescr( pTypeDescr ) +{ + if (_pReflection) + _pReflection->acquire(); + if (_pTypeDescr) + { + typelib_typedescription_acquire( _pTypeDescr ); + if (! _pTypeDescr->bComplete) + typelib_typedescription_complete( &_pTypeDescr ); + } + +#ifdef TEST_LIST_CLASSES + ClassNameList::const_iterator iFind( find( g_aClassNames.begin(), g_aClassNames.end(), _aName ) ); + OSL_ENSHURE( iFind == g_aClassNames.end(), "### idl class already exists!" ); + g_aClassNames.push_front( _aName ); +#endif +} +//__________________________________________________________________________________________________ +IdlClassImpl::~IdlClassImpl() +{ + if (_pTypeDescr) + typelib_typedescription_release( _pTypeDescr ); + if (_pReflection) + _pReflection->release(); + +#ifdef TEST_LIST_CLASSES + ClassNameList::iterator iFind( find( g_aClassNames.begin(), g_aClassNames.end(), _aName ) ); + OSL_ENSHURE( iFind != g_aClassNames.end(), "### idl class does not exist!" ); + g_aClassNames.erase( iFind ); +#endif +} + +// XIdlClassImpl default implementation +//__________________________________________________________________________________________________ +TypeClass IdlClassImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return _eTypeClass; +} +//__________________________________________________________________________________________________ +OUString IdlClassImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} +//__________________________________________________________________________________________________ +sal_Bool IdlClassImpl::equals( const Reference< XIdlClass >& xType ) + throw(::com::sun::star::uno::RuntimeException) +{ + return (xType.is() && + (xType->getTypeClass() == _eTypeClass) && (xType->getName() == _aName)); +} + +static sal_Bool s_aAssignableFromTab[11][11] = +{ + /* from CH,BO,BY,SH,US,LO,UL,HY,UH,FL,DO */ +/* TypeClass_CHAR */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +/* TypeClass_BOOLEAN */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +/* TypeClass_BYTE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, +/* TypeClass_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 }, +/* TypeClass_UNSIGNED_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 }, +/* TypeClass_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, +/* TypeClass_UNSIGNED_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, +/* TypeClass_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, +/* TypeClass_UNSIGNED_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, +/* TypeClass_FLOAT */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, +/* TypeClass_DOUBLE */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 } +}; +//__________________________________________________________________________________________________ +sal_Bool IdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType ) + throw(::com::sun::star::uno::RuntimeException) +{ + TypeClass eAssign = getTypeClass(); + if (equals( xType ) || eAssign == TypeClass_ANY) // default shot + { + return sal_True; + } + else + { + TypeClass eFrom = xType->getTypeClass(); + if (eAssign > TypeClass_VOID && eAssign < TypeClass_STRING && + eFrom > TypeClass_VOID && eFrom < TypeClass_STRING) + { + return s_aAssignableFromTab[eAssign-1][eFrom-1]; + } + } + return sal_False; +} +//__________________________________________________________________________________________________ +void IdlClassImpl::createObject( Any & rObj ) + throw(::com::sun::star::uno::RuntimeException) +{ + rObj.clear(); + uno_any_destruct( &rObj, cpp_release ); + uno_any_construct( &rObj, 0, getTypeDescr(), 0 ); +} + +// what TODO ???? +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > IdlClassImpl::getClasses() + throw(::com::sun::star::uno::RuntimeException) +{ + OSL_ENSHURE( sal_False, "### unexpected use!" ); + return Sequence< Reference< XIdlClass > >(); +} +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlClassImpl::getClass( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + OSL_ENSHURE( sal_False, "### unexpected use!" ); + return Reference< XIdlClass >(); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > IdlClassImpl::getInterfaces() + throw(::com::sun::star::uno::RuntimeException) +{ +// OSL_ENSHURE( sal_False, "### unexpected use!" ); + return Sequence< Reference< XIdlClass > >(); +} + +// structs, interfaces +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > IdlClassImpl::getSuperclasses() throw(::com::sun::star::uno::RuntimeException) +{ + return Sequence< Reference< XIdlClass > >(); +} +// structs +//__________________________________________________________________________________________________ +Reference< XIdlField > IdlClassImpl::getField( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + return Reference< XIdlField >(); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlField > > IdlClassImpl::getFields() + throw(::com::sun::star::uno::RuntimeException) +{ + return Sequence< Reference< XIdlField > >(); +} +// interfaces +//__________________________________________________________________________________________________ +Uik IdlClassImpl::getUik() + throw(::com::sun::star::uno::RuntimeException) +{ + return Uik(); +} +//__________________________________________________________________________________________________ +Reference< XIdlMethod > IdlClassImpl::getMethod( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + return Reference< XIdlMethod >(); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlMethod > > IdlClassImpl::getMethods() + throw(::com::sun::star::uno::RuntimeException) +{ + return Sequence< Reference< XIdlMethod > >(); +} +// array +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlClassImpl::getComponentType() + throw(::com::sun::star::uno::RuntimeException) +{ + return Reference< XIdlClass >(); +} +//__________________________________________________________________________________________________ +Reference< XIdlArray > IdlClassImpl::getArray() + throw(::com::sun::star::uno::RuntimeException) +{ + return Reference< XIdlArray >(); +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +IdlMemberImpl::IdlMemberImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, + typelib_TypeDescription * pDeclTypeDescr ) + : _pReflection( pReflection ) + , _aName( rName ) + , _pTypeDescr( pTypeDescr ) + , _pDeclTypeDescr( pDeclTypeDescr ) +{ + _pReflection->acquire(); + typelib_typedescription_acquire( _pTypeDescr ); + typelib_typedescription_acquire( _pDeclTypeDescr ); +} +//__________________________________________________________________________________________________ +IdlMemberImpl::~IdlMemberImpl() +{ + typelib_typedescription_release( _pDeclTypeDescr ); + typelib_typedescription_release( _pTypeDescr ); + _pReflection->release(); +} + +// XIdlMember +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlMemberImpl::getDeclaringClass() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xDeclClass.is()) + _xDeclClass = getReflection()->forType( getDeclTypeDescr() ); + return _xDeclClass; +} +//__________________________________________________________________________________________________ +OUString IdlMemberImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} + +} + + diff --git a/stoc/source/corereflection/crcomp.cxx b/stoc/source/corereflection/crcomp.cxx new file mode 100644 index 000000000000..4743f3d1c9ab --- /dev/null +++ b/stoc/source/corereflection/crcomp.cxx @@ -0,0 +1,393 @@ +/************************************************************************* + * + * $RCSfile: crcomp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _RTL_STRBUF_HXX_ +#include <rtl/strbuf.hxx> +#endif + +#include <com/sun/star/reflection/XIdlField.hpp> + +#include "base.hxx" + + +namespace stoc_corefl +{ + +//================================================================================================== +class IdlCompFieldImpl + : public IdlMemberImpl + , public XIdlField +{ + sal_Int32 _nOffset; + +public: + IdlCompFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr, + sal_Int32 nOffset ) + : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr ) + , _nOffset( nOffset ) + {} + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XIdlMember + virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + // XIdlField + virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); + virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL set( const Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException); +}; + +// XInterface +//__________________________________________________________________________________________________ +Any IdlCompFieldImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlField * >( this ) ) ); + return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void IdlCompFieldImpl::acquire() throw() +{ + IdlMemberImpl::acquire(); +} +//__________________________________________________________________________________________________ +void IdlCompFieldImpl::release() throw() +{ + IdlMemberImpl::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > IdlCompFieldImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlField > *)0 ), + IdlMemberImpl::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > IdlCompFieldImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XIdlMember +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlCompFieldImpl::getDeclaringClass() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xDeclClass.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _xDeclClass.is()) + { + typelib_CompoundTypeDescription * pTD = + (typelib_CompoundTypeDescription *)getDeclTypeDescr(); + while (pTD) + { + typelib_TypeDescriptionReference ** ppTypeRefs = pTD->ppTypeRefs; + for ( sal_Int32 nPos = pTD->nMembers; nPos--; ) + { + if (td_equals( (typelib_TypeDescription *)getTypeDescr(), ppTypeRefs[nPos] )) + { + _xDeclClass = getReflection()->forType( (typelib_TypeDescription *)pTD ); + return _xDeclClass; + } + } + pTD = pTD->pBaseTypeDescription; + } + } + } + return _xDeclClass; +} +//__________________________________________________________________________________________________ +OUString IdlCompFieldImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return IdlMemberImpl::getName(); +} + +// XIdlField +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlCompFieldImpl::getType() + throw(::com::sun::star::uno::RuntimeException) +{ + return getReflection()->forType( getTypeDescr() ); +} +//__________________________________________________________________________________________________ +FieldAccessMode IdlCompFieldImpl::getAccessMode() + throw(::com::sun::star::uno::RuntimeException) +{ + return FieldAccessMode_READWRITE; +} +//__________________________________________________________________________________________________ +Any IdlCompFieldImpl::get( const Any & rObj ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + if (rObj.getValueTypeClass() == typelib_TypeClass_STRUCT || + rObj.getValueTypeClass() == typelib_TypeClass_EXCEPTION) + { + typelib_TypeDescription * pObjTD = 0; + TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() ); + + typelib_TypeDescription * pTD = pObjTD; + typelib_TypeDescription * pDeclTD = getDeclTypeDescr(); + while (pTD && !typelib_typedescription_equals( pTD, pDeclTD )) + pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription; + + OSL_ENSHURE( pTD, "### illegal object type!" ); + if (pTD) + { + TYPELIB_DANGER_RELEASE( pObjTD ); + Any aRet; + uno_any_destruct( &aRet, cpp_release ); + uno_any_construct( &aRet, (char *)rObj.getValue() + _nOffset, getTypeDescr(), cpp_acquire ); + return aRet; + } + TYPELIB_DANGER_RELEASE( pObjTD ); + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + return Any(); // dummy +} +//__________________________________________________________________________________________________ +void IdlCompFieldImpl::set( const Any & rObj, const Any & rValue ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) +{ + if (rObj.getValueTypeClass() == typelib_TypeClass_STRUCT || + rObj.getValueTypeClass() == typelib_TypeClass_EXCEPTION) + { + typelib_TypeDescription * pObjTD = 0; + TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() ); + + typelib_TypeDescription * pTD = pObjTD; + typelib_TypeDescription * pDeclTD = getDeclTypeDescr(); + while (pTD && !typelib_typedescription_equals( pTD, pDeclTD )) + pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription; + + OSL_ENSHURE( pTD, "### illegal object type!" ); + if (pTD) + { + TYPELIB_DANGER_RELEASE( pObjTD ); + if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() )) + { + return; + } + else + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ), + (XWeak *)(OWeakObject *)this, 1 ); + } + } + TYPELIB_DANGER_RELEASE( pObjTD ); + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +CompoundIdlClassImpl::~CompoundIdlClassImpl() +{ + delete _pFields; +} + +//__________________________________________________________________________________________________ +sal_Bool CompoundIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType ) + throw(::com::sun::star::uno::RuntimeException) +{ + if (xType.is()) + { + TypeClass eTC = xType->getTypeClass(); + if (eTC == TypeClass_STRUCT || eTC == TypeClass_EXCEPTION) + { + if (equals( xType )) + return sal_True; + else + { + const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses(); + if (rSeq.getLength()) + { + OSL_ENSHURE( rSeq.getLength() == 1, "### unexpected len of super classes!" ); + return isAssignableFrom( rSeq[0] ); + } + } + } + } + return sal_False; +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > CompoundIdlClassImpl::getSuperclasses() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xSuperClass.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _xSuperClass.is()) + { + typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr()->pBaseTypeDescription; + if (pCompTypeDescr) + _xSuperClass = getReflection()->forType( (typelib_TypeDescription *)pCompTypeDescr ); + } + } + if (_xSuperClass.is()) + return Sequence< Reference< XIdlClass > >( &_xSuperClass, 1 ); + else + return Sequence< Reference< XIdlClass > >(); +} +//__________________________________________________________________________________________________ +Reference< XIdlField > CompoundIdlClassImpl::getField( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pFields) + getFields(); // init fields + + const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) ); + if (iFind != _aName2Field.end()) + return Reference< XIdlField >( (*iFind).second ); + else + return Reference< XIdlField >(); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlField > > CompoundIdlClassImpl::getFields() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( getMutexAccess() ); + if (! _pFields) + { + sal_Int32 nAll = 0; + typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr(); + for ( ; pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription ) + nAll += pCompTypeDescr->nMembers; + + Sequence< Reference< XIdlField > > * pFields = + new Sequence< Reference< XIdlField > >( nAll ); + Reference< XIdlField > * pSeq = pFields->getArray(); + + for ( pCompTypeDescr = getTypeDescr(); pCompTypeDescr; + pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription ) + { + typelib_TypeDescriptionReference ** ppTypeRefs = pCompTypeDescr->ppTypeRefs; + rtl_uString ** ppNames = pCompTypeDescr->ppMemberNames; + sal_Int32 * pMemberOffsets = pCompTypeDescr->pMemberOffsets; + + for ( sal_Int32 nPos = pCompTypeDescr->nMembers; nPos--; ) + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, ppTypeRefs[nPos] ); + OSL_ENSHURE( pTD, "### cannot get field in struct!" ); + if (pTD) + { + OUString aName( ppNames[nPos] ); + _aName2Field[aName] = pSeq[--nAll] = new IdlCompFieldImpl( + getReflection(), aName, pTD, IdlClassImpl::getTypeDescr(), pMemberOffsets[nPos] ); + TYPELIB_DANGER_RELEASE( pTD ); + } + } + } + + _pFields = pFields; + } + return *_pFields; +} + +} + + diff --git a/stoc/source/corereflection/crefl.cxx b/stoc/source/corereflection/crefl.cxx new file mode 100644 index 000000000000..7a280a6eae4e --- /dev/null +++ b/stoc/source/corereflection/crefl.cxx @@ -0,0 +1,488 @@ +/************************************************************************* + * + * $RCSfile: crefl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif + +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/reflection/XTypeDescription.hpp> + +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; + +#include "base.hxx" + + +namespace stoc_corefl +{ + +static const sal_Int32 CACHE_SIZE = 256; + +#define SERVICENAME "com.sun.star.reflection.CoreReflection" +#define IMPLNAME "com.sun.star.comp.stoc.CoreReflection" + +//-------------------------------------------------------------------------------------------------- +inline static Sequence< OUString > getSupportedServiceNames() +{ + OUString aName( OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ) ); + return Sequence< OUString >( &aName, 1 ); +} + +//__________________________________________________________________________________________________ +IdlReflectionServiceImpl::IdlReflectionServiceImpl( const Reference< XMultiServiceFactory > & xMgr ) + : OComponentHelper( _aComponentMutex ) + , _xMgr( xMgr ) + , _xTDMgr( xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.TypeDescriptionManager") ) ), + UNO_QUERY ) + , _aElements( CACHE_SIZE ) +{ + OSL_ENSHURE( _xTDMgr.is(), "### cannot get service \"com.sun.star.reflection.TypeDescriptionManager\"!" ); +} +//__________________________________________________________________________________________________ +IdlReflectionServiceImpl::~IdlReflectionServiceImpl() +{ + TRACE( "> IdlReflectionServiceImpl dtor <\n" ); +} + +// XInterface +//__________________________________________________________________________________________________ +Any IdlReflectionServiceImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( + rType, + static_cast< XIdlReflection * >( this ), + static_cast< XHierarchicalNameAccess * >( this ), + static_cast< XServiceInfo * >( this ) ) ); + + return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void IdlReflectionServiceImpl::acquire() throw() +{ + OComponentHelper::acquire(); +} +//__________________________________________________________________________________________________ +void IdlReflectionServiceImpl::release() throw() +{ + OComponentHelper::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > IdlReflectionServiceImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( _aComponentMutex ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlReflection > *)0 ), + ::getCppuType( (const Reference< XHierarchicalNameAccess > *)0 ), + ::getCppuType( (const Reference< XServiceInfo > *)0 ), + OComponentHelper::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > IdlReflectionServiceImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( _aComponentMutex ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XComponent +//__________________________________________________________________________________________________ +void IdlReflectionServiceImpl::dispose() + throw(::com::sun::star::uno::RuntimeException) +{ + TRACE( "> disposing corereflection... <" ); + OComponentHelper::dispose(); + + MutexGuard aGuard( _aComponentMutex ); + _aElements.clear(); + _xTDMgr.clear(); + _xMgr.clear(); +#ifdef TEST_LIST_CLASSES + OSL_ENSHURE( g_aClassNames.size() == 0, "### idl classes still alive!" ); + ClassNameList::const_iterator iPos( g_aClassNames.begin() ); + while (iPos != g_aClassNames.end()) + { + OUString aName( *iPos ); + ++iPos; + } +#endif +} + +// XServiceInfo +//__________________________________________________________________________________________________ +OUString IdlReflectionServiceImpl::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ); +} +//__________________________________________________________________________________________________ +sal_Bool IdlReflectionServiceImpl::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 > IdlReflectionServiceImpl::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + return stoc_corefl::getSupportedServiceNames(); +} + +// XIdlReflection +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlReflectionServiceImpl::getType( const Any & rObj ) + throw(::com::sun::star::uno::RuntimeException) +{ + return (rObj.hasValue() ? forType( rObj.getValueTypeRef() ) : Reference< XIdlClass >()); +} + +//__________________________________________________________________________________________________ +inline Reference< XIdlClass > IdlReflectionServiceImpl::constructClass( + typelib_TypeDescription * pTypeDescr ) +{ + OSL_ENSHURE( pTypeDescr->eTypeClass != typelib_TypeClass_TYPEDEF, "### unexpected typedef!" ); + + switch (pTypeDescr->eTypeClass) + { + case typelib_TypeClass_VOID: + case typelib_TypeClass_CHAR: + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + case typelib_TypeClass_FLOAT: + case typelib_TypeClass_DOUBLE: + case typelib_TypeClass_STRING: + case typelib_TypeClass_ANY: + return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + case TypeClass_ENUM: + return new EnumIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_UNION: + case typelib_TypeClass_EXCEPTION: + return new CompoundIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + case typelib_TypeClass_ARRAY: + case typelib_TypeClass_SEQUENCE: + return new ArrayIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + case typelib_TypeClass_INTERFACE: + return new InterfaceIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); + + case typelib_TypeClass_TYPE: + return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr ); +#ifdef DEBUG + case typelib_TypeClass_INTERFACE_METHOD: + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + case typelib_TypeClass_SERVICE: + case typelib_TypeClass_MODULE: + case typelib_TypeClass_UNKNOWN: + case typelib_TypeClass_TYPEDEF: + default: + OSL_TRACE( "### corereflection type unsupported: " ); + OString aName( OUStringToOString( pTypeDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( aName.getStr() ); + OSL_TRACE( "\n" ); +#endif + } + return Reference< XIdlClass >(); +} +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlReflectionServiceImpl::forName( const OUString & rTypeName ) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XIdlClass > xRet; + Any aAny( _aElements.getValue( rTypeName ) ); + + if (aAny.hasValue()) + { + if (aAny.getValueTypeClass() == TypeClass_INTERFACE) + xRet = *(const Reference< XIdlClass > *)aAny.getValue(); + } + else + { + // try to get _type_ by name + typelib_TypeDescription * pTD = 0; + typelib_typedescription_getByName( &pTD, rTypeName.pData ); + if (pTD) + { + if ((xRet = constructClass( pTD )).is()) + _aElements.setValue( rTypeName, makeAny( xRet ) ); // update + typelib_typedescription_release( pTD ); + } + } + + return xRet; +} + +// XHierarchicalNameAccess +//__________________________________________________________________________________________________ +Any IdlReflectionServiceImpl::getByHierarchicalName( const OUString & rName ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException) +{ + Any aRet( _aElements.getValue( rName ) ); + if (! aRet.hasValue()) + { + // first look for constants exclusivly! + aRet = _xTDMgr->getByHierarchicalName( rName ); + if (aRet.getValueTypeClass() == TypeClass_INTERFACE) // if no constant, + // i.e. XTypeDescription for a type + { + // type retrieved from tdmgr + OSL_ASSERT( (*(Reference< XInterface > *)aRet.getValue())->queryInterface( + ::getCppuType( (const Reference< XTypeDescription > *)0 ) ).hasValue() ); + + // if you are interested in a type then CALL forName()!!! + // this way is NOT recommended for types, because this method looks for constants first + + // if td manager found some type, it will be in the cache (hopefully.. we just got it) + // so the second retrieving via c typelib callback chain should succeed... + + // try to get _type_ by name + typelib_TypeDescription * pTD = 0; + typelib_typedescription_getByName( &pTD, rName.pData ); + + aRet.clear(); // kick XTypeDescription interface + + if (pTD) + { + Reference< XIdlClass > xIdlClass( constructClass( pTD ) ); + aRet.setValue( &xIdlClass, ::getCppuType( (const Reference< XIdlClass > *)0 ) ); + typelib_typedescription_release( pTD ); + } + } + // else is constant + + // update + if (aRet.hasValue()) + _aElements.setValue( rName, aRet ); + else + { + throw NoSuchElementException( rName, Reference< XInterface >() ); + } + } + return aRet; +} +//__________________________________________________________________________________________________ +sal_Bool IdlReflectionServiceImpl::hasByHierarchicalName( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + try + { + return getByHierarchicalName( rName ).hasValue(); + } + catch (NoSuchElementException &) + { + } + return sal_False; +} + +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescription * pTypeDescr ) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XIdlClass > xRet; + OUString aName( pTypeDescr->pTypeName ); + Any aAny( _aElements.getValue( aName ) ); + + if (aAny.hasValue()) + { + if (aAny.getValueTypeClass() == TypeClass_INTERFACE) + xRet = *(const Reference< XIdlClass > *)aAny.getValue(); + } + else + { + if (pTypeDescr && (xRet = constructClass( pTypeDescr )).is()) + _aElements.setValue( aName, makeAny( xRet ) ); // update + } + + return xRet; +} +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference * pRef ) + throw(::com::sun::star::uno::RuntimeException) +{ + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, pRef ); + if (pTD) + { + Reference< XIdlClass > xRet = forType( pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + return xRet; + } + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("IdlReflectionServiceImpl::forType() failed!") ), + (XWeak *)(OWeakObject *)this ); + return Reference< XIdlClass >(); // dummy +} + +//================================================================================================== +Reference< XInterface > SAL_CALL IdlReflectionServiceImpl_create( + const Reference< XMultiServiceFactory > & xMgr ) + throw(::com::sun::star::uno::Exception) +{ + return Reference< XInterface >( (XWeak *)(OWeakObject *)new IdlReflectionServiceImpl( xMgr ) ); +} + +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) ); + + const Sequence< OUString > & rSNL = stoc_corefl::getSupportedServiceNames(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ), + stoc_corefl::IdlReflectionServiceImpl_create, + stoc_corefl::getSupportedServiceNames() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + diff --git a/stoc/source/corereflection/crenum.cxx b/stoc/source/corereflection/crenum.cxx new file mode 100644 index 000000000000..9cd809bb197a --- /dev/null +++ b/stoc/source/corereflection/crenum.cxx @@ -0,0 +1,264 @@ +/************************************************************************* + * + * $RCSfile: crenum.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "base.hxx" + +namespace stoc_corefl +{ + +//================================================================================================== +class IdlEnumFieldImpl + : public IdlMemberImpl + , public XIdlField +{ + sal_Int32 _nValue; + +public: + IdlEnumFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, sal_Int32 nValue ) + : IdlMemberImpl( pReflection, rName, pTypeDescr, pTypeDescr ) + , _nValue( nValue ) + {} + virtual ~IdlEnumFieldImpl(); + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XIdlMember + virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + // XIdlField + virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); + virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL set( const Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException); +}; +//__________________________________________________________________________________________________ +IdlEnumFieldImpl::~IdlEnumFieldImpl() +{ +} + +// XInterface +//__________________________________________________________________________________________________ +Any IdlEnumFieldImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlField * >( this ) ) ); + return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void IdlEnumFieldImpl::acquire() throw() +{ + IdlMemberImpl::acquire(); +} +//__________________________________________________________________________________________________ +void IdlEnumFieldImpl::release() throw() +{ + IdlMemberImpl::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > IdlEnumFieldImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlField > *)0 ), + IdlMemberImpl::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > IdlEnumFieldImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XIdlMember +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlEnumFieldImpl::getDeclaringClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return IdlMemberImpl::getDeclaringClass(); +} +//__________________________________________________________________________________________________ +OUString IdlEnumFieldImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return IdlMemberImpl::getName(); +} + +// XIdlField +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlEnumFieldImpl::getType() + throw(::com::sun::star::uno::RuntimeException) +{ + return getDeclaringClass(); +} +//__________________________________________________________________________________________________ +FieldAccessMode IdlEnumFieldImpl::getAccessMode() + throw(::com::sun::star::uno::RuntimeException) +{ + return FieldAccessMode_READONLY; +} +//__________________________________________________________________________________________________ +Any IdlEnumFieldImpl::get( const Any & rObj ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + return Any( &_nValue, getTypeDescr() ); +} +//__________________________________________________________________________________________________ +void IdlEnumFieldImpl::set( const Any & rObj, const Any & rValue ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) +{ + throw IllegalAccessException( + OUString( RTL_CONSTASCII_USTRINGPARAM("enum field is constant!") ), + (XWeak *)(OWeakObject *)this ); +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +EnumIdlClassImpl::~EnumIdlClassImpl() +{ + delete _pFields; +} + +// IdlClassImpl modifications +//__________________________________________________________________________________________________ +Reference< XIdlField > EnumIdlClassImpl::getField( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pFields) + getFields(); // init members + + const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) ); + if (iFind != _aName2Field.end()) + return (*iFind).second; + else + return Reference< XIdlField >(); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlField > > EnumIdlClassImpl::getFields() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pFields) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _pFields) + { + sal_Int32 nFields = getTypeDescr()->nEnumValues; + Sequence< Reference< XIdlField > > * pFields = + new Sequence< Reference< XIdlField > >( nFields ); + Reference< XIdlField > * pSeq = pFields->getArray(); + + while (nFields--) + { + OUString aName( getTypeDescr()->ppEnumNames[nFields] ); + _aName2Field[aName] = pSeq[nFields] = new IdlEnumFieldImpl( + getReflection(), aName, IdlClassImpl::getTypeDescr(), getTypeDescr()->pEnumValues[nFields] ); + } + + _pFields = pFields; + } + } + return *_pFields; +} +//__________________________________________________________________________________________________ +void EnumIdlClassImpl::createObject( Any & rObj ) + throw(::com::sun::star::uno::RuntimeException) +{ + int eVal = ((typelib_EnumTypeDescription *)IdlClassImpl::getTypeDescr())->nDefaultEnumValue; + rObj.setValue( &eVal, IdlClassImpl::getTypeDescr() ); +} + +} + + diff --git a/stoc/source/corereflection/criface.cxx b/stoc/source/corereflection/criface.cxx new file mode 100644 index 000000000000..8d0ae2730660 --- /dev/null +++ b/stoc/source/corereflection/criface.cxx @@ -0,0 +1,1001 @@ +/************************************************************************* + * + * $RCSfile: criface.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <sal/config.h> +#ifdef SAL_UNX +#include <alloca.h> +#endif +#include <malloc.h> +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif + +#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_ +#include <typelib/typedescription.hxx> +#endif +#ifndef _UNO_DATA_H_ +#include <uno/data.h> +#endif + +#include "base.hxx" + + +namespace stoc_corefl +{ + +//================================================================================================== +class IdlAttributeFieldImpl + : public IdlMemberImpl + , public XIdlField +{ +public: + typelib_InterfaceAttributeTypeDescription * getTypeDescr() + { return (typelib_InterfaceAttributeTypeDescription *)IdlMemberImpl::getTypeDescr(); } + + IdlAttributeFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr ) + : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr ) + {} + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XIdlMember + virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + // XIdlField + virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); + virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL set( const Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException); +}; + +// XInterface +//__________________________________________________________________________________________________ +Any IdlAttributeFieldImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlField * >( this ) ) ); + return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void IdlAttributeFieldImpl::acquire() throw() +{ + IdlMemberImpl::acquire(); +} +//__________________________________________________________________________________________________ +void IdlAttributeFieldImpl::release() throw() +{ + IdlMemberImpl::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > IdlAttributeFieldImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlField > *)0 ), + IdlMemberImpl::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > IdlAttributeFieldImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XIdlMember +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlAttributeFieldImpl::getDeclaringClass() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xDeclClass.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _xDeclClass.is()) + { + typelib_InterfaceTypeDescription * pTD = + (typelib_InterfaceTypeDescription *)getDeclTypeDescr(); + while (pTD) + { + typelib_TypeDescriptionReference ** ppTypeRefs = pTD->ppMembers; + for ( sal_Int32 nPos = pTD->nMembers; nPos--; ) + { + if (td_equals( (typelib_TypeDescription *)getTypeDescr(), ppTypeRefs[nPos] )) + { + _xDeclClass = getReflection()->forType( (typelib_TypeDescription *)pTD ); + return _xDeclClass; + } + } + pTD = pTD->pBaseTypeDescription; + } + } + } + return _xDeclClass; +} +//__________________________________________________________________________________________________ +OUString IdlAttributeFieldImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return IdlMemberImpl::getName(); +} + +// XIdlField +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlAttributeFieldImpl::getType() + throw(::com::sun::star::uno::RuntimeException) +{ + return getReflection()->forType( getTypeDescr()->pAttributeTypeRef ); +} +//__________________________________________________________________________________________________ +FieldAccessMode IdlAttributeFieldImpl::getAccessMode() + throw(::com::sun::star::uno::RuntimeException) +{ + return (((typelib_InterfaceAttributeTypeDescription *)getTypeDescr())->bReadOnly + ? FieldAccessMode_READONLY : FieldAccessMode_READWRITE); +} +//__________________________________________________________________________________________________ +Any IdlAttributeFieldImpl::get( const Any & rObj ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + uno_Interface * pUnoI = mapToUno( rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() ); + OSL_ENSHURE( pUnoI, "### illegal destination object given!" ); + if (pUnoI) + { + TypeDescription aTD( getTypeDescr()->pAttributeTypeRef ); + typelib_TypeDescription * pTD = aTD.get(); + + uno_Any aExc; + uno_Any * pExc = &aExc; + void * pReturn = alloca( pTD->nSize ); + + (*pUnoI->pDispatcher)( pUnoI, (typelib_TypeDescription *)getTypeDescr(), pReturn, 0, &pExc ); + (*pUnoI->release)( pUnoI ); + + Any aRet; + if (pExc) + { + // DBO TODO: throw original exception generically + uno_any_destruct( pExc, 0 ); + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("exception occured during get of attribute!") ), + *(const Reference< XInterface > *)rObj.getValue() ); + } + else + { + uno_any_destruct( &aRet, cpp_release ); + uno_any_constructAndConvert( &aRet, pReturn, pTD, getUno2Cpp().get() ); + uno_destructData( pReturn, pTD, 0 ); + } + return aRet; + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + return Any(); // dummy +} +//__________________________________________________________________________________________________ +void IdlAttributeFieldImpl::set( const Any & rObj, const Any & rValue ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) +{ + if (getTypeDescr()->bReadOnly) + { + throw IllegalAccessException( + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot set readonly attribute!") ), + (XWeak *)(OWeakObject *)this ); + } + + uno_Interface * pUnoI = mapToUno( rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() ); + OSL_ENSHURE( pUnoI, "### illegal destination object given!" ); + if (pUnoI) + { + TypeDescription aTD( getTypeDescr()->pAttributeTypeRef ); + typelib_TypeDescription * pTD = aTD.get(); + + // construct uno value to be set + void * pArgs[1]; + void * pArg = pArgs[0] = alloca( pTD->nSize ); + + sal_Bool bAssign; + if (pTD->eTypeClass == typelib_TypeClass_ANY) + { + uno_copyAndConvertData( pArg, SAL_CONST_CAST( Any *, &rValue ), + pTD, getCpp2Uno().get() ); + bAssign = sal_True; + } + else if (typelib_typedescriptionreference_equals( rValue.getValueTypeRef(), pTD->pWeakRef )) + { + uno_copyAndConvertData( pArg, SAL_CONST_CAST( void *, rValue.getValue() ), + pTD, getCpp2Uno().get() ); + bAssign = sal_True; + } + else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE) + { + Reference< XInterface > xObj; + if (bAssign = extract( rValue, (typelib_InterfaceTypeDescription *)pTD, + xObj, getReflection() )) + { + *(void **)pArg = getCpp2Uno().mapInterface( + xObj.get(), (typelib_InterfaceTypeDescription *)pTD ); + } + } + else + { + typelib_TypeDescription * pValueTD = 0; + TYPELIB_DANGER_GET( &pValueTD, rValue.getValueTypeRef() ); + // construct temp uno val to do proper assignment: todo opt + void * pTemp = alloca( pValueTD->nSize ); + uno_copyAndConvertData( + pTemp, (void *)rValue.getValue(), pValueTD, getCpp2Uno().get() ); + uno_constructData( + pArg, pTD ); + // assignment does simple conversion + bAssign = uno_assignData( + pArg, pTD, pTemp, pValueTD, 0, 0, 0 ); + uno_destructData( + pTemp, pValueTD, 0 ); + TYPELIB_DANGER_RELEASE( pValueTD ); + } + + if (bAssign) + { + uno_Any aExc; + uno_Any * pExc = &aExc; + (*pUnoI->pDispatcher)( pUnoI, (typelib_TypeDescription *)getTypeDescr(), 0, pArgs, &pExc ); + (*pUnoI->release)( pUnoI ); + + uno_destructData( pArg, pTD, 0 ); + if (pExc) + { + // DBO TODO: throw original exception generically + uno_any_destruct( pExc, 0 ); + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("exception occured during get of attribute!") ), + *(const Reference< XInterface > *)rObj.getValue() ); + } + return; + } + (*pUnoI->release)( pUnoI ); + + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ), + *(const Reference< XInterface > *)rObj.getValue(), 1 ); + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal destination object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//================================================================================================== +class IdlInterfaceMethodImpl + : public IdlMemberImpl + , public XIdlMethod +{ + Sequence< Reference< XIdlClass > > * _pExceptionTypes; + Sequence< Reference< XIdlClass > > * _pParamTypes; + Sequence< ParamInfo > * _pParamInfos; + +public: + typelib_InterfaceMethodTypeDescription * getTypeDescr() + { return (typelib_InterfaceMethodTypeDescription *)IdlMemberImpl::getTypeDescr(); } + + IdlInterfaceMethodImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName, + typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr ) + : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr ) + , _pExceptionTypes( 0 ) + , _pParamTypes( 0 ) + , _pParamInfos( 0 ) + {} + virtual ~IdlInterfaceMethodImpl(); + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XIdlMember + virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + // XIdlMethod + virtual Reference< XIdlClass > SAL_CALL getReturnType() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlClass > > SAL_CALL getParameterTypes() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< ParamInfo > SAL_CALL getParameterInfos() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XIdlClass > > SAL_CALL getExceptionTypes() throw(::com::sun::star::uno::RuntimeException); + virtual MethodMode SAL_CALL getMode() throw(::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL invoke( const Any & rObj, Sequence< Any > & rArgs ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException); +}; +//__________________________________________________________________________________________________ +IdlInterfaceMethodImpl::~IdlInterfaceMethodImpl() +{ + delete _pParamInfos; + delete _pParamTypes; + delete _pExceptionTypes; +} + +// XInterface +//__________________________________________________________________________________________________ +Any IdlInterfaceMethodImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlMethod * >( this ) ) ); + return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void IdlInterfaceMethodImpl::acquire() throw() +{ + IdlMemberImpl::acquire(); +} +//__________________________________________________________________________________________________ +void IdlInterfaceMethodImpl::release() throw() +{ + IdlMemberImpl::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > IdlInterfaceMethodImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIdlMethod > *)0 ), + IdlMemberImpl::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > IdlInterfaceMethodImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( getMutexAccess() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XIdlMember +//__________________________________________________________________________________________________ +Reference< XIdlClass > IdlInterfaceMethodImpl::getDeclaringClass() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xDeclClass.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _xDeclClass.is()) + { + typelib_InterfaceTypeDescription * pTD = + (typelib_InterfaceTypeDescription *)getDeclTypeDescr(); + while (pTD) + { + typelib_TypeDescriptionReference ** ppTypeRefs = pTD->ppMembers; + for ( sal_Int32 nPos = pTD->nMembers; nPos--; ) + { + if (td_equals( (typelib_TypeDescription *)getTypeDescr(), ppTypeRefs[nPos] )) + { + _xDeclClass = getReflection()->forType( (typelib_TypeDescription *)pTD ); + return _xDeclClass; + } + } + pTD = pTD->pBaseTypeDescription; + } + } + } + return _xDeclClass; +} +//__________________________________________________________________________________________________ +OUString IdlInterfaceMethodImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return IdlMemberImpl::getName(); +} + +// XIdlMethod +//__________________________________________________________________________________________________ +Reference< XIdlClass > SAL_CALL IdlInterfaceMethodImpl::getReturnType() + throw(::com::sun::star::uno::RuntimeException) +{ + return getReflection()->forType( getTypeDescr()->pReturnTypeRef ); +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getExceptionTypes() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pExceptionTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _pExceptionTypes) + { + sal_Int32 nExc = getTypeDescr()->nExceptions; + Sequence< Reference< XIdlClass > > * pTempExceptionTypes = + new Sequence< Reference< XIdlClass > >( nExc ); + Reference< XIdlClass > * pExceptionTypes = pTempExceptionTypes->getArray(); + + typelib_TypeDescriptionReference ** ppExc = getTypeDescr()->ppExceptions; + IdlReflectionServiceImpl * pRefl = getReflection(); + + while (nExc--) + pExceptionTypes[nExc] = pRefl->forType( ppExc[nExc] ); + + _pExceptionTypes = pTempExceptionTypes; + } + } + return *_pExceptionTypes; +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getParameterTypes() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pParamTypes) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _pParamTypes) + { + sal_Int32 nParams = getTypeDescr()->nParams; + Sequence< Reference< XIdlClass > > * pTempParamTypes = + new Sequence< Reference< XIdlClass > >( nParams ); + Reference< XIdlClass > * pParamTypes = pTempParamTypes->getArray(); + + typelib_MethodParameter * pTypelibParams = getTypeDescr()->pParams; + IdlReflectionServiceImpl * pRefl = getReflection(); + + while (nParams--) + pParamTypes[nParams] = pRefl->forType( pTypelibParams[nParams].pTypeRef ); + + _pParamTypes = pTempParamTypes; + } + } + return *_pParamTypes; +} +//__________________________________________________________________________________________________ +Sequence< ParamInfo > IdlInterfaceMethodImpl::getParameterInfos() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pParamInfos) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _pParamInfos) + { + sal_Int32 nParams = getTypeDescr()->nParams; + Sequence< ParamInfo > * pTempParamInfos = new Sequence< ParamInfo >( nParams ); + ParamInfo * pParamInfos = pTempParamInfos->getArray(); + + typelib_MethodParameter * pTypelibParams = getTypeDescr()->pParams; + + if (_pParamTypes) // use param types + { + const Reference< XIdlClass > * pParamTypes = _pParamTypes->getConstArray(); + + while (nParams--) + { + const typelib_MethodParameter & rParam = pTypelibParams[nParams]; + ParamInfo & rInfo = pParamInfos[nParams]; + rInfo.aName = rParam.pName; + if (rParam.bIn) + rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN); + else + rInfo.aMode = ParamMode_OUT; + rInfo.aType = pParamTypes[nParams]; + } + } + else // make also param types sequence if not already initialized + { + Sequence< Reference< XIdlClass > > * pTempParamTypes = + new Sequence< Reference< XIdlClass > >( nParams ); + Reference< XIdlClass > * pParamTypes = pTempParamTypes->getArray(); + + IdlReflectionServiceImpl * pRefl = getReflection(); + + while (nParams--) + { + const typelib_MethodParameter & rParam = pTypelibParams[nParams]; + ParamInfo & rInfo = pParamInfos[nParams]; + rInfo.aName = rParam.pName; + if (rParam.bIn) + rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN); + else + rInfo.aMode = ParamMode_OUT; + rInfo.aType = pParamTypes[nParams] = pRefl->forType( rParam.pTypeRef ); + } + + _pParamTypes = pTempParamTypes; + } + + _pParamInfos = pTempParamInfos; + } + } + return *_pParamInfos; +} +//__________________________________________________________________________________________________ +MethodMode SAL_CALL IdlInterfaceMethodImpl::getMode() + throw(::com::sun::star::uno::RuntimeException) +{ + return (getTypeDescr()->bOneWay ? MethodMode_ONEWAY : MethodMode_TWOWAY); +} +//__________________________________________________________________________________________________ +Any SAL_CALL IdlInterfaceMethodImpl::invoke( const Any & rObj, Sequence< Any > & rArgs ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::reflection::InvocationTargetException, + ::com::sun::star::uno::RuntimeException) +{ + if (rObj.getValueTypeClass() == TypeClass_INTERFACE) + { + // acquire()/ release() + if (rtl_ustr_ascii_compare( ((typelib_TypeDescription *)getTypeDescr())->pTypeName->buffer, + "com.sun.star.uno.XInterface::acquire" ) == 0) + { + (*(const Reference< XInterface > *)rObj.getValue())->acquire(); + return Any(); + } + else if (rtl_ustr_ascii_compare( ((typelib_TypeDescription *)getTypeDescr())->pTypeName->buffer, + "com.sun.star.uno.XInterface::release" ) == 0) + { + (*(const Reference< XInterface > *)rObj.getValue())->release(); + return Any(); + } + } + + uno_Interface * pUnoI = mapToUno( rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() ); + OSL_ENSHURE( pUnoI, "### illegal destination object given!" ); + if (pUnoI) + { + sal_Int32 nParams = getTypeDescr()->nParams; + if (rArgs.getLength() != nParams) + { + (*pUnoI->release)( pUnoI ); + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("arguments len differ!") ), + *(const Reference< XInterface > *)rObj.getValue(), 1 ); + } + + Any * pCppArgs = rArgs.getArray(); + typelib_MethodParameter * pParams = getTypeDescr()->pParams; + typelib_TypeDescription * pReturnType = 0; + TYPELIB_DANGER_GET( &pReturnType, getTypeDescr()->pReturnTypeRef ); + + void * pUnoReturn = alloca( pReturnType->nSize ); + void ** ppUnoArgs = (void **)alloca( sizeof(void *) * nParams *2 ); + typelib_TypeDescription ** ppParamTypes = (typelib_TypeDescription **)(ppUnoArgs + nParams); + + // convert arguments + for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) + { + ppParamTypes[nPos] = 0; + TYPELIB_DANGER_GET( ppParamTypes + nPos, pParams[nPos].pTypeRef ); + typelib_TypeDescription * pTD = ppParamTypes[nPos]; + + ppUnoArgs[nPos] = alloca( pTD->nSize ); + if (pParams[nPos].bIn) + { + sal_Bool bAssign; + if (typelib_typedescriptionreference_equals( pCppArgs[nPos].getValueTypeRef(), pTD->pWeakRef )) + { + uno_type_copyAndConvertData( + ppUnoArgs[nPos], (void *)pCppArgs[nPos].getValue(), + pCppArgs[nPos].getValueTypeRef(), getCpp2Uno().get() ); + bAssign = sal_True; + } + else if (pTD->eTypeClass == typelib_TypeClass_ANY) + { + uno_type_any_constructAndConvert( + (uno_Any *)ppUnoArgs[nPos], (void *)pCppArgs[nPos].getValue(), + pCppArgs[nPos].getValueTypeRef(), getCpp2Uno().get() ); + bAssign = sal_True; + } + else if (pCppArgs[nPos].getValueTypeClass() == TypeClass_INTERFACE && + pTD->eTypeClass == typelib_TypeClass_INTERFACE) + { + Reference< XInterface > xDest; + if (bAssign = extract( pCppArgs[nPos], (typelib_InterfaceTypeDescription *)pTD, + xDest, getReflection() )) + { + *(void **)ppUnoArgs[nPos] = getCpp2Uno().mapInterface( + xDest.get(), (typelib_InterfaceTypeDescription *)pTD ); + } + } + else + { + typelib_TypeDescription * pValueTD = 0; + TYPELIB_DANGER_GET( &pValueTD, pCppArgs[nPos].getValueTypeRef() ); + // construct temp uno val to do proper assignment: todo opt + void * pTemp = alloca( pValueTD->nSize ); + uno_copyAndConvertData( + pTemp, (void *)pCppArgs[nPos].getValue(), pValueTD, getCpp2Uno().get() ); + uno_constructData( + ppUnoArgs[nPos], pTD ); + // assignment does simple conversion + bAssign = uno_assignData( + ppUnoArgs[nPos], pTD, pTemp, pValueTD, 0, 0, 0 ); + uno_destructData( + pTemp, pValueTD, 0 ); + TYPELIB_DANGER_RELEASE( pValueTD ); + } + + if (! bAssign) + { + IllegalArgumentException aExc( + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot coerce argument type during corereflection call!") ), + *(const Reference< XInterface > *)rObj.getValue(), nPos ); + + // cleanup + while (nPos--) + { + if (pParams[nPos].bIn) + uno_destructData( ppUnoArgs[nPos], ppParamTypes[nPos], 0 ); + TYPELIB_DANGER_RELEASE( ppParamTypes[nPos] ); + } + TYPELIB_DANGER_RELEASE( pReturnType ); + (*pUnoI->release)( pUnoI ); + + throw aExc; + } + } + } + + uno_Any aUnoExc; + uno_Any * pUnoExc = &aUnoExc; + + (*pUnoI->pDispatcher)( + pUnoI, (typelib_TypeDescription *)getTypeDescr(), pUnoReturn, ppUnoArgs, &pUnoExc ); + (*pUnoI->release)( pUnoI ); + + Any aRet; + if (pUnoExc) + { + // cleanup + while (nParams--) + { + if (pParams[nParams].bIn) + uno_destructData( ppUnoArgs[nParams], ppParamTypes[nParams], 0 ); + TYPELIB_DANGER_RELEASE( ppParamTypes[nParams] ); + } + TYPELIB_DANGER_RELEASE( pReturnType ); + + InvocationTargetException aExc; + aExc.Context = *(const Reference< XInterface > *)rObj.getValue(); + aExc.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("exception occured during invocation!") ); + uno_any_destruct( &aExc.TargetException, cpp_release ); + uno_type_copyAndConvertData( + &aExc.TargetException, pUnoExc, ::getCppuType( (const Any *)0 ).getTypeLibType(), getUno2Cpp().get() ); + uno_any_destruct( pUnoExc, 0 ); + throw aExc; + } + else + { + // reconvert arguments and cleanup + while (nParams--) + { + if (pParams[nParams].bOut) // write back + { + uno_any_destruct( &pCppArgs[nParams], cpp_release ); + uno_any_constructAndConvert( + &pCppArgs[nParams], ppUnoArgs[nParams], ppParamTypes[nParams], getUno2Cpp().get() ); + } + uno_destructData( ppUnoArgs[nParams], ppParamTypes[nParams], 0 ); + TYPELIB_DANGER_RELEASE( ppParamTypes[nParams] ); + } + uno_any_destruct( &aRet, cpp_release ); + uno_any_constructAndConvert( &aRet, pUnoReturn, pReturnType, getUno2Cpp().get() ); + uno_destructData( pUnoReturn, pReturnType, 0 ); + TYPELIB_DANGER_RELEASE( pReturnType ); + } + return aRet; + } + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal destination object given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + return Any(); // dummy +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +InterfaceIdlClassImpl::~InterfaceIdlClassImpl() +{ + for ( sal_Int32 nPos = _nMethods + _nAttributes; nPos--; ) + typelib_typedescription_release( _pSortedMemberInit[nPos].second ); + + delete [] _pSortedMemberInit; +} + +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlClass > > InterfaceIdlClassImpl::getSuperclasses() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _xSuperClass.is()) + { + MutexGuard aGuard( getMutexAccess() ); + if (! _xSuperClass.is()) + { + typelib_InterfaceTypeDescription * pInterfaceTypeDescr = getTypeDescr()->pBaseTypeDescription; + if (pInterfaceTypeDescr) + _xSuperClass = getReflection()->forType( (typelib_TypeDescription *)pInterfaceTypeDescr ); + } + } + + if (_xSuperClass.is()) + return Sequence< Reference< XIdlClass > >( &_xSuperClass, 1 ); + else + return Sequence< Reference< XIdlClass > >(); +} +//__________________________________________________________________________________________________ +void InterfaceIdlClassImpl::initMembers() +{ + sal_Int32 nAll = getTypeDescr()->nAllMembers; + MemberInit * pSortedMemberInit = new MemberInit[nAll]; + typelib_TypeDescriptionReference ** ppAllMembers = getTypeDescr()->ppAllMembers; + + for ( sal_Int32 nPos = 0; nPos < nAll; ++nPos ) + { + sal_Int32 nIndex; + if (ppAllMembers[nPos]->eTypeClass == typelib_TypeClass_INTERFACE_METHOD) + { + // methods to front + nIndex = _nMethods; + ++_nMethods; + } + else + { + ++_nAttributes; + nIndex = (nAll - _nAttributes); + // attributes at the back + } + + typelib_TypeDescription * pTD = 0; + typelib_typedescriptionreference_getDescription( &pTD, ppAllMembers[nPos] ); + OSL_ENSHURE( pTD, "### cannot get type description!" ); + pSortedMemberInit[nIndex].first = ((typelib_InterfaceMemberTypeDescription *)pTD)->pMemberName; + pSortedMemberInit[nIndex].second = pTD; + } + + _pSortedMemberInit = pSortedMemberInit; +} +//__________________________________________________________________________________________________ +sal_Bool InterfaceIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType ) + throw(::com::sun::star::uno::RuntimeException) +{ + if (xType.is() && xType->getTypeClass() == TypeClass_INTERFACE) + { + if (equals( xType )) + return sal_True; + else + { + const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses(); + if (rSeq.getLength()) + { + OSL_ENSHURE( rSeq.getLength() == 1, "### unexpected len of super classes!" ); + return isAssignableFrom( rSeq[0] ); + } + } + } + return sal_False; +} +//__________________________________________________________________________________________________ +Uik InterfaceIdlClassImpl::getUik() + throw(::com::sun::star::uno::RuntimeException) +{ + return *(Uik *)&getTypeDescr()->aUik; +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlMethod > > InterfaceIdlClassImpl::getMethods() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( getMutexAccess() ); + if (! _pSortedMemberInit) + initMembers(); + + // create methods sequence + Sequence< Reference< XIdlMethod > > aRet( _nMethods ); + Reference< XIdlMethod > * pRet = aRet.getArray(); + for ( sal_Int32 nPos = _nMethods; nPos--; ) + { + + /*_aName2Method[_pSortedMemberInit[nPos].first] = */pRet[nPos] = new IdlInterfaceMethodImpl( + getReflection(), _pSortedMemberInit[nPos].first, + _pSortedMemberInit[nPos].second, IdlClassImpl::getTypeDescr() ); + } + return aRet; +} +//__________________________________________________________________________________________________ +Sequence< Reference< XIdlField > > InterfaceIdlClassImpl::getFields() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( getMutexAccess() ); + if (! _pSortedMemberInit) + initMembers(); + + // create fields sequence + Sequence< Reference< XIdlField > > aRet( _nAttributes ); + Reference< XIdlField > * pRet = aRet.getArray(); + for ( sal_Int32 nPos = _nAttributes; nPos--; ) + { + /*_aName2Field[_pSortedMemberInit[_nMethods+nPos].first] = */pRet[_nAttributes-nPos-1] = + new IdlAttributeFieldImpl( + getReflection(), _pSortedMemberInit[_nMethods+nPos].first, + _pSortedMemberInit[_nMethods+nPos].second, IdlClassImpl::getTypeDescr() ); + } + return aRet; +} +//__________________________________________________________________________________________________ +Reference< XIdlMethod > InterfaceIdlClassImpl::getMethod( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( getMutexAccess() ); + if (! _pSortedMemberInit) + initMembers(); + + Reference< XIdlMethod > xRet; + + // try weak map + const OUString2Method::const_iterator iFind( _aName2Method.find( rName ) ); + if (iFind != _aName2Method.end()) + xRet = (*iFind).second; // harden ref + + if (! xRet.is()) + { + for ( sal_Int32 nPos = _nMethods; nPos--; ) + { + if (_pSortedMemberInit[nPos].first == rName) + { + _aName2Method[rName] = xRet = new IdlInterfaceMethodImpl( + getReflection(), rName, + _pSortedMemberInit[nPos].second, IdlClassImpl::getTypeDescr() ); + break; + } + } + } + return xRet; +} +//__________________________________________________________________________________________________ +Reference< XIdlField > InterfaceIdlClassImpl::getField( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( getMutexAccess() ); + if (! _pSortedMemberInit) + initMembers(); + + Reference< XIdlField > xRet; + + // try weak map + const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) ); + if (iFind != _aName2Field.end()) + xRet = (*iFind).second; // harden ref + + if (! xRet.is()) + { + for ( sal_Int32 nPos = _nAttributes; nPos--; ) + { + if (_pSortedMemberInit[_nMethods+nPos].first == rName) + { + _aName2Field[rName] = xRet = new IdlAttributeFieldImpl( + getReflection(), rName, + _pSortedMemberInit[_nMethods+nPos].second, IdlClassImpl::getTypeDescr() ); + break; + } + } + } + return xRet; +} +//__________________________________________________________________________________________________ +void InterfaceIdlClassImpl::createObject( Any & rObj ) + throw(::com::sun::star::uno::RuntimeException) +{ + // interfaces cannot be constructed + rObj.clear(); +} + +} + + diff --git a/stoc/source/corereflection/lrucache.hxx b/stoc/source/corereflection/lrucache.hxx new file mode 100644 index 000000000000..4111f80973b3 --- /dev/null +++ b/stoc/source/corereflection/lrucache.hxx @@ -0,0 +1,282 @@ +/************************************************************************* + * + * $RCSfile: lrucache.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#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 + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _RTL_USTRING_ +#include <rtl/ustring> +#endif + +#include <stl/hash_map> + + +/** 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 ::std::hash_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( const t_Key & rKey ) const; + /** Sets a value to be cached for given key. + <br> + @param rKey a key + @param rValue a value + */ + inline void setValue( const t_Key & rKey, const t_Val & 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( const t_Key & 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( const t_Key & rKey ) const +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + const t_Key2Element::const_iterator 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( const t_Key & rKey ) const +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + const t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) ); + if (iFind != _aKey2Element.end()) + { + CacheEntry * pEntry = (*iFind).second; + toFront( pEntry ); +#ifdef __CACHE_DIAGNOSE + OSL_TRACE( "> retrieved element \"" ); + OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_TRACE( "\" from cache <\n" ); +#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( + const t_Key & rKey, const t_Val & rValue ) +{ + if (_nCachedElements > 0) + { + ::osl::MutexGuard aGuard( _aCacheMutex ); + const t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) ); + + CacheEntry * pEntry; + if (iFind == _aKey2Element.end()) + { + pEntry = _pTail; // erase last element +#ifdef __CACHE_DIAGNOSE + if (pEntry->aKey.getLength()) + { + OSL_TRACE( "> kicking element \"" ); + OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_TRACE( "\" from cache <\n" ); + } +#endif + _aKey2Element.erase( pEntry->aKey ); + _aKey2Element[ pEntry->aKey = rKey ] = pEntry; + } + else + { + pEntry = (*iFind).second; +#ifdef __CACHE_DIAGNOSE + OSL_TRACE( "> replacing element \"" ); + OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_TRACE( "\" in cache <\n" ); +#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 + OSL_TRACE( "> cleared cache <\n" ); +#endif +} + +//================================================================================================== +struct FctHashOUString : public ::std::unary_function< const ::rtl::OUString &, size_t > +{ + size_t operator()( const ::rtl::OUString & rKey ) const + { return 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 diff --git a/stoc/source/corereflection/makefile.mk b/stoc/source/corereflection/makefile.mk new file mode 100644 index 000000000000..4a9421865067 --- /dev/null +++ b/stoc/source/corereflection/makefile.mk @@ -0,0 +1,110 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= corefl +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + +SLOFILES= \ + $(SLO)$/crefl.obj \ + $(SLO)$/crbase.obj \ + $(SLO)$/crarray.obj \ + $(SLO)$/crcomp.obj \ + $(SLO)$/criface.obj \ + $(SLO)$/crenum.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/stoc/source/cppumaker.mk b/stoc/source/cppumaker.mk new file mode 100644 index 000000000000..50b331fcaebd --- /dev/null +++ b/stoc/source/cppumaker.mk @@ -0,0 +1,77 @@ +#************************************************************************* +# +# $RCSfile: cppumaker.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +UNOUCRDEP= $(SOLARBINDIR)$/applicat.rdb +UNOUCRRDB= $(SOLARBINDIR)$/applicat.rdb + +CPPUMAKERFLAGS = + +.IF "$(BOOTSTRAP_SERVICE)" == "TRUE" +UNOUCROUT= $(OUT)$/inc$/bootstrap +INCPRE+= $(OUT)$/inc$/bootstrap +.ELSE +.IF "$(COM)" == "MSC" +CPPUMAKERFLAGS = -L +.ENDIF +UNOUCROUT= $(OUT)$/inc$/light +INCPRE+= $(OUT)$/inc$/light +.ENDIF + diff --git a/stoc/source/defaultregistry/defaultregistry.cxx b/stoc/source/defaultregistry/defaultregistry.cxx new file mode 100644 index 000000000000..5e5ba13ae124 --- /dev/null +++ b/stoc/source/defaultregistry/defaultregistry.cxx @@ -0,0 +1,1440 @@ +/************************************************************************* + * + * $RCSfile: defaultregistry.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _OSL_DIAGNOSE_HXX_ +#include <osl/diagnose.h> +#endif + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE1_HXX_ +#include <cppuhelper/implbase1.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE3_HXX_ +#include <cppuhelper/implbase3.hxx> +#endif + +#ifndef _REGISTRY_REGISTRY_HXX_ +#include <registry/registry.hxx> +#endif + +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XInitialization.hpp> + +using namespace com::sun::star::uno; +using namespace com::sun::star::registry; +using namespace com::sun::star::lang; +using namespace cppu; +using namespace vos; +using namespace osl; +using namespace rtl; + + +#define NESTED_SERVICENAME "com.sun.star.registry.NestedRegistry" +#define NESTED_IMPLNAME "com.sun.star.comp.stoc.NestedRegistry" + +namespace stoc_defreg +{ + +//************************************************************************* +// NestedRegistryImpl +//************************************************************************* +class NestedKeyImpl; + +class NestedRegistryImpl : public WeakAggImplHelper3 < XSimpleRegistry, XInitialization, XServiceInfo > +{ +public: + NestedRegistryImpl( const Reference<XMultiServiceFactory> & rXSMgr ); + + NestedRegistryImpl( const Reference<XMultiServiceFactory> & rXSMgr, + Reference<XSimpleRegistry>& localReg, + Reference<XSimpleRegistry>& systemReg ); + + ~NestedRegistryImpl(); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException); + static OUString SAL_CALL getImplementationName_Static( ); + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( ); + + // XInitialization + virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException); + + // XSimpleRegistry + virtual OUString SAL_CALL getURL() throw(RuntimeException); + virtual void SAL_CALL open( const OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) throw(InvalidRegistryException, RuntimeException); + virtual sal_Bool SAL_CALL isValid( ) throw(RuntimeException); + virtual void SAL_CALL close( ) throw(InvalidRegistryException, RuntimeException); + virtual void SAL_CALL destroy( ) throw(InvalidRegistryException, RuntimeException); + virtual Reference< XRegistryKey > SAL_CALL getRootKey( ) throw(InvalidRegistryException, RuntimeException); + virtual sal_Bool SAL_CALL isReadOnly( ) throw(InvalidRegistryException, RuntimeException); + virtual void SAL_CALL mergeKey( const OUString& aKeyName, const OUString& aUrl ) throw(InvalidRegistryException, MergeConflictException, RuntimeException); + + friend NestedKeyImpl; +protected: + Mutex m_mutex; + sal_uInt32 m_state; + Reference<XSimpleRegistry> m_localReg; + Reference<XSimpleRegistry> m_defaultReg; + +private: + Reference<XMultiServiceFactory> m_xSMgr; +}; + +//************************************************************************* +// class NestedKeyImpl the implenetation of interface XRegistryKey +//************************************************************************* +class NestedKeyImpl : public WeakImplHelper1< XRegistryKey > +{ +public: + NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry, + Reference<XRegistryKey>& localKey, + Reference<XRegistryKey>& defaultKey); + + NestedKeyImpl( const OUString& aKeyName, + NestedKeyImpl* pKey); + + ~NestedKeyImpl(); + + // XRegistryKey + virtual OUString SAL_CALL getKeyName() throw(RuntimeException); + virtual sal_Bool SAL_CALL isReadOnly( ) throw(InvalidRegistryException, RuntimeException); + virtual sal_Bool SAL_CALL isValid( ) throw(RuntimeException); + virtual RegistryKeyType SAL_CALL getKeyType( const OUString& rKeyName ) throw(InvalidRegistryException, RuntimeException); + virtual RegistryValueType SAL_CALL getValueType( ) throw(InvalidRegistryException, RuntimeException); + virtual sal_Int32 SAL_CALL getLongValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setLongValue( sal_Int32 value ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< sal_Int32 > SAL_CALL getLongListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setLongListValue( const ::com::sun::star::uno::Sequence< sal_Int32 >& seqValue ) throw(InvalidRegistryException, RuntimeException); + virtual OUString SAL_CALL getAsciiValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setAsciiValue( const OUString& value ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< OUString > SAL_CALL getAsciiListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setAsciiListValue( const ::com::sun::star::uno::Sequence< OUString >& seqValue ) throw(InvalidRegistryException, RuntimeException); + virtual OUString SAL_CALL getStringValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setStringValue( const OUString& value ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< OUString > SAL_CALL getStringListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setStringListValue( const ::com::sun::star::uno::Sequence< OUString >& seqValue ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getBinaryValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setBinaryValue( const ::com::sun::star::uno::Sequence< sal_Int8 >& value ) throw(InvalidRegistryException, RuntimeException); + virtual Reference< XRegistryKey > SAL_CALL openKey( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException); + virtual Reference< XRegistryKey > SAL_CALL createKey( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException); + virtual void SAL_CALL closeKey( ) throw(InvalidRegistryException, RuntimeException); + virtual void SAL_CALL deleteKey( const OUString& rKeyName ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< Reference< XRegistryKey > > SAL_CALL openKeys( ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< OUString > SAL_CALL getKeyNames( ) throw(InvalidRegistryException, RuntimeException); + virtual sal_Bool SAL_CALL createLink( const OUString& aLinkName, const OUString& aLinkTarget ) throw(InvalidRegistryException, RuntimeException); + virtual void SAL_CALL deleteLink( const OUString& rLinkName ) throw(InvalidRegistryException, RuntimeException); + virtual OUString SAL_CALL getLinkTarget( const OUString& rLinkName ) throw(InvalidRegistryException, RuntimeException); + virtual OUString SAL_CALL getResolvedName( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException); + +protected: + void computeChanges(); + OUString computeName(const OUString& name); + + OUString m_name; + sal_uInt32 m_state; + NestedRegistryImpl* m_pRegistry; + Reference<XRegistryKey> m_localKey; + Reference<XRegistryKey> m_defaultKey; +}; + + +//************************************************************************* +NestedKeyImpl::NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry, + Reference<XRegistryKey>& localKey, + Reference<XRegistryKey>& defaultKey ) + : m_pRegistry(pDefaultRegistry) +{ + m_pRegistry->acquire(); + + m_localKey = localKey; + m_defaultKey = defaultKey; + + if (m_localKey.is()) + { + m_name = m_localKey->getKeyName(); + } else + if (m_defaultKey.is()) + { + m_name = m_defaultKey->getKeyName(); + } + + m_state = m_pRegistry->m_state; +} + +//************************************************************************* +NestedKeyImpl::NestedKeyImpl( const OUString& rKeyName, + NestedKeyImpl* pKey) + : m_pRegistry(pKey->m_pRegistry) +{ + m_pRegistry->acquire(); + + if (pKey->m_localKey.is() && pKey->m_localKey->isValid()) + { + m_localKey = pKey->m_localKey->openKey(rKeyName); + } + if (pKey->m_defaultKey.is() && pKey->m_defaultKey->isValid()) + { + m_defaultKey = pKey->m_defaultKey->openKey(rKeyName); + } + + if (m_localKey.is()) + { + m_name = m_localKey->getKeyName(); + } else + if (m_defaultKey.is()) + { + m_name = m_defaultKey->getKeyName(); + } + + m_state = m_pRegistry->m_state; +} + +//************************************************************************* +NestedKeyImpl::~NestedKeyImpl() +{ + if ( m_pRegistry ) + m_pRegistry->release(); +} + +//************************************************************************* +void NestedKeyImpl::computeChanges() +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( m_state != m_pRegistry->m_state ) + { + Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey()); + + Reference<XRegistryKey> tmpKey = rootKey->openKey(m_name); + + if ( tmpKey.is() ) + { + m_localKey = rootKey->openKey(m_name); + } + + m_state = m_pRegistry->m_state; + } +} + +//************************************************************************* +// NestedKey_Impl::computeName() +// +OUString NestedKeyImpl::computeName(const OUString& name) +{ + OUString resLocalName, resDefaultName; + + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + try + { + if ( m_localKey.is() && m_localKey->isValid() ) + { + resLocalName = m_localKey->getResolvedName(name); + } else + { + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + return m_defaultKey->getResolvedName(name); + } + + if ( resLocalName.getLength() > 0 && m_pRegistry->m_defaultReg->isValid() ) + { + Reference<XRegistryKey> localRoot(m_pRegistry->m_localReg->getRootKey()); + Reference<XRegistryKey> defaultRoot(m_pRegistry->m_defaultReg->getRootKey()); + + resDefaultName = defaultRoot->getResolvedName(resLocalName); + + sal_uInt32 count = 100; + + while (resLocalName != resDefaultName && count > 0) + { + count--; + + if (resLocalName.getLength() == 0 || resDefaultName.getLength() == 0) + throw InvalidRegistryException(); + + resLocalName = localRoot->getResolvedName(resDefaultName); + resDefaultName = defaultRoot->getResolvedName(resLocalName); + } + } + } + catch(InvalidRegistryException& ) + { + } + + return resLocalName; +} + +//************************************************************************* +OUString SAL_CALL NestedKeyImpl::getKeyName() throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + return m_name; +} + +//************************************************************************* +sal_Bool SAL_CALL NestedKeyImpl::isReadOnly( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + return m_localKey->isReadOnly(); + else + throw InvalidRegistryException(); + + return sal_False; +} + +//************************************************************************* +sal_Bool SAL_CALL NestedKeyImpl::isValid( ) throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + return ((m_localKey.is() && m_localKey->isValid()) || + (m_defaultKey.is() && m_defaultKey->isValid()) ); +} + +//************************************************************************* +RegistryKeyType SAL_CALL NestedKeyImpl::getKeyType( const OUString& rKeyName ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + return m_localKey->getKeyType(rKeyName); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + return m_defaultKey->getKeyType(rKeyName); + } + + return RegistryKeyType_KEY; +} + +//************************************************************************* +RegistryValueType SAL_CALL NestedKeyImpl::getValueType( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + return m_localKey->getValueType(); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + return m_defaultKey->getValueType(); + } + + return RegistryValueType_NOT_DEFINED; +} + +//************************************************************************* +sal_Int32 SAL_CALL NestedKeyImpl::getLongValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + return m_localKey->getLongValue(); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + return m_defaultKey->getLongValue(); + } else + { + throw InvalidRegistryException(); + } + + return 0; +} + +//************************************************************************* +void SAL_CALL NestedKeyImpl::setLongValue( sal_Int32 value ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + m_localKey->setLongValue(value); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey()); + m_localKey = rootKey->createKey(m_name); + m_localKey->setLongValue(value); + m_state = m_pRegistry->m_state++; + } else + { + throw InvalidRegistryException(); + } +} + +//************************************************************************* +Sequence< sal_Int32 > SAL_CALL NestedKeyImpl::getLongListValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + return m_localKey->getLongListValue(); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + return m_defaultKey->getLongListValue(); + } else + { + throw InvalidRegistryException(); + } + + return Sequence<sal_Int32>(); +} + +//************************************************************************* +void SAL_CALL NestedKeyImpl::setLongListValue( const Sequence< sal_Int32 >& seqValue ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + m_localKey->setLongListValue(seqValue); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey()); + m_localKey = rootKey->createKey(m_name); + m_localKey->setLongListValue(seqValue); + m_state = m_pRegistry->m_state++; + } else + { + throw InvalidRegistryException(); + } +} + +//************************************************************************* +OUString SAL_CALL NestedKeyImpl::getAsciiValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + return m_localKey->getAsciiValue(); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + return m_defaultKey->getAsciiValue(); + } else + { + throw InvalidRegistryException(); + } + + return OUString(); +} + +//************************************************************************* +void SAL_CALL NestedKeyImpl::setAsciiValue( const OUString& value ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + m_localKey->setAsciiValue(value); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey()); + m_localKey = rootKey->createKey(m_name); + m_localKey->setAsciiValue(value); + m_state = m_pRegistry->m_state++; + } else + { + throw InvalidRegistryException(); + } +} + +//************************************************************************* +Sequence< OUString > SAL_CALL NestedKeyImpl::getAsciiListValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + return m_localKey->getAsciiListValue(); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + return m_defaultKey->getAsciiListValue(); + } else + { + throw InvalidRegistryException(); + } + + return Sequence<OUString>(); +} + +//************************************************************************* +void SAL_CALL NestedKeyImpl::setAsciiListValue( const Sequence< OUString >& seqValue ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + m_localKey->setAsciiListValue(seqValue); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey()); + m_localKey = rootKey->createKey(m_name); + m_localKey->setAsciiListValue(seqValue); + m_state = m_pRegistry->m_state++; + } else + { + throw InvalidRegistryException(); + } +} + +//************************************************************************* +OUString SAL_CALL NestedKeyImpl::getStringValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + return m_localKey->getStringValue(); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + return m_defaultKey->getStringValue(); + } else + { + throw InvalidRegistryException(); + } + + return OUString(); +} + +//************************************************************************* +void SAL_CALL NestedKeyImpl::setStringValue( const OUString& value ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + m_localKey->setStringValue(value); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey()); + m_localKey = rootKey->createKey(m_name); + m_localKey->setStringValue(value); + m_state = m_pRegistry->m_state++; + } else + { + throw InvalidRegistryException(); + } +} + +//************************************************************************* +Sequence< OUString > SAL_CALL NestedKeyImpl::getStringListValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + return m_localKey->getStringListValue(); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + return m_defaultKey->getStringListValue(); + } else + { + throw InvalidRegistryException(); + } + + return Sequence<OUString>(); +} + +//************************************************************************* +void SAL_CALL NestedKeyImpl::setStringListValue( const Sequence< OUString >& seqValue ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + m_localKey->setStringListValue(seqValue); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey()); + m_localKey = rootKey->createKey(m_name); + m_localKey->setStringListValue(seqValue); + m_state = m_pRegistry->m_state++; + } else + { + throw InvalidRegistryException(); + } +} + +//************************************************************************* +Sequence< sal_Int8 > SAL_CALL NestedKeyImpl::getBinaryValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + return m_localKey->getBinaryValue(); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + return m_defaultKey->getBinaryValue(); + } else + { + throw InvalidRegistryException(); + } + + return Sequence<sal_Int8>(); +} + +//************************************************************************* +void SAL_CALL NestedKeyImpl::setBinaryValue( const Sequence< sal_Int8 >& value ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + computeChanges(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + m_localKey->setBinaryValue(value); + } else + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey()); + m_localKey = rootKey->createKey(m_name); + m_localKey->setBinaryValue(value); + m_state = m_pRegistry->m_state++; + } else + { + throw InvalidRegistryException(); + } +} + +//************************************************************************* +Reference< XRegistryKey > SAL_CALL NestedKeyImpl::openKey( const OUString& aKeyName ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_localKey.is() && !m_defaultKey.is() ) + { + throw InvalidRegistryException(); + } + + OUString resolvedName = computeName(aKeyName); + + if ( resolvedName.getLength() == 0 ) + throw InvalidRegistryException(); + + Reference<XRegistryKey> localKey, defaultKey; + + if ( m_localKey.is() && m_localKey->isValid() ) + { + localKey = m_pRegistry->m_localReg->getRootKey()->openKey(resolvedName); + } + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName); + } + + if ( localKey.is() || defaultKey.is() ) + { + return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey)); + } else + { + return Reference<XRegistryKey>(); + } +} + +//************************************************************************* +Reference< XRegistryKey > SAL_CALL NestedKeyImpl::createKey( const OUString& aKeyName ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( (!m_localKey.is() && !m_defaultKey.is()) || + (m_localKey.is() && m_localKey->isReadOnly()) ) + { + throw InvalidRegistryException(); + } + + OUString resolvedName = computeName(aKeyName); + + if ( resolvedName.getLength() == 0 ) + throw InvalidRegistryException(); + + if ( m_localKey.is() && m_localKey->isValid() ) + { + Reference<XRegistryKey> localKey, defaultKey; + + localKey = m_pRegistry->m_localReg->getRootKey()->createKey(resolvedName); + if ( localKey.is() ) + { + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName); + } + + m_state = m_pRegistry->m_state++; + + return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey)); + } + } else + { + Reference<XRegistryKey> localKey, defaultKey; + + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey()); + m_localKey = rootKey->createKey(m_name); + + localKey = m_pRegistry->m_localReg->getRootKey()->createKey(resolvedName); + + if ( localKey.is() ) + { + defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName); + + m_state = m_pRegistry->m_state++; + + return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey)); + } + } + } + + return Reference<XRegistryKey>(); +} + +//************************************************************************* +void SAL_CALL NestedKeyImpl::closeKey( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( m_localKey.is() && m_localKey->isValid() ) + { + m_localKey->closeKey(); + } + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + m_defaultKey->closeKey(); + } +} + +//************************************************************************* +void SAL_CALL NestedKeyImpl::deleteKey( const OUString& rKeyName ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( m_localKey.is() && m_localKey->isValid() && + !m_localKey->isReadOnly() ) + { + OUString resolvedName = computeName(rKeyName); + + if ( resolvedName.getLength() == 0 ) + { + throw InvalidRegistryException(); + } + + m_pRegistry->m_localReg->getRootKey()->deleteKey(resolvedName); + } else + { + throw InvalidRegistryException(); + } +} + +//************************************************************************* +Sequence< Reference< XRegistryKey > > SAL_CALL NestedKeyImpl::openKeys( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_localKey.is() && !m_defaultKey.is() ) + { + throw InvalidRegistryException(); + } + + Sequence<OUString> localSeq, defaultSeq; + + if ( m_localKey.is() && m_localKey->isValid() ) + { + localSeq = m_localKey->getKeyNames(); + } + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + defaultSeq = m_defaultKey->getKeyNames(); + } + + sal_uInt32 local = localSeq.getLength(); + sal_uInt32 def = defaultSeq.getLength(); + sal_uInt32 len = 0; + + sal_uInt32 i, j; + for (i=0; i < local; i++) + { + for (j=0 ; j < def; j++) + { + if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] ) + { + len++; + break; + } + } + } + + Sequence< Reference<XRegistryKey> > retSeq(local + def - len); + sal_Bool insert = sal_True; + OUString name; + sal_Int32 lastIndex; + + for (i=0; i < local; i++) + { + name = localSeq.getConstArray()[i]; + lastIndex = name.lastIndexOf('/'); + name = name.copy(lastIndex); + retSeq.getArray()[i] = + (XRegistryKey*)new NestedKeyImpl(name, this); + } + + sal_uInt32 k = local; + for (i=0; i < def; i++) + { + insert = sal_True; + + for (j=0 ; j < local; j++) + { + if ( retSeq.getConstArray()[j]->getKeyName() + == defaultSeq.getConstArray()[i] ) + { + insert = sal_False; + break; + } + } + + if ( insert ) + { + name = defaultSeq.getConstArray()[i]; + lastIndex = name.lastIndexOf('/'); + name = name.copy(lastIndex); + retSeq.getArray()[k++] = + (XRegistryKey*)new NestedKeyImpl(name, this); + } + } + + return retSeq; +} + +//************************************************************************* +Sequence< OUString > SAL_CALL NestedKeyImpl::getKeyNames( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_localKey.is() && !m_defaultKey.is() ) + { + throw InvalidRegistryException(); + } + + Sequence<OUString> localSeq, defaultSeq; + + if ( m_localKey.is() && m_localKey->isValid() ) + { + localSeq = m_localKey->getKeyNames(); + } + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + defaultSeq = m_defaultKey->getKeyNames(); + } + + sal_uInt32 local = localSeq.getLength(); + sal_uInt32 def = defaultSeq.getLength(); + sal_uInt32 len = 0; + + sal_uInt32 i, j; + for (i=0; i < local; i++) + { + for (j=0 ; j < def; j++) + { + if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] ) + { + len++; + break; + } + } + } + + Sequence<OUString> retSeq(local + def - len); + sal_Bool insert = sal_True; + + for (i=0; i < local; i++) + { + retSeq.getArray()[i] = localSeq.getConstArray()[i]; + } + + sal_uInt32 k = local; + for (i=0; i < def; i++) + { + insert = sal_True; + + for (j=0 ; j < local; j++) + { + if ( retSeq.getConstArray()[j] == defaultSeq.getConstArray()[i] ) + { + insert = sal_False; + break; + } + } + + if ( insert ) + retSeq.getArray()[k++] = defaultSeq.getConstArray()[i]; + } + + return retSeq; +} + +//************************************************************************* +sal_Bool SAL_CALL NestedKeyImpl::createLink( const OUString& aLinkName, const OUString& aLinkTarget ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + + sal_Bool isCreated = False; + if ( !m_localKey.is() && !m_defaultKey.is() ) + { + throw InvalidRegistryException(); + } + + OUString linkName; + OUString resolvedName; + sal_Int32 lastIndex = aLinkName.lastIndexOf('/'); + + if ( lastIndex > 0 ) + { + linkName = aLinkName.copy(0, lastIndex); + + resolvedName = computeName(linkName); + + if ( resolvedName.getLength() == 0 ) + { + throw InvalidRegistryException(); + } + + resolvedName = resolvedName + aLinkName.copy(lastIndex); + } else + { + if ( lastIndex == 0 ) + resolvedName = m_name + aLinkName; + else + resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + aLinkName; + } + + if ( m_localKey.is() && m_localKey->isValid() ) + { + isCreated = m_pRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget); + } else + { + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + { + Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey()); + m_localKey = rootKey->createKey(m_name); + + isCreated = m_pRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget); + } + } + + if ( isCreated ) + m_state = m_pRegistry->m_state++; + + return isCreated; +} + +//************************************************************************* +void SAL_CALL NestedKeyImpl::deleteLink( const OUString& rLinkName ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_localKey.is() && !m_defaultKey.is() ) + { + throw InvalidRegistryException(); + } + + OUString linkName; + OUString resolvedName; + sal_Int32 lastIndex = rLinkName.lastIndexOf('/'); + + if ( lastIndex > 0 ) + { + linkName = rLinkName.copy(0, lastIndex); + + resolvedName = computeName(linkName); + + if ( resolvedName.getLength() == 0 ) + { + throw InvalidRegistryException(); + } + + resolvedName = resolvedName + rLinkName.copy(lastIndex); + } else + { + if ( lastIndex == 0 ) + resolvedName = m_name + rLinkName; + else + resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + rLinkName; + } + + if ( m_localKey.is() && m_localKey->isValid() && + !m_localKey->isReadOnly() ) + { + m_pRegistry->m_localReg->getRootKey()->deleteLink(resolvedName); + } else + { + throw InvalidRegistryException(); + } +} + +//************************************************************************* +OUString SAL_CALL NestedKeyImpl::getLinkTarget( const OUString& rLinkName ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_localKey.is() && !m_defaultKey.is() ) + { + throw InvalidRegistryException(); + } + + OUString linkName; + OUString resolvedName; + sal_Int32 lastIndex = rLinkName.lastIndexOf('/'); + + if ( lastIndex > 0 ) + { + linkName = rLinkName.copy(0, lastIndex); + + resolvedName = computeName(linkName); + + if ( resolvedName.getLength() == 0 ) + { + throw InvalidRegistryException(); + } + + resolvedName = resolvedName + rLinkName.copy(lastIndex); + } else + { + if ( lastIndex == 0 ) + resolvedName = m_name + rLinkName; + else + resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + rLinkName; + } + + OUString linkTarget; + if ( m_localKey.is() && m_localKey->isValid() ) + { + try + { + linkTarget = m_pRegistry->m_localReg->getRootKey()->getLinkTarget(resolvedName); + return linkTarget; + } + catch(InvalidRegistryException& ) + { + } + } + + if ( m_defaultKey.is() && m_defaultKey->isValid() ) + linkTarget = m_pRegistry->m_defaultReg->getRootKey()->getLinkTarget(resolvedName); + + return linkTarget; +} + +//************************************************************************* +OUString SAL_CALL NestedKeyImpl::getResolvedName( const OUString& aKeyName ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_localKey.is() && !m_defaultKey.is() ) + { + throw InvalidRegistryException(); + } + + OUString resolvedName = computeName(aKeyName); + + if ( resolvedName.getLength() == 0 ) + { + throw InvalidRegistryException(); + } + + return resolvedName; +} + +//************************************************************************* +// +// DefaultRegistry Implementation +// +//************************************************************************* +NestedRegistryImpl::NestedRegistryImpl( const Reference<XMultiServiceFactory> & rSMgr ) + : m_state(0) + , m_xSMgr(rSMgr) +{ +} + +NestedRegistryImpl::NestedRegistryImpl( const Reference<XMultiServiceFactory> & rSMgr, + Reference<XSimpleRegistry>& localReg, + Reference<XSimpleRegistry>& defaultReg) + : m_state(0) + , m_localReg(localReg) + , m_defaultReg(defaultReg) + , m_xSMgr(rSMgr) +{ +} + +//************************************************************************* +NestedRegistryImpl::~NestedRegistryImpl() +{ +} + +//************************************************************************* +OUString SAL_CALL NestedRegistryImpl::getImplementationName( ) + throw(RuntimeException) +{ + return OUString::createFromAscii( NESTED_IMPLNAME ); +} + +//************************************************************************* +sal_Bool SAL_CALL NestedRegistryImpl::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +//************************************************************************* +Sequence<OUString> SAL_CALL NestedRegistryImpl::getSupportedServiceNames( ) + throw(RuntimeException) +{ + return getSupportedServiceNames_Static(); +} + +//************************************************************************* +Sequence<OUString> SAL_CALL NestedRegistryImpl::getSupportedServiceNames_Static( ) +{ + OUString aStr( OUString::createFromAscii( NESTED_SERVICENAME ) ); + return Sequence< OUString >( &aStr, 1 ); +} + +//************************************************************************* +void SAL_CALL NestedRegistryImpl::initialize( const Sequence< Any >& aArguments ) + throw( Exception, RuntimeException ) +{ + Guard< Mutex > aGuard( m_mutex ); + if ( (aArguments.getLength() == 2) && + (aArguments[0].getValueType().getTypeClass() == TypeClass_INTERFACE) && + (aArguments[1].getValueType().getTypeClass() == TypeClass_INTERFACE) ) + { + aArguments[0] >>= m_localReg; + aArguments[1] >>= m_defaultReg; + if ( m_localReg == m_defaultReg ) + m_defaultReg = Reference< XSimpleRegistry >(); + } +} + +//************************************************************************* +OUString SAL_CALL NestedRegistryImpl::getURL() throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + try + { + if ( m_localReg.is() && m_localReg->isValid() ) + return m_localReg->getURL(); + } + catch(InvalidRegistryException& ) + { + } + + return OUString(); +} + +//************************************************************************* +void SAL_CALL NestedRegistryImpl::open( const OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) + throw(InvalidRegistryException, RuntimeException) +{ + throw InvalidRegistryException(); +} + +//************************************************************************* +sal_Bool SAL_CALL NestedRegistryImpl::isValid( ) throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + try + { + if ( (m_localReg.is() && m_localReg->isValid()) || + (m_defaultReg.is() && m_defaultReg->isValid()) ) + return sal_True; + } + catch(InvalidRegistryException& ) + { + } + + return sal_False; +} + +//************************************************************************* +void SAL_CALL NestedRegistryImpl::close( ) + throw(InvalidRegistryException, RuntimeException) +{ + throw InvalidRegistryException(); +} + +//************************************************************************* +void SAL_CALL NestedRegistryImpl::destroy( ) + throw(InvalidRegistryException, RuntimeException) +{ + throw InvalidRegistryException(); +} + +//************************************************************************* +Reference< XRegistryKey > SAL_CALL NestedRegistryImpl::getRootKey( ) + throw(InvalidRegistryException, RuntimeException) +{ + Reference<XRegistryKey> tmpKey; + + Guard< Mutex > aGuard( m_mutex ); + if ( m_localReg.is() && m_localReg->isValid() ) + { + Reference<XRegistryKey> localKey, defaultKey; + + localKey = m_localReg->getRootKey(); + + if ( localKey.is() ) + { + if ( m_defaultReg.is() && m_defaultReg->isValid() ) + { + defaultKey = m_defaultReg->getRootKey(); + } + + return ((XRegistryKey*)new NestedKeyImpl(this, localKey, defaultKey)); + } + } else + { + throw InvalidRegistryException(); + } + + return Reference<XRegistryKey>(); +} + +//************************************************************************* +sal_Bool SAL_CALL NestedRegistryImpl::isReadOnly( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + try + { + if ( m_localReg.is() && m_localReg->isValid() ) + return m_localReg->isReadOnly(); + } + catch(InvalidRegistryException& ) + { + } + + return sal_False; +} + +//************************************************************************* +void SAL_CALL NestedRegistryImpl::mergeKey( const OUString& aKeyName, const OUString& aUrl ) + throw(InvalidRegistryException, MergeConflictException, RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + if ( m_localReg.is() && m_localReg->isValid() ) + { + m_localReg->mergeKey(aKeyName, aUrl); + + m_state++; + } +} + +//************************************************************************* +Reference<XInterface> SAL_CALL NestedRegistry_CreateInstance( const Reference<XMultiServiceFactory>& rSMgr ) + throw(Exception) +{ + Reference<XInterface> xRet; + XSimpleRegistry *pRegistry = (XSimpleRegistry*) new NestedRegistryImpl(rSMgr); + + if (pRegistry) + { + xRet = Reference<XInterface>::query(pRegistry); + } + + return xRet; +} + +} // namespace stco_defreg + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + // NestedRegistry + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString::createFromAscii( "/" NESTED_IMPLNAME "/UNO/SERVICES" ) ) ); + + Sequence< OUString > & rSNL = ::stoc_defreg::NestedRegistryImpl::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + if ( rtl_str_compare( pImplName, NESTED_IMPLNAME ) == 0 ) + { + Reference< XSingleServiceFactory > xFactory( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + ::stoc_defreg::NestedRegistry_CreateInstance, + ::stoc_defreg::NestedRegistryImpl::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + + diff --git a/stoc/source/defaultregistry/makefile.mk b/stoc/source/defaultregistry/makefile.mk new file mode 100644 index 000000000000..af0e7cd2f347 --- /dev/null +++ b/stoc/source/defaultregistry/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= defreg +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +BOOTSTRAP_SERVICE=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + + +SLOFILES= \ + $(SLO)$/defaultregistry.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/stoc/source/implementationregistration/implreg.cxx b/stoc/source/implementationregistration/implreg.cxx new file mode 100644 index 000000000000..357d9d2184e6 --- /dev/null +++ b/stoc/source/implementationregistration/implreg.cxx @@ -0,0 +1,1750 @@ +/************************************************************************* + * + * $RCSfile: implreg.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <stl/list> + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif + +#ifndef _CPPUHELPER_SERVICEFACTORY_HXX_ +#include <cppuhelper/servicefactory.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE3_HXX +#include <cppuhelper/implbase3.hxx> +#endif + +#include <uno/mapping.hxx> +#include <vos/thread.hxx> +#include <vos/conditn.hxx> + +#include <rtl/ustring.hxx> + +#ifndef _VOS_PROCESS_HXX_ +#include <vos/process.hxx> +#endif + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/loader/XImplementationLoader.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#if defined(SAL_W32) || defined(SAL_OS2) +#include <io.h> +#endif + + +using namespace com::sun::star::uno; +using namespace com::sun::star::loader; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; +using namespace cppu; +using namespace rtl; +using namespace vos; + +namespace stoc_impreg +{ + +#define IMPLEMENTATION_NAME "com.sun.star.comp.stoc.ImplementationRegistration" +#define SERVICE_NAME "com.sun.star.registry.ImplementationRegistration" + +//************************************************************************* +// static getTempName() +// +// Shouldn't this whole routine be rewritten ???? (jbu) + +static OUString getTempName() +{ + OUString uTmpPath; + OString tmpPath; + sal_Char tmpPattern[512]; + sal_Char *pTmpName = NULL; + + OStartupInfo StartupInfo; + + if (StartupInfo.getEnvironment(OUString(RTL_CONSTASCII_USTRINGPARAM("TMP")), uTmpPath) != OStartupInfo::E_None) + { + if (StartupInfo.getEnvironment(OUString(RTL_CONSTASCII_USTRINGPARAM("TEMP")), uTmpPath) != OStartupInfo::E_None) + { +#if defined(WIN32) || defined(WNT) || defined(OS2) + tmpPath = OString("c:\\temp"); +#else + tmpPath = OString("/tmp"); +#endif + } + } + + if (uTmpPath.getLength()) + { + tmpPath = OUStringToOString(uTmpPath, osl_getThreadTextEncoding()); + } + +#if defined(WIN32) || defined(WNT) + strcpy(tmpPattern, tmpPath.getStr()); + strcat(tmpPattern, "\\reg_XXXXXX"); + pTmpName = mktemp(tmpPattern); +#endif + +#ifdef __OS2__ + strcpy(tmpPattern, tempnam(NULL, "reg_")); + pTmpName = tmpPattern; +#endif + +#ifdef UNX + strcpy(tmpPattern, tmpPath.getStr()); + strcat(tmpPattern, "/reg_XXXXXX"); + pTmpName = mktemp(tmpPattern); +#endif + + return OStringToOUString(pTmpName, osl_getThreadTextEncoding()); +} + +//************************************************************************* +// static deleteAllLinkReferences() +// +static void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg, + const Reference < XRegistryKey >& xSource) +{ + try + { + Reference < XRegistryKey > xKey = xSource->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS") ) ); + + if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST)) + { + Sequence<OUString> linkNames = xKey->getAsciiListValue(); + + if (linkNames.getLength()) + { + const OUString* pLinkNames = linkNames.getConstArray(); + + OUString aLinkName; + OUString aLinkParent; + Reference < XRegistryKey > xLinkParent; + const sal_Unicode* pTmpName = NULL; + const sal_Unicode* pShortName = NULL; + sal_Int32 sEnd = 0; + + for (sal_Int32 i = 0; i < linkNames.getLength(); i++) + { + aLinkName = pLinkNames[i]; + + pTmpName = aLinkName.getStr(); + + if (pTmpName[0] != L'/') + continue; + + sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' ); + if ( nIndex == -1 ) + pShortName = 0; + else + pShortName = pTmpName+nIndex; + + while (pShortName && pShortName[1] == L'%') + { + nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' ); + if ( nIndex == -1 ) + pShortName = 0; + else + pShortName += nIndex+2; + } + + if (pShortName) + { + aLinkName = aLinkName.copy(0, pShortName - pTmpName); + } + + xReg->getRootKey()->deleteLink(aLinkName); + + sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' ); + + aLinkParent = aLinkName.copy(0, sEnd); + + while(aLinkParent.len()) + { + xLinkParent = xReg->getRootKey()->openKey(aLinkParent); + + if (xLinkParent.is() && (xLinkParent->getKeyNames().getLength() == 0)) + { + aLinkName = aLinkParent; + + xReg->getRootKey()->deleteKey(aLinkParent); + + sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' ); + + aLinkParent = aLinkName.copy(0, sEnd); + } else + { + break; + } + } + } + } + } + } + catch(InvalidRegistryException&) + { + } +} + +//************************************************************************* +// static prepareLink +// +static void prepareLink( const Reference < XSimpleRegistry > & xDest, + const Reference < XRegistryKey > & xSource, + const OUString& link) +{ + try + { + OUString linkRefName = xSource->getKeyName(); + OUString linkName(link); + sal_Bool isRelativ = False; + + const sal_Unicode* pTmpName = link.getStr(); + const sal_Unicode* pShortName; + sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' ); + if ( nIndex == -1 ) + pShortName = 0; + else + pShortName = pTmpName+nIndex; + + if (pTmpName[0] != L'/') + isRelativ = sal_True; + + while (pShortName && pShortName[1] == L'%') + { + nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' ); + if ( nIndex == -1 ) + pShortName = 0; + else + pShortName += nIndex+2; + } + + if (pShortName) + { + linkRefName = linkRefName + link.copy(pShortName - pTmpName + 1); + linkName = link.copy(0, pShortName - pTmpName); + } + + if (isRelativ) + xSource->createLink(linkName, linkRefName); + else + xDest->getRootKey()->createLink(linkName, linkRefName); + } + catch(InvalidRegistryException&) + { + } +} + +//************************************************************************* +// static searchImplForLink +// +static OUString searchImplForLink(const Reference < XRegistryKey > & xRootKey, + const OUString& linkName, + const OUString& implName) +{ + OUString ret; + + try + { + Reference < XRegistryKey > xKey = xRootKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS") ) ); + + if (xKey.is()) + { + Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys(); + + const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray(); + Reference < XRegistryKey > xImplKey; + + for (sal_Int32 i = 0; i < subKeys.getLength(); i++) + { + xImplKey = pSubKeys[i]; + + try + { + if (xImplKey->getKeyType( OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO") ) + linkName) == RegistryKeyType_LINK) + { + OUString oldImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/")); + if (implName != oldImplName) + { + ret = oldImplName; + break; + } + } + } + catch(InvalidRegistryException&) + { + } + } + } + } + catch(InvalidRegistryException&) + { + } + + return ret; +} + +//************************************************************************* +// static searchLinkTargetForImpl +// +static OUString searchLinkTargetForImpl(const Reference < XRegistryKey >& xRootKey, + const OUString& linkName, + const OUString& implName) +{ + OUString ret; + + try + { + Reference < XRegistryKey > xKey = xRootKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS") ) ); + + if (xKey.is()) + { + Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys(); + + const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray(); + Reference < XRegistryKey > xImplKey; + + for (sal_Int32 i = 0; i < subKeys.getLength(); i++) + { + xImplKey = pSubKeys[i]; + + OUString tmpImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/")); + if (tmpImplName == implName && + xImplKey->getKeyType(OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO") ) + linkName) == RegistryKeyType_LINK) + { + return xImplKey->getLinkTarget(OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO") ) + linkName); + } + } + } + } + catch(InvalidRegistryException&) + { + } + + return ret; +} + +//************************************************************************* +// static createUniqueSubEntry +// +static void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey, + const OUString& value) +{ + if (xSuperKey.is()) + { + try + { + if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST) + { + sal_Int32 entryNum = 1; + sal_Int32 length = 0; + sal_Bool bReady = sal_False; + + Sequence<OUString> implEntries = xSuperKey->getAsciiListValue(); + length = implEntries.getLength(); + + for (sal_Int32 i = 0; !bReady && (i < length); i++) + { + bReady = (implEntries.getConstArray()[i] == value); + } + + if (bReady) + { + Sequence<OUString> implEntriesNew(length); + implEntriesNew.getArray()[0] = value; + + for (sal_Int32 i=0, j=1; i < length; i++) + { + if (implEntries.getConstArray()[i] != value) + implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i]; + } + xSuperKey->setAsciiListValue(implEntriesNew); + } else + { + Sequence<OUString> implEntriesNew(length+1); + implEntriesNew.getArray()[0] = value; + + for (sal_Int32 i = 0; i < length; i++) + { + implEntriesNew.getArray()[i+1] = implEntries.getConstArray()[i]; + } + xSuperKey->setAsciiListValue(implEntriesNew); + } + } else + { + Sequence<OUString> implEntriesNew(1); + + implEntriesNew.getArray()[0] = value; + + xSuperKey->setAsciiListValue(implEntriesNew); + } + } + catch(InvalidRegistryException&) + { + } + } +} + +//************************************************************************* +// static deleteSubEntry +// +static sal_Bool deleteSubEntry(const Reference < XRegistryKey >& xSuperKey, const OUString& value) +{ + if (xSuperKey.is()) + { + try + { + if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST) + { + Sequence<OUString> implEntries = xSuperKey->getAsciiListValue(); + sal_Int32 length = implEntries.getLength(); + sal_Int32 equals = 0; + sal_Bool hasNoImplementations = sal_False; + + for (sal_Int32 i = 0; i < length; i++) + { + if (implEntries.getConstArray()[i] == value) + equals++; + } + + if (equals == length) + { + hasNoImplementations = sal_True; + } else + { + Sequence<OUString> implEntriesNew(length - equals); + + sal_Int32 j = 0; + for (sal_Int32 i = 0; i < length; i++) + { + if (implEntries.getConstArray()[i] != value) + { + implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i]; + } + } + xSuperKey->setAsciiListValue(implEntriesNew); + } + + if (hasNoImplementations) + { + return sal_True; + } + } + } + catch(InvalidRegistryException&) + { + } + } + + return sal_False; +} + +//************************************************************************* +// static prepareUserLink +// +static sal_Bool prepareUserLink(const Reference < XSimpleRegistry >& xDest, + const OUString& linkName, + const OUString& linkTarget, + const OUString& implName) +{ + sal_Bool ret = sal_False; + + Reference < XRegistryKey > xRootKey; + + try + { + xRootKey = xDest->getRootKey(); + + if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK) + { + OUString oldImplName(searchImplForLink(xRootKey, linkName, implName)); + + if (oldImplName.len()) + { + createUniqueSubEntry(xDest->getRootKey()->createKey( + linkName + OUString( RTL_CONSTASCII_USTRINGPARAM(":old") ) ), oldImplName); + } + } + } + catch (InvalidRegistryException&) + { + } + + try + { + if (xRootKey->isValid()) + { + ret = xRootKey->createLink(linkName, linkTarget); + } + } + catch(InvalidRegistryException&) + { + } + + return ret; +} + +//************************************************************************* +// static deleteUserLink +// +static void deletePathIfPossible(const Reference < XRegistryKey >& xRootKey, + const OUString& path) +{ + try + { + Sequence<OUString> keyNames(xRootKey->openKey(path)->getKeyNames()); + + if (keyNames.getLength() == 0 && + xRootKey->openKey(path)->getValueType() == RegistryValueType_NOT_DEFINED) + { + xRootKey->deleteKey(path); + + OUString tmpPath(path); + OUString newPath = tmpPath.copy(0, tmpPath.lastIndexOf('/')).getStr(); + + if (newPath.len() > 1) + deletePathIfPossible(xRootKey, newPath); + } + } + catch(InvalidRegistryException&) + { + } +} + + +//************************************************************************* +// static deleteUserLink +// +static sal_Bool deleteUserLink(const Reference < XRegistryKey >& xRootKey, + const OUString& linkName, + const OUString& linkTarget, + const OUString& implName) +{ + sal_Bool ret = sal_False; + + try + { + sal_Bool bClean = sal_False; + + if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK) + { + OUString tmpTarget = xRootKey->getLinkTarget(linkName); + + if (tmpTarget == linkTarget) + { + xRootKey->deleteLink(linkName); + } + } + + Reference < XRegistryKey > xOldKey = xRootKey->openKey( + linkName + OUString( RTL_CONSTASCII_USTRINGPARAM(":old") )); + if (xOldKey.is()) + { + sal_Bool hasNoImplementations = sal_False; + + if (xOldKey->getValueType() == RegistryValueType_ASCIILIST) + { + Sequence<OUString> implEntries = xOldKey->getAsciiListValue(); + sal_Int32 length = implEntries.getLength(); + sal_Int32 equals = 0; + + for (sal_Int32 i = 0; i < length; i++) + { + if (implEntries.getConstArray()[i] == implName) + equals++; + } + + if (equals == length) + { + hasNoImplementations = sal_True; + } else + { + OUString oldImpl; + + if (length > equals + 1) + { + Sequence<OUString> implEntriesNew(length - equals - 1); + + sal_Int32 j = 0; + sal_Bool first = sal_True; + for (sal_Int32 i = 0; i < length; i++) + { + if (implEntries.getConstArray()[i] != implName) + { + if (first) + { + oldImpl = implEntries.getConstArray()[i]; + first = sal_False; + } else + { + implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i]; + } + } + } + + xOldKey->setAsciiListValue(implEntriesNew); + } else + { + oldImpl = implEntries.getConstArray()[0]; + + xOldKey->closeKey(); + xRootKey->deleteKey(xOldKey->getKeyName()); + } + + OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl); + if (oldTarget.len()) + { + xRootKey->createLink(linkName, oldTarget); + } + } + + if (hasNoImplementations) + { + bClean = sal_True; + hasNoImplementations = sal_False; + xOldKey->closeKey(); + xRootKey->deleteKey(xOldKey->getKeyName()); + } + } + } else + { + bClean = sal_True; + } + + if (bClean) + { + OUString tmpName(linkName); + OUString path = tmpName.copy(0, tmpName.lastIndexOf('/')).getStr(); + deletePathIfPossible(xRootKey, path); + } + } + catch(InvalidRegistryException&) + { + } + + return ret; +} + +//************************************************************************* +// static prepareUserKeys +// +static sal_Bool prepareUserKeys(const Reference < XSimpleRegistry >& xDest, + const Reference < XRegistryKey >& xUnoKey, + const Reference < XRegistryKey >& xKey, + const OUString& implName, + sal_Bool bRegister) +{ + sal_Bool ret = sal_False; + sal_Bool hasSubKeys = sal_False; + + try + { + Sequence<OUString> keyNames = xKey->getKeyNames(); + + OUString relativKey; + if (keyNames.getLength()) + relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().len()+1); + + if (keyNames.getLength() == 1 && + xKey->getKeyType(relativKey) == RegistryKeyType_LINK) + { + hasSubKeys = sal_True; + + OUString linkTarget = xKey->getLinkTarget(relativKey); + OUString linkName(xKey->getKeyName().copy(xUnoKey->getKeyName().len())); + + linkName = linkName + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + relativKey; + + if (bRegister) + { + prepareUserLink(xDest, linkName, linkTarget, implName); + } else + { + deleteUserLink(xDest->getRootKey(), linkName, linkTarget, implName); + } + } else + { + Sequence< Reference < XRegistryKey> > subKeys = xKey->openKeys(); + + if (subKeys.getLength()) + { + hasSubKeys = sal_True; + const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray(); + + for (sal_Int32 i = 0; i < subKeys.getLength(); i++) + { + ret = prepareUserKeys(xDest, xUnoKey, pSubKeys[i], implName, bRegister); + } + } + } + } + catch(InvalidRegistryException&) + { + } + + try + { + if (hasSubKeys) + { + return ret; + } + + OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().len())); + + Reference < XRegistryKey > xRootKey = xDest->getRootKey(); + if (bRegister) + { + createUniqueSubEntry(xRootKey->createKey(keyName), implName); + } else + { + if (deleteSubEntry(xRootKey->openKey(keyName), implName)) + { + xRootKey->deleteKey(keyName); + + OUString tmpName(keyName); + OUString path = tmpName.copy(0, tmpName.lastIndexOf('/')).getStr(); + deletePathIfPossible(xRootKey, path); + } + } + } + catch(InvalidRegistryException&) + { + } + + return ret; +} + +//************************************************************************* +// static deleteAllImplementations +// +static void deleteAllImplementations( const Reference < XSimpleRegistry >& xReg, + const Reference < XRegistryKey >& xSource, + const OUString& locationUrl, + std::list<OUString> & implNames) +{ + try + { + Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys(); + + if (subKeys.getLength() > 0) + { + const Reference < XRegistryKey> * pSubKeys = subKeys.getConstArray(); + Reference < XRegistryKey > xImplKey; + sal_Bool hasLocationUrl = sal_False; + + for (sal_Int32 i = 0; i < subKeys.getLength(); i++) + { + xImplKey = pSubKeys[i]; + Reference < XRegistryKey > xKey = xImplKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") ) );; + + if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII)) + { + if (xKey->getAsciiValue() == locationUrl) + { + hasLocationUrl = sal_True; + + OUString implName(xImplKey->getKeyName().getStr() + 1); + sal_Int32 firstDot = implName.search(L'/'); + + if (firstDot >= 0) + implName = implName.copy(firstDot + 1); + + implNames.push_back(implName); + + deleteAllLinkReferences(xReg, xImplKey); + + xKey = xImplKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO"))); + if (xKey.is()) + { + Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys(); + + if (subKeys.getLength()) + { + const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray(); + + for (sal_Int32 i = 0; i < subKeys.getLength(); i++) + { + if (pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVCIES") )) && + pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS") )) && + pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") )) && + pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") ))) + { + prepareUserKeys(xReg, xKey, pSubKeys[i], implName, sal_False); + } + } + } + } + } + } + + if (hasLocationUrl) + { + hasLocationUrl = sal_False; + xImplKey->closeKey(); + xReg->getRootKey()->deleteKey(xImplKey->getKeyName()); + } + } + + subKeys = xSource->openKeys(); + if (subKeys.getLength() == 0) + { + xSource->closeKey(); + xReg->getRootKey()->deleteKey(xSource->getKeyName()); + } + } else + { + xSource->closeKey(); + xReg->getRootKey()->deleteKey(xSource->getKeyName()); + } + } + catch(InvalidRegistryException&) + { + } +} + +//************************************************************************* +// static deleteAllServiceEntries +// +static void deleteAllServiceEntries( const Reference < XSimpleRegistry >& xReg, + const Reference < XRegistryKey >& xSource, + const OUString& implName) +{ + try + { + Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys(); + + if (subKeys.getLength() > 0) + { + const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray(); + Reference < XRegistryKey > xServiceKey; + sal_Bool hasNoImplementations = sal_False; + + for (sal_Int32 i = 0; i < subKeys.getLength(); i++) + { + xServiceKey = pSubKeys[i]; + + if (xServiceKey->getValueType() == RegistryValueType_ASCIILIST) + { + Sequence<OUString> implEntries = xServiceKey->getAsciiListValue(); + sal_Int32 length = implEntries.getLength(); + sal_Int32 equals = 0; + + for (sal_Int32 i = 0; i < length; i++) + { + if (implEntries.getConstArray()[i] == implName) + equals++; + } + + if (equals == length) + { + hasNoImplementations = sal_True; + } else + { + if (equals > 0) + { + Sequence<OUString> implEntriesNew(length-equals); + + sal_Int32 j = 0; + for (sal_Int32 i = 0; i < length; i++) + { + if (implEntries.getConstArray()[i] != implName) + { + implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i]; + } + } + + xServiceKey->setAsciiListValue(implEntriesNew); + } + } + } + + if (hasNoImplementations) + { + hasNoImplementations = sal_False; + xServiceKey->closeKey(); + xReg->getRootKey()->deleteKey(xServiceKey->getKeyName()); + } + } + + subKeys = xSource->openKeys(); + if (subKeys.getLength() == 0) + { + xSource->closeKey(); + xReg->getRootKey()->deleteKey(xSource->getKeyName()); + } + } else + { + xSource->closeKey(); + xReg->getRootKey()->deleteKey(xSource->getKeyName()); + } + } + catch(InvalidRegistryException&) + { + } +} + + +//************************************************************************* +// static prepareRegistry +// +static sal_Bool prepareRegistry(const Reference < XSimpleRegistry >& xDest, + const Reference < XRegistryKey >& xSource, + const OUString& implementationLoaderUrl, + const OUString& locationUrl) +{ + sal_Bool ret = sal_False; + + try + { + Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys(); + + if (!subKeys.getLength()) + { + return ret; + } + + + const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray(); + Reference < XRegistryKey > xImplKey; + + for (sal_Int32 i = 0; i < subKeys.getLength(); i++) + { + xImplKey = pSubKeys[i]; + + Reference < XRegistryKey > xKey = xImplKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES") ) ); + + if (xKey.is()) + { + // update entries in SERVICES section + Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys(); + OUString implName; + + if (serviceKeys.getLength()) + { + const Reference < XRegistryKey > * pServiceKeys = serviceKeys.getConstArray(); + + implName = OUString(xImplKey->getKeyName().getStr() + 1); + sal_Int32 firstDot = implName.search(L'/'); + + if (firstDot >= 0) + implName = implName.copy(firstDot + 1); + + sal_Int32 offset = xKey->getKeyName().len() + 1; + + for (sal_Int32 i = 0; i < serviceKeys.getLength(); i++) + { + OUString serviceName = pServiceKeys[i]->getKeyName().copy(offset); + + createUniqueSubEntry( + xDest->getRootKey()->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/SERVICES/") ) + serviceName ), + implName); + } + + ret = sal_True; + } + + xKey = xImplKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO") )); + if (xKey.is()) + { + Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys(); + + if (subKeys.getLength()) + { + const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray(); + + for (sal_Int32 i = 0; i < subKeys.getLength(); i++) + { + if (pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVCIES") )) && + pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS") ))) + { + prepareUserKeys(xDest, xKey, pSubKeys[i], implName, sal_True); + } + } + } + } + + // update LOCATION entry + xKey = xImplKey->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") ) ); + + if (xKey.is()) + { + xKey->setAsciiValue(locationUrl); + } + + // update ACTIVATOR entry + xKey = xImplKey->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") ) ); + + if (xKey.is()) + { + xKey->setAsciiValue(implementationLoaderUrl); + } + + // update DATA entry + //xKey = xImplKey->createKey("/DATA"); + + xKey = xImplKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS") ) ); + + if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST)) + { + // update link entries in REGISTRY_LINKS section + Sequence<OUString> linkNames = xKey->getAsciiListValue(); + + if (linkNames.getLength()) + { + const OUString* pLinkNames = linkNames.getConstArray(); + + for (sal_Int32 i = 0; i < linkNames.getLength(); i++) + { + prepareLink(xDest, xImplKey, pLinkNames[i]); + } + } + } + } + } + } + catch(InvalidRegistryException&) + { + } + + return ret; +} + + +static void findImplementations( const Reference < XRegistryKey > & xSource, + std::list <OUString>& implNames) +{ + sal_Bool isImplKey = sal_False; + + try + { + Reference < XRegistryKey > xKey = xSource->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES") ) ); + + if (xKey.is() && (xKey->getKeyNames().getLength() > 0)) + { + isImplKey = sal_True; + + OUString implName = OUString(xSource->getKeyName().getStr() + 1).replace(L'/', L'.').getStr(); + sal_Int32 firstDot = implName.search(L'.'); + + if (firstDot >= 0) + implName = implName.copy(firstDot + 1); + + implNames.push_back(implName); + } + } + catch(InvalidRegistryException&) + { + } + + if (isImplKey) return; + + try + { + Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys(); + + if (subKeys.getLength() > 0) + { + const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray(); + + for (sal_Int32 i = 0; i < subKeys.getLength(); i++) + { + findImplementations(pSubKeys[i], implNames); + } + + } + } + catch(InvalidRegistryException&) + { + } +} + + + + + + + + +//************************************************************************* +// class ImplementationRegistration the implenetation of interface +// XImplementationRegistration +// +class ImplementationRegistration + : public WeakImplHelper3< XImplementationRegistration, XServiceInfo, XInitialization > +{ +public: + ImplementationRegistration( const Reference < XMultiServiceFactory > & rSMgr ); + ~ImplementationRegistration(); + + // XServiceInfo + OUString SAL_CALL getImplementationName() throw(); + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(); + Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw(); + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(void) throw(); + + // Methoden von XImplementationRegistration + virtual void SAL_CALL registerImplementation( + const OUString& implementationLoader, + const OUString& location, + const Reference < XSimpleRegistry > & xReg) + throw( CannotRegisterImplementationException, RuntimeException ); + + virtual sal_Bool SAL_CALL revokeImplementation( + const OUString& location, + const Reference < XSimpleRegistry >& xReg) + throw( RuntimeException ); + + virtual Sequence< OUString > SAL_CALL getImplementations( + const OUString& implementationLoader, + const OUString& location) + throw( RuntimeException ); + virtual Sequence< OUString > SAL_CALL checkInstantiation( + const OUString& implementationName) + throw( RuntimeException ); + +public: // XInitialization + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + +private: // helper methods + + static sal_Bool doRegistration( const Reference < XMultiServiceFactory >& xSMgr, + const Reference < XImplementationLoader >& xAct, + const Reference < XSimpleRegistry >& xDest, + const OUString& implementationLoaderUrl, + const OUString& locationUrl, + sal_Bool bRegister); + + Reference< XSimpleRegistry > getRegistryFromServiceManager(); + + static Reference< XSimpleRegistry > createTemporarySimpleRegistry( const Reference < XMultiServiceFactory > & r ); + +private: // members + Reference < XMultiServiceFactory > m_xSMgr; +}; + +//************************************************************************* +// ImplementationRegistration() +// +ImplementationRegistration::ImplementationRegistration( const Reference < XMultiServiceFactory > & rSMgr ) + : m_xSMgr( rSMgr ) +{ +} + +//************************************************************************* +// ~ImplementationRegistration() +// +ImplementationRegistration::~ImplementationRegistration() +{ +} + + +// XServiceInfo +OUString ImplementationRegistration::getImplementationName() throw() +{ + return OUString::createFromAscii( IMPLEMENTATION_NAME ); +} + +// XServiceInfo +sal_Bool ImplementationRegistration::supportsService(const OUString& ServiceName) throw() +{ + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +// XServiceInfo +Sequence< OUString > ImplementationRegistration::getSupportedServiceNames(void) throw() +{ + return getSupportedServiceNames_Static(); +} + +// ORegistryServiceManager_Static +Sequence< OUString > ImplementationRegistration::getSupportedServiceNames_Static(void) throw () +{ + OUString aServiceName( OUString::createFromAscii( SERVICE_NAME ) ); + Sequence< OUString > aSNS( &aServiceName, 1 ); + return aSNS; +} + + +Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager() +{ + Reference < XPropertySet > xPropSet = + Reference< XPropertySet >::query (m_xSMgr ); + Reference < XSimpleRegistry > xRegistry; + + if( xPropSet.is() ) { + + try { // the implementation does not support XIntrospectionAccess ! + + Any aAny = xPropSet->getPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM("Registry") ) ); + + if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) { + aAny >>= xRegistry; + } + } + catch( UnknownPropertyException e ) { + // empty reference is error signal ! + } + } + + return xRegistry; +} + + +//************************************************************************ +// XInitialization +// +void ImplementationRegistration::initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArgs ) + throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + + if( aArgs.getLength() != 4 ) { + throw IllegalArgumentException(); + } + + Reference< XImplementationLoader > rLoader; + OUString loaderServiceName; + OUString locationUrl; + Reference< XSimpleRegistry > rReg; + + // 1st argument : An instance of an implementation loader + if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) { + aArgs.getConstArray()[0] >>= rLoader; + } + if( !rLoader.is()) { + throw IllegalArgumentException(); + } + + // 2nd argument : The service name of the loader. This name is written into the registry + if( aArgs.getConstArray()[1].getValueType().getTypeClass() == TypeClass_STRING ) { + aArgs.getConstArray()[1] >>= loaderServiceName; + } + if( ! loaderServiceName.getLength() ) { + throw IllegalArgumentException(); + } + + // 3rd argument : The file name of the dll, that contains the loader + if( aArgs.getConstArray()[2].getValueType().getTypeClass() == TypeClass_STRING ) { + aArgs.getConstArray()[2] >>= locationUrl; + } + if( ! locationUrl.getLength() ) { + throw IllegalArgumentException(); + } + + // 4th argument : The registry, the service should be written to + if( aArgs.getConstArray()[3].getValueType().getTypeClass() == TypeClass_INTERFACE ) { + aArgs.getConstArray()[3] >>= rReg; + } + + if( !rReg.is() ) { + rReg = getRegistryFromServiceManager(); + if( !rReg.is() ) { + throw IllegalArgumentException(); + } + } + + + // TODO : SimpleRegistry in doRegistration von hand anziehen ! + if (!doRegistration(m_xSMgr, rLoader , rReg, loaderServiceName , locationUrl, sal_True)) { + throw Exception(); + } + + // ------------------------------------------------------------ +} + + + +//************************************************************************* +// virtual function registerImplementation of XImplementationRegistration +// +void ImplementationRegistration::registerImplementation( + const OUString& implementationLoaderUrl, + const OUString& locationUrl, + const Reference < XSimpleRegistry > & xReg) + throw( CannotRegisterImplementationException, RuntimeException ) +{ + OUString implLoaderUrl(implementationLoaderUrl); + OUString activatorName; + + if (implementationLoaderUrl.len() > 0) + { + OUString tmpActivator(implementationLoaderUrl.getStr()); + activatorName = tmpActivator.getToken(0, L':').getStr(); + } else + { + // check locationUrl to find out what kind of loader is needed + // set iimplLoaderUrl + } + + if( m_xSMgr.is() ) { + Reference < XImplementationLoader > xAct( m_xSMgr->createInstance(activatorName) , UNO_QUERY ); + if (xAct.is()) + { + Reference < XSimpleRegistry > xRegistry; + + if (xReg.is()) + { + // registry supplied by user + xRegistry = xReg; + } + else + { + xRegistry = getRegistryFromServiceManager(); + } + + if ( xRegistry.is()) + { + if (!doRegistration(m_xSMgr, xAct, xRegistry, implLoaderUrl, locationUrl, sal_True)) + throw CannotRegisterImplementationException(); + + return; + } + } + } + + throw CannotRegisterImplementationException(); +} + +//************************************************************************* +// virtual function revokeImplementation of XImplementationRegistration +// +sal_Bool ImplementationRegistration::revokeImplementation(const OUString& location, + const Reference < XSimpleRegistry >& xReg) + throw ( RuntimeException ) +{ + sal_Bool ret = sal_False; + + Reference < XSimpleRegistry > xRegistry; + + if (xReg.is()) { + xRegistry = xReg; + } + else { + Reference < XPropertySet > xPropSet = Reference< XPropertySet >::query( m_xSMgr ); + if( xPropSet.is() ) { + try { + Any aAny = xPropSet->getPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM("Registry") ) ); + + if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) + { + aAny >>= xRegistry; + } + } + catch ( UnknownPropertyException e ) { + } + } + } + + if (xRegistry.is()) + { + ret = doRegistration(m_xSMgr, Reference< XImplementationLoader > (), xRegistry, OUString(), location, sal_False); + } + + return ret; +} + +//************************************************************************* +// virtual function getImplementations of XImplementationRegistration +// +Sequence< OUString > ImplementationRegistration::getImplementations( + const OUString & implementationLoaderUrl, + const OUString & locationUrl) + throw ( RuntimeException ) +{ + OUString implLoaderUrl(implementationLoaderUrl); + OUString activatorName; + + if (implementationLoaderUrl.len() > 0) + { + OUString tmpActivator(implementationLoaderUrl.getStr()); + activatorName = tmpActivator.getToken(0, L':').getStr(); + } else + { + // check locationUrl to find out what kind of loader is needed + // set implLoaderUrl + } + + if( m_xSMgr.is() ) { + + Reference < XImplementationLoader > xAct( m_xSMgr->createInstance( activatorName ), UNO_QUERY ); + + if (xAct.is()) + { + + Reference < XSimpleRegistry > xReg = createTemporarySimpleRegistry( m_xSMgr); + + if (xReg.is()) + { + try + { + OUString aTempName = getTempName(); + + xReg->open(aTempName, sal_False, sal_True); + Reference < XRegistryKey > xImpl; + + { // only necessary for deleting the temporary variable of rootkey + xImpl = xReg->getRootKey()->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS") ) ); + } + if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl)) + { + std::list <OUString> implNames; + + findImplementations(xImpl, implNames); + + if (!implNames.empty()) + { + std::list<OUString>::const_iterator iter = implNames.begin(); + + Sequence<OUString> seqImpl(implNames.size()); + OUString *pImplNames = seqImpl.getArray(); + + sal_Int32 index = 0; + while (iter != implNames.end()) + { + pImplNames[index] = *iter; + index++; + ++iter; + } + + xImpl->closeKey(); + xReg->destroy(); + return seqImpl; + } + } + + xImpl->closeKey(); + xReg->destroy(); + } + catch(MergeConflictException&) + { + } + catch(InvalidRegistryException&) + { + } + } + } + } + + return Sequence<OUString>(); +} + +//************************************************************************* +// virtual function checkInstantiation of XImplementationRegistration +// +Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString& implementationName) + throw ( RuntimeException ) +{ + VOS_ENSHURE( sal_False, "ImplementationRegistration::checkInstantiation not implemented" ); + return Sequence<OUString>(); +} + +//************************************************************************* +// helper function doRegistration +// +sal_Bool ImplementationRegistration::doRegistration( + const Reference< XMultiServiceFactory > & xSMgr, + const Reference < XImplementationLoader > & xAct, + const Reference < XSimpleRegistry >& xDest, + const OUString& implementationLoaderUrl, + const OUString& locationUrl, + sal_Bool bRegister) +{ + sal_Bool ret = sal_False; + + if (!bRegister) + { + // deregister + try + { + if( xDest.is() ) + { + std::list<OUString> aNames; + + Reference < XRegistryKey > xRootKey( xDest->getRootKey() ); + + Reference < XRegistryKey > xKey = xRootKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS") ) ); + if (xKey.is()) + { + deleteAllImplementations(xDest, xKey, locationUrl, aNames); + ret = sal_True; + } + + + xKey = xRootKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/SERVICES") ) ); + if (xKey.is()) + { + std::list<OUString>::const_iterator iter = aNames.begin(); + + while (iter != aNames.end()) + { + deleteAllServiceEntries(xDest, xKey, *iter); + ++iter; + } + } + + if (xRootKey.is()) + xRootKey->closeKey(); + if (xKey.is()) + xKey->closeKey(); + } + } + catch(InvalidRegistryException&) + { + } + } else + { + Reference < XSimpleRegistry > xReg = createTemporarySimpleRegistry( xSMgr ); + Reference < XRegistryKey > xSourceKey; + + if (xAct.is() && xReg.is() && xDest.is()) + { + OUString aTempName = getTempName(); + try + { + xReg->open(aTempName, sal_False, sal_True); + + { // only necessary for deleting the temporary variable of rootkey + xSourceKey = xReg->getRootKey()->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS") ) ); + } + + if (xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl)) + { + if (prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, locationUrl)) + { + // Release Source key and registry. + xSourceKey->closeKey(); + xReg->close(); + + xDest->mergeKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ), aTempName ); + + ret = sal_True; + } + } + + // Cleanup Source registry. + if ( xSourceKey->isValid() ) + xSourceKey->closeKey(); + if ( xReg->isValid() ) + xReg->destroy(); + else + { + xReg->open( aTempName, sal_False, sal_True ); + xReg->destroy(); + } + } + catch(MergeConflictException&) + { + } + catch(InvalidRegistryException&) + { + } + catch(CannotRegisterImplementationException&) + { + // destroy temp registry + if ( xSourceKey->isValid() ) + xSourceKey->closeKey(); + if ( xReg->isValid() ) + xReg->destroy(); + else + { + xReg->open( aTempName, sal_False, sal_True ); + xReg->destroy(); + } + // and throw again + throw; + } + } + } + + return ret; +} + + + +Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry( + const ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory > & rSMgr) +{ + + Reference < XSimpleRegistry > xReg = Reference< XSimpleRegistry >::query( + rSMgr->createInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry") ) ) ); + OSL_ASSERT( xReg.is() ); +// if( ! xReg.is() ) { +// // use as fallback ( bootstrap ) + +// Reference< XInterface > r = ::cppu::__loadLibComponentFactory( +// "simreg", +// "com.sun.star.comp.stoc.SimpleRegistry", +// rSMgr , +// Reference < XRegistryKey >() )->createInstance(); + +// xReg = Reference< XSimpleRegistry > ( r , UNO_QUERY ); +// } + + return xReg; +} + + + +//************************************************************************* +static Reference<XInterface> SAL_CALL ImplementationRegistration_CreateInstance( const Reference<XMultiServiceFactory> & rSMgr ) throw(Exception) +{ + return (XImplementationRegistration *)new ImplementationRegistration(rSMgr); +} + +} + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString::createFromAscii( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) ); + + const Sequence< OUString > & rSNL = + ::stoc_impreg::ImplementationRegistration::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + ::stoc_impreg::ImplementationRegistration_CreateInstance, + ::stoc_impreg::ImplementationRegistration::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + diff --git a/stoc/source/implementationregistration/makefile.mk b/stoc/source/implementationregistration/makefile.mk new file mode 100644 index 000000000000..1df1a699dfe3 --- /dev/null +++ b/stoc/source/implementationregistration/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= impreg +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +BOOTSTRAP_SERVICE=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + + +SLOFILES= \ + $(SLO)$/implreg.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/stoc/source/inspect/insp.xml b/stoc/source/inspect/insp.xml new file mode 100644 index 000000000000..2f7bc5b8cc60 --- /dev/null +++ b/stoc/source/inspect/insp.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE COMPONENTDESCRIPTION PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "componentdescription.dtd"> + +<COMPONENTDESCRIPTION + xmlns:xlink="http://www.w3.org/1999/xlink/Namespace" > + +<Author> Juergen Schmidt </Author> + +<Name> com.sun.star.comp.stoc.Introspection </Name> + +<Description> + This component implements XIntrospection. The method XIntrospection::inspect(any object) + returns an XIntrospectionAccess that provides information about the methods, properties + and listeners supported by the inspected object. Matching pairs of getName/setName() + methods will also be offered as property "Name". +</Description> + +<ModuleName> insp </ModuleName> + +<LoaderName> com.sun.star.loader.SharedLibrary </LoaderName> + +<Language> c++ </Language> + +<Status StatusValue="final"/> + +<SupportedService> com.sun.star.beans.Introspection </SupportedService> + +<ServiceDependency> com.sun.star.reflection.CoreReflection </ServiceDependency> + +<ProjectBuildDependency> cppuhelper </ProjectBuildDependency> +<ProjectBuildDependency> cppu </ProjectBuildDependency> +<ProjectBuildDependency> vos </ProjectBuildDependency> +<ProjectBuildDependency> sal </ProjectBuildDependency> + +<RuntimeModuleDependency> cppuhelper </RuntimeModuleDependency> +<RuntimeModuleDependency> cppu1 </RuntimeModuleDependency> +<RuntimeModuleDependency> vos1$(COM) </RuntimeModuleDependency> +<RuntimeModuleDependency> sal1 </RuntimeModuleDependency> + +<Type> com.sun.star.beans.XIntrospection </Type> +<Type> com.sun.star.beans.XIntrospectionAccess </Type> +<Type> com.sun.star.beans.XPropertySet </Type> +<Type> com.sun.star.beans.XFastPropertySet </Type> +<Type> com.sun.star.beans.XMaterialHolder </Type> +<Type> com.sun.star.beans.XExactName </Type> +<Type> com.sun.star.beans.PropertyAttribute </Type> +<Type> com.sun.star.beans.PropertyConcept </Type> +<Type> com.sun.star.beans.MethodConcept </Type> +<Type> com.sun.star.lang.XEventListener </Type> +<Type> com.sun.star.lang.XInitialization </Type> +<Type> com.sun.star.lang.XTypeProvider </Type> +<Type> com.sun.star.lang.XServiceInfo </Type> +<Type> com.sun.star.lang.XSingleServiceFactory </Type> +<Type> com.sun.star.lang.XMultiServiceFactory </Type> +<Type> com.sun.star.registry.XRegistryKey </Type> +<Type> com.sun.star.uno.XAggregation </Type> +<Type> com.sun.star.uno.XWeak </Type> +<Type> com.sun.star.uno.TypeClass </Type> +<Type> com.sun.star.container.XEnumerationAccess </Type> +<Type> com.sun.star.container.XNameContainer </Type> +<Type> com.sun.star.container.XIndexContainer </Type> +<Type> com.sun.star.reflection.XIdlReflection </Type> +<Type> com.sun.star.reflection.XIdlClassProvider </Type> +<Type> com.sun.star.reflection.XIdlClass </Type> +<Type> com.sun.star.reflection.XIdlArray </Type> +<Type> com.sun.star.reflection.FieldAccessMode </Type> + +</COMPONENTDESCRIPTION> diff --git a/stoc/source/inspect/introspection.cxx b/stoc/source/inspect/introspection.cxx new file mode 100644 index 000000000000..2a838d534e22 --- /dev/null +++ b/stoc/source/inspect/introspection.cxx @@ -0,0 +1,3023 @@ +/************************************************************************* + * + * $RCSfile: introspection.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + + +// Schalter fuer Introspection-Caching +#ifndef OS2 +#define USE_INTROSPECTION_CACHE +#endif + +#ifdef USE_INTROSPECTION_CACHE +#define INTROSPECTION_CACHE_MAX_SIZE 100 +#endif + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _VOS_MODULE_HXX_ +#include <vos/module.hxx> +#endif + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_COMPONENT_HXX_ +#include <cppuhelper/component.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#include <cppuhelper/implbase3.hxx> +#include <cppuhelper/typeprovider.hxx> + +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> +#include <com/sun/star/reflection/XIdlClassProvider.hpp> +#include <com/sun/star/reflection/XIdlClass.hpp> +#include <com/sun/star/beans/UnknownPropertyException.hpp> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XFastPropertySet.hpp> +#include <com/sun/star/beans/XIntrospection.hpp> +#include <com/sun/star/beans/XIntrospectionAccess.hpp> +#include <com/sun/star/beans/XMaterialHolder.hpp> +#include <com/sun/star/beans/XExactName.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertyConcept.hpp> +#include <com/sun/star/beans/MethodConcept.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +#include <rtl/ustrbuf.hxx> +#include <rtl/strbuf.hxx> +#include <stl/hash_map> + +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 namespace com::sun::star::beans; +using namespace com::sun::star::beans::PropertyAttribute; +using namespace com::sun::star::beans::PropertyConcept; +using namespace com::sun::star::beans::MethodConcept; +using namespace cppu; +using namespace osl; +using namespace rtl; + +#define IMPLEMENTATION_NAME "com.sun.star.comp.stoc.Introspection" +#define SERVICE_NAME "com.sun.star.beans.Introspection" + +namespace stoc_inspect +{ + +typedef WeakImplHelper3< XIntrospectionAccess, XMaterialHolder, XExactName > IntrospectionAccessHelper; + + +//================================================================================================== + +// Spezial-Wert fuer Method-Concept, um "normale" Funktionen kennzeichnen zu koennen +#define MethodConcept_NORMAL_IMPL 0x80000000 + + +// Methode zur Feststellung, ob eine Klasse von einer anderen abgeleitet ist +sal_Bool isDerivedFrom( Reference<XIdlClass> xToTestClass, Reference<XIdlClass> xDerivedFromClass ) +{ + Sequence< Reference<XIdlClass> > aClassesSeq = xToTestClass->getSuperclasses(); + const Reference<XIdlClass>* pClassesArray = aClassesSeq.getConstArray(); + sal_Int32 nSuperClassCount = aClassesSeq.getLength(); + sal_Int32 i; + for( i = 0 ; i < nSuperClassCount ; i++ ) + { + const Reference<XIdlClass>& rxClass = pClassesArray[i]; + if( xDerivedFromClass->equals( rxClass ) ) + { + // Treffer + return sal_True; + } + else + { + // Rekursiv weitersuchen + return isDerivedFrom( rxClass, xDerivedFromClass ); + } + } + return sal_False; +} + +//======================================================================== + +// *** Klassifizierung der Properties (kein enum, um Sequence verwenden zu koennen) *** +// Properties aus einem PropertySet-Interface +#define MAP_PROPERTY_SET 0 +// Properties aus Fields +#define MAP_FIELD 1 +// Properties, die durch get/set-Methoden beschrieben werden +#define MAP_GETSET 2 +// Properties, die nur eine set-Methode haben +#define MAP_SETONLY 3 + + +// Schrittweite, in der die Groesse der Sequences angepasst wird +#define ARRAY_SIZE_STEP 20 + + + +//************************************** +//*** IntrospectionAccessStatic_Impl *** +//************************************** +// Entspricht dem alten IntrospectionAccessImpl, bildet jetzt den statischen +// Anteil des neuen Instanz-bezogenen ImplIntrospectionAccess + +// ACHTUNG !!! Von Hand refcounten !!! + + +// Hashtable fuer die Suche nach Namen +struct hashName_Impl +{ + size_t operator()(const OUString Str) const + { + return (size_t)Str.hashCode(); + } +}; + +struct eqName_Impl +{ + sal_Bool operator()(const OUString Str1, const OUString Str2) const + { + return ( Str1 == Str2 ); + } +}; + +typedef NAMESPACE_STD(hash_map) +< + OUString, + sal_Int32, + hashName_Impl, + eqName_Impl +> +IntrospectionNameMap; + + +// Hashtable zur Zuordnung der exakten Namen zu den zu Lower-Case +// konvertierten Namen, dient zur Unterstützung von XExactName +typedef NAMESPACE_STD(hash_map) +< + OUString, + OUString, + hashName_Impl, + eqName_Impl +> +LowerToExactNameMap; + + +class IntrospectionAccessStatic_Impl +{ + friend class ImplIntrospection; + friend class ImplIntrospectionAccess; + + // CoreReflection halten + Reference< XIdlReflection > mxCoreReflection; + + // InterfaceSequences, um Zusatz-Infos zu einer Property speichern zu koennen. + // z.B. das Field bei MAP_FIELD, die get/set-Methoden bei MAP_GETSET usw. + Sequence< Reference<XInterface> > aInterfaceSeq1; + Sequence< Reference<XInterface> > aInterfaceSeq2; + + // Hashtables fuer die Namen + IntrospectionNameMap maPropertyNameMap; + IntrospectionNameMap maMethodNameMap; + LowerToExactNameMap maLowerToExactNameMap; + + // Sequence aller Properties, auch zum Liefern aus getProperties() + Sequence<Property> maAllPropertySeq; + + // Mapping der Properties auf Zugriffs-Arten + Sequence<sal_Int16> maMapTypeSeq; + + // Klassifizierung der gefundenen Methoden + Sequence<sal_Int32> maPropertyConceptSeq; + + // Anzahl der Properties + sal_Int32 mnPropCount; + + // Anzahl der Properties, die den jeweiligen Konzepten zugeordnet sind + //sal_Int32 mnDangerousPropCount; + sal_Int32 mnPropertySetPropCount; + sal_Int32 mnAttributePropCount; + sal_Int32 mnMethodPropCount; + + // Flag, ob ein FastPropertySet unterstuetzt wird + sal_Bool mbFastPropSet; + + // Original-Handles eines FastPropertySets + sal_Int32* mpOrgPropertyHandleArray; + + // MethodSequence, die alle Methoden aufnimmt + Sequence< Reference<XIdlMethod> > maAllMethodSeq; + + // Klassifizierung der gefundenen Methoden + Sequence<sal_Int32> maMethodConceptSeq; + + // Anzahl der Methoden + sal_Int32 mnMethCount; + + // Sequence der Listener, die angemeldet werden koennen + Sequence< Type > maSupportedListenerSeq; + + // BaseInit (soll spaeter in der Applikation erfolgen!) + void BaseInit( void ); + + // Hilfs-Methoden zur Groessen-Anpassung der Sequences + void checkPropertyArraysSize + ( + Property*& rpAllPropArray, + sal_Int16*& rpMapTypeArray, + sal_Int32*& rpPropertyConceptArray, + sal_Int32 iNextIndex + ); + void checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, Reference<XInterface>*& rpInterfaceArray, + sal_Int32 iNextIndex ); + + // RefCount + sal_Int32 nRefCount; + + +public: + IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ ); + ~IntrospectionAccessStatic_Impl() + { + delete mpOrgPropertyHandleArray; + } + sal_Int32 getPropertyIndex( const OUString& aPropertyName ) const; + sal_Int32 getMethodIndex( const OUString& aMethodName ) const; + + void acquire() { nRefCount++; } + void release() + { + nRefCount--; + if( nRefCount <= 0 ) + delete this; + } + + // Methoden von XIntrospectionAccess (ALT, jetzt nur Impl) + void setPropertyValue(const Any& obj, const OUString& aPropertyName, const Any& aValue) const; + Any getPropertyValue(const Any& obj, const OUString& aPropertyName) const; + void setPropertyValueByIndex(const Any& obj, sal_Int32 nIndex, const Any& aValue) const; + Any getPropertyValueByIndex(const Any& obj, sal_Int32 nIndex) const; + + Sequence<Property> getProperties(void) const { return maAllPropertySeq; } + Sequence< Reference<XIdlMethod> > getMethods(void) const { return maAllMethodSeq; } + Sequence< Type > getSupportedListeners(void) const { return maSupportedListenerSeq; } + Sequence<sal_Int32> getPropertyConcepts(void) const { return maPropertyConceptSeq; } + Sequence<sal_Int32> getMethodConcepts(void) const { return maMethodConceptSeq; } +}; + + +// Ctor +IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ ) + : mxCoreReflection( xCoreReflection_ ) +{ + aInterfaceSeq1.realloc( ARRAY_SIZE_STEP ); + aInterfaceSeq2.realloc( ARRAY_SIZE_STEP ); + + // Property-Daten + maAllPropertySeq.realloc( ARRAY_SIZE_STEP ); + maMapTypeSeq.realloc( ARRAY_SIZE_STEP ); + maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP ); + + mbFastPropSet = sal_False; + mpOrgPropertyHandleArray = NULL; + + mnPropCount = 0L; + //mnDangerousPropCount = 0L; + mnPropertySetPropCount = 0L; + mnAttributePropCount = 0L; + mnMethodPropCount = 0L; + + // Method-Daten + mnMethCount = 0L; + + // Eigenens RefCounting + nRefCount = 0L; +} + +// Von Hand refcounten !!! + + +sal_Int32 IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString& aPropertyName ) const +{ + sal_Int32 iHashResult = -1; + IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this; + IntrospectionNameMap::iterator aIt = pThis->maPropertyNameMap.find( aPropertyName ); + if( !( aIt == pThis->maPropertyNameMap.end() ) ) + iHashResult = (*aIt).second; + return iHashResult; +} + +sal_Int32 IntrospectionAccessStatic_Impl::getMethodIndex( const OUString& aMethodName ) const +{ + sal_Int32 iHashResult = -1; + IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this; + IntrospectionNameMap::iterator aIt = pThis->maMethodNameMap.find( aMethodName ); + if( !( aIt == pThis->maMethodNameMap.end() ) ) + iHashResult = (*aIt).second; + return iHashResult; +} + +void IntrospectionAccessStatic_Impl::setPropertyValue( const Any& obj, const OUString& aPropertyName, const Any& aValue ) const +{ + sal_Int32 i = getPropertyIndex( aPropertyName ); + if( i != -1 ) + setPropertyValueByIndex( obj, (sal_Int32)i, aValue ); + else + throw UnknownPropertyException(); +} + +void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const +{ + // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes? + TypeClass eObjType = obj.getValueType().getTypeClass(); + + Reference<XInterface> xInterface; + if( eObjType == TypeClass_INTERFACE ) + { + xInterface = *( Reference<XInterface>*)obj.getValue(); + } + else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) ) + { + throw IllegalArgumentException(); + return; + } + + // Flags pruefen + const Property* pProps = maAllPropertySeq.getConstArray(); + if( (pProps[ nSequenceIndex ].Attributes & READONLY) != 0 ) + { + throw UnknownPropertyException(); + return; + } + + const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray(); + switch( pMapTypeArray[ nSequenceIndex ] ) + { + case MAP_PROPERTY_SET: + { + // Property besorgen + const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ]; + + // Interface-Parameter auf den richtigen Typ bringen + sal_Bool bUseCopy = sal_False; + Any aRealValue; + + TypeClass eValType = aValue.getValueType().getTypeClass(); + if( eValType == TypeClass_INTERFACE ) + { + Type aPropType = rProp.Type; + OUString aTypeName( aPropType.getTypeName() ); + Reference< XIdlClass > xPropClass = mxCoreReflection->forName( aTypeName ); + //Reference<XIdlClass> xPropClass = rProp.Type; + if( xPropClass.is() && xPropClass->getTypeClass() == TypeClass_INTERFACE ) + { + Reference<XInterface> valInterface = *(Reference<XInterface>*)aValue.getValue(); + if( valInterface.is() ) + { + //Any queryInterface( const Type& rType ); + aRealValue = valInterface->queryInterface( aPropType ); + if( aRealValue.hasValue() ) + bUseCopy = sal_True; + } + } + } + + // Haben wir ein FastPropertySet und ein gueltiges Handle? + // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet + // zu Beginn des Introspection-Vorgangs abgefragt wird. + sal_Int32 nOrgHandle; + if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 ) + { + // PropertySet-Interface holen + Reference<XFastPropertySet> xFastPropSet = + Reference<XFastPropertySet>::query( xInterface ); + if( xFastPropSet.is() ) + { + xFastPropSet->setFastPropertyValue( nOrgHandle, bUseCopy ? aRealValue : aValue ); + } + else + { + // throw UnknownPropertyException + } + } + // sonst eben das normale nehmen + else + { + // PropertySet-Interface holen + Reference<XPropertySet> xPropSet = + Reference<XPropertySet>::query( xInterface ); + if( xPropSet.is() ) + { + xPropSet->setPropertyValue( rProp.Name, bUseCopy ? aRealValue : aValue ); + } + else + { + // throw UnknownPropertyException + } + } + } + break; + + case MAP_FIELD: + { + Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get()); + if( xField.is() ) + { + xField->set( obj, aValue ); + // IllegalArgumentException + // NullPointerException + } + else + { + // throw IllegalArgumentException(); + } + } + break; + + case MAP_GETSET: + case MAP_SETONLY: + { + // set-Methode holen + Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq2.getConstArray()[ nSequenceIndex ].get()); + if( xMethod.is() ) + { + Sequence<Any> args( 1 ); + args.getArray()[0] = aValue; + xMethod->invoke( obj, args ); + } + else + { + // throw IllegalArgumentException(); + } + } + break; + } +} + +Any IntrospectionAccessStatic_Impl::getPropertyValue( const Any& obj, const OUString& aPropertyName ) const +{ + sal_Int32 i = getPropertyIndex( aPropertyName ); + if( i != -1 ) + return getPropertyValueByIndex( obj, i ); + + throw UnknownPropertyException(); + return Any(); +} + +Any IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex) const +{ + Any aRet; + + // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes? + TypeClass eObjType = obj.getValueType().getTypeClass(); + + Reference<XInterface> xInterface; + if( eObjType == TypeClass_INTERFACE ) + { + xInterface = *(Reference<XInterface>*)obj.getValue(); + } + else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) ) + { + // throw IllegalArgumentException(); + return aRet; + } + + const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray(); + switch( pMapTypeArray[ nSequenceIndex ] ) + { + case MAP_PROPERTY_SET: + { + // Property besorgen + const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ]; + + // Haben wir ein FastPropertySet und ein gueltiges Handle? + // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet + // zu Beginn des Introspection-Vorgangs abgefragt wird. + sal_Int32 nOrgHandle; + if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 ) + { + // PropertySet-Interface holen + Reference<XFastPropertySet> xFastPropSet = + Reference<XFastPropertySet>::query( xInterface ); + if( xFastPropSet.is() ) + { + aRet = xFastPropSet->getFastPropertyValue( nOrgHandle); + } + else + { + // throw UnknownPropertyException + return aRet; + } + } + // sonst eben das normale nehmen + else + { + // PropertySet-Interface holen + Reference<XPropertySet> xPropSet = + Reference<XPropertySet>::query( xInterface ); + if( xPropSet.is() ) + { + aRet = xPropSet->getPropertyValue( rProp.Name ); + } + else + { + // throw UnknownPropertyException + return aRet; + } + } + } + break; + + case MAP_FIELD: + { + Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get()); + if( xField.is() ) + { + aRet = xField->get( obj ); + // IllegalArgumentException + // NullPointerException + } + else + { + // throw IllegalArgumentException(); + return aRet; + } + } + break; + + case MAP_GETSET: + { + // get-Methode holen + Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get()); + if( xMethod.is() ) + { + Sequence<Any> args; + aRet = xMethod->invoke( obj, args ); + } + else + { + // throw IllegalArgumentException(); + return aRet; + } + } + break; + + case MAP_SETONLY: + { + // get-Methode gibt es nicht + // throw WriteOnlyPropertyException(); + return aRet; + } + break; + } + return aRet; +} + + +// Hilfs-Methoden zur Groessen-Anpassung der Sequences +void IntrospectionAccessStatic_Impl::checkPropertyArraysSize +( + Property*& rpAllPropArray, + sal_Int16*& rpMapTypeArray, + sal_Int32*& rpPropertyConceptArray, + sal_Int32 iNextIndex +) +{ + sal_Int32 nLen = maAllPropertySeq.getLength(); + if( iNextIndex >= nLen ) + { + maAllPropertySeq.realloc( nLen + ARRAY_SIZE_STEP ); + rpAllPropArray = maAllPropertySeq.getArray(); + + maMapTypeSeq.realloc( nLen + ARRAY_SIZE_STEP ); + rpMapTypeArray = maMapTypeSeq.getArray(); + + maPropertyConceptSeq.realloc( nLen + ARRAY_SIZE_STEP ); + rpPropertyConceptArray = maPropertyConceptSeq.getArray(); + } +} + +void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, + Reference<XInterface>*& rpInterfaceArray, sal_Int32 iNextIndex ) +{ + sal_Int32 nLen = rSeq.getLength(); + if( iNextIndex >= nLen ) + { + // Neue Groesse mit ARRAY_SIZE_STEP abgleichen + sal_Int32 nMissingSize = iNextIndex - nLen + 1; + sal_Int32 nSteps = nMissingSize / ARRAY_SIZE_STEP + 1; + sal_Int32 nNewSize = nLen + nSteps * ARRAY_SIZE_STEP; + + rSeq.realloc( nNewSize ); + rpInterfaceArray = rSeq.getArray(); + } +} + + +//******************************* +//*** ImplIntrospectionAdapter *** +//******************************* + +// Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene +// Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse +// ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl +class ImplIntrospectionAdapter : + public XPropertySet, public XFastPropertySet, public XPropertySetInfo, + public XNameContainer, public XIndexContainer, + public XEnumerationAccess, public XIdlArray, + public OWeakObject +{ + // Parent-Objekt + ImplIntrospectionAccess* mpAccess; + + // Untersuchtes Objekt + const Any& mrInspectedObject; + + // Statische Daten der Introspection + IntrospectionAccessStatic_Impl* mpStaticImpl; + + // Objekt als Interface + Reference<XInterface> mxIface; + + // Original-Interfaces des Objekts + Reference<XElementAccess> mxObjElementAccess; + Reference<XNameContainer> mxObjNameContainer; + Reference<XNameAccess> mxObjNameAccess; + Reference<XIndexAccess> mxObjIndexAccess; + Reference<XIndexContainer> mxObjIndexContainer; + Reference<XEnumerationAccess> mxObjEnumerationAccess; + Reference<XIdlArray> mxObjIdlArray; + +public: + ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_, + const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ ); + ~ImplIntrospectionAdapter(); + + // Methoden von XInterface + virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException ); + virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); } + virtual void SAL_CALL release() throw() { OWeakObject::release(); } + + // Methoden von XPropertySet + virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( RuntimeException ); + virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, const Any& aValue) + throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ); + virtual Any SAL_CALL getPropertyValue(const OUString& aPropertyName) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); + virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); + virtual void SAL_CALL removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); + virtual void SAL_CALL addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); + virtual void SAL_CALL removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); + + // Methoden von XFastPropertySet + virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const Any& aValue) + throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ); + virtual Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); + + // Methoden von XPropertySetInfo + virtual Sequence< Property > SAL_CALL getProperties(void) throw( RuntimeException ); + virtual Property SAL_CALL getPropertyByName(const OUString& Name) throw( RuntimeException ); + virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& Name) throw( RuntimeException ); + + // Methoden von XElementAccess + virtual Type SAL_CALL getElementType(void) throw( RuntimeException ); + virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException ); + + // Methoden von XNameAccess + virtual Any SAL_CALL getByName(const OUString& Name) + throw( NoSuchElementException, WrappedTargetException, RuntimeException ); + virtual Sequence<OUString> SAL_CALL getElementNames(void) throw( RuntimeException ); + virtual sal_Bool SAL_CALL hasByName(const OUString& Name) throw( RuntimeException ); + + // Methoden von XNameContainer + virtual void SAL_CALL insertByName(const OUString& Name, const Any& Element) + throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException ); + virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element) + throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException ); + virtual void SAL_CALL removeByName(const OUString& Name) + throw( NoSuchElementException, WrappedTargetException, RuntimeException ); + + // Methoden von XIndexAccess + virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException ); + virtual Any SAL_CALL getByIndex(sal_Int32 Index) + throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); + + // Methoden von XIndexContainer + virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element) + throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); + virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element) + throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); + virtual void SAL_CALL removeByIndex(sal_Int32 Index) + throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); + + // Methoden von XEnumerationAccess + virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException ); + + // Methoden von XIdlArray + virtual void SAL_CALL realloc(Any& array, sal_Int32 length) + throw( IllegalArgumentException, RuntimeException ); + virtual sal_Int32 SAL_CALL getLen(const Any& array) throw( IllegalArgumentException, RuntimeException ); + virtual Any SAL_CALL get(const Any& array, sal_Int32 index) + throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException ); + virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value) + throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException ); +}; + +ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_, + const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ ) + : mpAccess( pAccess_), mrInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ) +{ + mpStaticImpl->acquire(); + + // Objekt als Interfaceholen + TypeClass eType = mrInspectedObject.getValueType().getTypeClass(); + if( eType == TypeClass_INTERFACE ) + { + mxIface = *( Reference< XInterface >*)mrInspectedObject.getValue(); + + mxObjElementAccess = Reference<XElementAccess>::query( mxIface ); + mxObjNameAccess = Reference<XNameAccess>::query( mxIface ); + mxObjNameContainer = Reference<XNameContainer>::query( mxIface ); + mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface ); + mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface ); + mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface ); + mxObjIdlArray = Reference<XIdlArray>::query( mxIface ); + } +} + +ImplIntrospectionAdapter::~ImplIntrospectionAdapter() +{ + mpStaticImpl->release(); +} + +// Methoden von XInterface +Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType ) + throw( RuntimeException ) +{ + Any aRet( ::cppu::queryInterface( + rType, + static_cast< XPropertySet * >( this ), + static_cast< XFastPropertySet * >( this ), + static_cast< XPropertySetInfo * >( this ) ) ); + if( !aRet.hasValue() ) + aRet = OWeakObject::queryInterface( rType ); + + if( !aRet.hasValue() ) + { + // Wrapper fuer die Objekt-Interfaces + if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface + ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() ) + || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() ) + || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() ) + || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() ) + || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() ) + || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() ) + || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() ) + ) + { + } + } + return aRet; +} + + +//******************************* +//*** ImplIntrospectionAccess *** +//******************************* + +// Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene +// Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse +// ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl +class ImplIntrospectionAccess : IntrospectionAccessHelper +{ + friend class ImplIntrospection; + + // Untersuchtes Objekt + Any maInspectedObject; + + // Als Interface + Reference<XInterface> mxIface; + + // Statische Daten der Introspection + IntrospectionAccessStatic_Impl* mpStaticImpl; + + // Adapter-Implementation + ImplIntrospectionAdapter* mpAdapter; + + // Letzte Sequence, die bei getProperties geliefert wurde (Optimierung) + Sequence<Property> maLastPropertySeq; + sal_Int32 mnLastPropertyConcept; + + // Letzte Sequence, die bei getMethods geliefert wurde (Optimierung) + Sequence<Reference<XIdlMethod> > maLastMethodSeq; + sal_Int32 mnLastMethodConcept; + +public: + ImplIntrospectionAccess( const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ ); + ~ImplIntrospectionAccess(); + + // Methoden von XIntrospectionAccess + virtual sal_Int32 SAL_CALL getSuppliedMethodConcepts(void) + throw( RuntimeException ); + virtual sal_Int32 SAL_CALL getSuppliedPropertyConcepts(void) + throw( RuntimeException ); + virtual Property SAL_CALL getProperty(const OUString& Name, sal_Int32 PropertyConcepts) + throw( NoSuchElementException, RuntimeException ); + virtual sal_Bool SAL_CALL hasProperty(const OUString& Name, sal_Int32 PropertyConcepts) + throw( RuntimeException ); + virtual Sequence< Property > SAL_CALL getProperties(sal_Int32 PropertyConcepts) + throw( RuntimeException ); + virtual Reference<XIdlMethod> SAL_CALL getMethod(const OUString& Name, sal_Int32 MethodConcepts) + throw( NoSuchMethodException, RuntimeException ); + virtual sal_Bool SAL_CALL hasMethod(const OUString& Name, sal_Int32 MethodConcepts) + throw( RuntimeException ); + virtual Sequence< Reference<XIdlMethod> > SAL_CALL getMethods(sal_Int32 MethodConcepts) + throw( RuntimeException ); + virtual Sequence< Type > SAL_CALL getSupportedListeners(void) + throw( RuntimeException ); + virtual Reference<XInterface> SAL_CALL queryAdapter( const Type& rType ) + throw( IllegalTypeException, RuntimeException ); + + // Methoden von XMaterialHolder + virtual Any SAL_CALL getMaterial(void); + + // Methoden von XExactName + virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException ); +}; + +ImplIntrospectionAccess::ImplIntrospectionAccess + ( const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ ) + : maInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ), mpAdapter( NULL ) +{ + mpStaticImpl->acquire(); + + // Objekt als Interface merken, wenn moeglich + TypeClass eType = maInspectedObject.getValueType().getTypeClass(); + if( eType == TypeClass_INTERFACE ) + mxIface = *(Reference<XInterface>*)maInspectedObject.getValue(); + + mnLastPropertyConcept = -1; + mnLastMethodConcept = -1; +} + +ImplIntrospectionAccess::~ImplIntrospectionAccess() +{ + mpStaticImpl->release(); + + // Eigene Referenz loslassen + if (mpAdapter) + mpAdapter->release(); +} + + +//*************************************************** +//*** Implementation von ImplIntrospectionAdapter *** +//*************************************************** + +// Methoden von XPropertySet +Reference<XPropertySetInfo> ImplIntrospectionAdapter::getPropertySetInfo(void) + throw( RuntimeException ) +{ + return (XPropertySetInfo *)this; +} + +void ImplIntrospectionAdapter::setPropertyValue(const OUString& aPropertyName, const Any& aValue) + throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ) +{ + mpStaticImpl->setPropertyValue( mrInspectedObject, aPropertyName, aValue ); +} + +Any ImplIntrospectionAdapter::getPropertyValue(const OUString& aPropertyName) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) +{ + return mpStaticImpl->getPropertyValue( mrInspectedObject, aPropertyName ); +} + +void ImplIntrospectionAdapter::addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) +{ + if( mxIface.is() ) + { + Reference<XPropertySet> xPropSet = + Reference<XPropertySet>::query( mxIface ); + //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY ); + if( xPropSet.is() ) + xPropSet->addPropertyChangeListener(aPropertyName, aListener); + } +} + +void ImplIntrospectionAdapter::removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) +{ + if( mxIface.is() ) + { + Reference<XPropertySet> xPropSet = + Reference<XPropertySet>::query( mxIface ); + //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY ); + if( xPropSet.is() ) + xPropSet->removePropertyChangeListener(aPropertyName, aListener); + } +} + +void ImplIntrospectionAdapter::addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) +{ + if( mxIface.is() ) + { + Reference<XPropertySet> xPropSet = + Reference<XPropertySet>::query( mxIface ); + //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY ); + if( xPropSet.is() ) + xPropSet->addVetoableChangeListener(aPropertyName, aListener); + } +} + +void ImplIntrospectionAdapter::removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) +{ + if( mxIface.is() ) + { + Reference<XPropertySet> xPropSet = + Reference<XPropertySet>::query( mxIface ); + if( xPropSet.is() ) + xPropSet->removeVetoableChangeListener(aPropertyName, aListener); + } +} + + +// Methoden von XFastPropertySet +void ImplIntrospectionAdapter::setFastPropertyValue(sal_Int32 nHandle, const Any& aValue) + throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ) +{ +} + +Any ImplIntrospectionAdapter::getFastPropertyValue(sal_Int32 nHandle) + throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) +{ + return Any(); +} + +// Methoden von XPropertySetInfo +Sequence< Property > ImplIntrospectionAdapter::getProperties(void) throw( RuntimeException ) +{ + return mpStaticImpl->getProperties(); +} + +Property ImplIntrospectionAdapter::getPropertyByName(const OUString& Name) + throw( RuntimeException ) +{ + return mpAccess->getProperty( Name, PropertyConcept::ALL ); +} + +sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name) + throw( RuntimeException ) +{ + return mpAccess->hasProperty( Name, PropertyConcept::ALL ); +} + +// Methoden von XElementAccess +Type ImplIntrospectionAdapter::getElementType(void) throw( RuntimeException ) +{ + return mxObjElementAccess->getElementType(); +} + +sal_Bool ImplIntrospectionAdapter::hasElements(void) throw( RuntimeException ) +{ + return mxObjElementAccess->hasElements(); +} + +// Methoden von XNameAccess +Any ImplIntrospectionAdapter::getByName(const OUString& Name) + throw( NoSuchElementException, WrappedTargetException, RuntimeException ) +{ + return mxObjNameAccess->getByName( Name ); +} + +Sequence< OUString > ImplIntrospectionAdapter::getElementNames(void) + throw( RuntimeException ) +{ + return mxObjNameAccess->getElementNames(); +} + +sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name) + throw( RuntimeException ) +{ + return mxObjNameAccess->hasByName( Name ); +} + +// Methoden von XNameContainer +void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element) + throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException ) +{ + mxObjNameContainer->insertByName( Name, Element ); +} + +void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element) + throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException ) +{ + mxObjNameContainer->replaceByName( Name, Element ); +} + +void ImplIntrospectionAdapter::removeByName(const OUString& Name) + throw( NoSuchElementException, WrappedTargetException, RuntimeException ) +{ + mxObjNameContainer->removeByName( Name ); +} + +// Methoden von XIndexAccess +// Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const +sal_Int32 ImplIntrospectionAdapter::getCount(void) throw( RuntimeException ) +{ + return mxObjIndexAccess->getCount(); +} + +Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index) + throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + return mxObjIndexAccess->getByIndex( Index ); +} + +// Methoden von XIndexContainer +void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element) + throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + mxObjIndexContainer->insertByIndex( Index, Element ); +} + +void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element) + throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + mxObjIndexContainer->replaceByIndex( Index, Element ); +} + +void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index) + throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + mxObjIndexContainer->removeByIndex( Index ); +} + +// Methoden von XEnumerationAccess +// Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const; +Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration(void) throw( RuntimeException ) +{ + return mxObjEnumerationAccess->createEnumeration(); +} + +// Methoden von XIdlArray +void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length) + throw( IllegalArgumentException, RuntimeException ) +{ + mxObjIdlArray->realloc( array, length ); +} + +sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array) + throw( IllegalArgumentException, RuntimeException ) +{ + return mxObjIdlArray->getLen( array ); +} + +Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index) + throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException ) +{ + return mxObjIdlArray->get( array, index ); +} + +void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value) + throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException ) +{ + mxObjIdlArray->set( array, index, value ); +} + + +//************************************************** +//*** Implementation von ImplIntrospectionAccess *** +//************************************************** + +// Methoden von XIntrospectionAccess +sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts(void) + throw( RuntimeException ) +{ + return MethodConcept::DANGEROUS | + PROPERTY | + LISTENER | + ENUMERATION | + NAMECONTAINER | + INDEXCONTAINER; +} + +sal_Int32 ImplIntrospectionAccess::getSuppliedPropertyConcepts(void) + throw( RuntimeException ) +{ + return PropertyConcept::DANGEROUS | + PROPERTYSET | + ATTRIBUTES | + METHODS; +} + +Property ImplIntrospectionAccess::getProperty(const OUString& Name, sal_Int32 PropertyConcepts) + throw( NoSuchElementException, RuntimeException ) +{ + Property aRet; + sal_Int32 i = mpStaticImpl->getPropertyIndex( Name ); + sal_Bool bFound = sal_False; + if( i != -1 ) + { + sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ]; + if( (PropertyConcepts & nConcept) != 0 ) + { + const Property* pProps = mpStaticImpl->getProperties().getConstArray(); + aRet = pProps[ i ]; + bFound = sal_True; + } + } + if( !bFound ) + throw NoSuchElementException() ; + return aRet; +} + +sal_Bool ImplIntrospectionAccess::hasProperty(const OUString& Name, sal_Int32 PropertyConcepts) + throw( RuntimeException ) +{ + sal_Int32 i = mpStaticImpl->getPropertyIndex( Name ); + sal_Bool bRet = sal_False; + if( i != -1 ) + { + sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ]; + if( (PropertyConcepts & nConcept) != 0 ) + bRet = sal_True; + } + return bRet; +} + +Sequence< Property > ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts) + throw( RuntimeException ) +{ + // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen + sal_Int32 nAllSupportedMask = PROPERTYSET | + ATTRIBUTES | + METHODS; + if( ( PropertyConcepts & nAllSupportedMask ) == nAllSupportedMask ) + { + return mpStaticImpl->getProperties(); + } + + // Gleiche Sequence wie beim vorigen mal? + if( mnLastPropertyConcept == PropertyConcepts ) + { + return maLastPropertySeq; + } + + // Anzahl der zu liefernden Properties + sal_Int32 nCount = 0; + + // Es gibt zur Zeit keine DANGEROUS-Properties + // if( PropertyConcepts & DANGEROUS ) + // nCount += mpStaticImpl->mnDangerousPropCount; + if( PropertyConcepts & PROPERTYSET ) + nCount += mpStaticImpl->mnPropertySetPropCount; + if( PropertyConcepts & ATTRIBUTES ) + nCount += mpStaticImpl->mnAttributePropCount; + if( PropertyConcepts & METHODS ) + nCount += mpStaticImpl->mnMethodPropCount; + + // Sequence entsprechend der geforderten Anzahl reallocieren + ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen + pThis->maLastPropertySeq.realloc( nCount ); + Property* pDestProps = pThis->maLastPropertySeq.getArray(); + + // Alle Properties durchgehen und entsprechend der Concepte uebernehmen + Sequence<Property> aPropSeq = mpStaticImpl->getProperties(); + const Property* pSourceProps = aPropSeq.getConstArray(); + const sal_Int32* pConcepts = mpStaticImpl->getPropertyConcepts().getConstArray(); + sal_Int32 nLen = aPropSeq.getLength(); + + sal_Int32 iDest = 0; + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + sal_Int32 nConcept = pConcepts[ i ]; + if( nConcept & PropertyConcepts ) + pDestProps[ iDest++ ] = pSourceProps[ i ]; + + /* + // Property mit Concepts ausgeben + OUString aPropName = pSourceProps[ i ].Name; + String aNameStr = OOUStringToString(aPropName, CHARSET_SYSTEM); + String ConceptStr; + if( nConcept & PROPERTYSET ) + ConceptStr += "PROPERTYSET"; + if( nConcept & ATTRIBUTES ) + ConceptStr += "ATTRIBUTES"; + if( nConcept & METHODS ) + ConceptStr += "METHODS"; + printf( "Property %ld: %s, Concept = %s\n", i, aNameStr.GetStr(), ConceptStr.GetStr() ); + */ + } + + // PropertyConcept merken, dies entspricht maLastPropertySeq + pThis->mnLastPropertyConcept = PropertyConcepts; + + // Zusammengebastelte Sequence liefern + return maLastPropertySeq; +} + +Reference<XIdlMethod> ImplIntrospectionAccess::getMethod(const OUString& Name, sal_Int32 MethodConcepts) + throw( NoSuchMethodException, RuntimeException ) +{ + Reference<XIdlMethod> xRet; + sal_Int32 i = mpStaticImpl->getMethodIndex( Name ); + if( i != -1 ) + { + + sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ]; + if( (MethodConcepts & nConcept) != 0 ) + { + const Reference<XIdlMethod>* pMethods = mpStaticImpl->getMethods().getConstArray(); + xRet = pMethods[i]; + } + } + if( !xRet.is() ) + throw NoSuchMethodException(); + return xRet; +} + +sal_Bool ImplIntrospectionAccess::hasMethod(const OUString& Name, sal_Int32 MethodConcepts) + throw( RuntimeException ) +{ + sal_Int32 i = mpStaticImpl->getMethodIndex( Name ); + sal_Bool bRet = sal_False; + if( i != -1 ) + { + sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ]; + if( (MethodConcepts & nConcept) != 0 ) + bRet = sal_True; + } + return bRet; +} + +Sequence< Reference<XIdlMethod> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts) + throw( RuntimeException ) +{ + ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen + + // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen + sal_Int32 nAllSupportedMask = MethodConcept::DANGEROUS | + PROPERTY | + LISTENER | + ENUMERATION | + NAMECONTAINER | + INDEXCONTAINER | + MethodConcept_NORMAL_IMPL; + if( ( MethodConcepts & nAllSupportedMask ) == nAllSupportedMask ) + { + return mpStaticImpl->getMethods(); + } + + // Gleiche Sequence wie beim vorigen mal? + if( mnLastMethodConcept == MethodConcepts ) + { + return maLastMethodSeq; + } + + // Methoden-Sequences besorgen + Sequence< Reference<XIdlMethod> > aMethodSeq = mpStaticImpl->getMethods(); + const Reference<XIdlMethod>* pSourceMethods = aMethodSeq.getConstArray(); + const sal_Int32* pConcepts = mpStaticImpl->getMethodConcepts().getConstArray(); + sal_Int32 nLen = aMethodSeq.getLength(); + + // Sequence entsprechend der geforderten Anzahl reallocieren + // Anders als bei den Properties kann die Anzahl nicht durch + // Zaehler in inspect() vorher ermittelt werden, da Methoden + // mehreren Konzepten angehoeren koennen + pThis->maLastMethodSeq.realloc( nLen ); + Reference<XIdlMethod>* pDestMethods = pThis->maLastMethodSeq.getArray(); + + // Alle Methods durchgehen und entsprechend der Concepte uebernehmen + sal_Int32 iDest = 0; + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + sal_Int32 nConcept = pConcepts[ i ]; + if( nConcept & MethodConcepts ) + pDestMethods[ iDest++ ] = pSourceMethods[ i ]; + + /* + // Methode mit Concepts ausgeben + const XIdlMethodRef& rxMethod = pSourceMethods[ i ]; + OUString aMethName = rxMethod->getName(); + String aNameStr = OOUStringToString(aMethName, CHARSET_SYSTEM); + String ConceptStr; + if( nConcept & DANGEROUS ) + ConceptStr += "DANGEROUS |"; + if( nConcept & PROPERTY ) + ConceptStr += "PROPERTY |"; + if( nConcept & LISTENER ) + ConceptStr += "LISTENER |"; + if( nConcept & ENUMERATION ) + ConceptStr += "ENUMERATION |"; + if( nConcept & NAMECONTAINER ) + ConceptStr += "NAMECONTAINER |"; + if( nConcept & INDEXCONTAINER ) + ConceptStr += "INDEXCONTAINER |"; + if( nConcept & NORMAL_IMPL ) + ConceptStr += "NORMAL_IMPL |"; + printf( "Method %ld: %s, Concepts = %s\n", i, aNameStr.GetStr(), ConceptStr.GetStr() ); + */ + } + + // Auf die richtige Laenge bringen + pThis->maLastMethodSeq.realloc( iDest ); + + // MethodConcept merken, dies entspricht maLastMethodSeq + pThis->mnLastMethodConcept = MethodConcepts; + + // Zusammengebastelte Sequence liefern + return maLastMethodSeq; +} + +Sequence< Type > ImplIntrospectionAccess::getSupportedListeners(void) + throw( RuntimeException ) +{ + return mpStaticImpl->getSupportedListeners(); +} + +Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type& rType ) + throw( IllegalTypeException, RuntimeException ) +{ + // Gibt es schon einen Adapter? + if( !mpAdapter ) + { + ((ImplIntrospectionAccess*)this)->mpAdapter = + new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl ); + + // Selbst eine Referenz halten + mpAdapter->acquire(); + } + + Reference<XInterface> xRet; + Any aIfaceAny( mpAdapter->queryInterface( rType ) ); + if( aIfaceAny.hasValue() ) + xRet = *(Reference<XInterface>*)aIfaceAny.getValue(); + + return xRet; +} + +// Methoden von XMaterialHolder +Any ImplIntrospectionAccess::getMaterial(void) +{ + return maInspectedObject; +} + +// Hilfs-Funktion zur LowerCase-Wandlung eines OUString +OUString toLower( OUString aUStr ) +{ + // Tabelle fuer XExactName pflegen + NAMESPACE_RTL(OUString) aOWStr( aUStr.getStr() ); + NAMESPACE_RTL(OUString) aOWLowerStr = aOWStr.toLowerCase(); + OUString aLowerUStr( aOWLowerStr.getStr() ); + return aLowerUStr; +} + +// Methoden von XExactName +OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName ) throw( RuntimeException ) +{ + OUString aRetStr; + LowerToExactNameMap::iterator aIt = + mpStaticImpl->maLowerToExactNameMap.find( toLower( rApproximateName ) ); + if( !( aIt == mpStaticImpl->maLowerToExactNameMap.end() ) ) + aRetStr = (*aIt).second; + return aRetStr; +} + + +//----------------------------------------------------------------------------- + +#ifdef USE_INTROSPECTION_CACHE + +struct hashIntrospectionKey_Impl +{ + Sequence< Reference<XIdlClass> > aIdlClasses; + Reference<XPropertySetInfo> xPropInfo; + Reference<XIdlClass> xImplClass; + sal_Int32 nHitCount; + + void IncHitCount() const { ((hashIntrospectionKey_Impl*)this)->nHitCount++; } + hashIntrospectionKey_Impl() : nHitCount( 0 ) {} + hashIntrospectionKey_Impl( const Sequence< Reference<XIdlClass> > & rIdlClasses, + const Reference<XPropertySetInfo> & rxPropInfo, + const Reference<XIdlClass> & rxImplClass ); +}; + +hashIntrospectionKey_Impl::hashIntrospectionKey_Impl +( + const Sequence< Reference<XIdlClass> > & rIdlClasses, + const Reference<XPropertySetInfo> & rxPropInfo, + const Reference<XIdlClass> & rxImplClass +) + : aIdlClasses( rIdlClasses ) + , xPropInfo( rxPropInfo ) + , xImplClass( rxImplClass ) + , nHitCount( 0 ) +{} + + +struct hashIntrospectionAccessCache_Impl +{ + size_t operator()(const hashIntrospectionKey_Impl & rObj ) const + { + return (size_t)rObj.xImplClass.get() ^ (size_t)rObj.xPropInfo.get(); + } + + bool operator()( const hashIntrospectionKey_Impl & rObj1, + const hashIntrospectionKey_Impl & rObj2 ) const + { + if( rObj1.xPropInfo != rObj2.xPropInfo + || rObj1.xImplClass != rObj2.xImplClass ) + return sal_False; + + sal_Int32 nCount1 = rObj1.aIdlClasses.getLength(); + sal_Int32 nCount2 = rObj2.aIdlClasses.getLength(); + if( nCount1 != nCount2 ) + return sal_False; + + const Reference<XIdlClass>* pRefs1 = rObj1.aIdlClasses.getConstArray(); + const Reference<XIdlClass>* pRefs2 = rObj2.aIdlClasses.getConstArray(); + return memcmp( pRefs1, pRefs2, nCount1 * sizeof( Reference<XIdlClass> ) ) == 0; + } + +}; + +typedef NAMESPACE_STD(hash_map) +< + hashIntrospectionKey_Impl, + IntrospectionAccessStatic_Impl*, + hashIntrospectionAccessCache_Impl, + hashIntrospectionAccessCache_Impl +> +IntrospectionAccessCacheMap_Impl; + +class IntrospectionAccessCacheMap : public IntrospectionAccessCacheMap_Impl +{ +public: + ~IntrospectionAccessCacheMap() + { + IntrospectionAccessCacheMap::iterator iter = begin(); + IntrospectionAccessCacheMap::iterator end = this->end(); + while( iter != end ) + { + + (*iter).second->release(); + (*iter).second = NULL; + iter++; + } + } +}; + + +// For XTypeProvider +struct hashTypeProviderKey_Impl +{ + Reference<XPropertySetInfo> xPropInfo; + Sequence< sal_Int8 > maImpIdSeq; + sal_Int32 nHitCount; + + void IncHitCount() const { ((hashTypeProviderKey_Impl*)this)->nHitCount++; } + hashTypeProviderKey_Impl() : nHitCount( 0 ) {} + hashTypeProviderKey_Impl( const Reference<XPropertySetInfo> & rxPropInfo, const Sequence< sal_Int8 > & aImpIdSeq_ ); +}; + +hashTypeProviderKey_Impl::hashTypeProviderKey_Impl +( + const Reference<XPropertySetInfo> & rxPropInfo, + const Sequence< sal_Int8 > & aImpIdSeq_ +) + : xPropInfo( rxPropInfo ) + , maImpIdSeq( aImpIdSeq_ ) + , nHitCount( 0 ) +{} + + +struct TypeProviderAccessCache_Impl +{ + size_t operator()(const hashTypeProviderKey_Impl & rObj ) const; + + bool operator()( const hashTypeProviderKey_Impl & rObj1, + const hashTypeProviderKey_Impl & rObj2 ) const + { + if( rObj1.xPropInfo != rObj2.xPropInfo ) + return sal_False; + + const sal_Int8* pId1 = rObj1.maImpIdSeq.getConstArray(); + const sal_Int8* pId2 = rObj2.maImpIdSeq.getConstArray(); + return memcmp( pId1, pId2, 16 * sizeof( sal_Int8 ) ) == 0; + } +}; + +size_t TypeProviderAccessCache_Impl::operator()(const hashTypeProviderKey_Impl & rObj ) const +{ + const sal_Int32* pBytesAsInt32Array = (const sal_Int32*)rObj.maImpIdSeq.getConstArray(); + sal_Int32 nId32 = pBytesAsInt32Array[0] ^ + pBytesAsInt32Array[1] ^ + pBytesAsInt32Array[2] ^ + pBytesAsInt32Array[3]; + return (size_t)nId32 ^ (size_t)rObj.xPropInfo.get(); +} + + +typedef NAMESPACE_STD(hash_map) +< + hashTypeProviderKey_Impl, + IntrospectionAccessStatic_Impl*, + TypeProviderAccessCache_Impl, + TypeProviderAccessCache_Impl +> +TypeProviderAccessCacheMap_Impl; + +class TypeProviderAccessCacheMap : public TypeProviderAccessCacheMap_Impl +{ +public: + ~TypeProviderAccessCacheMap() + { + TypeProviderAccessCacheMap::iterator iter = begin(); + TypeProviderAccessCacheMap::iterator end = this->end(); + while( iter != end ) + { + (*iter).second->release(); + (*iter).second = NULL; + iter++; + } + } +}; + +#endif + + +//************************* +//*** ImplIntrospection *** +//************************* + +struct OIntrospectionMutex +{ + Mutex m_mutex; +}; + +class ImplIntrospection : public XIntrospection + , public XServiceInfo + , public OIntrospectionMutex + , public OComponentHelper +{ + friend class ImplMergeIntrospection; + friend class ImplMVCIntrospection; + + // Implementation der Introspection. + // ACHTUNG: RefCounting von Hand !!! + IntrospectionAccessStatic_Impl* implInspect(const Any& aToInspectObj); + + // Save XMultiServiceFactory from createComponent + Reference<XMultiServiceFactory> m_xSMgr; + + // CoreReflection halten + Reference< XIdlReflection > mxCoreReflection; + + // Klassen, deren Methoden eine spezielle Rolle spielen + Reference<XIdlClass> mxElementAccessClass; + Reference<XIdlClass> mxNameContainerClass; + Reference<XIdlClass> mxNameAccessClass; + Reference<XIdlClass> mxIndexContainerClass; + Reference<XIdlClass> mxIndexAccessClass; + Reference<XIdlClass> mxEnumerationAccessClass; + Reference<XIdlClass> mxInterfaceClass; + Reference<XIdlClass> mxAggregationClass; + sal_Bool mbDisposed; + +#ifdef USE_INTROSPECTION_CACHE + sal_uInt16 mnCacheEntryCount; + IntrospectionAccessCacheMap* mpCache; + TypeProviderAccessCacheMap* mpTypeProviderCache; +#endif + +public: + ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr ); + + // Methoden von XInterface + virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException ); + virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() { OComponentHelper::release(); } + + // XTypeProvider + Sequence< Type > SAL_CALL getTypes( ) throw( RuntimeException ); + Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw( RuntimeException ); + + // XServiceInfo + OUString SAL_CALL getImplementationName() throw(); + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(); + Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw(); + static OUString SAL_CALL getImplementationName_Static( ); + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(void) throw(); + + // Methoden von XIntrospection + virtual Reference<XIntrospectionAccess> SAL_CALL inspect(const Any& aToInspectObj) + throw( RuntimeException ); + +protected: + // some XComponent part from OComponentHelper + virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); +}; + +enum MethodType +{ + STANDARD_METHOD, // normale Methode, kein Bezug zu Properties oder Listenern + GETSET_METHOD, // gehoert zu einer get/set-Property + ADD_LISTENER_METHOD, // add-Methode einer Listener-Schnittstelle + REMOVE_LISTENER_METHOD, // remove-Methode einer Listener-Schnittstelle + INVALID_METHOD // Methode, deren Klasse nicht beruecksichtigt wird, z.B. XPropertySet +}; + +// Ctor +ImplIntrospection::ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr ) + : m_xSMgr( rXSMgr ) + , OComponentHelper( m_mutex ) +{ +#ifdef USE_INTROSPECTION_CACHE + mnCacheEntryCount = 0; + mpCache = NULL; + mpTypeProviderCache = NULL; +#endif + + // Spezielle Klassen holen + Reference< XInterface > xServiceIface = m_xSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) ); + if( xServiceIface.is() ) + mxCoreReflection = Reference< XIdlReflection >::query( xServiceIface ); + + mxElementAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XElementAccess")) ); + mxNameContainerClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XNameContainer")) ); + mxNameAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XNameAccess")) ); + mxIndexContainerClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XIndexContainer")) ); + mxIndexAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XIndexAccess")) ); + mxEnumerationAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XEnumerationAccess")) ); + mxInterfaceClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface")) ); + mxAggregationClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XAggregation")) ); + mbDisposed = sal_False; +} + +// XComponent +void ImplIntrospection::dispose() throw(::com::sun::star::uno::RuntimeException) +{ + OComponentHelper::dispose(); + +#ifdef USE_INTROSPECTION_CACHE + // Cache loeschen + delete mpCache; + mpCache = NULL; + delete mpTypeProviderCache; + mpTypeProviderCache = NULL; +#endif + + mxElementAccessClass = NULL; + mxNameContainerClass = NULL; + mxNameAccessClass = NULL; + mxIndexContainerClass = NULL; + mxIndexAccessClass = NULL; + mxEnumerationAccessClass = NULL; + mxInterfaceClass = NULL; + mxAggregationClass = NULL; + mbDisposed = sal_True; +} + + +//----------------------------------------------------------------------------- + +// XInterface +Any ImplIntrospection::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( + rType, + static_cast< XIntrospection * >( this ), + static_cast< XServiceInfo * >( this ) ) ); + + return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType )); +} + +// XTypeProvider +Sequence< Type > ImplIntrospection::getTypes() + throw( RuntimeException ) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XIntrospection > *)0 ), + ::getCppuType( (const Reference< XServiceInfo > *)0 ), + OComponentHelper::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} + +Sequence< sal_Int8 > ImplIntrospection::getImplementationId() + throw( RuntimeException ) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + + +// XServiceInfo +OUString ImplIntrospection::getImplementationName() throw() +{ + return getImplementationName_Static(); +} + +// XServiceInfo +sal_Bool ImplIntrospection::supportsService(const OUString& ServiceName) throw() +{ + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +// XServiceInfo +Sequence< OUString > ImplIntrospection::getSupportedServiceNames(void) throw() +{ + return getSupportedServiceNames_Static(); +} + +//************************************************************************* +// Helper XServiceInfo +OUString ImplIntrospection::getImplementationName_Static( ) +{ + return OUString::createFromAscii( IMPLEMENTATION_NAME ); +} + +// ORegistryServiceManager_Static +Sequence< OUString > ImplIntrospection::getSupportedServiceNames_Static(void) throw() +{ + Sequence< OUString > aSNS( 1 ); + aSNS.getArray()[0] = OUString::createFromAscii( SERVICE_NAME ); + return aSNS; +} + +//************************************************************************* + +// Methoden von XIntrospection +Reference<XIntrospectionAccess> ImplIntrospection::inspect(const Any& aToInspectObj) + throw( RuntimeException ) +{ + Reference<XIntrospectionAccess> xAccess; + + if ( aToInspectObj.getValueType().getTypeClass() == TypeClass_TYPE ) + { + Type aType; + aToInspectObj >>= aType; + + Reference< XIdlClass > xIdlClass = mxCoreReflection->forName(((Type*)(aToInspectObj.getValue()))->getTypeName()); + + if ( xIdlClass.is() ) + { + Any aRealInspectObj; + aRealInspectObj <<= xIdlClass; + + IntrospectionAccessStatic_Impl* pStaticImpl = implInspect( aRealInspectObj ); + if( pStaticImpl ) + xAccess = new ImplIntrospectionAccess( aRealInspectObj, pStaticImpl ); + } + } + else + { + IntrospectionAccessStatic_Impl* pStaticImpl = implInspect( aToInspectObj ); + if( pStaticImpl ) + xAccess = new ImplIntrospectionAccess( aToInspectObj, pStaticImpl ); + } + + return xAccess; +} + +//----------------------------------------------------------------------------- + +// Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces +struct hashInterface_Impl +{ + size_t operator()(const void* p) const + { + return (size_t)p; + } +}; + +struct eqInterface_Impl +{ + bool operator()(const void* p1, const void* p2) const + { + return ( p1 == p2 ); + } +}; + +typedef NAMESPACE_STD(hash_map) +< + void*, + void*, + hashInterface_Impl, + eqInterface_Impl +> +CheckedInterfacesMap; + + + +// TODO: Spaeter auslagern +Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr ) +{ + static Reference< XIdlReflection > xRefl; + + // void als Default-Klasse eintragen + Reference<XIdlClass> xRetClass; + typelib_TypeDescription * pTD = 0; + rType.getDescription( &pTD ); + if( pTD ) + { + OUString sOWName( pTD->pTypeName ); + if( !xRefl.is() ) + { + xRefl = Reference< XIdlReflection >( xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) ), UNO_QUERY ); + OSL_ENSHURE( xRefl.is(), "### no corereflection!" ); + } + xRetClass = xRefl->forName( sOWName ); + } + return xRetClass; +} + +// Implementation der Introspection. +IntrospectionAccessStatic_Impl* ImplIntrospection::implInspect(const Any& aToInspectObj) +{ + MutexGuard aGuard( m_mutex ); + + // Wenn die Introspection schon disposed ist, wird nur ein leeres Ergebnis geliefert + if( mbDisposed ) + return NULL; + + // Objekt untersuchen + TypeClass eType = aToInspectObj.getValueType().getTypeClass(); + if( eType != TypeClass_INTERFACE && eType != TypeClass_STRUCT && eType != TypeClass_EXCEPTION ) + return NULL; + + Reference<XInterface> x; + if( eType == TypeClass_INTERFACE ) + { + // Interface aus dem Any besorgen + x = *(Reference<XInterface>*)aToInspectObj.getValue(); + if( !x.is() ) + return NULL; + } + +#ifdef USE_INTROSPECTION_CACHE + // Haben wir schon eine Cache-Instanz + if( !mpCache ) + mpCache = new IntrospectionAccessCacheMap; + if( !mpTypeProviderCache ) + mpTypeProviderCache = new TypeProviderAccessCacheMap; + IntrospectionAccessCacheMap& aCache = *mpCache; + TypeProviderAccessCacheMap& aTPCache = *mpTypeProviderCache; + + // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz + IntrospectionAccessStatic_Impl* pAccess = NULL; +#else + // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz + IntrospectionAccessStatic_Impl* pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection ); +#endif + + // Pruefen: Ist schon ein passendes Access-Objekt gecached? + Sequence< Reference<XIdlClass> > SupportedClassSeq; + Sequence< Type > SupportedTypesSeq; + Reference<XIdlClassProvider> xClassProvider; + Reference<XTypeProvider> xTypeProvider; + Reference<XIdlClass> xImplClass; + Reference<XPropertySetInfo> xPropSetInfo; + Reference<XPropertySet> xPropSet; + + // Bei Interfaces XTypeProvider / XIdlClassProvider- und PropertySet-Interface anfordern + if( eType == TypeClass_INTERFACE ) + { + // XIdlClassProvider + xTypeProvider = Reference<XTypeProvider>::query( x ); + if( xTypeProvider.is() ) + { + SupportedTypesSeq = xTypeProvider->getTypes(); + sal_Int32 nTypeCount = SupportedTypesSeq.getLength(); + if( nTypeCount ) + { + SupportedClassSeq.realloc( nTypeCount ); + Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray(); + + const Type* pTypes = SupportedTypesSeq.getConstArray(); + for( sal_Int32 i = 0 ; i < nTypeCount ; i++ ) + { + pClasses[ i ] = TypeToIdlClass( pTypes[ i ], m_xSMgr ); + } + // TODO: Caching! + } + } + else + { + // XIdlClassProvider + xClassProvider = Reference<XIdlClassProvider>::query( x ); + if( xClassProvider.is() ) + { + SupportedClassSeq = xClassProvider->getIdlClasses(); + if( SupportedClassSeq.getLength() ) + xImplClass = SupportedClassSeq.getConstArray()[0]; + } + } + // #70197, fuer InvocationAdapter: Interface-Typ im Any auch ohne + // ClassProvider unterstuetzen + if( !xClassProvider.is() && !xTypeProvider.is() ) + { + xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr ); + SupportedClassSeq.realloc( 1 ); + SupportedClassSeq.getArray()[ 0 ] = xImplClass; + } + + xPropSet = Reference<XPropertySet>::query( x ); + // Jetzt versuchen, das PropertySetInfo zu bekommen + if( xPropSet.is() ) + xPropSetInfo = xPropSet->getPropertySetInfo(); + } + else + { + xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr ); + } + +#ifdef USE_INTROSPECTION_CACHE + if( xTypeProvider.is() ) + { + Sequence< sal_Int8 > aImpIdSeq = xTypeProvider->getImplementationId(); + + // cache only, if the descriptor class is set + hashTypeProviderKey_Impl aKeySeq( xPropSetInfo, aImpIdSeq ); + + TypeProviderAccessCacheMap::iterator aIt = aTPCache.find( aKeySeq ); + if( aIt == aTPCache.end() ) + { + // not found + // Neue Instanz anlegen und unter dem gegebenen Key einfuegen + pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection ); + + // RefCount von Hand erhoehen, muss beim Entfernen + // aus der Hashtable wieder released werden + pAccess->acquire(); + + // Groesse begrenzen, alten Eintrag wieder rausschmeissen + if( mnCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE ) + { + // Access mit dem kleinsten HitCount suchen + TypeProviderAccessCacheMap::iterator iter = aTPCache.begin(); + TypeProviderAccessCacheMap::iterator end = aTPCache.end(); + TypeProviderAccessCacheMap::iterator toDelete = iter; + while( iter != end ) + { + if( (*iter).first.nHitCount < (*toDelete).first.nHitCount ) + toDelete = iter; + ++iter; + } + + // Gefundenen Eintrag entfernen + if( (*toDelete).second ) + (*toDelete).second->release(); + (*toDelete).second = NULL; + aTPCache.erase( toDelete ); + } + else + mnCacheEntryCount++; + + // Neuer Eintrage rein in die Table + aKeySeq.nHitCount = 1; + aTPCache[ aKeySeq ] = pAccess; + + } + else + { + // Hit-Count erhoehen + (*aIt).first.IncHitCount(); + return (*aIt).second; + } + + } + else if( xImplClass.is() ) + { + // cache only, if the descriptor class is set + hashIntrospectionKey_Impl aKeySeq( SupportedClassSeq, xPropSetInfo, xImplClass ); + + IntrospectionAccessCacheMap::iterator aIt = aCache.find( aKeySeq ); + if( aIt == aCache.end() ) + { + // not found + // Neue Instanz anlegen und unter dem gegebenen Key einfuegen + pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection ); + + // RefCount von Hand erhoehen, muss beim Entfernen + // aus der Hashtable wieder released werden + pAccess->acquire(); + + // Groesse begrenzen, alten Eintrag wieder rausschmeissen + if( mnCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE ) + { + // Access mit dem kleinsten HitCount suchen + IntrospectionAccessCacheMap::iterator iter = aCache.begin(); + IntrospectionAccessCacheMap::iterator end = aCache.end(); + IntrospectionAccessCacheMap::iterator toDelete = iter; + while( iter != end ) + { + if( (*iter).first.nHitCount < (*toDelete).first.nHitCount ) + toDelete = iter; + ++iter; + } + + // Gefundenen Eintrag entfernen + if( (*toDelete).second ) + (*toDelete).second->release(); + (*toDelete).second = NULL; + aCache.erase( toDelete ); + } + else + mnCacheEntryCount++; + + // Neuer Eintrage rein in die Table + aKeySeq.nHitCount = 1; + aCache[ aKeySeq ] = pAccess; + + } + else + { + // Hit-Count erhoehen + (*aIt).first.IncHitCount(); + return (*aIt).second; + } + } +#endif + + // Kein Access gecached -> neu anlegen + Property* pAllPropArray; + Reference<XInterface>* pInterfaces1; + Reference<XInterface>* pInterfaces2; + sal_Int16* pMapTypeArray; + sal_Int32* pPropertyConceptArray; + sal_Int32 i; + + if( !pAccess ) + pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection ); + + // Referenzen auf wichtige Daten von pAccess + sal_Int32& rPropCount = pAccess->mnPropCount; + IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap; + IntrospectionNameMap& rMethodNameMap = pAccess->maMethodNameMap; + LowerToExactNameMap& rLowerToExactNameMap = pAccess->maLowerToExactNameMap; + + // Schon mal Pointer auf das eigene Property-Feld holen + pAllPropArray = pAccess->maAllPropertySeq.getArray(); + pInterfaces1 = pAccess->aInterfaceSeq1.getArray(); + pInterfaces2 = pAccess->aInterfaceSeq2.getArray(); + pMapTypeArray = pAccess->maMapTypeSeq.getArray(); + pPropertyConceptArray = pAccess->maPropertyConceptSeq.getArray(); + + //************************* + //*** Analyse vornehmen *** + //************************* + if( eType == TypeClass_INTERFACE ) + { + // Zunaechst nach speziellen Interfaces suchen, die fuer + // die Introspection von besonderer Bedeutung sind. + + // XPropertySet vorhanden? + if( xPropSet.is() && xPropSetInfo.is() ) + { + // Gibt es auch ein FastPropertySet? + Reference<XFastPropertySet> xDummy = Reference<XFastPropertySet>::query( x ); + sal_Bool bFast = pAccess->mbFastPropSet = xDummy.is(); + + Sequence<Property> aPropSeq = xPropSetInfo->getProperties(); + const Property* pProps = aPropSeq.getConstArray(); + sal_Int32 nLen = aPropSeq.getLength(); + + // Bei FastPropertySet muessen wir uns die Original-Handles merken + if( bFast ) + pAccess->mpOrgPropertyHandleArray = new sal_Int32[ nLen ]; + + for( i = 0 ; i < nLen ; i++ ) + { + // Property in eigene Liste uebernehmen + pAccess->checkPropertyArraysSize + ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount ); + Property& rProp = pAllPropArray[ rPropCount ]; + rProp = pProps[ i ]; + + if( bFast ) + pAccess->mpOrgPropertyHandleArray[ i ] = rProp.Handle; + + // PropCount als Handle fuer das eigene FastPropertySet eintragen + rProp.Handle = rPropCount; + + // Art der Property merken + pMapTypeArray[ rPropCount ] = MAP_PROPERTY_SET; + pPropertyConceptArray[ rPropCount ] = PROPERTYSET; + pAccess->mnPropertySetPropCount++; + + // Namen in Hashtable eintragen, wenn nicht schon bekannt + OUString aPropName = rProp.Name; + + // Haben wir den Namen schon? + IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName ); + if( aIt == rPropNameMap.end() ) + { + // Neuer Eintrag in die Hashtable + rPropNameMap[ aPropName ] = rPropCount; + + // Tabelle fuer XExactName pflegen + rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName; + } + else + { + OSL_ENSHURE( sal_False, + OString( "Introspection: Property \"" ) + + OUStringToOString( aPropName, RTL_TEXTENCODING_ASCII_US ) + + OString( "\" found more than once in PropertySet" ) ); + } + + // Count pflegen + rPropCount++; + } + } + + + // Jetzt alle weiteren implementierten Interfaces durchgehen + // Diese muessen durch das XIdlClassProvider-Interface geliefert werden. + // #70197, fuer InvocationAdapter: Interface-Typ im Any auch ohne + // ClassProvider unterstuetzen + //if( xClassProvider.is() ) + { + // Indizes in die Export-Tabellen + sal_Int32 iAllExportedMethod = 0L; + sal_Int32 iAllSupportedListener = 0L; + + // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces + CheckedInterfacesMap aCheckedInterfacesMap; + + // Flag, ob XInterface-Methoden erfasst werden sollen + // (das darf nur einmal erfolgen, initial zulassen) + sal_Bool bXInterfaceIsInvalid = sal_False; + + // Flag, ob die XInterface-Methoden schon erfasst wurden. Wenn sal_True, + // wird bXInterfaceIsInvalid am Ende der Iface-Schleife aktiviert und + // XInterface-Methoden werden danach abgeklemmt. + sal_Bool bFoundXInterface = sal_False; + + // Schleife ueber alle vom ClassProvider angegebenen Klassen + sal_Int32 nClassCount = SupportedClassSeq.getLength(); + for( sal_Int32 nIdx = 0 ; nIdx < nClassCount; nIdx++ ) + { + Reference<XIdlClass> xImplClass = SupportedClassSeq.getConstArray()[nIdx]; + while( xImplClass.is() ) + { + // Interfaces der Implementation holen + Sequence< Reference<XIdlClass> > aClassSeq = xImplClass->getInterfaces(); + sal_Int32 nIfaceCount = aClassSeq.getLength(); + + aClassSeq.realloc( nIfaceCount + 1 ); + aClassSeq.getArray()[ nIfaceCount ] = xImplClass; + nIfaceCount++; + + const Reference<XIdlClass>* pParamArray = aClassSeq.getConstArray(); + + for( sal_Int32 j = 0 ; j < nIfaceCount ; j++ ) + { + const Reference<XIdlClass>& rxIfaceClass = pParamArray[j]; + + // Pruefen, ob das Interface schon beruecksichtigt wurde. + XInterface* pIface = SAL_STATIC_CAST( XInterface*, rxIfaceClass.get() ); + if( aCheckedInterfacesMap.count( pIface ) > 0 ) + { + // Kennen wir schon + continue; + } + else + { + // Sonst eintragen + aCheckedInterfacesMap[ pIface ] = pIface; + } + + //******************************************************************** + + // 2. Fields als Properties registrieren + + // Felder holen + Sequence< Reference<XIdlField> > fields = rxIfaceClass->getFields(); + const Reference<XIdlField>* pFields = fields.getConstArray(); + sal_Int32 nLen = fields.getLength(); + + for( i = 0 ; i < nLen ; i++ ) + { + Reference<XIdlField> xField = pFields[i]; + Reference<XIdlClass> xPropType = xField->getType(); + + // Ist die PropertySequence gross genug? + pAccess->checkPropertyArraysSize + ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount ); + + // In eigenes Property-Array eintragen + Property& rProp = pAllPropArray[ rPropCount ]; + OUString aFieldName = xField->getName(); + rProp.Name = aFieldName; + rProp.Handle = rPropCount; + Type aFieldType( xPropType->getTypeClass(), xPropType->getName() ); + rProp.Type = aFieldType; + FieldAccessMode eAccessMode = xField->getAccessMode(); + rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY || + eAccessMode == FieldAccessMode_CONST) + ? READONLY : 0; + + // Namen in Hashtable eintragen + OUString aPropName = rProp.Name; + + // Haben wir den Namen schon? + IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName ); + if( !( aIt == rPropNameMap.end() ) ) + { + /* TODO + OSL_TRACE( + String( "Introspection: Property \"" ) + + OOUStringToString( aPropName, CHARSET_SYSTEM ) + + String( "\" found more than once" ) ); + */ + continue; + } + + // Neuer Eintrag in die Hashtable + rPropNameMap[ aPropName ] = rPropCount; + + // Tabelle fuer XExactName pflegen + rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName; + + // Field merken + pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1, + pInterfaces1, rPropCount ); + pInterfaces1[ rPropCount ] = xField; + + // Art der Property merken + pMapTypeArray[ rPropCount ] = MAP_FIELD; + pPropertyConceptArray[ rPropCount ] = ATTRIBUTES; + pAccess->mnAttributePropCount++; + + // Count pflegen + rPropCount++; + } + + //******************************************************************** + + // 3. Methoden + + // Zaehler fuer die gefundenen Listener + sal_Int32 nListenerCount = 0L; + + // Alle Methoden holen und merken + Sequence< Reference<XIdlMethod> > methods = rxIfaceClass->getMethods(); + const Reference<XIdlMethod>* pSourceMethods = methods.getConstArray(); + sal_Int32 nSourceMethodCount = methods.getLength(); + + // 3. a) get/set- und Listener-Methoden suchen + + // Feld fuer Infos ueber die Methoden anlegen, damit spaeter leicht die Methoden + // gefunden werden koennen, die nicht im Zusammenhang mit Properties oder Listenern + // stehen. NEU: auch MethodConceptArray initialisieren + MethodType* pMethodTypes = new MethodType[ nSourceMethodCount ]; + sal_Int32* pLocalMethodConcepts = new sal_Int32[ nSourceMethodCount ]; + for( i = 0 ; i < nSourceMethodCount ; i++ ) + { + pMethodTypes[ i ] = STANDARD_METHOD; + pLocalMethodConcepts[ i ] = 0; + } + + OUString aMethName; + OUString aPropName; + OUString aStartStr; + for( i = 0 ; i < nSourceMethodCount ; i++ ) + { + // Methode ansprechen + const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i]; + sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ]; + + // Namen besorgen + aMethName = rxMethod_i->getName(); + + // Methoden katalogisieren + // Alle (?) Methoden von XInterface filtern, damit z.B. nicht + // vom Scripting aus aquire oder release gerufen werden kann + if( rxMethod_i->getDeclaringClass()->equals( mxInterfaceClass ) ) + { + // XInterface-Methoden sind hiermit einmal beruecksichtigt + bFoundXInterface = sal_True; + + if( bXInterfaceIsInvalid ) + { + pMethodTypes[ i ] = INVALID_METHOD; + continue; + } + else + { + if( aMethName != OUString( RTL_CONSTASCII_USTRINGPARAM("queryInterface")) ) + { + rMethodConcept_i |= MethodConcept::DANGEROUS; + continue; + } + } + } + else if( rxMethod_i->getDeclaringClass()->equals( mxAggregationClass ) ) + { + if( aMethName == OUString( RTL_CONSTASCII_USTRINGPARAM("setDelegator")) ) + { + rMethodConcept_i |= MethodConcept::DANGEROUS; + continue; + } + } + else if( rxMethod_i->getDeclaringClass()->equals( mxElementAccessClass ) ) + { + rMethodConcept_i |= ( NAMECONTAINER | + INDEXCONTAINER | + ENUMERATION ); + } + else if( rxMethod_i->getDeclaringClass()->equals( mxNameContainerClass ) || + rxMethod_i->getDeclaringClass()->equals( mxNameAccessClass ) ) + { + rMethodConcept_i |= NAMECONTAINER; + } + else if( rxMethod_i->getDeclaringClass()->equals( mxIndexContainerClass ) || + rxMethod_i->getDeclaringClass()->equals( mxIndexAccessClass ) ) + { + rMethodConcept_i |= INDEXCONTAINER; + } + else if( rxMethod_i->getDeclaringClass()->equals( mxEnumerationAccessClass ) ) + { + rMethodConcept_i |= ENUMERATION; + } + + // Wenn der Name zu kurz ist, wird's sowieso nichts + if( aMethName.len() <= 3 ) + continue; + + // Ist es eine get-Methode? + aStartStr = aMethName.copy( 0, 3 ); + if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("get")) ) + { + // Namen der potentiellen Property + aPropName = aMethName.copy( 3 ); + + // get-Methode darf keinen Parameter haben + Sequence< Reference<XIdlClass> > getParams = rxMethod_i->getParameterTypes(); + if( getParams.getLength() > 0 ) + { + continue; + } + + // Haben wir den Namen schon? + IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName ); + if( !( aIt == rPropNameMap.end() ) ) + { + /* TODO + OSL_TRACE( + String( "Introspection: Property \"" ) + + OOUStringToString( aPropName, CHARSET_SYSTEM ) + + String( "\" found more than once" ) ); + */ + continue; + } + + // Eine readonly-Property ist es jetzt mindestens schon + rMethodConcept_i |= PROPERTY; + + pMethodTypes[i] = GETSET_METHOD; + Reference<XIdlClass> xGetRetType = rxMethod_i->getReturnType(); + + // Ist die PropertySequence gross genug? + pAccess->checkPropertyArraysSize + ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount ); + + // In eigenes Property-Array eintragen + Property& rProp = pAllPropArray[ rPropCount ]; + rProp.Name = aPropName; + rProp.Handle = rPropCount; + rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() ); + rProp.Attributes = READONLY; + + // Neuer Eintrag in die Hashtable + rPropNameMap[ aPropName ] = rPropCount; + + // Tabelle fuer XExactName pflegen + rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName; + + // get-Methode merken + pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1, + pInterfaces1, rPropCount ); + pInterfaces1[ rPropCount ] = rxMethod_i; + + // Art der Property merken + pMapTypeArray[ rPropCount ] = MAP_GETSET; + pPropertyConceptArray[ rPropCount ] = METHODS; + pAccess->mnMethodPropCount++; + + // Passende set-Methode suchen + sal_Int32 k; + for( k = 0 ; k < nSourceMethodCount ; k++ ) + { + // Methode ansprechen + const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k]; + + // Nur Methoden nehmen, die nicht schon zugeordnet sind + if( k == i || pMethodTypes[k] != STANDARD_METHOD ) + continue; + + // Name holen und auswerten + OUString aMethName2 = rxMethod_k->getName(); + OUString aStartStr2 = aMethName2.copy( 0, 3 ); + // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!! + if( !( aStartStr2 == OUString( RTL_CONSTASCII_USTRINGPARAM("set")) ) ) + continue; + + // Ist es denn der gleiche Name? + OUString aPropName2 = aMethName2.copy( 3 ); + // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!! + if( !( aPropName == aPropName2 ) ) + continue; + + // set-Methode muss void returnen + Reference<XIdlClass> xSetRetType = rxMethod_k->getReturnType(); + if( xSetRetType->getTypeClass() != TypeClass_VOID ) + { + continue; + } + + // set-Methode darf nur einen Parameter haben + Sequence< Reference<XIdlClass> > setParams = rxMethod_k->getParameterTypes(); + sal_Int32 nParamCount = setParams.getLength(); + if( nParamCount != 1 ) + { + continue; + } + + // Jetzt muss nur noch der return-Typ dem Parameter-Typ entsprechen + const Reference<XIdlClass>* pParamArray = setParams.getConstArray(); + Reference<XIdlClass> xParamType = pParamArray[ 0 ]; + if( xParamType->equals( xGetRetType ) ) + { + pLocalMethodConcepts[ k ] = PROPERTY; + + pMethodTypes[k] = GETSET_METHOD; + + // ReadOnly-Flag wieder loschen + rProp.Attributes &= ~READONLY; + + // set-Methode merken + pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2, + pInterfaces2, rPropCount ); + pInterfaces2[ rPropCount ] = rxMethod_k; + } + } + + // Count pflegen + rPropCount++; + } + + // Ist es eine addListener-Methode? + else if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("add")) ) + { + OUString aListenerStr( RTL_CONSTASCII_USTRINGPARAM("Listener" ) ); + + // Namen der potentiellen Property + sal_Int32 nStrLen = aMethName.len(); + OUString aEndStr = aMethName.copy( nStrLen - aListenerStr.len() ); + + // Endet das Teil auf Listener? + // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!! + if( !( aEndStr == aListenerStr ) ) + continue; + + // Welcher Listener? + OUString aListenerName = aMethName.copy( 3, nStrLen - aListenerStr.len() - 3 ); + + // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden + // - Rueckgabe-Typ + // - Anzahl und Art der Parameter + + + // Passende remove-Methode suchen, sonst gilt's nicht + sal_Int32 k; + for( k = 0 ; k < nSourceMethodCount ; k++ ) + { + // Methode ansprechen + const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k]; + + // Nur Methoden nehmen, die nicht schon zugeordnet sind + if( k == i || pMethodTypes[k] != STANDARD_METHOD ) + continue; + + // Name holen und auswerten + OUString aMethName2 = rxMethod_k->getName(); + OUString aStartStr2 = aMethName2.copy( 0, 6 ); + OUString aRemoveStr( RTL_CONSTASCII_USTRINGPARAM("remove" ) ); + // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!! + if( !( aStartStr2 == aRemoveStr ) ) + continue; + + // Ist es denn der gleiche Listener? + if( aMethName2.len() - aRemoveStr.len() <= aListenerStr.len() ) + continue; + OUString aListenerName2 = aMethName2.copy + ( 6, aMethName2.len() - aRemoveStr.len() - aListenerStr.len() ); + // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!! + if( !( aListenerName == aListenerName2 ) ) + continue; + + // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden + // - Rueckgabe-Typ + // - Anzahl und Art der Parameter + + + // Methoden sind als Listener-Schnittstelle erkannt + rMethodConcept_i |= LISTENER; + pLocalMethodConcepts[ k ] |= LISTENER; + + pMethodTypes[i] = ADD_LISTENER_METHOD; + pMethodTypes[k] = REMOVE_LISTENER_METHOD; + nListenerCount++; + } + } + } + + + // Jetzt koennen noch SET-Methoden ohne zugehoerige GET-Methode existieren, + // diese muessen zu Write-Only-Properties gemachte werden. + for( i = 0 ; i < nSourceMethodCount ; i++ ) + { + // Methode ansprechen + const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i]; + + // Nur Methoden nehmen, die nicht schon zugeordnet sind + if( pMethodTypes[i] != STANDARD_METHOD ) + continue; + + // Namen besorgen + aMethName = rxMethod_i->getName(); + + // Wenn der Name zu kurz ist, wird's sowieso nichts + if( aMethName.len() <= 3 ) + continue; + + // Ist es eine set-Methode ohne zugehoerige get-Methode? + aStartStr = aMethName.copy( 0, 3 ); + if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("set")) ) + { + // Namen der potentiellen Property + aPropName = aMethName.copy( 3 ); + + // set-Methode muss void returnen + Reference<XIdlClass> xSetRetType = rxMethod_i->getReturnType(); + if( xSetRetType->getTypeClass() != TypeClass_VOID ) + { + continue; + } + + // set-Methode darf nur einen Parameter haben + Sequence< Reference<XIdlClass> > setParams = rxMethod_i->getParameterTypes(); + sal_Int32 nParamCount = setParams.getLength(); + if( nParamCount != 1 ) + { + continue; + } + + // Haben wir den Namen schon? + IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName ); + if( !( aIt == rPropNameMap.end() ) ) + { + /* TODO: + OSL_TRACE( + String( "Introspection: Property \"" ) + + OOUStringToString( aPropName, CHARSET_SYSTEM ) + + String( "\" found more than once" ) ); + */ + continue; + } + + // Alles klar, es ist eine Write-Only-Property + pLocalMethodConcepts[ i ] = PROPERTY; + + pMethodTypes[i] = GETSET_METHOD; + Reference<XIdlClass> xGetRetType = setParams.getConstArray()[0]; + + // Ist die PropertySequence gross genug? + pAccess->checkPropertyArraysSize + ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount ); + + // In eigenes Property-Array eintragen + Property& rProp = pAllPropArray[ rPropCount ]; + rProp.Name = aPropName; + rProp.Handle = rPropCount; + rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() ); + rProp.Attributes = 0; // PROPERTY_WRITEONLY ??? + + // Neuer Eintrag in die Hashtable + rPropNameMap[ aPropName ] = rPropCount; + + // Tabelle fuer XExactName pflegen + rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName; + + // set-Methode merken + pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2, + pInterfaces2, rPropCount ); + pInterfaces2[ rPropCount ] = rxMethod_i; + + // Art der Property merken + pMapTypeArray[ rPropCount ] = MAP_SETONLY; + pPropertyConceptArray[ rPropCount ] = METHODS; + pAccess->mnMethodPropCount++; + + // Count pflegen + rPropCount++; + } + } + + + //******************************************************************** + + // 4. Methoden in die Gesamt-Sequence uebernehmen + + // Wieviele Methoden muessen in die Method-Sequence? + sal_Int32 nExportedMethodCount = 0L; + sal_Int32 nSupportedListenerCount = 0L; + for( i = 0 ; i < nSourceMethodCount ; i++ ) + { + if( pMethodTypes[ i ] != INVALID_METHOD ) + { + nExportedMethodCount++; + } + if( pMethodTypes[ i ] == ADD_LISTENER_METHOD ) + { + nSupportedListenerCount++; + } + } + + // Sequences im Access-Objekt entsprechend aufbohren + pAccess->maAllMethodSeq.realloc( nExportedMethodCount + iAllExportedMethod ); + pAccess->maMethodConceptSeq.realloc( nExportedMethodCount + iAllExportedMethod ); + pAccess->maSupportedListenerSeq.realloc( nSupportedListenerCount + iAllSupportedListener ); + + // Methoden reinschreiben + Reference<XIdlMethod>* pDestMethods = pAccess->maAllMethodSeq.getArray(); + sal_Int32* pMethodConceptArray = pAccess->maMethodConceptSeq.getArray(); + Type* pListenerClassRefs = pAccess->maSupportedListenerSeq.getArray(); + for( i = 0 ; i < nSourceMethodCount ; i++ ) + { + if( pMethodTypes[ i ] != INVALID_METHOD ) + { + // Methode ansprechen + const Reference<XIdlMethod>& rxMethod = pSourceMethods[i]; + + // Namen in Hashtable eintragen, wenn nicht schon bekannt + OUString aMethName = rxMethod->getName(); + IntrospectionNameMap::iterator aIt = rMethodNameMap.find( aMethName ); + if( !( aIt == rMethodNameMap.end() ) ) + { + /* TODO: + OSL_TRACE( String( "Introspection: Method \"" ) + + OOUStringToString( aMethName, CHARSET_SYSTEM ) + + String( "\" found more than once" ) ); + */ + continue; + } + + // Eintragen + rMethodNameMap[ aMethName ] = iAllExportedMethod; + + // Tabelle fuer XExactName pflegen + rLowerToExactNameMap[ toLower( aMethName ) ] = aMethName; + + pDestMethods[ iAllExportedMethod ] = rxMethod; + + // Wenn kein Concept gesetzt wurde, ist die Methode "normal" + sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ]; + if( !rMethodConcept_i ) + rMethodConcept_i = MethodConcept_NORMAL_IMPL; + pMethodConceptArray[ iAllExportedMethod ] = rMethodConcept_i; + iAllExportedMethod++; + } + if( pMethodTypes[ i ] == ADD_LISTENER_METHOD ) + { + // Klasse des Listeners ermitteln + const Reference<XIdlMethod>& rxMethod = pSourceMethods[i]; + + // void als Default-Klasse eintragen + Reference<XIdlClass> xListenerClass = TypeToIdlClass( getCppuVoidType(), m_xSMgr ); + // ALT: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass(); + + // 1. Moeglichkeit: Parameter nach einer Listener-Klasse durchsuchen + // Nachteil: Superklassen muessen rekursiv durchsucht werden + Sequence< Reference<XIdlClass> > aParams = rxMethod->getParameterTypes(); + const Reference<XIdlClass>* pParamArray = aParams.getConstArray(); + + Reference<XIdlClass> xEventListenerClass = TypeToIdlClass( getCppuType( (Reference<XEventListener>*) NULL ), m_xSMgr ); + // ALT: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass(); + sal_Int32 nParamCount = aParams.getLength(); + sal_Int32 k; + for( k = 0 ; k < nParamCount ; k++ ) + { + const Reference<XIdlClass>& rxClass = pParamArray[k]; + + // Sind wir von einem Listener abgeleitet? + if( rxClass->equals( xEventListenerClass ) || + isDerivedFrom( rxClass, xEventListenerClass ) ) + { + xListenerClass = rxClass; + break; + } + } + + // 2. Moeglichkeit: Namen der Methode auswerden + // Nachteil: geht nicht bei Test-Listenern, die es nicht gibt + //aMethName = rxMethod->getName(); + //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 ); + //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName ); + Type aListenerType( TypeClass_INTERFACE, xListenerClass->getName() ); + pListenerClassRefs[ iAllSupportedListener ] = aListenerType; + iAllSupportedListener++; + } + } + + // Wenn in diesem Durchlauf XInterface-Methoden + // dabei waren, diese zukuenftig ignorieren + if( bFoundXInterface ) + bXInterfaceIsInvalid = sal_True; + + delete pMethodTypes; + delete pLocalMethodConcepts; + } + + // Super-Klasse(n) vorhanden? Dann dort fortsetzen + Sequence< Reference<XIdlClass> > aSuperClassSeq = xImplClass->getSuperclasses(); + + // Zur Zeit wird nur von einer Superklasse ausgegangen + if( aSuperClassSeq.getLength() >= 1 ) + { + xImplClass = aSuperClassSeq.getConstArray()[0]; + OSL_ENSHURE( xImplClass.is(), "super class null" ); + } + else + { + xImplClass = NULL; + } + } + } + + // Anzahl der exportierten Methoden uebernehmen und Sequences anpassen + // (kann abweichen, weil doppelte Methoden erst nach der Ermittlung + // von nExportedMethodCount herausgeworfen werden) + sal_Int32& rMethCount = pAccess->mnMethCount; + rMethCount = iAllExportedMethod; + pAccess->maAllMethodSeq.realloc( rMethCount ); + pAccess->maMethodConceptSeq.realloc( rMethCount ); + + // Groesse der Property-Sequences anpassen + pAccess->maAllPropertySeq.realloc( rPropCount ); + pAccess->maPropertyConceptSeq.realloc( rPropCount ); + pAccess->maMapTypeSeq.realloc( rPropCount ); + + // Ende der Schleife ueber alle vom ClassProvider angegebenen Klassen + } + } + // Bei structs Fields als Properties registrieren + else //if( eType == TypeClass_STRUCT ) + { + // Ist es ein Interface oder eine struct? + //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass(); + Reference<XIdlClass> xClassRef = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr ); + if( !xClassRef.is() ) + { + OSL_ENSHURE( sal_False, "Can't get XIdlClass from Reflection" ); + return pAccess; + } + + // Felder holen + Sequence< Reference<XIdlField> > fields = xClassRef->getFields(); + const Reference<XIdlField>* pFields = fields.getConstArray(); + sal_Int32 nLen = fields.getLength(); + + for( i = 0 ; i < nLen ; i++ ) + { + Reference<XIdlField> xField = pFields[i]; + Reference<XIdlClass> xPropType = xField->getType(); + OUString aPropName = xField->getName(); + + // Ist die PropertySequence gross genug? + pAccess->checkPropertyArraysSize + ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount ); + + // In eigenes Property-Array eintragen + Property& rProp = pAllPropArray[ rPropCount ]; + rProp.Name = aPropName; + rProp.Handle = rPropCount; + rProp.Type = Type( xPropType->getTypeClass(), xPropType->getName() ); + FieldAccessMode eAccessMode = xField->getAccessMode(); + rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY || + eAccessMode == FieldAccessMode_CONST) + ? READONLY : 0; + + //FieldAccessMode eAccessMode = xField->getAccessMode(); + //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST) + //? PropertyAttribute::READONLY : 0; + + // Namen in Hashtable eintragen + rPropNameMap[ aPropName ] = rPropCount; + + // Tabelle fuer XExactName pflegen + rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName; + + // Field merken + pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1, + pInterfaces1, rPropCount ); + pInterfaces1[ rPropCount ] = xField; + + // Art der Property merken + pMapTypeArray[ rPropCount ] = MAP_FIELD; + pPropertyConceptArray[ rPropCount ] = ATTRIBUTES; + pAccess->mnAttributePropCount++; + + // Count pflegen + rPropCount++; + } + } + + // Property-Sequence auf die richtige Laenge bringen + pAccess->maAllPropertySeq.realloc( pAccess->mnPropCount ); + + return pAccess; +} + +//************************************************************************* +Reference< XInterface > SAL_CALL ImplIntrospection_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr ) + throw( RuntimeException ) +{ + Reference< XInterface > xService = (OWeakObject*)(OComponentHelper*)new ImplIntrospection( rSMgr ); + return xService; +} + +} + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString::createFromAscii( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) ); + + const Sequence< OUString > & rSNL = + stoc_inspect::ImplIntrospection::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + stoc_inspect::ImplIntrospection_CreateInstance, + stoc_inspect::ImplIntrospection::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + diff --git a/stoc/source/inspect/makefile.mk b/stoc/source/inspect/makefile.mk new file mode 100644 index 000000000000..fcc65bdf8748 --- /dev/null +++ b/stoc/source/inspect/makefile.mk @@ -0,0 +1,106 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= insp +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + + +SLOFILES= \ + $(SLO)$/introspection.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/stoc/source/invocation/inv.xml b/stoc/source/invocation/inv.xml new file mode 100644 index 000000000000..b8a30a05af05 --- /dev/null +++ b/stoc/source/invocation/inv.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE COMPONENTDESCRIPTION PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "componentdescription.dtd"> + +<COMPONENTDESCRIPTION + xmlns:xlink="http://www.w3.org/1999/xlink/Namespace" > + +<Author> Daniel Boelzle </Author> + +<Name> com.sun.star.comp.stoc.Invocation </Name> + +<Description> +You can construct Invocation objects through this factory service. +Invoke createInstanceWithArguments() of XSingleServiceFactory +to create an Invocation adapter for your object; +invoking createInstance() will fail. +Instances implement XInvocation to invoke methods and set/get properties at an object +which corresponds with the object which implements this interface. + +There are two ways to get information about this object. First you +can get the implemented method with XInvocation::getMethodNames() +and the properties with XInvocation::getPropertyNames(). +Second you can get, if provided, all information about the methods and the +properties with XInvocation::getIntrospection(). +Container access is available through the XIndexContainer, +XNameContainer and XEnumerationContainer +(use XInterface::queryInterface). +</Description> + +<ModuleName> inv </ModuleName> + +<LoaderName> com.sun.star.loader.SharedLibrary </LoaderName> + +<Language> C++ </Language> + +<Status StatusValue="final"/> + +<SupportedService> +com.sun.star.script.Invocation +</SupportedService> + +<ServiceDependency>com.sun.star.script.Converter</ServiceDependency> +<ServiceDependency>com.sun.star.beans.Introspection</ServiceDependency> +<ServiceDependency>com.sun.star.reflection.CoreReflection</ServiceDependency> + +<ProjectBuildDependency> cppuhelper </ProjectBuildDependency> +<ProjectBuildDependency> cppu </ProjectBuildDependency> +<ProjectBuildDependency> vos </ProjectBuildDependency> +<ProjectBuildDependency> sal </ProjectBuildDependency> + +<RuntimeModuleDependency> cppuhelper </RuntimeModuleDependency> +<RuntimeModuleDependency> cppu </RuntimeModuleDependency> +<RuntimeModuleDependency> sal </RuntimeModuleDependency> + +<Type> com.sun.star.script.XInvocation </Type> +<Type> com.sun.star.script.XInvocation2 </Type> +<Type> com.sun.star.script.InvocationInfo </Type> +<Type> com.sun.star.script.MemberType </Type> +<Type> com.sun.star.script.XTypeConverter </Type> +<Type> com.sun.star.script.FailReason </Type> +<Type> com.sun.star.beans.XIntrospection </Type> +<Type> com.sun.star.beans.XIntrospectionAccess </Type> +<Type> com.sun.star.beans.XPropertySet </Type> +<Type> com.sun.star.beans.XFastPropertySet </Type> +<Type> com.sun.star.beans.XMaterialHolder </Type> +<Type> com.sun.star.beans.XExactName </Type> +<Type> com.sun.star.beans.PropertyAttribute </Type> +<Type> com.sun.star.beans.PropertyConcept </Type> +<Type> com.sun.star.beans.MethodConcept </Type> +<Type> com.sun.star.lang.XEventListener </Type> +<Type> com.sun.star.lang.XInitialization </Type> +<Type> com.sun.star.lang.XTypeProvider </Type> +<Type> com.sun.star.lang.XServiceInfo </Type> +<Type> com.sun.star.lang.XSingleServiceFactory </Type> +<Type> com.sun.star.lang.XMultiServiceFactory </Type> +<Type> com.sun.star.registry.XRegistryKey </Type> +<Type> com.sun.star.uno.XAggregation </Type> +<Type> com.sun.star.uno.XWeak </Type> +<Type> com.sun.star.uno.TypeClass </Type> +<Type> com.sun.star.container.XEnumerationAccess </Type> +<Type> com.sun.star.container.XNameContainer </Type> +<Type> com.sun.star.container.XIndexContainer </Type> +<Type> com.sun.star.reflection.XIdlReflection </Type> +<Type> com.sun.star.reflection.XIdlClassProvider </Type> +<Type> com.sun.star.reflection.XIdlClass </Type> +<Type> com.sun.star.reflection.XIdlArray </Type> +<Type> com.sun.star.reflection.FieldAccessMode </Type> + +</COMPONENTDESCRIPTION> + diff --git a/stoc/source/invocation/invocation.cxx b/stoc/source/invocation/invocation.cxx new file mode 100644 index 000000000000..fa065dc4331f --- /dev/null +++ b/stoc/source/invocation/invocation.cxx @@ -0,0 +1,1282 @@ +/************************************************************************* + * + * $RCSfile: invocation.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CPPUHELER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#include <cppuhelper/typeprovider.hxx> + +#include <com/sun/star/script/FailReason.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/script/XInvocation.hpp> +#include <com/sun/star/script/XInvocation2.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/beans/XExactName.hpp> +#include <com/sun/star/beans/XMaterialHolder.hpp> +#include <com/sun/star/beans/XIntrospection.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/MethodConcept.hpp> +#include <com/sun/star/beans/PropertyConcept.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +#include <rtl/ustrbuf.hxx> +#include <rtl/strbuf.hxx> + +#include <stdlib.h> +#include <search.h> + + +#define SERVICE_NAME "com.sun.star.script.Invocation" +#define IMPL_NAME "com.sun.star.comp.stoc.Invocation" + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::script; +using namespace com::sun::star::reflection; +using namespace com::sun::star::beans; +using namespace com::sun::star::registry; +using namespace com::sun::star::container; +using namespace cppu; +using namespace rtl; +using namespace osl; + + +namespace stoc_inv +{ + +// TODO: Zentral implementieren +inline Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XIdlReflection > & xRefl ) +{ + return xRefl->forName( rType.getTypeName() ); +} + + +//================================================================================================== +class Invocation_Impl + : public OWeakObject + , public XInvocation2 + , public XNameContainer + , public XIndexContainer + , public XEnumerationAccess + , public XExactName + , public XMaterialHolder + , public XTypeProvider +{ +public: + Invocation_Impl( const Any & rAdapted, const Reference<XTypeConverter> &, + const Reference<XIntrospection> &, + const Reference<XIdlReflection> & ); + + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & aType) throw( RuntimeException ); + virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); } + virtual void SAL_CALL release() throw() { OWeakObject::release(); } + //void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); } + + + // XTypeProvider + virtual Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) + throw(RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId( ) + throw( RuntimeException); + + // Methoden von XMaterialHolder + virtual Any SAL_CALL getMaterial(void); + + // ? XTool + virtual void SAL_CALL setMaterial( const Any& rMaterial ); + + // XInvocation + virtual Reference<XIntrospectionAccess> SAL_CALL getIntrospection(void) throw( RuntimeException ); + virtual Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam) + throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException ); + virtual void SAL_CALL setValue(const OUString& PropertyName, const Any& Value) + throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException ); + virtual Any SAL_CALL getValue(const OUString& PropertyName) + throw( UnknownPropertyException, RuntimeException ); + virtual sal_Bool SAL_CALL hasMethod(const OUString& Name) throw( RuntimeException ); + virtual sal_Bool SAL_CALL hasProperty(const OUString& Name) throw( RuntimeException ); + + // XInvocation2 + virtual Sequence< OUString > SAL_CALL getMemberNames( ) + throw( RuntimeException ); + virtual Sequence< InvocationInfo > SAL_CALL getInfo( ) + throw( RuntimeException ); + virtual InvocationInfo SAL_CALL getInfoForName( const OUString& aName, sal_Bool bExact ) + throw( IllegalArgumentException, RuntimeException ); + + // All Access and Container methods are not thread save + // XElementAccess + virtual Type SAL_CALL getElementType(void) throw( RuntimeException ) + { return _xElementAccess->getElementType(); } + + virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException ) + { return _xElementAccess->hasElements(); } + + // XNameContainer + virtual void SAL_CALL insertByName( const OUString& Name, const Any& Element ) + throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException ) + { _xNameContainer->insertByName( Name, Element ); } + + virtual void SAL_CALL replaceByName( const OUString& Name, const Any& Element ) + throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException ) + { _xNameContainer->replaceByName( Name, Element ); } + + virtual void SAL_CALL removeByName( const OUString& Name ) + throw( NoSuchElementException, WrappedTargetException, RuntimeException ) + { _xNameContainer->removeByName( Name ); } + + // XNameAccess + virtual Any SAL_CALL getByName( const OUString& Name ) + throw( NoSuchElementException, WrappedTargetException, RuntimeException ) + { return _xNameAccess->getByName( Name ); } + + virtual Sequence<OUString> SAL_CALL getElementNames(void) throw( RuntimeException ) + { return _xNameAccess->getElementNames(); } + + virtual sal_Bool SAL_CALL hasByName( const OUString& Name ) throw( RuntimeException ) + { return _xNameAccess->hasByName( Name ); } + + // XIndexContainer + virtual void SAL_CALL insertByIndex( sal_Int32 Index, const Any& Element ) + throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) + { _xIndexContainer->insertByIndex( Index, Element ); } + + virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element ) + throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) + { _xIndexContainer->replaceByIndex( Index, Element ); } + + virtual void SAL_CALL removeByIndex( sal_Int32 Index ) + throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) + { _xIndexContainer->removeByIndex( Index ); } + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException ) + { return _xIndexAccess->getCount(); } + + virtual Any SAL_CALL getByIndex( sal_Int32 Index ) + throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) + { return _xIndexAccess->getByIndex( Index ); } + + // XEnumerationAccess + virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException ) + { return _xEnumerationAccess->createEnumeration(); } + + // XExactName + virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException ); + + + //===================================================================================================== +private: + void getInfoSequenceImpl( Sequence< OUString >* pStringSeq, Sequence< InvocationInfo >* pInfoSeq ); + void fillInfoForNameAccess( InvocationInfo& rInfo, const OUString& aName ); + void fillInfoForProperty( InvocationInfo& rInfo, const Property& rProp ); + void fillInfoForMethod( InvocationInfo& rInfo, const Reference< XIdlMethod > xMethod ); + + Reference<XTypeConverter> xTypeConverter; + Reference<XIntrospection> xIntrospection; + Reference<XIdlReflection> xCoreReflection; + + Any _aMaterial; + // _xDirect and (_xIntrospectionAccess, xPropertySet) are exclusive + Reference<XInvocation> _xDirect; + Reference<XInvocation2> _xDirect2; + Reference<XPropertySet> _xPropertySet; + Reference<XIntrospectionAccess> _xIntrospectionAccess; + + // supplied Interfaces + Reference<XNameContainer> _xNameContainer; + Reference<XNameAccess> _xNameAccess; + Reference<XIndexContainer> _xIndexContainer; + Reference<XIndexAccess> _xIndexAccess; + Reference<XEnumerationAccess> _xEnumerationAccess; + Reference<XElementAccess> _xElementAccess; + + // + Reference<XExactName> _xENDirect, _xENIntrospection, _xENNameAccess; +}; + + +//================================================================================================== +//================================================================================================== +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +Invocation_Impl::Invocation_Impl +( + const Any & rAdapted, + const Reference<XTypeConverter> & rTC, + const Reference<XIntrospection> & rI, + const Reference<XIdlReflection> & rCR +) + : xIntrospection( rI ) + , xTypeConverter( rTC ) + , xCoreReflection( rCR ) +{ + setMaterial( rAdapted ); +} + +//################################################################################################## +//### INTERFACE IMPLEMENTATIONS #################################################################### +//################################################################################################## + + +Any SAL_CALL Invocation_Impl::queryInterface( const Type & aType ) + throw( RuntimeException ) +{ + // TODO: Aendern, so sehr ineffektiv, + + // PropertySet-Implementation + Any a = ::cppu::queryInterface( aType, + SAL_STATIC_CAST(XInvocation*, this), + SAL_STATIC_CAST(XMaterialHolder*, this), + SAL_STATIC_CAST(XTypeProvider *,this) ); + if( a.hasValue() ) + { + return a; + } + + if( aType == getCppuType( (Reference<XExactName>*) NULL ) ) + { + // Ivocation does not support XExactName, if direct object supports + // XInvocation, but not XExactName. + if ((_xDirect.is() && _xENDirect.is()) || + (!_xDirect.is() && (_xENIntrospection.is() || _xENNameAccess.is()))) + { + return cppu::queryInterface( aType, SAL_STATIC_CAST(XExactName*, this) ); + } + } + else if ( aType == getCppuType( (Reference<XNameContainer>*) NULL ) ) + { + if( _xNameContainer.is() ) + return cppu::queryInterface( aType, SAL_STATIC_CAST(XNameContainer*, this) ); + } + else if ( aType == getCppuType( (Reference<XNameAccess>*) NULL ) ) + { + if( _xNameAccess.is() ) + return cppu::queryInterface( aType, SAL_STATIC_CAST(XNameAccess*, this) ); + } + else if ( aType == getCppuType( (Reference<XIndexContainer>*) NULL ) ) + { + if (_xIndexContainer.is()) + return cppu::queryInterface( aType, SAL_STATIC_CAST(XIndexContainer*, this) ); + } + else if ( aType == getCppuType( (Reference<XIndexAccess>*) NULL ) ) + { + if (_xIndexAccess.is()) + return cppu::queryInterface( aType, SAL_STATIC_CAST(XIndexAccess*, this) ); + } + else if ( aType == getCppuType( (Reference<XEnumerationAccess>*) NULL ) ) + { + if (_xEnumerationAccess.is()) + return cppu::queryInterface( aType , SAL_STATIC_CAST(XEnumerationAccess*, this) ); + } + else if ( aType == getCppuType( (Reference<XElementAccess>*) NULL ) ) + { + if (_xElementAccess.is()) + { + return ::cppu::queryInterface + ( aType , SAL_STATIC_CAST(XElementAccess*, SAL_STATIC_CAST(XNameContainer*, this) ) ); + } + } + else if ( aType == getCppuType( (Reference<XInvocation2>*) NULL ) ) + { + // Invocation does not support XInvocation2, if direct object supports + // XInvocation, but not XInvocation2. + if ( ( _xDirect.is() && _xDirect2.is()) || + (!_xDirect.is() && _xIntrospectionAccess.is() ) ) + { + return cppu::queryInterface( aType, SAL_STATIC_CAST(XInvocation2*, this) ); + } + } + + return OWeakObject::queryInterface( aType ); +} + + +//-------------------------------------------------------------------------------------------------- +Any Invocation_Impl::getMaterial(void) +{ + // AB, 12.2.1999 Sicherstellen, dass das Material wenn moeglich + // aus der direkten Invocation bzw. von der Introspection geholt + // wird, da sonst Structs nicht korrekt behandelt werden + Reference<XMaterialHolder> xMaterialHolder; + if( _xDirect.is() ) + { + xMaterialHolder = Reference<XMaterialHolder>::query( _xDirect ); + //_xDirect->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder ); + } + else if( _xIntrospectionAccess.is() ) + { + xMaterialHolder = Reference<XMaterialHolder>::query( _xIntrospectionAccess ); + //_xIntrospectionAccess->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder ); + } + if( xMaterialHolder.is() ) + { + return xMaterialHolder->getMaterial(); + } + return _aMaterial; +} + +//-------------------------------------------------------------------------------------------------- +void Invocation_Impl::setMaterial( const Any& rMaterial ) +{ + // set the material first and only once + Reference<XInterface> xObj; + + if (rMaterial.getValueType().getTypeClass() == TypeClass_INTERFACE) + xObj = *(Reference<XInterface>*)rMaterial.getValue(); + _aMaterial = rMaterial; + + // Ersteinmal alles ausserhalb des guards machen + _xDirect = Reference<XInvocation>::query( xObj ); + + if( _xDirect.is() ) + { + // Objekt direkt befragen + _xElementAccess = Reference<XElementAccess>::query( _xDirect ); + _xEnumerationAccess = Reference<XEnumerationAccess>::query( _xDirect ); + _xIndexAccess = Reference<XIndexAccess>::query( _xDirect ); + _xIndexContainer = Reference<XIndexContainer>::query( _xDirect ); + _xNameAccess = Reference<XNameAccess>::query( _xDirect ); + _xNameContainer = Reference<XNameContainer>::query( _xDirect ); + _xENDirect = Reference<XExactName>::query( _xDirect ); + _xDirect2 = Reference<XInvocation2>::query( _xDirect ); + + // only once!!! + //_xIntrospectionAccess = XIntrospectionAccessRef(); + //_xPropertySet = XPropertySetRef(); + } + else + { + // Invocation ueber die Introspection machen + if (xIntrospection.is()) + { + _xIntrospectionAccess = xIntrospection->inspect( _aMaterial ); + if( _xIntrospectionAccess.is() ) + { + + _xElementAccess = Reference<XElementAccess>::query( + _xIntrospectionAccess->queryAdapter( + getCppuType( (Reference<XElementAccess>*) NULL ) ) ); + + _xEnumerationAccess = Reference<XEnumerationAccess>::query( + _xIntrospectionAccess->queryAdapter( + getCppuType( (Reference<XEnumerationAccess>*) NULL )) ); + + _xIndexAccess = Reference<XIndexAccess>::query( + _xIntrospectionAccess->queryAdapter( + getCppuType( (Reference<XIndexAccess>*) NULL ) ) ); + + _xIndexContainer = Reference<XIndexContainer>::query( + _xIntrospectionAccess->queryAdapter( + getCppuType( (Reference<XIndexContainer>*) NULL ) ) ); + + _xNameAccess = Reference<XNameAccess>::query( + _xIntrospectionAccess->queryAdapter( + getCppuType( (Reference<XNameAccess>*) NULL ) ) ); + + _xNameContainer = Reference<XNameContainer>::query( + _xIntrospectionAccess->queryAdapter( + getCppuType( (Reference<XNameContainer>*) NULL ) ) ); + + _xPropertySet = Reference<XPropertySet>::query( + _xIntrospectionAccess->queryAdapter( + getCppuType( (Reference<XPropertySet>*) NULL )) ); + + _xENIntrospection = Reference<XExactName>::query( _xIntrospectionAccess ); + if (_xNameAccess.is()) + _xENNameAccess = Reference<XExactName>::query( _xNameAccess ); + } + } + /* only once !!! + _xDirect = XInvocationRef(); + if( !_xIntrospectionAccess.is() ) + { + // reset + _xElementAccess = XElementAccessRef(); + _xEnumerationAccess = XEnumerationAccessRef(); + _xIndexAccess = XIndexAccessRef(); + _xIndexContainer = XIndexContainerRef(); + _xNameAccess = XNameAccessRef(); + _xNameContainer = XNameContainerRef(); + _xPropertySet = XPropertySetRef(); + } + */ + } +} + +//-------------------------------------------------------------------------------------------------- +OUString Invocation_Impl::getExactName( const OUString& rApproximateName ) + throw( RuntimeException ) +{ + if (_xENDirect.is()) + return _xENDirect->getExactName( rApproximateName ); + + OUString aRet; + if (_xENIntrospection.is()) + aRet = _xENIntrospection->getExactName( rApproximateName ); + if (!aRet.len() && _xENNameAccess.is()) + aRet = _xENNameAccess->getExactName( rApproximateName ); + return aRet; +} + +//-------------------------------------------------------------------------------------------------- +Reference<XIntrospectionAccess> Invocation_Impl::getIntrospection(void) + throw( RuntimeException ) +{ + if( _xDirect.is() ) + return _xDirect->getIntrospection(); + else + return _xIntrospectionAccess; +} + +//-------------------------------------------------------------------------------------------------- +sal_Bool Invocation_Impl::hasMethod( const OUString& Name ) + throw( RuntimeException ) +{ + if (_xDirect.is()) + return _xDirect->hasMethod( Name ); + if( _xIntrospectionAccess.is() ) + return _xIntrospectionAccess->hasMethod( Name, MethodConcept::ALL ^ MethodConcept::DANGEROUS ); + return sal_False; +} + +//-------------------------------------------------------------------------------------------------- +sal_Bool Invocation_Impl::hasProperty( const OUString& Name ) + throw( RuntimeException ) +{ + if (_xDirect.is()) + return _xDirect->hasProperty( Name ); + // PropertySet + if( _xIntrospectionAccess.is() + && _xIntrospectionAccess->hasProperty( Name, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) ) + return sal_True; + // NameAccess + if( _xNameAccess.is() ) + return _xNameAccess->hasByName( Name ); + return sal_False; +} + +//-------------------------------------------------------------------------------------------------- +Any Invocation_Impl::getValue( const OUString& PropertyName ) + throw( UnknownPropertyException, RuntimeException ) +{ + if (_xDirect.is()) + return _xDirect->getValue( PropertyName ); + // PropertySet + if( _xIntrospectionAccess.is() && _xPropertySet.is() + && _xIntrospectionAccess->hasProperty( PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) ) + { + return _xPropertySet->getPropertyValue( PropertyName ); + } + // NameAccess + if( _xNameAccess.is() && _xNameAccess->hasByName( PropertyName ) ) + return _xNameAccess->getByName( PropertyName ); + + throw UnknownPropertyException(); + return Any(); // dummy +} + +//-------------------------------------------------------------------------------------------------- +void Invocation_Impl::setValue( const OUString& PropertyName, const Any& Value ) + throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException ) +{ + if (_xDirect.is()) + _xDirect->setValue( PropertyName, Value ); + else + { + // Properties + + if( _xIntrospectionAccess.is() && _xPropertySet.is() + && _xIntrospectionAccess->hasProperty( PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) ) + { + Property aProp = _xIntrospectionAccess->getProperty( PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ); + Reference < XIdlClass > r = TypeToIdlClass( aProp.Type, xCoreReflection ); + if( r->isAssignableFrom( + TypeToIdlClass( Value.getValueType(), xCoreReflection ) ) ) + _xPropertySet->setPropertyValue( PropertyName, Value ); + else if( xTypeConverter.is() ) + _xPropertySet->setPropertyValue( PropertyName, xTypeConverter->convertTo( Value, aProp.Type ) ); + else + throw CannotConvertException(); + } + // NameContainer + else + + if( _xNameContainer.is() ) + { + Any aConv; + Reference < XIdlClass > r = TypeToIdlClass( _xNameContainer->getElementType(), xCoreReflection ); + if( r->isAssignableFrom(TypeToIdlClass( Value.getValueType(), xCoreReflection ) ) ) + aConv = Value; + else if( xTypeConverter.is() ) + aConv = xTypeConverter->convertTo( Value, _xNameContainer->getElementType() ); + else + throw CannotConvertException(); + + // bei Vorhandensein ersetzen, ansonsten einfuegen + if (_xNameContainer->hasByName( PropertyName )) + _xNameContainer->replaceByName( PropertyName, aConv ); + else + _xNameContainer->insertByName( PropertyName, aConv ); + } + else + throw UnknownPropertyException(); + } +} + +//-------------------------------------------------------------------------------------------------- +Any Invocation_Impl::invoke( const OUString& FunctionName, const Sequence<Any>& InParams, + Sequence<sal_Int16>& OutIndizes, Sequence<Any>& OutParams ) + throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException ) +{ + if (_xDirect.is()) + return _xDirect->invoke( FunctionName, InParams, OutIndizes, OutParams ); + + if (_xIntrospectionAccess.is()) + { + // throw NoSuchMethodException if not exist + Reference<XIdlMethod> xMethod = _xIntrospectionAccess->getMethod( FunctionName, MethodConcept::ALL ^ MethodConcept::DANGEROUS ); + + // ParameterInfos + Sequence<ParamInfo> aFParams = xMethod->getParameterInfos(); + const ParamInfo* pFParams = aFParams.getConstArray(); + sal_uInt32 nFParamsLen = aFParams.getLength(); + + // IN Parameter + const Any* pInParams = InParams.getConstArray(); + sal_uInt32 nInParamsLen = InParams.getLength(); + sal_uInt32 nInIndex = 0; + + // Introspection Invoke Parameter + Sequence<Any> aInvokeParams( nFParamsLen ); + Any* pInvokeParams = aInvokeParams.getArray(); + + // OUT Indizes + OutIndizes.realloc( nFParamsLen ); + sal_Int16* pOutIndizes = OutIndizes.getArray(); + sal_uInt32 nOutIndex = 0; + + try + { + for ( sal_uInt32 nPos = 0; nPos < nFParamsLen; ++nPos ) + { + const ParamInfo& rFParam = pFParams[nPos]; + const Reference<XIdlClass>& rDestType = rFParam.aType; + + // is IN/INOUT parameter? + if (rFParam.aMode != ParamMode_OUT) + { + // IN parameter available? + if (nInIndex >= nInParamsLen) + throw CannotConvertException(); + //TODO: Parameter? throw( CannotConvertException( OUString( RTL_CONSTASCII_USTRINGPARAM(not enough IN parameters available!")), Reference<XInterface>(), rDestType->getTypeClass(), FailReason::NO_DEFAULT_AVAILABLE, nInIndex ) ); + + if (rDestType->isAssignableFrom( TypeToIdlClass( pInParams[nInIndex].getValueType(), xCoreReflection ) )) + pInvokeParams[nPos] = pInParams[nInIndex]; + else if (xTypeConverter.is()) + { + Type aDestType( rDestType->getTypeClass(), rDestType->getName() ); + pInvokeParams[nPos] = xTypeConverter->convertTo( pInParams[nInIndex], aDestType ); + } + else + throw CannotConvertException(); + + ++nInIndex; + } + + // is OUT/INOUT parameter? + if (rFParam.aMode != ParamMode_IN) + { + pOutIndizes[nOutIndex] = nPos; + if (rFParam.aMode == ParamMode_OUT) + rDestType->createObject( pInvokeParams[nPos] ); // default init + ++nOutIndex; + } + } + + // execute Method + Any aRet = xMethod->invoke( _aMaterial, aInvokeParams ); + + // OUT Params + OutIndizes.realloc( nOutIndex ); + pOutIndizes = OutIndizes.getArray(); + OutParams.realloc( nOutIndex ); + Any* pOutParams = OutParams.getArray(); + + for ( ; nOutIndex--; ) + pOutParams[nOutIndex] = pInvokeParams[pOutIndizes[nOutIndex]]; + + return aRet; + } + catch( CannotConvertException& rExc ) + { + rExc.ArgumentIndex = nInIndex; // optionalen Parameter Index hinzufuegen + throw rExc; + } + } + throw NoSuchMethodException(); + return Any(); +} + +//-------------------------------------------------------------------------------------------------- + +// Struct to optimize sorting +struct MemberItem +{ + OUString aName; + + // Defines where the member comes from + enum { NAMEACCESS, PROPERTYSET, METHOD } eMode; + + // Index to respective sequence + // (Index to NameAccess sequence for eMode==NAMEACCESS etc.) + sal_Int32 nIndex; +}; + +// qsort compare function for MemberItem +int __cdecl compare(const void *elem1, const void *elem2 ) +{ + MemberItem* pItem1 = *(MemberItem**)elem1; + MemberItem* pItem2 = *(MemberItem**)elem2; + return (int)pItem1->aName.compareTo( pItem2->aName ); +} + + +// Implementation of getting name or info +// String sequence will be filled when pStringSeq != NULL +// Info sequence will be filled when pInfoSeq != NULL +void Invocation_Impl::getInfoSequenceImpl +( + Sequence< OUString >* pStringSeq, + Sequence< InvocationInfo >* pInfoSeq +) +{ + //Sequence< OUString > aStrSeq; + //if( !pStringSeq ) + //pStringSeq = &aStrSeq; + + + // Get all needed sequences + Sequence<OUString> aNameAccessNames; + Sequence<Property> aPropertySeq; + Sequence< Reference< XIdlMethod > > aMethodSeq; + + if( _xNameAccess.is() ) + { + aNameAccessNames = _xNameAccess->getElementNames(); + } + + if( _xIntrospectionAccess.is() ) + { + aPropertySeq = _xIntrospectionAccess->getProperties + ( PropertyConcept::ALL - PropertyConcept::DANGEROUS ); + + aMethodSeq = _xIntrospectionAccess->getMethods + ( MethodConcept::ALL - MethodConcept::DANGEROUS ); + } + + sal_Int32 nNameAccessCount = aNameAccessNames.getLength(); + sal_Int32 nPropertyCount = aPropertySeq.getLength(); + sal_Int32 nMethodCount = aMethodSeq.getLength(); + sal_Int32 nTotalCount = nNameAccessCount + nPropertyCount + nMethodCount; + + // Create and fill array of MemberItems + MemberItem* pItems = new MemberItem[ nTotalCount ]; + const OUString* pStrings = aNameAccessNames.getConstArray(); + const Property* pProps = aPropertySeq.getConstArray(); + const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray(); + + // Create array of MemberItem* for sorting + MemberItem** ppItems = new MemberItem*[ nTotalCount ]; + + // Fill array of MemberItems + sal_Int32 i, iTotal = 0; + + // Name Access + for( i = 0 ; i < nNameAccessCount ; i++, iTotal++ ) + { + MemberItem& rItem = pItems[ iTotal ]; + ppItems[ iTotal ] = &rItem; + rItem.aName = pStrings[ i ]; + rItem.eMode = MemberItem::NAMEACCESS; + rItem.nIndex = i; + } + + // Property set + for( i = 0 ; i < nPropertyCount ; i++, iTotal++ ) + { + MemberItem& rItem = pItems[ iTotal ]; + ppItems[ iTotal ] = &rItem; + rItem.aName = pProps[ i ].Name; + rItem.eMode = MemberItem::PROPERTYSET; + rItem.nIndex = i; + } + + // Methods + for( i = 0 ; i < nMethodCount ; i++, iTotal++ ) + { + MemberItem& rItem = pItems[ iTotal ]; + ppItems[ iTotal ] = &rItem; + Reference< XIdlMethod > xMethod = pMethods[ i ]; + rItem.aName = xMethod->getName(); + rItem.eMode = MemberItem::METHOD; + rItem.nIndex = i; + } + + // Sort pointer array + qsort( ppItems, (size_t)nTotalCount, sizeof( MemberItem* ), compare ); + + // Setting up result sequences + OUString* pRetStrings = NULL; + if( pStringSeq ) + { + pStringSeq->realloc( nTotalCount ); + pRetStrings = pStringSeq->getArray(); + } + + InvocationInfo* pRetInfos = NULL; + if( pInfoSeq ) + { + pInfoSeq->realloc( nTotalCount ); + pRetInfos = pInfoSeq->getArray(); + } + + // Fill result sequences in the correct order of members + for( iTotal = 0 ; iTotal < nTotalCount ; iTotal++ ) + { + MemberItem& rItem = pItems[ iTotal ]; + if( pRetStrings ) + { + pRetStrings[ iTotal ] = rItem.aName; + } + + if( pRetInfos ) + { + if( rItem.eMode == MemberItem::NAMEACCESS ) + { + fillInfoForNameAccess( pRetInfos[ iTotal ], rItem.aName ); + } + else if( rItem.eMode == MemberItem::PROPERTYSET ) + { + fillInfoForProperty( pRetInfos[ iTotal ], pProps[ rItem.nIndex ] ); + } + else if( rItem.eMode == MemberItem::METHOD ) + { + fillInfoForMethod( pRetInfos[ iTotal ], pMethods[ rItem.nIndex ] ); + } + } + } +} + +// XInvocation2 +Sequence< OUString > SAL_CALL Invocation_Impl::getMemberNames( ) + throw( RuntimeException ) +{ + if( _xDirect2.is() ) + { + return _xDirect2->getMemberNames(); + } + Sequence< OUString > aRetSeq; + getInfoSequenceImpl( &aRetSeq, NULL ); + return aRetSeq; +} + +Sequence< InvocationInfo > SAL_CALL Invocation_Impl::getInfo( ) + throw( RuntimeException ) +{ + if( _xDirect2.is() ) + { + return _xDirect2->getInfo(); + } + Sequence< InvocationInfo > aRetSeq; + getInfoSequenceImpl( NULL, &aRetSeq ); + return aRetSeq; +} + +InvocationInfo SAL_CALL Invocation_Impl::getInfoForName( const OUString& aName, sal_Bool bExact ) + throw( IllegalArgumentException, RuntimeException ) +{ + if( _xDirect2.is() ) + { + return _xDirect2->getInfoForName( aName, bExact ); + } + + sal_Bool bFound = sal_False; + OUString aExactName = aName; + InvocationInfo aRetInfo; + + if( bExact ) + aExactName = getExactName( aName ); + if( aExactName.getLength() > 0 ) + { + if( _xIntrospectionAccess->hasMethod( aExactName, MethodConcept::ALL ^ MethodConcept::DANGEROUS ) ) + { + Reference<XIdlMethod> xMethod = _xIntrospectionAccess->getMethod + ( aExactName, MethodConcept::ALL ^ MethodConcept::DANGEROUS ); + fillInfoForMethod( aRetInfo, xMethod ); + bFound = sal_True; + } + else + { + if( _xIntrospectionAccess.is() && _xIntrospectionAccess->hasProperty + ( aExactName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) ) + { + Property aProp = _xIntrospectionAccess->getProperty + ( aExactName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ); + fillInfoForProperty( aRetInfo, aProp ); + bFound = sal_True; + } + // NameAccess + else if( _xNameAccess.is() && _xNameAccess->hasByName( aExactName ) ) + { + fillInfoForNameAccess( aRetInfo, aExactName ); + bFound = sal_True; + } + } + } + if( !bFound ) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("Unknown name, getExactName() failed!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + return aRetInfo; +} + +// Helper functions to fill InvocationInfo for XNameAccess +void Invocation_Impl::fillInfoForNameAccess +( + InvocationInfo& rInfo, + const OUString& aName +) +{ + rInfo.aName = aName; + rInfo.eMemberType = MemberType_PROPERTY; + rInfo.PropertyAttribute = 0; + if( !_xNameContainer.is() ) + { + rInfo.PropertyAttribute = PropertyAttribute::READONLY; + } + rInfo.aType = _xNameAccess->getElementType(); +} + +void Invocation_Impl::fillInfoForProperty +( + InvocationInfo& rInfo, + const Property& rProp +) +{ + rInfo.aName = rProp.Name; + rInfo.eMemberType = MemberType_PROPERTY; + rInfo.PropertyAttribute = rProp.Attributes; + rInfo.aType = rProp.Type; +} + +void Invocation_Impl::fillInfoForMethod +( + InvocationInfo& rInfo, + const Reference< XIdlMethod > xMethod +) +{ + rInfo.aName = xMethod->getName(); + rInfo.eMemberType = MemberType_METHOD; + Reference< XIdlClass > xReturnClass = xMethod->getReturnType(); + Type aReturnType( xReturnClass->getTypeClass(), xReturnClass->getName() ); + rInfo.aType = aReturnType; + Sequence<ParamInfo> aParamInfos = xMethod->getParameterInfos(); + sal_Int32 nParamCount = aParamInfos.getLength(); + if( nParamCount > 0 ) + { + const ParamInfo* pInfos = aParamInfos.getConstArray(); + + rInfo.aParamTypes.realloc( nParamCount ); + Type* pParamTypes = rInfo.aParamTypes.getArray(); + rInfo.aParamModes.realloc( nParamCount ); + ParamMode* pParamModes = rInfo.aParamModes.getArray(); + + for( sal_Int32 i = 0 ; i < nParamCount ; i++ ) + { + Reference< XIdlClass > xParamClass = pInfos[i].aType; + Type aParamType( xParamClass->getTypeClass(), xParamClass->getName() ); + pParamTypes[ i ] = aParamType; + pParamModes[ i ] = pInfos[i].aMode; + } + } +} + + +// XIdlClassProvider + +// XTypeProvider +Sequence< Type > SAL_CALL Invocation_Impl::getTypes(void) throw( RuntimeException ) +{ + // TODO !!!! + + return Sequence< Type > (); +} + +Sequence< sal_Int8 > SAL_CALL Invocation_Impl::getImplementationId( ) throw( RuntimeException) +{ + static OImplementationId *pId = 0; + if( ! pId ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pId ) + { + static OImplementationId id( sal_False ); + pId = &id; + } + } + return (*pId).getImplementationId(); +} + +/* +Sequence< Reference<XIdlClass> > Invocation_Impl::getIdlClasses(void) throw( RuntimeException ) +{ + Reflection * ppReflection[7]; + Usal_Int16 i = 0; + ppReflection[i++] = XInvocation_getReflection(); + if( _xElementAccess.is() ) + ppReflection[i++] = XElementAccess_getReflection(); + if( _xEnumerationAccess.is() ) + ppReflection[i++] = XEnumerationAccess_getReflection(); + if( _xIndexAccess.is() ) + ppReflection[i++] = XIndexAccess_getReflection(); + if( _xNameAccess.is() ) + ppReflection[i++] = XNameAccess_getReflection(); + if( _xIndexContainer.is() ) + ppReflection[i++] = XIndexContainer_getReflection(); + if( _xNameContainer.is() ) + ppReflection[i++] = XNameContainer_getReflection(); + + // Ivocation does not support XExactName, if direct object supports + // XInvocation, but not XExactName. + if ((_xDirect.is() && _xENDirect.is()) || + (!_xDirect.is() && (_xENIntrospection.is() || _xENNameAccess.is()))) + { + ppReflection[i++] = XExactName_getReflection(); + } + + Reference<XIdlClass> xClass = createStandardClass( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.Invocation")), + OWeakObject::getStaticIdlClass(), i, + ppReflection ); + return Sequence<Reference<XIdlClass>>( &xClass, 1 ); +} +*/ +//================================================================================================== +//================================================================================================== +//================================================================================================== +class InvocationService + : public OWeakObject + , public XSingleServiceFactory + , public XServiceInfo +{ +public: + InvocationService( const Reference<XMultiServiceFactory> & rSMgr ) + : mxSMgr( rSMgr ) + , xTypeConverter( Reference<XTypeConverter>::query( rSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter")) ) ) ) + , xIntrospection( Reference<XIntrospection>::query( rSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.Introspection")) ) ) ) + , xCoreReflection( Reference<XIdlReflection>::query( rSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) ) ) ) + {} + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & aType ) throw( RuntimeException ); + virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); } + virtual void SAL_CALL release() throw() { OWeakObject::release(); } + //void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); } + + // XIdlClassProvider + // virtual Sequence< Reference<XIdlClass> > SAL_CALL getIdlClasses(void) throw( RuntimeException ); + // XTypeProvider + virtual Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) + throw(RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId( ) + throw( RuntimeException); + + // XServiceInfo + OUString SAL_CALL getImplementationName() throw( RuntimeException ); + static OUString SAL_CALL getImplementationName_Static() throw( RuntimeException ) + { + return OUString::createFromAscii( IMPL_NAME ); + } + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw( RuntimeException ); + Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw( RuntimeException ); + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(void) throw( RuntimeException ); + + // XSingleServiceFactory + Reference<XInterface> SAL_CALL createInstance(void) throw( Exception, RuntimeException ); + Reference<XInterface> SAL_CALL createInstanceWithArguments( + const Sequence<Any>& rArguments ) throw( Exception, RuntimeException ); +private: + + Reference<XMultiServiceFactory> mxSMgr; + Reference<XTypeConverter> xTypeConverter; + Reference<XIntrospection> xIntrospection; + Reference<XIdlReflection> xCoreReflection; +}; + +//-------------------------------------------------------------------------------------------------- +Any SAL_CALL InvocationService::queryInterface( const Type & aType ) + throw( RuntimeException ) +{ + // PropertySet-Implementation + Any a = cppu::queryInterface( aType, + SAL_STATIC_CAST(XSingleServiceFactory*, this), + SAL_STATIC_CAST(XServiceInfo*, this) ); + if( a.hasValue() ) + { + return a; + } + + return OWeakObject::queryInterface( aType ); +} + + +// XTypeProvider +Sequence< Type > SAL_CALL InvocationService::getTypes(void) throw( RuntimeException ) +{ + static OTypeCollection *pCollection = 0; + if( ! pCollection ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pCollection ) + { + static OTypeCollection collection( + getCppuType( (Reference< XSingleServiceFactory> * )0), + getCppuType( (Reference< XServiceInfo > * ) 0 ) ); + pCollection = &collection; + } + } + + return (*pCollection).getTypes(); +} + +Sequence< sal_Int8 > SAL_CALL InvocationService::getImplementationId( ) throw( RuntimeException) +{ + static OImplementationId *pId = 0; + if( ! pId ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( ! pId ) + { + static OImplementationId id( sal_False ); + pId = &id; + } + } + return (*pId).getImplementationId(); +} + +// // XIdlClassProvider +// Sequence< Reference<XIdlClass> > InvocationService::getIdlClasses(void) throw( RuntimeException ) +// { +// Sequence< Reference<XIdlClass> > aSeq( &getStaticIdlClass(), 1 ); +// return aSeq; +// } + + +// XServiceInfo +OUString InvocationService::getImplementationName() throw( RuntimeException ) +{ + return getImplementationName_Static(); +} + +// XServiceInfo +sal_Bool InvocationService::supportsService(const OUString& ServiceName) throw( RuntimeException ) +{ + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +// XServiceInfo +Sequence< OUString > InvocationService::getSupportedServiceNames(void) throw( RuntimeException ) +{ + return getSupportedServiceNames_Static(); +} + +// ORegistryServiceManager_Static +Sequence< OUString > InvocationService::getSupportedServiceNames_Static(void) throw( RuntimeException ) +{ + Sequence< OUString > aSNS( 1 ); + aSNS.getArray()[0] = OUString::createFromAscii( SERVICE_NAME ); + return aSNS; +} + +//-------------------------------------------------------------------------------------------------- +Reference<XInterface> InvocationService::createInstance(void) throw( Exception, RuntimeException ) +{ + //TODO:throw( Exception(OUString( RTL_CONSTASCII_USTRINGPARAM("no default construction of invocation adapter possible!")), *this) ); + return Reference<XInterface>(); // dummy +} + +//-------------------------------------------------------------------------------------------------- +Reference<XInterface> InvocationService::createInstanceWithArguments( + const Sequence<Any>& rArguments ) throw( Exception, RuntimeException ) +{ + if (rArguments.getLength() == 1) + { + return Reference< XInterface > + ( *new Invocation_Impl( *rArguments.getConstArray(), + xTypeConverter, xIntrospection, xCoreReflection ) ); + } + else + { + //TODO:throw( Exception(OUString( RTL_CONSTASCII_USTRINGPARAM("no default construction of invocation adapter possible!")), *this) ); + return Reference<XInterface>(); + } +} + + +//************************************************************************* +Reference<XInterface> SAL_CALL InvocationService_CreateInstance( const Reference<XMultiServiceFactory> & rSMgr ) + throw( RuntimeException ) +{ + Reference<XInterface> xService = Reference< XInterface > ( *new InvocationService( rSMgr ) ); + return xService; +} + +} + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString::createFromAscii( "/" IMPL_NAME "/UNO/SERVICES" ) ) ); + + const Sequence< OUString > & rSNL = + stoc_inv::InvocationService::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPL_NAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + stoc_inv::InvocationService_CreateInstance, + stoc_inv::InvocationService::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + diff --git a/stoc/source/invocation/makefile.mk b/stoc/source/invocation/makefile.mk new file mode 100644 index 000000000000..0980f71e65d9 --- /dev/null +++ b/stoc/source/invocation/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= inv +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + + +SLOFILES= \ + $(SLO)$/invocation.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + + diff --git a/stoc/source/invocation_adapterfactory/iafactory.cxx b/stoc/source/invocation_adapterfactory/iafactory.cxx new file mode 100644 index 000000000000..267d16ec501c --- /dev/null +++ b/stoc/source/invocation_adapterfactory/iafactory.cxx @@ -0,0 +1,760 @@ +/************************************************************************* + * + * $RCSfile: iafactory.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_INTERLOCK_H_ +#include <osl/interlck.h> +#endif + +#ifndef _UNO_DISPATCHER_H_ +#include <uno/dispatcher.h> +#endif +#ifndef _UNO_DATA_H_ +#include <uno/data.h> +#endif +#ifndef _UNO_ANY2_H_ +#include <uno/any2.h> +#endif +#ifndef _UNO_MAPPING_HXX_ +#include <uno/mapping.hxx> +#endif + +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE3_HXX_ +#include <cppuhelper/implbase3.hxx> +#endif + +#include <com/sun/star/uno/XAggregation.hpp> +#include <com/sun/star/script/XInvocationAdapterFactory.hpp> +#include <com/sun/star/script/XInvocationAdapterFactory2.hpp> +#include <com/sun/star/script/XInvocation.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/reflection/InvocationTargetException.hpp> + +using namespace cppu; +using namespace rtl; +using namespace osl; +using namespace com::sun::star::uno; +using namespace com::sun::star::script; +using namespace com::sun::star::reflection; +using namespace com::sun::star::registry; +using namespace com::sun::star::lang; + +#define SERVICENAME "com.sun.star.script.InvocationAdapterFactory" +#define IMPLNAME "com.sun.star.comp.stoc.InvocationAdapterFactory" + +namespace stoc_invadp +{ + +//-------------------------------------------------------------------------------------------------- +static inline Sequence< OUString > getSupportedServiceNames() +{ + OUString aName( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME ) ); + return Sequence< OUString >( &aName, 1 ); +} + +//================================================================================================== +class FactoryImpl + : public WeakImplHelper3< XServiceInfo, XInvocationAdapterFactory, XInvocationAdapterFactory2 > +{ + Mapping _aUno2Cpp; + Mapping _aCpp2Uno; + +public: + FactoryImpl(); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw (RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException); + + // XInvocationAdapterFactory + virtual Reference< XInterface > SAL_CALL createAdapter( + const Reference< XInvocation > & xReceiver, + const Type & rType ) throw (RuntimeException); + // XInvocationAdapterFactory2 + virtual Reference< XInterface > SAL_CALL createAdapter( + const Reference< XInvocation > & xReceiver, + const Sequence< Type > & rTypes ) throw (RuntimeException); +}; + +struct AdapterImpl; +//================================================================================================== +struct InterfaceAdapterImpl : public uno_Interface +{ + AdapterImpl * pAdapter; + typelib_InterfaceTypeDescription * pTypeDescr; +}; +//================================================================================================== +struct AdapterImpl +{ + oslInterlockedCount nRef; + uno_Interface * pReceiver; // XInvocation receiver + + sal_Int32 nInterfaces; + InterfaceAdapterImpl * pInterfaces; + + // XInvocation calls + void getValue( const typelib_TypeDescription * pMemberType, + void * pReturn, void * pArgs[], uno_Any ** ppException ); + void setValue( const typelib_TypeDescription * pMemberType, + void * pReturn, void * pArgs[], uno_Any ** ppException ); + void invoke( const typelib_TypeDescription * pMemberType, + void * pReturn, void * pArgs[], uno_Any ** ppException ); + + inline ~AdapterImpl(); + + static inline uno_Interface * createAdapter( + uno_Interface * pReceiver_, const Sequence< Type > & rTypes ); +}; + +//-------------------------------------------------------------------------------------------------- +inline static sal_Bool coerce_assign( + void * pDest, typelib_TypeDescription * pTD, uno_Any * pSource ) +{ + if (pSource->pType->eTypeClass != typelib_TypeClass_VOID) + { + if (pTD->eTypeClass == typelib_TypeClass_ANY) + return uno_assignData( pDest, pTD, pSource, pTD, 0, 0, 0 ); + else + return uno_type_assignData( pDest, pTD->pWeakRef, pSource->pData, pSource->pType, 0, 0, 0 ); + } + else + { + uno_constructData( pDest, pTD ); + return sal_True; + } +} + +//-------------------------------------------------------------------------------------------------- +static inline void copyUnoAny( uno_Any * pDest, uno_Any * pSource ) +{ + ::uno_type_any_construct( pDest, pSource->pData, pSource->pType, 0 ); +} +//-------------------------------------------------------------------------------------------------- +static inline void constructRuntimeException( uno_Any * pExc, const OUString & rMsg ) +{ + RuntimeException aExc; + aExc.Message = rMsg; + typelib_TypeDescription * pTD = 0; + const Type & rType = ::getCppuType( (const RuntimeException *)0 ); + // no conversion neeeded due to binary compatibility + no convertable type + ::uno_type_any_construct( pExc, &aExc, rType.getTypeLibType(), 0 ); +} + +//__________________________________________________________________________________________________ +void AdapterImpl::getValue( + const typelib_TypeDescription * pMemberType, + void * pReturn, void * pArgs[], uno_Any ** ppException ) +{ + // XInvocation type description + typelib_InterfaceTypeDescription * pInvocationTD = 0; + const Type & rIType = ::getCppuType( (const Reference< XInvocation > *)0 ); + TYPELIB_DANGER_GET( (typelib_TypeDescription **)&pInvocationTD, rIType.getTypeLibType() ); + // getValue() + typelib_InterfaceMethodTypeDescription * pInvokMethodTD = 0; + TYPELIB_DANGER_GET( (typelib_TypeDescription **)&pInvokMethodTD, pInvocationTD->ppMembers[3] ); + // attribute type + typelib_TypeDescription * pAttributeTD = 0; + TYPELIB_DANGER_GET( &pAttributeTD, ((typelib_InterfaceAttributeTypeDescription *)pMemberType)->pAttributeTypeRef ); + + uno_Any aInvokRet; + void * pInvokArgs[1]; + pInvokArgs[0] = &((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName; + uno_Any aInvokExc; + uno_Any * pInvokExc = &aInvokExc; + + // getValue() + (*pReceiver->pDispatcher)( + pReceiver, (typelib_TypeDescription *)pInvokMethodTD, + &aInvokRet, pInvokArgs, &pInvokExc ); + + if (pInvokExc) // getValue() call exception + { + copyUnoAny( *ppException, pInvokExc ); + uno_any_destruct( pInvokExc, 0 ); // cleanup + } + else // invocation call succeeded + { + uno_constructData( pReturn, pAttributeTD ); + if (coerce_assign( pReturn, pAttributeTD, &aInvokRet )) + { + *ppException = 0; // no exceptions be thrown + } + else // no assignment possible => throw runtime exception + { + uno_destructData( pReturn, pAttributeTD, 0 ); + constructRuntimeException( + *ppException, + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot coerce return type of attribute get call!") ) ); + } + uno_any_destruct( &aInvokRet, 0 ); + } + + TYPELIB_DANGER_RELEASE( pAttributeTD ); + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pInvokMethodTD ); + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pInvocationTD ); +} +//__________________________________________________________________________________________________ +void AdapterImpl::setValue( + const typelib_TypeDescription * pMemberType, + void * pReturn, void * pArgs[], uno_Any ** ppException ) +{ + // XInvocation type description + typelib_InterfaceTypeDescription * pInvocationTD = 0; + const Type & rIType = ::getCppuType( (const Reference< XInvocation > *)0 ); + TYPELIB_DANGER_GET( (typelib_TypeDescription **)&pInvocationTD, rIType.getTypeLibType() ); + // setValue() + typelib_InterfaceMethodTypeDescription * pInvokMethodTD = 0; + TYPELIB_DANGER_GET( (typelib_TypeDescription **)&pInvokMethodTD, pInvocationTD->ppMembers[2] ); + // attribute type + typelib_TypeDescription * pAttributeTD = 0; + TYPELIB_DANGER_GET( &pAttributeTD, ((typelib_InterfaceAttributeTypeDescription *)pMemberType)->pAttributeTypeRef ); + + uno_Any aInvokVal; + uno_any_construct( &aInvokVal, pArgs[0], pAttributeTD, 0 ); + + void * pInvokArgs[2]; + pInvokArgs[0] = &((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName; + pInvokArgs[1] = &aInvokVal; + uno_Any aInvokExc; + uno_Any * pInvokExc = &aInvokExc; + + // setValue() + (*pReceiver->pDispatcher)( + pReceiver, (typelib_TypeDescription *)pInvokMethodTD, + 0, pInvokArgs, &pInvokExc ); + + if (pInvokExc) // setValue() call exception + { + copyUnoAny( *ppException, pInvokExc ); + uno_any_destruct( pInvokExc, 0 ); // cleanup + } + else // invocation call succeeded + { + *ppException = 0; // no exceptions be thrown + } + + uno_any_destruct( &aInvokVal, 0 ); // cleanup + + TYPELIB_DANGER_RELEASE( pAttributeTD ); + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pInvokMethodTD ); + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pInvocationTD ); +} +//__________________________________________________________________________________________________ +void AdapterImpl::invoke( + const typelib_TypeDescription * pMemberType, + void * pReturn, void * pArgs[], uno_Any ** ppException ) +{ + // XInvocation type description + typelib_InterfaceTypeDescription * pInvocationTD = 0; + const Type & rIType = ::getCppuType( (const Reference< XInvocation > *)0 ); + TYPELIB_DANGER_GET( (typelib_TypeDescription **)&pInvocationTD, rIType.getTypeLibType() ); + // invoke() + typelib_InterfaceMethodTypeDescription * pInvokMethodTD = 0; + TYPELIB_DANGER_GET( (typelib_TypeDescription **)&pInvokMethodTD, pInvocationTD->ppMembers[1] ); + + sal_Int32 nParams = ((typelib_InterfaceMethodTypeDescription *)pMemberType)->nParams; + typelib_MethodParameter * pFormalParams = ((typelib_InterfaceMethodTypeDescription *)pMemberType)->pParams; + + // count in params + sal_Int32 nInParams = 0; + sal_Int32 nPos; + for ( nPos = nParams; nPos--; ) + { + if (pFormalParams[nPos].bIn) + ++nInParams; + } + + // in params + typelib_TypeDescription * pAnySeqTD = 0; + const Type & rAnyType = ::getCppuType( (const Sequence< Any > *)0 ); + TYPELIB_DANGER_GET( &pAnySeqTD, rAnyType.getTypeLibType() ); + uno_Sequence * pInParamsSeq = 0; + uno_sequence_construct( &pInParamsSeq, pAnySeqTD, 0, nInParams, 0 ); + + uno_Any * pInAnys = (uno_Any *)pInParamsSeq->elements; + typelib_TypeDescription * pAnyTD = 0; + TYPELIB_DANGER_GET( &pAnyTD, ((typelib_IndirectTypeDescription *)pAnySeqTD)->pType ); + sal_Int32 nInParamsPos = nInParams; + for ( nPos = nParams; nPos--; ) + { + typelib_MethodParameter & rParam = pFormalParams[nPos]; + if (rParam.bIn) + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, rParam.pTypeRef ); + // assignment to any never fails... + uno_assignData( &pInAnys[--nInParamsPos], pAnyTD, pArgs[nPos], pTD, 0, 0, 0 ); + TYPELIB_DANGER_RELEASE( pTD ); + } + } + + // out params, out indices + uno_Sequence * pOutIndices; + uno_Sequence * pOutParams; + // return + uno_Any aInvokRet; + // perform call + void * pInvokArgs[4]; + pInvokArgs[0] = &((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName; + pInvokArgs[1] = &pInParamsSeq; + pInvokArgs[2] = &pOutIndices; + pInvokArgs[3] = &pOutParams; + uno_Any aInvokExc; + uno_Any * pInvokExc = &aInvokExc; + + // invoke() call + (*pReceiver->pDispatcher)( + pReceiver, (typelib_TypeDescription *)pInvokMethodTD, + &aInvokRet, pInvokArgs, &pInvokExc ); + + if (pInvokExc) + { + OUString aInvokExcName( pInvokExc->pType->pTypeName ); + if (aInvokExcName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.reflection.InvocationTargetException") )) + { + // unwrap invocation target exception + copyUnoAny( *ppException, + &((InvocationTargetException *)pInvokExc->pData)->TargetException ); + } + else + { + // defer original exception to caller + copyUnoAny( *ppException, pInvokExc ); + } + uno_any_destruct( pInvokExc, 0 ); // cleanup + } + else // no invocation exception + { + typelib_TypeDescription * pShortSeqTD = 0; + const Type & rSeqShortType = ::getCppuType( (const Sequence< sal_Int16 > *)0 ); + TYPELIB_DANGER_GET( &pShortSeqTD, rSeqShortType.getTypeLibType() ); + + // write changed out params + OSL_ENSHURE( pOutParams->nElements == pOutIndices->nElements, "### out params lens differ!" ); + if (pOutParams->nElements == pOutIndices->nElements) + { + sal_Int16 * pIndices = (sal_Int16 *)pOutIndices->elements; + uno_Any * pOut = (uno_Any *)pOutParams->elements; + for ( nPos = 0; nPos < pOutIndices->nElements; ++nPos ) + { + sal_Int32 nIndex = pIndices[nPos]; + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, pFormalParams[nIndex].pTypeRef ); + OSL_ENSHURE( nIndex < nParams, "### illegal index!" ); + if (! pFormalParams[nIndex].bIn) // is pure out param + uno_constructData( pArgs[nIndex], pTD ); + if (! coerce_assign( pArgs[nIndex], pTD, &pOut[nPos] )) // if fail + { + // cleanup of out params + if (! pFormalParams[nIndex].bIn) // is pure out param + uno_destructData( pArgs[nIndex], pTD, 0 ); + TYPELIB_DANGER_RELEASE( pTD ); + for ( sal_Int32 n = 0; n < nPos; ++n ) + { + sal_Int32 nIndex = pIndices[n]; + pTD = 0; + TYPELIB_DANGER_GET( &pTD, pFormalParams[nIndex].pTypeRef ); + OSL_ENSHURE( nIndex < nParams, "### illegal index!" ); + uno_destructData( pArgs[nIndex], pTD, 0 ); + TYPELIB_DANGER_RELEASE( pTD ); + } + break; + } + TYPELIB_DANGER_RELEASE( pTD ); + } + if (nPos == pOutIndices->nElements) // out param copy ok; write return value + { + // return value + typelib_TypeDescription * pReturnTD = 0; + TYPELIB_DANGER_GET( &pReturnTD, ((typelib_InterfaceMethodTypeDescription *)pMemberType)->pReturnTypeRef ); + uno_constructData( pReturn, pReturnTD ); + if (coerce_assign( pReturn, pReturnTD, &aInvokRet )) + { + *ppException = 0; // no exception + } + else + { + uno_destructData( pReturn, pReturnTD, 0 ); + // set runtime exception + constructRuntimeException( + *ppException, + OUString( RTL_CONSTASCII_USTRINGPARAM("failed to coerce return type during invocation call!") ) ); + } + TYPELIB_DANGER_RELEASE( pReturnTD ); + } + else + { + // set runtime exception + constructRuntimeException( + *ppException, + OUString( RTL_CONSTASCII_USTRINGPARAM("failed to coerce parameter type during invocation call!") ) ); + } + } + else + { + // set runtime exception + constructRuntimeException( + *ppException, + OUString( RTL_CONSTASCII_USTRINGPARAM("out params lengths differ after invocation call!") ) ); + } + // cleanup invok out params + uno_destructData( &pOutIndices, pShortSeqTD, 0 ); + uno_destructData( &pOutParams, pAnySeqTD, 0 ); + // cleanup invok return value + uno_any_destruct( &aInvokRet, 0 ); + + TYPELIB_DANGER_RELEASE( pShortSeqTD ); + } + // cleanup constructed in params + uno_destructData( &pInParamsSeq, pAnySeqTD, 0 ); + TYPELIB_DANGER_RELEASE( pAnyTD ); + TYPELIB_DANGER_RELEASE( pAnySeqTD ); + + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pInvokMethodTD ); + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pInvocationTD ); +} + +//-------------------------------------------------------------------------------------------------- +static inline td_equals( + typelib_TypeDescription * pTD, typelib_TypeDescriptionReference * pType ) +{ + return (pTD->pWeakRef == pType || + (pTD->pTypeName->length == pType->pTypeName->length && + rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0)); +} + +extern "C" +{ +//__________________________________________________________________________________________________ +static void SAL_CALL adapter_acquire( uno_Interface * pUnoI ) +{ + ::osl_incrementInterlockedCount( + & static_cast< InterfaceAdapterImpl * >( pUnoI )->pAdapter->nRef ); +} +//__________________________________________________________________________________________________ +static void SAL_CALL adapter_release( uno_Interface * pUnoI ) +{ + AdapterImpl * pThis = static_cast< InterfaceAdapterImpl * >( pUnoI )->pAdapter; + if (! osl_decrementInterlockedCount( &pThis->nRef )) + { + delete pThis; + } +} +//__________________________________________________________________________________________________ +static void SAL_CALL adapter_dispatch( + uno_Interface * pUnoI, const typelib_TypeDescription * pMemberType, + void * pReturn, void * pArgs[], uno_Any ** ppException ) +{ + AdapterImpl * pThis = + static_cast< InterfaceAdapterImpl * >( pUnoI )->pAdapter; + + // query to emulated interface + switch (((typelib_InterfaceMemberTypeDescription *)pMemberType)->nPosition) + { + case 0: // queryInterface() + { + *ppException = 0; // no exc + typelib_TypeDescriptionReference * pDemanded = + *(typelib_TypeDescriptionReference **)pArgs[0]; + // pInterfaces[0] is XInterface + for ( sal_Int32 nPos = 0; nPos < pThis->nInterfaces; ++nPos ) + { + typelib_InterfaceTypeDescription * pTD = pThis->pInterfaces[nPos].pTypeDescr; + while (pTD) + { + if (td_equals( (typelib_TypeDescription *)pTD, pDemanded )) + { + uno_Interface * pUnoI = &pThis->pInterfaces[nPos]; + ::uno_any_construct( + (uno_Any *)pReturn, &pUnoI, (typelib_TypeDescription *)pTD, 0 ); + return; + } + pTD = pTD->pBaseTypeDescription; + } + } + ::uno_any_construct( (uno_Any *)pReturn, 0, 0, 0 ); // clear() + break; + } + case 1: // acquire() + *ppException = 0; // no exc + adapter_acquire( pUnoI ); + break; + case 2: // release() + *ppException = 0; // no exc + adapter_release( pUnoI ); + break; + + default: + { + if (pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD) // method + { + pThis->invoke( pMemberType, pReturn, pArgs, ppException ); + } + else // attribute + { + if (pReturn) + pThis->getValue( pMemberType, pReturn, pArgs, ppException ); + else + pThis->setValue( pMemberType, pReturn, pArgs, ppException ); + } + } + } +} +} + +//__________________________________________________________________________________________________ +inline uno_Interface * AdapterImpl::createAdapter( + uno_Interface * pReceiver_, const Sequence< Type > & rTypes ) +{ + AdapterImpl * pThis = new AdapterImpl(); + + pThis->nRef = 1; + + (*pReceiver_->acquire)( pReceiver_ ); + pThis->pReceiver = pReceiver_; + + pThis->nInterfaces = rTypes.getLength(); + pThis->pInterfaces = new InterfaceAdapterImpl[ rTypes.getLength() ]; + + const Type * pTypes = rTypes.getConstArray(); + for ( sal_Int32 nPos = rTypes.getLength(); nPos--; ) + { + InterfaceAdapterImpl * pInterface = &pThis->pInterfaces[nPos]; + + pInterface->pAdapter = pThis; + pInterface->pTypeDescr = 0; + pTypes[nPos].getDescription( (typelib_TypeDescription **)&pInterface->pTypeDescr ); + OSL_ASSERT( pInterface->pTypeDescr ); + // + pInterface->acquire = adapter_acquire; + pInterface->release = adapter_release; + pInterface->pDispatcher = adapter_dispatch; + } + + // returns XInterface + return &pThis->pInterfaces[0]; +} +//__________________________________________________________________________________________________ +inline AdapterImpl::~AdapterImpl() +{ + for ( sal_Int32 nPos = nInterfaces; nPos--; ) + { + ::typelib_typedescription_release( (typelib_TypeDescription *)pInterfaces[nPos].pTypeDescr ); + } + delete [] pInterfaces; + // + (*pReceiver->release)( pReceiver ); +} + +//__________________________________________________________________________________________________ +FactoryImpl::FactoryImpl() +{ + OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); + OUString aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ); + + _aUno2Cpp = Mapping( aUnoEnvTypeName, aCppEnvTypeName ); + _aCpp2Uno = Mapping( aCppEnvTypeName, aUnoEnvTypeName ); + OSL_ENSHURE( _aUno2Cpp.is() && _aCpp2Uno.is(), "### no uno / c++ mappings!" ); +} + +// XInvocationAdapterFactory +//__________________________________________________________________________________________________ +Reference< XInterface > FactoryImpl::createAdapter( + const Reference< XInvocation > & xReceiver, const Type & rType ) + throw (RuntimeException) +{ + return createAdapter( xReceiver, Sequence< Type >( &rType, 1 ) ); +} +// XInvocationAdapterFactory2 +//__________________________________________________________________________________________________ +Reference< XInterface > FactoryImpl::createAdapter( + const Reference< XInvocation > & xReceiver, const Sequence< Type > & rTypes ) + throw (RuntimeException) +{ + Reference< XInterface > xRet; + if (xReceiver.is() && rTypes.getLength()) + { + uno_Interface * pReceiver = (uno_Interface *)_aCpp2Uno.mapInterface( + xReceiver.get(), ::getCppuType( &xReceiver ) ); + if (pReceiver) + { + uno_Interface * pRet = AdapterImpl::createAdapter( pReceiver, rTypes ); + _aUno2Cpp.mapInterface( (void **)&xRet, pRet, ::getCppuType( &xRet ) ); + OSL_ASSERT( xRet.is() ); + (*pRet->release)( pRet ); + (*pReceiver->release)( pReceiver ); + } + } + return xRet; +} + +// XServiceInfo +//__________________________________________________________________________________________________ +OUString FactoryImpl::getImplementationName() + throw (RuntimeException) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ); +} +//__________________________________________________________________________________________________ +sal_Bool FactoryImpl::supportsService( const OUString & rServiceName ) + throw (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 > FactoryImpl::getSupportedServiceNames() + throw (RuntimeException) +{ + return stoc_invadp::getSupportedServiceNames(); +} + +//================================================================================================== +static Reference< XInterface > SAL_CALL FactoryImpl_create( + const Reference< XMultiServiceFactory > & xMgr ) + throw (Exception) +{ + return Reference< XInterface >( *new FactoryImpl() ); +} + +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) ); + + const Sequence< OUString > & rSNL = stoc_invadp::getSupportedServiceNames(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ), + stoc_invadp::FactoryImpl_create, + stoc_invadp::getSupportedServiceNames() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + diff --git a/stoc/source/invocation_adapterfactory/invadp.xml b/stoc/source/invocation_adapterfactory/invadp.xml new file mode 100644 index 000000000000..6085782ca0c0 --- /dev/null +++ b/stoc/source/invocation_adapterfactory/invadp.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE COMPONENTDESCRIPTION PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "componentdescription.dtd"> + +<COMPONENTDESCRIPTION + xmlns:xlink="http://www.w3.org/1999/xlink/Namespace" > + +<Author> Daniel Boelzle </Author> + +<Name> com.sun.star.comp.stoc.InvocationAdapterFactory </Name> + +<Description> +You can create adapter interfaces of any given type for an invocation +interface by using an adapter factory instance. +</Description> + +<ModuleName> invadp </ModuleName> + +<LoaderName> com.sun.star.loader.SharedLibrary </LoaderName> + +<Language> C++ </Language> + +<Status StatusValue="final"/> + +<SupportedService> com.sun.star.script.InvocationAdapterFactory </SupportedService> + +<ServiceDependency></ServiceDependency> + +<ProjectBuildDependency> cppuhelper </ProjectBuildDependency> +<ProjectBuildDependency> cppu </ProjectBuildDependency> +<ProjectBuildDependency> sal </ProjectBuildDependency> + +<RuntimeModuleDependency> cppuhelper </RuntimeModuleDependency> +<RuntimeModuleDependency> cppu </RuntimeModuleDependency> +<RuntimeModuleDependency> sal </RuntimeModuleDependency> + +<Type> com.sun.star.script.XInvocationAdapterFactory </Type> +<Type> com.sun.star.script.XInvocationAdapterFactory2 </Type> +<Type> com.sun.star.lang.XTypeProvider </Type> +<Type> com.sun.star.lang.XServiceInfo </Type> +<Type> com.sun.star.lang.XSingleServiceFactory </Type> +<Type> com.sun.star.lang.XMultiServiceFactory </Type> +<Type> com.sun.star.registry.XSimpleRegistry </Type> +<Type> com.sun.star.registry.XRegistryKey </Type> +<Type> com.sun.star.uno.XAggregation </Type> +<Type> com.sun.star.uno.XWeak </Type> +<Type> com.sun.star.uno.TypeClass </Type> +<Type> com.sun.star.container.XEnumerationAccess </Type> +<Type> com.sun.star.container.XNameContainer </Type> +<Type> com.sun.star.container.XIndexContainer </Type> +<Type> com.sun.star.reflection.InvocationTargetException </Type> + +</COMPONENTDESCRIPTION> + diff --git a/stoc/source/invocation_adapterfactory/makefile.mk b/stoc/source/invocation_adapterfactory/makefile.mk new file mode 100644 index 000000000000..f2d9bb52ef17 --- /dev/null +++ b/stoc/source/invocation_adapterfactory/makefile.mk @@ -0,0 +1,105 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME=stoc +TARGET=invadp +USE_DEFFILE=TRUE +NO_BSYMBOLIC=TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + + +SLOFILES= \ + $(SLO)$/iafactory.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/stoc/source/javaloader/javaloader.cxx b/stoc/source/javaloader/javaloader.cxx new file mode 100644 index 000000000000..139e7a4d57df --- /dev/null +++ b/stoc/source/javaloader/javaloader.cxx @@ -0,0 +1,674 @@ +/************************************************************************* + * + * $RCSfile: javaloader.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <string.h> + +#include <osl/diagnose.h> +#include <osl/interlck.h> + +#include <rtl/ustring> +#include <rtl/process.h> + +#include <uno/dispatcher.h> +#include <uno/environment.h> +#include <uno/mapping.h> +#include <uno/mapping.hxx> + +#include <cppuhelper/servicefactory.hxx> + +#include <com/sun/star/uno/Reference.hxx> + +#ifdef LINUX +#undef minor +#undef major +#endif +#include <com/sun/star/corba/giop/MessageHeader_1_1.hpp> + +#include <com/sun/star/bridge/XBridgeFactory.hpp> +#include <com/sun/star/bridge/XBridge.hpp> +#include <com/sun/star/bridge/XInstanceProvider.hpp> + +#include <com/sun/star/connection/XConnection.hpp> + +#include <com/sun/star/java/XJavaVM.hpp> +#include <com/sun/star/java/XJavaThreadRegister_11.hpp> + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <bridges/remote/context.h> +#include <bridges/remote/connection.h> +#include <bridges/remote/remote.h> + +#include "jni.h" + +#include <cppuhelper/factory.hxx> + +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> + +#include <com/sun/star/loader/XImplementationLoader.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +#include "jthreadpool.hxx" + +using namespace ::com::sun::star::bridge; +using namespace ::com::sun::star::connection; +using namespace ::com::sun::star::java; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::loader; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::io; + +using namespace ::cppu; +using namespace ::rtl; + +namespace loader { + class JVMThreadAttach { + JavaVM * _pJavaVM; + Reference<XJavaThreadRegister_11> _xJavaThreadRegister_11; + + public: + JNIEnv * _pJNIEnv; + + JVMThreadAttach(JavaVM * pJavaVM, XJavaThreadRegister_11 * pXJavaThreadRegister_11) throw (RuntimeException); + ~JVMThreadAttach() throw (RuntimeException); + }; + + JVMThreadAttach::JVMThreadAttach(JavaVM * pJavaVM, XJavaThreadRegister_11 * pXJavaThreadRegister_11) throw (RuntimeException) + : _pJNIEnv(NULL), + _pJavaVM(pJavaVM), + _xJavaThreadRegister_11(pXJavaThreadRegister_11) + { + pXJavaThreadRegister_11->registerThread(); + pJavaVM->AttachCurrentThread(&_pJNIEnv, NULL); + } + + JVMThreadAttach::~JVMThreadAttach() throw (RuntimeException) + { + _xJavaThreadRegister_11->revokeThread(); + if(!_xJavaThreadRegister_11->isThreadAttached()) + _pJavaVM->DetachCurrentThread(); + } + + + + struct ConnectionWrapper : public remote_Connection { + sal_Int32 _refCount; + + JavaVM * _pJavaVM; + XJavaThreadRegister_11 * _pXJavaThreadRegister_11; + + jclass _jcByteArray; + jmethodID _jmConnection_read; + jmethodID _jmConnection_write; + jmethodID _jmConnection_flush; + jmethodID _jmConnection_close; + jobject _joConnection; + + ConnectionWrapper(JavaVM * pJavaVM, XJavaThreadRegister_11 * pXJavaThreadRegister_11, jobject joConnection) throw(RuntimeException); + ~ConnectionWrapper() throw(RuntimeException); + + }; + + void SAL_CALL ConnectionWrapper_acquire(remote_Connection * blb) { + ++ ((ConnectionWrapper *)blb)->_refCount; + } + + void SAL_CALL ConnectionWrapper_release (remote_Connection * blb) { + if(!-- ((ConnectionWrapper *)blb)->_refCount) + delete (ConnectionWrapper *)blb; + } + + sal_Int32 SAL_CALL ConnectionWrapper_read(remote_Connection * blb, sal_Int8 *pDest, sal_Int32 nSize) { + ConnectionWrapper * pC = (ConnectionWrapper *)blb; + jint jiRes = -1; + + try { + JVMThreadAttach jvm(pC->_pJavaVM, pC->_pXJavaThreadRegister_11); + + try { + jobjectArray joDest = jvm._pJNIEnv->NewObjectArray(1, pC->_jcByteArray, 0); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 1"), Reference<XInterface>()); + jvm._pJNIEnv->SetObjectArrayElement(joDest, 0, jvm._pJNIEnv->NewByteArray(10)); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 2"), Reference<XInterface>()); + + jiRes = jvm._pJNIEnv->CallIntMethod(pC->_joConnection, pC->_jmConnection_read, joDest, (jint)nSize); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 3"), Reference<XInterface>()); + + jbyteArray jaDest = reinterpret_cast<jbyteArray>(jvm._pJNIEnv->GetObjectArrayElement(joDest, 0)); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 4"), Reference<XInterface>()); + + jbyte * pBytes = jvm._pJNIEnv->GetByteArrayElements(jaDest, NULL); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 5"), Reference<XInterface>()); + memcpy(pDest, pBytes, jiRes * sizeof(sal_Int8)); + jvm._pJNIEnv->ReleaseByteArrayElements(jaDest, pBytes, 0); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 6"), Reference<XInterface>()); + } + catch(RuntimeException & runtimeException) { + if(jvm._pJNIEnv->ExceptionOccurred()) { + jvm._pJNIEnv->ExceptionDescribe(); + jvm._pJNIEnv->ExceptionClear(); + } + + throw runtimeException; + } + } + catch(RuntimeException &) { + osl_trace("ConnectionWrapper_read - runtimeException occurred\n"); + jiRes = -1; + } + + return (sal_Int32)jiRes; + } + + sal_Int32 SAL_CALL ConnectionWrapper_write(remote_Connection * blb, const sal_Int8 *pSource, sal_Int32 nSize) { + ConnectionWrapper * pC = (ConnectionWrapper *)blb; + + try { + JVMThreadAttach jvm(pC->_pJavaVM, pC->_pXJavaThreadRegister_11); + + try { + jbyteArray jaSource = jvm._pJNIEnv->NewByteArray(nSize); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 7"), Reference<XInterface>()); + jbyte * pBytes = jvm._pJNIEnv->GetByteArrayElements(jaSource, NULL); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 8"), Reference<XInterface>()); + memcpy(pBytes, pSource, nSize * sizeof(jbyte)); + jvm._pJNIEnv->ReleaseByteArrayElements(jaSource, pBytes, 0); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 9"), Reference<XInterface>()); + + jvm._pJNIEnv->CallVoidMethod(pC->_joConnection, pC->_jmConnection_write, jaSource, (jint)nSize); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 10"), Reference<XInterface>()); + } + catch(RuntimeException & runtimeException) { + if(jvm._pJNIEnv->ExceptionOccurred()) { + jvm._pJNIEnv->ExceptionDescribe(); + jvm._pJNIEnv->ExceptionClear(); + } + + throw runtimeException; + } + } + catch(RuntimeException &) { + osl_trace("ConnectionWrapper_read - runtimeException occurred\n"); + nSize = -1; + } + + return nSize; + } + + void SAL_CALL ConnectionWrapper_flush(remote_Connection * blb) { + ConnectionWrapper * pC = (ConnectionWrapper *)blb; + + JVMThreadAttach jvm(pC->_pJavaVM, pC->_pXJavaThreadRegister_11); + jvm._pJNIEnv->CallVoidMethod(pC->_joConnection, pC->_jmConnection_flush); + if(jvm._pJNIEnv->ExceptionOccurred()) { + jvm._pJNIEnv->ExceptionDescribe(); + jvm._pJNIEnv->ExceptionClear(); + } + } + + void SAL_CALL ConnectionWrapper_close(remote_Connection * blb) { + ConnectionWrapper * pC = (ConnectionWrapper *)blb; + + JVMThreadAttach jvm(pC->_pJavaVM, pC->_pXJavaThreadRegister_11); + jvm._pJNIEnv->CallVoidMethod(pC->_joConnection, pC->_jmConnection_close); + if(jvm._pJNIEnv->ExceptionOccurred()) { + jvm._pJNIEnv->ExceptionDescribe(); + jvm._pJNIEnv->ExceptionClear(); + } + } + + ConnectionWrapper::ConnectionWrapper(JavaVM * pJavaVM, XJavaThreadRegister_11 * pXJavaThreadRegister_11, jobject joConnection) throw(RuntimeException) + : _refCount(0), + _pJavaVM(pJavaVM), + _pXJavaThreadRegister_11(pXJavaThreadRegister_11) + { + if(!pJavaVM || !pXJavaThreadRegister_11 || !joConnection) + throw RuntimeException(OUString::createFromAscii("hier 11"), Reference<XInterface>()); + + acquire = ConnectionWrapper_acquire; + release = ConnectionWrapper_release; + read = ConnectionWrapper_read; + write = ConnectionWrapper_write; + flush = ConnectionWrapper_flush; + close = ConnectionWrapper_close; + + JVMThreadAttach jvm(pJavaVM, pXJavaThreadRegister_11); + + _jcByteArray = jvm._pJNIEnv->FindClass("[B"); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 12"), Reference<XInterface>()); + _jcByteArray = reinterpret_cast<jclass>(jvm._pJNIEnv->NewGlobalRef(reinterpret_cast<jobject>(_jcByteArray))); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 13"), Reference<XInterface>()); + + jclass jcConnection = jvm._pJNIEnv->FindClass("com/sun/star/connection/XConnection"); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 14"), Reference<XInterface>()); + + _jmConnection_read = jvm._pJNIEnv->GetMethodID(jcConnection, "read", "([[BI)I"); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 15"), Reference<XInterface>()); +// _jmConnection_read = reinterpret_cast<jmethodID>(jvm._pJNIEnv->NewGlobalRef(reinterpret_cast<jobject>(_jmConnection_read))); + _jmConnection_write = jvm._pJNIEnv->GetMethodID(jcConnection, "write", "([B)V"); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 16"), Reference<XInterface>()); +// _jmConnection_write = reinterpret_cast<jmethodID>(jvm._pJNIEnv->NewGlobalRef(reinterpret_cast<jobject>(_jmConnection_write))); + _jmConnection_flush = jvm._pJNIEnv->GetMethodID(jcConnection, "flush", "()V"); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 17"), Reference<XInterface>()); +// _jmConnection_flush = reinterpret_cast<jmethodID>(jvm._pJNIEnv->NewGlobalRef(reinterpret_cast<jobject>(_jmConnection_flush))); + _jmConnection_close = jvm._pJNIEnv->GetMethodID(jcConnection, "close", "()V"); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 18"), Reference<XInterface>()); +// _jmConnection_close = reinterpret_cast<jmethodID>(jvm._pJNIEnv->NewGlobalRef(reinterpret_cast<jobject>(_jmConnection_close))); + + _joConnection = jvm._pJNIEnv->NewGlobalRef(joConnection); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 19"), Reference<XInterface>()); + } + + ConnectionWrapper::~ConnectionWrapper() throw(RuntimeException) { + JVMThreadAttach jvm(_pJavaVM, _pXJavaThreadRegister_11); + + jvm._pJNIEnv->DeleteGlobalRef(_joConnection); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 20"), Reference<XInterface>()); + + jvm._pJNIEnv->DeleteGlobalRef(reinterpret_cast<jobject>(_jmConnection_read)); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 21"), Reference<XInterface>()); + jvm._pJNIEnv->DeleteGlobalRef(reinterpret_cast<jobject>(_jmConnection_write)); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 22"), Reference<XInterface>()); + jvm._pJNIEnv->DeleteGlobalRef(reinterpret_cast<jobject>(_jmConnection_flush)); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 23"), Reference<XInterface>()); + jvm._pJNIEnv->DeleteGlobalRef(reinterpret_cast<jobject>(_jmConnection_close)); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 24"), Reference<XInterface>()); + + jvm._pJNIEnv->DeleteGlobalRef(_jcByteArray); if(jvm._pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 25"), Reference<XInterface>()); + } + + + + + class JavaComponentLoader : public WeakImplHelper2<XImplementationLoader, XServiceInfo> { + Reference<XMultiServiceFactory> _xSMgr; + Reference<XImplementationLoader> _javaLoader; + + uno_Environment * _pRemote_Environment; + protected: + JavaComponentLoader(const Reference<XMultiServiceFactory> & rXSMgr) throw(RuntimeException); + ~JavaComponentLoader(); + + public: + static const OUString implname; + static const OUString servname; + static Reference<XInterface> CreateInstance(const Reference<XMultiServiceFactory> & rSMgr) throw(Exception); + static Sequence<OUString> SAL_CALL getSupportedServiceNames_Static(); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence<OUString> SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // XImplementationLoader + virtual Reference<XInterface> SAL_CALL activate(const OUString& implementationName, const OUString& implementationLoaderUrl, const OUString& locationUrl, const Reference<XRegistryKey>& xKey) throw(CannotActivateFactoryException, RuntimeException); + virtual sal_Bool SAL_CALL writeRegistryInfo(const Reference<XRegistryKey>& xKey, const OUString& implementationLoaderUrl, const OUString& locationUrl) throw(CannotRegisterImplementationException, RuntimeException); + }; + + const OUString JavaComponentLoader::implname = L"com.sun.star.comp.stoc.JavaComponentLoader"; + const OUString JavaComponentLoader::servname = L"com.sun.star.loader.Java2"; + + Sequence<OUString> SAL_CALL JavaComponentLoader::getSupportedServiceNames_Static() { + return Sequence<OUString>(&servname, 1); + } + + + Reference<XInterface> SAL_CALL JavaComponentLoader::CreateInstance(const Reference<XMultiServiceFactory> & rSMgr) throw(Exception) + { + Reference<XInterface> xRet; + + try { + XImplementationLoader *pXLoader = (XImplementationLoader *)new JavaComponentLoader(rSMgr); + + xRet = Reference<XInterface>::query(pXLoader); + } + catch(RuntimeException & runtimeException) { + osl_trace("Could not init javaloader\n"); + OString message = OUStringToOString(runtimeException.Message, RTL_TEXTENCODING_ASCII_US); + fprintf(stderr, "exception: %s\n", (const char *)message); + } + + return xRet; + } + + JavaComponentLoader::JavaComponentLoader(const Reference<XMultiServiceFactory> & rSMgr) throw(RuntimeException) + : _pRemote_Environment(NULL) + { + Reference<XJavaVM> xJavaVM(rSMgr->createInstance(OUString::createFromAscii("com.sun.star.java.JavaVirtualMachine")), UNO_QUERY); + + Reference<XJavaThreadRegister_11> xJavaThreadRegister_11(xJavaVM, UNO_QUERY); + + JavaVM * pJavaVM; + + + Sequence<sal_Int8> processID(16); + rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8 *>(processID.getArray())); + + pJavaVM = *(JavaVM **)(xJavaVM->getJavaVM(processID).getValue()); +// pJavaVM = *reinterpret_cast<JavaVM **>(xJavaVM->getJavaVM(processID).getValue()); + + if(!pJavaVM) + throw RuntimeException(OUString::createFromAscii("hier -1"), Reference<XInterface>()); + + JNIEnv * pJNIEnv; + + pJavaVM->AttachCurrentThread(&pJNIEnv, (void *)NULL); + xJavaThreadRegister_11->registerThread(); + + if( ! javaloader_initNativeThreadPool( pJNIEnv, xJavaThreadRegister_11 ) ) + { + throw RuntimeException( + OUString::createFromAscii( "native threadpool couldn't be initialzed" ), + Reference< XInterface > () ); + } + + remote_Connection * pRemote_Connection = NULL; + + try { + jclass jcServiceManager = pJNIEnv->FindClass("com/sun/star/comp/servicemanager/ServiceManager"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 26"), Reference<XInterface>()); + jmethodID jmServiceManager_init = pJNIEnv->GetMethodID(jcServiceManager, "<init>", "()V"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 27"), Reference<XInterface>()); + jobject joServiceManager = pJNIEnv->NewObject(jcServiceManager, jmServiceManager_init); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 28"), Reference<XInterface>()); + + // we need to register the need services + static const char * neededServices[] = { + "com.sun.star.comp.servicemanager.ServiceManager", + "com.sun.star.comp.loader.JavaLoader", + "com.sun.star.lib.uno.bridges.java_remote.java_remote_bridge", + "com.sun.star.comp.connections.PipedConnection", + "com.sun.star.comp.connections.ConstantInstanceProvider" + }; + + + jclass jcString = pJNIEnv->FindClass("java/lang/String"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 29"), Reference<XInterface>()); + jobjectArray jaNeededServices = pJNIEnv->NewObjectArray(sizeof(neededServices) / sizeof(char *), jcString, NULL); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 30"), Reference<XInterface>()); + for(int i = 0; i < sizeof(neededServices) / sizeof(char *); ++ i) { + pJNIEnv->SetObjectArrayElement(jaNeededServices, i, pJNIEnv->NewStringUTF(neededServices[i])); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 31"), Reference<XInterface>()); + } + + jmethodID jmServiceManager_addFactories = pJNIEnv->GetMethodID(jcServiceManager, + "addFactories", + "([Ljava/lang/String;)V"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 32"), Reference<XInterface>()); + + pJNIEnv->CallVoidMethod(joServiceManager, jmServiceManager_addFactories, jaNeededServices); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 33"), Reference<XInterface>()); + + // + jmethodID jmServiceManager_createInstanceWithArguments = pJNIEnv->GetMethodID(jcServiceManager, + "createInstanceWithArguments", + "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 34"), Reference<XInterface>()); + + // create an instance of our special inprocess connection + jmethodID jmServiceManager_createInstance = pJNIEnv->GetMethodID(jcServiceManager, + "createInstance", + "(Ljava/lang/String;)Ljava/lang/Object;"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 35"), Reference<XInterface>()); + + jstring jsConnectionName = pJNIEnv->NewStringUTF("com.sun.star.connection.PipedConnection"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 36"), Reference<XInterface>()); + jobject joConnection_nativeSide = pJNIEnv->CallObjectMethod(joServiceManager, + jmServiceManager_createInstance, + jsConnectionName); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 37"), Reference<XInterface>()); + + jclass jcObject = pJNIEnv->FindClass("java/lang/Object"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 38"), Reference<XInterface>()); + jobjectArray jaArgs = pJNIEnv->NewObjectArray(1, jcObject, joConnection_nativeSide); + jobject joConnection_javaSide = pJNIEnv->CallObjectMethod(joServiceManager, + jmServiceManager_createInstanceWithArguments, + jsConnectionName, jaArgs); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 39"), Reference<XInterface>()); + + // create an constant service provider with java servicemanager + jstring jsInstanceProvider = pJNIEnv->NewStringUTF("com.sun.star.comp.connection.InstanceProvider"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 40"), Reference<XInterface>()); + jobject joInstanceProvider = pJNIEnv->CallObjectMethod(joServiceManager, + jmServiceManager_createInstance, + jsInstanceProvider); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 41"), Reference<XInterface>()); + + // create the bridge factory && the bridge + jaArgs = pJNIEnv->NewObjectArray(3, jcObject, NULL); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 42"), Reference<XInterface>()); + + pJNIEnv->SetObjectArrayElement(jaArgs, 0, pJNIEnv->NewStringUTF("iiop")); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 43"), Reference<XInterface>()); + pJNIEnv->SetObjectArrayElement(jaArgs, 1, joConnection_javaSide); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 44"), Reference<XInterface>()); + pJNIEnv->SetObjectArrayElement(jaArgs, 2, joInstanceProvider); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 45"), Reference<XInterface>()); + + jstring jsBridgeComponent = pJNIEnv->NewStringUTF("com.sun.star.bridge.Bridge"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 46"), Reference<XInterface>()); + jobject joBridge = pJNIEnv->CallObjectMethod(joServiceManager, + jmServiceManager_createInstanceWithArguments, + jsBridgeComponent, + jaArgs); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 47"), Reference<XInterface>()); + + pRemote_Connection = new ConnectionWrapper(pJavaVM, xJavaThreadRegister_11.get(), joConnection_nativeSide); + } + catch(RuntimeException & runtimeException) { + if(pJNIEnv->ExceptionOccurred()) { + pJNIEnv->ExceptionDescribe(); + pJNIEnv->ExceptionClear(); + } + + throw runtimeException; + } + + xJavaThreadRegister_11->revokeThread(); + if(!xJavaThreadRegister_11->isThreadAttached()) + pJavaVM->DetachCurrentThread(); + + + // + // everything is prepared to map an initial object from remote (java) to here + // + OString idStr("the id string"); + OString dcpStr("the description string"); + remote_Context * pRemote_Context = remote_createContext(pRemote_Connection, idStr.pData, dcpStr.pData, NULL); if(!pRemote_Connection) throw RuntimeException(OUString::createFromAscii("hier 48"), Reference<XInterface>()); + + uno_getEnvironment(&_pRemote_Environment, "remote", pRemote_Context); if(!_pRemote_Environment) throw RuntimeException(OUString::createFromAscii("hier 49"), Reference<XInterface>()); + + uno_Environment * pUNO_Environment = NULL; + uno_getEnvironment(&pUNO_Environment, "uno", NULL); if(!pUNO_Environment) throw RuntimeException(OUString::createFromAscii("hier 50"), Reference<XInterface>()); + + Mapping mapping(_pRemote_Environment, pUNO_Environment, OString()); + + + + OString remoteO("SERVICEMANAGER"); + + typelib_InterfaceTypeDescription *pType = 0; + getCppuType((Reference <XInterface> *) 0).getDescription((typelib_TypeDescription **) & pType) ; if(!pType) throw RuntimeException(OUString::createFromAscii("hier 51"), Reference<XInterface>()); + + remote_Interface *pRemoteI = 0; + + getCppuType( (::com::sun::star::corba::giop::MessageHeader_1_1*)0 ); + + + pRemote_Context->getRemoteInstance(_pRemote_Environment, + &pRemoteI, + remoteO.pData, + pType); if(!pRemoteI) throw RuntimeException(OUString::createFromAscii("hier 52"), Reference<XInterface>()); + + // got an interface ! + uno_Environment *pEnvCpp =0; + uno_getEnvironment(&pEnvCpp , CPPU_CURRENT_LANGUAGE_BINDING_NAME , 0); if(!pEnvCpp) throw RuntimeException(OUString::createFromAscii("hier 53"), Reference<XInterface>()); + + Mapping map(_pRemote_Environment , pEnvCpp); + + XInterface * pCppI = (XInterface *) map.mapInterface(pRemoteI, pType); if(!pCppI) throw RuntimeException(OUString::createFromAscii("hier 54"), Reference<XInterface>()); + + Reference<XInterface> rReturn = Reference<XInterface>(pCppI); + + Reference<XMultiServiceFactory> serviceManager(rReturn, UNO_QUERY); if(!serviceManager.is()) throw RuntimeException(OUString::createFromAscii("hier 55"), Reference<XInterface>()); + + Reference<XInterface> javaLoader_xInterface = + serviceManager->createInstance(OUString::createFromAscii("com.sun.star.loader.Java")); if(!javaLoader_xInterface.is()) throw RuntimeException(OUString::createFromAscii("hier 56"), Reference<XInterface>()); + _javaLoader = Reference<XImplementationLoader>(javaLoader_xInterface, UNO_QUERY); if(!_javaLoader.is()) throw RuntimeException(OUString::createFromAscii("hier 57"), Reference<XInterface>()); + _javaLoader->acquire(); + + Reference<XInitialization> javaLoader_xInit(javaLoader_xInterface, UNO_QUERY); + + Any any_smgr; + any_smgr <<= rSMgr; + javaLoader_xInit->initialize(Sequence<Any>(&any_smgr, 1)); + + + // important: release the context and the environments + + pCppI->release(); + pEnvCpp->release(pEnvCpp); + pRemoteI->release(pRemoteI); + + pUNO_Environment->release(pUNO_Environment); + pRemote_Context->aBase.release(reinterpret_cast<uno_Context *>(pRemote_Context)); + } + + + JavaComponentLoader::~JavaComponentLoader() { + if(_pRemote_Environment) + { + _pRemote_Environment->dispose(_pRemote_Environment); + _pRemote_Environment->release(_pRemote_Environment); + } + +// JVMThreadAttach jvm(pC->_pJavaVM, pC->_pXJavaThreadRegister_11); + +// try { +// jclass jcThreadPool = jvm._pJNIEnv->FindClass("com/sun/star/lib/uno/environments/remote/ThreadPool"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 1"), Reference<XInterface>()); +// jmethodID jmThreadPool_reset = jvm._pJNIEnv->GetMethodID(jcThreadPool, "reset", "()V"); if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUString::createFromAscii("hier 1"), Reference<XInterface>()); + +// jvm._pJNIEnv->CallStaticVoidMethod(jcThreadPool, jmThreadPool_reset); +// } +// catch( + } + + // XServiceInfo + OUString SAL_CALL JavaComponentLoader::getImplementationName() throw(::com::sun::star::uno::RuntimeException) { + return implname; + } + + sal_Bool SAL_CALL JavaComponentLoader::supportsService(const OUString & ServiceName) throw(::com::sun::star::uno::RuntimeException) { + sal_Bool bSupport = sal_False; + + Sequence<OUString> aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getArray(); + for(sal_Int32 i = 0; i < aSNL.getLength() && !bSupport; ++ i) + bSupport = pArray[i] == ServiceName; + + return bSupport; + } + + Sequence<OUString> SAL_CALL JavaComponentLoader::getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException) { + return getSupportedServiceNames_Static(); + } + + + + // XImplementationLoader + sal_Bool SAL_CALL JavaComponentLoader::writeRegistryInfo(const Reference<XRegistryKey> & xKey, const OUString & blabla, const OUString & rLibName) + throw(CannotRegisterImplementationException, RuntimeException) + { + sal_Bool bSuccess = sal_False; + + bSuccess = _javaLoader->writeRegistryInfo(xKey, blabla, rLibName); + + return bSuccess; + } + + + Reference<XInterface> SAL_CALL JavaComponentLoader::activate(const OUString & rImplName, + const OUString & blabla, + const OUString & rLibName, + const Reference<XRegistryKey> & xKey) + throw(CannotActivateFactoryException, RuntimeException) + { + return _javaLoader->activate(rImplName, blabla, rLibName, xKey); + } +} + + +extern "C" +{ + SAL_DLLEXPORT void SAL_CALL component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv) { + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; + } + + SAL_DLLEXPORT sal_Bool SAL_CALL component_writeInfo(XMultiServiceFactory * pServiceManager, XRegistryKey * pRegistryKey) { + sal_Bool bRes = sal_False; + + if (pRegistryKey) { + try { + OUString x = OUString::createFromAscii("/"); + x += ::loader::JavaComponentLoader::implname; + x += OUString::createFromAscii("/UNO/SERVICES"); + + Reference<XRegistryKey> xNewKey(pRegistryKey->createKey(x)); + + const Sequence<OUString> rSNL = ::loader::JavaComponentLoader::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for (sal_Int32 nPos = rSNL.getLength(); nPos--;) + xNewKey->createKey(pArray[nPos]); + + bRes = sal_True; + } + catch (InvalidRegistryException &) { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + + return bRes; + } + + SAL_DLLEXPORT void * SAL_CALL component_getFactory(const sal_Char * pImplName, XMultiServiceFactory * pServiceManager, XRegistryKey * pRegistryKey) { + void * pRet = 0; + + + OString xx(::loader::JavaComponentLoader::implname.getStr(), ::loader::JavaComponentLoader::implname.getLength(), RTL_TEXTENCODING_DONTKNOW); + if (pServiceManager && rtl_str_compare(pImplName, xx) == 0) + { + Reference<XSingleServiceFactory> xFactory(createOneInstanceFactory(pServiceManager, + OUString::createFromAscii(pImplName), + ::loader::JavaComponentLoader::CreateInstance, + ::loader::JavaComponentLoader::getSupportedServiceNames_Static())); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; + } +} + diff --git a/stoc/source/javaloader/makefile.mk b/stoc/source/javaloader/makefile.mk new file mode 100644 index 000000000000..df9ba3a8b9cd --- /dev/null +++ b/stoc/source/javaloader/makefile.mk @@ -0,0 +1,154 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=bridges +TARGET=javaloader +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +CPPUMAKERFLAGS += -C +UNOUCRDEP=$(SOLARBINDIR)$/applicat.rdb +UNOUCRRDB=$(SOLARBINDIR)$/applicat.rdb + +# output directory (one dir for each project) +UNOUCROUT=$(OUT)$/inc + +# adding to inludepath +INCPRE+=$(UNOUCROUT) + +UNOTYPES= \ + com.sun.star.corba.giop.MessageHeader_1_1 \ + com.sun.star.uno.TypeClass \ + com.sun.star.lang.XSingleServiceFactory \ + com.sun.star.lang.XMultiServiceFactory \ + com.sun.star.registry.XRegistryKey \ + com.sun.star.bridge.XBridgeFactory \ + com.sun.star.bridge.XBridge \ + com.sun.star.bridge.XInstanceProvider \ + com.sun.star.connection.XConnection \ + com.sun.star.java.XJavaVM \ + com.sun.star.java.XJavaThreadRegister_11 \ + com.sun.star.uno.XWeak \ + com.sun.star.uno.XAggregation \ + com.sun.star.lang.XTypeProvider \ + com.sun.star.loader.XImplementationLoader \ + com.sun.star.lang.XServiceInfo \ + com.sun.star.lang.XInitialization + +SLOFILES= $(SLO)$/javaloader.obj \ + $(SLO)$/jthreadpool.obj + +SHL1TARGET= $(TARGET) + +.IF "$(COM)" == "GCC" +REMOTE_CONTEXTLIB = -lrmcxt1 +.ELIF "$(COM)" == "C50" +REMOTE_CONTEXTLIB = -lrmcxt1 +.ELSE +REMOTE_CONTEXTLIB = irmcxt.lib +.ENDIF + +SHL1STDLIBS=\ + $(SALLIB)\ + $(VOSLIB)\ + $(CPPULIB)\ + $(CPPUHELPERLIB) \ + $(REMOTE_CONTEXTLIB) + + +SHL1LIBS=\ + $(SLB)$/$(TARGET).lib + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + + +$(MISC)$/$(SHL1TARGET).def: makefile.mk + @echo ------------------------------ + @echo Making: $@ + @echo LIBRARY $(SHL1TARGET) >$@ + @echo EXPORTS >>$@ + @echo component_getImplementationEnvironment >>$@ + @echo component_writeInfo >>$@ + @echo component_getFactory >>$@ + @echo Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_add >>$@ + @echo Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_createTicket >>$@ + @echo Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose >>$@ + @echo Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_reply >>$@ + @echo Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_request >>$@ + @echo Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_retrieve >>$@ + @echo Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_revoke >>$@ + @echo Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_stopDispose >>$@ + @echo Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_waitOnTicket >>$@ diff --git a/stoc/source/javavm/javavm.cxx b/stoc/source/javavm/javavm.cxx new file mode 100644 index 000000000000..163286e95070 --- /dev/null +++ b/stoc/source/javavm/javavm.cxx @@ -0,0 +1,1641 @@ +/************************************************************************* + * + * $RCSfile: javavm.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + + +#if STLPORT_VERSION < 321 +// #include <tools/presys.h> +#include <hash_map.h> +// #include <tools/postsys.h> +#else +#include <stl/vector> +#include <stl/hash_map> +#include <cstdarg> // std::va_list and friends +#endif + +//#include "jre.hxx" +#include <jni.h> +#include <time.h> +#ifdef UNX +#include <limits.h> +#define _MAX_PATH PATH_MAX +#endif + +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#include <cppuhelper/typeprovider.hxx> + +#ifndef _UNO_MAPPING_HXX_ +#include <uno/mapping.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring.hxx> +#endif +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif + +#ifndef _VOS_MUTEX_HXX_ +#include <vos/mutex.hxx> +#endif + +#ifndef _VOS_PROCESS_HXX_ +#include <vos/process.hxx> +#endif + +#ifndef _VOS_DIAGNOSE_H_ +#include <vos/diagnose.hxx> +#endif + +#ifndef _VOS_MODULE_HXX_ +#include <vos/module.hxx> +#endif + +#ifndef _VOS_THREAD_HXX_ +#include <vos/thread.hxx> +#endif + +#ifndef _VOS_CONDITN_HXX_ +#include <vos/conditn.hxx> +#endif + +#ifndef ___JSETTINGS +#include "settings.hxx" +#endif + +#ifndef _VOS_PROFILE_HXX_ +#include <vos/profile.hxx> +#endif + +#ifndef _OSL_FILE_HXX_ +#include <osl/file.hxx> +#endif + +// #ifndef _STRING_HXX +// #include <tools/string.hxx> +// #endif + +// #ifndef _ISOLANG_HXX +// #include <tools/isolang.hxx> +// #endif + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <com/sun/star/java/XJavaVM.hpp> +#include <com/sun/star/java/XJavaThreadRegister_11.hpp> +#include <com/sun/star/uno/Exception.hpp> + +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/InvalidRegistryException.hpp> +#include <com/sun/star/frame/XConfigManager.hpp> + +#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_ +#include <com/sun/star/uno/Sequence.hxx> +#endif + +#ifndef _RTL_PROCESS_H_ +#include <rtl/process.h> +#endif + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::java; +using namespace com::sun::star::registry; +using namespace com::sun::star::frame; +using namespace vos; +using namespace rtl; +using namespace cppu; +using namespace osl; + +#define UNRESOLVED_AWT_SYMBOLS +#if defined(SOLARIS) && defined (UNRESOLVED_AWT_SYMBOLS) +#include <dlfcn.h> +#endif +#if defined(LINUX) +#include <dlfcn.h> +#endif + +#if defined(OS2) +#define NOVMTHREAD +#endif + +#include "jvmargs.hxx" + +#if defined(WNT) || defined(OS2) +#define HAS_SETTINGS_FALLBACK +#endif + +#ifdef UNIX +#define INI_FILE "javarc" +#define SLASH_INI_FILE "/javarc" +#else +#define INI_FILE "java.ini" +#define SLASH_INI_FILE "/java.ini" +#endif + +#ifdef OS2 +#define JCALL JNICALL0 +#else +#define JCALL JNICALL +#endif + +//========================================================================= +static jint JCALL vm_vfprintf( FILE *fp, const char *format, va_list args ) +{ +#ifdef DEBUG + char buff[1024]; + + vsprintf( buff, format, args ); + + VOS_TRACE("%s", buff); + return strlen(buff); +#else + return 0; +#endif +} + +//========================================================================= + +static void JCALL vm_exit(jint code) +{ + VOS_TRACE("vm_exit: %d\n", code); +} + +static void JCALL vm_abort() +{ + VOS_TRACE("vm_abort\n"); +} + +class VMException : public Exception +{ + OUString errDescription; + sal_Int32 errNum; + +public: + VMException( sal_Int32 val ) + { + errNum = val; + errDescription = OUString::createFromAscii("error: #") + OUString::valueOf( val ); + } + + VMException( sal_Int32 val, const sal_Unicode* what ) + { + errNum = val; + errDescription = OUString::createFromAscii("error: #") + OUString::valueOf( val ) + OUString( what ); + } + + VMException( sal_Int32 val, const char* what ) + { + errNum = val; + errDescription = OUString::createFromAscii("error: #") + OUString::valueOf( val ) + OUString::createFromAscii( what ); + + } + + sal_Int32 getErrNum() + { + return errNum; + } + +/* virtual const sal_Unicode * what() const throw() + { + return errDescription.getStr(); + } +*/ + + virtual OUString what() const throw() + { + return OUString ( errDescription ); + } + +}; + +typedef ::std::hash_map +< + sal_uInt32, + sal_uInt32, + ::std::hash<sal_uInt32>, + ::std::equal_to<sal_uInt32> +> UINT32_UINT32_HashMap; + +struct JavaVirtualMachine_Mutex +{ + OMutex aMutex; +}; + +class JavaVirtualMachine_Impl; + +class OCreatorThread : public OThread +{ +private: + JavaVirtualMachine_Impl * pJavaVirtualMachine_Impl; + JAVAVM * pJVM; + + OCondition start_Condition; + OCondition wait_Condition; + + XSimpleRegistry* pJavaReg; + XSimpleRegistry* pSOfficeReg; + +protected: + virtual void SAL_CALL run(); + +public: + + OCreatorThread(JavaVirtualMachine_Impl * pJavaVirtualMachine_Impl); + JAVAVM * createJavaVM( XSimpleRegistry* pJavaReg, XSimpleRegistry* pSOfficeReg ); + void disposeJavaVM(); + +}; + +class JavaVirtualMachine_Impl : + public ::com::sun::star::java::XJavaVM, + public ::com::sun::star::java::XJavaThreadRegister_11, + public ::com::sun::star::lang::XServiceInfo, + public ::com::sun::star::lang::XTypeProvider, + public JavaVirtualMachine_Mutex, + public ::cppu::OWeakObject +{ +public: + int error; + + JavaVirtualMachine_Impl( const Reference< XMultiServiceFactory> & rSMgr ); + ~JavaVirtualMachine_Impl(); + + virtual Any SAL_CALL queryInterface( const Type & aType ) + throw( RuntimeException ); + virtual void SAL_CALL acquire() throw() + { OWeakObject::acquire(); } + virtual void SAL_CALL release() throw() + { OWeakObject::release(); } + + // XTypeProvider + virtual Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() + throw(RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() + throw( RuntimeException); + + // XJavaVM + virtual Any SAL_CALL getJavaVM( const Sequence<sal_Int8>& processID ) + throw(RuntimeException); + virtual sal_Bool SAL_CALL isVMStarted(void) + throw( RuntimeException); + virtual sal_Bool SAL_CALL isVMEnabled(void) + throw( RuntimeException); + + // XJavaThreadRegister_11 + virtual sal_Bool SAL_CALL isThreadAttached(void) + throw( RuntimeException); + virtual void SAL_CALL registerThread(void) + throw( RuntimeException); + virtual void SAL_CALL revokeThread(void) + throw( RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() + throw( RuntimeException); + virtual sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) + throw( RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(void) + throw( RuntimeException); + + + static OUString SAL_CALL getImplementationName_Static() + { + return OUString::createFromAscii("com.sun.star.comp.stoc.JavaVirtualMachine"); + } + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static() + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray()[0] = OUString::createFromAscii("com.sun.star.java.JavaVirtualMachine"); + return aSNS; + } + + JAVAVM * createJavaVM( XSimpleRegistry* pJavaReg, XSimpleRegistry* pSOfficeReg ); + void disposeJavaVM(); + +private: + void setError(int); + +#ifndef NOVMTHREAD + OCreatorThread creatorThread; +#endif + + OModule aJavaLib; + + JAVAVM * pJavaVM; /* denotes a Java VM */ + Reference<XMultiServiceFactory> xSMgr; + UINT32_UINT32_HashMap aRegisterdThreadMap; + + void readINetSection( XSimpleRegistry* pOfficeReg, JVM * pJVM ) throw (VMException); + void readJavaSection( XSimpleRegistry* pJavaReg, JVM * pJVM ); + void setLanguageAndCountrySection( XSimpleRegistry* pOfficeReg, JVM* pjvm ); + + sal_Bool getSettings( JSettings & rSettings, + const Reference<XRegistryKey> xRegistryKey ); + + OUString getJavaIniFileName( const Reference<XSimpleRegistry>& xSofficeReg, + const Reference<XConfigManager>& xConfigManager ); + +}; + +void JavaVirtualMachine_Impl::setError(int error) +{ + this->error = error; +} + +OCreatorThread::OCreatorThread( JavaVirtualMachine_Impl * pJavaVirtualMachine_Impl ) + : pJVM(NULL) +{ + this->pJavaVirtualMachine_Impl = pJavaVirtualMachine_Impl; +} + +void OCreatorThread::run() +{ + start_Condition.wait(); + start_Condition.reset(); + pJVM = pJavaVirtualMachine_Impl->createJavaVM( pJavaReg, pSOfficeReg ); + wait_Condition.set(); + +#if defined(WNT) || defined(OS2) + suspend(); + +#else + start_Condition.wait(); + start_Condition.reset(); + + if ( pJVM ) + { + pJavaVirtualMachine_Impl->disposeJavaVM(); + } + + wait_Condition.set(); +#endif +} + +JAVAVM * OCreatorThread::createJavaVM( XSimpleRegistry* pJavaReg, XSimpleRegistry* pSOfficeReg ) +{ + this->pJavaReg = pJavaReg; + this->pSOfficeReg = pSOfficeReg; + + create(); + + if ( !pJVM ) + { + start_Condition.set(); + + wait_Condition.wait(); + wait_Condition.reset(); + } + return pJVM; +} + +void OCreatorThread::disposeJavaVM() +{ + start_Condition.set(); // start disposing vm + +#ifdef UNX + wait_Condition.wait(); // wait until disposed + wait_Condition.reset(); +#endif +} + + +//************************************************************************* +// +// CLASS JAVA_VM IMPLEMENTATION +// + + +//************************************************************************* +// JavaVirtualMachine_Impl_CreateInstance() +static Reference< XInterface> SAL_CALL JavaVirtualMachine_Impl_createInstance( const Reference< XMultiServiceFactory> & rSMgr ) + throw (VMException) +{ + XJavaVM *pJVM= SAL_STATIC_CAST( XJavaVM*, new JavaVirtualMachine_Impl( rSMgr )); + return Reference<XInterface> ( SAL_STATIC_CAST( XInterface*, pJVM)); + +} + + + +Sequence< Type > SAL_CALL JavaVirtualMachine_Impl::getTypes(void) + throw( RuntimeException ) +{ + static OTypeCollection *pCollection = 0; + if ( ! pCollection ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if ( ! pCollection ) + { + static OTypeCollection collection( + getCppuType( (Reference < XTypeProvider > * ) 0 ), + getCppuType( (Reference < XJavaVM > * ) 0 ), + getCppuType( (Reference < XServiceInfo > *)0 ) , + getCppuType( (Reference < XJavaThreadRegister_11 > *) 0 ) ); + pCollection = &collection; + } + } + + return (*pCollection).getTypes(); +} + +Sequence< sal_Int8 > SAL_CALL JavaVirtualMachine_Impl::getImplementationId( ) + throw( RuntimeException ) +{ + static OImplementationId *pId = 0; + if ( ! pId ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if ( ! pId ) + { + static OImplementationId id( sal_False ); + pId = &id; + } + } + return (*pId).getImplementationId(); +} + +//*************************************************************************/ +// +Any SAL_CALL JavaVirtualMachine_Impl::queryInterface( const Type &aType ) + throw( RuntimeException ) + +{ + Any a = ::cppu::queryInterface( aType, + SAL_STATIC_CAST( XJavaVM * ,this), + SAL_STATIC_CAST( XServiceInfo *, this), + SAL_STATIC_CAST( XJavaThreadRegister_11 *, this ), + SAL_STATIC_CAST( XTypeProvider *, this) ); + if ( a.hasValue() ) + { + return a; + } + return OWeakObject::queryInterface( aType ); +} + +// XServiceInfo +OUString SAL_CALL JavaVirtualMachine_Impl::getImplementationName() + throw( RuntimeException ) +{ + return JavaVirtualMachine_Impl::getImplementationName_Static(); +} + +// XServiceInfo +sal_Bool SAL_CALL JavaVirtualMachine_Impl::supportsService( const OUString& ServiceName ) + throw( RuntimeException ) +{ + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + + for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if ( pArray[i] == ServiceName ) + return sal_True; + + return sal_False; +} + +// XServiceInfo +Sequence< OUString > SAL_CALL JavaVirtualMachine_Impl::getSupportedServiceNames() + throw( RuntimeException) +{ + return getSupportedServiceNames_Static(); +} + + +static OUString getValue( const Reference<XRegistryKey>& xRegistryRootKey, const OUString& rKey ) +{ + OUString aEntryValue; + + if ( xRegistryRootKey.is() && xRegistryRootKey->isValid() ) + { + try + { + Reference<XRegistryKey> aEntry = xRegistryRootKey->openKey( rKey ); + + if ( aEntry.is() && aEntry->isValid() ) + { + aEntryValue = aEntry->getStringValue(); + } + } + catch (InvalidRegistryException e) + { + } + catch (InvalidValueException e) + { + } + } + + return aEntryValue; +} + +JavaVirtualMachine_Impl::JavaVirtualMachine_Impl( const Reference<XMultiServiceFactory> & rSMgr) + : pJavaVM(NULL), + xSMgr(rSMgr), + error(0) +#ifndef NOVMTHREAD + , creatorThread(this) +#endif +{ +} + +JavaVirtualMachine_Impl::~JavaVirtualMachine_Impl() +{ + if ( pJavaVM ) + { +#ifndef NOVMTHREAD + creatorThread.disposeJavaVM(); +#else + disposeJavaVM(); +#endif + } +} + +// XJavaVM +Any JavaVirtualMachine_Impl::getJavaVM( const Sequence<sal_Int8> & processId ) throw (RuntimeException) +{ + OGuard aGuard( aMutex ); + + Sequence<sal_Int8> localProcessID(16); + rtl_getGlobalProcessId( (sal_uInt8*) localProcessID.getArray() ); + + if ( localProcessID == processId && !pJavaVM && !error ) + { + Reference<XInterface> xInterfaceRef_1( xSMgr->createInstance( OUString::createFromAscii("com.sun.star.config.SpecialConfigManager") ) ); + Reference<XSimpleRegistry> xSofficeReg(xInterfaceRef_1, UNO_QUERY); + + // now we try to open it + // sal_Char buffer[_MAX_PATH] = ""; + +// OUString aOfficeIni; +// OProfile::getProfileName( aOfficeIni, OUString::createFromAscii( "soffice" ), +// OUString::createFromAscii( STAROFFICE_SVERSION_KEY ) ); + + //OProfile::getProfileName( buffer, _MAX_PATH, 0, STAROFFICE_SVERSION_KEY ); + + try + { + // xSofficeReg->open( aOfficeIni, sal_True, sal_False ); + + if ( ! xSofficeReg->isValid() ) + { + InvalidRegistryException e; + e.Message = OUString::createFromAscii("can not open "); +// e.Message += aOfficeIni; + throw e; + } + } + catch ( InvalidRegistryException e ) + { + e.Message = OUString::createFromAscii("can not open "); +// e.Message += aOfficeIni; + throw e; + + } + + OUString aJavaIniFileName; + // get name for java.ini + if ( xSofficeReg.is() && xSofficeReg->isValid() ) + { + Reference<XConfigManager> xConfigManager( xInterfaceRef_1, UNO_QUERY ); + aJavaIniFileName = getJavaIniFileName( xSofficeReg, xConfigManager ); + } + + if ( ! aJavaIniFileName.len() ) // search the java.ini beneath the executable + { + aJavaIniFileName = OUString::createFromAscii( INI_FILE ); + } + + Reference<XInterface> xInterfaceRef_2( xSMgr->createInstance( + OUString::createFromAscii("com.sun.star.config.ConfigManager") ) ); + Reference<XSimpleRegistry> xJavaReg( xInterfaceRef_2, UNO_QUERY ); + + try + { + OUString tmpJavaIni; + File::getFileURLFromNormalizedPath( aJavaIniFileName, tmpJavaIni ); + xJavaReg->open( tmpJavaIni, sal_True, sal_False ); + + if ( xJavaReg->isValid() ) + { + sal_Bool bIsVMEnabled = sal_False; + + Reference<XRegistryKey> xJavaIni = xJavaReg->getRootKey(); + + OUString aEntryValue = getValue( xJavaIni, OUString::createFromAscii("Java/Java") ); + +#ifdef HAS_SETTINGS_FALLBACK + bIsVMEnabled = aEntryValue.len() == 0 || aEntryValue.compareToAscii("1") == 0; +#else + bIsVMEnabled = aEntryValue.len() > 0 && aEntryValue.compareToAscii("1") == 0; +#endif + + if ( bIsVMEnabled ) + { +#ifndef NOVMTHREAD + pJavaVM = creatorThread.createJavaVM( xJavaReg.get(), xSofficeReg.get() ); +#else + pJavaVM = createJavaVM( xJavaReg, xSofficeReg ); +#endif + } + + xJavaReg->close(); + } + else + { + InvalidRegistryException e; + e.Message = OUString::createFromAscii("can not open "); + e.Message += aJavaIniFileName; + throw e; + } + } + catch ( InvalidRegistryException e ) + { + e.Message = OUString::createFromAscii("can not open "); + e.Message += aJavaIniFileName; + throw e; + } + + // don't close soffice + // if ( xSofficeReg.is() && xSofficeReg->isValid() ) + // { + // xSofficeReg->close(); + // } + } + Any aRet; + if( sizeof( pJavaVM ) == sizeof( sal_Int32 ) ) + { + // 32 bit system + sal_Int32 nP = (sal_Int32)pJavaVM; + aRet <<= nP; + } + else if( sizeof( pJavaVM ) == sizeof( sal_Int64 ) ) + { + // 64 bit system + sal_Int64 nP = (sal_Int64)pJavaVM; + aRet <<= nP; + } + return aRet; +} + +// XJavaVM +sal_Bool JavaVirtualMachine_Impl::isVMStarted(void) + throw ( RuntimeException ) +{ + return pJavaVM != NULL; +} + +// XJavaVM +sal_Bool JavaVirtualMachine_Impl::isVMEnabled(void) + throw ( RuntimeException) +{ + Reference<XInterface> xInterfaceRef_1( xSMgr->createInstance( + OUString::createFromAscii("com.sun.star.config.SpecialConfigManager") ) ); + Reference<XSimpleRegistry> xSofficeReg( xInterfaceRef_1, UNO_QUERY ); + + // now we try to open it + // sal_Char buffer[_MAX_PATH] = ""; + // OProfile::getProfileName( buffer, _MAX_PATH, 0, STAROFFICE_SVERSION_KEY ); + +// OUString aOfficeIni; +// OProfile::getProfileName( aOfficeIni, OUString::createFromAscii( "soffice" ), +// OUString::createFromAscii( STAROFFICE_SVERSION_KEY ) ); + + try + { + // xSofficeReg->open( aOfficeIni, sal_True, sal_False ); + + if ( ! xSofficeReg->isValid() ) + { + InvalidRegistryException e; + e.Message = OUString::createFromAscii("can not open "); +// e.Message += aOfficeIni; + throw e; + } + } + catch ( InvalidRegistryException e ) + { + e.Message = OUString::createFromAscii("can not open "); +// e.Message += aOfficeIni; + throw e; + } + + OUString aJavaIniFileName; + // get name for java.ini + if ( xSofficeReg.is() && xSofficeReg->isValid() ) + { + Reference<XConfigManager> xConfigManager( xInterfaceRef_1, UNO_QUERY ); + aJavaIniFileName = getJavaIniFileName( xSofficeReg, xConfigManager ); + } + + if ( ! aJavaIniFileName.len() ) // search the java.ini beneath the executable + { + aJavaIniFileName = OUString::createFromAscii( INI_FILE ); + } + + Reference<XInterface> xInterfaceRef_2( xSMgr->createInstance( + OUString::createFromAscii("com.sun.star.config.ConfigManager") ) ); + Reference<XSimpleRegistry> xJavaReg( xInterfaceRef_2, UNO_QUERY ); + + try + { + xJavaReg->open( aJavaIniFileName, sal_True, sal_False ); + if ( xJavaReg->isValid() ) + { + Reference<XRegistryKey> xJavaIni = xJavaReg->getRootKey(); + OUString aEntryValue = getValue( xJavaIni, OUString::createFromAscii("Java/Java") ); + xJavaReg->close(); + +#ifdef HAS_SETTINGS_FALLBACK + return aEntryValue.len() == 0 || aEntryValue.compareToAscii("1") == 0; +#else + return aEntryValue.len() > 0 && aEntryValue.compareToAscii("1") == 0; +#endif + } + else + { + InvalidRegistryException e; + e.Message = OUString::createFromAscii("can not open "); + e.Message += aJavaIniFileName; + throw e; + } + + } + catch ( InvalidRegistryException e ) + { + e.Message = OUString::createFromAscii("can not open "); + e.Message += aJavaIniFileName; + throw e; + } + + return sal_False; +} + +// XJavaThreadRegister_11 +sal_Bool JavaVirtualMachine_Impl::isThreadAttached( void ) + throw ( RuntimeException) +{ + sal_Int32 nThreadID = OThread::getCurrentIdentifier(); + + // Mutex holen + OGuard aGuard(aMutex); + return aRegisterdThreadMap.end() != aRegisterdThreadMap.find(nThreadID); +} + +// XJavaThreadRegister_11 +void JavaVirtualMachine_Impl::registerThread(void) + throw ( RuntimeException) +{ + sal_Int32 nThreadID = OThread::getCurrentIdentifier(); + + // Mutex holen + OGuard aGuard(aMutex); + + UINT32_UINT32_HashMap::iterator aIt = aRegisterdThreadMap.find(nThreadID); + + if ( aIt == aRegisterdThreadMap.end() ) + aRegisterdThreadMap[nThreadID] = 1; + else + (*aIt).second++; +} + +// XJavaThreadRegister_11 +void JavaVirtualMachine_Impl::revokeThread(void) + throw ( RuntimeException) +{ + sal_Int32 nThreadID = OThread::getCurrentIdentifier(); + + // Mutex holen + OGuard aGuard(aMutex); + + UINT32_UINT32_HashMap::iterator aIt = aRegisterdThreadMap.find(nThreadID); + VOS_ASSERT( aIt != aRegisterdThreadMap.end() ); + if ( aIt != aRegisterdThreadMap.end() ) + { + if ( 0 == --((*aIt).second) ) + aRegisterdThreadMap.erase( nThreadID ); + } +} + +sal_Bool JavaVirtualMachine_Impl::getSettings( JSettings& rSettings, const Reference<XRegistryKey> xRegistryRootKey) +{ + char * pJavaDebug = getenv( "STAR_JAVADEBUG" ); + sal_Bool bSettingsOk = sal_False; + + + if (pJavaDebug) + { + rSettings.setDebug( sal_True ); + rSettings.setDebugPort( atoi(pJavaDebug) ); + } + + if ( rSettings.getDebug() && pJavaDebug ) + { + char * pClassPath = getenv ("CLASSPATH"); + + if (pClassPath) + rSettings.classPath = OUString::createFromAscii( pClassPath ); + } + + + OUString aDebug = getValue( xRegistryRootKey, OUString::createFromAscii("Java/Debug") ); + + if ( aDebug.len() && aDebug.compareToAscii("1") == 0 ) + rSettings.setDebug(sal_True); + + OUString aJavaVmHome = getValue( xRegistryRootKey, OUString::createFromAscii("Java/Home") ); + +// fprintf(stderr, "#### GetSettings: home - %s\n", OUStringToOString(aJavaVmHome, CHARSET_SYSTEM).GetStr()); + OUString aJavaVmVersion = getValue( xRegistryRootKey, OUString::createFromAscii("Java/Version") ); + OUString aJavaVmName = getValue( xRegistryRootKey, OUString::createFromAscii("Java/RuntimeLib") ); + +// fprintf(stderr, "JavaVirtualMachine_Impl::getSettings: %s\n", aJavaVmName.getStr()); + + rSettings.setRuntimeLib( aJavaVmName ); + + if ( aJavaVmName.len() ) + bSettingsOk = GetVmNameSettings( rSettings, aJavaVmName, aJavaVmVersion, rSettings.getDebug() ); + if ( !bSettingsOk && aJavaVmHome.len() ) + bSettingsOk = GetVmHomeSettings( rSettings, aJavaVmHome, aJavaVmVersion, rSettings.getDebug() ); + if ( !bSettingsOk ) + bSettingsOk = GetDefaultSettings( rSettings, aJavaVmVersion, rSettings.getDebug() ); + + OUString aEntryValue; + + aEntryValue = getValue( xRegistryRootKey, OUString::createFromAscii("Java/RuntimeLib") ); + + if ( aEntryValue.len() ) + rSettings.setRuntimeLib( aEntryValue ); + + aEntryValue = getValue( xRegistryRootKey, OUString::createFromAscii("Java/SystemClasspath") ); + + if ( aEntryValue.len() ) + rSettings.classPath = aEntryValue; + + aEntryValue = getValue( xRegistryRootKey, OUString::createFromAscii("Java/UserClasspath") ); + + if ( aEntryValue.len() ) + { +#ifdef UNX + // #68287# Semikolona to colon + sal_Int32 tokenCount = aEntryValue.getTokenCount(); + OUString path; + + for ( sal_Int32 i = 0; i < tokenCount; ++i ) + { + if ( path.len() ) + path += OUString::createFromAscii(":"); + + path += aEntryValue.getToken(i); + } + + aEntryValue = path; +#endif + rSettings.classPath = rSettings.classPath + OUString(ENV_DEL) + aEntryValue; + } + + return bSettingsOk; +} + +#ifdef SOLARIS +#include <sys/utsname.h> +/* getSolarisRelease + * make a single integer from solaris release string + */ + +int getSolarisRelease() +{ + struct utsname aRelease; + static int nRelease = 0; + + if ( nRelease != 0 ) + { + /* computed once, returned many */ + return nRelease; + } + else + if ( uname( &aRelease ) > -1 ) + { + int nTokens; + int nMajor, nMinor, nMMinor; + + /* release will be something like 5.5.1 or 5.6 */ + nTokens = sscanf(aRelease.release, "%i.%i.%i\n", + &nMajor, &nMinor, &nMMinor ); + + switch ( nTokens ) + { + case 0: nMajor = 0; + /* fall thru */ + case 1: nMinor = 0; + /* fall thru */ + case 2: nMMinor = 0; + break; + case 3: + default: + /* 3 tokens cannot match more than 3 times */ + break; + } + + /* will be something like 551 or 560, dont expect a minor release + * number larger than 9 */ + nRelease = nMajor * 100 + nMinor * 10 + nMMinor; + + /* okay, the paranoic case */ + if ( nRelease == 0 ) + nRelease = -1; + } + else + { + /* never saw uname fail, but just in case + * (must be very old solaris) */ + nRelease = -1; + } + + return nRelease; +} +#endif + +#ifdef UNX +static OUString preOpen( sal_Bool bDebug, + const OUString & usLibraryPath, + const OUString & usRuntimeLib, + const OUString & rCompiler) +{ + //**************************************************************************************/ + // now try to load the java lib ********************************************************/ + + OUString usCompiler = rCompiler; + char * error = NULL; + + dlerror(); // CLEAR + +#if defined(LINUX) + + OString sRuntime = OUStringToOString( usLibraryPath + usRuntimeLib, RTL_TEXTENCODING_ASCII_US ); + dlopen( sRuntime.getStr(), RTLD_LAZY | RTLD_GLOBAL ); + error = dlerror(); + + if (error) throw VMException( -1, error ); + + if (bDebug) + { + OString sAgent = OUStringToOString(usLibraryPath, RTL_TEXTENCODING_ASCII_US) + "libagent_g.so"; + + void *handle = dlopen( sAgent.getStr(), RTLD_GLOBAL | RTLD_LAZY); + error = dlerror(); + if (error) throw VMException( -2, error ); + } +#endif // LINUX + +// String sLibZip = OUStringToOString( usLibraryPath + OUString::createFromAscii("libzip.so") ); +// void * libzipso = dlopen(sLibZip.GetStr(), RTLD_LAZY | RTLD_GLOBAL); +// error = dlerror(); +// if (error) +// fprintf (stderr, "preOpen - %s: %s\n", sLibZip.GetStr(), error); + + +#if defined(SOLARIS) && defined(UNRESOLVED_AWT_SYMBOLS) + OString sRuntime = OUStringToOString(usLibraryPath + usRuntimeLib, RTL_TEXTENCODING_ASCII_US); + + if ( !dlopen(sRuntime.getStr(), RTLD_LAZY | RTLD_GLOBAL) ) + { + error = dlerror(); + throw VMException( -3, error ); + } + + void* libJITHandel; + + if ( ! usCompiler.equalsIgnoreCase( OUString::createFromAscii("NONE") ) ) + { +#if defined(INTEL) + OUString preopen; + if ( usCompiler.len() ) + usCompiler = OUString::createFromAscii("sunwjit"); + + preopen = OUString::createFromAscii("lib") + usCompiler + OUString::createFromAscii(".so"); + OString sAgent = OUStringToOString( usLibraryPath + preopen, RTL_TEXTENCODING_ASCII_US ); + libJITHandel = dlopen(sAgent.getStr(), RTLD_GLOBAL | RTLD_LAZY); + +#elif defined(SPARC) + int release = getSolarisRelease(); + OUString preopen; + + if ( release < 560 ) + { // seems to be solaris 2.5.x or less + //fprintf(stderr, "seems to be solaris 2.5.x\n"); + + if ( usCompiler.len() ) + { // enable JIT only if recommendet by user (entry in sofficerc) + preopen = OUString::createFromAscii("lib") + usCompiler + OUString::createFromAscii(".so"); + OString sAgent = OUStringToOString(preopen, RTL_TEXTENCODING_ASCII_US); + //fprintf(stderr, "TRY to open %s\n", sAgent.GetStr()); + libJITHandel = dlopen(sAgent.getStr(), RTLD_GLOBAL | RTLD_LAZY); + } + else + { + //fprintf(stderr, "no compiler set: set to NONE"); + usCompiler = OUString::createFromAscii("NONE"); + } + } + else + { + //fprintf(stderr, "seems to be solaris 2.6.x\n"); + + if ( !usCompiler.len() ) + { + usCompiler = OUString::createFromAscii("sunwjit"); + preopen = OUString::createFromAscii("libjit.so"); + } + else + preopen = OUString::createFromAscii("lib") + usCompiler + OUString::createFromAscii(".so"); + + OString sJIT = OUStringToOString( preopen, RTL_TEXTENCODING_ASCII_US ); + + libJITHandel = dlopen(sJIT.getStr(), RTLD_GROUP | RTLD_LAZY); + } + +#endif // SPARC + if ( !usCompiler.equalsIgnoreCase( OUString::createFromAscii("NONE") ) ) + { +// error = dlerror(); + +// if (error) +// fprintf (stderr, "preopen JIT DLL: %s\n", error); + +// if ( libJITHandel == NULL ) +// usCompiler = OUString::createFromAscii("NONE"; + } + } +#endif + return usCompiler; +} +#endif // UNX + + +inline sal_Bool IsEqualToAscii( const OUString & rString, const sal_Char* anotherString ) +{ + return rString.compareToAscii( anotherString ) == 0; +} + +void JavaVirtualMachine_Impl::readJavaSection( XSimpleRegistry* pJavaReg, JVM* pjvm ) +{ + sal_Bool bSetDefaultToolkit = sal_True; + sal_Bool bSetDefaultTKTLib = sal_True; + + //if ( pJavaReg->isValid() ) + //{ + // try + // { + Reference<XRegistryKey> xJavaSection = pJavaReg->getRootKey()->openKey( OUString::createFromAscii("Java") ); + + if ( xJavaSection.is() && xJavaSection->isValid() ) + { + Sequence< OUString > aJavaProperties = xJavaSection->getKeyNames(); + OUString* pSectionEntry = aJavaProperties.getArray(); + sal_Int32 nCount = aJavaProperties.getLength(); + + for ( sal_Int32 i=0; i<nCount; i++ ) + { + OUString aEntryValue = ( xJavaSection->openKey( pSectionEntry[i] ))->getStringValue(); + + if ( !pSectionEntry[i].len() ) + ; + else if ( pSectionEntry[i] == OUString::createFromAscii("Debug") ) + pjvm->setDebug( IsEqualToAscii( aEntryValue, "1" ) ); + else if ( IsEqualToAscii(pSectionEntry[i], "Java") ) + ; + else if ( IsEqualToAscii(pSectionEntry[i], "Version") ) + ; + else if ( IsEqualToAscii(pSectionEntry[i], "Home") ) + ; + else if ( IsEqualToAscii(pSectionEntry[i], "SystemClasspath") ) + ; + else if ( IsEqualToAscii(pSectionEntry[i], "awt.toolkit") ) + { + bSetDefaultToolkit = sal_False; + + pjvm->pushProp( pSectionEntry[i] + OUString::createFromAscii("=") + aEntryValue ); + } + else if ( IsEqualToAscii(pSectionEntry[i], "java.compiler") ) + pjvm->setCompiler( aEntryValue ); + + else if ( IsEqualToAscii(pSectionEntry[i], "DisableAsyncGC") ) + pjvm->disableAsyncGC(IsEqualToAscii( aEntryValue, "1") ); + + else if ( IsEqualToAscii(pSectionEntry[i], "EnableClassGC") ) + pjvm->enableClassGC(IsEqualToAscii(aEntryValue, "0") ); + + else if ( IsEqualToAscii(pSectionEntry[i], "EnableVerboseGC") ) + pjvm->enableVerboseGC(IsEqualToAscii(aEntryValue, "1") ); + + else if ( IsEqualToAscii(pSectionEntry[i], "Verbose") ) + pjvm->verbose(IsEqualToAscii(aEntryValue, "1") ); + + else if ( pSectionEntry[i] == OUString::createFromAscii("NativeStackSize") ) + pjvm->nativeStackSize( aEntryValue.toInt32() ); + + else if ( IsEqualToAscii(pSectionEntry[i], "JavaStackSize") ) + pjvm->javaStackSize( aEntryValue.toInt32() ); + + else if ( IsEqualToAscii(pSectionEntry[i], "VerifyMode") ) + pjvm->verifyMode( aEntryValue ); + + else if ( IsEqualToAscii(pSectionEntry[i], "MinHeapSize") ) + pjvm->minHeapSize( aEntryValue.toInt32() ); + + else if ( IsEqualToAscii(pSectionEntry[i], "MaxHeapSize") ) + pjvm->maxHeapSize( aEntryValue.toInt32() ); + + else if ( IsEqualToAscii(pSectionEntry[i], "DebugPort") ) + pjvm->setDebugPort( aEntryValue.toInt32() ); + else + { + if ( aEntryValue.len() ) + pSectionEntry[i] = pSectionEntry[i] + OUString::createFromAscii("=") + aEntryValue; + + pjvm->pushProp( pSectionEntry[i] ); + } + } + } + else + { + InvalidRegistryException e; + e.Message = OUString::createFromAscii("no Java Section found"); + throw e; + } +} + +void JavaVirtualMachine_Impl::setLanguageAndCountrySection( XSimpleRegistry* pOfficeReg, JVM* pjvm ) +{ +// TEMPORARY DISABLED +// OUString aValue; + +// Reference<XRegistryKey> xRegistryRootKey = pOfficeReg->getRootKey(); +// aValue = getValue( xRegistryRootKey, OUString::createFromAscii("User/Language") ); + +// if ( aValue.len() ) +// { +// OUString aLanguage; +// OUString aCountry; + +// // LanguageType aLangNum = (LanguageType) String( OUStringToOString( aValue, RTL_TEXTENCODING_ASCII_US) ); +// LanguageType aLangNum = (LanguageType) aValue.toInt32(); + +// { +// String langStr; +// String countryStr; + +// ConvertLanguageToIsoNames( aLangNum, langStr, countryStr ); + +// aLanguage = OUString( langStr ); +// aCountry = OUString( countryStr ); +// } + +// if ( aLanguage.getLength() ) pjvm->pushProp( OUString::createFromAscii("user.language=") + aLanguage ); + +// if ( aCountry.getLength() ) pjvm->pushProp( OUString::createFromAscii("user.region=") + aCountry ); +// } +} + +void JavaVirtualMachine_Impl::readINetSection( XSimpleRegistry* pOfficeReg, JVM* pjvm ) throw (VMException) +{ + Reference<XRegistryKey> xRegistryRootKey = pOfficeReg->getRootKey(); + + // HTTPProxyHost, HTTPProxyPort, FTPProxyHost, FTPProxyPort + // Reading proxy and port values in the INet section + + OUString aValue; + + // HTTPProxy + aValue = getValue( xRegistryRootKey, OUString::createFromAscii("INet/HTTPProxy") ); + if ( aValue.len() ) pjvm->pushProp( OUString::createFromAscii("http.proxyHost=") + aValue ); + + // HTTPProxyPort + aValue = getValue( xRegistryRootKey, OUString::createFromAscii("INet/HTTPProxyPort") ); + if ( aValue.len() ) pjvm->pushProp( OUString::createFromAscii("http.proxyPort=") + aValue ); + + // FTPPProxy + aValue = getValue( xRegistryRootKey, OUString::createFromAscii("INet/FTPProxy" ) ); + if ( aValue.len() ) pjvm->pushProp( OUString::createFromAscii("ftpProxyHost=") + aValue ); + + // FTPProxyPort + aValue = getValue( xRegistryRootKey, OUString::createFromAscii("INet/FTPProxyPort" ) ); + if ( aValue.len() ) pjvm->pushProp( OUString::createFromAscii("FTPProxyPort=") + aValue ); +} + +static void initSJSettings( JNIEnv * pJNIEnv ) throw (VMException) +{ + // init SjSettings -> SecurityManager + jclass jcSjSettings = pJNIEnv->FindClass("stardiv/controller/SjSettings"); + if (!jcSjSettings) throw VMException( -9, "Can't find class \"stardiv/controller/SjSettings\"." ); + + jmethodID jmChangeProperties = pJNIEnv->GetStaticMethodID( jcSjSettings , "changeProperties", "(Ljava/util/Properties;)V" ); + if ( !jmChangeProperties ) throw VMException( -9, "Can't find method \"changeProperties\" of class \"stardiv/controller/SjSettingss\"." ); + + pJNIEnv->CallStaticVoidMethod( jcSjSettings, jmChangeProperties, NULL ); + + if ( pJNIEnv->ExceptionOccurred() ) + { + pJNIEnv->ExceptionClear(); + throw VMException( -9, "An exception occured when calling method \"changeProperties\" of class \"stardiv/controller/SjSettingss\"."); + } +} + + +static void setTimeZone( JVM * pjvm ) +{ + /* A Bug in the Java function + ** struct Hjava_util_Properties * java_lang_System_initProperties( + ** struct Hjava_lang_System *this, + ** struct Hjava_util_Properties *props); + ** This function doesn't detect MEZ, MET or "W. Europe Standard Time" + */ + struct tm *tmData; + time_t clock = time(NULL); + tzset(); + tmData = localtime(&clock); + char * p = tzname[0]; +#ifdef WNT + if ( OString( "MET" ) == p ) +#else + if ( OString( "MEZ" ) == p ) +#endif + { + pjvm->pushProp( OUString::createFromAscii("user.timezone=ECT") ); + } +} + +static void setVMLibraryPath(const OString & usLibraryPath, JNIEnv * pJNIEnv) +{ + // setzte den privaten LD_LIBRARY_PATH an java.lang.Runtime + jclass jcRuntime = pJNIEnv->FindClass("java/lang/Runtime"); if (pJNIEnv->ExceptionOccurred()) return; + jmethodID jmGetRuntime = pJNIEnv->GetStaticMethodID(jcRuntime, + "getRuntime", + "()Ljava/lang/Runtime;"); if (pJNIEnv->ExceptionOccurred()) return; + jobject joRuntime = pJNIEnv->CallStaticObjectMethod(jcRuntime, jmGetRuntime); if (pJNIEnv->ExceptionOccurred()) return; + + jfieldID jfPaths = pJNIEnv->GetFieldID(jcRuntime, "paths", "[Ljava/lang/String;"); if (pJNIEnv->ExceptionOccurred()) return; + +// jstring jsJavaLibPath = pJNIEnv->NewStringUTF(usLibraryPath.GetStr()); if (pJNIEnv->ExceptionOccurred()) return; + jstring jsJavaLibPath = pJNIEnv->NewStringUTF(usLibraryPath); if (pJNIEnv->ExceptionOccurred()) return; + jstring jsOfficeLibPath = pJNIEnv->NewStringUTF(""); if (pJNIEnv->ExceptionOccurred()) return; + + + jclass jcString = pJNIEnv->FindClass("java/lang/String"); if (pJNIEnv->ExceptionOccurred()) return; + jarray jaPaths = pJNIEnv->NewObjectArray(2, jcString, NULL); if (pJNIEnv->ExceptionOccurred()) return; + pJNIEnv->SetObjectArrayElement((jobjectArray)jaPaths, 0, jsJavaLibPath); if (pJNIEnv->ExceptionOccurred()) return; + pJNIEnv->SetObjectArrayElement((jobjectArray)jaPaths, 1, jsOfficeLibPath); if (pJNIEnv->ExceptionOccurred()) return; + + pJNIEnv->SetObjectField(joRuntime, jfPaths, jaPaths); if (pJNIEnv->ExceptionOccurred()) return; +} + +#ifdef UNX +#include <limits.h> +#define _MAX_PATH PATH_MAX +#endif + +/* +static OUString pathExpansion() +{ + OUString aClassPath; + + // Application home + char buf[_MAX_PATH]; + if ( OStartupInfo::E_None == OStartupInfo().getExecutableFile(buf, _MAX_PATH ) ) + { + OString aPath = buf; + sal_Int16 nPos = aPath.getLength(); + if ( nPos ) + { + while ( nPos-- && aPath[nPos] != PATH_DEL[0] ); + + +// #ifdef UNX +// // cut /bin too +// while( nPos-- && aPath[nPos] != PATH_DEL[0] ) +// ; +// #endif + +// aPath.Erase( nPos ); + aPath= aPath.copy( 0, nPos+1); // last character is the path delimiter + } + + OUString aAppHome = OUString::createFromAscii( aPath ); + // classpath is set by the java INI + // aClassPath += ENV_DEL + aAppHome + OUString::createFromAscii("classes") + PATH_DEL + OUString::createFromAscii("classes.jar"); + // aClassPath += ENV_DEL + aAppHome + OUString::createFromAscii("classes") + PATH_DEL + OUString::createFromAscii("sandbox.jar"); + } + + return aClassPath; +} +*/ + +JAVAVM * JavaVirtualMachine_Impl::createJavaVM( XSimpleRegistry* pJavaReg, XSimpleRegistry* pOfficeReg) +{ + try + { + JSettings aSettings; + + try + { + Reference<XRegistryKey> xJavaIni( pJavaReg->getRootKey(), UNO_QUERY ); + + // test if Java is enabled + OUString aEntryValue = getValue( xJavaIni, OUString::createFromAscii("Java/Java") ); + + if ( aEntryValue.len() == 0 || aEntryValue == OUString::createFromAscii("0") ) throw VMException( -4, "Can't find entry \"Java\" in section \"Java\"."); + if ( ! getSettings( aSettings, xJavaIni ) ) throw VMException( -5, "An exception occured while reading JVM settings."); + +#ifdef UNX + OUString usCompiler = getValue( xJavaIni, OUString::createFromAscii("Java/java.compiler") ); + + if ( usCompiler.len() != 0 ) + aSettings.setCompiler( usCompiler ); + + aSettings.setCompiler(preOpen( aSettings.getDebug(), + aSettings.getLibraryPath(), + aSettings.getRuntimeLib(), + aSettings.getCompiler() + ) + ); +#endif + + sal_Bool bLoaded = aJavaLib.load( aSettings.getLibraryPath() + aSettings.getRuntimeLib() ); + + if ( !bLoaded ) + { + throw VMException( -6, OUString::createFromAscii("can't load ") + + aSettings.getLibraryPath() + + aSettings.getRuntimeLib() ); + } + + JNI_InitArgs_Type * initArgs = (JNI_InitArgs_Type *) aJavaLib.getSymbol(OUString::createFromAscii("JNI_GetDefaultJavaVMInitArgs")); + + if ( !initArgs ) throw VMException( -7, "can't load symbol \"JNI_GetDefaultJavaVMInitArgs\"." ); + + JVM jvm(initArgs); + readJavaSection( pJavaReg, &jvm ); + + if ( aSettings.getCompiler().len() ) + { + jvm.setCompiler( aSettings.getCompiler() ); + } + + // read out the INet section in the soffice.ini / sofficerc + readINetSection( pOfficeReg, &jvm ); + setLanguageAndCountrySection( pOfficeReg, &jvm ); + + // security settings + jvm.pushProp( OUString::createFromAscii("stardiv.security.defaultSecurityManager=true") ); + jvm.pushProp( OUString::createFromAscii("stardiv.security.noExit=true") ); + jvm.pushProp( OUString::createFromAscii("stardiv.controller.installConsole=true") ); + + OUString aClassPath( aSettings.classPath ); + //aClassPath = aClassPath + pathExpansion(); + + jvm.classPath( OUStringToOString(aClassPath, RTL_TEXTENCODING_ASCII_US) ); + + jvm.abort(vm_abort); + jvm.exit(vm_exit); + jvm.vfprintf(vm_vfprintf); + + setTimeZone( &jvm ); + + JNI_CreateVM_Type * pCreateJavaVM = (JNI_CreateVM_Type *) aJavaLib.getSymbol( OUString::createFromAscii("JNI_CreateJavaVM") ); + if ( !pCreateJavaVM ) throw VMException( -8, "Can't load symbol \"JNI_CreateJavaVM\"." ); + + JNIEnv * pJNIEnv = NULL; + jint err = pCreateJavaVM( &pJavaVM, &pJNIEnv, (void *)jvm.getJDK1_1InitArgs() ); + + if ( err ) throw VMException( -9, "Can't create Java VM" ); + + initSJSettings( pJNIEnv ); + + } + catch ( InvalidRegistryException e ) + { + } + } + catch ( VMException e ) + { + setError( e.getErrNum() ); + fprintf(stderr, "error - could not load java, cause %s.", e.what()); + } + + return pJavaVM; +} + +void JavaVirtualMachine_Impl::disposeJavaVM() +{ + if ( pJavaVM ) + { +// pJavaVM->DestroyJavaVM(); + pJavaVM = NULL; + } +} + +OUString JavaVirtualMachine_Impl::getJavaIniFileName( const Reference<XSimpleRegistry>& xSofficeReg, + const Reference<XConfigManager>& xConfigManager ) +{ + OUString iniFileName; + sal_Bool bIniFound = sal_False; + + if ( xSofficeReg.is() && xSofficeReg->isValid() ) + { + Reference<XRegistryKey> xRegistryRootKey = xSofficeReg->getRootKey(); + + if ( xRegistryRootKey.is() && xRegistryRootKey->isValid() ) + { + try + { + ::osl::DirectoryItem aJavaIni; + + try + { + OUString tmpFileName; + OUString fileName; + tmpFileName = getValue( xRegistryRootKey, OUString::createFromAscii("Directories/UserConfig-Path") ); + tmpFileName = xConfigManager->substituteVariables( tmpFileName ); + + File::normalizePath( tmpFileName, fileName ); + fileName += OUString::createFromAscii(SLASH_INI_FILE); + bIniFound = DirectoryItem::get( fileName, aJavaIni ) == FileBase::E_None; + + } + catch ( Exception e ) + { + bIniFound = sal_False; + } + + if ( !bIniFound ) + { + OUString tmpFileName; + OUString fileName; + tmpFileName = getValue( xRegistryRootKey, OUString::createFromAscii("Directories/Config-Dir") ); + tmpFileName = xConfigManager->substituteVariables( tmpFileName ); + + File::normalizePath( tmpFileName, fileName ); + fileName += OUString::createFromAscii(SLASH_INI_FILE); + bIniFound = DirectoryItem::get( fileName, aJavaIni ) == FileBase::E_None; + } + + if ( bIniFound ) + { + FileStatus fileStatus( FileStatusMask_FilePath /*FileStatusMask_NativePath*/ ); + + if ( FileBase::E_None == aJavaIni.getFileStatus( fileStatus ) ) + iniFileName = fileStatus.getFilePath(); + //iniFileName = fileStatus.getNativePath(); + else + bIniFound = sal_False; + } + + } + catch (Exception e) + { + bIniFound = sal_False; + } + } + } + + if ( ! bIniFound ) + { + iniFileName = OUString::createFromAscii(""); + } + + return iniFileName; +} + +// *************************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString::createFromAscii("/") + + JavaVirtualMachine_Impl::getImplementationName_Static() + + OUString::createFromAscii("/UNO/SERVICES" )) ); + + const Sequence< OUString > & rSNL = + JavaVirtualMachine_Impl::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if ( JavaVirtualMachine_Impl::getImplementationName_Static().equals(OUString::createFromAscii(pImplName)) ) + { + Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + JavaVirtualMachine_Impl::getImplementationName_Static(), + JavaVirtualMachine_Impl_createInstance, + JavaVirtualMachine_Impl::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} + +#ifdef __cplusplus +} // END of extern "C" +#endif + diff --git a/stoc/source/javavm/jen.xml b/stoc/source/javavm/jen.xml new file mode 100644 index 000000000000..02624e740613 --- /dev/null +++ b/stoc/source/javavm/jen.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE COMPONENTDESCRIPTION PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "componentdescription.dtd"> + +<COMPONENTDESCRIPTION + xmlns:xlink="http://www.w3.org/1999/xlink/Namespace" > + +<Author> Juergen Schmidt </Author> + +<Name> com.sun.star.comp.stoc.JavaVirtualMachine </Name> + +<Description> + This component provides ... +</Description> + +<ModuleName> jen </ModuleName> + +<LoaderName> com.sun.star.loader.SharedLibrary </LoaderName> + +<Language> c++ </Language> + +<Status StatusValue="final"/> + +<SupportedService> com.sun.star.java.JavaVirtualMachine </SupportedService> + +<ServiceDependency> ... </ServiceDependency> + +<ProjectBuildDependency> cppuhelper </ProjectBuildDependency> +<ProjectBuildDependency> cppu </ProjectBuildDependency> +<ProjectBuildDependency> tools </ProjectBuildDependency> +<ProjectBuildDependency> vos </ProjectBuildDependency> +<ProjectBuildDependency> sal </ProjectBuildDependency> + +<RuntimeModuleDependency> cppuhelper </RuntimeModuleDependency> +<RuntimeModuleDependency> cppu1 </RuntimeModuleDependency> +<RuntimeModuleDependency> tl(COM) </RuntimeModuleDependency> +<RuntimeModuleDependency> vos1$(COM) </RuntimeModuleDependency> +<RuntimeModuleDependency> sal1 </RuntimeModuleDependency> + +<Type> com.sun.star.java.XJavaVM </Type> +<Type> com.sun.star.java.XJavaVM </Type> +<Type> com.sun.star.java.XJavaThreadRegister_11 </Type> +<Type> com.sun.star.frame.XConfigManager </Type> +<Type> com.sun.star.container.XNameAccess </Type> +<Type> com.sun.star.lang.XTypeProvider </Type> +<Type> com.sun.star.lang.XServiceInfo </Type> +<Type> com.sun.star.lang.XSingleServiceFactory </Type> +<Type> com.sun.star.lang.XMultiServiceFactory </Type> +<Type> com.sun.star.registry.XSimpleRegistry </Type> +<Type> com.sun.star.uno.XAggregation </Type> +<Type> com.sun.star.uno.XWeak </Type> +<Type> com.sun.star.uno.TypeClass </Type> + +</COMPONENTDESCRIPTION> + diff --git a/stoc/source/javavm/jvmargs.cxx b/stoc/source/javavm/jvmargs.cxx new file mode 100644 index 000000000000..8c28679e8e0d --- /dev/null +++ b/stoc/source/javavm/jvmargs.cxx @@ -0,0 +1,303 @@ +/************************************************************************* + * + * $RCSfile: jvmargs.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "jvmargs.hxx" + + +JVM::JVM(JNI_InitArgs_Type * pVMInitArgs) + : debug(sal_False) +{ + /* + ** The following is used to specify that we require at least + ** JNI version 1.1. Currently, this field is not checked but + ** will be starting with JDK/JRE 1.2. The value returned after + ** calling JNI_GetDefaultJavaVMInitArgs() is the actual JNI version + ** supported, and is always higher that the requested version. + */ + + + jDK1_1InitArgs.version = JNI_VERSION_1_1; + pVMInitArgs(&jDK1_1InitArgs); + + javaVMInitArgs.nOptions = 0; + javaVMInitArgs.options = NULL; + jiDebugPort = 1199; +} + +JVM::~JVM() +{ + if(javaVMInitArgs.options) + { + for(size_t i = 0; i < javaVMInitArgs.nOptions; i++) + { + free(javaVMInitArgs.options[i].optionString); + } + + free(javaVMInitArgs.options); + javaVMInitArgs.nOptions = 0; + javaVMInitArgs.options = NULL; + } + + size_t i = 0; + if(jDK1_1InitArgs.properties) + { + while(jDK1_1InitArgs.properties[i]) + free(jDK1_1InitArgs.properties[i ++]); + + free(jDK1_1InitArgs.properties); + } +} + +void JVM::pushPProp(OUString uString, void * extraInfo) +{ + JavaVMOption javaVMOption; + + javaVMOption.optionString = strdup(OUStringToOString(uString, RTL_TEXTENCODING_ASCII_US)); + javaVMOption.extraInfo = extraInfo; + + p_props.push_back(javaVMOption); +} + +void JVM::pushProp(const OUString & uString) +{ + props.push_back(uString); +} + +void JVM::disableAsyncGC(jboolean jbFlag) +{ + jDK1_1InitArgs.disableAsyncGC = jbFlag; +} + +void JVM::enableClassGC(jboolean jbFlag) +{ + jDK1_1InitArgs.enableClassGC = jbFlag; + if(!jbFlag) + { + OUString tmpStr( RTL_CONSTASCII_USTRINGPARAM("-Xnoclassgc") ); + pushPProp(tmpStr); + } +} + +void JVM::enableVerboseGC(jboolean jbFlag) +{ + jDK1_1InitArgs.enableVerboseGC = jbFlag; + pushPProp( OUString(RTL_CONSTASCII_USTRINGPARAM("-verbose:gc"))); +} + +void JVM::verbose(jboolean jbFlag) +{ + jDK1_1InitArgs.verbose = jbFlag; + pushPProp(OUString(RTL_CONSTASCII_USTRINGPARAM("-verbose:class"))); +} + +void JVM::nativeStackSize(jint jiSize) +{ + jDK1_1InitArgs.nativeStackSize = jiSize; +} + +void JVM::javaStackSize(jint jiSize) +{ + jDK1_1InitArgs.javaStackSize = jiSize; +} + +void JVM::verifyMode(OUString uStr) +{ + pushPProp( OUString(RTL_CONSTASCII_USTRINGPARAM("-Xverify:")) + uStr ); + + if( uStr.compareToAscii("none") == 0 ) + jDK1_1InitArgs.verifyMode = 0; + else if( uStr.compareToAscii("remote") == 0) + jDK1_1InitArgs.verifyMode = 1; + else if( uStr.compareToAscii("all") == 0 ) + jDK1_1InitArgs.verifyMode = 2; +} + +void JVM::minHeapSize(jint jiSize) +{ + // Workaround ! Der neue Wert wird nur uebernommen, wenn dieser ueber dem + // DefaultSize ( 1 MB ) liegt. Ein zu kleiner initialer HeapSize f’hrt unter Solaris Sparc zum Deadlock. + if(jiSize > (sal_uInt32) jDK1_1InitArgs.minHeapSize) + jDK1_1InitArgs.minHeapSize = jiSize; + + pushPProp( OUString(RTL_CONSTASCII_USTRINGPARAM("-Xms")) + OUString::valueOf((sal_Int32) jiSize) ); +} + +void JVM::maxHeapSize(jint jiSize) +{ + jDK1_1InitArgs.maxHeapSize = jiSize; + pushPProp( OUString(RTL_CONSTASCII_USTRINGPARAM("-Xmx")) + OUString::valueOf((sal_Int32)jiSize) ); +} + +void JVM::setDebug(sal_Bool flag) +{ + fprintf(stderr, "#### JVM::setDebug: %d\n", flag); + debug = flag; +} + +sal_Bool JVM::getDebug() +{ + return debug; +} + +void JVM::setDebugPort(jint jiPort) +{ + jiDebugPort = jiPort; +} + +void JVM::setCompiler(const OUString & usCompiler) +{ + this->usCompiler = usCompiler; +} + +OUString JVM::getCompiler() +{ + return usCompiler; +} + +void JVM::classPath( OString str ) +{ +// jDK1_1InitArgs.classpath = strdup(str.GetStr()); + jDK1_1InitArgs.classpath = strdup(str); + pushPProp( OUString(RTL_CONSTASCII_USTRINGPARAM("java.class.path=")) + OStringToOUString(str, RTL_TEXTENCODING_ASCII_US ) ); +} + +void JVM::vfprintf(JNIvfprintf vfprintf) +{ + jDK1_1InitArgs.vfprintf = vfprintf; + pushPProp( OUString(RTL_CONSTASCII_USTRINGPARAM("vfprintf")), (void *)vfprintf ); +} + +void JVM::exit(JNIexit exit) +{ + jDK1_1InitArgs.exit = exit; + pushPProp( OUString(RTL_CONSTASCII_USTRINGPARAM("exit")), (void *)exit ); +} + +void JVM::abort(JNIabort abort) +{ + jDK1_1InitArgs.abort = abort; + pushPProp( OUString(RTL_CONSTASCII_USTRINGPARAM("abort=")), (void *)abort ); +} + + +const JDK1_1InitArgs * JVM::getJDK1_1InitArgs() +{ + if( usCompiler.getLength() ) + pushProp( OUString(RTL_CONSTASCII_USTRINGPARAM("java.compiler=")) + usCompiler); + + if(debug) + { + jDK1_1InitArgs.debugging = JNI_TRUE; + jDK1_1InitArgs.debugPort = jiDebugPort; + pushPProp( OUString(RTL_CONSTASCII_USTRINGPARAM("-Xdebug")), &jiDebugPort); + } + + if(!jDK1_1InitArgs.properties) + { + size_t size = props.size() + 1; + jDK1_1InitArgs.properties = (char **) calloc(sizeof(const char *), props.size() + 1); + + for(size_t i = 0; i < props.size(); i++) + { + OUString str = props[i]; + + jDK1_1InitArgs.properties[i] = strdup( OUStringToOString(str, RTL_TEXTENCODING_ASCII_US) ); + } + + jDK1_1InitArgs.properties[props.size()] = NULL; + } + + return &jDK1_1InitArgs; +} + +const JavaVMInitArgs * JVM::getJavaVMInitArgs() +{ + if(usCompiler.getLength()) + pushProp( OUString(RTL_CONSTASCII_USTRINGPARAM("java.compiler=")) + usCompiler); + + javaVMInitArgs.version = JNI_VERSION_1_2; + javaVMInitArgs.nOptions = props.size() + p_props.size(); + javaVMInitArgs.ignoreUnrecognized = JNI_TRUE; + + javaVMInitArgs.options = (JavaVMOption *)calloc(sizeof(JavaVMOption), javaVMInitArgs.nOptions); + + size_t i; + + for(i = 0; i < p_props.size(); i++) + { + javaVMInitArgs.options[i] = p_props[i]; + } + + + for(;i < javaVMInitArgs.nOptions; i++) + { + OUString str = props[i - p_props.size()]; + + if( str.copy(0, 2).compareToAscii("-D") != 0 && str.copy(0, 2).compareToAscii("-X") != 0 ) + str = OUString(RTL_CONSTASCII_USTRINGPARAM("-D")) + str; + + javaVMInitArgs.options[i].optionString = strdup( OUStringToOString(str, RTL_TEXTENCODING_ASCII_US) ); + javaVMInitArgs.options[i].extraInfo = NULL; + } + + return &javaVMInitArgs; +} + diff --git a/stoc/source/javavm/jvmargs.hxx b/stoc/source/javavm/jvmargs.hxx new file mode 100644 index 000000000000..617755fba8cf --- /dev/null +++ b/stoc/source/javavm/jvmargs.hxx @@ -0,0 +1,228 @@ +/************************************************************************* + * + * $RCSfile: jvmargs.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef __JVM +#define __JVM + +#if STLPORT_VERSION < 321 +#include <tools/presys.h> +#include <vector.h> +#include <tools/postsys.h> +#else +#include <cstdarg> +#include <stl/vector> +#endif + +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring.hxx> +#endif + +#include "jni.h" + +using namespace ::rtl; + +#ifndef JNI_VERSION_1_2 + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 + +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ +#define JNI_ENOMEM (-4) /* not enough memory */ +#define JNI_EEXIST (-5) /* VM already created */ +#define JNI_EINVAL (-6) /* invalid arguments */ + + +struct JNIInvokeInterface12_; +struct JavaVM12_; + +typedef JavaVM12_ JavaVM12; +#define JAVAVM JavaVM12 + +struct JNIInvokeInterface12_ +{ + void *reserved0; + void *reserved1; + void *reserved2; + + jint (JNICALL *DestroyJavaVM)(JavaVM12 *vm); + jint (JNICALL *AttachCurrentThread)(JavaVM12 *vm, void **penv, void *args); + jint (JNICALL *DetachCurrentThread)(JavaVM12 *vm); + jint (JNICALL *GetEnv)(JavaVM12 *vm, void **penv, jint version); +}; + +struct JavaVM12_ +{ + const struct JNIInvokeInterface12_ *functions; + + jint DestroyJavaVM() + { + return functions->DestroyJavaVM(this); + } + + jint AttachCurrentThread(void **penv, void *args) + { + return functions->AttachCurrentThread(this, penv, args); + } + + jint DetachCurrentThread() + { + return functions->DetachCurrentThread(this); + } + + jint GetEnv(void **penv, jint version) + { + return functions->GetEnv(this, penv, version); + } +}; + +typedef struct JavaVMOption +{ + char *optionString; + void *extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs +{ + jint version; + + jint nOptions; + JavaVMOption *options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +typedef struct JavaVMAttachArgs +{ + jint version; + + char *name; + jobject group; +} JavaVMAttachArgs; + +#else +#define JAVAVM JavaVM +#endif + +typedef jint (JNICALL *JNIvfprintf)(FILE *fp, const char *format, va_list args); +typedef void (JNICALL *JNIexit)(jint code); +typedef void (JNICALL *JNIabort)(void); + +extern "C" { + +#ifdef OS2 +typedef jint JNICALL0 JNI_InitArgs_Type(void *); +typedef jint JNICALL0 JNI_CreateVM_Type(JAVAVM **, JNIEnv **, void *); +#else +typedef jint JNICALL JNI_InitArgs_Type(void *); +typedef jint JNICALL JNI_CreateVM_Type(JAVAVM **, JNIEnv **, void *); +#endif + +} + +class JVM +{ + ::std::vector<JavaVMOption> p_props; + + JavaVMInitArgs javaVMInitArgs; + JDK1_1InitArgs jDK1_1InitArgs; + + ::std::vector<OUString> props; + + sal_Bool debug; + jint jiDebugPort; + OUString usCompiler; + +protected: + void pushPProp(OUString uString, void * extraInfo = NULL); + +public: + JVM(JNI_InitArgs_Type * pVMInitArgs) ; + ~JVM() ; + + void pushProp(const OUString & uString); + + void disableAsyncGC(jboolean jbFlag); + void enableClassGC(jboolean jbFlag); + void enableVerboseGC(jboolean jbFlag); + void verbose(jboolean jbFlag); + + void setCompiler(const OUString & usCompiler); + void nativeStackSize(jint jiSize); + void javaStackSize(jint jiSize); + void verifyMode(OUString uStr); + void minHeapSize(jint jiSize); + void maxHeapSize(jint jiSize); + void setDebug(sal_Bool flag); + void setDebugPort(jint jiDebugPort); + void classPath(OString str); + void vfprintf(JNIvfprintf vfprintf); + void exit(JNIexit exit); + void abort(JNIabort abort); + + sal_Bool getDebug(); + OUString getCompiler(); + + const JavaVMInitArgs * getJavaVMInitArgs(); + + const JDK1_1InitArgs * getJDK1_1InitArgs(); +}; + +#endif diff --git a/stoc/source/javavm/makefile.mk b/stoc/source/javavm/makefile.mk new file mode 100644 index 000000000000..6016289ff455 --- /dev/null +++ b/stoc/source/javavm/makefile.mk @@ -0,0 +1,147 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME=stoc +TARGET=jen +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- + +# Kollision zwischen bool.h aus Java und bool.h aus der STL. +# Das Problem tritt fuer alle Plattformen auf, aber anscheinend stolpert nur der +# GCC darueber +.IF "$(COM)" == "GCC" +CDEFS += -D__SGI_STL_BOOL_H +.ENDIF + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES= \ + com.sun.star.uno.Exception \ + com.sun.star.uno.XInterface \ + com.sun.star.java.XJavaVM \ + com.sun.star.uno.XWeak \ + com.sun.star.uno.TypeClass \ + com.sun.star.java.XJavaThreadRegister_11 \ + com.sun.star.lang.XServiceInfo \ + com.sun.star.lang.XTypeProvider \ + com.sun.star.lang.XMultiServiceFactory \ + com.sun.star.container.XNameAccess \ + com.sun.star.lang.XSingleServiceFactory \ + com.sun.star.registry.XRegistryKey \ + com.sun.star.registry.XSimpleRegistry \ + com.sun.star.frame.XConfigManager + +SLOFILES= \ + $(SLO)$/settings.obj \ + $(SLO)$/javavm.obj \ + $(SLO)$/jvmargs.obj \ + $(SLO)$/jen_desc.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(UNOLIB) \ + $(VOSLIB) \ + $(SALLIB) + +.IF "$(GUI)"=="WNT" +SHL1STDLIBS += advapi32.lib +.ENDIF + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.IF "$(depend)" == "" +ALL : $(BIN)$/jen.rdb \ + $(MISC)$/jen_desc.cxx \ + ALLTAR +.ELSE +ALL: ALLDEP +.ENDIF + +.INCLUDE : target.mk + +$(BIN)$/jen.rdb: $(SOLARBINDIR)$/applicat.rdb + +rdbmaker -BUCR -O$(BIN)$/jen.rdb $(foreach,i,$(UNOTYPES) -T$i ) $(SOLARBINDIR)$/applicat.rdb + +$(MISC)$/jen_desc.cxx: jen.xml + +xml2cmp -func $(MISC)$/jen_desc.cxx jen.xml + + diff --git a/stoc/source/loader/dllcomponentloader.cxx b/stoc/source/loader/dllcomponentloader.cxx new file mode 100644 index 000000000000..50374afca311 --- /dev/null +++ b/stoc/source/loader/dllcomponentloader.cxx @@ -0,0 +1,560 @@ +/************************************************************************* + * + * $RCSfile: dllcomponentloader.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MODULE_H_ +#include <osl/module.h> +#endif +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring.hxx> +#endif +#ifndef _RTL_STRBUF_HXX_ +#include <rtl/strbuf.hxx> +#endif + +#ifndef _UNO_ENVIRONMENT_H_ +#include <uno/environment.h> +#endif +#ifndef _UNO_MAPPING_HXX_ +#include <uno/mapping.hxx> +#endif + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE3_HXX_ +#include <cppuhelper/implbase3.hxx> +#endif + +#include <com/sun/star/loader/XImplementationLoader.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +using namespace com::sun::star::uno; +using namespace com::sun::star::loader; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; +using namespace cppu; +using namespace rtl; + +namespace stoc_loader +{ + +#define SERVICENAME "com.sun.star.loader.SharedLibrary" +#define IMPLNAME "com.sun.star.comp.stoc.DLLComponentLoader" + +//************************************************************************* +// DllComponentLoader +//************************************************************************* +class DllComponentLoader + : public WeakImplHelper3< XImplementationLoader, + XInitialization, + XServiceInfo > +{ +public: + DllComponentLoader( const Reference<XMultiServiceFactory> & rXSMgr ); + ~DllComponentLoader(); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( ); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XImplementationLoader + virtual Reference<XInterface> SAL_CALL activate( const OUString& implementationName, const OUString& implementationLoaderUrl, const OUString& locationUrl, const Reference<XRegistryKey>& xKey ) throw(CannotActivateFactoryException, RuntimeException); + virtual sal_Bool SAL_CALL writeRegistryInfo( const Reference<XRegistryKey>& xKey, const OUString& implementationLoaderUrl, const OUString& locationUrl ) throw(CannotRegisterImplementationException, RuntimeException); + +private: + Reference<XMultiServiceFactory> m_xSMgr; +}; + +//************************************************************************* +DllComponentLoader::DllComponentLoader( const Reference<XMultiServiceFactory> & rXSMgr ) + : m_xSMgr( rXSMgr ) +{ +} + +//************************************************************************* +DllComponentLoader::~DllComponentLoader() +{ +} + +//************************************************************************* +OUString SAL_CALL DllComponentLoader::getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ); +} + +//************************************************************************* +sal_Bool SAL_CALL DllComponentLoader::supportsService( const OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException) +{ + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +//************************************************************************* +Sequence<OUString> SAL_CALL DllComponentLoader::getSupportedServiceNames( ) + throw(::com::sun::star::uno::RuntimeException) +{ + return getSupportedServiceNames_Static(); +} + +//************************************************************************* +Sequence<OUString> SAL_CALL DllComponentLoader::getSupportedServiceNames_Static( ) +{ + OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ); + return Sequence< OUString >( &aName, 1 ); +} + +//************************************************************************* +void DllComponentLoader::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArgs ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + if( aArgs.getLength() != 1 ) + { + throw IllegalArgumentException(); + } + + Reference< XMultiServiceFactory > rServiceManager; + + if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) + { + aArgs.getConstArray()[0] >>= rServiceManager; + } + + if( !rServiceManager.is() ) + { + throw IllegalArgumentException(); + } + + m_xSMgr = rServiceManager; +} + +//************************************************************************* +Reference<XInterface> SAL_CALL DllComponentLoader::activate( + const OUString & rImplName, const OUString &, const OUString & rLibName, + const Reference< XRegistryKey > & xKey ) + + throw(CannotActivateFactoryException, RuntimeException) +{ + Reference< XSingleServiceFactory > xRet; + OUString sMessage; + + oslModule lib = osl_loadModule( rLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL ); + + if (lib) + { + void * pSym; + + // ========================= LATEST VERSION ========================= + OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) ); + if (pSym = osl_getSymbol( lib, aGetEnvName.pData )) + { + uno_Environment * pCurrentEnv = 0; + uno_Environment * pEnv = 0; + const sal_Char * pEnvTypeName = 0; + (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv ); + + sal_Bool bNeedsMapping = + (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME )); + + OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) ); + + if (bNeedsMapping) + { + if (! pEnv) + uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 ); + if (pEnv) + { + OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); + uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 ); + if (pCurrentEnv) + bNeedsMapping = (pEnv != pCurrentEnv); + } + } + + OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY) ); + if (pSym = osl_getSymbol( lib, aGetFactoryName.pData )) + { + OString aImplName( OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) ); + + if (bNeedsMapping) + { + if (pEnv && pCurrentEnv) + { + Mapping aCurrent2Env( pCurrentEnv, pEnv ); + Mapping aEnv2Current( pEnv, pCurrentEnv ); + + if (aCurrent2Env.is() && aEnv2Current.is()) + { + void * pSMgr = aCurrent2Env.mapInterface( + m_xSMgr.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) ); + void * pKey = aCurrent2Env.mapInterface( + xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) ); + + void * pSSF = (*((component_getFactoryFunc)pSym))( + aImplName.getStr(), pSMgr, pKey ); + + if (pKey) + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey ); + if (pSMgr) + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr ); + + if (pSSF) + { + XSingleServiceFactory * pRet = (XSingleServiceFactory *) + aEnv2Current.mapInterface( + pSSF, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) ); + if (pRet) + { + xRet = pRet; + pRet->release(); + } + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF ); + } + } + } + } + else + { + XSingleServiceFactory * pRet = (XSingleServiceFactory *) + (*((component_getFactoryFunc)pSym))( + aImplName.getStr(), m_xSMgr.get(), xKey.get() ); + if (pRet) + { + xRet = pRet; + pRet->release(); + } + } + } else + { + sMessage = OUString::createFromAscii("symbol \""); + sMessage += aGetFactoryName; + sMessage += OUString::createFromAscii("\" could not be found in \""); + sMessage += rLibName; + sMessage += OUString::createFromAscii("\""); + } + + if (pEnv) + (*pEnv->release)( pEnv ); + if (pCurrentEnv) + (*pCurrentEnv->release)( pCurrentEnv ); + } + else + { + sMessage = OUString::createFromAscii("symbol \""); + sMessage += aGetEnvName; + sMessage += OUString::createFromAscii("\" could not be found in \""); + sMessage += rLibName; + sMessage += OUString::createFromAscii("\""); + } + + if (!xRet.is() && !sMessage.getLength()) + { + sMessage = OUString::createFromAscii("got no factory from component \""); + sMessage += rLibName; + sMessage += OUString::createFromAscii("\"!"); + } + + if (! xRet.is()) + osl_unloadModule( lib ); + } else + { + sMessage = OUString::createFromAscii("component library \""); + sMessage += rLibName; + sMessage += OUString::createFromAscii("\" could not be loaded"); + } + + if (! xRet.is()) + { + CannotActivateFactoryException e; + e.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("component could not be activated: ") ) + sMessage; + throw e; + } + + return xRet; +} + + +//************************************************************************* +sal_Bool SAL_CALL DllComponentLoader::writeRegistryInfo( + const Reference< XRegistryKey > & xKey, const OUString &, const OUString & rLibName ) + + throw(CannotRegisterImplementationException, RuntimeException) +{ + sal_Bool bRet = sal_False; + OUString sMessage; + + oslModule lib = osl_loadModule( rLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL ); + + if (lib) + { + void * pSym; + + // ========================= LATEST VERSION ========================= + OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) ); + if (pSym = osl_getSymbol( lib, aGetEnvName.pData )) + { + uno_Environment * pCurrentEnv = 0; + uno_Environment * pEnv = 0; + const sal_Char * pEnvTypeName = 0; + (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv ); + + sal_Bool bNeedsMapping = + (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME )); + + OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) ); + + if (bNeedsMapping) + { + if (! pEnv) + uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 ); + if (pEnv) + { + OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); + uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 ); + if (pCurrentEnv) + bNeedsMapping = (pEnv != pCurrentEnv); + } + } + + OUString aWriteInfoName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_WRITEINFO) ); + if (pSym = osl_getSymbol( lib, aWriteInfoName.pData )) + { + if (bNeedsMapping) + { + if (pEnv && pCurrentEnv) + { + Mapping aCurrent2Env( pCurrentEnv, pEnv ); + if (aCurrent2Env.is()) + { + void * pSMgr = aCurrent2Env.mapInterface( + m_xSMgr.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) ); + void * pKey = aCurrent2Env.mapInterface( + xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) ); + // key is mandatory + if (pKey) + { + bRet = (*((component_writeInfoFunc)pSym))( pSMgr, pKey ); + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey ); + } + + if (pSMgr) + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr ); + } + } + } + else + { + // key is mandatory + if (xKey.is()) + bRet = (*((component_writeInfoFunc)pSym))( m_xSMgr.get(), xKey.get() ); + } + } else + { + sMessage = OUString::createFromAscii("symbol \""); + sMessage += aWriteInfoName; + sMessage += OUString::createFromAscii("\" could not be found in \""); + sMessage += rLibName; + sMessage += OUString::createFromAscii("\""); + } + + if (pEnv) + (*pEnv->release)( pEnv ); + if (pCurrentEnv) + (*pCurrentEnv->release)( pCurrentEnv ); + } + else + { + sMessage = OUString::createFromAscii("symbol \""); + sMessage += aGetEnvName; + sMessage += OUString::createFromAscii("\" could not be found in \""); + sMessage += rLibName; + sMessage += OUString::createFromAscii("\""); + } + + if (!bRet && !sMessage.getLength()) + { + sMessage = OUString::createFromAscii("calling symbol \""); + sMessage += OUString::createFromAscii( COMPONENT_WRITEINFO ); + sMessage += OUString::createFromAscii("\" found in \""); + sMessage += rLibName; + sMessage += OUString::createFromAscii("\" returned FALSE"); + } + } else + { + sMessage = OUString::createFromAscii("component library \""); + sMessage += rLibName; + sMessage += OUString::createFromAscii("\" could not be loaded"); + } + + if (! bRet) + { + CannotRegisterImplementationException e; + e.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("component could not be registered: ") ) + sMessage; + throw e; + } + + return bRet; +} + + +//************************************************************************* +Reference<XInterface> SAL_CALL DllComponentLoader_CreateInstance( const Reference<XMultiServiceFactory> & rSMgr ) throw(Exception) +{ + Reference<XInterface> xRet; + + XImplementationLoader *pXLoader = (XImplementationLoader *)new DllComponentLoader(rSMgr); + + if (pXLoader) + { + xRet = Reference<XInterface>::query(pXLoader); + } + + return xRet; +} + +} + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) ); + + const Sequence< OUString > & rSNL = + ::stoc_loader::DllComponentLoader::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (rtl_str_compare( pImplName, IMPLNAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ), + ::stoc_loader::DllComponentLoader_CreateInstance, + ::stoc_loader::DllComponentLoader::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + + + diff --git a/stoc/source/loader/makefile.mk b/stoc/source/loader/makefile.mk new file mode 100644 index 000000000000..fe8393882519 --- /dev/null +++ b/stoc/source/loader/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= cpld +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +BOOTSTRAP_SERVICE=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + +SLOFILES= \ + $(SLO)$/dllcomponentloader.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(VOSLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/stoc/source/namingservice/makefile.mk b/stoc/source/namingservice/makefile.mk new file mode 100644 index 000000000000..381a73adb179 --- /dev/null +++ b/stoc/source/namingservice/makefile.mk @@ -0,0 +1,105 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= namingservice +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + +SLOFILES= \ + $(SLO)$/namingservice.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/stoc/source/namingservice/namingservice.cxx b/stoc/source/namingservice/namingservice.cxx new file mode 100644 index 000000000000..6c351fc6d3bc --- /dev/null +++ b/stoc/source/namingservice/namingservice.cxx @@ -0,0 +1,301 @@ +/************************************************************************* + * + * $RCSfile: namingservice.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <stl/hash_map> + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +#ifndef _UNO_DISPATCHER_H_ +#include <uno/dispatcher.h> +#endif +#ifndef _UNO_MAPPING_HXX_ +#include <uno/mapping.hxx> +#endif + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_COMPONENT_HXX_ +#include <cppuhelper/component.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE2_HXX_ +#include <cppuhelper/implbase2.hxx> +#endif + +#include <com/sun/star/uno/XNamingService.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +using namespace cppu; +using namespace rtl; +using namespace osl; +using namespace std; + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; + +#define SERVICENAME "com.sun.star.uno.NamingService" +#define IMPLNAME "com.sun.star.comp.stoc.NamingService" + +namespace stoc_namingservice +{ + +struct equalOWString_Impl +{ + sal_Bool operator()(const OUString & s1, const OUString & s2) const + { return s1 == s2; } +}; + +struct hashOWString_Impl +{ + size_t operator()(const OUString & rName) const + { return rName.hashCode(); } +}; + +typedef hash_map +< + OUString, + Reference<XInterface >, + hashOWString_Impl, + equalOWString_Impl +> HashMap_OWString_Interface; + +//================================================================================================== +class NamingService_Impl + : public WeakImplHelper2 < XServiceInfo, XNamingService > +{ + Mutex aMutex; + HashMap_OWString_Interface aMap; +public: + NamingService_Impl(); + ~NamingService_Impl(); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static() + { + OUString aStr( OUString::createFromAscii( SERVICENAME ) ); + return Sequence< OUString >( &aStr, 1 ); + } + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getRegisteredObject( const ::rtl::OUString& Name ); + virtual void SAL_CALL registerObject( const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Object ); + virtual void SAL_CALL revokeObject( const ::rtl::OUString& Name ); +}; + +//================================================================================================== +static Reference<XInterface> SAL_CALL NamingService_Impl_create( const Reference<XMultiServiceFactory> & ) +{ + static Reference<XNamingService> * pNS = 0; + + if( !pNS ) + { + Guard< Mutex > aGuard( Mutex::getGlobalMutex() ); + // only one Naming Service for the hole process + static Reference<XNamingService> xNS = new NamingService_Impl(); + pNS = &xNS; + } + + return *pNS; +} + +//================================================================================================== +NamingService_Impl::NamingService_Impl() +{ +} + +//================================================================================================== +NamingService_Impl::~NamingService_Impl() +{ +} + +// XServiceInfo +OUString NamingService_Impl::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return OUString::createFromAscii( IMPLNAME ); +} + +// XServiceInfo +sal_Bool NamingService_Impl::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; +} + +// XServiceInfo +Sequence< OUString > NamingService_Impl::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + return getSupportedServiceNames_Static(); +} + +// XServiceInfo +Reference< XInterface > NamingService_Impl::getRegisteredObject( const OUString& Name ) +{ + Guard< Mutex > aGuard( aMutex ); + Reference< XInterface > xRet; + HashMap_OWString_Interface::iterator aIt = aMap.find( Name ); + if( aIt != aMap.end() ) + xRet = (*aIt).second; + return xRet; +} + +// XServiceInfo +void NamingService_Impl::registerObject( const OUString& Name, const Reference< XInterface >& Object ) +{ + Guard< Mutex > aGuard( aMutex ); + aMap[ Name ] = Object; +} + +// XServiceInfo +void NamingService_Impl::revokeObject( const OUString& Name ) +{ + Guard< Mutex > aGuard( aMutex ); + aMap.erase( Name ); +} + +} + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + // NamingService + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString::createFromAscii( "/" IMPLNAME "/UNO/SERVICES" ) ) ); + + Sequence< OUString > & rSNL = + ::stoc_namingservice::NamingService_Impl::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (rtl_str_compare( pImplName, IMPLNAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + ::stoc_namingservice::NamingService_Impl_create, + ::stoc_namingservice::NamingService_Impl::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + diff --git a/stoc/source/namingservice/namingservice.xml b/stoc/source/namingservice/namingservice.xml new file mode 100644 index 000000000000..a76cd213abd2 --- /dev/null +++ b/stoc/source/namingservice/namingservice.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE COMPONENTDESCRIPTION PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "componentdescription.dtd"> + +<COMPONENTDESCRIPTION + xmlns:xlink="http://www.w3.org/1999/xlink/Namespace" > + +<Author> Juergen Schmidt </Author> + +<Name> com.sun.star.comp.stoc.NamingService </Name> + +<Description> + This component provides ... +</Description> + +<ModuleName> namingservice </ModuleName> + +<LoaderName> com.sun.star.loader.SharedLibrary </LoaderName> + +<Language> c++ </Language> + +<Status StatusValue="final"/> + +<SupportedService> com.sun.star.uno.NamingService </SupportedService> + +<ProjectBuildDependency> cppuhelper </ProjectBuildDependency> +<ProjectBuildDependency> cppu </ProjectBuildDependency> +<ProjectBuildDependency> sal </ProjectBuildDependency> + +<RuntimeModuleDependency> cppuhelper </RuntimeModuleDependency> +<RuntimeModuleDependency> cppu1 </RuntimeModuleDependency> +<RuntimeModuleDependency> sal1 </RuntimeModuleDependency> + +<Type> com.sun.star.lang.XComponent </Type> +<Type> com.sun.star.lang.IllegalArgumentException </Type> +<Type> com.sun.star.lang.XInitialization </Type> +<Type> com.sun.star.lang.XTypeProvider </Type> +<Type> com.sun.star.lang.XServiceInfo </Type> +<Type> com.sun.star.lang.XSingleServiceFactory </Type> +<Type> com.sun.star.lang.XMultiServiceFactory </Type> +<Type> com.sun.star.registry.XRegistryKey </Type> +<Type> com.sun.star.uno.XAggregation </Type> +<Type> com.sun.star.uno.XWeak </Type> +<Type> com.sun.star.uno.TypeClass </Type> +<Type> com.sun.star.uno.XNamingService </Type> + +</COMPONENTDESCRIPTION> + diff --git a/stoc/source/proxy_factory/makefile.mk b/stoc/source/proxy_factory/makefile.mk new file mode 100644 index 000000000000..819e463ba543 --- /dev/null +++ b/stoc/source/proxy_factory/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:34 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=stoc +TARGET=proxyfac +USE_DEFFILE=TRUE +NO_BSYMBOLIC=TRUE +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + + +SLOFILES= \ + $(SLO)$/proxyfac.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET=$(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB=i$(TARGET) +SHL1LIBS=$(SLB)$/$(TARGET).lib +SHL1DEF=$(MISC)$/$(SHL1TARGET).def + +DEF1NAME=$(SHL1TARGET) +DEF1EXPORTFILE=exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/stoc/source/proxy_factory/proxyfac.cxx b/stoc/source/proxy_factory/proxyfac.cxx new file mode 100644 index 000000000000..41c904127ef2 --- /dev/null +++ b/stoc/source/proxy_factory/proxyfac.cxx @@ -0,0 +1,459 @@ +/************************************************************************* + * + * $RCSfile: proxyfac.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <osl/diagnose.h> +#include <osl/interlck.h> + +#include <uno/dispatcher.h> +#include <uno/data.h> +#include <uno/any2.h> +#include <uno/mapping.hxx> + +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/weakagg.hxx> +#include <cppuhelper/queryinterface.hxx> + +#include <stl/vector> + +#include <com/sun/star/uno/XAggregation.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/util/XProxyFactory.hpp> + +using namespace std; +using namespace rtl; +using namespace osl; +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::util; +using namespace com::sun::star::registry; + +#define SERVICENAME "com.sun.star.util.ProxyFactory" +#define IMPLNAME "com.sun.star.comp.util.ProxyFactory" + +namespace stoc_proxyfac +{ + +//-------------------------------------------------------------------------------------------------- +static inline uno_Interface * uno_queryInterface( + uno_Interface * pUnoI, typelib_InterfaceTypeDescription * pTypeDescr ) +{ + uno_Interface * pRet = 0; + + void * pArgs[1]; + + typelib_InterfaceTypeDescription * pTXInterfaceDescr = 0; + const Type & rXIType = ::getCppuType( (const Reference<XInterface > *)0 ); + TYPELIB_DANGER_GET( (typelib_TypeDescription **)&pTXInterfaceDescr, rXIType.getTypeLibType() ); + OSL_ASSERT( pTXInterfaceDescr->ppAllMembers ); + typelib_TypeDescription * pMTqueryInterface = 0; + TYPELIB_DANGER_GET( &pMTqueryInterface, pTXInterfaceDescr->ppAllMembers[0] ); + + Type aType( ((typelib_TypeDescription *)pTypeDescr)->pWeakRef ); + pArgs[0] = &aType; + + uno_Any aRetI, aExc; + uno_Any * pExc = &aExc; + + (*((uno_Interface *)pUnoI)->pDispatcher)( + (uno_Interface *)pUnoI, pMTqueryInterface, &aRetI, pArgs, &pExc ); + + OSL_ENSHURE( !pExc, "### Exception occured during queryInterface()!" ); + if (pExc) // cleanup exception + { + uno_any_destruct( pExc, 0 ); + } + else + { + if (aRetI.pType->eTypeClass == typelib_TypeClass_INTERFACE) + { + pRet = *(uno_Interface **)aRetI.pData; + (*pRet->acquire)( pRet ); + } + uno_any_destruct( &aRetI, 0 ); + } + + TYPELIB_DANGER_RELEASE( pMTqueryInterface ); + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pTXInterfaceDescr ); + return pRet; +} + +struct ProxyRoot; +struct FactoryImpl; + +//================================================================================================== +struct uno_Proxy : public uno_Interface +{ + ProxyRoot * pRoot; + uno_Interface * pTarget; + typelib_InterfaceTypeDescription * pTypeDescr; +}; +typedef vector< uno_Proxy * > t_InterfaceVector; + +//================================================================================================== +struct ProxyRoot : public OWeakAggObject +{ + FactoryImpl * pFactory; + Mutex aMutex; + t_InterfaceVector aInterfaces; + + uno_Interface * pTarget; + + inline ProxyRoot( FactoryImpl * pFactory_, const Reference< XInterface > & xTarget_ ); + virtual ~ProxyRoot(); + + virtual Any SAL_CALL queryAggregation( const Type & rType ) throw (RuntimeException); +}; +//================================================================================================== +struct FactoryImpl : public WeakImplHelper2< XServiceInfo, XProxyFactory > +{ + Mapping aUno2Cpp; + Mapping aCpp2Uno; + + FactoryImpl(); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw (RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException); + + // XProxyFactory + virtual Reference< XAggregation > SAL_CALL createProxy( const Reference< XInterface > & xTarget ) throw (RuntimeException); +}; + +extern "C" +{ +//__________________________________________________________________________________________________ +static void SAL_CALL uno_proxy_dispatch( + uno_Interface * pUnoI, const typelib_TypeDescription * pMemberType, + void * pReturn, void * pArgs[], uno_Any ** ppException ) +{ + uno_Proxy * pThis = static_cast< uno_Proxy * >( pUnoI ); + + try + { + switch (((typelib_InterfaceMemberTypeDescription *)pMemberType)->nPosition) + { + case 0: // queryInterface() + { + Any aRet( pThis->pRoot->queryInterface( * reinterpret_cast< const Type * >( pArgs[0] ) ) ); + const Type & rAnyType = ::getCppuType( &aRet ); + uno_type_copyAndConvertData( + pReturn, &aRet, rAnyType.getTypeLibType(), pThis->pRoot->pFactory->aCpp2Uno.get() ); + *ppException = 0; // no exc + break; + } + case 1: // acquire() + pThis->pRoot->acquire(); + *ppException = 0; // no exc + break; + case 2: // release() + pThis->pRoot->release(); + *ppException = 0; // no exc + break; + default: + (*pThis->pTarget->pDispatcher)( pThis->pTarget, pMemberType, pReturn, pArgs, ppException ); + } + } + catch (...) + { + RuntimeException aExc; + aExc.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("unexpected exception occured!" ) ); + aExc.Context = (XAggregation *)pThis->pRoot; + const Type & rExcType = ::getCppuType( &aExc ); + uno_type_any_constructAndConvert( *ppException, &aExc, rExcType.getTypeLibType(), + pThis->pRoot->pFactory->aCpp2Uno.get() ); + } +} +//-------------------------------------------------------------------------------------------------- +static void SAL_CALL uno_proxy_acquire( uno_Interface * pUnoI ) +{ + static_cast< uno_Proxy * >( pUnoI )->pRoot->acquire(); +} +//-------------------------------------------------------------------------------------------------- +static void SAL_CALL uno_proxy_release( uno_Interface * pUnoI ) +{ + static_cast< uno_Proxy * >( pUnoI )->pRoot->release(); +} +} + +//__________________________________________________________________________________________________ +inline ProxyRoot::ProxyRoot( FactoryImpl * pFactory_, const Reference< XInterface > & xTarget_ ) + : pFactory( pFactory_ ) + , pTarget( 0 ) +{ + pFactory->acquire(); + pFactory->aCpp2Uno.mapInterface( (void **)&pTarget, xTarget_.get(), ::getCppuType( &xTarget_ ) ); + OSL_ENSHURE( pTarget, "### mapping interface failed!" ); + aInterfaces.reserve( 8 ); +} +//__________________________________________________________________________________________________ +ProxyRoot::~ProxyRoot() +{ + for ( t_InterfaceVector::const_iterator iPos( aInterfaces.begin() ); + iPos != aInterfaces.end(); ++iPos ) + { + uno_Proxy * p = *iPos; + (*p->pTarget->release)( p->pTarget ); + typelib_typedescription_release( (typelib_TypeDescription *)p->pTypeDescr ); + delete p; + } + (*pTarget->release)( pTarget ); + pFactory->release(); +} + +//-------------------------------------------------------------------------------------------------- +static inline sal_Bool type_equals( + const Type & rType, typelib_InterfaceTypeDescription * pTypeDescr ) +{ + typelib_TypeDescriptionReference * p1 = rType.getTypeLibType(); + typelib_TypeDescriptionReference * p2 = (typelib_TypeDescriptionReference *)pTypeDescr; + + return (p1 == p2 || + (p1->pTypeName->length == p2->pTypeName->length && + rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0)); +} +//__________________________________________________________________________________________________ +Any ProxyRoot::queryAggregation( const Type & rType ) + throw (RuntimeException) +{ + Any aRet( OWeakAggObject::queryAggregation( rType ) ); + if (! aRet.hasValue()) + { + // query existing interfaces + MutexGuard aGuard( aMutex ); + for ( t_InterfaceVector::const_iterator iPos( aInterfaces.begin() ); + iPos != aInterfaces.end(); ++iPos ) + { + uno_Proxy * p = *iPos; + typelib_InterfaceTypeDescription * pTypeDescr = p->pTypeDescr; + while (pTypeDescr) + { + if (type_equals( rType, pTypeDescr )) + { + Reference< XInterface > xRet; + pFactory->aUno2Cpp.mapInterface( (void **)&xRet, (uno_Interface *)p, pTypeDescr ); + aRet.setValue( &xRet, (typelib_TypeDescription *)pTypeDescr ); + return aRet; + } + pTypeDescr = pTypeDescr->pBaseTypeDescription; + } + } + // else perform query + typelib_InterfaceTypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( (typelib_TypeDescription **)&pTypeDescr, rType.getTypeLibType() ); + uno_Interface * pProxyTarget = uno_queryInterface( pTarget, pTypeDescr ); + if (pProxyTarget) + { + uno_Proxy * p = new uno_Proxy(); + p->acquire = uno_proxy_acquire; + p->release = uno_proxy_release; + p->pDispatcher = uno_proxy_dispatch; + // + p->pRoot = this; + p->pTarget = pProxyTarget; + typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr ); + p->pTypeDescr = pTypeDescr; + + Reference< XInterface > xRet; + pFactory->aUno2Cpp.mapInterface( (void **)&xRet, (uno_Interface *)p, pTypeDescr ); + OSL_ENSHURE( xRet.is(), "### mapping interface failed!" ); + aInterfaces.push_back( p ); + aRet.setValue( &xRet, (typelib_TypeDescription *)pTypeDescr ); + } + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pTypeDescr ); + } + return aRet; +} + +//################################################################################################## +//################################################################################################## + +//-------------------------------------------------------------------------------------------------- +inline static Sequence< OUString > getSupportedServiceNames() +{ + OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ); + return Sequence< OUString >( &aName, 1 ); +} + +//__________________________________________________________________________________________________ +FactoryImpl::FactoryImpl() + : aUno2Cpp( OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ), + OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ) ) + , aCpp2Uno( OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ), + OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ) ) +{ + OSL_ENSHURE( aUno2Cpp.is(), "### cannot get bridge uno <-> C++!" ); + OSL_ENSHURE( aCpp2Uno.is(), "### cannot get bridge C++ <-> uno!" ); +} + +// XProxyFactory +//__________________________________________________________________________________________________ +Reference< XAggregation > FactoryImpl::createProxy( const Reference< XInterface > & xTarget ) + throw (RuntimeException) +{ + return new ProxyRoot( this, xTarget ); +} +// XServiceInfo +//__________________________________________________________________________________________________ +OUString FactoryImpl::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ); +} +//__________________________________________________________________________________________________ +sal_Bool FactoryImpl::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 > FactoryImpl::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + return stoc_proxyfac::getSupportedServiceNames(); +} + +//================================================================================================== +static Reference< XInterface > SAL_CALL FactoryImpl_create( const Reference< XMultiServiceFactory > & xMgr ) + throw(::com::sun::star::uno::Exception) +{ + return Reference< XInterface >( *new FactoryImpl() ); +} + +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) ); + + const Sequence< OUString > & rSNL = stoc_proxyfac::getSupportedServiceNames(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ), + stoc_proxyfac::FactoryImpl_create, + stoc_proxyfac::getSupportedServiceNames() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + diff --git a/stoc/source/proxy_factory/proxyfac.xml b/stoc/source/proxy_factory/proxyfac.xml new file mode 100644 index 000000000000..98892ec1f147 --- /dev/null +++ b/stoc/source/proxy_factory/proxyfac.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE COMPONENTDESCRIPTION PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "componentdescription.dtd"> + +<COMPONENTDESCRIPTION + xmlns:xlink="http://www.w3.org/1999/xlink/Namespace" > + +<Author> Daniel Boelzle </Author> + +<Name> com.sun.star.comp.stoc.ProxyFactory </Name> + +<Description> +Specifies a factory object to create proxy objects. +These proxy object represent a given target object and can be +be aggregated. The proxy objects act UNO conform and do NOT provide +original target interfaces on queryInterface() calls. +</Description> + +<ModuleName> proxyfac </ModuleName> + +<LoaderName> com.sun.star.loader.SharedLibrary </LoaderName> + +<Language> C++ </Language> + +<Status StatusValue="final"/> + +<SupportedService> com.sun.star.util.ProxyFactory </SupportedService> + +<ServiceDependency> </ServiceDependency> + +<ProjectBuildDependency> cppuhelper </ProjectBuildDependency> +<ProjectBuildDependency> cppu </ProjectBuildDependency> +<ProjectBuildDependency> sal </ProjectBuildDependency> + +<RuntimeModuleDependency> cppuhelper </RuntimeModuleDependency> +<RuntimeModuleDependency> cppu </RuntimeModuleDependency> +<RuntimeModuleDependency> sal </RuntimeModuleDependency> + +<Type> com.sun.star.lang.XTypeProvider </Type> +<Type> com.sun.star.lang.XServiceInfo </Type> +<Type> com.sun.star.lang.XSingleServiceFactory </Type> +<Type> com.sun.star.lang.XMultiServiceFactory </Type> +<Type> com.sun.star.registry.XSimpleRegistry </Type> +<Type> com.sun.star.registry.XRegistryKey </Type> +<Type> com.sun.star.uno.XAggregation </Type> +<Type> com.sun.star.uno.XWeak </Type> +<Type> com.sun.star.util.XProxyFactory </Type> + +</COMPONENTDESCRIPTION> + diff --git a/stoc/source/registry_tdprovider/base.hxx b/stoc/source/registry_tdprovider/base.hxx new file mode 100644 index 000000000000..a1c32dc8f1e4 --- /dev/null +++ b/stoc/source/registry_tdprovider/base.hxx @@ -0,0 +1,337 @@ +/************************************************************************* + * + * $RCSfile: base.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef __REGISTRY_REFLREAD_HXX__ +#include <registry/reflread.hxx> +#endif + +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE1_HXX_ +#include <cppuhelper/implbase1.hxx> +#endif +#ifndef _CPPUHELPER_EXTRACT_HXX_ +#include <cppuhelper/extract.hxx> +#endif + +#include <stl/vector> + +#include <com/sun/star/reflection/XTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceTypeDescription.hpp> +#include <com/sun/star/reflection/XCompoundTypeDescription.hpp> +#include <com/sun/star/reflection/XEnumTypeDescription.hpp> +#include <com/sun/star/reflection/XIndirectTypeDescription.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + + +using namespace std; +using namespace rtl; +using namespace osl; +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; +using namespace com::sun::star::reflection; + + +namespace stoc_rdbtdp +{ + +//-------------------------------------------------------------------------------------------------- +inline sal_Int32 getRTValueAsInt32( const RTConstValue & rVal ) +{ + switch (rVal.m_type) + { + case RT_TYPE_BYTE: + return rVal.m_value.aByte; + case RT_TYPE_INT16: + return rVal.m_value.aShort; + case RT_TYPE_UINT16: + return rVal.m_value.aUShort; + case RT_TYPE_INT32: + return rVal.m_value.aLong; + case RT_TYPE_UINT32: + return rVal.m_value.aULong; + } + OSL_ENSHURE( sal_False, "### unexpected value type!" ); + return 0; +} +//-------------------------------------------------------------------------------------------------- +inline Any getRTValue( const RTConstValue & rVal ) +{ + switch (rVal.m_type) + { + case RT_TYPE_BOOL: + return Any( &rVal.m_value.aBool, ::getCppuBooleanType() ); + case RT_TYPE_BYTE: + return Any( &rVal.m_value.aByte, ::getCppuType( (const sal_Int8 *)0 ) ); + case RT_TYPE_INT16: + return Any( &rVal.m_value.aShort, ::getCppuType( (const sal_Int16 *)0 ) ); + case RT_TYPE_UINT16: + return Any( &rVal.m_value.aUShort, ::getCppuType( (const sal_uInt16 *)0 ) ); + case RT_TYPE_INT32: + return Any( &rVal.m_value.aLong, ::getCppuType( (const sal_Int32 *)0 ) ); + case RT_TYPE_UINT32: + return Any( &rVal.m_value.aULong, ::getCppuType( (const sal_uInt32 *)0 ) ); + case RT_TYPE_FLOAT: + return Any( &rVal.m_value.aFloat, ::getCppuType( (const float *)0 ) ); + case RT_TYPE_DOUBLE: + return Any( &rVal.m_value.aDouble, ::getCppuType( (const double *)0 ) ); + case RT_TYPE_STRING: + { + OUString aStr( rVal.m_value.aString ); + return Any( &aStr, ::getCppuType( (const OUString *)0 ) ); + } + } + OSL_ENSHURE( sal_False, "### unexpected RTValue!" ); + return Any(); +} + +//================================================================================================== +struct MethodInit +{ +// WeakReference< XInterfaceMemberTypeDescription > wxMember; + // + OUString aTypeName; + OUString aMemberName; + OUString aReturnTypeName; + sal_uInt16 nMethodIndex; + sal_Bool bOneWay; +}; +//================================================================================================== +struct AttributeInit +{ +// WeakReference< XInterfaceMemberTypeDescription > wxMember; + // + OUString aTypeName; + OUString aMemberName; + OUString aMemberTypeName; + sal_Bool bReadOnly; +}; + +//================================================================================================== +class TypeDescriptionImpl : public WeakImplHelper1< XTypeDescription > +{ + TypeClass _eTypeClass; + OUString _aName; + +public: + TypeDescriptionImpl( TypeClass eTypeClass, const OUString & rName ) + : _eTypeClass( eTypeClass ) + , _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); +}; + +//================================================================================================== +class InterfaceTypeDescriptionImpl : public WeakImplHelper1< XInterfaceTypeDescription > +{ + Reference< XHierarchicalNameAccess > _xTDMgr; + Sequence< sal_Int8 > _aBytes; + + OUString _aName; + Uik _aUik; + + OUString _aBaseType; + Mutex _aBaseTypeMutex; + Reference< XTypeDescription > _xBaseTD; + + Mutex _aMembersMutex; + sal_Int32 _nBaseOffset; + vector< AttributeInit > * _pAttributes; + vector< MethodInit > * _pMethods; + +public: + InterfaceTypeDescriptionImpl( const Reference< XHierarchicalNameAccess > & xTDMgr, + const OUString & rName, const OUString & rBaseType, + const RTUik & rUik, const Sequence< sal_Int8 > & rBytes ); + virtual ~InterfaceTypeDescriptionImpl(); + + // XTypeDescription + virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + + // XInterfaceTypeDescription + virtual Uik SAL_CALL getUik() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XTypeDescription > SAL_CALL getBaseType() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XInterfaceMemberTypeDescription > > SAL_CALL getMembers() throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class CompoundTypeDescriptionImpl : public WeakImplHelper1< XCompoundTypeDescription > +{ + Reference< XHierarchicalNameAccess > _xTDMgr; + TypeClass _eTypeClass; + Sequence< sal_Int8 > _aBytes; + OUString _aName; + + OUString _aBaseType; + Mutex _aBaseTypeMutex; + Reference< XTypeDescription > _xBaseTD; + + Mutex _aMembersMutex; + Sequence< Reference< XTypeDescription > > * _pMembers; + + Mutex _aMemberNamesMutex; + Sequence< OUString > * _pMemberNames; + +public: + CompoundTypeDescriptionImpl( const Reference< XHierarchicalNameAccess > & xTDMgr, + TypeClass eTypeClass, + const OUString & rName, const OUString & rBaseName, + const Sequence< sal_Int8 > & rBytes ) + : _xTDMgr( xTDMgr ) + , _eTypeClass( eTypeClass ) + , _aBytes( rBytes ) + , _aName( rName ) + , _aBaseType( rBaseName ) + , _pMembers( 0 ) + , _pMemberNames( 0 ) + {} + virtual ~CompoundTypeDescriptionImpl(); + + // XTypeDescription + virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + + // XCompoundTypeDescription + virtual Reference< XTypeDescription > SAL_CALL getBaseType() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XTypeDescription > > SAL_CALL getMemberTypes() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< OUString > SAL_CALL getMemberNames() throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class EnumTypeDescriptionImpl : public WeakImplHelper1< XEnumTypeDescription > +{ + Reference< XHierarchicalNameAccess > _xTDMgr; + Sequence< sal_Int8 > _aBytes; + + OUString _aName; + sal_Int32 _nDefaultValue; + + Mutex _aEnumNamesMutex; + Sequence< OUString > * _pEnumNames; + Mutex _aEnumValuesMutex; + Sequence< sal_Int32 > * _pEnumValues; + +public: + EnumTypeDescriptionImpl( const Reference< XHierarchicalNameAccess > & xTDMgr, + const OUString & rName, sal_Int32 nDefaultValue, + const Sequence< sal_Int8 > & rBytes ) + : _xTDMgr( xTDMgr ) + , _aName( rName ) + , _nDefaultValue( nDefaultValue ) + , _aBytes( rBytes ) + , _pEnumNames( 0 ) + , _pEnumValues( 0 ) + {} + virtual ~EnumTypeDescriptionImpl(); + + // XTypeDescription + virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + + // XEnumTypeDescription + virtual sal_Int32 SAL_CALL getDefaultEnumValue() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< OUString > SAL_CALL getEnumNames() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int32 > SAL_CALL getEnumValues() throw(::com::sun::star::uno::RuntimeException); +}; + +//================================================================================================== +class TypedefTypeDescriptionImpl : public WeakImplHelper1< XIndirectTypeDescription > +{ + Reference< XHierarchicalNameAccess > _xTDMgr; + OUString _aName; + + Mutex _aRefTDMutex; + OUString _aRefName; + Reference< XTypeDescription > _xRefTD; + +public: + TypedefTypeDescriptionImpl( const Reference< XHierarchicalNameAccess > & xTDMgr, + const OUString & rName, const OUString & rRefName ) + : _xTDMgr( xTDMgr ) + , _aName( rName ) + , _aRefName( rRefName ) + {} + + // 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); +}; + +} + + diff --git a/stoc/source/registry_tdprovider/makefile.mk b/stoc/source/registry_tdprovider/makefile.mk new file mode 100644 index 000000000000..db99fa4f856a --- /dev/null +++ b/stoc/source/registry_tdprovider/makefile.mk @@ -0,0 +1,112 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= rdbtdp +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +BOOTSTRAP_SERVICE=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + + +SLOFILES= \ + $(SLO)$/tdprovider.obj \ + $(SLO)$/tdef.obj \ + $(SLO)$/tdenum.obj \ + $(SLO)$/tdcomp.obj \ + $(SLO)$/tdiface.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/stoc/source/registry_tdprovider/tdcomp.cxx b/stoc/source/registry_tdprovider/tdcomp.cxx new file mode 100644 index 000000000000..86c0693f92b1 --- /dev/null +++ b/stoc/source/registry_tdprovider/tdcomp.cxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * $RCSfile: tdcomp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "base.hxx" + +namespace stoc_rdbtdp +{ + +//__________________________________________________________________________________________________ +CompoundTypeDescriptionImpl::~CompoundTypeDescriptionImpl() +{ + delete _pMembers; + delete _pMemberNames; +} + +// XTypeDescription +//__________________________________________________________________________________________________ +TypeClass CompoundTypeDescriptionImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return _eTypeClass; +} +//__________________________________________________________________________________________________ +OUString CompoundTypeDescriptionImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} + +// XCompoundTypeDescription +//__________________________________________________________________________________________________ +Reference< XTypeDescription > CompoundTypeDescriptionImpl::getBaseType() + throw(::com::sun::star::uno::RuntimeException) +{ + if (!_xBaseTD.is() && _aBaseType.getLength()) + { + MutexGuard aGuard( _aBaseTypeMutex ); + if (!_xBaseTD.is() && _aBaseType.getLength()) + { + try + { + if (extractInterface( _xBaseTD, _xTDMgr->getByHierarchicalName( _aBaseType ) )) + return _xBaseTD; + } + catch (NoSuchElementException &) + { + } + // never try again, if no base td was found + _aBaseType = OUString(); + } + } + return _xBaseTD; +} +//__________________________________________________________________________________________________ +Sequence< Reference< XTypeDescription > > CompoundTypeDescriptionImpl::getMemberTypes() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pMembers) + { + MutexGuard aGuard( _aMembersMutex ); + if (! _pMembers) + { + RegistryTypeReaderLoader aLoader; + RegistryTypeReader aReader( aLoader, (const sal_uInt8 *)_aBytes.getConstArray(), + _aBytes.getLength(), sal_False ); + + sal_uInt16 nFields = (sal_uInt16)aReader.getFieldCount(); + Sequence< Reference< XTypeDescription > > * pTempMembers = + new Sequence< Reference< XTypeDescription > >( nFields ); + Reference< XTypeDescription > * pMembers = pTempMembers->getArray(); + + while (nFields--) + { + try + { + extractInterface( + pMembers[nFields], + _xTDMgr->getByHierarchicalName( + aReader.getFieldType( nFields ).replace( '/', '.' ) ) ); + } + catch (NoSuchElementException &) + { + } + OSL_ENSHURE( pMembers[nFields].is(), "### compound member unknown!" ); + } + + _pMembers = pTempMembers; + } + } + return *_pMembers; +} +//__________________________________________________________________________________________________ +Sequence< OUString > CompoundTypeDescriptionImpl::getMemberNames() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pMemberNames) + { + MutexGuard aGuard( _aMemberNamesMutex ); + if (! _pMemberNames) + { + RegistryTypeReaderLoader aLoader; + RegistryTypeReader aReader( aLoader, (const sal_uInt8 *)_aBytes.getConstArray(), + _aBytes.getLength(), sal_False ); + + sal_uInt16 nFields = (sal_uInt16)aReader.getFieldCount(); + Sequence< OUString > * pTempMemberNames = new Sequence< OUString >( nFields ); + OUString * pMemberNames = pTempMemberNames->getArray(); + + while (nFields--) + { + pMemberNames[nFields] = aReader.getFieldName( nFields ); + } + + _pMemberNames = pTempMemberNames; + } + } + return *_pMemberNames; +} + +} + + diff --git a/stoc/source/registry_tdprovider/tdef.cxx b/stoc/source/registry_tdprovider/tdef.cxx new file mode 100644 index 000000000000..412338c5ad45 --- /dev/null +++ b/stoc/source/registry_tdprovider/tdef.cxx @@ -0,0 +1,108 @@ +/************************************************************************* + * + * $RCSfile: tdef.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "base.hxx" + +namespace stoc_rdbtdp +{ + +// XTypeDescription +//__________________________________________________________________________________________________ +TypeClass TypedefTypeDescriptionImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return TypeClass_TYPEDEF; +} +//__________________________________________________________________________________________________ +OUString TypedefTypeDescriptionImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} + +// XIndirectTypeDescription +//__________________________________________________________________________________________________ +Reference< XTypeDescription > TypedefTypeDescriptionImpl::getReferencedType() + throw(::com::sun::star::uno::RuntimeException) +{ + if (!_xRefTD.is() && _aRefName.getLength()) + { + MutexGuard aGuard( _aRefTDMutex ); + if (!_xRefTD.is() && _aRefName.getLength()) + { + try + { + if (extractInterface( _xRefTD, _xTDMgr->getByHierarchicalName( _aRefName ) )) + return _xRefTD; + } + catch (NoSuchElementException &) + { + } + // never try again, if no base td was found + _aRefName = OUString(); + } + } + return _xRefTD; +} + +} + + diff --git a/stoc/source/registry_tdprovider/tdenum.cxx b/stoc/source/registry_tdprovider/tdenum.cxx new file mode 100644 index 000000000000..5d07495a1a72 --- /dev/null +++ b/stoc/source/registry_tdprovider/tdenum.cxx @@ -0,0 +1,152 @@ +/************************************************************************* + * + * $RCSfile: tdenum.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "base.hxx" + +namespace stoc_rdbtdp +{ + +//__________________________________________________________________________________________________ +EnumTypeDescriptionImpl::~EnumTypeDescriptionImpl() +{ + delete _pEnumNames; + delete _pEnumValues; +} + +// XTypeDescription +//__________________________________________________________________________________________________ +TypeClass EnumTypeDescriptionImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return TypeClass_ENUM; +} +//__________________________________________________________________________________________________ +OUString EnumTypeDescriptionImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} + +// XEnumTypeDescription +//__________________________________________________________________________________________________ +sal_Int32 EnumTypeDescriptionImpl::getDefaultEnumValue() + throw(::com::sun::star::uno::RuntimeException) +{ + return _nDefaultValue; +} +//__________________________________________________________________________________________________ +Sequence< OUString > EnumTypeDescriptionImpl::getEnumNames() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pEnumNames) + { + MutexGuard aGuard( _aEnumNamesMutex ); + if (! _pEnumNames) + { + RegistryTypeReaderLoader aLoader; + RegistryTypeReader aReader( aLoader, (const sal_uInt8 *)_aBytes.getConstArray(), + _aBytes.getLength(), sal_False ); + + sal_uInt16 nFields = (sal_uInt16)aReader.getFieldCount(); + Sequence< OUString > * pTempEnumNames = new Sequence< OUString >( nFields ); + OUString * pEnumNames = pTempEnumNames->getArray(); + + while (nFields--) + { + pEnumNames[nFields] = aReader.getFieldName( nFields ); + } + + _pEnumNames = pTempEnumNames; + } + } + return *_pEnumNames; +} +//__________________________________________________________________________________________________ +Sequence< sal_Int32 > EnumTypeDescriptionImpl::getEnumValues() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pEnumValues) + { + MutexGuard aGuard( _aEnumValuesMutex ); + if (! _pEnumValues) + { + RegistryTypeReaderLoader aLoader; + RegistryTypeReader aReader( aLoader, (const sal_uInt8 *)_aBytes.getConstArray(), + _aBytes.getLength(), sal_False ); + + sal_uInt16 nFields = (sal_uInt16)aReader.getFieldCount(); + Sequence< sal_Int32 > * pTempEnumValues = new Sequence< sal_Int32 >( nFields ); + sal_Int32 * pEnumValues = pTempEnumValues->getArray(); + + while (nFields--) + { + pEnumValues[nFields] = getRTValueAsInt32( aReader.getFieldConstValue( nFields ) ); + } + + _pEnumValues = pTempEnumValues; + } + } + return *_pEnumValues; +} + +} + + diff --git a/stoc/source/registry_tdprovider/tdiface.cxx b/stoc/source/registry_tdprovider/tdiface.cxx new file mode 100644 index 000000000000..ea97705607c3 --- /dev/null +++ b/stoc/source/registry_tdprovider/tdiface.cxx @@ -0,0 +1,662 @@ +/************************************************************************* + * + * $RCSfile: tdiface.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _RTL_USTRBUF_HXX_ +#include <rtl/ustrbuf.hxx> +#endif + +#include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceAttributeTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp> +#include <com/sun/star/reflection/XMethodParameter.hpp> + +#include "base.hxx" + + +namespace stoc_rdbtdp +{ + +//================================================================================================== +class MethodParameterImpl : public WeakImplHelper1< XMethodParameter > +{ + Reference< XHierarchicalNameAccess > _xTDMgr; + + OUString _aName; + OUString _aTypeName; + Mutex _aTypeMutex; + Reference< XTypeDescription > _xType; + + sal_Bool _bIn; + sal_Bool _bOut; + sal_Int32 _nPosition; + +public: + MethodParameterImpl( const Reference< XHierarchicalNameAccess > & xTDMgr, + const OUString & rParamName, const OUString & rParamType, + sal_Bool bIn, sal_Bool bOut, sal_Int32 nPosition ) + : _xTDMgr( xTDMgr ) + , _aName( rParamName ) + , _aTypeName( rParamType ) + , _bIn( bIn ) + , _bOut( bOut ) + , _nPosition( nPosition ) + {} + + // XMethodParameter + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isIn() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isOut() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException); +}; + +// XMethodParameter +//__________________________________________________________________________________________________ +OUString MethodParameterImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} +//__________________________________________________________________________________________________ +Reference<XTypeDescription > MethodParameterImpl::getType() + throw(::com::sun::star::uno::RuntimeException) +{ + if (!_xType.is() && _aTypeName.getLength()) + { + MutexGuard aGuard( _aTypeMutex ); + if (!_xType.is() && _aTypeName.getLength()) + { + try + { + if (extractInterface( _xType, _xTDMgr->getByHierarchicalName( _aTypeName ) )) + return _xType; + } + catch (NoSuchElementException &) + { + } + // never try again, if no td was found + _aTypeName = OUString(); + } + } + return _xType; +} +//__________________________________________________________________________________________________ +sal_Bool MethodParameterImpl::isIn() + throw(::com::sun::star::uno::RuntimeException) +{ + return _bIn; +} +//__________________________________________________________________________________________________ +sal_Bool MethodParameterImpl::isOut() + throw(::com::sun::star::uno::RuntimeException) +{ + return _bOut; +} +//__________________________________________________________________________________________________ +sal_Int32 MethodParameterImpl::getPosition() + throw(::com::sun::star::uno::RuntimeException) +{ + return _nPosition; +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//================================================================================================== +class InterfaceMethodImpl : public WeakImplHelper1< XInterfaceMethodTypeDescription > +{ + Reference< XHierarchicalNameAccess > _xTDMgr; + + OUString _aTypeName; + OUString _aMemberName; + + OUString _aReturnType; + Mutex _aReturnTypeMutex; + Reference< XTypeDescription > _xReturnTD; + + Sequence< sal_Int8 > _aBytes; + sal_uInt16 _nMethodIndex; + Mutex _aParamsMutex; + Sequence< Reference< XMethodParameter > > * _pParams; + Mutex _aExcMutex; + Sequence< Reference< XTypeDescription > > * _pExceptions; + + sal_Bool _bIsOneWay; + sal_Int32 _nPosition; + +public: + InterfaceMethodImpl( const Reference< XHierarchicalNameAccess > & xTDMgr, + const OUString & rTypeName, + const OUString & rMemberName, + const OUString & rReturnType, + const Sequence< sal_Int8 > & rBytes, + sal_uInt16 nMethodIndex, + sal_Bool bIsOneWay, + sal_Int32 nPosition ) + : _xTDMgr( xTDMgr ) + , _aTypeName( rTypeName ) + , _aMemberName( rMemberName ) + , _aReturnType( rReturnType ) + , _aBytes( rBytes ) + , _nMethodIndex( nMethodIndex ) + , _pParams( 0 ) + , _pExceptions( 0 ) + , _bIsOneWay( bIsOneWay ) + , _nPosition( nPosition ) + {} + virtual ~InterfaceMethodImpl(); + + // XTypeDescription + virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + + // XInterfaceMemberTypeDescription + virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException); + + // XInterfaceMethodTypeDescription + virtual Reference< XTypeDescription > SAL_CALL getReturnType() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isOneway() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XMethodParameter > > SAL_CALL getParameters() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< Reference< XTypeDescription > > SAL_CALL getExceptions() throw(::com::sun::star::uno::RuntimeException); +}; +//__________________________________________________________________________________________________ +InterfaceMethodImpl::~InterfaceMethodImpl() +{ + delete _pParams; + delete _pExceptions; +} + +// XTypeDescription +//__________________________________________________________________________________________________ +TypeClass InterfaceMethodImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return TypeClass_INTERFACE_METHOD; +} +//__________________________________________________________________________________________________ +OUString InterfaceMethodImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aTypeName; +} + +// XInterfaceMemberTypeDescription +//__________________________________________________________________________________________________ +OUString InterfaceMethodImpl::getMemberName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aMemberName; +} +//__________________________________________________________________________________________________ +sal_Int32 InterfaceMethodImpl::getPosition() + throw(::com::sun::star::uno::RuntimeException) +{ + return _nPosition; +} + +// XInterfaceMethodTypeDescription +//__________________________________________________________________________________________________ +Reference<XTypeDescription > InterfaceMethodImpl::getReturnType() + throw(::com::sun::star::uno::RuntimeException) +{ + if (!_xReturnTD.is() && _aReturnType.getLength()) + { + MutexGuard aGuard( _aReturnTypeMutex ); + if (!_xReturnTD.is() && _aReturnType.getLength()) + { + try + { + if (extractInterface( _xReturnTD, _xTDMgr->getByHierarchicalName( _aReturnType ) )) + return _xReturnTD; + } + catch (NoSuchElementException &) + { + } + // never try again, if no td was found + _aReturnType = OUString(); + } + } + return _xReturnTD; +} +//__________________________________________________________________________________________________ +sal_Bool InterfaceMethodImpl::isOneway() + throw(::com::sun::star::uno::RuntimeException) +{ + return _bIsOneWay; +} +//__________________________________________________________________________________________________ +Sequence<Reference<XMethodParameter > > InterfaceMethodImpl::getParameters() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pParams) + { + MutexGuard aGuard( _aParamsMutex ); + if (! _pParams) + { + RegistryTypeReaderLoader aLoader; + RegistryTypeReader aReader( aLoader, (const sal_uInt8 *)_aBytes.getConstArray(), + _aBytes.getLength(), sal_False ); + + sal_uInt16 nParams = (sal_uInt16)aReader.getMethodParamCount( _nMethodIndex ); + Sequence< Reference< XMethodParameter > > * pTempParams = + new Sequence< Reference< XMethodParameter > >( nParams ); + Reference< XMethodParameter > * pParams = pTempParams->getArray(); + + while (nParams--) + { + RTParamMode eMode = aReader.getMethodParamMode( _nMethodIndex, nParams ); + + pParams[nParams] = new MethodParameterImpl( + _xTDMgr, + aReader.getMethodParamName( _nMethodIndex, nParams ), + aReader.getMethodParamType( _nMethodIndex, nParams ).replace( '/', '.' ), + (eMode == RT_PARAM_IN || eMode == RT_PARAM_INOUT), + (eMode == RT_PARAM_OUT || eMode == RT_PARAM_INOUT), + nParams ); + } + + _pParams = pTempParams; + } + } + return *_pParams; +} +//__________________________________________________________________________________________________ +Sequence<Reference<XTypeDescription > > InterfaceMethodImpl::getExceptions() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pExceptions) + { + MutexGuard aGuard( _aExcMutex ); + if (! _pExceptions) + { + RegistryTypeReaderLoader aLoader; + RegistryTypeReader aReader( aLoader, (const sal_uInt8 *)_aBytes.getConstArray(), + _aBytes.getLength(), sal_False ); + + sal_uInt16 nExc = (sal_uInt16)aReader.getMethodExcCount( _nMethodIndex ); + Sequence< Reference< XTypeDescription > > * pExceptions = + new Sequence< Reference< XTypeDescription > >( nExc ); + Reference< XTypeDescription > * pExc = pExceptions->getArray(); + + while (nExc--) + { + try + { + OUString aMethodExcName( aReader.getMethodExcType( _nMethodIndex, nExc ) ); + + extractInterface( + pExc[nExc], _xTDMgr->getByHierarchicalName( aMethodExcName.replace( '/', '.' ) ) ); + } + catch (NoSuchElementException &) + { + } + OSL_ENSHURE( pExc[nExc].is(), "### exception type unknown!" ); + } + + _pExceptions = pExceptions; + } + } + return *_pExceptions; +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//================================================================================================== +class InterfaceAttributeImpl : public WeakImplHelper1< XInterfaceAttributeTypeDescription > +{ + Reference< XHierarchicalNameAccess > _xTDMgr; + + OUString _aTypeName; + OUString _aMemberName; + + OUString _aMemberTypeName; + Mutex _aMemberTypeMutex; + Reference< XTypeDescription > _xMemberTD; + + sal_Bool _bReadOnly; + sal_Int32 _nPosition; + +public: + InterfaceAttributeImpl( const Reference< XHierarchicalNameAccess > & xTDMgr, + const OUString & rTypeName, + const OUString & rMemberName, + const OUString & rMemberTypeName, + sal_Bool bReadOnly, + sal_Int32 nPosition ) + : _xTDMgr( xTDMgr ) + , _aTypeName( rTypeName ) + , _aMemberName( rMemberName ) + , _aMemberTypeName( rMemberTypeName ) + , _bReadOnly( bReadOnly ) + , _nPosition( nPosition ) + {} + + // XTypeDescription + virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); + virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); + + // XInterfaceMemberTypeDescription + virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException); + + // XInterfaceAttributeTypeDescription + virtual sal_Bool SAL_CALL isReadOnly() throw(::com::sun::star::uno::RuntimeException); + virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); +}; + +// XTypeDescription +//__________________________________________________________________________________________________ +TypeClass InterfaceAttributeImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return TypeClass_INTERFACE_ATTRIBUTE; +} +//__________________________________________________________________________________________________ +OUString InterfaceAttributeImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aTypeName; +} + +// XInterfaceMemberTypeDescription +//__________________________________________________________________________________________________ +OUString InterfaceAttributeImpl::getMemberName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aMemberName; +} +//__________________________________________________________________________________________________ +sal_Int32 InterfaceAttributeImpl::getPosition() + throw(::com::sun::star::uno::RuntimeException) +{ + return _nPosition; +} + +// XInterfaceAttributeTypeDescription +//__________________________________________________________________________________________________ +sal_Bool InterfaceAttributeImpl::isReadOnly() + throw(::com::sun::star::uno::RuntimeException) +{ + return _bReadOnly; +} +//__________________________________________________________________________________________________ +Reference<XTypeDescription > InterfaceAttributeImpl::getType() + throw(::com::sun::star::uno::RuntimeException) +{ + if (!_xMemberTD.is() && _aMemberTypeName.getLength()) + { + MutexGuard aGuard( _aMemberTypeMutex ); + if (!_xMemberTD.is() && _aMemberTypeName.getLength()) + { + try + { + if (extractInterface( _xMemberTD, _xTDMgr->getByHierarchicalName( _aMemberTypeName ) )) + return _xMemberTD; + } + catch (NoSuchElementException &) + { + } + // never try again, if no td was found + _aMemberTypeName = OUString(); + } + } + return _xMemberTD; +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +InterfaceTypeDescriptionImpl::InterfaceTypeDescriptionImpl( + const Reference< XHierarchicalNameAccess > & xTDMgr, + const OUString & rName, const OUString & rBaseType, + const RTUik & rUik, const Sequence< sal_Int8 > & rBytes ) + : _xTDMgr( xTDMgr ) + , _aName( rName ) + , _aBaseType( rBaseType ) + , _aBytes( rBytes ) + , _pAttributes( 0 ) + , _pMethods( 0 ) +{ + // uik + _aUik.m_Data1 = rUik.m_Data1; + _aUik.m_Data2 = rUik.m_Data2; + _aUik.m_Data3 = rUik.m_Data3; + _aUik.m_Data4 = rUik.m_Data4; + _aUik.m_Data5 = rUik.m_Data5; +} +//__________________________________________________________________________________________________ +InterfaceTypeDescriptionImpl::~InterfaceTypeDescriptionImpl() +{ + delete _pAttributes; + delete _pMethods; +} + +// XTypeDescription +//__________________________________________________________________________________________________ +TypeClass InterfaceTypeDescriptionImpl::getTypeClass() + throw(::com::sun::star::uno::RuntimeException) +{ + return TypeClass_INTERFACE; +} +//__________________________________________________________________________________________________ +OUString InterfaceTypeDescriptionImpl::getName() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aName; +} + +// XInterfaceTypeDescription +//__________________________________________________________________________________________________ +Reference< XTypeDescription > InterfaceTypeDescriptionImpl::getBaseType() + throw(::com::sun::star::uno::RuntimeException) +{ + if (!_xBaseTD.is() && _aBaseType.getLength()) + { + MutexGuard aGuard( _aBaseTypeMutex ); + if (!_xBaseTD.is() && _aBaseType.getLength()) + { + try + { + if (extractInterface( _xBaseTD, _xTDMgr->getByHierarchicalName( _aBaseType ) )) + return _xBaseTD; + } + catch (NoSuchElementException &) + { + } + // never try again, if no base td was found + _aBaseType = OUString(); + } + } + return _xBaseTD; +} +//__________________________________________________________________________________________________ +Uik SAL_CALL InterfaceTypeDescriptionImpl::getUik() + throw(::com::sun::star::uno::RuntimeException) +{ + return _aUik; +} +//__________________________________________________________________________________________________ +Sequence< Reference< XInterfaceMemberTypeDescription > > InterfaceTypeDescriptionImpl::getMembers() + throw(::com::sun::star::uno::RuntimeException) +{ + if (! _pMethods) + { + MutexGuard aGuard( _aMembersMutex ); + if (! _pMethods) + { + RegistryTypeReaderLoader aLoader; + RegistryTypeReader aReader( aLoader, (const sal_uInt8 *)_aBytes.getConstArray(), + _aBytes.getLength(), sal_False ); + sal_uInt16 nMethods = (sal_uInt16)aReader.getMethodCount(); + sal_uInt16 nFields = (sal_uInt16)aReader.getFieldCount(); + + vector< AttributeInit > * pAttributes = new vector< AttributeInit >( nFields ); + vector< MethodInit > * pMethods = new vector< MethodInit >( nMethods ); + + OUString aInterfaceName( getName() ); + + // base offsets + _nBaseOffset = 0; + + Reference< XTypeDescription > xBase( getBaseType(), UNO_QUERY ); + while (xBase.is()) + { + Reference< XInterfaceTypeDescription > xBaseInterface( xBase, UNO_QUERY ); + Sequence< Reference< XInterfaceMemberTypeDescription > > aBaseMembers( xBaseInterface->getMembers() ); + if (aBaseMembers.getLength()) + { + _nBaseOffset = aBaseMembers[aBaseMembers.getLength()-1]->getPosition() +1; + break; + } + xBase = xBaseInterface->getBaseType(); + } + + // all methods + while (nMethods--) + { + OUString aMemberName( aReader.getMethodName( nMethods ) ); + OUStringBuffer aTypeName( aInterfaceName ); + aTypeName.appendAscii( RTL_CONSTASCII_STRINGPARAM("::") ); + aTypeName.append( aMemberName ); + + RTMethodMode eMode = aReader.getMethodMode( nMethods ); + + MethodInit & rInit = pMethods->operator[]( nMethods ); + + rInit.aTypeName = aTypeName.makeStringAndClear(); + rInit.aMemberName = aMemberName; + rInit.aReturnTypeName = aReader.getMethodReturnType( nMethods ).replace( '/', '.' ); + rInit.nMethodIndex = nMethods; + rInit.bOneWay = (eMode == RT_MODE_ONEWAY || eMode == RT_MODE_ONEWAY_CONST); + } + + // all fields + while (nFields--) + { + OUString aMemberName( aReader.getFieldName( nFields ) ); + OUString aMemberType( aReader.getFieldType( nFields ).replace( '/', '.' ) ); + OUStringBuffer aTypeName( aInterfaceName ); + aTypeName.appendAscii( RTL_CONSTASCII_STRINGPARAM("::") ); + aTypeName.append( aMemberName ); + + AttributeInit & rInit = pAttributes->operator[]( nFields ); + + rInit.aTypeName = aTypeName.makeStringAndClear(); + rInit.aMemberName = aMemberName; + rInit.aMemberTypeName = aMemberType; + rInit.bReadOnly = (aReader.getFieldAccess( nFields ) == RT_ACCESS_READONLY); + } + + _pAttributes = pAttributes; + _pMethods = pMethods; + } + } + + // collect members + sal_Int32 nAttributes = _pAttributes->size(); + sal_Int32 nMethods = _pMethods->size(); + + Sequence< Reference< XInterfaceMemberTypeDescription > > aMembers( nAttributes + nMethods ); + Reference< XInterfaceMemberTypeDescription > * pMembers = aMembers.getArray(); + + while (nMethods--) + { + MethodInit & rInit = _pMethods->operator[]( nMethods ); +/* if (! (pMembers[nAttributes+nMethods] = rInit.wxMember).is()) + { + rInit.wxMember = */pMembers[nAttributes+nMethods] = new InterfaceMethodImpl( + _xTDMgr, rInit.aTypeName, rInit.aMemberName, + rInit.aReturnTypeName, _aBytes, rInit.nMethodIndex, + rInit.bOneWay, _nBaseOffset+nAttributes+nMethods ); +// } + } + while (nAttributes--) + { + AttributeInit & rInit = _pAttributes->operator[]( nAttributes ); +/* if (! (pMembers[nAttributes] = rInit.wxMember).is()) + { + rInit.wxMember = */pMembers[nAttributes] = new InterfaceAttributeImpl( + _xTDMgr, rInit.aTypeName, rInit.aMemberName, rInit.aMemberTypeName, + rInit.bReadOnly, _nBaseOffset+nAttributes ); +// } + } + + return aMembers; +} + +} + + diff --git a/stoc/source/registry_tdprovider/tdprovider.cxx b/stoc/source/registry_tdprovider/tdprovider.cxx new file mode 100644 index 000000000000..81021fb338a6 --- /dev/null +++ b/stoc/source/registry_tdprovider/tdprovider.cxx @@ -0,0 +1,528 @@ +/************************************************************************* + * + * $RCSfile: tdprovider.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#ifndef _UNO_DISPATCHER_H_ +#include <uno/dispatcher.h> +#endif +#ifndef _UNO_MAPPING_HXX_ +#include <uno/mapping.hxx> +#endif + +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_COMPONENT_HXX_ +#include <cppuhelper/component.hxx> +#endif +#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ +#include <cppuhelper/typeprovider.hxx> +#endif + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <stl/list> + +#include "base.hxx" + +using namespace com::sun::star::beans; +using namespace com::sun::star::registry; + + +namespace stoc_rdbtdp +{ + +#define SERVICENAME "com.sun.star.reflection.TypeDescriptionProvider" +#define IMPLNAME "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider" + +// typedef list< Reference< XSimpleRegistry > > RegistryList; +typedef list< Reference< XRegistryKey > > RegistryKeyList; + +//-------------------------------------------------------------------------------------------------- +inline static Sequence< OUString > getSupportedServiceNames() +{ + OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ); + return Sequence< OUString >( &aName, 1 ); +} + +//================================================================================================== +class ProviderImpl + : public OComponentHelper + , public XServiceInfo + , public XHierarchicalNameAccess +{ + Mutex _aComponentMutex; + Reference< XMultiServiceFactory > _xSMgr; + Reference< XHierarchicalNameAccess > _xTDMgr; + + Mutex _aListsMutex; +// RegistryList _aOpenRegistries; + RegistryKeyList _aBaseKeys; + RegistryTypeReaderLoader _aLoader; + +public: + ProviderImpl( const Reference< XMultiServiceFactory > & xMgr ); + virtual ~ProviderImpl(); + + // XInterface + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // some XComponent part from OComponentHelper + virtual void SAL_CALL dispose() throw(::com::sun::star::uno::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); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::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); +}; +//__________________________________________________________________________________________________ +ProviderImpl::ProviderImpl( const Reference< XMultiServiceFactory > & xSMgr ) + : OComponentHelper( _aComponentMutex ) + , _xSMgr( xSMgr ) + , _xTDMgr( _xSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.TypeDescriptionManager") ) ), UNO_QUERY ) +{ + OSL_ENSHURE( _xTDMgr.is(), "### cannot get service instance \"com.sun.star.reflection.TypeDescriptionManager\"!" ); +} +//__________________________________________________________________________________________________ +ProviderImpl::~ProviderImpl() +{ +} + +// XInterface +//__________________________________________________________________________________________________ +Any ProviderImpl::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( cppu::queryInterface( + rType, + static_cast< XHierarchicalNameAccess * >( this ), + static_cast< XServiceInfo * >( this ) ) ); + + return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType )); +} +//__________________________________________________________________________________________________ +void ProviderImpl::acquire() throw() +{ + OComponentHelper::acquire(); +} +//__________________________________________________________________________________________________ +void ProviderImpl::release() throw() +{ + OComponentHelper::release(); +} + +// XTypeProvider +//__________________________________________________________________________________________________ +Sequence< Type > ProviderImpl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XServiceInfo > *)0 ), + ::getCppuType( (const Reference< XHierarchicalNameAccess > *)0 ), + OComponentHelper::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > ProviderImpl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// XComponent +//__________________________________________________________________________________________________ +void ProviderImpl::dispose() + throw(::com::sun::star::uno::RuntimeException) +{ + OComponentHelper::dispose(); + + MutexGuard aGuard( _aListsMutex ); + for ( RegistryKeyList::const_iterator iPos( _aBaseKeys.begin() ); + iPos != _aBaseKeys.end(); ++iPos ) + { + (*iPos)->closeKey(); + } + _aBaseKeys.clear(); +// for ( RegistryList::const_iterator iRPos( _aOpenRegistries.begin() ); +// iRPos != _aOpenRegistries.end(); ++iRPos ) +// { +// (*iRPos)->close(); +// } +// _aOpenRegistries.clear(); + + MutexGuard aGuard2( _aComponentMutex ); + _xTDMgr.clear(); + _xSMgr.clear(); +} + +// XServiceInfo +//__________________________________________________________________________________________________ +OUString ProviderImpl::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ); +} +//__________________________________________________________________________________________________ +sal_Bool ProviderImpl::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 > ProviderImpl::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + return stoc_rdbtdp::getSupportedServiceNames(); +} + +// XHierarchicalNameAccess +//__________________________________________________________________________________________________ +Any SAL_CALL ProviderImpl::getByHierarchicalName( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException, com::sun::star::container::NoSuchElementException) +{ + Any aRet; + + if (_aLoader.isLoaded()) // dll is loaded? + { + MutexGuard aGuard( _aListsMutex ); + if (! _aBaseKeys.size()) + { + // DBO TODO: + // listen for registry changes + + // reading from service manager registry for all typelib data + Reference< XPropertySet > xProps( _xSMgr, UNO_QUERY ); + if (xProps.is()) + { + Any aReg( xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Registry") ) ) ); + if (aReg.hasValue() && aReg.getValueTypeClass() == TypeClass_INTERFACE) + { + Reference< XSimpleRegistry > xSource( + *(const Reference< XInterface > *)aReg.getValue(), UNO_QUERY ); + if (xSource->isValid()) + { + Reference< XRegistryKey > xKey( xSource->getRootKey()->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UCR") ) ) ); + if (xKey.is()) + _aBaseKeys.push_back( xKey ); + } + } + } + } + + // read from registry + OUString aKey( rName.replace( '.', '/' ) ); + for ( RegistryKeyList::const_iterator iPos( _aBaseKeys.begin() ); + !aRet.hasValue() && iPos != _aBaseKeys.end(); ++iPos ) + { + Reference< XRegistryKey > xBaseKey( *iPos ); + Reference< XRegistryKey > xKey( xBaseKey->openKey( aKey ) ); + if (xKey.is()) + { + if (xKey->getValueType() == RegistryValueType_BINARY) + { + Sequence< sal_Int8 > aBytes( xKey->getBinaryValue() ); + RegistryTypeReader aReader( _aLoader, + (const sal_uInt8 *)aBytes.getConstArray(), + aBytes.getLength(), + sal_False ); + + OUString aName( aReader.getTypeName().replace( '/', '.' ) ); + + switch (aReader.getTypeClass()) + { + case RT_TYPE_INTERFACE: + { + RTUik aUik; + aReader.getUik( aUik ); + aRet <<= Reference< XTypeDescription >( new InterfaceTypeDescriptionImpl( + _xTDMgr, aName, + aReader.getSuperTypeName().replace( '/', '.' ), + aUik, aBytes ) ); + break; + } + case RT_TYPE_EXCEPTION: + aRet <<= Reference< XTypeDescription >( new CompoundTypeDescriptionImpl( + _xTDMgr, TypeClass_EXCEPTION, aName, + aReader.getSuperTypeName().replace( '/', '.' ), + aBytes ) ); + break; + case RT_TYPE_STRUCT: + aRet <<= Reference< XTypeDescription >( new CompoundTypeDescriptionImpl( + _xTDMgr, TypeClass_STRUCT, aName, + aReader.getSuperTypeName().replace( '/', '.' ), + aBytes ) ); + break; + case RT_TYPE_ENUM: + aRet <<= Reference< XTypeDescription >( new EnumTypeDescriptionImpl( + _xTDMgr, aName, + getRTValueAsInt32( aReader.getFieldConstValue( 0 ) ), + aBytes ) ); + break; + case RT_TYPE_TYPEDEF: + aRet <<= Reference< XTypeDescription >( new TypedefTypeDescriptionImpl( + _xTDMgr, aName, + aReader.getSuperTypeName().replace( '/', '.' ) ) ); + break; + +/* // these following are in question + case RT_TYPE_MODULE: + aRet <<= Reference< XTypeDescription >( new TypeDescriptionImpl( + TypeClass_MODULE, aName ) ); + break; + case RT_TYPE_SERVICE: + aRet <<= Reference< XTypeDescription >( new TypeDescriptionImpl( + TypeClass_SERVICE, aName ) ); + break; +// case RT_TYPE_INVALID: +// case RT_TYPE_CONSTANTS: +// case RT_TYPE_OBJECT: + default: // existing registry node + aRet <<= Reference< XTypeDescription >( new TypeDescriptionImpl( + TypeClass_UNKNOWN, aName ) ); + break; +*/ + } + } + xKey->closeKey(); + } + else // might be a constant + { + sal_Int32 nIndex = aKey.lastIndexOf( '/' ); + if (nIndex > 0) + { + // open module + Reference< XRegistryKey > xKey( xBaseKey->openKey( aKey.copy( 0, nIndex ) ) ); + if (xKey.is()) + { + if (xKey->getValueType() == RegistryValueType_BINARY) + { + Sequence< sal_Int8 > aBytes( xKey->getBinaryValue() ); + RegistryTypeReader aReader( + _aLoader, (const sal_uInt8 *)aBytes.getConstArray(), + aBytes.getLength(), sal_False ); + + if (aReader.getTypeClass() == RT_TYPE_MODULE || + aReader.getTypeClass() == RT_TYPE_CONSTANTS || + aReader.getTypeClass() == RT_TYPE_ENUM) + { + OUString aFieldName( aKey.copy( nIndex+1, aKey.getLength() - nIndex -1 ) ); + sal_Int32 nPos = aReader.getFieldCount(); + while (nPos--) + { + if ( aFieldName.equals( aReader.getFieldName( (sal_uInt16)nPos )) ) + break; + } + if (nPos >= 0) + aRet = getRTValue( aReader.getFieldConstValue( nPos ) ); + } + } + xKey->closeKey(); + } + } + } + } + } + + if (! aRet.hasValue()) + { + NoSuchElementException aExc; + aExc.Message = rName; + throw aExc; + } + return aRet; +} +//__________________________________________________________________________________________________ +sal_Bool ProviderImpl::hasByHierarchicalName( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + try + { + return getByHierarchicalName( rName ).hasValue(); + } + catch (NoSuchElementException &) + { + } + return sal_False; +} + +//================================================================================================== +static Reference< XInterface > SAL_CALL ProviderImpl_create( const Reference< XMultiServiceFactory > & xMgr ) + throw(::com::sun::star::uno::Exception) +{ + return Reference< XInterface >( *new ProviderImpl( xMgr ) ); +} + +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) ); + + const Sequence< OUString > & rSNL = stoc_rdbtdp::getSupportedServiceNames(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ), + stoc_rdbtdp::ProviderImpl_create, + stoc_rdbtdp::getSupportedServiceNames() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + diff --git a/stoc/source/servicemanager/makefile.mk b/stoc/source/servicemanager/makefile.mk new file mode 100644 index 000000000000..fe8980004a31 --- /dev/null +++ b/stoc/source/servicemanager/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= smgr +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +BOOTSTRAP_SERVICE=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + + +SLOFILES= \ + $(SLO)$/servicemanager.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/stoc/source/servicemanager/servicemanager.cxx b/stoc/source/servicemanager/servicemanager.cxx new file mode 100644 index 000000000000..4613d3669d1f --- /dev/null +++ b/stoc/source/servicemanager/servicemanager.cxx @@ -0,0 +1,1422 @@ +/************************************************************************* + * + * $RCSfile: servicemanager.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _RTL_USTRBUF_HXX_ +#include <rtl/ustrbuf.hxx> +#endif + +#include <stl/hash_map> +#include <stl/hash_set> + +#ifndef _UNO_MAPPING_HXX_ +#include <uno/mapping.hxx> +#endif +#ifndef _UNO_DISPATCHER_H_ +#include <uno/dispatcher.h> +#endif +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CPPUHELPER_WEAKREF_HXX_ +#include <cppuhelper/weakref.hxx> +#endif +#ifndef _CPPUHELPER_COMPONENT_HXX_ +#include <cppuhelper/component.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE1_HXX +#include <cppuhelper/implbase1.hxx> +#endif +#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ +#include <cppuhelper/typeprovider.hxx> +#endif + + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/container/XSet.hpp> +#include <com/sun/star/container/XElementAccess.hpp> +#include <com/sun/star/container/XEnumeration.hpp> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> + +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::registry; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; +using namespace cppu; +using namespace osl; +using namespace rtl; +using namespace std; + +namespace stoc_smgr +{ + +/***************************************************************************** + helper functions +*****************************************************************************/ +OUString Point2Slash(const OUString& s) +{ + static OUString slash( RTL_CONSTASCII_USTRINGPARAM("/") ); + + OUString ret; + + sal_Int32 tokenCount = s.getTokenCount(L'.'); + + for (sal_Int32 i = 0; i < tokenCount; i++) + { + OUString token = s.getToken(i, L'.'); + + if (token.len()) + ret = ret + slash + token; + } + + return ret; +} + +/***************************************************************************** + Enumeration by ServiceName +*****************************************************************************/ +struct hashRef_Impl +{ + size_t operator()(const Reference<XInterface > & rName) const + { + // query to XInterface. The cast to XInterface* must be the same for the same object + Reference<XInterface > x( Reference<XInterface >::query( rName ) ); + return (size_t)x.get(); + } +}; + +struct equaltoRef_Impl +{ + size_t operator()(const Reference<XInterface > & rName1, const Reference<XInterface > & rName2 ) const + { return rName1 == rName2; } +}; + +typedef hash_set +< + Reference<XInterface >, + hashRef_Impl, + equaltoRef_Impl +> HashSet_Ref; + + +class ServiceEnumeration_Impl : public WeakImplHelper1< XEnumeration > +{ +public: + ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories ) + : aFactories( rFactories ) + , nIt( 0 ) + {} + virtual ~ServiceEnumeration_Impl() {}; + + // XEnumeration + sal_Bool SAL_CALL hasMoreElements() + throw(::com::sun::star::uno::RuntimeException); + Any SAL_CALL nextElement() + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); +private: + Mutex aMutex; + Sequence< Reference<XInterface > > aFactories; + sal_Int32 nIt; +}; + +// XEnumeration +sal_Bool ServiceEnumeration_Impl::hasMoreElements() throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( aMutex ); + return nIt != aFactories.getLength(); +} + +// XEnumeration +Any ServiceEnumeration_Impl::nextElement() + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( aMutex ); + if( nIt == aFactories.getLength() ) + throw NoSuchElementException(); + + return Any( &aFactories.getConstArray()[nIt++], ::getCppuType( (const Reference<XInterface > *)0 ) ); +} + +/***************************************************************************** + Enumeration by implementation +*****************************************************************************/ +class ImplementationEnumeration_Impl : public WeakImplHelper1< XEnumeration > +{ +public: + ImplementationEnumeration_Impl( const HashSet_Ref & rImplementationMap ) + : aImplementationMap( rImplementationMap ) + , aIt( aImplementationMap.begin() ) + {} + virtual ~ImplementationEnumeration_Impl(); + + // 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); + +private: + Mutex aMutex; + HashSet_Ref aImplementationMap; + HashSet_Ref::iterator aIt; + sal_Int32 nNext; + Reference<XInterface > xNext; +}; + +ImplementationEnumeration_Impl::~ImplementationEnumeration_Impl() +{ +} + +// XEnumeration +sal_Bool ImplementationEnumeration_Impl::hasMoreElements() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( aMutex ); + return aIt != aImplementationMap.end(); +} + +// XEnumeration +Any ImplementationEnumeration_Impl::nextElement() + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( aMutex ); + if( aIt == aImplementationMap.end() ) + throw NoSuchElementException(); + + Any ret( &(*aIt), ::getCppuType( (const Reference<XInterface > *)0 ) ); + ++aIt; + return ret; +} + +/***************************************************************************** + Hash tables +*****************************************************************************/ +struct equalOWString_Impl +{ + sal_Bool operator()(const OUString & s1, const OUString & s2) const + { return s1 == s2; } +}; + +struct hashOWString_Impl +{ + size_t operator()(const OUString & rName) const + { return rName.hashCode(); } +}; + +typedef hash_set +< + OUString, + hashOWString_Impl, + equalOWString_Impl +> HashSet_OWString; + +typedef hash_multimap +< + OUString, + Reference<XInterface >, + hashOWString_Impl, + equalOWString_Impl +> HashMultimap_OWString_Interface; + +typedef hash_map +< + OUString, + Reference<XInterface >, + hashOWString_Impl, + equalOWString_Impl +> HashMap_OWString_Interface; + +/***************************************************************************** + class OServiceManager_Listener +*****************************************************************************/ +class OServiceManager_Listener : public WeakImplHelper1< XEventListener > +{ +private: + WeakReference<XSet > xSMgr; + +public: + OServiceManager_Listener( const Reference<XSet > & rSMgr ) + : xSMgr( rSMgr ) + {} + + // XEventListener + virtual void SAL_CALL disposing(const EventObject & rEvt ) throw(::com::sun::star::uno::RuntimeException); +}; + +void OServiceManager_Listener::disposing(const EventObject & rEvt ) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference<XSet > x( xSMgr ); + if( x.is() ) + { + try + { + x->remove( Any( &rEvt.Source, ::getCppuType( (const Reference<XInterface > *)0 ) ) ); + } + catch( const IllegalArgumentException & ) + { + OSL_ENSHURE( sal_False, "IllegalArgumentException catched" ); + } + catch( const NoSuchElementException & ) + { + OSL_ENSHURE( sal_False, "NoSuchElementException catched" ); + } + } +} + + +/***************************************************************************** + class OServiceManager +*****************************************************************************/ +struct OServiceManagerMutex +{ + Mutex m_mutex; +}; + +class OServiceManager + : public XMultiServiceFactory + , public XSet + , public XContentEnumerationAccess + , public XServiceInfo + , public OServiceManagerMutex + , public OComponentHelper +{ +public: + OServiceManager(); + ~OServiceManager(); + + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw() + { OComponentHelper::acquire(); } + virtual void SAL_CALL release() throw() + { OComponentHelper::release(); } + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + static OUString getImplementationName_Static() throw(::com::sun::star::uno::RuntimeException) + { return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.OServiceManager") ); } + virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + static Sequence< OUString > getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException); + + // XMultiServiceFactory + virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(::com::sun::star::uno::RuntimeException); + virtual Reference<XInterface > SAL_CALL createInstance(const OUString &) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString &, const Sequence<Any >& Arguments) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // The same as the interface method, but only uique names + Sequence< OUString > getAvailableServiceNames( HashSet_OWString & aNameSet ); + + // 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 & Element ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL insert( const Any & Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL remove( const Any & Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); + + // XContentEnumerationAccess + //Sequence< OUString > getAvailableServiceNames() throw( (Exception) ); + virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); + +protected: + sal_Bool haveFactoryWithThisImplementation(const OUString& aImplName); + + virtual Reference<XSingleServiceFactory > queryServiceFactory(const OUString& aServiceName); +private: + + Reference<XEventListener > getFactoryListener(); + + HashMultimap_OWString_Interface m_ServiceMap; + HashSet_Ref m_ImplementationMap; + HashMap_OWString_Interface m_ImplementationNameMap; + Reference<XEventListener > xFactoryListener; +}; + +/** + * Create a ServiceManager + */ +OServiceManager::OServiceManager() + : OComponentHelper( m_mutex ) +{ +} + +/** + * Destroy the ServiceManager + */ +OServiceManager::~OServiceManager() +{ +} + +// OComponentHelper +void OServiceManager::dispose() + throw(::com::sun::star::uno::RuntimeException) +{ + // notify the disposing listener, the service manager is still full alive + EventObject aEvt; + aEvt.Source = Reference<XInterface >( *this ); + rBHelper.aLC.disposeAndClear( aEvt ); + + // dispose all factories + HashSet_Ref aImpls; + { + MutexGuard aGuard( m_mutex ); + aImpls = m_ImplementationMap; + } + HashSet_Ref::iterator aIt = aImpls.begin(); + while( aIt != aImpls.end() ) + { + Reference<XComponent > xComp( Reference<XComponent >::query( *aIt++ ) ); + if( xComp.is() ) + xComp->dispose(); + } + + // set the service manager to disposed + OComponentHelper::dispose(); + + // dispose + HashSet_Ref aImplMap; + { + MutexGuard aGuard( m_mutex ); + // erase all members + m_ServiceMap = HashMultimap_OWString_Interface(); + aImplMap = m_ImplementationMap; + m_ImplementationMap = HashSet_Ref(); + m_ImplementationNameMap = HashMap_OWString_Interface(); + } + + // not only the Event should hold the object + OSL_ASSERT( m_refCount != 1 ); +} + +// XTypeProvider +Sequence< Type > OServiceManager::getTypes() + throw(::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * s_pTypes = 0; + if (! s_pTypes) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pTypes) + { + static OTypeCollection s_aTypes( + ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ), + ::getCppuType( (const Reference< XSet > *)0 ), + ::getCppuType( (const Reference< XContentEnumerationAccess > *)0 ), + ::getCppuType( (const Reference< XServiceInfo > *)0 ), + OComponentHelper::getTypes() ); + s_pTypes = &s_aTypes; + } + } + return s_pTypes->getTypes(); +} +Sequence< sal_Int8 > OServiceManager::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * s_pId = 0; + if (! s_pId) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pId) + { + static OImplementationId s_aId; + s_pId = &s_aId; + } + } + return s_pId->getImplementationId(); +} + +// OServiceManager +Reference<XEventListener > OServiceManager::getFactoryListener() +{ + MutexGuard aGuard( m_mutex ); + if( !xFactoryListener.is() ) + xFactoryListener = new OServiceManager_Listener( this ); + return xFactoryListener; +} + +// XInterface +Any OServiceManager::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( + rType, + static_cast< XMultiServiceFactory * >( this ), + static_cast< XServiceInfo * >( this ), + static_cast< XContentEnumerationAccess *>( this ), + static_cast< XSet *>( this ), + static_cast< XEnumerationAccess *>( this ), + static_cast< XElementAccess *>( this ) ) ); + + return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType )); +} + +// XMultiServiceFactory, XContentEnumeration +Sequence< OUString > OServiceManager::getAvailableServiceNames( HashSet_OWString & aNameSet ) +{ + MutexGuard aGuard( m_mutex ); + + HashMultimap_OWString_Interface::iterator aSIt = m_ServiceMap.begin(); + while( aSIt != m_ServiceMap.end() ) + aNameSet.insert( (*aSIt++).first ); + + /* do not return the implementation names + HashMap_OWString_Interface m_ImplementationNameMap; + HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.begin(); + while( aIt != m_ImplementationNameMap.end() ) + aNameSet.insert( (*aIt++).first ); + */ + + Sequence< OUString > aNames( aNameSet.size() ); + OUString * pArray = aNames.getArray(); + sal_Int32 i = 0; + HashSet_OWString::iterator next = aNameSet.begin(); + while( next != aNameSet.end() ) + pArray[i++] = (*next++); + + return aNames; +} + +// XMultiServiceFactory, XContentEnumeration +Sequence< OUString > OServiceManager::getAvailableServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + // all names + HashSet_OWString aNameSet; + return getAvailableServiceNames( aNameSet ); +} + +// XMultibleServiceFactory +Reference<XInterface > OServiceManager::createInstance(const OUString& ServiceSpecifier ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + ClearableMutexGuard aGuard( m_mutex ); + + Reference<XSingleServiceFactory > xFactory( queryServiceFactory( ServiceSpecifier ) ); + + Reference<XInterface > xRet; + if( xFactory.is() ) + { + aGuard.clear(); + xRet = xFactory->createInstance(); + } + return xRet; +} + +// XMultibleServiceFactory +Reference<XInterface > OServiceManager::createInstanceWithArguments +( + const OUString& ServiceSpecifier, + const Sequence<Any >& Arguments +) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + ClearableMutexGuard aGuard( m_mutex ); + Reference<XInterface > xRet; + Reference<XSingleServiceFactory > xFactory( queryServiceFactory( ServiceSpecifier ) ); + aGuard.clear(); + + if( xFactory.is() ) + { + // single service factory found + if( Arguments.getLength() ) + xRet = xFactory->createInstanceWithArguments( Arguments ); + else + xRet = xFactory->createInstance(); + } +// else if( Arguments.getLength() +// && !Arguments.getConstArray()[0].hasValue() ) +// { + // JSC: muss noch mal ueberdacht werden !!!! + /* + // multible service factory found + XMultiServiceFactoryRef xFactory( xProv, USR_QUERY ); + if( xFactory.is() ) + { + OUString aNextServiceSpecifier = Arguments.getConstArray()[0].getString(); + // Remove the first element from the argument list + Sequence<UsrAny> aNewArgs = Arguments; + SequenceRemoveElementAt( aNewArgs, 0 ); + // create instance + if( aNewArgs.getLen() ) + xRet = xFactory->createInstanceWithArguments( aNextServiceSpecifier, aNewArgs ); + else + xRet = xFactory->createInstance( aNextServiceSpecifier ); + } + */ +// } + + return xRet; +} + +// XServiceInfo +OUString OServiceManager::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return getImplementationName_Static(); +} + +// XServiceInfo +sal_Bool OServiceManager::supportsService(const OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException) +{ + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +// XServiceInfo +Sequence< OUString > OServiceManager::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + return getSupportedServiceNames_Static(); +} + +// OServiceManager_Static +Sequence< OUString > OServiceManager::getSupportedServiceNames_Static() + throw(::com::sun::star::uno::RuntimeException) +{ + Sequence< OUString > aSNS( 2 ); + aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory") ); + aSNS.getArray()[1] = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.ServiceManager") ); + return aSNS; +} + +Reference<XSingleServiceFactory > OServiceManager::queryServiceFactory(const OUString& aServiceName) +{ + MutexGuard aGuard( m_mutex ); + Reference<XSingleServiceFactory > xRet; + + HashMultimap_OWString_Interface::iterator aMultiIt = + ((OServiceManager*)this)->m_ServiceMap.find( aServiceName ); + if( aMultiIt == ((OServiceManager*)this)->m_ServiceMap.end() ) + { + // no service found, look for an implementation + HashMap_OWString_Interface::iterator aIt = + ((OServiceManager*)this)->m_ImplementationNameMap.find( aServiceName ); + if( aIt != ((OServiceManager*)this)->m_ImplementationNameMap.end() ) + // an implementation found + xRet = Reference<XSingleServiceFactory >::query( (*aIt).second ); + } + else + { + xRet = Reference<XSingleServiceFactory >::query( (*aMultiIt).second ); + } + + return xRet; +} + +// XContentEnumerationAccess +Reference<XEnumeration > OServiceManager::createContentEnumeration(const OUString& aServiceName) + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( ((OServiceManager *)this)->m_mutex ); + + // get all factories + pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> + p = ((OServiceManager *)this)->m_ServiceMap.equal_range( aServiceName ); + + if( p.first == p.second ) + // nothing + return Reference<XEnumeration >(); + + // get the length of the sequence + sal_Int32 nLen = 0; + HashMultimap_OWString_Interface::iterator next = p.first; + while( next != p.second ) + { + nLen++; + next++; + } + + Sequence< Reference<XInterface > > aFactories( nLen ); + Reference<XInterface > * pArray = aFactories.getArray(); + sal_Int32 i = 0; + while( p.first != p.second ) + { + pArray[i++] = (*p.first).second; + p.first++; + } + return new ServiceEnumeration_Impl( aFactories ); +} + +// XEnumeration +Reference<XEnumeration > OServiceManager::createEnumeration() throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( m_mutex ); + return new ImplementationEnumeration_Impl( m_ImplementationMap ); +} + +// XElementAccess +Type OServiceManager::getElementType() + throw(::com::sun::star::uno::RuntimeException) +{ + return ::getCppuType( (const Reference< XInterface > *)0 ); +} + +// XElementAccess +sal_Bool OServiceManager::hasElements() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( m_mutex ); + return !m_ImplementationMap.empty(); +} + +// XSet +sal_Bool OServiceManager::has( const Any & Element ) + throw(::com::sun::star::uno::RuntimeException) +{ + if( Element.getValueTypeClass() == TypeClass_INTERFACE ) + { + MutexGuard aGuard( m_mutex ); + HashSet_Ref::iterator aIt = + ((OServiceManager*)this)->m_ImplementationMap.find( *(Reference<XInterface >*)Element.getValue() ); + return aIt != m_ImplementationMap.end(); + } + return sal_False; +} + +// XSet +void OServiceManager::insert( const Any & Element ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException) +{ + if( Element.getValueTypeClass() != TypeClass_INTERFACE ) + throw IllegalArgumentException(); + Reference<XInterface > xEle( *(Reference<XInterface >*)Element.getValue(), UNO_QUERY ); + if( !xEle.is() ) + throw IllegalArgumentException(); + + { + MutexGuard aGuard( m_mutex ); + HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle ); + if( aIt != m_ImplementationMap.end() ) + throw ElementExistException(); + + // put into the implementation hashmap + m_ImplementationMap.insert( xEle ); + + // put into the implementation name hashmap + Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) ); + if( xInfo.is() ) + { + OUString aImplName = xInfo->getImplementationName(); + if( aImplName.len() ) + m_ImplementationNameMap[ aImplName ] = xEle; + } + + //put into the service map + Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) ); + if( xSF.is() ) + { + Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames(); + const OUString * pArray = aServiceNames.getConstArray(); + for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ ) + m_ServiceMap.insert( HashMultimap_OWString_Interface::value_type( pArray[i], + *(Reference<XInterface > *)Element.getValue() ) ); + } + } + // add the disposing listener to the factory + Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) ); + if( xComp.is() ) + xComp->addEventListener( getFactoryListener() ); +} + +// helper function +sal_Bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName) +{ + if( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end()) + return sal_True; + else + return sal_False; +} + +// XSet +void OServiceManager::remove( const Any & Element ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException) +{ + if( Element.getValueTypeClass() != TypeClass_INTERFACE ) + throw IllegalArgumentException(); + Reference<XInterface > xEle = *(Reference<XInterface > *)Element.getValue(); + if( !xEle.is() ) + throw IllegalArgumentException(); + + // remove the disposing listener from the factory + Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) ); + if( xComp.is() ) + xComp->removeEventListener( getFactoryListener() ); + + MutexGuard aGuard( m_mutex ); + HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle ); + if( aIt == m_ImplementationMap.end() ) + throw NoSuchElementException(); + + // remove from the implementation map + m_ImplementationMap.erase( aIt ); + // remove from the implementation name hashmap + Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) ); + if( xInfo.is() ) + { + OUString aImplName = xInfo->getImplementationName(); + if( aImplName.len() ) + m_ImplementationNameMap.erase( aImplName ); + } + + //remove from the service map + Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) ); + if( xSF.is() ) + { + Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames(); + const OUString * pArray = aServiceNames.getConstArray(); + for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ ) + { + pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> p = + m_ServiceMap.equal_range( pArray[i] ); + + while( p.first != p.second ) + { + if( xEle == (*p.first).second ) + { + m_ServiceMap.erase( p.first ); + break; + } + p.first++; + } + } + } +} + +/***************************************************************************** + class ORegistryServiceManager +*****************************************************************************/ +class ORegistryServiceManager + : public XInitialization + , public XPropertySet + , public OServiceManager +{ +public: + ORegistryServiceManager(); + ~ORegistryServiceManager(); + + Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + void SAL_CALL acquire() throw() + { OServiceManager::acquire(); } + void SAL_CALL release() throw() + { OServiceManager::release(); } + + // XInitialization + void SAL_CALL initialize(const Sequence< Any >& Arguments) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + static OUString getImplementationName_Static() throw(::com::sun::star::uno::RuntimeException) + { return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.ORegistryServiceManager") ); } + + //sal_Bool supportsService(const OUString& ServiceName) throw( () ); + Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + static Sequence< OUString > getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException); + + // XMultiServiceFactory + Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // XTypeProvider + Sequence< Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); + Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); + + // XContentEnumerationAccess + //Sequence< OUString > getAvailableServiceNames() throw( (Exception) ); + Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(::com::sun::star::uno::RuntimeException); + + // XComponent + void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); + + // XPropertySet + Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() + throw(::com::sun::star::uno::RuntimeException); + void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + Any SAL_CALL getPropertyValue(const OUString& PropertyName) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + +protected: + //OServiceManager + Reference<XSingleServiceFactory > queryServiceFactory(const OUString& aServiceName); +private: + + Reference<XRegistryKey > getRootKey(); + Reference<XSingleServiceFactory > loadWithImplementationName( const OUString & rImplName ); + Sequence<OUString> getFromServiceName(const OUString& serviceName); + Reference<XSingleServiceFactory > loadWithServiceName( const OUString & rImplName ); + void fillAllNamesFromRegistry( HashSet_OWString & ); + + sal_Bool m_searchedRegistry; + Reference<XSimpleRegistry > m_xRegistry; // readonly property Registry + Reference<XRegistryKey > m_xRootKey; +}; + +/** + * Create a ServiceManager + */ +ORegistryServiceManager::ORegistryServiceManager() + : m_searchedRegistry(sal_False) +{ +} + +/** + * Destroy the ServiceManager + */ +ORegistryServiceManager::~ORegistryServiceManager() +{ +} + +// OComponentHelper +void ORegistryServiceManager::dispose()throw(::com::sun::star::uno::RuntimeException) +{ + OServiceManager::dispose(); + // dispose + MutexGuard aGuard( m_mutex ); + // erase all members + m_xRegistry = Reference<XSimpleRegistry >(); + m_xRootKey = Reference<XRegistryKey >(); +} + +// XTypeProvider +Sequence< Type > ORegistryServiceManager::getTypes() + throw(::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * pTypes = 0; + if (! pTypes) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! pTypes) + { + static OTypeCollection aTypes( + ::getCppuType( (const Reference< XPropertySet > *)0 ), + ::getCppuType( (const Reference< XInitialization > *)0 ), + OServiceManager::getTypes() ); + pTypes = &aTypes; + } + } + return pTypes->getTypes(); +} +Sequence< sal_Int8 > ORegistryServiceManager::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * pId = 0; + if (! pId) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! pId) + { + static OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); +} + +/** + * Return the root key of the registry. The Default registry service is ordered + * if no registry is set. + */ +//Reference<XServiceProvider > create_DefaultRegistry_ServiceProvider(); + +Reference<XRegistryKey > ORegistryServiceManager::getRootKey() +{ + MutexGuard aGuard( m_mutex ); + { + // DefaultRegistry suchen !!!! + if( !m_xRegistry.is() && !m_searchedRegistry ) + { + // merken, es wird nur einmal gesucht + m_searchedRegistry = sal_True; + + Reference<XSingleServiceFactory > xFact = queryServiceFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.DefaultRegistry") ) ); + if ( xFact.is() ) + { + m_xRegistry = Reference<XSimpleRegistry >::query( xFact->createInstance() ); + } + } + + if( m_xRegistry.is() && !m_xRootKey.is() ) + m_xRootKey = m_xRegistry->getRootKey(); + return m_xRootKey; + } +} + +/** + * Create a service provider from the registry with an implementation name + */ +Reference<XSingleServiceFactory > ORegistryServiceManager::loadWithImplementationName(const OUString& name) +{ + Reference<XSingleServiceFactory > ret; + + Reference<XRegistryKey > xRootKey = getRootKey(); + if( !xRootKey.is() ) + return ret; + + try + { + OUString implementationName = OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS/") ) + name; + Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName); + + if( xImpKey.is() ) + { + ret = createSingleRegistryFactory( this, name, xImpKey ); + Any a( &ret, ::getCppuType( (const Reference<XInterface > *)0 ) ); + insert( a ); + } + } + catch (InvalidRegistryException &) + { + } + return ret; +} + +/** + * Return all implementation out of the registry. + */ +Sequence<OUString> ORegistryServiceManager::getFromServiceName(const OUString& serviceName) +{ + Reference<XRegistryKey > xRootKey = getRootKey(); + if( !xRootKey.is() ) + return Sequence<OUString>(); + + try + { + OUString regName = OUString( RTL_CONSTASCII_USTRINGPARAM("/SERVICES/") ) + serviceName; + Reference<XRegistryKey > xServKey = m_xRootKey->openKey(regName); + + if( xServKey.is() && xServKey->getValueType() == RegistryValueType_ASCIILIST ) + { + return xServKey->getAsciiListValue(); + } + } + catch (InvalidRegistryException &) + { + } + + return Sequence<OUString>(); +} + +/** + * Create a service provider from the registry + */ +Reference<XSingleServiceFactory > ORegistryServiceManager::loadWithServiceName(const OUString& serviceName) +{ + Sequence<OUString> implEntries = getFromServiceName( serviceName ); + for (sal_Int32 i = 0; i < implEntries.getLength(); i++) + return loadWithImplementationName( implEntries.getConstArray()[i] ); + + return Reference<XSingleServiceFactory >(); +} + +/** + * Return a sequence of all service names from the registry. + */ +void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet ) +{ + Reference<XRegistryKey > xRootKey = getRootKey(); + if( !xRootKey.is() ) + return; + + try + { + Reference<XRegistryKey > xServicesKey = xRootKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("SERVICES") ) ); + // root + /Services + / + if( xServicesKey.is() ) + { + sal_Int32 nPrefix = xServicesKey->getKeyName().len() +1; + Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys(); + for( sal_Int32 i = 0; i < aKeys.getLength(); i++ ) + rSet.insert( aKeys.getConstArray()[i]->getKeyName().copy( nPrefix ) ); + } + } + catch (InvalidRegistryException &) + { + } +} + +// XInterface +Any ORegistryServiceManager::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( cppu::queryInterface( + rType, + static_cast< XInitialization * >( this ), + static_cast< XPropertySet * >( this ) ) ); + + return (aRet.hasValue() ? aRet : OServiceManager::queryInterface( rType )); +} + +// XInitialization +void ORegistryServiceManager::initialize(const Sequence< Any >& Arguments) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + if( Arguments.getLength() == 0 ) + return; + if( Arguments.getLength() != 1 + || Arguments.getConstArray()[0].getValueTypeClass() != TypeClass_INTERFACE ) + throw IllegalArgumentException(); + + Reference<XSimpleRegistry > xRef( Reference<XSimpleRegistry >::query( + *(Reference<XInterface > *)Arguments.getConstArray()[0].getValue() ) ); + if( !xRef.is() ) + throw IllegalArgumentException(); + + MutexGuard aGuard( m_mutex ); + m_xRegistry = xRef; + m_xRootKey = Reference<XRegistryKey >(); +} + +// XMultiServiceFactory, XContentEnumeration +Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( m_mutex ); + // all names + HashSet_OWString aNameSet; + + // all names from the registry + fillAllNamesFromRegistry( aNameSet ); + + return OServiceManager::getAvailableServiceNames( aNameSet ); +} + +// XServiceInfo +OUString ORegistryServiceManager::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return getImplementationName_Static(); +} + +// XServiceInfo +Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException) +{ + return getSupportedServiceNames_Static(); +} + +// ORegistryServiceManager_Static +Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames_Static() + throw(::com::sun::star::uno::RuntimeException) +{ + Sequence< OUString > aSNS( 2 ); + aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory") ); + aSNS.getArray()[1] = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.RegistryServiceManager") ); + return aSNS; +} + +// OServiceManager +Reference<XSingleServiceFactory > ORegistryServiceManager::queryServiceFactory(const OUString& aServiceName) +{ + Reference<XSingleServiceFactory > xRet = OServiceManager::queryServiceFactory( aServiceName ); + if( !xRet.is() ) + { + MutexGuard aGuard( m_mutex ); + xRet = ((ORegistryServiceManager *)this)->loadWithServiceName( aServiceName ); + if( !xRet.is() ) + xRet = ((ORegistryServiceManager *)this)->loadWithImplementationName( aServiceName ); + } + + return xRet; +} + +// XContentEnumerationAccess +Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(const OUString& aServiceName) + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( ((ORegistryServiceManager *)this)->m_mutex ); + // get all implementation names registered under this service name from the registry + Sequence<OUString> aImpls = ((ORegistryServiceManager *)this)->getFromServiceName( aServiceName ); + // load and insert all factories specified by the registry + sal_Int32 i; + OUString aImplName; + for( i = 0; i < aImpls.getLength(); i++ ) + { + aImplName = aImpls.getConstArray()[i]; + if ( !haveFactoryWithThisImplementation(aImplName) ) + { + loadWithImplementationName( aImplName ); + } + } + // call the superclass to enumerate all contents + return OServiceManager::createContentEnumeration( aServiceName ); +} + +// XPropertySet +Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo() + throw(::com::sun::star::uno::RuntimeException) +{ + return Reference<XPropertySetInfo >(); +} + +void ORegistryServiceManager::setPropertyValue(const OUString& PropertyName, + const Any& aValue) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + throw UnknownPropertyException(); +} + +Any ORegistryServiceManager::getPropertyValue(const OUString& PropertyName) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + Any ret; + + if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Registry") )) + { + MutexGuard aGuard( m_mutex ); + if( m_xRegistry.is() ) + { + ret = Any( &m_xRegistry, ::getCppuType( (const Reference<XSimpleRegistry > *)0 ) ); + } + } else + { + UnknownPropertyException except; + except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager : unknown property " ) ); + except.Message += PropertyName; + throw except; + } + + return ret; +} + +void ORegistryServiceManager::addPropertyChangeListener(const OUString& PropertyName, + const Reference<XPropertyChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + throw UnknownPropertyException(); +} + +void ORegistryServiceManager::removePropertyChangeListener(const OUString& PropertyName, + const Reference<XPropertyChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + throw UnknownPropertyException(); +} + +void ORegistryServiceManager::addVetoableChangeListener(const OUString& PropertyName, + const Reference<XVetoableChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + throw UnknownPropertyException(); +} + +void ORegistryServiceManager::removeVetoableChangeListener(const OUString& PropertyName, + const Reference<XVetoableChangeListener >& aListener) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + throw UnknownPropertyException(); +} + + +/** + * Create the ServiceManager + */ +static Reference<XInterface > SAL_CALL OServiceManager_CreateInstance(const Reference<XMultiServiceFactory > & rSMgr) +{ + return Reference<XInterface >( SAL_STATIC_CAST( XInterface *, SAL_STATIC_CAST( OWeakObject *, new OServiceManager() ) ) ); +} + +/** + * Create the ServiceManager + */ +static Reference<XInterface > SAL_CALL ORegistryServiceManager_CreateInstance(const Reference<XMultiServiceFactory > & rSMgr) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + return Reference<XInterface >( SAL_STATIC_CAST( XInterface *, SAL_STATIC_CAST( OWeakObject *, new ORegistryServiceManager() ) ) ); +} + +} // namespace + + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + OUStringBuffer buf( 32 ); + // OServiceManager + buf.append( (sal_Unicode)'/' ); + buf.append( stoc_smgr::OServiceManager::getImplementationName_Static() ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/UNO/SERVICES") ); + Reference<XRegistryKey> xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( buf.makeStringAndClear() ) ); + const Sequence<OUString > & rSMnames = + stoc_smgr::OServiceManager::getSupportedServiceNames_Static(); + const OUString * pNames = rSMnames.getConstArray(); + sal_Int32 nPos; + for ( nPos = rSMnames.getLength(); nPos--; ) + xNewKey->createKey( pNames[nPos] ); + + // ORegistryServiceManager + buf.append( (sal_Unicode)'/' ); + buf.append( stoc_smgr::ORegistryServiceManager::getImplementationName_Static() ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/UNO/SERVICES") ); + xNewKey = reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + buf.makeStringAndClear() ); + const Sequence<OUString > & rRSMnames = + stoc_smgr::ORegistryServiceManager::getSupportedServiceNames_Static(); + pNames = rRSMnames.getConstArray(); + for ( nPos = rRSMnames.getLength(); nPos--; ) + xNewKey->createKey( pNames[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + Reference< XSingleServiceFactory > xFactory; + + if (stoc_smgr::OServiceManager::getImplementationName_Static().compareToAscii( pImplName ) == 0) + { + xFactory = createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + stoc_smgr::OServiceManager::getImplementationName_Static(), + stoc_smgr::OServiceManager_CreateInstance, + stoc_smgr::OServiceManager::getSupportedServiceNames_Static() ); + } + if (stoc_smgr::ORegistryServiceManager::getImplementationName_Static().compareToAscii( pImplName ) == 0) + { + xFactory = createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + stoc_smgr::ORegistryServiceManager::getImplementationName_Static(), + stoc_smgr::ORegistryServiceManager_CreateInstance, + stoc_smgr::ORegistryServiceManager::getSupportedServiceNames_Static() ); + } + + if (xFactory.is()) + { + xFactory->acquire(); + return xFactory.get(); + } + return 0; +} +} + + diff --git a/stoc/source/simpleregistry/makefile.mk b/stoc/source/simpleregistry/makefile.mk new file mode 100644 index 000000000000..c780de0ecef9 --- /dev/null +++ b/stoc/source/simpleregistry/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= simreg +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +BOOTSTRAP_SERVICE=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + + +SLOFILES= \ + $(SLO)$/simpleregistry.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/stoc/source/simpleregistry/simpleregistry.cxx b/stoc/source/simpleregistry/simpleregistry.cxx new file mode 100644 index 000000000000..9433c2f07dfb --- /dev/null +++ b/stoc/source/simpleregistry/simpleregistry.cxx @@ -0,0 +1,1252 @@ +/************************************************************************* + * + * $RCSfile: simpleregistry.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE1_HXX_ +#include <cppuhelper/implbase1.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE2_HXX_ +#include <cppuhelper/implbase2.hxx> +#endif + +#ifndef _REGISTRY_REGISTRY_HXX_ +#include <registry/registry.hxx> +#endif + +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +using namespace com::sun::star::uno; +using namespace com::sun::star::registry; +using namespace com::sun::star::lang; +using namespace cppu; +using namespace osl; +using namespace rtl; + +#define SERVICENAME "com.sun.star.registry.SimpleRegistry" +#define IMPLNAME "com.sun.star.comp.stoc.SimpleRegistry" + +namespace stoc_simreg { + +//************************************************************************* +// class RegistryKeyImpl the implenetation of interface XRegistryKey +//************************************************************************* +class RegistryKeyImpl; + +//************************************************************************* +// SimpleRegistryImpl +//************************************************************************* +class SimpleRegistryImpl : public WeakImplHelper2< XSimpleRegistry, XServiceInfo > +{ +public: + SimpleRegistryImpl( const Reference<XMultiServiceFactory> & rXSMgr, + const Registry& rRegistry ); + + ~SimpleRegistryImpl(); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException); + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( ); + + // XSimpleRegistry + virtual OUString SAL_CALL getURL() throw(RuntimeException); + virtual void SAL_CALL open( const OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) throw(InvalidRegistryException, RuntimeException); + virtual sal_Bool SAL_CALL isValid( ) throw(RuntimeException); + virtual void SAL_CALL close( ) throw(InvalidRegistryException, RuntimeException); + virtual void SAL_CALL destroy( ) throw(InvalidRegistryException, RuntimeException); + virtual Reference< XRegistryKey > SAL_CALL getRootKey( ) throw(InvalidRegistryException, RuntimeException); + virtual sal_Bool SAL_CALL isReadOnly( ) throw(InvalidRegistryException, RuntimeException); + virtual void SAL_CALL mergeKey( const OUString& aKeyName, const OUString& aUrl ) throw(InvalidRegistryException, MergeConflictException, RuntimeException); + + friend RegistryKeyImpl; +protected: + Mutex m_mutex; + OUString m_url; + Registry m_registry; + + Reference<XMultiServiceFactory> m_xSMgr; +}; + + +class RegistryKeyImpl : public WeakImplHelper1< XRegistryKey > +{ +public: + RegistryKeyImpl( const RegistryKey& rKey, SimpleRegistryImpl* pRegistry ); + + RegistryKeyImpl( const OUString& rKeyName, SimpleRegistryImpl* pRegistry ); + + ~RegistryKeyImpl(); + + // XRegistryKey + virtual OUString SAL_CALL getKeyName() throw(RuntimeException); + virtual sal_Bool SAL_CALL isReadOnly( ) throw(InvalidRegistryException, RuntimeException); + virtual sal_Bool SAL_CALL isValid( ) throw(RuntimeException); + virtual RegistryKeyType SAL_CALL getKeyType( const OUString& rKeyName ) throw(InvalidRegistryException, RuntimeException); + virtual RegistryValueType SAL_CALL getValueType( ) throw(InvalidRegistryException, RuntimeException); + virtual sal_Int32 SAL_CALL getLongValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setLongValue( sal_Int32 value ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< sal_Int32 > SAL_CALL getLongListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setLongListValue( const ::com::sun::star::uno::Sequence< sal_Int32 >& seqValue ) throw(InvalidRegistryException, RuntimeException); + virtual OUString SAL_CALL getAsciiValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setAsciiValue( const OUString& value ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< OUString > SAL_CALL getAsciiListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setAsciiListValue( const ::com::sun::star::uno::Sequence< OUString >& seqValue ) throw(InvalidRegistryException, RuntimeException); + virtual OUString SAL_CALL getStringValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setStringValue( const OUString& value ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< OUString > SAL_CALL getStringListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setStringListValue( const ::com::sun::star::uno::Sequence< OUString >& seqValue ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getBinaryValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException); + virtual void SAL_CALL setBinaryValue( const ::com::sun::star::uno::Sequence< sal_Int8 >& value ) throw(InvalidRegistryException, RuntimeException); + virtual Reference< XRegistryKey > SAL_CALL openKey( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException); + virtual Reference< XRegistryKey > SAL_CALL createKey( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException); + virtual void SAL_CALL closeKey( ) throw(InvalidRegistryException, RuntimeException); + virtual void SAL_CALL deleteKey( const OUString& rKeyName ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< Reference< XRegistryKey > > SAL_CALL openKeys( ) throw(InvalidRegistryException, RuntimeException); + virtual Sequence< OUString > SAL_CALL getKeyNames( ) throw(InvalidRegistryException, RuntimeException); + virtual sal_Bool SAL_CALL createLink( const OUString& aLinkName, const OUString& aLinkTarget ) throw(InvalidRegistryException, RuntimeException); + virtual void SAL_CALL deleteLink( const OUString& rLinkName ) throw(InvalidRegistryException, RuntimeException); + virtual OUString SAL_CALL getLinkTarget( const OUString& rLinkName ) throw(InvalidRegistryException, RuntimeException); + virtual OUString SAL_CALL getResolvedName( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException); + +protected: + OUString m_name; + RegistryKey m_key; + SimpleRegistryImpl* m_pRegistry; +}; + +//************************************************************************* +RegistryKeyImpl::RegistryKeyImpl( const RegistryKey& key, SimpleRegistryImpl* pRegistry ) + : m_key(key) + , m_pRegistry(pRegistry) +{ + m_pRegistry->acquire(); + m_name = m_key.getName(); +} + +//************************************************************************* +RegistryKeyImpl::RegistryKeyImpl( const OUString& rKeyName, + SimpleRegistryImpl* pRegistry ) + : m_pRegistry(pRegistry) +{ + m_pRegistry->acquire(); + + RegistryKey rootKey; + if (!pRegistry->m_registry.isValid() || + pRegistry->m_registry.openRootKey(rootKey)) + { + throw InvalidRegistryException(); + } else + { + if ( rootKey.openKey(rKeyName, m_key) ) + { + throw InvalidRegistryException(); + } else + { + m_name = rKeyName; + } + } +} + +//************************************************************************* +RegistryKeyImpl::~RegistryKeyImpl() +{ + m_pRegistry->release(); +} + +//************************************************************************* +OUString SAL_CALL RegistryKeyImpl::getKeyName() throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + return m_name; +} + +//************************************************************************* +sal_Bool SAL_CALL RegistryKeyImpl::isReadOnly( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if (m_key.isValid()) + { + return(m_key.isReadOnly()); + } else + { + throw InvalidRegistryException(); + } + + return sal_False; +} + +//************************************************************************* +sal_Bool SAL_CALL RegistryKeyImpl::isValid( ) throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + return m_key.isValid(); +} + +//************************************************************************* +RegistryKeyType SAL_CALL RegistryKeyImpl::getKeyType( const OUString& rKeyName ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( m_key.isValid() ) + { + RegKeyType keyType; + if ( !m_key.getKeyType(rKeyName, &keyType) ) + { + switch (keyType) + { + case RG_KEYTYPE: + return RegistryKeyType_KEY; + break; + case RG_LINKTYPE: + return RegistryKeyType_LINK; + break; + } + } else + { + throw InvalidRegistryException(); + } + } else + { + throw InvalidRegistryException(); + } + + return RegistryKeyType_KEY; +} + +//************************************************************************* +RegistryValueType SAL_CALL RegistryKeyImpl::getValueType( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if (!m_key.isValid()) + { + throw InvalidRegistryException(); + } else + { + RegValueType type; + sal_uInt32 size; + + if (m_key.getValueInfo(OUString(), &type, &size)) + { + return RegistryValueType_NOT_DEFINED; + } else + { + switch (type) + { + case RG_VALUETYPE_LONG: return RegistryValueType_LONG; + case RG_VALUETYPE_STRING: return RegistryValueType_ASCII; + case RG_VALUETYPE_UNICODE: return RegistryValueType_STRING; + case RG_VALUETYPE_BINARY: return RegistryValueType_BINARY; + case RG_VALUETYPE_LONGLIST: return RegistryValueType_LONGLIST; + case RG_VALUETYPE_STRINGLIST: return RegistryValueType_ASCIILIST; + case RG_VALUETYPE_UNICODELIST: return RegistryValueType_STRINGLIST; + default: return RegistryValueType_NOT_DEFINED; + } + } + } + + return RegistryValueType_NOT_DEFINED; +} + +//************************************************************************* +sal_Int32 SAL_CALL RegistryKeyImpl::getLongValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if (!m_key.isValid()) + { + throw InvalidRegistryException(); + } else + { + RegValueType type; + sal_uInt32 size; + + if ( !m_key.getValueInfo(OUString(), &type, &size) ) + { + if (type == RG_VALUETYPE_LONG) + { + sal_Int32 value; + if ( !m_key.getValue(OUString(), (RegValue)&value) ) + { + return value; + } + } + } + + throw InvalidValueException(); + } + + return 0; +} + +//************************************************************************* +void SAL_CALL RegistryKeyImpl::setLongValue( sal_Int32 value ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + if (m_key.setValue(OUString(), RG_VALUETYPE_LONG, &value, sizeof(sal_Int32))) + { + throw InvalidValueException(); + } + } +} + +//************************************************************************* +Sequence< sal_Int32 > SAL_CALL RegistryKeyImpl::getLongListValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegValueType type; + sal_uInt32 size; + + if ( !m_key.getValueInfo(OUString(), &type, &size) ) + { + if (type == RG_VALUETYPE_LONGLIST) + { + RegistryValueList<sal_Int32> tmpValue; + if ( !m_key.getLongListValue(OUString(), tmpValue) ) + { + Sequence<sal_Int32> seqValue(size); + + for (sal_uInt32 i=0; i < size; i++) + { + seqValue.getArray()[i] = tmpValue.getElement(i); + } + + return seqValue; + } + } + } + + throw InvalidValueException(); + } + + return Sequence<sal_Int32>(); +} + +//************************************************************************* +void SAL_CALL RegistryKeyImpl::setLongListValue( const Sequence< sal_Int32 >& seqValue ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + sal_uInt32 length = seqValue.getLength(); + sal_Int32* tmpValue = new sal_Int32[length]; + + for (sal_uInt32 i=0; i < length; i++) + { + tmpValue[i] = seqValue.getConstArray()[i]; + } + + if ( m_key.setLongListValue(OUString(), tmpValue, length) ) + { + delete[] tmpValue; + throw InvalidValueException(); + } + + delete[] tmpValue; + } +} + +//************************************************************************* +OUString SAL_CALL RegistryKeyImpl::getAsciiValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if (!m_key.isValid()) + { + throw InvalidRegistryException(); + } else + { + RegValueType type; + sal_uInt32 size; + + if ( !m_key.getValueInfo(OUString(), &type, &size) ) + { + if ( type == RG_VALUETYPE_STRING ) + { + char* value = new char[size]; + if ( m_key.getValue(OUString(), (RegValue)value) ) + { + delete(value); + throw InvalidValueException(); + } else + { + OUString ret(OStringToOUString(value, RTL_TEXTENCODING_ASCII_US)); + delete(value); + return ret; + } + } + } + + throw InvalidValueException(); + } + + return OUString(); +} + +//************************************************************************* +void SAL_CALL RegistryKeyImpl::setAsciiValue( const OUString& value ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + OString sValue = OUStringToOString(value, RTL_TEXTENCODING_ASCII_US); + sal_uInt32 size = sValue.getLength()+1; + if ( m_key.setValue(OUString(), RG_VALUETYPE_STRING, + (RegValue)(sValue.getStr()), size) ) + { + throw InvalidValueException(); + } + } +} + +//************************************************************************* +Sequence< OUString > SAL_CALL RegistryKeyImpl::getAsciiListValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegValueType type; + sal_uInt32 size; + + if ( !m_key.getValueInfo(OUString(), &type, &size) ) + { + if (type == RG_VALUETYPE_STRINGLIST) + { + RegistryValueList<char*> tmpValue; + if ( !m_key.getStringListValue(OUString(), tmpValue) ) + { + Sequence<OUString> seqValue(size); + + for (sal_uInt32 i=0; i < size; i++) + { + seqValue.getArray()[i] = + OStringToOUString(tmpValue.getElement(i), RTL_TEXTENCODING_ASCII_US); + } + + return seqValue; + } + } + } + + throw InvalidValueException(); + } + + return Sequence<OUString>(); +} + +//************************************************************************* +void SAL_CALL RegistryKeyImpl::setAsciiListValue( const Sequence< OUString >& seqValue ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + sal_uInt32 length = seqValue.getLength(); + OString* pSValue = new OString[length]; + char** tmpValue = new char*[length]; + + for (sal_uInt32 i=0; i < length; i++) + { + pSValue[i] = OUStringToOString(seqValue.getConstArray()[i], RTL_TEXTENCODING_ASCII_US); + tmpValue[i] = (char*)pSValue[i].getStr(); + } + + if ( m_key.setStringListValue(OUString(), tmpValue, length) ) + { + delete[] pSValue; + delete[] tmpValue; + throw InvalidValueException(); + } + + delete[] pSValue; + delete[] tmpValue; + } +} + +//************************************************************************* +OUString SAL_CALL RegistryKeyImpl::getStringValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegValueType type; + sal_uInt32 size; + + if ( !m_key.getValueInfo(OUString(), &type, &size) ) + { + if (type == RG_VALUETYPE_UNICODE) + { + sal_Unicode* value = new sal_Unicode[size]; + if ( m_key.getValue(OUString(), (RegValue)value) ) + { + delete(value); + throw InvalidValueException(); + } else + { + OUString ret(value); + delete(value); + return ret; + } + } + } + + throw InvalidValueException(); + } + + return OUString(); +} + +//************************************************************************* +void SAL_CALL RegistryKeyImpl::setStringValue( const OUString& value ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + sal_uInt32 size = (value.getLength() + 1) * sizeof(sal_Unicode); + if ( m_key.setValue(OUString(), RG_VALUETYPE_UNICODE, + (RegValue)(value.getStr()), size) ) + { + throw InvalidValueException(); + } + } +} + +//************************************************************************* +Sequence< OUString > SAL_CALL RegistryKeyImpl::getStringListValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegValueType type; + sal_uInt32 size; + + if ( !m_key.getValueInfo(OUString(), &type, &size) ) + { + if (type == RG_VALUETYPE_UNICODELIST) + { + RegistryValueList<sal_Unicode*> tmpValue; + if ( !m_key.getUnicodeListValue(OUString(), tmpValue) ) + { + Sequence<OUString> seqValue(size); + + for (sal_uInt32 i=0; i < size; i++) + { + seqValue.getArray()[i] = OUString(tmpValue.getElement(i)); + } + + return seqValue; + } + } + } + + throw InvalidValueException(); + } + + return Sequence<OUString>(); +} + +//************************************************************************* +void SAL_CALL RegistryKeyImpl::setStringListValue( const Sequence< OUString >& seqValue ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + sal_uInt32 length = seqValue.getLength(); + sal_Unicode** tmpValue = new sal_Unicode*[length]; + + for (sal_uInt32 i=0; i < length; i++) + { + tmpValue[i] = (sal_Unicode*)seqValue.getConstArray()[i].getStr(); + } + + if (m_key.setUnicodeListValue(OUString(), tmpValue, length)) + { + delete[] tmpValue; + throw InvalidValueException(); + } + + delete[] tmpValue; + } +} + +//************************************************************************* +Sequence< sal_Int8 > SAL_CALL RegistryKeyImpl::getBinaryValue( ) + throw(InvalidRegistryException, InvalidValueException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegValueType type; + sal_uInt32 size; + + if ( !m_key.getValueInfo(OUString(), &type, &size) ) + { + if (type == RG_VALUETYPE_BINARY) + { + sal_Int8* value = new sal_Int8[size]; + if (m_key.getValue(OUString(), (RegValue)value)) + { + delete(value); + throw InvalidValueException(); + } else + { + Sequence<sal_Int8> seqBytes(value, size); + delete(value); + return seqBytes; + } + } + } + + throw InvalidValueException(); + } + + return Sequence< sal_Int8 >(); +} + +//************************************************************************* +void SAL_CALL RegistryKeyImpl::setBinaryValue( const Sequence< sal_Int8 >& value ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + sal_uInt32 size = value.getLength(); + if ( m_key.setValue(OUString(), RG_VALUETYPE_BINARY, + (RegValue)(value.getConstArray()), size) ) + { + throw InvalidValueException(); + } + } +} + +//************************************************************************* +Reference< XRegistryKey > SAL_CALL RegistryKeyImpl::openKey( const OUString& aKeyName ) + throw(InvalidRegistryException, RuntimeException) +{ + RegistryKey newKey; + + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegError _ret = REG_NO_ERROR; + if ( _ret = m_key.openKey(aKeyName, newKey) ) + { + if ( _ret == REG_INVALID_KEY ) + throw InvalidRegistryException(); + + return Reference<XRegistryKey>(); + } else + { + return ((XRegistryKey*)new RegistryKeyImpl(newKey, m_pRegistry)); + } + } + + return Reference<XRegistryKey>(); +} + +//************************************************************************* +Reference< XRegistryKey > SAL_CALL RegistryKeyImpl::createKey( const OUString& aKeyName ) + throw(InvalidRegistryException, RuntimeException) +{ + RegistryKey newKey; + + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegError _ret = REG_NO_ERROR; + if ( _ret = m_key.createKey(aKeyName, newKey) ) + { + if (_ret == REG_INVALID_KEY) + throw InvalidRegistryException(); + + return Reference<XRegistryKey>(); + } else + { + return ((XRegistryKey*)new RegistryKeyImpl(newKey, m_pRegistry)); + } + } + + return Reference<XRegistryKey>(); +} + +//************************************************************************* +void SAL_CALL RegistryKeyImpl::closeKey( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( m_key.isValid() ) + { + if ( !m_key.closeKey() ) + return; + } + + throw InvalidRegistryException(); +} + +//************************************************************************* +void SAL_CALL RegistryKeyImpl::deleteKey( const OUString& rKeyName ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( m_key.isValid() ) + { + if ( !m_key.deleteKey(rKeyName) ) + return; + } + + throw InvalidRegistryException(); +} + +//************************************************************************* +Sequence< Reference< XRegistryKey > > SAL_CALL RegistryKeyImpl::openKeys( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegistryKeyArray subKeys; + RegError _ret = REG_NO_ERROR; + if ( _ret = m_key.openSubKeys(OUString(), subKeys) ) + { + if ( _ret == REG_INVALID_KEY ) + throw InvalidRegistryException(); + + return Sequence< Reference<XRegistryKey> >(); + } else + { + sal_uInt32 length = subKeys.getLength(); + Sequence< Reference<XRegistryKey> > seqKeys(length); + + for (sal_uInt32 i=0; i < length; i++) + { + seqKeys.getArray()[i] = + (XRegistryKey*) new RegistryKeyImpl(subKeys.getElement(i), m_pRegistry); + } + return seqKeys; + } + } + + return Sequence< Reference<XRegistryKey> >(); +} + +//************************************************************************* +Sequence< OUString > SAL_CALL RegistryKeyImpl::getKeyNames( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegistryKeyNames subKeys; + RegError _ret = REG_NO_ERROR; + if ( _ret = m_key.getKeyNames(OUString(), subKeys) ) + { + if ( _ret == REG_INVALID_KEY ) + throw InvalidRegistryException(); + + return Sequence<OUString>(); + } else + { + sal_uInt32 length = subKeys.getLength(); + Sequence<OUString> seqKeys(length); + + for (sal_uInt32 i=0; i < length; i++) + { + seqKeys.getArray()[i] = subKeys.getElement(i); + } + return seqKeys; + } + } + + return Sequence<OUString>(); +} + +//************************************************************************* +sal_Bool SAL_CALL RegistryKeyImpl::createLink( const OUString& aLinkName, const OUString& aLinkTarget ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegError ret = REG_NO_ERROR; + + if ( ret = m_key.createLink(aLinkName, aLinkTarget) ) + { + if ( ret == REG_DETECT_RECURSION || + ret == REG_INVALID_KEY ) + { + throw InvalidRegistryException(); + } else + return sal_False; + } else + { + return sal_True; + } + } + + return sal_False; +} + +//************************************************************************* +void SAL_CALL RegistryKeyImpl::deleteLink( const OUString& rLinkName ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + if ( m_key.deleteLink(rLinkName) ) + { + throw InvalidRegistryException(); + } + } +} + +//************************************************************************* +OUString SAL_CALL RegistryKeyImpl::getLinkTarget( const OUString& rLinkName ) + throw(InvalidRegistryException, RuntimeException) +{ + OUString linkTarget; + + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegError ret = REG_NO_ERROR; + + if ( ret = m_key.getLinkTarget(rLinkName, linkTarget) ) + { + throw InvalidRegistryException(); + } + } + + return linkTarget; +} + +//************************************************************************* +OUString SAL_CALL RegistryKeyImpl::getResolvedName( const OUString& aKeyName ) + throw(InvalidRegistryException, RuntimeException) +{ + OUString resolvedName; + + Guard< Mutex > aGuard( m_pRegistry->m_mutex ); + if ( !m_key.isValid() ) + { + throw InvalidRegistryException(); + } else + { + RegError ret = REG_NO_ERROR; + + if ( ret = m_key.getResolvedKeyName(aKeyName, sal_True, resolvedName) ) + { + throw InvalidRegistryException(); + } + } + + return resolvedName; +} + +//************************************************************************* +SimpleRegistryImpl::SimpleRegistryImpl( const Reference<XMultiServiceFactory> & rXSMgr, + const Registry& rRegistry ) + : m_xSMgr(rXSMgr) + , m_registry(rRegistry) +{ +} + +//************************************************************************* +SimpleRegistryImpl::~SimpleRegistryImpl() +{ +} + +//************************************************************************* +OUString SAL_CALL SimpleRegistryImpl::getImplementationName( ) + throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ); +} + +//************************************************************************* +sal_Bool SAL_CALL SimpleRegistryImpl::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +//************************************************************************* +Sequence<OUString> SAL_CALL SimpleRegistryImpl::getSupportedServiceNames( ) + throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + return getSupportedServiceNames_Static(); +} + +//************************************************************************* +Sequence<OUString> SAL_CALL SimpleRegistryImpl::getSupportedServiceNames_Static( ) +{ + OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ); + return Sequence< OUString >( &aName, 1 ); +} + +//************************************************************************* +OUString SAL_CALL SimpleRegistryImpl::getURL() throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + return m_url; +} + +//************************************************************************* +void SAL_CALL SimpleRegistryImpl::open( const OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + if ( m_registry.isValid() ) + { + m_registry.close(); + } + + RegAccessMode accessMode = REG_READWRITE; + + if ( bReadOnly ) + accessMode = REG_READONLY; + + if ( !m_registry.open(rURL, accessMode) ) + return; + + if ( bCreate ) + { + if ( !m_registry.create(rURL) ) + return; + } + + throw InvalidRegistryException(); +} + +//************************************************************************* +sal_Bool SAL_CALL SimpleRegistryImpl::isValid( ) throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + return m_registry.isValid(); +} + +//************************************************************************* +void SAL_CALL SimpleRegistryImpl::close( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + if ( m_registry.isValid() ) + { + if ( !m_registry.close() ) + return; + } + + throw InvalidRegistryException(); +} + +//************************************************************************* +void SAL_CALL SimpleRegistryImpl::destroy( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + if ( m_registry.isValid() ) + { + if ( !m_registry.destroy(OUString()) ) + return; + } + + throw InvalidRegistryException(); +} + +//************************************************************************* +Reference< XRegistryKey > SAL_CALL SimpleRegistryImpl::getRootKey( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + if ( m_registry.isValid() ) + return ((XRegistryKey*)new RegistryKeyImpl(OUString( RTL_CONSTASCII_USTRINGPARAM("/") ), this)); + else + throw InvalidRegistryException(); + + return Reference< XRegistryKey >(); +} + +//************************************************************************* +sal_Bool SAL_CALL SimpleRegistryImpl::isReadOnly( ) + throw(InvalidRegistryException, RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + if ( m_registry.isValid() ) + return m_registry.isReadOnly(); + else + throw InvalidRegistryException(); + + return sal_False; +} + +//************************************************************************* +void SAL_CALL SimpleRegistryImpl::mergeKey( const OUString& aKeyName, const OUString& aUrl ) + throw(InvalidRegistryException, MergeConflictException, RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + if ( m_registry.isValid() ) + { + RegistryKey rootKey; + if ( !m_registry.openRootKey(rootKey) ) + { + RegError ret; + if (ret = m_registry.mergeKey(rootKey, aKeyName, aUrl, sal_False, sal_False)) + { + if ( ret == REG_MERGE_ERROR ) + throw MergeConflictException(); + else + throw InvalidRegistryException(); + } + + return; + } + } + + throw InvalidRegistryException(); +} + +//************************************************************************* +Reference<XInterface> SAL_CALL SimpleRegistry_CreateInstance( const Reference<XMultiServiceFactory>& rSMgr ) +{ + Reference<XInterface> xRet; + RegistryLoader aLoader; + + if ( aLoader.isLoaded() ) + { + Registry reg(aLoader); + + XSimpleRegistry *pRegistry = (XSimpleRegistry*) new SimpleRegistryImpl(rSMgr, reg); + + if (pRegistry) + { + xRet = Reference<XInterface>::query(pRegistry); + } + } + + return xRet; +} + +} + + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) ); + + const Sequence< OUString > & rSNL = + ::stoc_simreg::SimpleRegistryImpl::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (rtl_str_compare( pImplName, IMPLNAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ), + ::stoc_simreg::SimpleRegistry_CreateInstance, + ::stoc_simreg::SimpleRegistryImpl::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + + diff --git a/stoc/source/tdmanager/lrucache.hxx b/stoc/source/tdmanager/lrucache.hxx new file mode 100644 index 000000000000..6616916e0deb --- /dev/null +++ b/stoc/source/tdmanager/lrucache.hxx @@ -0,0 +1,282 @@ +/************************************************************************* + * + * $RCSfile: lrucache.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#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 + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _RTL_USTRING_ +#include <rtl/ustring> +#endif + +#include <stl/hash_map> + + +/** 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 ::std::hash_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( const t_Key & rKey ) const; + /** Sets a value to be cached for given key. + <br> + @param rKey a key + @param rValue a value + */ + inline void setValue( const t_Key & rKey, const t_Val & 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( const t_Key & 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( const t_Key & rKey ) const +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + const t_Key2Element::const_iterator 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( const t_Key & rKey ) const +{ + ::osl::MutexGuard aGuard( _aCacheMutex ); + const t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) ); + if (iFind != _aKey2Element.end()) + { + CacheEntry * pEntry = (*iFind).second; + toFront( pEntry ); +#ifdef __CACHE_DIAGNOSE + OSL_TRACE( "> retrieved element \"" ); + OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_TRACE( "\" from cache <\n" ); +#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( + const t_Key & rKey, const t_Val & rValue ) +{ + if (_nCachedElements > 0) + { + ::osl::MutexGuard aGuard( _aCacheMutex ); + const t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) ); + + CacheEntry * pEntry; + if (iFind == _aKey2Element.end()) + { + pEntry = _pTail; // erase last element +#ifdef __CACHE_DIAGNOSE + if (pEntry->aKey.getLength()) + { + OSL_TRACE( "> kicking element \"" ); + OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_TRACE( "\" from cache <\n" ); + } +#endif + _aKey2Element.erase( pEntry->aKey ); + _aKey2Element[ pEntry->aKey = rKey ] = pEntry; + } + else + { + pEntry = (*iFind).second; +#ifdef __CACHE_DIAGNOSE + OSL_TRACE( "> replacing element \"" ); + OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() ); + OSL_TRACE( "\" in cache <\n" ); +#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 + OSL_TRACE( "> cleared cache <\n" ); +#endif +} + +//================================================================================================== +struct FctHashOUString : public ::std::unary_function< const ::rtl::OUString &, size_t > +{ + size_t operator()( const ::rtl::OUString & rKey ) const + { return 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 diff --git a/stoc/source/tdmanager/makefile.mk b/stoc/source/tdmanager/makefile.mk new file mode 100644 index 000000000000..c56b297b9190 --- /dev/null +++ b/stoc/source/tdmanager/makefile.mk @@ -0,0 +1,108 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= tdmgr +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +BOOTSTRAP_SERVICE=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + + +SLOFILES= \ + $(SLO)$/tdmgr.obj \ + $(SLO)$/transfer.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/stoc/source/tdmanager/tdmgr.cxx b/stoc/source/tdmanager/tdmgr.cxx new file mode 100644 index 000000000000..482a1b5ca513 --- /dev/null +++ b/stoc/source/tdmanager/tdmgr.cxx @@ -0,0 +1,834 @@ +/************************************************************************* + * + * $RCSfile: tdmgr.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// #define TRACE(x) OSL_TRACE(x) +#define TRACE(x) + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_COMPONENT_HXX_ +#include <cppuhelper/component.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE3_HXX_ +#include <cppuhelper/implbase3.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE1_HXX_ +#include <cppuhelper/implbase1.hxx> +#endif +#ifndef _CPPUHELPER_EXTRACT_HXX_ +#include <cppuhelper/extract.hxx> +#endif + +#include "lrucache.hxx" + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XTypeProvider.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/XIndirectTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceTypeDescription.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +#include <stl/algorithm> +#include <stl/vector> + + + +using namespace std; +using namespace cppu; +using namespace rtl; +using namespace osl; +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; + + +namespace stoc_tdmgr +{ + +static const sal_Int32 CACHE_SIZE = 512; + +#define SERVICENAME "com.sun.star.reflection.TypeDescriptionManager" +#define IMPLNAME "com.sun.star.comp.stoc.TypeDescriptionManager" + +//-------------------------------------------------------------------------------------------------- +template < class T > +inline sal_Bool extract( const Any & rAny, Reference< T > & rDest ) +{ + rDest.clear(); + if (! (rAny >>= rDest)) + { + if (rAny.getValueTypeClass() == TypeClass_INTERFACE) + rDest = Reference< T >::query( *(const Reference< XInterface > *)rAny.getValue() ); + } + return rDest.is(); +} +//-------------------------------------------------------------------------------------------------- +inline static Sequence< OUString > getSupportedServiceNames() +{ + OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ); + return Sequence< OUString >( &aName, 1 ); +} + +typedef vector< Reference< XHierarchicalNameAccess > > ProviderVector; + +class EnumerationImpl; +class ManagerImpl; + +//================================================================================================== +class EventListenerImpl : public ImplHelper1< XEventListener > +{ + ManagerImpl * _pMgr; + +public: + EventListenerImpl( ManagerImpl * pMgr ) + : _pMgr( pMgr ) + {} + + // 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); +}; + +//================================================================================================== +class ManagerImpl : public WeakImplHelper3< XServiceInfo, XSet, XHierarchicalNameAccess > +{ + friend EnumerationImpl; + friend EventListenerImpl; + + Mutex _aComponentMutex; + Reference< XMultiServiceFactory > _xSMgr; + EventListenerImpl _aEventListener; + + // elements + sal_Bool _bCaching; + LRU_CacheAnyByOUString _aElements; + // provider chain + ProviderVector _aProviders; + sal_Bool _bProviderInit; + + inline void initProviders(); + inline Any getSimpleType( const OUString & rName ); + +public: + ManagerImpl( const Reference< XMultiServiceFactory > & xSMgr ); + virtual ~ManagerImpl(); + + // 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); +}; + +//================================================================================================== +class EnumerationImpl + : public WeakImplHelper1< XEnumeration > +{ + ManagerImpl * _pMgr; + sal_Int32 _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) +{ + MutexGuard aGuard( _pMgr->_aComponentMutex ); + if (rEvt.Source == _pMgr->_xSMgr) + { + Reference< XComponent > xComp( _pMgr->_xSMgr, UNO_QUERY ); + OSL_ENSHURE( xComp.is(), "### service manager must implement XComponent!" ); + xComp->removeEventListener( this ); + _pMgr->_bCaching = sal_False; + _pMgr->_aElements.clear(); + _pMgr->_xSMgr.clear(); + } + else + { + _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] ); +} + +//################################################################################################## + + +//================================================================================================== +typelib_TypeDescription * createCTD( const Reference<XTypeDescription > & xType ); + +//================================================================================================== +extern "C" +{ +static void SAL_CALL tdmgr_typelib_callback( void * pContext, typelib_TypeDescription ** ppRet, + rtl_uString * pTypeName ) +{ + OSL_ENSHURE( pContext && ppRet && pTypeName, "### null ptr!" ); + if (ppRet) + { + if (*ppRet) + { + typelib_typedescription_release( *ppRet ); + *ppRet = 0; + } + if (pContext && pTypeName) + { + try + { + Reference< XTypeDescription > xTD; + if (extractInterface( + xTD, reinterpret_cast< ManagerImpl * >( pContext )->getByHierarchicalName( pTypeName ) )) + { + *ppRet = createCTD( xTD ); + } + } + catch (...) + { + } + } +#ifdef DEBUG + if (! *ppRet) + { + OSL_TRACE( "### typelib type not accessable: " ); + OString aTypeName( OUStringToOString( pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( aTypeName.getStr() ); + OSL_TRACE( "\n" ); + } +#endif + } +} +} + +//__________________________________________________________________________________________________ +ManagerImpl::ManagerImpl( const Reference< XMultiServiceFactory > & xSMgr ) + : _xSMgr( xSMgr ) + , _aEventListener( this ) + , _bCaching( sal_True ) + , _aElements( CACHE_SIZE ) + , _bProviderInit( sal_False ) +{ + // register c typelib callback + typelib_typedescription_registerCallback( this, tdmgr_typelib_callback ); + + // listen to service manager vanishing... + Reference< XComponent > xComp( _xSMgr, UNO_QUERY ); + OSL_ENSHURE( xComp.is(), "### service manager must implement XComponent!" ); + xComp->addEventListener( &_aEventListener ); +} +//__________________________________________________________________________________________________ +ManagerImpl::~ManagerImpl() +{ + OSL_ENSHURE( _aProviders.size() == 0, "### still providers left!" ); + TRACE( "> TypeDescriptionManager shut down. <\n" ); + MutexGuard aGuard( _aComponentMutex ); + + // deregister of c typelib callback + typelib_typedescription_revokeCallback( this, tdmgr_typelib_callback ); +} +//__________________________________________________________________________________________________ +inline void ManagerImpl::initProviders() +{ + // looking up service manager for all known provider implementations + Reference< XContentEnumerationAccess > xEnumAccess( _xSMgr, UNO_QUERY ); + OSL_ENSHURE( xEnumAccess.is(), "### service manager must export XContentEnumerationAccess!" ); + + Reference< XEnumeration > xEnum( xEnumAccess->createContentEnumeration( + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.TypeDescriptionProvider") ) ) ); + OSL_ENSHURE( xEnum.is(), "### no TypeDescriptionProviders available!" ); + if (xEnum.is()) + { + while (xEnum->hasMoreElements()) + { + Any aAny( xEnum->nextElement() ); + if (aAny.getValueTypeClass() == TypeClass_INTERFACE) + { + Reference< XServiceInfo > xInfo( + *(const Reference< XInterface > *)aAny.getValue(), UNO_QUERY ); + if (xInfo.is() && + !xInfo->getImplementationName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(IMPLNAME) )) // no self insertion + { + Reference< XSingleServiceFactory > xFactory( + *(const Reference< XInterface > *)aAny.getValue(), UNO_QUERY ); + OSL_ENSHURE( xFactory.is(), "### the thing that should not be!" ); + + Reference< XHierarchicalNameAccess > xHA( xFactory->createInstance(), UNO_QUERY ); + if (xHA.is()) + { + try + { + insert( makeAny( xHA ) ); + } + catch (IllegalArgumentException &) + { + } + catch (ElementExistException &) + { + } + } + } + } + } + } + OSL_ENSHURE( !_aProviders.empty(), "### no typedescription providers found!" ); +} + +// XServiceInfo +//__________________________________________________________________________________________________ +OUString ManagerImpl::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ); +} +//__________________________________________________________________________________________________ +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_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.size() > 0); +} + +// 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 (extract( 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) +{ + Reference< XHierarchicalNameAccess > xElem; + if (! extract( rElement, xElem )) + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no type description provider given!") ), + (XWeak *)(OWeakObject *)this, 0 ); + } + + MutexGuard aGuard( _aComponentMutex ); + if (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end()) + { + throw ElementExistException( + OUString( RTL_CONSTASCII_USTRINGPARAM("provider already inserted!") ), + (XWeak *)(OWeakObject *)this ); + } + _aProviders.push_back( xElem ); + Reference< XComponent > xComp( xElem, 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) +{ + Reference< XHierarchicalNameAccess > xElem; + if (! extract( 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( xElem, UNO_QUERY ); + if (xComp.is()) + xComp->removeEventListener( &_aEventListener ); +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//================================================================================================== +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; +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//__________________________________________________________________________________________________ +inline Any ManagerImpl::getSimpleType( const OUString & rName ) +{ + Any aRet; + + if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("string") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_STRING, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("long") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_LONG, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned long") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_LONG, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("boolean") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BOOLEAN, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("char") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_CHAR, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("byte") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BYTE, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("short") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_SHORT, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned short") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_SHORT, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("hyper") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_HYPER, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned hyper") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_HYPER, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("float") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_FLOAT, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("double") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_DOUBLE, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("any") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_ANY, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("void") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_VOID, rName ) ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("type") )) + aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_TYPE, rName ) ); + + return aRet; +} + +// XHierarchicalNameAccess +//__________________________________________________________________________________________________ +Any ManagerImpl::getByHierarchicalName( const OUString & rName ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException) +{ + Any aRet; + if (_bCaching) + _aElements.getValue( rName ); + if (rName.getLength() && !aRet.hasValue()) + { + sal_Int32 nIndex; + if (rName[0] == '[') // test for sequence + { + Reference< XTypeDescription > xElemType; + if (extract( getByHierarchicalName( rName.copy( 2 ) ), xElemType )) + aRet <<= Reference< XTypeDescription >( new SequenceTypeDescriptionImpl( xElemType ) ); + else + return Any(); // further lookup makes no sense + } + else if ((nIndex = rName.indexOf( ':' )) >= 0) // test for interface member names + { + Reference< XInterfaceTypeDescription > xIfaceTD; + if (extract( getByHierarchicalName( rName.copy( 0, nIndex ) ), xIfaceTD )) + { + 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 >::query( pMembers[nPos] ); + break; + } + } + if (! aRet.hasValue()) + return Any(); // further lookup makes no sense + } + } + else if (rName.indexOf( '.' ) < 0) // test for simple/ build in types + { + aRet = getSimpleType( rName ); + } + + if (! aRet.hasValue()) + { + // last, try callback chain + MutexGuard aGuard( _aComponentMutex ); + if (! _bProviderInit) + { + initProviders(); + _bProviderInit = sal_True; + } + for ( ProviderVector::const_iterator iPos( _aProviders.begin() ); + iPos != _aProviders.end(); ++iPos ) + { + try + { + if ((aRet = (*iPos)->getByHierarchicalName( rName )).hasValue()) + break; + } + catch (NoSuchElementException &) + { + } + } + } + + // update cache + if (_bCaching && aRet.hasValue()) + _aElements.setValue( rName, aRet ); + } + + if (! aRet.hasValue()) + { + NoSuchElementException aExc; + aExc.Message = rName; + throw aExc; + } + return aRet; +} +//__________________________________________________________________________________________________ +sal_Bool ManagerImpl::hasByHierarchicalName( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + try + { + return getByHierarchicalName( rName ).hasValue(); + } + catch (NoSuchElementException &) + { + } + return sal_False; +} + +//================================================================================================== +static Reference< XInterface > SAL_CALL ManagerImpl_create( const Reference< XMultiServiceFactory > & xSMgr ) + throw(::com::sun::star::uno::Exception) +{ + return Reference< XInterface >( *new ManagerImpl( xSMgr ) ); +} + +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) ); + + const Sequence< OUString > & rSNL = stoc_tdmgr::getSupportedServiceNames(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ), + stoc_tdmgr::ManagerImpl_create, + stoc_tdmgr::getSupportedServiceNames() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + diff --git a/stoc/source/typeconv/convert.cxx b/stoc/source/typeconv/convert.cxx new file mode 100644 index 000000000000..b8add2091be1 --- /dev/null +++ b/stoc/source/typeconv/convert.cxx @@ -0,0 +1,907 @@ +/************************************************************************* + * + * $RCSfile: convert.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <osl/diagnose.h> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase2.hxx> + +#include <typelib/typedescription.hxx> +#include <uno/data.h> + +#ifdef WNT +#include <cmath> +#else +#include <math.h> +#endif +#include <float.h> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/script/FailReason.hpp> +#include <com/sun/star/container/XSet.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::script; +using namespace com::sun::star::registry; +using namespace cppu; +using namespace rtl; + +#define SERVICENAME "com.sun.star.script.Converter" +#define IMPLNAME "com.sun.star.comp.stoc.TypeConverter" + +namespace stoc_tcv +{ + +const double MIN_DOUBLE = -DBL_MAX; +const double MAX_DOUBLE = DBL_MAX; +const double MIN_FLOAT = -FLT_MAX; +const double MAX_FLOAT = FLT_MAX; + +//-------------------------------------------------------------------------------------------------- +static inline double round( double aVal ) +{ + sal_Bool bPos = (aVal >= 0.0); // + aVal = ::fabs( aVal ); + double aUpper = ::ceil( aVal ); + + aVal = ((aUpper-aVal) <= 0.5) ? aUpper : (aUpper - 1.0); + return (bPos ? aVal : -aVal); +} + +//-------------------------------------------------------------------------------------------------- +static sal_Bool getNumericValue( double & rfVal, const OUString & rStr ) +{ + double fRet = rStr.toDouble(); + if (fRet == 0.0) + { + sal_Int32 nLen = rStr.getLength(); + if (!nLen || (nLen == 1 && rStr[0] == '0')) // common case + { + rfVal = 0.0; + return sal_True; + } + + OUString trim( rStr.trim() ); + + // try hex + sal_Int32 nX = trim.indexOf( 'x' ); + if (nX < 0) + nX = trim.indexOf( 'X' ); + + if (nX > 0 && trim[nX-1] == '0') // 0x + { + sal_Bool bNeg = sal_False; + switch (nX) + { + case 2: // (+|-)0x... + if (trim[0] == '-') + bNeg = sal_True; + else if (trim[0] != '+') + return sal_False; + case 1: // 0x... + break; + default: + return sal_False; + } + + OUString aHexRest( trim.copy( nX+1 ) ); + sal_Int64 nRet = aHexRest.toInt64( 16 ); + + if (nRet == 0) + { + for ( sal_Int32 nPos = aHexRest.getLength(); nPos--; ) + { + if (aHexRest[nPos] != '0') + return sal_False; + } + } + + rfVal = (bNeg ? -nRet : nRet); + return sal_True; + } + + nLen = trim.getLength(); + sal_Int32 nPos = 0; + + // skip +/- + if (nLen && (trim[0] == '-' || trim[0] == '+')) + ++nPos; + + while (nPos < nLen) // skip leading zeros + { + if (trim[nPos] != '0') + { + if (trim[nPos] != '.') + return sal_False; + ++nPos; + while (nPos < nLen) // skip trailing zeros + { + if (trim[nPos] != '0') + return sal_False; + ++nPos; + } + break; + } + ++nPos; + } + } + rfVal = fRet; + return sal_True; +} + +//================================================================================================== +class TypeConverter_Impl : public WeakImplHelper2< XTypeConverter, XServiceInfo > +{ + // ...misc helpers... + sal_Int64 toHyper( const Any& rAny, sal_Int64 min = 0x8000000000000000, sal_uInt64 max = 0xffffffffffffffff ) + throw( CannotConvertException ); + double toDouble( const Any& rAny, double min = MIN_DOUBLE, double max = MAX_DOUBLE ) const + throw( CannotConvertException ); + +public: + static OUString getImplementationName_Static(void); + static Sequence< OUString > getSupportedServiceNames_Static(void) throw( RuntimeException ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw( RuntimeException ); + virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw( RuntimeException ); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw( RuntimeException ); + + // XTypeConverter + virtual Any SAL_CALL convertTo( const Any& aFrom, const Type& DestinationType ) throw( IllegalArgumentException, CannotConvertException, RuntimeException); + virtual Any SAL_CALL convertToSimpleType( const Any& aFrom, TypeClass aDestinationType ) throw( IllegalArgumentException, CannotConvertException, RuntimeException); +}; + +// XServiceInfo +OUString TypeConverter_Impl::getImplementationName() throw( RuntimeException ) +{ + return getImplementationName_Static(); +} + +// XServiceInfo Helper +OUString TypeConverter_Impl::getImplementationName_Static(void) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) ); +} + +// XServiceInfo +sal_Bool TypeConverter_Impl::supportsService(const OUString& ServiceName) throw( RuntimeException ) +{ + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +// XServiceInfo +Sequence< OUString > TypeConverter_Impl::getSupportedServiceNames(void) throw( RuntimeException ) +{ + return getSupportedServiceNames_Static(); +} + +// ORegistryServiceManager_Static +Sequence< OUString > TypeConverter_Impl::getSupportedServiceNames_Static(void) throw( RuntimeException ) +{ + Sequence< OUString > aSNS( 1 ); + aSNS[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME ) ); + return aSNS; +} + +//-------------------------------------------------------------------------------------------------- +sal_Int64 TypeConverter_Impl::toHyper( const Any& rAny, sal_Int64 min, sal_uInt64 max ) + throw( CannotConvertException ) +{ + sal_Int64 nRet; + TypeClass aDestinationClass = rAny.getValueTypeClass(); + + switch (aDestinationClass) + { + // ANY +// case TypeClass_ANY: // any sollte schon vorher entschachtelt sein... +// break; + // ENUM + case TypeClass_ENUM: + nRet = *(int *)rAny.getValue(); + break; + // BOOL + case TypeClass_BOOLEAN: + nRet = (*(sal_Bool*)rAny.getValue() ? 1 : 0); + break; + // CHAR, BYTE + case TypeClass_CHAR: + nRet = *(sal_Unicode *)rAny.getValue(); + break; + case TypeClass_BYTE: + nRet = *(sal_Int8 *)rAny.getValue(); + break; + // SHORT + case TypeClass_SHORT: + nRet = *(sal_Int16 *)rAny.getValue(); + break; + // UNSIGNED SHORT + case TypeClass_UNSIGNED_SHORT: + nRet = *(sal_uInt16 *)rAny.getValue(); + break; + // LONG + case TypeClass_LONG: + nRet = *(sal_Int32 *)rAny.getValue(); + break; + // UNSIGNED LONG + case TypeClass_UNSIGNED_LONG: + nRet = *(sal_uInt32 *)rAny.getValue(); + break; + // HYPER + case TypeClass_HYPER: + nRet = *(sal_Int64 *)rAny.getValue(); + break; + // UNSIGNED HYPER + case TypeClass_UNSIGNED_HYPER: + { + nRet = *(sal_Int64 *)rAny.getValue(); + if ((min < 0 || (sal_uInt64)nRet >= (sal_uInt64)min) && // lower bound + (sal_uInt64)nRet <= max) // upper bound + { + return nRet; + } + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("UNSIGNED HYPER out of range!") ), + Reference<XInterface>(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 ); + } + + // FLOAT, DOUBLE + case TypeClass_FLOAT: + { + double fVal = round( *(float *)rAny.getValue() ); + // implementationsabh. cast von unsigned nach signed! +#ifdef SAL_W32 // conversion from unsigned __int64 to double not impl + nRet = (fVal > 0x7fffffffffffffff ? (__int64)fVal : (sal_Int64)fVal); + if (fVal >= min && fVal <= (__int64)(max & 0x7fffffffffffffff)) +#else + nRet = (fVal > 0x7fffffffffffffff ? (sal_uInt64)fVal : (sal_Int64)fVal); + if (fVal >= min && fVal <= max) +#endif + { + return nRet; + } + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("FLOAT out of range!") ), + Reference<XInterface>(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 ); + } + case TypeClass_DOUBLE: + { + double fVal = round( *(double *)rAny.getValue() ); + // implementationsabh. cast von unsigned nach signed! +#ifdef SAL_W32 // conversion from unsigned __int64 to double not impl + nRet = (fVal > 0x7fffffffffffffff ? (__int64)fVal : (sal_Int64)fVal); + if (fVal >= min && fVal <= (__int64)(max & 0x7fffffffffffffff)) +#else + nRet = (fVal > 0x7fffffffffffffff ? (sal_uInt64)fVal : (sal_Int64)fVal); + if (fVal >= min && fVal <= max) +#endif + { + return nRet; + } + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("DOUBLE out of range!") ), + Reference<XInterface>(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 ); + } + + // STRING + case TypeClass_STRING: + { + double fVal; + if (! getNumericValue( fVal, *(OUString *)rAny.getValue() )) + { + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("invalid STRING value!") ), + Reference<XInterface>(), aDestinationClass, FailReason::IS_NOT_NUMBER, 0 ); + } + else + { + // implementationsabh. cast von unsigned nach signed! + nRet = (fVal > 0x7fffffffffffffff ? (sal_uInt64)fVal : (sal_Int64)fVal); +#ifdef SAL_W32 // conversion from unsigned __int64 to double not impl + if (fVal >= min && fVal <= (__int64)(max & 0x7fffffffffffffff)) +#else + if (fVal >= min && fVal <= max) +#endif + return nRet; + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("STRING value out of range!") ), + Reference<XInterface>(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 ); + } + } + + default: + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("TYPE is not supported!") ), + Reference<XInterface>(), aDestinationClass, FailReason::TYPE_NOT_SUPPORTED, 0 ); + } + + if (nRet >= min && (nRet < 0 || (sal_uInt64)nRet <= max)) + return nRet; + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("VALUE is out of range!") ), + Reference<XInterface>(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 ); + return 0; // dummy +} + +//-------------------------------------------------------------------------------------------------- +double TypeConverter_Impl::toDouble( const Any& rAny, double min, double max ) const + throw( CannotConvertException ) +{ + double fRet; + TypeClass aDestinationClass = rAny.getValueTypeClass(); + + switch (aDestinationClass) + { + // ANY +// case TypeClass_ANY: // any sollte schon vorher entschachtelt sein... +// break; + // ENUM + case TypeClass_ENUM: + fRet = *(int *)rAny.getValue(); + break; + // BOOL + case TypeClass_BOOLEAN: + fRet = (*(sal_Bool*)rAny.getValue() ? 1.0 : 0.0); + break; + // CHAR, BYTE + case TypeClass_CHAR: + fRet = *(sal_Unicode *)rAny.getValue(); + break; + case TypeClass_BYTE: + fRet = *(sal_Int8 *)rAny.getValue(); + break; + // SHORT + case TypeClass_SHORT: + fRet = *(sal_Int16 *)rAny.getValue(); + break; + // UNSIGNED SHORT + case TypeClass_UNSIGNED_SHORT: + fRet = *(sal_uInt16 *)rAny.getValue(); + break; + // LONG + case TypeClass_LONG: + fRet = *(sal_Int32 *)rAny.getValue(); + break; + // UNSIGNED LONG + case TypeClass_UNSIGNED_LONG: + fRet = *(sal_uInt32 *)rAny.getValue(); + break; + // HYPER + case TypeClass_HYPER: + fRet = *(sal_Int64 *)rAny.getValue(); + break; + // UNSIGNED HYPER + case TypeClass_UNSIGNED_HYPER: +#ifdef SAL_W32 + fRet = *(__int64 *)rAny.getValue(); +#else + fRet = *(sal_uInt64 *)rAny.getValue(); +#endif + break; + // FLOAT, DOUBLE + case TypeClass_FLOAT: + fRet = *(float *)rAny.getValue(); + break; + case TypeClass_DOUBLE: + fRet = *(double *)rAny.getValue(); + break; + + // STRING + case TypeClass_STRING: + { + if (! getNumericValue( fRet, *(OUString *)rAny.getValue() )) + { + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("invalid STRING value!") ), + Reference<XInterface>(), aDestinationClass, FailReason::IS_NOT_NUMBER, 0 ); + } + break; + } + + default: + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("TYPE is not supported!") ), + Reference< XInterface >(), aDestinationClass, FailReason::TYPE_NOT_SUPPORTED, 0 ); + } + + if (fRet >= min && fRet <= max) + return fRet; + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("VALUE is out of range!") ), + Reference< XInterface >(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 ); + return 0.0; // dummy +} + +//-------------------------------------------------------------------------------------------------- +Any SAL_CALL TypeConverter_Impl::convertTo( const Any& rVal, const Type& aDestType ) + throw( IllegalArgumentException, CannotConvertException, RuntimeException) +{ + Type aSourceType = rVal.getValueType(); + if (aSourceType == aDestType) + return rVal; + + TypeClass aSourceClass = aSourceType.getTypeClass(); + TypeClass aDestinationClass = aDestType.getTypeClass(); + + Any aRet; + + // convert to... + switch (aDestinationClass) + { + // --- to VOID ------------------------------------------------------------------------------ + case TypeClass_VOID: + return Any(); + // --- to ANY ------------------------------------------------------------------------------- + case TypeClass_ANY: + return rVal; + + // --- to STRUCT, UNION, EXCEPTION ---------------------------------------------------------- + case TypeClass_STRUCT: +// case TypeClass_UNION: // todo + case TypeClass_EXCEPTION: + { + // same types or destination type is derived source type? + TypeDescription aSourceTD( aSourceType ); + TypeDescription aDestTD( aDestType ); + if (typelib_typedescription_isAssignableFrom( aDestTD.get(), aSourceTD.get() )) + { + aRet.setValue( rVal.getValue(), aDestTD.get() ); // evtl. .uP.cAsT. + } + else + { + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("value is not of same or derived type!") ), + Reference< XInterface >(), aDestinationClass, FailReason::SOURCE_IS_NO_DERIVED_TYPE, 0 ); + } + break; + } + // --- to INTERFACE ------------------------------------------------------------------------- + case TypeClass_INTERFACE: + { + if (rVal.getValueTypeClass() != TypeClass_INTERFACE || + !*(XInterface * const *)rVal.getValue()) + { + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("value is no interface!") ), + Reference< XInterface >(), aDestinationClass, FailReason::NO_SUCH_INTERFACE, 0 ); + } + if (! (aRet = (*(XInterface * const *)rVal.getValue())->queryInterface( aDestType )).hasValue()) + { + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("value has no such interface!") ), + Reference< XInterface >(), aDestinationClass, FailReason::NO_SUCH_INTERFACE, 0 ); + } + break; + } + // --- to SEQUENCE -------------------------------------------------------------------------- + case TypeClass_SEQUENCE: + { + if (aSourceClass==TypeClass_SEQUENCE) + { + // wenn beide Sequences vom gleichen Typ sind + if( aSourceType == aDestType ) + return rVal; + + TypeDescription aSourceTD( aSourceType ); + TypeDescription aDestTD( aDestType ); + typelib_TypeDescription * pSourceElementTD = 0; + TYPELIB_DANGER_GET( &pSourceElementTD, ((typelib_IndirectTypeDescription *)aSourceTD.get())->pType ); + typelib_TypeDescription * pDestElementTD = 0; + TYPELIB_DANGER_GET( &pDestElementTD, ((typelib_IndirectTypeDescription *)aDestTD.get())->pType ); + + sal_uInt32 nPos = (*(const uno_Sequence * const *)rVal.getValue())->nElements; + uno_Sequence * pRet = 0; + uno_sequence_construct( &pRet, aDestTD.get(), 0, nPos, cpp_acquire ); + aRet.setValue( &pRet, aDestTD.get() ); + uno_destructData( &pRet, aDestTD.get(), cpp_release ); // decr ref count + + char * pDestElements = (*(uno_Sequence * const *)aRet.getValue())->elements; + const char * pSourceElements = (*(const uno_Sequence * const *)rVal.getValue())->elements; + + while (nPos--) + { + char * pDestPos = pDestElements + (nPos * pDestElementTD->nSize); + const char * pSourcePos = pSourceElements + (nPos * pSourceElementTD->nSize); + + Any aElement( convertTo( Any( pSourcePos, pSourceElementTD ), pDestElementTD->pWeakRef ) ); + + sal_Bool bSucc = uno_assignData( + pDestPos, pDestElementTD, + (pDestElementTD->eTypeClass == typelib_TypeClass_ANY + ? &aElement : const_cast< void * >( aElement.getValue() )), + pDestElementTD, cpp_queryInterface, cpp_acquire, cpp_release ); + OSL_ASSERT( bSucc ); + } + TYPELIB_DANGER_RELEASE( pDestElementTD ); + TYPELIB_DANGER_RELEASE( pSourceElementTD ); + } + } + break; + // --- to ENUM ------------------------------------------------------------------------------ + case TypeClass_ENUM: + { + TypeDescription aEnumTD( aDestType ); + sal_Int32 nPos = -1; + + if (aSourceClass==TypeClass_STRING) + { + for ( nPos = ((typelib_EnumTypeDescription *)aEnumTD.get())->nEnumValues; nPos--; ) + { + if (((const OUString *)rVal.getValue())->equalsIgnoreCase( ((typelib_EnumTypeDescription *)aEnumTD.get())->ppEnumNames[nPos] )) + break; + } + } + else if (aSourceClass!=TypeClass_ENUM && // exclude some unwanted types for toHyper() + aSourceClass!=TypeClass_BOOLEAN && + aSourceClass!=TypeClass_CHAR) + { + sal_Int32 nEnumValue = toHyper( rVal, 0, 0xffffffff ); + for ( nPos = ((typelib_EnumTypeDescription *)aEnumTD.get())->nEnumValues; nPos--; ) + { + if (nEnumValue == ((typelib_EnumTypeDescription *)aEnumTD.get())->pEnumValues[nPos]) + break; + } + } + + if (nPos >= 0) + { + aRet.setValue( &((typelib_EnumTypeDescription *)aEnumTD.get())->pEnumValues[nPos], aEnumTD.get() ); + } + else + { + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("value cannot be converted to demanded ENUM!") ), + Reference< XInterface >(), aDestinationClass, FailReason::IS_NOT_ENUM, 0 ); + } + break; + } + + default: + // else simple type conversion possible? + try + { + aRet = convertToSimpleType( rVal, aDestinationClass ); // CannotConvertException darf durchfliegen + } + catch (IllegalArgumentException &) + { + // ...FailReason::INVALID fliegt + } + } + + if (aRet.getValueTypeClass() != TypeClass_VOID) + return aRet; + + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("conversion not possible!") ), + Reference< XInterface >(), aDestinationClass, FailReason::INVALID, 0 ); + return Any(); // dummy +} + +//-------------------------------------------------------------------------------------------------- +Any TypeConverter_Impl::convertToSimpleType( const Any& rVal, TypeClass aDestinationClass ) + throw( IllegalArgumentException, CannotConvertException, RuntimeException ) +{ + switch (aDestinationClass) + { + // only simple Conversion of _simple_ types + case TypeClass_INTERFACE: + case TypeClass_SERVICE: + case TypeClass_STRUCT: + case TypeClass_TYPEDEF: + case TypeClass_UNION: + case TypeClass_EXCEPTION: + case TypeClass_ARRAY: + case TypeClass_SEQUENCE: + case TypeClass_ENUM: + case TypeClass_UNKNOWN: + case TypeClass_MODULE: + throw IllegalArgumentException(); + } + + Type aSourceType = rVal.getValueType(); + TypeClass aSourceClass = aSourceType.getTypeClass(); + if (aDestinationClass == aSourceClass) + return rVal; + + Any aRet; + + // Convert to... + switch (aDestinationClass) + { + // --- to VOID ------------------------------------------------------------------------------ + case TypeClass_VOID: + return Any(); + + // --- to ANY ------------------------------------------------------------------------------- + case TypeClass_ANY: + return rVal; + + // --- to BOOL ------------------------------------------------------------------------------ + case TypeClass_BOOLEAN: + switch (aSourceClass) + { + default: + { + sal_Bool bTmp = (toDouble( rVal ) != 0.0); + aRet.setValue( &bTmp, getBooleanCppuType() ); + } + case TypeClass_ENUM: // exclude enums + break; + + case TypeClass_STRING: + { + const OUString & aStr = *(const OUString *)rVal.getValue(); + if (aStr.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("0") ) || + aStr.equalsIgnoreCase( OUString( RTL_CONSTASCII_USTRINGPARAM("false") ) )) + { + sal_Bool bFalse = sal_False; + aRet.setValue( &bFalse, getCppuBooleanType() ); + } + else if (aStr.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("1") ) || + aStr.equalsIgnoreCase( OUString( RTL_CONSTASCII_USTRINGPARAM("true") ) )) + { + sal_Bool bTrue = sal_True; + aRet.setValue( &bTrue, getCppuBooleanType() ); + } + else + { + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("STRING has no boolean value!") ), + Reference< XInterface >(), aDestinationClass, FailReason::IS_NOT_BOOL, 0 ); + } + } + } + break; + + // --- to CHAR, BYTE ------------------------------------------------------------------------ + case TypeClass_CHAR: + { + if (aSourceClass==TypeClass_STRING) + { + if ((*(const OUString *)rVal.getValue()).getLength() == 1) // single char + aRet.setValue( (*(const OUString *)rVal.getValue()).getStr(), ::getCharCppuType() ); + } + else if (aSourceClass!=TypeClass_ENUM && // exclude enums, chars + aSourceClass!=TypeClass_CHAR) + { + sal_Unicode cRet = (sal_Unicode)toHyper( rVal, 0, 0xffff ); // range + aRet.setValue( &cRet, ::getCharCppuType() ); + } + break; + } + case TypeClass_BYTE: + aRet <<= (sal_Int8)( toHyper( rVal, -(sal_Int64)0x80, 0x7f ) ); + break; + + // --- to SHORT, UNSIGNED SHORT ------------------------------------------------------------- + case TypeClass_SHORT: + aRet <<= (sal_Int16)( toHyper( rVal, -(sal_Int64)0x8000, 0x7fff ) ); + break; + case TypeClass_UNSIGNED_SHORT: + aRet <<= (sal_uInt16)( toHyper( rVal, 0, 0xffff ) ); + break; + + // --- to LONG, UNSIGNED LONG --------------------------------------------------------------- + case TypeClass_LONG: + aRet <<= (sal_Int32)( toHyper( rVal, -(sal_Int64)0x80000000, 0x7fffffff ) ); + break; + case TypeClass_UNSIGNED_LONG: + aRet <<= (sal_uInt32)( toHyper( rVal, 0, 0xffffffff ) ); + break; + + // --- to HYPER, UNSIGNED HYPER-------------------------------------------- + case TypeClass_HYPER: + aRet <<= toHyper( rVal, -(sal_Int64)0x8000000000000000, 0x7fffffffffffffff ); + break; + case TypeClass_UNSIGNED_HYPER: + aRet <<= (sal_uInt64)( toHyper( rVal, 0, 0xffffffffffffffff ) ); + break; + + // --- to FLOAT, DOUBLE --------------------------------------------------------------------- + case TypeClass_FLOAT: + aRet <<= (float)( toDouble( rVal, MIN_FLOAT, MAX_FLOAT ) ); + break; + case TypeClass_DOUBLE: + aRet <<= (double)( toDouble( rVal, MIN_DOUBLE, MAX_DOUBLE ) ); + break; + + // --- to STRING ---------------------------------------------------------------------------- + case TypeClass_STRING: + switch (aSourceClass) + { + case TypeClass_ENUM: + { + TypeDescription aEnumTD( aSourceType ); + sal_Int32 nPos; + sal_Int32 nEnumValue = *(int *)rVal.getValue(); + for ( nPos = ((typelib_EnumTypeDescription *)aEnumTD.get())->nEnumValues; nPos--; ) + { + if (nEnumValue == ((typelib_EnumTypeDescription *)aEnumTD.get())->pEnumValues[nPos]) + break; + } + if (nPos >= 0) + { + aRet.setValue( &((typelib_EnumTypeDescription *)aEnumTD.get())->ppEnumNames[nPos], ::getCppuType( (const OUString *)0 ) ); + } + else + { + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("value is not ENUM!") ), + Reference< XInterface >(), aDestinationClass, FailReason::IS_NOT_ENUM, 0 ); + } + break; + } + + case TypeClass_BOOLEAN: + aRet <<= OUString::createFromAscii( (*(sal_Bool *)rVal.getValue() ? "true" : "false") ); + break; + case TypeClass_CHAR: + aRet <<= OUString( (sal_Unicode *)rVal.getValue(), 1 ); + break; + + case TypeClass_LONG: + { + sal_Int32 nInt(0); + rVal >>= nInt; + aRet <<= OUString::valueOf( nInt ); + } + break; + + default: + aRet <<= OUString::valueOf( toDouble( rVal ) ); + } + } + + if (aRet.getValueTypeClass() != TypeClass_VOID) + return aRet; + + throw CannotConvertException( + OUString( RTL_CONSTASCII_USTRINGPARAM("conversion not possible!") ), + Reference< XInterface >(), aDestinationClass, FailReason::INVALID, 0 ); + return Any(); // dummy +} + +//************************************************************************* +Reference< XInterface > SAL_CALL TypeConverter_Impl_CreateInstance( + const Reference< XMultiServiceFactory > & rSMgr ) + throw( RuntimeException ) +{ + return (XWeak *)(OWeakObject *)new TypeConverter_Impl(); +} + +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) ); + + const Sequence< OUString > & rSNL = + stoc_tcv::TypeConverter_Impl::getSupportedServiceNames_Static(); + + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + stoc_tcv::TypeConverter_Impl_CreateInstance, + stoc_tcv::TypeConverter_Impl::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + diff --git a/stoc/source/typeconv/makefile.mk b/stoc/source/typeconv/makefile.mk new file mode 100644 index 000000000000..3165dcdf4fce --- /dev/null +++ b/stoc/source/typeconv/makefile.mk @@ -0,0 +1,105 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME=stoc +TARGET=tcv +USE_DEFFILE=TRUE +NO_BSYMBOLIC=TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +.INCLUDE : ..$/cppumaker.mk + +UNOTYPES=$($(TARGET)_XML2CMPTYPES) + +SLOFILES= \ + $(SLO)$/convert.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/stoc/test/excomp/example/ExampleComponent1.idl b/stoc/test/excomp/example/ExampleComponent1.idl new file mode 100644 index 000000000000..3cfe772fa548 --- /dev/null +++ b/stoc/test/excomp/example/ExampleComponent1.idl @@ -0,0 +1,77 @@ +/************************************************************************* + * + * $RCSfile: ExampleComponent1.idl,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _EXCOMP_EXAMPLECOMPONENT1_IDL_ +#define _EXCOMP_EXAMPLECOMPONENT1_IDL_ + +#include <example/XTest.idl> + +module example +{ + +service ExampleComponent1 +{ + interface XTest; +}; + +}; // test + + +#endif diff --git a/stoc/test/excomp/example/ExampleComponent2.idl b/stoc/test/excomp/example/ExampleComponent2.idl new file mode 100644 index 000000000000..ad0e2237511f --- /dev/null +++ b/stoc/test/excomp/example/ExampleComponent2.idl @@ -0,0 +1,77 @@ +/************************************************************************* + * + * $RCSfile: ExampleComponent2.idl,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _EXCOMP_EXAMPLECOMPONENT2_IDL_ +#define _EXCOMP_EXAMPLECOMPONENT2_IDL_ + +#include <example/XTest.idl> + +module example +{ + +service ExampleComponent2 +{ + interface XTest; +}; + +}; // test + + +#endif diff --git a/stoc/test/excomp/example/XTest.idl b/stoc/test/excomp/example/XTest.idl new file mode 100644 index 000000000000..01d1e4bb44ef --- /dev/null +++ b/stoc/test/excomp/example/XTest.idl @@ -0,0 +1,84 @@ +/************************************************************************* + * + * $RCSfile: XTest.idl,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _EXCOMP_XTEST_IDL_ +#define _EXCOMP_XTEST_IDL_ + +#include <com/sun/star/uno/XInterface.idl> + +module example +{ +/** + * Simple test interface. + * + * @author Juergen Schmidt + */ +[ uik(46833373-3462-11d3-87A50070-24594732), ident("XTest", 1.0) ] +interface XTest : com::sun::star::uno::XInterface +{ + /** + * in parameter test, tests by calls reference also (complex types) + */ + string getMessage( ); +}; + +}; // test + +#endif diff --git a/stoc/test/excomp/excomp.cxx b/stoc/test/excomp/excomp.cxx new file mode 100644 index 000000000000..27d9954aff2b --- /dev/null +++ b/stoc/test/excomp/excomp.cxx @@ -0,0 +1,182 @@ +/************************************************************************* + * + * $RCSfile: excomp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#ifndef _VOS_PROCESS_HXX_ +#include <vos/process.hxx> +#endif + +#include <example/XTest.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/lang/XComponent.hpp> + +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif + +#ifndef _CPPUHELPER_SERVICEFACTORY_HXX_ +#include <cppuhelper/servicefactory.hxx> +#endif + + +using namespace com::sun::star::uno; +using namespace com::sun::star::registry; +using namespace com::sun::star::lang; +using namespace example; +using namespace cppu; +using namespace vos; +using namespace rtl; + +#ifdef _DEBUG +#define TEST_ENSHURE(c, m) VOS_ENSHURE(c, m) +#else +#define TEST_ENSHURE(c, m) VOS_VERIFY(c) +#endif + +OUString getExePath() +{ + OStartupInfo startupInfo; + OUString exe; + + VOS_VERIFY(startupInfo.getExecutableFile(exe) == OStartupInfo::E_None); + +#if defined(WIN32) || defined(__OS2__) || defined(WNT) + exe = exe.copy(0, exe.getLength() - 10); +#else + exe = exe.copy(0, exe.getLength() - 6); +#endif + return exe; +} + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int _cdecl main( int argc, char * argv[] ) +#endif +{ +#ifdef UNX + OUString compName1(RTL_CONSTASCII_USTRINGPARAM("libexcomp1.so")); + OUString compName2(RTL_CONSTASCII_USTRINGPARAM("libexcomp2.so")); +#else + OUString compName1(RTL_CONSTASCII_USTRINGPARAM("excomp1")); + OUString compName2(RTL_CONSTASCII_USTRINGPARAM("excomp2")); +#endif + + OUString exePath( getExePath() ); + OUString excompRdb(exePath); + + excompRdb += OUString::createFromAscii("excomp.rdb"); + + Reference< XMultiServiceFactory > xSMgr = ::cppu::createRegistryServiceFactory( excompRdb ); + TEST_ENSHURE( xSMgr.is(), "excomp error 0" ); + + typelib_TypeDescription* pTypeDesc = NULL; + OUString sType = OUString::createFromAscii("com.sun.star.text.XTextDocument"); + typelib_typedescription_getByName( &pTypeDesc, sType.pData); + typelib_InterfaceTypeDescription* pInterDesc = (typelib_InterfaceTypeDescription*)pTypeDesc; + + Reference< XInterface > xIFace = xSMgr->createInstance(OUString::createFromAscii("com.sun.star.registry.ImplementationRegistration")); + Reference< XImplementationRegistration > xImpReg( xIFace, UNO_QUERY); + TEST_ENSHURE( xImpReg.is(), "excomp error 1" ); + try + { + xImpReg->registerImplementation(OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), + compName1, + Reference< XSimpleRegistry >() ); + xImpReg->registerImplementation(OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), + compName2, + Reference< XSimpleRegistry >() ); + } + catch( CannotRegisterImplementationException& e) + { + TEST_ENSHURE( e.Message.getLength(), OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr() ); + } + + Reference< XTest > xTest1( xSMgr->createInstance(OUString::createFromAscii("example.ExampleComponent1")), + UNO_QUERY); + TEST_ENSHURE( xTest1.is(), "excomp error 2" ); + Reference< XTest > xTest2( xSMgr->createInstance(OUString::createFromAscii("example.ExampleComponent2")), + UNO_QUERY); + TEST_ENSHURE( xTest2.is(), "excomp error 3" ); + + OUString m1 = xTest1->getMessage(); + OUString m2 = xTest2->getMessage(); + + fprintf(stdout, "ExampleComponent1, Message = \"%s\"\n", OUStringToOString(m1, RTL_TEXTENCODING_ASCII_US).getStr()); + fprintf(stdout, "ExampleComponent2, Message = \"%s\"\n", OUStringToOString(m2, RTL_TEXTENCODING_ASCII_US).getStr()); + + xImpReg->revokeImplementation(compName1, Reference< XSimpleRegistry >() ); + xImpReg->revokeImplementation(compName2, Reference< XSimpleRegistry >() ); + + Reference< XComponent >( xSMgr, UNO_QUERY )->dispose(); + + return(0); +} + + diff --git a/stoc/test/excomp/excomp1.cxx b/stoc/test/excomp/excomp1.cxx new file mode 100644 index 000000000000..fc5f3577df80 --- /dev/null +++ b/stoc/test/excomp/excomp1.cxx @@ -0,0 +1,259 @@ +/************************************************************************* + * + * $RCSfile: excomp1.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif + +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif + +#ifndef _CPPUHELPER_IMPLBASE2_HXX_ +#include <cppuhelper/implbase2.hxx> +#endif + +#include <example/XTest.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +using namespace example; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; +using namespace cppu; +using namespace osl; +using namespace rtl; + +#define SERVICENAME1 "example.ExampleComponent1" +#define IMPLNAME1 "example.ExampleComponent1.Impl" + +namespace excomp_impl { + +//************************************************************************* +// ExampleComponent1Impl +//************************************************************************* +class ExampleComponent1Impl : public WeakImplHelper2< XTest, XServiceInfo > +{ +public: + ExampleComponent1Impl( const Reference<XMultiServiceFactory> & rXSMgr ); + + ~ExampleComponent1Impl(); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException); + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( ); + + // XSimpleRegistry + virtual OUString SAL_CALL getMessage() throw(RuntimeException); + +protected: + Mutex m_mutex; + + Reference<XMultiServiceFactory> m_xSMgr; +}; + +//************************************************************************* +ExampleComponent1Impl::ExampleComponent1Impl( const Reference<XMultiServiceFactory> & rXSMgr ) + : m_xSMgr(rXSMgr) +{ +} + +//************************************************************************* +ExampleComponent1Impl::~ExampleComponent1Impl() +{ +} + +//************************************************************************* +OUString SAL_CALL ExampleComponent1Impl::getImplementationName( ) + throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME1) ); +} + +//************************************************************************* +sal_Bool SAL_CALL ExampleComponent1Impl::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +//************************************************************************* +Sequence<OUString> SAL_CALL ExampleComponent1Impl::getSupportedServiceNames( ) + throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + return getSupportedServiceNames_Static(); +} + +//************************************************************************* +Sequence<OUString> SAL_CALL ExampleComponent1Impl::getSupportedServiceNames_Static( ) +{ + OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME1) ); + return Sequence< OUString >( &aName, 1 ); +} + +//************************************************************************* +OUString SAL_CALL ExampleComponent1Impl::getMessage() throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + return OUString::createFromAscii("Lalelu nur der Mann im Mond schaut zu ..."); +} + + +//************************************************************************* +Reference<XInterface> SAL_CALL ExampleComponent1_CreateInstance( const Reference<XMultiServiceFactory>& rSMgr ) +{ + Reference<XInterface> xRet; + + XTest *pXTest = (XTest*) new ExampleComponent1Impl(rSMgr); + + if (pXTest) + { + xRet = Reference< XInterface >::query(pXTest); + } + + return xRet; +} + +} // excomp_impl + + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + // ExampleComponent1 + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME1 "/UNO/SERVICES") ) ) ); + + Sequence< OUString > & rSNL = + ::excomp_impl::ExampleComponent1Impl::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (rtl_str_compare( pImplName, IMPLNAME1 ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME1) ), + ::excomp_impl::ExampleComponent1_CreateInstance, + ::excomp_impl::ExampleComponent1Impl::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + + diff --git a/stoc/test/excomp/excomp1.xml b/stoc/test/excomp/excomp1.xml new file mode 100644 index 000000000000..0246dd4f88ca --- /dev/null +++ b/stoc/test/excomp/excomp1.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE COMPONENTDESCRIPTION PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "componentdescription.dtd"> + +<COMPONENTDESCRIPTION + xmlns:xlink="http://www.w3.org/1999/xlink/Namespace" > + +<Author> Juergen Schmidt </Author> + +<Name> example.ExampleComponent1.Impl </Name> + +<Description> + This component provides a simple demo component. +</Description> + +<ModuleName> excomp1 </ModuleName> + +<LoaderName> com.sun.star.loader.SharedLibrary </LoaderName> + +<Language> c++ </Language> + +<Status StatusValue="final"/> + +<SupportedService> example.ExampleComponent1 </SupportedService> + +<ProjectBuildDependency> cppuhelper </ProjectBuildDependency> +<ProjectBuildDependency> cppu </ProjectBuildDependency> +<ProjectBuildDependency> vos </ProjectBuildDependency> +<ProjectBuildDependency> sal </ProjectBuildDependency> + +<RuntimeModuleDependency> cppuhelper </RuntimeModuleDependency> +<RuntimeModuleDependency> cppu </RuntimeModuleDependency> +<RuntimeModuleDependency> vos </RuntimeModuleDependency> +<RuntimeModuleDependency> sal </RuntimeModuleDependency> + +<Type> com.sun.star.lang.XTypeProvider </Type> +<Type> com.sun.star.lang.XServiceInfo </Type> +<Type> com.sun.star.lang.XSingleServiceFactory </Type> +<Type> com.sun.star.lang.XMultiServiceFactory </Type> +<Type> com.sun.star.registry.XRegistryKey </Type> +<Type> com.sun.star.uno.XAggregation </Type> +<Type> com.sun.star.uno.XWeak </Type> +<Type> com.sun.star.uno.TypeClass </Type> +<Type> example.XTest </Type> + +</COMPONENTDESCRIPTION> diff --git a/stoc/test/excomp/excomp2.cxx b/stoc/test/excomp/excomp2.cxx new file mode 100644 index 000000000000..ccedc6dbf907 --- /dev/null +++ b/stoc/test/excomp/excomp2.cxx @@ -0,0 +1,334 @@ +/************************************************************************* + * + * $RCSfile: excomp2.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif + +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif + +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ +#include <cppuhelper/typeprovider.hxx> +#endif + +#include <example/XTest.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +using namespace example; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; +using namespace cppu; +using namespace osl; +using namespace rtl; + +#define SERVICENAME2 "example.ExampleComponent2" +#define IMPLNAME2 "example.ExampleComponent2.Impl" + +namespace excomp2_impl { + +//************************************************************************* +// ExampleComponent2Impl +//************************************************************************* +class ExampleComponent2Impl : public OWeakObject + , public XTypeProvider + , public XServiceInfo + , public XTest +{ +public: + ExampleComponent2Impl( const Reference<XMultiServiceFactory> & rXSMgr ); + + ~ExampleComponent2Impl(); + + // XInterface + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw() + { OWeakObject::acquire(); } + virtual void SAL_CALL release() throw() + { OWeakObject::release(); } + + // XTypeProvider + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException); + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( ); + + // XTest + virtual OUString SAL_CALL getMessage() throw(RuntimeException); + +protected: + Mutex m_mutex; + + Reference<XMultiServiceFactory> m_xSMgr; +}; + +//************************************************************************* +ExampleComponent2Impl::ExampleComponent2Impl( const Reference<XMultiServiceFactory> & rXSMgr ) + : m_xSMgr(rXSMgr) +{ +} + +//************************************************************************* +ExampleComponent2Impl::~ExampleComponent2Impl() +{ +} + +//************************************************************************* +Any SAL_CALL ExampleComponent2Impl::queryInterface( const ::com::sun::star::uno::Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet = ::cppu::queryInterface(rType, + static_cast< XTypeProvider * >( this ), + static_cast< XServiceInfo * >( this ), + static_cast< XTest * >( this ) ); + if ( aRet.hasValue() ) + return aRet; + + return OWeakObject::queryInterface( rType ); +} + +//************************************************************************* +Sequence< Type > SAL_CALL ExampleComponent2Impl::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * pTypes = 0; + if (! pTypes) + { + MutexGuard aGuard( m_mutex ); + if (! pTypes) + { + static OTypeCollection aTypes( + ::getCppuType( (const Reference< XInterface > *)0 ), + ::getCppuType( (const Reference< XWeak > *)0 ), + ::getCppuType( (const Reference< XTypeProvider > *)0 ), + ::getCppuType( (const Reference< XServiceInfo > *)0 ), + ::getCppuType( (const Reference< XTest > *)0 ) ); + pTypes = &aTypes; + } + } + return pTypes->getTypes(); +} + +//************************************************************************* +Sequence< sal_Int8 > SAL_CALL ExampleComponent2Impl::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * pId = 0; + if (! pId) + { + MutexGuard aGuard( m_mutex ); + if (! pId) + { + static OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); +} + +//************************************************************************* +OUString SAL_CALL ExampleComponent2Impl::getImplementationName( ) + throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME2) ); +} + +//************************************************************************* +sal_Bool SAL_CALL ExampleComponent2Impl::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +//************************************************************************* +Sequence<OUString> SAL_CALL ExampleComponent2Impl::getSupportedServiceNames( ) + throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + return getSupportedServiceNames_Static(); +} + +//************************************************************************* +Sequence<OUString> SAL_CALL ExampleComponent2Impl::getSupportedServiceNames_Static( ) +{ + OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME2) ); + return Sequence< OUString >( &aName, 1 ); +} + +//************************************************************************* +OUString SAL_CALL ExampleComponent2Impl::getMessage() throw(RuntimeException) +{ + Guard< Mutex > aGuard( m_mutex ); + return OUString::createFromAscii("Alle meine Entchen schwimmen auf dem See, schwimmen auf dem See ..."); +} + + +//************************************************************************* +Reference<XInterface> SAL_CALL ExampleComponent2_CreateInstance( const Reference<XMultiServiceFactory>& rSMgr ) +{ + Reference<XInterface> xRet; + + XTest *pXTest = (XTest*) new ExampleComponent2Impl(rSMgr); + + if (pXTest) + { + xRet = Reference< XInterface >::query(pXTest); + } + + return xRet; +} + + +} // excomp_impl + + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + // ExampleComponent2 + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME2 "/UNO/SERVICES") ) ) ); + + Sequence< OUString > & rSNL = + ::excomp2_impl::ExampleComponent2Impl::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSHURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (rtl_str_compare( pImplName, IMPLNAME2 ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME2) ), + ::excomp2_impl::ExampleComponent2_CreateInstance, + ::excomp2_impl::ExampleComponent2Impl::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + + diff --git a/stoc/test/excomp/excomp2.xml b/stoc/test/excomp/excomp2.xml new file mode 100644 index 000000000000..4fa4db28eb2d --- /dev/null +++ b/stoc/test/excomp/excomp2.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE COMPONENTDESCRIPTION PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "componentdescription.dtd"> + +<COMPONENTDESCRIPTION + xmlns:xlink="http://www.w3.org/1999/xlink/Namespace" > + +<Author> Juergen Schmidt </Author> + +<Name> example.ExampleComponent2.Impl </Name> + +<Description> + This component provides a simple demo component. +</Description> + +<ModuleName> excomp2 </ModuleName> + +<LoaderName> com.sun.star.loader.SharedLibrary </LoaderName> + +<Language> c++ </Language> + +<Status StatusValue="final"/> + +<SupportedService> example.ExampleComponent2 </SupportedService> + +<ProjectBuildDependency> cppuhelper </ProjectBuildDependency> +<ProjectBuildDependency> cppu </ProjectBuildDependency> +<ProjectBuildDependency> vos </ProjectBuildDependency> +<ProjectBuildDependency> sal </ProjectBuildDependency> + +<RuntimeModuleDependency> cppuhelper </RuntimeModuleDependency> +<RuntimeModuleDependency> cppu </RuntimeModuleDependency> +<RuntimeModuleDependency> vos </RuntimeModuleDependency> +<RuntimeModuleDependency> sal </RuntimeModuleDependency> + +<Type> com.sun.star.lang.XTypeProvider </Type> +<Type> com.sun.star.lang.XServiceInfo </Type> +<Type> com.sun.star.lang.XSingleServiceFactory </Type> +<Type> com.sun.star.lang.XMultiServiceFactory </Type> +<Type> com.sun.star.registry.XRegistryKey </Type> +<Type> com.sun.star.uno.XAggregation </Type> +<Type> com.sun.star.uno.XWeak </Type> +<Type> com.sun.star.uno.TypeClass </Type> +<Type> example.XTest </Type> + +</COMPONENTDESCRIPTION> diff --git a/stoc/test/excomp/exports.dxp b/stoc/test/excomp/exports.dxp new file mode 100644 index 000000000000..2513a15ad5d5 --- /dev/null +++ b/stoc/test/excomp/exports.dxp @@ -0,0 +1,4 @@ +component_getDescriptionFunc +component_getImplementationEnvironment +component_writeInfo +component_getFactory diff --git a/stoc/test/excomp/makefile.mk b/stoc/test/excomp/makefile.mk new file mode 100644 index 000000000000..578a1880cff3 --- /dev/null +++ b/stoc/test/excomp/makefile.mk @@ -0,0 +1,167 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET= excomp +TARGET1= excomp1 +TARGET2= excomp2 +TARGETTYPE=CUI +#LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE= TRUE +NO_BSYMBOLIC= TRUE +COMP1TYPELIST=$(TARGET1) +COMP2TYPELIST=$(TARGET2) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +UNOUCRDEP= $(BIN)$/excomp.rdb +UNOUCRRDB= $(BIN)$/excomp.rdb +UNOUCROUT= $(OUT)$/inc +INCPRE+= $(OUT)$/inc + +UNOTYPES=$($(TARGET1)_XML2CMPTYPES) +UNOTYPES+=$($(TARGET2)_XML2CMPTYPES) +UNOTYPES+= com.sun.star.registry.XImplementationRegistration \ + com.sun.star.lang.XComponent + +# --- Application excomp ------------------------------------------------ +APP1TARGET= $(TARGET) +APP1OBJS= $(OBJ)$/excomp.obj + +APP1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +# ---- objects ---- +SLOFILES= \ + $(SLO)$/excomp1.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj \ + $(SLO)$/excomp2.obj \ + $(SLO)$/$(COMP2TYPELIST)_description.obj + +# ---- excomp1 ------ +SHL1TARGET= $(TARGET1) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1LIBS= +SHL1OBJS= $(SLO)$/excomp1.obj \ + $(SLO)$/$(COMP1TYPELIST)_description.obj +SHL1IMPLIB= i$(TARGET1) +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# ---- excomp2 ------ +SHL2TARGET= $(TARGET2) + +SHL2STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +SHL2DEPN= +SHL2LIBS= +SHL2OBJS= $(SLO)$/excomp2.obj \ + $(SLO)$/$(COMP2TYPELIST)_description.obj +SHL2IMPLIB= i$(TARGET2) +SHL2DEF= $(MISC)$/$(SHL2TARGET).def + +DEF2NAME= $(SHL2TARGET) +DEF2EXPORTFILE= exports.dxp + +ALLIDLFILES:= example$/XTest.idl example$/ExampleComponent1.idl example$/ExampleComponent2.idl + +# --- Targets ------------------------------------------------------ + +.IF "$(depend)" == "" +ALL : $(BIN)$/excomp.rdb \ + ALLTAR +.ELSE +ALL: ALLDEP +.ENDIF + +.INCLUDE : target.mk + +$(BIN)$/excomp.rdb: $(ALLIDLFILES) + +unoidl -I$(PRJ) -I$(SOLARIDLDIR) -Burd -OH$(MISC)$/excomp $? + +regmerge $@ /UCR $(MISC)$/excomp$/{$(?:f:s/.idl/.urd/)} + +regmerge $@ / $(SOLARBINDIR)$/applicat.rdb + touch $@ + diff --git a/stoc/test/javavm/makefile.mk b/stoc/test/javavm/makefile.mk new file mode 100644 index 000000000000..4784d96882c6 --- /dev/null +++ b/stoc/test/javavm/makefile.mk @@ -0,0 +1,124 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= stoc +TARGET6= testjavavm +TARGETTYPE= CUI +LIBTARGET= NO +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC= TRUE + +UNOUCRDEP= $(SOLARBINDIR)$/applicat.rdb +UNOUCRRDB= $(SOLARBINDIR)$/applicat.rdb +#UNOUCROUT= $(OUT)$/inc$/test +UNOUCROUT= $(OUT)$/inc$ +#INCPRE+= $(OUT)$/inc$/test +INCPRE+= $(OUT)$/inc$ + +#asdf: +# echo $(OUT) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Application 6 - testjavavm ------------------------------------ +APP6TARGET= $(TARGET6) +APP6OBJS = $(OBJ)$/testjavavm.obj +APP6STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) \ + $(UNOLIB) + +.IF "$(GUI)"=="WNT" +APP6STDLIBS+= $(LIBCIMT) +.ENDIF + +#ALLIDLFILES:= + +# --- Target ------------------------------------------------ + +.IF "$(depend)" == "" +ALL : unoheader \ + ALLTAR +.ELSE +ALL: ALLDEP +.ENDIF + +.INCLUDE : target.mk + +TESTJAVAVM:=com.sun.star.uno.XWeak;com.sun.star.java.XJavaVM;com.sun.star.java.XJavaThreadRegister.XJavaThreadRegister_11;com.sun.star.registry.XSimpleRegistry;com.sun.star.lang.XComponent;com.sun.star.registry.XImplementationRegistration;com.sun.star.lang.XSingleServiceFactory;com.sun.star.uno.TypeClass;com.sun.star.lang.XMultiServiceFactory + +#$(BIN)$/stoctest.rdb: $(ALLIDLFILES) +# +unoidl -I$(PRJ) -I$(SOLARIDLDIR) -Burd -OH$(BIN) $? +# +regmerge $@ /UCR $(BIN)$/{$(?:f:s/.idl/.urd/)} +# +regmerge $@ / $(UNOUCRRDB) +# touch $@ + +unoheader: $(UNOUCRRDB) + +cppumaker -BUCR -O$(UNOUCROUT) -T"$(TESTJAVAVM)" $(UNOUCRRDB) + diff --git a/stoc/test/javavm/testjavavm.cxx b/stoc/test/javavm/testjavavm.cxx new file mode 100644 index 000000000000..34c883f2168e --- /dev/null +++ b/stoc/test/javavm/testjavavm.cxx @@ -0,0 +1,224 @@ +/************************************************************************* + * + * $RCSfile: testjavavm.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + + +#include <jni.h> + +//#include <iostream> +#include <stdio.h> +#include <uno/api.h> + +#include <vos/diagnose.hxx> +#include <vos/dynload.hxx> + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/weak.hxx> + +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/java/XJavaVM.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/java/XJavaThreadRegister/XJavaThreadRegister_11.hpp> + +//#include <cppuhelper/implbase1.hxx> + +using namespace std; +using namespace rtl; +using namespace cppu; +using namespace vos; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +//using namespace com::sun::star::reflection; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; +using namespace com::sun::star::java; +using namespace com::sun::star::java::XJavaThreadRegister; + + +sal_Bool testJavaVM(const Reference< XMultiServiceFactory > & xMgr ) +{ + + Reference<XInterface> xXInt= xMgr->createInstance(L"com.sun.star.java.JavaVirtualMachine"); + if( ! xXInt.is()) + return sal_False; + Reference<XJavaVM> xVM( xXInt, UNO_QUERY); + if( ! xVM.is()) + return sal_False; + Reference<XJavaThreadRegister_11> xreg11(xVM, UNO_QUERY); + if( ! xreg11.is()) + return sal_False; + + sal_Bool b= xreg11->isThreadAttached(); + xreg11->registerThread(); + b= xreg11->isThreadAttached(); + xreg11->revokeThread(); + b= xreg11->isThreadAttached(); + + Uik aMachineId; + aMachineId.m_Data1= 0; + aMachineId.m_Data2= 0; + aMachineId.m_Data3= 0; + aMachineId.m_Data4= 0; + aMachineId.m_Data5= 0; + + b= xVM->isVMEnabled(); + b= xVM->isVMStarted(); + + Any anyVM = xVM->getJavaVM( aMachineId, UNO_getProcessIdentifier()); + + b= xVM->isVMEnabled(); + b= xVM->isVMStarted(); + + + JavaVM* _jvm= *(JavaVM**) anyVM.getValue(); + JNIEnv *p_env; + if( _jvm->AttachCurrentThread( &p_env, 0)) + return sal_False; + +// jclass aJProg = p_env->FindClass("TestJavaVM"); +// if( p_env->ExceptionOccurred()){ +// p_env->ExceptionDescribe(); +// p_env->ExceptionClear(); +// } +// +// jmethodID mid= p_env->GetStaticMethodID( aJProg,"main", "([Ljava/lang/String;)V"); + + jclass cls = p_env->FindClass( "TestJavaVM"); + if (cls == 0) { + VOS_TRACE( "Can't find Prog class\n"); + exit(1); + } + +// jmethodID methid = p_env->GetStaticMethodID( cls, "main", "([Ljava/lang/String;)V"); +// if (methid == 0) { +// VOS_TRACE("Can't find Prog.main\n"); +// exit(1); +// } + +// jstring jstr = p_env->NewStringUTF(" from C!"); +// if (jstr == 0) { +// VOS_TRACE("Out of memory\n"); +// exit(1); +// } +// jobjectArray args = p_env->NewObjectArray( 1, +// p_env->FindClass("java/lang/String"), jstr); +// if (args == 0) { +// VOS_TRACE( "Out of memory\n"); +// exit(1); +// } +// p_env->CallStaticVoidMethod( cls, methid, args); + + + jmethodID id = p_env->GetStaticMethodID( cls, "getInt", "()I"); + if( id) + { + jint _i= p_env->CallStaticIntMethod(cls, id); + } + + if( p_env->ExceptionOccurred()){ + p_env->ExceptionDescribe(); + p_env->ExceptionClear(); + } + + + _jvm->DetachCurrentThread(); + return sal_True; +} + +extern +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int __cdecl main( int argc, char * argv[] ) +#endif +{ + Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( "applicat.rdb" ) ); + + sal_Bool bSucc = sal_False; + try + { + Reference<com::sun::star::registry::XImplementationRegistration> xImplReg( + xMgr->createInstance( L"com.sun.star.registry.ImplementationRegistration" ), UNO_QUERY ); + VOS_ENSHURE( xImplReg.is(), "### no impl reg!" ); + + sal_Char pLibName[256]; + ORealDynamicLoader::computeLibraryName("je558mi", pLibName, 255); + xImplReg->registerImplementation( + L"com.sun.star.loader.SharedLibrary", OWString::createFromAscii(pLibName), Reference< XSimpleRegistry >() ); + + bSucc = testJavaVM( xMgr ); + } + catch (Exception & rExc) + { + VOS_ENSHURE( sal_False, "### exception occured!" ); + OString aMsg( OWStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) ); + VOS_TRACE( "### exception occured: " ); + VOS_TRACE( aMsg.getStr() ); + VOS_TRACE( "\n" ); + } + + Reference< XComponent >( xMgr, UNO_QUERY )->dispose(); + printf("javavm %s", bSucc ? "succeeded" : "failed"); +// cout << "javavm " << (bSucc ? "succeeded" : "failed") << " !" << endl; + return (bSucc ? 0 : -1); +} + + diff --git a/stoc/test/javavm/testjavavm.java b/stoc/test/javavm/testjavavm.java new file mode 100644 index 000000000000..3acef1ae7801 --- /dev/null +++ b/stoc/test/javavm/testjavavm.java @@ -0,0 +1,73 @@ +/************************************************************************* + * + * $RCSfile: testjavavm.java,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +class TestJavaVM +{ + public static int getInt() + { + return 100; + } + + public static void main( String args[]) + { + System.out.println("Hello World"); + } +} diff --git a/stoc/test/language_binding.idl b/stoc/test/language_binding.idl new file mode 100644 index 000000000000..cc93e8a32197 --- /dev/null +++ b/stoc/test/language_binding.idl @@ -0,0 +1,213 @@ +/************************************************************************* + * + * $RCSfile: language_binding.idl,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _TEST_LANGUAGE_BINDING_IDL_ +#define _TEST_LANGUAGE_BINDING_IDL_ + +#include <com/sun/star/uno/XInterface.idl> +#include <com/sun/star/lang/IllegalArgumentException.idl> + +module test +{ + +enum TestEnum +{ + TEST, + ONE, + TWO, + CHECK, + LOLA, + PALOO, + ZA +}; + +/** + * simple c++ types + */ +struct TestSimple +{ + boolean Bool; + char Char; + byte Byte; + short Short; + unsigned short UShort; + long Long; + unsigned long ULong; + hyper Hyper; + unsigned hyper UHyper; + float Float; + double Double; + test::TestEnum Enum; +}; +/** + * complex c++ types + */ +struct TestElement : test::TestSimple +{ + string String; + com::sun::star::uno::XInterface Interface; + any Any; +}; +struct TestDataElements : test::TestElement +{ + sequence<test::TestElement > Sequence; +}; + +typedef TestDataElements TestData; + +/** + * Monster test interface to test language binding calls. + * + * @author Daniel Boelzle + */ +[ uik(46833373-3462-11d3-87A400A0-24494732), ident("XLBTest", 1.0) ] +interface XLBTestBase : com::sun::star::uno::XInterface +{ + /** + * in parameter test, tests by calls reference also (complex types) + */ + [oneway] void setValues( [in] boolean bBool, [in] char cChar, [in] byte nByte, + [in] short nShort, [in] unsigned short nUShort, + [in] long nLong, [in] unsigned long nULong, + [in] hyper nHyper, [in] unsigned hyper nUHyper, + [in] float fFloat, [in] double fDouble, + [in] test::TestEnum eEnum, [in] string aString, + [in] com::sun::star::uno::XInterface xInterface, [in] any aAny, + [in] sequence<test::TestElement > aSequence, + [in] test::TestData aStruct ); + /** + * inout parameter test + */ + test::TestData setValues2( [inout] boolean bBool, [inout] char cChar, [inout] byte nByte, + [inout] short nShort, [inout] unsigned short nUShort, + [inout] long nLong, [inout] unsigned long nULong, + [inout] hyper nHyper, [inout] unsigned hyper nUHyper, + [inout] float fFloat, [inout] double fDouble, + [inout] test::TestEnum eEnum, [inout] string aString, + [inout] com::sun::star::uno::XInterface xInterface, [inout] any aAny, + [inout] sequence<test::TestElement > aSequence, + [inout] test::TestData aStruct ); + + /** + * out parameter test + */ + test::TestData getValues( [out] boolean bBool, [out] char cChar, [out] byte nByte, + [out] short nShort, [out] unsigned short nUShort, + [out] long nLong, [out] unsigned long nULong, + [out] hyper nHyper, [out] unsigned hyper nUHyper, + [out] float fFloat, [out] double fDouble, + [out] test::TestEnum eEnum, [out] string aString, + [out] com::sun::star::uno::XInterface xInterface, [out] any aAny, + [out] sequence<test::TestElement > aSequence, + [out] test::TestData aStruct ); + + [attribute] boolean Bool; + [attribute] byte Byte; + [attribute] char Char; + [attribute] short Short; + [attribute] unsigned short UShort; + [attribute] long Long; + [attribute] unsigned long ULong; + [attribute] hyper Hyper; + [attribute] unsigned hyper UHyper; + [attribute] float Float; + [attribute] double Double; + [attribute] test::TestEnum Enum; + [attribute] string String; + [attribute] com::sun::star::uno::XInterface Interface; + [attribute] any Any; + [attribute] sequence<test::TestElement > Sequence; + [attribute] test::TestData Struct; +}; + + +/** + * Inherting from monster; adds raiseException(). + * + * @author Daniel Boelzle + */ +[ uik(44C34C20-3478-11d3-87A400A0-24494732), ident("XLanguageBindingTest", 1.0) ] +interface XLanguageBindingTest : test::XLBTestBase +{ + /** + * params are there only for dummy, to test if all temp out params will be released. + */ + test::TestData raiseException( [out] boolean bBool, [out] char cChar, [out] byte nByte, + [out] short nShort, [out] unsigned short nUShort, + [out] long nLong, [out] unsigned long nULong, + [out] hyper nHyper, [out] unsigned hyper nUHyper, + [out] float fFloat, [out] double fDouble, + [out] test::TestEnum eEnum, [out] string aString, + [out] com::sun::star::uno::XInterface xInterface, [out] any aAny, + [out] sequence<test::TestElement > aSequence, + [out] test::TestData aStruct ) + raises( com::sun::star::lang::IllegalArgumentException ); + + /** + * raises runtime exception + */ + [attribute] long RuntimeException; +}; + +}; // test + + +#endif diff --git a/stoc/test/makefile.mk b/stoc/test/makefile.mk new file mode 100644 index 000000000000..0c3c3b12b0d6 --- /dev/null +++ b/stoc/test/makefile.mk @@ -0,0 +1,239 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=.. + +PRJNAME=stoc +TARGET=stoc +TARGET1=testloader +TARGET2=testregistry +TARGET3=testsmgr +TARGET4=testcorefl +TARGET5=testiadapter +TARGET6=testintrosp +TARGET7=testconv +TARGET8=testproxyfac +TARGETTYPE=CUI +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- + +CXXFILES= testloader.cxx \ + testregistry.cxx \ + testsmgr.cxx + +# --- Application 1 ------------------------------------------------ +APP1TARGET= $(TARGET1) +APP1OBJS= $(OBJ)$/testloader.obj + +APP1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +.IF "$(GUI)"=="WNT" +APP1STDLIBS+= +# $(LIBCIMT) $(LIBCMT) +.ENDIF + +# --- Application 2 ------------------------------------------------ +APP2TARGET= $(TARGET2) +APP2OBJS= $(OBJ)$/testregistry.obj + +APP2STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) \ + $(UNOTOOLSLIB) + +.IF "$(GUI)"=="WNT" +APP2STDLIBS+= +# $(LIBCIMT) $(LIBCMT) +.ENDIF + + +# --- Application 3 - testsmgr main ------------------------------------ +APP3TARGET= $(TARGET3) +APP3OBJS = $(OBJ)$/testsmgr.obj +APP3STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +.IF "$(GUI)"=="UNX" +APP3STDLIBS+= -lat +.ENDIF +.IF "$(GUI)"=="WNT" +APP3STDLIBS+= $(LIBCIMT) \ + iat.lib +.ENDIF + +# --- Application 4 - testcorefl main ------------------------------------ +APP4TARGET= $(TARGET4) +APP4OBJS = $(OBJ)$/testcorefl.obj +APP4STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +.IF "$(GUI)"=="WNT" +APP4STDLIBS+= $(LIBCIMT) +.ENDIF + +# --- Application 5 - testiadapter main ------------------------------------ +APP5TARGET= $(TARGET5) +APP5OBJS = $(OBJ)$/testiadapter.obj +APP5STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +.IF "$(GUI)"=="WNT" +APP5STDLIBS+= $(LIBCIMT) +.ENDIF + +# --- Application 6 - testiadapter main ------------------------------------ +APP6TARGET= $(TARGET6) +APP6OBJS = $(OBJ)$/testintrosp.obj +APP6STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) + +.IF "$(GUI)"=="WNT" +APP6STDLIBS+= $(LIBCIMT) +.ENDIF + +# --- Application 7 - testiadapter main ------------------------------------ +APP7TARGET= $(TARGET7) +APP7OBJS = $(OBJ)$/testconv.obj +APP7STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +.IF "$(GUI)"=="WNT" +APP7STDLIBS+= $(LIBCIMT) +.ENDIF + +# --- Application 8 - testproxyfac main ------------------------------------ +APP8TARGET= $(TARGET8) +APP8OBJS = $(OBJ)$/testproxyfac.obj +APP8STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +.IF "$(GUI)"=="WNT" +APP8STDLIBS+= $(LIBCIMT) +.ENDIF + +ALLIDLFILES:= testcorefl.idl language_binding.idl testintrosp.idl + + +# --- Target ------------------------------------------------ + +.IF "$(depend)" == "" +ALL : unoheader \ + ALLTAR +.ELSE +ALL: ALLDEP +.ENDIF + +.INCLUDE : target.mk + +CPPUMAKERFLAGS = +.IF "$(COM)" == "MSC" +CPPUMAKERFLAGS = -L +.ENDIF + +FACTORYTYPES:=com.sun.star.container.XEnumeration;com.sun.star.lang.XComponent;com.sun.star.registry.XSimpleRegistry;com.sun.star.lang.XInitialization;com.sun.star.lang.XMultiServiceFactory;com.sun.star.loader.XImplementationLoader;com.sun.star.registry.XImplementationRegistration;com.sun.star.container.XSet;com.sun.star.lang.XSingleServiceFactory +TESTCOREFL:=ModuleC;ModuleC.XInterfaceA;ModuleC.XInterfaceB;ModuleA.XInterface1;com.sun.star.reflection.XIdlReflection;com.sun.star.reflection.XIdlField;com.sun.star.reflection.XIdlArray;com.sun.star.reflection.XIdlMethod;com.sun.star.reflection.XIdlClass;com.sun.star.beans.XPropertySet;com.sun.star.lang.XComponent;com.sun.star.container.XHierarchicalNameAccess +TESTIADAPTER:=com.sun.star.beans.XIntrospection;com.sun.star.beans.MethodConcept;com.sun.star.beans.XExactName;com.sun.star.lang.XTypeProvider;com.sun.star.uno.XAggregation;com.sun.star.script.XInvocationAdapterFactory;com.sun.star.script.XInvocation;com.sun.star.lang.XMultiServiceFactory;com.sun.star.registry.XSimpleRegistry;com.sun.star.lang.XInitialization;test.XLanguageBindingTest +TESTINTROSP:=ModuleA;ModuleA.XIntroTest;com.sun.star.beans.XPropertySet;com.sun.star.container.XIndexAccess;com.sun.star.container.XNameAccess;com.sun.star.beans.PropertyAttribute;com.sun.star.beans.PropertyConcept +TESTCONV:=com.sun.star.script.XTypeConverter +TESTPROXYFAC:=com.sun.star.util.XProxyFactory + +$(BIN)$/stoctest.rdb: $(ALLIDLFILES) + +unoidl -I$(PRJ) -I$(SOLARIDLDIR) -Burd -OH$(BIN) $? + +regmerge $@ /UCR $(BIN)$/{$(?:f:s/.idl/.urd/)} + +regmerge $@ / $(SOLARBINDIR)$/applicat.rdb + touch $@ + +unoheader: $(BIN)$/stoctest.rdb + +cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) -T"$(TESTIADAPTER);$(FACTORYTYPES)" $(BIN)$/stoctest.rdb + +cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) -T"$(TESTCOREFL)" $(BIN)$/stoctest.rdb + +cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) -T"$(TESTINTROSP)" $(BIN)$/stoctest.rdb + +cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) -T"$(TESTCONV)" $(BIN)$/stoctest.rdb + +cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) -T"$(TESTPROXYFAC)" $(BIN)$/stoctest.rdb + diff --git a/stoc/test/testconv.cxx b/stoc/test/testconv.cxx new file mode 100644 index 000000000000..5bacf288d1fe --- /dev/null +++ b/stoc/test/testconv.cxx @@ -0,0 +1,736 @@ +/************************************************************************* + * + * $RCSfile: testconv.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> +#include <cppuhelper/servicefactory.hxx> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/reflection/FieldAccessMode.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> + +#include <float.h> +#include <stdio.h> + + +using namespace rtl; +using namespace cppu; +using namespace osl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::script; +using namespace com::sun::star::reflection; +using namespace com::sun::star::registry; + +const double MIN_DOUBLE = -DBL_MAX; +const double MAX_DOUBLE = DBL_MAX; +const double MIN_FLOAT = -FLT_MAX; +const double MAX_FLOAT = FLT_MAX; + +//================================================================================================== +static void printValue( const Any & rVal ) +{ + // print value + OString aStr( OUStringToOString( rVal.getValueType().getTypeName(), RTL_TEXTENCODING_ISO_8859_1 ) ); + printf( "(%s)", aStr.getStr() ); + + switch (rVal.getValueTypeClass()) + { + case TypeClass_VOID: + printf( "void" ); + break; + case TypeClass_ANY: + if (rVal.hasValue()) + printValue( *(Any *)rVal.getValue() ); + break; + case TypeClass_BOOLEAN: + printf( "%s", (*(sal_Bool *)rVal.getValue() ? "true" : "false") ); + break; + case TypeClass_CHAR: + { + char ar[2]; + ar[0] = (char)(sal_Unicode)rVal.getValue(); + ar[1] = 0; + printf( ar ); + break; + } + case TypeClass_BYTE: + printf( "%x", (int)*(sal_Int8 *)rVal.getValue() ); + break; + case TypeClass_SHORT: + printf( "%x", *(sal_Int16 *)rVal.getValue() ); + break; + case TypeClass_UNSIGNED_SHORT: + printf( "%x", *(sal_uInt16 *)rVal.getValue() ); + break; + case TypeClass_LONG: + printf( "%x", *(sal_Int32 *)rVal.getValue() ); + break; + case TypeClass_UNSIGNED_LONG: + printf( "%x", *(sal_uInt32 *)rVal.getValue() ); + break; + case TypeClass_HYPER: + printf( "%x", (long)*(sal_Int64 *)rVal.getValue() ); + break; + case TypeClass_UNSIGNED_HYPER: + printf( "%x", (unsigned long)*(sal_uInt64 *)rVal.getValue() ); + break; + case TypeClass_FLOAT: + printf( "%f", *(float *)rVal.getValue() ); + break; + case TypeClass_DOUBLE: + printf( "%g", *(double *)rVal.getValue() ); + break; + case TypeClass_STRING: + { + OString aStr( OUStringToOString( *(OUString *)rVal.getValue(), RTL_TEXTENCODING_ISO_8859_1 ) ); + printf( aStr.getStr() ); + break; + } + case TypeClass_ENUM: + { + typelib_EnumTypeDescription * pEnumTD = 0; + TYPELIB_DANGER_GET( (typelib_TypeDescription **)&pEnumTD, rVal.getValueTypeRef() ); + + for ( sal_Int32 nPos = pEnumTD->nEnumValues; nPos--; ) + { + if (pEnumTD->pEnumValues[nPos] == *(int *)rVal.getValue()) + { + printf( OUStringToOString(pEnumTD->ppEnumNames[nPos]->buffer, RTL_TEXTENCODING_ASCII_US).getStr() ); + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pEnumTD ); + return; + } + } + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pEnumTD ); + printf( ">ENUM not found!<" ); + break; + } + case TypeClass_SEQUENCE: + { + uno_Sequence * pSeq = *(uno_Sequence **)rVal.getValue(); + typelib_TypeDescription * pSeqTD = 0; + TYPELIB_DANGER_GET( &pSeqTD, rVal.getValueTypeRef() ); + typelib_TypeDescription * pElemTD = 0; + TYPELIB_DANGER_GET( &pElemTD, ((typelib_IndirectTypeDescription *)pSeqTD)->pType ); + + sal_Int32 nLen = pSeq->nElements; + if (nLen) + { + printf( "{ " ); + for ( sal_Int32 nPos = 0; nPos < nLen; ++nPos ) + { + printValue( Any( ((char *)pSeq->elements) + (nPos * pElemTD->nSize), pElemTD ) ); + if (nPos < (nLen-1)) + printf( ", " ); + } + printf( " }" ); + } + + TYPELIB_DANGER_RELEASE( pElemTD ); + TYPELIB_DANGER_RELEASE( pSeqTD ); + break; + } + + default: + printf( ">not printable<" ); + break; + } +} + +static Reference< XTypeConverter > s_xConverter; + +//================================================================================================== +static sal_Bool convertTo( const Type & rDestType, const Any & rVal, sal_Bool bExpectSuccess ) +{ + sal_Bool bCanConvert = sal_False; + Any aRet; + + OString aExcMsg; + + try + { + aRet = s_xConverter->convertTo( rVal, rDestType ); + bCanConvert = sal_True; + } + catch (Exception & rExc) + { + aExcMsg = OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ); + } + + if (bExpectSuccess && !bCanConvert) + { + printf( "# conversion of " ); + printValue( rVal ); + printf( " to " ); + printf( OUStringToOString(rDestType.getTypeName(), RTL_TEXTENCODING_ASCII_US).getStr() ); + printf( " failed, but success was expected! [" ); + printf( aExcMsg.getStr() ); + printf( "]\n" ); + return sal_False; + } + if (!bExpectSuccess && bCanConvert) + { + printf( "# conversion of " ); + printValue( rVal ); + printf( " to " ); + printValue( aRet ); + printf( " was successful, but was not expected to be!\n" ); + return sal_False; + } + +#ifdef __MAG_MARKUS_NICHT___EXTRA_AUSGABEN__ +//= re-conversion output = + if (bCanConvert) + { + // re convert to original type + sal_Bool bReConvert = sal_False; + Any aRet2; + + try + { + aRet2 = s_xConverter->convertTo( aRet, rVal.getValueType() ); + bReConvert = sal_True; + } + catch (Exception & rExc) + { + aExcMsg = OUStringToOString( rExc.Message, RTL_TEXTENCODING_ISO_8859_1 ); + } + + if (bReConvert) + { + if (rVal != aRet2) + { + printf( "# re-conversion of " ); + printValue( rVal ); + printf( " to " ); + printValue( aRet ); + printf( " to " ); + printValue( aRet2 ); + printf( ": first and last do not match!\n" ); + } + } + else + { + printf( "# re-conversion of " ); + printValue( aRet ); + printf( " to " ); + printf( rVal.getValueType().getTypeName().getStr() ); + printf( " failed! [" ); + printf( aExcMsg.getStr() ); + printf( "]\n" ); + } + } +#endif + + return sal_True; +} + + +//================================================================================================== +typedef struct _ConvBlock +{ + Any _value; + sal_Bool _toString, _toDouble, _toFloat; + sal_Bool _toUINT32, _toINT32, _toUINT16, _toINT16, _toBYTE, _toBOOL, _toChar; + sal_Bool _toTypeClass, _toSeqINT16, _toSeqAny; + + _ConvBlock() + { + } + _ConvBlock( const Any & rValue_, + sal_Bool toString_, sal_Bool toDouble_, sal_Bool toFloat_, + sal_Bool toUINT32_, sal_Bool toINT32_, sal_Bool toUINT16_, sal_Bool toINT16_, + sal_Bool toBYTE_, sal_Bool toBOOL_, sal_Bool toChar_, + sal_Bool toTypeClass_, sal_Bool toSeqINT16_, sal_Bool toSeqAny_ ) + : _value( rValue_ ) + , _toString( toString_ ), _toDouble( toDouble_ ), _toFloat( toFloat_ ) + , _toUINT32( toUINT32_ ), _toINT32( toINT32_ ), _toUINT16( toUINT16_ ), _toINT16( toINT16_ ) + , _toBYTE( toBYTE_ ), _toBOOL( toBOOL_ ), _toChar( toChar_ ) + , _toTypeClass( toTypeClass_ ), _toSeqINT16( toSeqINT16_ ), _toSeqAny( toSeqAny_ ) + { + } +} ConvBlock; + + +//================================================================================================== +static sal_Int32 initBlocks( ConvBlock * pTestBlocks ) +{ + Any aVal; + + sal_uInt32 nElems = 0; + + // ==BYTE== + aVal <<= OUString::createFromAscii( "0xff" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "255" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_Int8)0xff; + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "0x80" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "128" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_Int8)( 0x80 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "0x7f" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "127" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= (sal_Int8)( 0x7f ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "5" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "+5" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= (sal_Int8)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "-5" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int8)( -5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "256" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==UINT16== + aVal <<= OUString::createFromAscii( "65535" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "0xffff" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt16)( 0xffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "32768" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt16)( 0x8000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "32767" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "0x7fff" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt16)( 0x7fff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "256" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "0x100" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt16)( 0x100 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_uInt16)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_uInt16)( -5 ); // is 0xfffb + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==INT16== + aVal <<= (sal_Int16)( -1 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int16)( -0x8000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int16)( 0x7fff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int16)( 0x100 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int16)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int16)( -5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==UINT32== + aVal <<= OUString::createFromAscii( "+4294967295" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "4294967295" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "0xffffffff" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt32)( 0xffffffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "-2147483648" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "-0x80000000" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_uInt32)( 0x80000000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "2147483647" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "0x7fffffff" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt32)( 0x7fffffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "65536" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString::createFromAscii( "0x10000" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt32)( 0x10000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_uInt32)( 0x8000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_uInt32)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "0xfffffffb" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt32)( -5 ); // is 0xfffffffb + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==INT32== + aVal <<= (sal_Int32)( 0xffffffff ); // is -1 + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( -0x80000000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( 0x7fffffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( 0x10000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( -0x8001 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( -5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==FLOAT== + aVal <<= OUString::createFromAscii( "-3.4e+38" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (float)( MIN_FLOAT ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "+3.4e+38" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (float)( MAX_FLOAT ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "9e-20" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= (float)( 9e-20 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "+.7071067811865" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= (float)( .7071067811865 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "3.14159265359" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= (float)( 3.14159265359 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (float)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==DOUBLE== + aVal <<= OUString::createFromAscii( "-1.7976931348623158e+308" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (double)( MIN_DOUBLE ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "1.7976931348623158e+308" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (double)( MAX_DOUBLE ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( MIN_FLOAT ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( MAX_FLOAT ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( -((double)0x80000000) ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( -((double)0x80000001) ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( 0x7fffffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( 0x80000000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( 0xffffffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "0x100000000" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); +#ifndef OS2 + aVal <<= (double)( 0x100000000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); +#endif + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==CHAR== + sal_Unicode c = 'A'; + aVal.setValue( &c, ::getCharCppuType() ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "A" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==BOOL== + aVal <<= OUString::createFromAscii( "0" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "1" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "False" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "true" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + + sal_Bool bTmp = sal_True; + aVal.setValue( &bTmp, getBooleanCppuType() ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==ZERO STRINGS== + aVal <<= OUString(); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "-" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "-0" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==TYPECLASS ENUM== + aVal <<= OUString::createFromAscii( "eNuM" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString::createFromAscii( "DOUBLE" ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + int e = 1; + aVal.setValue( &e, ::getCppuType( (const TypeClass *)0 ) ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal.setValue( &e, ::getCppuType( (const FieldAccessMode *)0 ) ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==SEQ of INT== + Sequence< sal_Int32 > aINT32Seq( 3 ), aINT32Seq2( 3 ); + sal_Int32 * pINT32Seq = aINT32Seq.getArray(); + pINT32Seq[0] = -32768; + pINT32Seq[1] = 0; + pINT32Seq[2] = 32767; + aVal <<= aINT32Seq; + pTestBlocks[nElems++] = ConvBlock( aVal, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + pINT32Seq = aINT32Seq2.getArray(); + pINT32Seq[0] = -32768; + pINT32Seq[1] = -32769; + pINT32Seq[2] = 32767; + aVal <<= aINT32Seq2; + pTestBlocks[nElems++] = ConvBlock( aVal, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==SEQ of ANY== + Sequence< Any > aAnySeq( 2 ), aAnySeq2( 2 ), aAnySeq3( 2 ); + Any * pAnySeq = aAnySeq.getArray(); + pAnySeq[0] = makeAny( aINT32Seq ); + pAnySeq[1] = makeAny( OUString::createFromAscii("lala") ); + aVal <<= aAnySeq; + pTestBlocks[nElems++] = ConvBlock( aVal, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + pAnySeq = aAnySeq2.getArray(); + pAnySeq[0] <<= (sal_Int32)4711; + pAnySeq[1] <<= OUString::createFromAscii("0815"); + aVal <<= aAnySeq2; + pTestBlocks[nElems++] = ConvBlock( aVal, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + pAnySeq = aAnySeq3.getArray(); + pAnySeq[0] <<= OUString::createFromAscii("TypeClass_UNION"); + pAnySeq[1] <<= OUString::createFromAscii("TypeClass_ENUM"); + aVal <<= aAnySeq3; + pTestBlocks[nElems++] = ConvBlock( aVal, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + return nElems; +} + +//================================================================================================== +static void test_Conversion( const Reference< XMultiServiceFactory > & xMgr ) +{ + printf( "test_Conversion(): start...\n" ); + + Reference< XTypeConverter > xConverter( xMgr->createInstance( + OUString::createFromAscii( "com.sun.star.script.Converter" ) ), UNO_QUERY ); + + ConvBlock * pTestBlocks = new ConvBlock[256]; + sal_Int32 nPos = initBlocks( pTestBlocks ); + + s_xConverter = xConverter; + while (nPos--) + { + const ConvBlock& rBlock = pTestBlocks[nPos]; + const Any & rVal = rBlock._value; + + convertTo( ::getCppuType( (const OUString *)0 ), rVal, rBlock._toString ); + convertTo( ::getCppuType( (const float *)0 ), rVal, rBlock._toFloat ); + convertTo( ::getCppuType( (const double *)0 ), rVal, rBlock._toDouble ); + convertTo( ::getCppuType( (const sal_uInt32 *)0 ), rVal, rBlock._toUINT32 ); + convertTo( ::getCppuType( (const sal_Int32 *)0 ), rVal, rBlock._toINT32 ); + convertTo( ::getCppuType( (const sal_uInt16 *)0 ), rVal, rBlock._toUINT16 ); + convertTo( ::getCppuType( (const sal_Int16 *)0 ), rVal, rBlock._toINT16 ); + convertTo( ::getCppuType( (const sal_Int8 *)0 ), rVal, rBlock._toBYTE ); + convertTo( ::getBooleanCppuType(), rVal, rBlock._toBOOL ); + convertTo( ::getCharCppuType(), rVal, rBlock._toChar ); + convertTo( ::getCppuType( (const TypeClass *)0 ), rVal, rBlock._toTypeClass ); + convertTo( ::getCppuType( (const Sequence< sal_Int16 > *)0 ), rVal, rBlock._toSeqINT16 ); + convertTo( ::getCppuType( (const Sequence< Any > *)0 ), rVal, rBlock._toSeqAny ); + + convertTo( ::getVoidCppuType(), rVal, sal_True ); // anything converts to void + } + s_xConverter.clear(); + + delete [] pTestBlocks; + + Any aRet; + aRet = xConverter->convertTo( Any( &xMgr, ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) ), + ::getCppuType( (const Reference< XServiceInfo > *)0 ) ); + aRet = xConverter->convertTo( aRet, ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) ); + aRet = xConverter->convertTo( aRet, ::getCppuType( (const Reference< XServiceInfo > *)0 ) ); + aRet <<= (sal_Int64)0x7fffffffffffffff; + aRet = xConverter->convertTo( aRet, ::getCppuType( (const sal_uInt64 *)0 ) ); + OSL_ASSERT( *(const sal_uInt64 *)aRet.getValue() == (sal_uInt64)0x7fffffffffffffff ); + aRet <<= (sal_uInt64)0xffffffffffffffff; + aRet = xConverter->convertTo( aRet, ::getCppuType( (const sal_uInt64 *)0 ) ); + OSL_ASSERT( *(const sal_uInt64 *)aRet.getValue() == (sal_uInt64)0xffffffffffffffff ); + aRet <<= (sal_Int64)0xffffffffffffffff; + aRet = xConverter->convertTo( aRet, ::getCppuType( (const sal_Int8 *)0 ) ); + OSL_ASSERT( *(const sal_Int8 *)aRet.getValue() == (-1) ); + printf( "test_Conversion(): end.\n" ); +} + + +#ifdef UNX +#define REG_PREFIX "lib" +#define DLL_POSTFIX ".so" +#else +#define REG_PREFIX "" +#define DLL_POSTFIX ".dll" +#endif + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int __cdecl main( int argc, char * argv[] ) +#endif +{ + Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( OUString::createFromAscii("stoctest.rdb") ) ); + + try + { + Reference< XImplementationRegistration > xImplReg( + xMgr->createInstance( OUString::createFromAscii("com.sun.star.registry.ImplementationRegistration") ), UNO_QUERY ); + OSL_ENSHURE( xImplReg.is(), "### no impl reg!" ); + + OUString aLibName( OUString::createFromAscii( REG_PREFIX ) ); + aLibName += OUString::createFromAscii("tcv"); +#ifndef OS2 + aLibName += OUString::createFromAscii( DLL_POSTFIX ); +#endif + xImplReg->registerImplementation( + OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), + aLibName, Reference< XSimpleRegistry >() ); + + test_Conversion( xMgr ); + } + catch (Exception & rExc) + { + OSL_ENSHURE( sal_False, "### exception occured!" ); + OString aMsg( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "### exception occured: " ); + OSL_TRACE( aMsg.getStr() ); + OSL_TRACE( "\n" ); + } + + Reference< XComponent >( xMgr, UNO_QUERY )->dispose(); + return 0; +} diff --git a/stoc/test/testcorefl.cxx b/stoc/test/testcorefl.cxx new file mode 100644 index 000000000000..d5d4287a2270 --- /dev/null +++ b/stoc/test/testcorefl.cxx @@ -0,0 +1,439 @@ +/************************************************************************* + * + * $RCSfile: testcorefl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <osl/diagnose.h> + +#ifdef _DEBUG +#define TEST_ENSHURE(c, m) OSL_ENSHURE(c, m) +#else +#define TEST_ENSHURE(c, m) OSL_VERIFY(c) +#endif + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/implbase1.hxx> + +#include <ModuleA/XInterface1.hpp> +#include <ModuleC/XInterfaceA.hpp> +#include <ModuleC/XInterfaceB.hpp> +#include <ModuleC/ModuleC.hpp> + +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> + +#include <rtl/ustrbuf.hxx> + +#include <stdio.h> + + +using namespace rtl; +using namespace cppu; +using namespace osl; +using namespace ModuleA; +using namespace ModuleB; +using namespace ModuleC; +using namespace ModuleA::ModuleB; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::registry; +using namespace com::sun::star::reflection; +using namespace com::sun::star::container; + + +//================================================================================================== +class OInterfaceA : public WeakImplHelper1< XInterfaceA > +{ +public: + + virtual void SAL_CALL methodA(void) + {} + + virtual void SAL_CALL methodB(sal_Int16 aShort) + {} + virtual Sequence< StructB > SAL_CALL methodC(const StructC& aStructC, StructA& aStructA) + { return Sequence< StructB >(); } +}; + +//================================================================================================== +static inline uik_equals( const Uik & rUik1, const Uik & rUik2 ) +{ + return (rUik1.m_Data1 == rUik2.m_Data1 && + rUik1.m_Data2 == rUik2.m_Data2 && + rUik1.m_Data3 == rUik2.m_Data3 && + rUik1.m_Data4 == rUik2.m_Data4 && + rUik1.m_Data5 == rUik2.m_Data5); +} +//================================================================================================== +static sal_Bool test_corefl( const Reference< XIdlReflection > & xRefl ) +{ + Reference< XIdlClass > xClass; + Reference< XHierarchicalNameAccess > xHNameAccess( xRefl, UNO_QUERY ); + TEST_ENSHURE(xHNameAccess.is(), "### cannot get XHierarchicalNameAccess!" ); + + TEST_ENSHURE(xRefl->forName(OUString::createFromAscii("ModuleA.StructA"))->getName() == OUString::createFromAscii("ModuleA.StructA"), "test_RegCoreReflection(): error 2b"); + TEST_ENSHURE(xRefl->forName(OUString::createFromAscii("ModuleA.ExceptionB"))->getTypeClass() == TypeClass_EXCEPTION, "test_RegCoreReflection(): error 2c"); + TEST_ENSHURE(xRefl->forName(OUString::createFromAscii("ModuleA.ModuleB.EnumA")).is(), "test_RegCoreReflection(): error 2e"); + // const + + TEST_ENSHURE(*(const sal_Bool *)xHNameAccess->getByHierarchicalName(OUString::createFromAscii("ModuleC.aConstBoolean")).getValue() == aConstBoolean, "test_RegCoreReflection(): error 4c"); + TEST_ENSHURE(*(const sal_Int8 *)xHNameAccess->getByHierarchicalName(OUString::createFromAscii("ModuleC.aConstByte")).getValue() == aConstByte, "test_RegCoreReflection(): error 4e"); + TEST_ENSHURE(xHNameAccess->getByHierarchicalName(OUString::createFromAscii("ModuleC.aConstShort")) == aConstShort, "test_RegCoreReflection(): error 4g"); + TEST_ENSHURE(xHNameAccess->getByHierarchicalName(OUString::createFromAscii("ModuleC.aConstUShort")) == aConstUShort, "test_RegCoreReflection(): error 4i"); + TEST_ENSHURE(xHNameAccess->getByHierarchicalName(OUString::createFromAscii("ModuleC.aConstLong")) == aConstLong, "test_RegCoreReflection(): error 4k"); + TEST_ENSHURE(xHNameAccess->getByHierarchicalName(OUString::createFromAscii("ModuleC.aConstULong")) == aConstULong, "test_RegCoreReflection(): error 4m"); + TEST_ENSHURE(xHNameAccess->getByHierarchicalName(OUString::createFromAscii("ModuleC.aConstFloat")) == aConstFloat, "test_RegCoreReflection(): error 4o"); + TEST_ENSHURE(xHNameAccess->getByHierarchicalName(OUString::createFromAscii("ModuleC.aConstDouble")) == aConstDouble, "test_RegCoreReflection(): error 4q"); + TEST_ENSHURE(xHNameAccess->getByHierarchicalName(OUString::createFromAscii("ModuleC.aConstString")) == aConstString, "test_RegCoreReflection(): error 4s"); + + // Enums + + xClass = xRefl->forName(OUString::createFromAscii("ModuleA.ModuleB.EnumA")); + + TEST_ENSHURE(xClass.is(), "test_RegCoreReflection(): error 5"); + + Sequence<Reference< XIdlField > > fields = xClass->getFields(); + + TEST_ENSHURE( + (fields.getLength() == 3) && + (fields.getArray()[0]->getName() == OUString( RTL_CONSTASCII_USTRINGPARAM("VAL_1") )) && + (*(EnumA*)fields.getArray()[0]->get(Any()).getValue() == EnumA_VAL_1) && + (fields.getArray()[1]->getName() == OUString( RTL_CONSTASCII_USTRINGPARAM("VAL_2") )) && + (*(EnumA*)fields.getArray()[1]->get(Any()).getValue() == EnumA_VAL_2) && + (fields.getArray()[2]->getName() == OUString( RTL_CONSTASCII_USTRINGPARAM("VAL_3") )) && + (*(EnumA*)fields.getArray()[2]->get(Any()).getValue() == EnumA_VAL_3), + "test_RegCoreReflection(): error 6"); + + + // Interface + + Reference< XIdlClass > xA = xRefl->forName( OUString::createFromAscii("ModuleC.XInterfaceB") ); + + xClass = xRefl->forName(OUString::createFromAscii("ModuleC.XInterfaceB")); + + TEST_ENSHURE(xClass == xA, "test_RegCoreReflection(): error 7"); + TEST_ENSHURE(xClass.is(), "test_RegCoreReflection(): error 7a"); + + typelib_TypeDescription * pTD = 0; + OUString aModuleName( RTL_CONSTASCII_USTRINGPARAM("ModuleC.XInterfaceB") ); + typelib_typedescription_getByName( &pTD, aModuleName.pData ); + TEST_ENSHURE( pTD, "### cannot get typedescription for ModuleC.XInterfaceB!" ); + + TEST_ENSHURE( uik_equals( *(Uik *)&((typelib_InterfaceTypeDescription *)pTD)->aUik, + xClass->getUik() ), + "test_RegCoreReflection(): error 8" ); + typelib_typedescription_release( pTD ); + + TEST_ENSHURE(xClass->getSuperclasses().getLength() == 1, "test_RegCoreReflection(): error 9"); + TEST_ENSHURE(xClass->getSuperclasses().getArray()[0]->getName() == OUString::createFromAscii("ModuleC.XInterfaceA"), "test_RegCoreReflection(): error 10"); + TEST_ENSHURE(xClass->getMethods().getLength() == 7, "test_RegCoreReflection(): error 11"); + TEST_ENSHURE(xA->getMethods().getLength() == 7, "test_RegCoreReflection(): error 11a"); + TEST_ENSHURE(xClass->getMethods().getArray()[3]->getName() == OUString::createFromAscii("methodA"), "test_RegCoreReflection(): 12"); + TEST_ENSHURE(xClass->getMethods().getArray()[3]->getReturnType()->getTypeClass() == TypeClass_VOID, "test_RegCoreReflection(): error 13"); + TEST_ENSHURE(xClass->getMethods().getArray()[3]->getParameterTypes().getLength() == 0, "test_RegCoreReflection(): error 14"); + TEST_ENSHURE(xClass->getMethods().getArray()[3]->getExceptionTypes().getLength() == 0, "test_RegCoreReflection(): error 15"); + TEST_ENSHURE(xClass->getMethods().getArray()[4]->getName() == OUString( RTL_CONSTASCII_USTRINGPARAM("methodB") ), "test_RegCoreReflection(): error 16"); + TEST_ENSHURE(xClass->getMethods().getArray()[4]->getMode() == MethodMode_ONEWAY, "test_RegCoreReflection(): error 16a"); + TEST_ENSHURE(xClass->getMethods().getArray()[4]->getReturnType()->getTypeClass() == TypeClass_VOID, "test_RegCoreReflection(): error 16"); + TEST_ENSHURE(xClass->getMethods().getArray()[4]->getParameterTypes().getLength() == 1, "test_RegCoreReflection(): error 17"); + TEST_ENSHURE(xClass->getMethods().getArray()[4]->getParameterTypes().getArray()[0]->getTypeClass() == TypeClass_SHORT, "test_RegCoreReflection(): error 18"); + TEST_ENSHURE(xClass->getMethods().getArray()[4]->getParameterInfos().getArray()[0].aName == OUString( RTL_CONSTASCII_USTRINGPARAM("aShort") ), "test_RegCoreReflection(): error 18a"); + TEST_ENSHURE(xClass->getMethods().getArray()[4]->getParameterInfos().getArray()[0].aType == xRefl->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("short") ) ), "test_RegCoreReflection(): error 18b"); + TEST_ENSHURE(xClass->getMethods().getArray()[4]->getParameterInfos().getArray()[0].aMode == ParamMode_IN, "test_RegCoreReflection(): error 18c"); + TEST_ENSHURE(xClass->getMethods().getArray()[4]->getExceptionTypes().getLength() == 0, "test_RegCoreReflection(): error 19"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getName() == OUString::createFromAscii("methodC"), "test_RegCoreReflection(): error 20"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getMode() == MethodMode_TWOWAY, "test_RegCoreReflection(): error 20a"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getReturnType()->getTypeClass() == TypeClass_SEQUENCE, "test_RegCoreReflection(): error 21"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getReturnType()->getComponentType()->getTypeClass() == TypeClass_STRUCT, "test_RegCoreReflection(): error 22"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getReturnType()->getComponentType()->getName() == OUString::createFromAscii("ModuleA.StructB"), "test_RegCoreReflection(): error 23"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getParameterTypes().getLength() == 2, "test_RegCoreReflection(): error 24"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getParameterTypes().getArray()[0]->getTypeClass() == TypeClass_STRUCT, "test_RegCoreReflection(): error 25"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getParameterTypes().getArray()[0]->getName() == OUString::createFromAscii("ModuleA.StructC"), "test_RegCoreReflection(): error 26"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getParameterTypes().getArray()[1]->getTypeClass() == TypeClass_STRUCT, "test_RegCoreReflection(): error 27"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getParameterTypes().getArray()[1]->getName() == OUString::createFromAscii("ModuleA.StructA"), "test_RegCoreReflection(): error 28"); + TEST_ENSHURE(xClass->getMethods().getArray()[5]->getExceptionTypes().getLength() == 0, "test_RegCoreReflection(): error 29"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getName() == OUString::createFromAscii("methodD"), "test_RegCoreReflection(): error 30"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getReturnType()->getTypeClass() == TypeClass_INTERFACE, "test_RegCoreReflection(): error 31"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getReturnType()->getName() == OUString::createFromAscii("ModuleC.XInterfaceA"), "test_RegCoreReflection(): error 32"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getParameterTypes().getLength() == 1, "test_RegCoreReflection(): error 33"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getParameterTypes().getArray()[0]->getTypeClass() == TypeClass_ENUM, "test_RegCoreReflection(): error 34"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getParameterTypes().getArray()[0]->getName() == OUString::createFromAscii("ModuleA.ModuleB.EnumA"), "test_RegCoreReflection(): error 35"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getLength() == 3, "test_RegCoreReflection(): error 36"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[0]->getTypeClass() == TypeClass_EXCEPTION, "test_RegCoreReflection(): error 37"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[0]->getName() == OUString::createFromAscii("ModuleA.ExceptionA"), "test_RegCoreReflection(): error 38"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[1]->getTypeClass() == TypeClass_EXCEPTION, "test_RegCoreReflection(): error 38"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[1]->getName() == OUString::createFromAscii("ModuleA.ExceptionB"), "test_RegCoreReflection(): error 39"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getTypeClass() == TypeClass_EXCEPTION, "test_RegCoreReflection(): error 40"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getName() == OUString::createFromAscii("ModuleA.ExceptionC"), "test_RegCoreReflection(): error 41"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getLength() == 3, "test_RegCoreReflection(): error 42"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[0]->getType()->getTypeClass() == TypeClass_BOOLEAN, "test_RegCoreReflection(): error 43"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[0]->getType()->getName() == OUString::createFromAscii("boolean"), "test_RegCoreReflection(): error 43a"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[1]->getType()->getTypeClass() == TypeClass_STRUCT, "test_RegCoreReflection(): error 44"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[1]->getType()->getName() == OUString::createFromAscii("ModuleA.StructC"), "test_RegCoreReflection(): error 45"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[2]->getType()->getTypeClass() == TypeClass_INTERFACE, "test_RegCoreReflection(): error 46"); + TEST_ENSHURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[2]->getType()->getName() == OUString::createFromAscii("ModuleA.XInterface1"), "test_RegCoreReflection(): error 47"); + + // SequenceReflections + + TEST_ENSHURE(xRefl->forName( OUString::createFromAscii("[]ModuleA.StructA") )->getTypeClass() == TypeClass_SEQUENCE, "test_RegCoreReflection(): error 48"); + TEST_ENSHURE(xRefl->forName( OUString::createFromAscii("[]ModuleA.StructA") )->getComponentType().is(), "test_RegCoreReflection(): error 49"); + TEST_ENSHURE(xRefl->forName( OUString::createFromAscii("[][]ModuleA.StructA") )->getComponentType()->getComponentType()->getName() == OUString::createFromAscii("ModuleA.StructA"), "test_RegCoreReflection(): error 50"); + TEST_ENSHURE(xRefl->forName( OUString::createFromAscii("[]com.sun.star.uno.XInterface") ) == xRefl->forName(OUString( RTL_CONSTASCII_USTRINGPARAM("ModuleA.StructC") ))->getField(OUString::createFromAscii("aInterfaceSeq"))->getType(), "test_RegCoreReflection(): error 51"); + + StructC aStructC; + aStructC.aLong = aConstLong; + aStructC.aShort = aConstShort; + aStructC.aFloat = aConstFloat; + aStructC.aDouble = aConstDouble; + aStructC.aString = aConstString; + aStructC.aInterfaceSeq = Sequence<Reference<XInterface > >(); + + Any aAny; + + xRefl->forName(OUString::createFromAscii("ModuleA.StructC"))->getField(OUString::createFromAscii("aInterfaceSeq"))->getType()->createObject(aAny); + + TEST_ENSHURE(aAny.getValueType() == ::getCppuType( (const Sequence<Reference< XInterface > > *)0 ), "test_RegCoreReflection(): error 51a"); + + Any aStructAny(&aStructC, ::getCppuType( (const StructC *) 0 )); + + sal_Int32 nLong = aConstLong * 2; + aAny.setValue( &nLong, ::getCppuType( (const sal_Int32 *)0 ) ); + + TEST_ENSHURE(*(sal_Int32*)xRefl->forName(OUString( RTL_CONSTASCII_USTRINGPARAM("ModuleA.StructA") ))->getField(OUString( RTL_CONSTASCII_USTRINGPARAM("aLong") ))->get( + Any(&aStructC, ::getCppuType( (const StructC *)0 ))).getValue() == aConstLong, "test_RegCoreReflection(): error 52"); + TEST_ENSHURE(xRefl->forName(OUString::createFromAscii("ModuleA.StructA"))->getField(OUString( RTL_CONSTASCII_USTRINGPARAM("aLong") ))->getAccessMode() == FieldAccessMode_READWRITE, "test_RegCoreReflection(): error 52a"); + xRefl->forName(OUString( RTL_CONSTASCII_USTRINGPARAM("ModuleA.StructC") ))->getField(OUString( RTL_CONSTASCII_USTRINGPARAM("aLong") ))->set(aStructAny, aAny); + TEST_ENSHURE(*(sal_Int32*)xRefl->forName(OUString::createFromAscii("ModuleA.StructB"))->getField(OUString( RTL_CONSTASCII_USTRINGPARAM("aLong") ))->get(aStructAny).getValue() == *(sal_Int32*)aAny.getValue(), "test_RegCoreReflection(): error 53"); + + xRefl->forName( OUString::createFromAscii("[]ModuleA.StructA") )->createObject(aAny); + + TEST_ENSHURE(aAny.getValueTypeName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("[]ModuleA.StructA")), "test_RegCoreReflection(): error 54"); + xRefl->forName(OUString::createFromAscii("[][]ModuleA.StructA"))->createObject(aAny); + + TEST_ENSHURE(aAny.getValueTypeName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("[][]ModuleA.StructA") ), "test_RegCoreReflection(): error 56"); + +// xClass = xRefl->forName(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.XIntroTest") )); + +// TEST_ENSHURE(xClass.is(), "test_RegCoreReflection(): error 58"); +// TEST_ENSHURE(xClass->getMethod(OUString::createFromAscii("getStrings"))->getReturnType()->getTypeClass() == TypeClass_SEQUENCE, "test_RegCoreReflection(): error 59"); +// TEST_ENSHURE(xClass->getMethod(OUString::createFromAscii("getStrings"))->getReturnType()->getComponentType()->getName() == OUString::createFromAscii("string"), "test_RegCoreReflection(): error 60"); + +// xClass->getMethod(OUString::createFromAscii("getStrings"))->getReturnType()->createObject(aAny); +// TEST_ENSHURE(aAny.getValueTypeName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("[]string") ), "test_RegCoreReflection(): error 61"); + + TEST_ENSHURE(xRefl->forName(OUString::createFromAscii("[][][]unsigned long"))->getComponentType()->getComponentType()->getComponentType()->getTypeClass() == TypeClass_UNSIGNED_LONG, "test_RegCoreReflection(): error 62"); + + try + { + Any bla = xRefl->forName(OUString::createFromAscii("ModuleA.StructC"))->getField(OUString::createFromAscii("aString"))->get(Any()); + TEST_ENSHURE(sal_False, "test_RegCoreReflection(): error 63"); + return sal_False; + } + catch (IllegalArgumentException &) + { + } + + try + { + Any blup; + blup <<= aStructC; + Any gulp; + xRefl->forName(OUString::createFromAscii("ModuleA.StructC"))->getField(OUString::createFromAscii("aString"))->set(blup, gulp); + TEST_ENSHURE(sal_False, "test_RegCoreReflection(): error 64"); + return sal_False; + } + catch (IllegalArgumentException &) + { + } + + try + { + Any gulp; + gulp <<= 3.14f; + Any blup; + blup <<= aStructC; + xRefl->forName(OUString::createFromAscii("ModuleA.StructC"))->getField(OUString::createFromAscii("aString"))->set(blup, gulp); + TEST_ENSHURE(sal_False, "test_RegCoreReflection(): error 65"); + return sal_False; + } + catch (IllegalArgumentException &) + { + } + + Any gulp; + gulp <<= OUString(OUString::createFromAscii("Test")); + Any blup; + blup <<= aStructC; + xRefl->forName(OUString::createFromAscii("ModuleA.StructC"))->getField(OUString::createFromAscii("aString"))->set(blup, gulp); + + Reference< XInterfaceA > xAI = new OInterfaceA(); + + try + { + Sequence< Any > params; + + Any a; + a <<= xAI; + Any bla = xRefl->forName(OUString::createFromAscii("ModuleC.XInterfaceA"))->getMethod(OUString::createFromAscii("methodC"))->invoke(a, params); + TEST_ENSHURE(sal_False, "test_RegCoreReflection(): error 66"); + return sal_False; + } + catch (IllegalArgumentException &) + { + } + + StructA aStructA; + + { + Sequence< Any > params(2); + + params.getArray()[0].setValue(&aStructC, ::getCppuType( (const StructC *)0 )); + params.getArray()[1].setValue(&aStructC, ::getCppuType( (const StructC *)0 )); + + Any a; + a <<= xAI; + Any bla = xRefl->forName(OUString::createFromAscii("ModuleC.XInterfaceA"))->getMethod(OUString::createFromAscii("methodC"))->invoke(a, params); + } + try + { + Sequence< Any > params(2); + + params.getArray()[0].setValue(&aStructA, ::getCppuType( (const StructA *)0 )); + params.getArray()[1].setValue(&aStructA, ::getCppuType( (const StructA *)0 )); + + Any a; + a <<= xAI; + Any bla = xRefl->forName(OUString::createFromAscii("ModuleC.XInterfaceA"))->getMethod(OUString::createFromAscii("methodC"))->invoke(a, params); + TEST_ENSHURE(sal_False, "test_RegCoreReflection(): error 67"); + return sal_False; + } + catch (IllegalArgumentException &) + { + } + + Sequence< Any > params(2); + + params.getArray()[0].setValue(&aStructC, ::getCppuType( (const StructC *)0 )); + params.getArray()[1].setValue(&aStructA, ::getCppuType( (const StructA *)0 )); + + Any a; + a <<= xAI; + TEST_ENSHURE(xRefl->forName(OUString::createFromAscii("ModuleC.XInterfaceA"))->getMethod(OUString::createFromAscii("methodC"))->invoke(a, params).getValueType() + == ::getCppuType( (const Sequence<StructB> *)0 ), "test_RegCoreReflection(): error 68"); + + return sal_True; +} + +#ifdef UNX +#define REG_PREFIX "lib" +#define DLL_POSTFIX ".so" +#else +#define REG_PREFIX "" +#define DLL_POSTFIX ".dll" +#endif + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int __cdecl main( int argc, char * argv[] ) +#endif +{ + Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("stoctest.rdb") ) ) ); + + sal_Bool bSucc = sal_False; + try + { + Reference< XImplementationRegistration > xImplReg( + xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.ImplementationRegistration") ) ), UNO_QUERY ); + OSL_ENSHURE( xImplReg.is(), "### no impl reg!" ); + + OUString aLibName( OUString::createFromAscii(REG_PREFIX) ); + aLibName += OUString::createFromAscii("corefl"); +#ifndef OS2 + aLibName += OUString::createFromAscii(DLL_POSTFIX); +#endif + xImplReg->registerImplementation( + OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), aLibName, Reference< XSimpleRegistry >() ); + + Reference< XIdlReflection > xRefl( xMgr->createInstance( OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ), UNO_QUERY ); + OSL_ENSHURE( xRefl.is(), "### no corereflection!" ); + + bSucc = test_corefl( xRefl ); + } + catch (Exception & rExc) + { + OSL_ENSHURE( sal_False, "### exception occured!" ); + OString aMsg( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "### exception occured: " ); + OSL_TRACE( aMsg.getStr() ); + OSL_TRACE( "\n" ); + } + + Reference< XComponent >( xMgr, UNO_QUERY )->dispose(); + + printf( "testcorefl %s !\n", (bSucc ? "succeeded" : "failed") ); + return (bSucc ? 0 : -1); +} diff --git a/stoc/test/testcorefl.idl b/stoc/test/testcorefl.idl new file mode 100644 index 000000000000..317a39b1743d --- /dev/null +++ b/stoc/test/testcorefl.idl @@ -0,0 +1,140 @@ +/************************************************************************* + * + * $RCSfile: testcorefl.idl,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <com/sun/star/uno/XInterface.idl> + +module ModuleA +{ + exception ExceptionA + { + boolean aBoolean; + }; + + struct StructA + { + long aLong; + short aShort; + }; + + struct StructB : StructA + { + double aDouble; + float aFloat; + }; + + struct StructC : StructB + { + string aString; + sequence<com::sun::star::uno::XInterface> aInterfaceSeq; + }; + + exception ExceptionB : ExceptionA + { + StructC aStructC; + }; + + [ uik(e227a3A1-33d6-12d1-aabe02a0-249d5590), ident("InterfaceB", 1.0) ] + interface XInterface1 : com::sun::star::uno::XInterface + { + }; + + exception ExceptionC : ExceptionB + { + XInterface1 aInterface1; + }; + + module ModuleB + { + enum EnumA { VAL_1, VAL_2, VAL_3 = 17}; + }; + +}; + +module ModuleC +{ + const boolean aConstBoolean = True; + const byte aConstByte = 0; + const short aConstShort = -1; + const unsigned short aConstUShort = 1; + const long aConstLong = -2; + const unsigned long aConstULong = 2; +// const hyper aConstHyper = -3; +// const unsigned hyper aConstUHyper = 3; + const float aConstFloat = 3.14; + const double aConstDouble = 3.14e-10; + const string aConstString = "test"; + + + [ uik(e227a3A0-33d6-11d1-aabe02a0-249d5590), ident("InterfaceA", 1.0) ] + interface XInterfaceA : com::sun::star::uno::XInterface + { + void methodA(); + [oneway] void methodB([in] short aShort); + sequence<ModuleA::StructB> methodC([in] ModuleA::StructC aStructC, [inout] ModuleA::StructA aStructA); + }; + + [ uik(e227a3A1-33d6-11d1-aabe02a0-12345678), ident("InterfaceB", 1.0) ] + interface XInterfaceB : XInterfaceA + { + [attribute] string aString; + + XInterfaceA methodD([in] ModuleA::ModuleB::EnumA aEnumA) raises (ModuleA::ExceptionA, ModuleA::ExceptionB, ModuleA::ExceptionC); + }; +}; diff --git a/stoc/test/testiadapter.cxx b/stoc/test/testiadapter.cxx new file mode 100644 index 000000000000..40101cacac3b --- /dev/null +++ b/stoc/test/testiadapter.cxx @@ -0,0 +1,1029 @@ +/************************************************************************* + * + * $RCSfile: testiadapter.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <stdio.h> + +#include <osl/diagnose.h> + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/weak.hxx> + +#include <test/XLanguageBindingTest.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/script/XInvocation.hpp> +#include <com/sun/star/script/XInvocationAdapterFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> + +#include <cppuhelper/implbase1.hxx> + + +using namespace test; +using namespace rtl; +using namespace cppu; +using namespace osl; +using namespace com::sun::star::uno; +using namespace com::sun::star::script; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::reflection; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; + + +//================================================================================================== +sal_Bool equals( const test::TestElement & rData1, const test::TestElement & rData2 ) +{ + OSL_ENSHURE( rData1.Bool == rData2.Bool, "### bool does not match!" ); + OSL_ENSHURE( rData1.Char == rData2.Char, "### char does not match!" ); + OSL_ENSHURE( rData1.Byte == rData2.Byte, "### byte does not match!" ); + OSL_ENSHURE( rData1.Short == rData2.Short, "### short does not match!" ); + OSL_ENSHURE( rData1.UShort == rData2.UShort, "### unsigned short does not match!" ); + OSL_ENSHURE( rData1.Long == rData2.Long, "### long does not match!" ); + OSL_ENSHURE( rData1.ULong == rData2.ULong, "### unsigned long does not match!" ); + OSL_ENSHURE( rData1.Hyper == rData2.Hyper, "### hyper does not match!" ); + OSL_ENSHURE( rData1.UHyper == rData2.UHyper, "### unsigned hyper does not match!" ); + OSL_ENSHURE( rData1.Float == rData2.Float, "### float does not match!" ); + OSL_ENSHURE( rData1.Double == rData2.Double, "### double does not match!" ); + OSL_ENSHURE( rData1.Enum == rData2.Enum, "### enum does not match!" ); + OSL_ENSHURE( rData1.String == rData2.String, "### string does not match!" ); + OSL_ENSHURE( rData1.Interface == rData2.Interface, "### interface does not match!" ); + OSL_ENSHURE( rData1.Any == rData2.Any, "### any does not match!" ); + + return (rData1.Bool == rData2.Bool && + rData1.Char == rData2.Char && + rData1.Byte == rData2.Byte && + rData1.Short == rData2.Short && + rData1.UShort == rData2.UShort && + rData1.Long == rData2.Long && + rData1.ULong == rData2.ULong && + rData1.Hyper == rData2.Hyper && + rData1.UHyper == rData2.UHyper && + rData1.Float == rData2.Float && + rData1.Double == rData2.Double && + rData1.Enum == rData2.Enum && + rData1.String == rData2.String && + rData1.Interface == rData2.Interface && + rData1.Any == rData2.Any); +} +//================================================================================================== +sal_Bool equals( const test::TestData & rData1, const test::TestData & rData2 ) +{ + sal_Int32 nLen; + + if ((rData1.Sequence == rData2.Sequence) && + equals( (const test::TestElement &)rData1, (const test::TestElement &)rData2 ) && + (nLen = rData1.Sequence.getLength()) == rData2.Sequence.getLength()) + { + // once again by hand sequence == + const test::TestElement * pElements1 = rData1.Sequence.getConstArray(); + const test::TestElement * pElements2 = rData2.Sequence.getConstArray(); + for ( ; nLen--; ) + { + if (! equals( pElements1[nLen], pElements2[nLen] )) + { + OSL_ENSHURE( sal_False, "### sequence element did not match!" ); + return sal_False; + } + } + return sal_True; + } + return sal_False; +} +//================================================================================================== +void assign( test::TestElement & rData, + sal_Bool bBool, sal_Unicode cChar, sal_Int8 nByte, + sal_Int16 nShort, sal_uInt16 nUShort, + sal_Int32 nLong, sal_uInt32 nULong, + sal_Int64 nHyper, sal_uInt64 nUHyper, + float fFloat, double fDouble, + test::TestEnum eEnum, const ::rtl::OUString& rStr, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xTest, + const ::com::sun::star::uno::Any& rAny ) +{ + rData.Bool = bBool; + rData.Char = cChar; + rData.Byte = nByte; + rData.Short = nShort; + rData.UShort = nUShort; + rData.Long = nLong; + rData.ULong = nULong; + rData.Hyper = nHyper; + rData.UHyper = nUHyper; + rData.Float = fFloat; + rData.Double = fDouble; + rData.Enum = eEnum; + rData.String = rStr; + rData.Interface = xTest; + rData.Any = rAny; +} +//================================================================================================== +void assign( test::TestData & rData, + sal_Bool bBool, sal_Unicode cChar, sal_Int8 nByte, + sal_Int16 nShort, sal_uInt16 nUShort, + sal_Int32 nLong, sal_uInt32 nULong, + sal_Int64 nHyper, sal_uInt64 nUHyper, + float fFloat, double fDouble, + test::TestEnum eEnum, const ::rtl::OUString& rStr, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xTest, + const ::com::sun::star::uno::Any& rAny, + const com::sun::star::uno::Sequence< test::TestElement >& rSequence ) +{ + assign( (test::TestElement &)rData, + bBool, cChar, nByte, nShort, nUShort, nLong, nULong, nHyper, nUHyper, fFloat, fDouble, + eEnum, rStr, xTest, rAny ); + rData.Sequence = rSequence; +} + +//================================================================================================== +class Test_Impl : public WeakImplHelper1< XLanguageBindingTest > +{ + test::TestData _aData, _aStructData; + +public: + virtual ~Test_Impl() + { OSL_TRACE( "> scalar Test_Impl dtor <\n" ); } + + // XLBTestBase + virtual void SAL_CALL setValues( sal_Bool bBool, sal_Unicode cChar, sal_Int8 nByte, + sal_Int16 nShort, sal_uInt16 nUShort, + sal_Int32 nLong, sal_uInt32 nULong, + sal_Int64 nHyper, sal_uInt64 nUHyper, + float fFloat, double fDouble, + test::TestEnum eEnum, const ::rtl::OUString& rStr, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xTest, + const ::com::sun::star::uno::Any& rAny, + const ::com::sun::star::uno::Sequence<test::TestElement >& rSequence, + const test::TestData& rStruct ) + throw(com::sun::star::uno::RuntimeException); + + virtual test::TestData SAL_CALL setValues2( sal_Bool& bBool, sal_Unicode& cChar, sal_Int8& nByte, + sal_Int16& nShort, sal_uInt16& nUShort, + sal_Int32& nLong, sal_uInt32& nULong, + sal_Int64& nHyper, sal_uInt64& nUHyper, + float& fFloat, double& fDouble, + test::TestEnum& eEnum, rtl::OUString& rStr, + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xTest, + ::com::sun::star::uno::Any& rAny, + ::com::sun::star::uno::Sequence<test::TestElement >& rSequence, + test::TestData& rStruct ) + throw(com::sun::star::uno::RuntimeException); + + virtual test::TestData SAL_CALL getValues( sal_Bool& bBool, sal_Unicode& cChar, sal_Int8& nByte, + sal_Int16& nShort, sal_uInt16& nUShort, + sal_Int32& nLong, sal_uInt32& nULong, + sal_Int64& nHyper, sal_uInt64& nUHyper, + float& fFloat, double& fDouble, + test::TestEnum& eEnum, rtl::OUString& rStr, + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xTest, + ::com::sun::star::uno::Any& rAny, + ::com::sun::star::uno::Sequence< test::TestElement >& rSequence, + test::TestData& rStruct ) + throw(com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL getBool() throw(com::sun::star::uno::RuntimeException) + { return _aData.Bool; } + virtual sal_Int8 SAL_CALL getByte() throw(com::sun::star::uno::RuntimeException) + { return _aData.Byte; } + virtual sal_Unicode SAL_CALL getChar() throw(com::sun::star::uno::RuntimeException) + { return _aData.Char; } + virtual sal_Int16 SAL_CALL getShort() throw(com::sun::star::uno::RuntimeException) + { return _aData.Short; } + virtual sal_uInt16 SAL_CALL getUShort() throw(com::sun::star::uno::RuntimeException) + { return _aData.UShort; } + virtual sal_Int32 SAL_CALL getLong() throw(com::sun::star::uno::RuntimeException) + { return _aData.Long; } + virtual sal_uInt32 SAL_CALL getULong() throw(com::sun::star::uno::RuntimeException) + { return _aData.ULong; } + virtual sal_Int64 SAL_CALL getHyper() throw(com::sun::star::uno::RuntimeException) + { return _aData.Hyper; } + virtual sal_uInt64 SAL_CALL getUHyper() throw(com::sun::star::uno::RuntimeException) + { return _aData.UHyper; } + virtual float SAL_CALL getFloat() throw(com::sun::star::uno::RuntimeException) + { return _aData.Float; } + virtual double SAL_CALL getDouble() throw(com::sun::star::uno::RuntimeException) + { return _aData.Double; } + virtual test::TestEnum SAL_CALL getEnum() throw(com::sun::star::uno::RuntimeException) + { return _aData.Enum; } + virtual rtl::OUString SAL_CALL getString() throw(com::sun::star::uno::RuntimeException) + { return _aData.String; } + virtual com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getInterface( ) throw(com::sun::star::uno::RuntimeException) + { return _aData.Interface; } + virtual com::sun::star::uno::Any SAL_CALL getAny() throw(com::sun::star::uno::RuntimeException) + { return _aData.Any; } + virtual com::sun::star::uno::Sequence< test::TestElement > SAL_CALL getSequence() throw(com::sun::star::uno::RuntimeException) + { return _aData.Sequence; } + virtual test::TestData SAL_CALL getStruct() throw(com::sun::star::uno::RuntimeException) + { return _aStructData; } + + virtual void SAL_CALL setBool( sal_Bool _bool ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Bool = _bool; } + virtual void SAL_CALL setByte( sal_Int8 _byte ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Byte = _byte; } + virtual void SAL_CALL setChar( sal_Unicode _char ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Char = _char; } + virtual void SAL_CALL setShort( sal_Int16 _short ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Short = _short; } + virtual void SAL_CALL setUShort( sal_uInt16 _ushort ) throw(::com::sun::star::uno::RuntimeException) + { _aData.UShort = _ushort; } + virtual void SAL_CALL setLong( sal_Int32 _long ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Long = _long; } + virtual void SAL_CALL setULong( sal_uInt32 _ulong ) throw(::com::sun::star::uno::RuntimeException) + { _aData.ULong = _ulong; } + virtual void SAL_CALL setHyper( sal_Int64 _hyper ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Hyper = _hyper; } + virtual void SAL_CALL setUHyper( sal_uInt64 _uhyper ) throw(::com::sun::star::uno::RuntimeException) + { _aData.UHyper = _uhyper; } + virtual void SAL_CALL setFloat( float _float ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Float = _float; } + virtual void SAL_CALL setDouble( double _double ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Double = _double; } + virtual void SAL_CALL setEnum( test::TestEnum _enum ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Enum = _enum; } + virtual void SAL_CALL setString( const ::rtl::OUString& _string ) throw(::com::sun::star::uno::RuntimeException) + { _aData.String = _string; } + virtual void SAL_CALL setInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _interface ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Interface = _interface; } + virtual void SAL_CALL setAny( const ::com::sun::star::uno::Any& _any ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Any = _any; } + virtual void SAL_CALL setSequence( const ::com::sun::star::uno::Sequence<test::TestElement >& _sequence ) throw(::com::sun::star::uno::RuntimeException) + { _aData.Sequence = _sequence; } + virtual void SAL_CALL setStruct( const test::TestData& _struct ) throw(::com::sun::star::uno::RuntimeException) + { _aStructData = _struct; } + + // XLanguageBindingTest + virtual test::TestData SAL_CALL raiseException( sal_Bool& bBool, sal_Unicode& cChar, sal_Int8& nByte, sal_Int16& nShort, sal_uInt16& nUShort, sal_Int32& nLong, sal_uInt32& nULong, sal_Int64& nHyper, sal_uInt64& nUHyper, float& fFloat, double& fDouble, test::TestEnum& eEnum, ::rtl::OUString& aString, ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xInterface, ::com::sun::star::uno::Any& aAny, ::com::sun::star::uno::Sequence<test::TestElement >& aSequence,test::TestData& aStruct ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getRuntimeException() throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setRuntimeException( sal_Int32 _runtimeexception ) throw(::com::sun::star::uno::RuntimeException); +}; +//================================================================================================== +class XLB_Invocation : public WeakImplHelper1< XInvocation > +{ + Reference< XLanguageBindingTest > _xLBT; + +public: + XLB_Invocation( const Reference< XMultiServiceFactory > & xMgr, + const Reference< XLanguageBindingTest > & xLBT ) + : _xLBT( xLBT ) + {} + + // XInvocation + virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw(::com::sun::star::uno::RuntimeException) + { return Reference< XIntrospectionAccess >(); } + virtual Any SAL_CALL invoke( const OUString & rFunctionName, + const Sequence< Any > & rParams, + Sequence< sal_Int16 > & rOutParamIndex, + Sequence< Any > & rOutParam ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::script::CannotConvertException, ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setValue( const OUString & rPropertyName, const Any & rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::script::CannotConvertException, ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException); + virtual Any SAL_CALL getValue( const OUString & rPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasMethod( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasProperty( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); +}; +//__________________________________________________________________________________________________ +Any XLB_Invocation::invoke( const OUString & rFunctionName, + const Sequence< Any > & rParams, + Sequence< sal_Int16 > & rOutParamIndex, + Sequence< Any > & rOutParam ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::script::CannotConvertException, ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException) +{ + Any aRet; + + OSL_ASSERT( rOutParam.getLength() == 0 ); + OSL_ASSERT( rOutParamIndex.getLength() == 0 ); + + try + { + sal_Bool aBool; + sal_Unicode aChar; + sal_Int8 nByte; + sal_Int16 nShort; + sal_uInt16 nUShort; + sal_Int32 nLong; + sal_uInt32 nULong; + sal_Int64 nHyper; + sal_uInt64 nUHyper; + float fFloat; + double fDouble; + TestEnum eEnum; + OUString aString; + Reference< XInterface > xInterface; + Any aAny; + Sequence< TestElement > aSeq; + TestData aData; + + if (rFunctionName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("setValues") )) + { + OSL_ASSERT( rParams.getLength() == 17 ); + aBool = *(sal_Bool *)rParams[0].getValue(); + aChar = *(sal_Unicode *)rParams[1].getValue(); + rParams[2] >>= nByte; + rParams[3] >>= nShort; + rParams[4] >>= nUShort; + rParams[5] >>= nLong; + rParams[6] >>= nULong; + rParams[7] >>= nHyper; + rParams[8] >>= nUHyper; + rParams[9] >>= fFloat; + rParams[10] >>= fDouble; + rParams[11] >>= eEnum; + rParams[12] >>= aString; + rParams[13] >>= xInterface; + rParams[14] >>= aAny; + rParams[15] >>= aSeq; + rParams[16] >>= aData; + + _xLBT->setValues( aBool, aChar, nByte, nShort, nUShort, nLong, nULong, + nHyper, nUHyper, fFloat, fDouble, eEnum, aString, xInterface, + aAny, aSeq, aData ); + + rOutParamIndex.realloc( 0 ); + rOutParam.realloc( 0 ); + } + else if (rFunctionName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("setValues2") )) + { + aBool = *(sal_Bool *)rParams[0].getValue(); + aChar = *(sal_Unicode *)rParams[1].getValue(); + rParams[2] >>= nByte; + rParams[3] >>= nShort; + rParams[4] >>= nUShort; + rParams[5] >>= nLong; + rParams[6] >>= nULong; + rParams[7] >>= nHyper; + rParams[8] >>= nUHyper; + rParams[9] >>= fFloat; + rParams[10] >>= fDouble; + rParams[11] >>= eEnum; + rParams[12] >>= aString; + rParams[13] >>= xInterface; + rParams[14] >>= aAny; + rParams[15] >>= aSeq; + rParams[16] >>= aData; + + aRet <<= _xLBT->setValues2( aBool, aChar, nByte, nShort, nUShort, nLong, nULong, + nHyper, nUHyper, fFloat, fDouble, eEnum, aString, xInterface, + aAny, aSeq, aData ); + + rOutParamIndex.realloc( 17 ); + rOutParamIndex[0] = 0; + rOutParamIndex[1] = 1; + rOutParamIndex[2] = 2; + rOutParamIndex[3] = 3; + rOutParamIndex[4] = 4; + rOutParamIndex[5] = 5; + rOutParamIndex[6] = 6; + rOutParamIndex[7] = 7; + rOutParamIndex[8] = 8; + rOutParamIndex[9] = 9; + rOutParamIndex[10] = 10; + rOutParamIndex[11] = 11; + rOutParamIndex[12] = 12; + rOutParamIndex[13] = 13; + rOutParamIndex[14] = 14; + rOutParamIndex[15] = 15; + rOutParamIndex[16] = 16; + + rOutParam.realloc( 17 ); + rOutParam[0].setValue( &aBool, ::getCppuBooleanType() ); + rOutParam[1].setValue( &aChar, ::getCppuCharType() ); + rOutParam[2] <<= nByte; + rOutParam[3] <<= nShort; + rOutParam[4] <<= nUShort; + rOutParam[5] <<= nLong; + rOutParam[6] <<= nULong; + rOutParam[7] <<= nHyper; + rOutParam[8] <<= nUHyper; + rOutParam[9] <<= fFloat; + rOutParam[10] <<= fDouble; + rOutParam[11] <<= eEnum; + rOutParam[12] <<= aString; + rOutParam[13] <<= xInterface; + rOutParam[14] <<= aAny; + rOutParam[15] <<= aSeq; + rOutParam[16] <<= aData; + } + else if (rFunctionName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("getValues") )) + { + aRet <<= _xLBT->getValues( aBool, aChar, nByte, nShort, nUShort, nLong, nULong, + nHyper, nUHyper, fFloat, fDouble, eEnum, aString, xInterface, + aAny, aSeq, aData ); + + rOutParamIndex.realloc( 17 ); + rOutParamIndex[0] = 0; + rOutParamIndex[1] = 1; + rOutParamIndex[2] = 2; + rOutParamIndex[3] = 3; + rOutParamIndex[4] = 4; + rOutParamIndex[5] = 5; + rOutParamIndex[6] = 6; + rOutParamIndex[7] = 7; + rOutParamIndex[8] = 8; + rOutParamIndex[9] = 9; + rOutParamIndex[10] = 10; + rOutParamIndex[11] = 11; + rOutParamIndex[12] = 12; + rOutParamIndex[13] = 13; + rOutParamIndex[14] = 14; + rOutParamIndex[15] = 15; + rOutParamIndex[16] = 16; + + rOutParam.realloc( 17 ); + rOutParam[0].setValue( &aBool, ::getCppuBooleanType() ); + rOutParam[1].setValue( &aChar, ::getCppuCharType() ); + rOutParam[2] <<= nByte; + rOutParam[3] <<= nShort; + rOutParam[4] <<= nUShort; + rOutParam[5] <<= nLong; + rOutParam[6] <<= nULong; + rOutParam[7] <<= nHyper; + rOutParam[8] <<= nUHyper; + rOutParam[9] <<= fFloat; + rOutParam[10] <<= fDouble; + rOutParam[11] <<= eEnum; + rOutParam[12] <<= aString; + rOutParam[13] <<= xInterface; + rOutParam[14] <<= aAny; + rOutParam[15] <<= aSeq; + rOutParam[16] <<= aData; + } + else if (rFunctionName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("raiseException") )) + { + aRet <<= _xLBT->raiseException( aBool, aChar, nByte, nShort, nUShort, nLong, nULong, + nHyper, nUHyper, fFloat, fDouble, eEnum, aString, xInterface, + aAny, aSeq, aData ); + + rOutParamIndex.realloc( 17 ); + rOutParamIndex[0] = 0; + rOutParamIndex[1] = 1; + rOutParamIndex[2] = 2; + rOutParamIndex[3] = 3; + rOutParamIndex[4] = 4; + rOutParamIndex[5] = 5; + rOutParamIndex[6] = 6; + rOutParamIndex[7] = 7; + rOutParamIndex[8] = 8; + rOutParamIndex[9] = 9; + rOutParamIndex[10] = 10; + rOutParamIndex[11] = 11; + rOutParamIndex[12] = 12; + rOutParamIndex[13] = 13; + rOutParamIndex[14] = 14; + rOutParamIndex[15] = 15; + rOutParamIndex[16] = 16; + + rOutParam.realloc( 17 ); + rOutParam[0].setValue( &aBool, ::getCppuBooleanType() ); + rOutParam[1].setValue( &aChar, ::getCppuCharType() ); + rOutParam[2] <<= nByte; + rOutParam[3] <<= nShort; + rOutParam[4] <<= nUShort; + rOutParam[5] <<= nLong; + rOutParam[6] <<= nULong; + rOutParam[7] <<= nHyper; + rOutParam[8] <<= nUHyper; + rOutParam[9] <<= fFloat; + rOutParam[10] <<= fDouble; + rOutParam[11] <<= eEnum; + rOutParam[12] <<= aString; + rOutParam[13] <<= xInterface; + rOutParam[14] <<= aAny; + rOutParam[15] <<= aSeq; + rOutParam[16] <<= aData; + } + else + { + OSL_ENSHURE( sal_False, "no XLanguageBindingTest call received on invocation!" ); + } + } + catch (IllegalArgumentException & rExc) + { + // thrown by raiseException() call + InvocationTargetException aExc; + aExc.TargetException <<= rExc; + throw aExc; + } + catch (Exception &) + { + OSL_ENSHURE( sal_False, "### unexpected exception caught!" ); + throw; + } + + return aRet; +} +//__________________________________________________________________________________________________ +void XLB_Invocation::setValue( const OUString & rName, const Any & rValue ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::script::CannotConvertException, ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException) +{ + if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Bool") )) + _xLBT->setBool( *(const sal_Bool *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Byte") )) + _xLBT->setByte( *(const sal_Int8 *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Char") )) + _xLBT->setChar( *(const sal_Unicode *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Short") )) + _xLBT->setShort( *(const sal_Int16 *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("UShort") )) + _xLBT->setUShort( *(const sal_uInt16 *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Long") )) + _xLBT->setLong( *(const sal_Int32 *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ULong") )) + _xLBT->setULong( *(const sal_uInt32 *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Hyper") )) + _xLBT->setHyper( *(const sal_Int64 *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("UHyper") )) + _xLBT->setUHyper( *(const sal_uInt64 *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Float") )) + _xLBT->setFloat( *(const float *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Double") )) + _xLBT->setDouble( *(const double *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Enum") )) + _xLBT->setEnum( *(const TestEnum *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("String") )) + _xLBT->setString( *(const OUString *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Interface") )) + _xLBT->setInterface( *(const Reference< XInterface > *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Any") )) + _xLBT->setAny( rValue ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Sequence") )) + _xLBT->setSequence( *(const Sequence< TestElement > *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Struct") )) + _xLBT->setStruct( *(const TestData *)rValue.getValue() ); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("RuntimeException") )) + _xLBT->setRuntimeException( *(const sal_Int32 *)rValue.getValue() ); +} +//__________________________________________________________________________________________________ +Any XLB_Invocation::getValue( const OUString & rName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + Any aRet; + if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Bool") )) + { + sal_Bool aBool = _xLBT->getBool(); + aRet.setValue( &aBool, ::getCppuBooleanType() ); + } + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Byte") )) + aRet <<= _xLBT->getByte(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Char") )) + { + sal_Unicode aChar = _xLBT->getChar(); + aRet.setValue( &aChar, ::getCppuCharType() ); + } + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Short") )) + aRet <<= _xLBT->getShort(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("UShort") )) + aRet <<= _xLBT->getUShort(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Long") )) + aRet <<= _xLBT->getLong(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ULong") )) + aRet <<= _xLBT->getULong(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Hyper") )) + aRet <<= _xLBT->getHyper(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("UHyper") )) + aRet <<= _xLBT->getUHyper(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Float") )) + aRet <<= _xLBT->getFloat(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Double") )) + aRet <<= _xLBT->getDouble(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Enum") )) + aRet <<= _xLBT->getEnum(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("String") )) + aRet <<= _xLBT->getString(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Interface") )) + aRet <<= _xLBT->getInterface(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Any") )) + aRet <<= _xLBT->getAny(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Sequence") )) + aRet <<= _xLBT->getSequence(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Struct") )) + aRet <<= _xLBT->getStruct(); + else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("RuntimeException") )) + aRet <<= _xLBT->getRuntimeException(); + return aRet; +} +//__________________________________________________________________________________________________ +sal_Bool XLB_Invocation::hasMethod( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + return (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("raiseException") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("getValues") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("setValues2") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("setValues") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("acquire") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("release") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("queryInterface") )); +} +//__________________________________________________________________________________________________ +sal_Bool XLB_Invocation::hasProperty( const OUString & rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + return (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Bool") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Byte") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Char") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Short") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("UShort") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Long") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ULong") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Hyper") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("UHyper") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Float") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Double") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Enum") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("String") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Interface") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Any") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Sequence") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Struct") ) || + rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("RuntimeException") ) ); +} + +//################################################################################################## + +//__________________________________________________________________________________________________ +void Test_Impl::setValues( sal_Bool bBool, sal_Unicode cChar, sal_Int8 nByte, + sal_Int16 nShort, sal_uInt16 nUShort, + sal_Int32 nLong, sal_uInt32 nULong, + sal_Int64 nHyper, sal_uInt64 nUHyper, + float fFloat, double fDouble, + test::TestEnum eEnum, const ::rtl::OUString& rStr, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xTest, + const ::com::sun::star::uno::Any& rAny, + const ::com::sun::star::uno::Sequence<test::TestElement >& rSequence, + const test::TestData& rStruct ) + throw(com::sun::star::uno::RuntimeException) +{ + assign( _aData, + bBool, cChar, nByte, nShort, nUShort, nLong, nULong, nHyper, nUHyper, fFloat, fDouble, + eEnum, rStr, xTest, rAny, rSequence ); + _aStructData = rStruct; +} +//__________________________________________________________________________________________________ +test::TestData Test_Impl::setValues2( sal_Bool& bBool, sal_Unicode& cChar, sal_Int8& nByte, + sal_Int16& nShort, sal_uInt16& nUShort, + sal_Int32& nLong, sal_uInt32& nULong, + sal_Int64& nHyper, sal_uInt64& nUHyper, + float& fFloat, double& fDouble, + test::TestEnum& eEnum, rtl::OUString& rStr, + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xTest, + ::com::sun::star::uno::Any& rAny, + ::com::sun::star::uno::Sequence<test::TestElement >& rSequence, + test::TestData& rStruct ) + throw(com::sun::star::uno::RuntimeException) +{ + assign( _aData, + bBool, cChar, nByte, nShort, nUShort, nLong, nULong, nHyper, nUHyper, fFloat, fDouble, + eEnum, rStr, xTest, rAny, rSequence ); + _aStructData = rStruct; + return _aStructData; +} +//__________________________________________________________________________________________________ +test::TestData Test_Impl::getValues( sal_Bool& bBool, sal_Unicode& cChar, sal_Int8& nByte, + sal_Int16& nShort, sal_uInt16& nUShort, + sal_Int32& nLong, sal_uInt32& nULong, + sal_Int64& nHyper, sal_uInt64& nUHyper, + float& fFloat, double& fDouble, + test::TestEnum& eEnum, rtl::OUString& rStr, + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xTest, + ::com::sun::star::uno::Any& rAny, + ::com::sun::star::uno::Sequence<test::TestElement >& rSequence, + test::TestData& rStruct ) + throw(com::sun::star::uno::RuntimeException) +{ + bBool = _aData.Bool; + cChar = _aData.Char; + nByte = _aData.Byte; + nShort = _aData.Short; + nUShort = _aData.UShort; + nLong = _aData.Long; + nULong = _aData.ULong; + nHyper = _aData.Hyper; + nUHyper = _aData.UHyper; + fFloat = _aData.Float; + fDouble = _aData.Double; + eEnum = _aData.Enum; + rStr = _aData.String; + xTest = _aData.Interface; + rAny = _aData.Any; + rSequence = _aData.Sequence; + rStruct = _aStructData; + return _aStructData; +} + +//================================================================================================== +sal_Bool performTest( const Reference<XLanguageBindingTest > & xLBT ) +{ + OSL_ENSHURE( xLBT.is(), "### no test interface!" ); + if (xLBT.is()) + { + // this data is never ever granted access to by calls other than equals(), assign()! + test::TestData aData; // test against this data + + Reference<XInterface > xI( *new OWeakObject() ); + + assign( (test::TestElement &)aData, + sal_True, '@', 17, 0x1234, 0xfedc, 0x12345678, 0xfedcba98, + 0x123456789abcdef0, 0xfedcba9876543210, + (float)17.0815, 3.1415926359, TestEnum_LOLA, OUString::createFromAscii("dumdidum"), xI, + Any( &xI, ::getCppuType( (const Reference<XInterface > *)0 ) ) ); + + OSL_ENSHURE( aData.Any == xI, "### unexpected any!" ); + OSL_ENSHURE( !(aData.Any != xI), "### unexpected any!" ); + + aData.Sequence = Sequence<test::TestElement >( (const test::TestElement *)&aData, 1 ); + // aData complete + //================================================================================ + + // this is a manually copy of aData for first setting... + test::TestData aSetData; + + assign( (test::TestElement &)aSetData, + aData.Bool, aData.Char, aData.Byte, aData.Short, aData.UShort, + aData.Long, aData.ULong, aData.Hyper, aData.UHyper, aData.Float, aData.Double, + aData.Enum, aData.String, xI, + Any( &xI, ::getCppuType( (const Reference<XInterface > *)0 ) ) ); + + aSetData.Sequence = Sequence<test::TestElement >( (const test::TestElement *)&aSetData, 1 ); + + xLBT->setValues( + aSetData.Bool, aSetData.Char, aSetData.Byte, aSetData.Short, aSetData.UShort, + aSetData.Long, aSetData.ULong, aSetData.Hyper, aSetData.UHyper, aSetData.Float, aSetData.Double, + aSetData.Enum, aSetData.String, aSetData.Interface, aSetData.Any, aSetData.Sequence, aSetData ); + + { + test::TestData aRet, aRet2; + xLBT->getValues( + aRet.Bool, aRet.Char, aRet.Byte, aRet.Short, aRet.UShort, + aRet.Long, aRet.ULong, aRet.Hyper, aRet.UHyper, aRet.Float, aRet.Double, + aRet.Enum, aRet.String, aRet.Interface, aRet.Any, aRet.Sequence, aRet2 ); + + OSL_ASSERT( equals( aData, aRet ) && equals( aData, aRet2 ) ); + + // set last retrieved values + test::TestData aSV2ret = xLBT->setValues2( + aRet.Bool, aRet.Char, aRet.Byte, aRet.Short, aRet.UShort, + aRet.Long, aRet.ULong, aRet.Hyper, aRet.UHyper, aRet.Float, aRet.Double, + aRet.Enum, aRet.String, aRet.Interface, aRet.Any, aRet.Sequence, aRet2 ); + + OSL_ASSERT( equals( aData, aSV2ret ) && equals( aData, aRet2 ) ); + } + { + test::TestData aRet, aRet2; + test::TestData aGVret = xLBT->getValues( + aRet.Bool, aRet.Char, aRet.Byte, aRet.Short, aRet.UShort, + aRet.Long, aRet.ULong, aRet.Hyper, aRet.UHyper, aRet.Float, aRet.Double, + aRet.Enum, aRet.String, aRet.Interface, aRet.Any, aRet.Sequence, aRet2 ); + + OSL_ASSERT( equals( aData, aRet ) && equals( aData, aRet2 ) && equals( aData, aGVret ) ); + + // set last retrieved values + xLBT->setBool( aRet.Bool ); + xLBT->setChar( aRet.Char ); + xLBT->setByte( aRet.Byte ); + xLBT->setShort( aRet.Short ); + xLBT->setUShort( aRet.UShort ); + xLBT->setLong( aRet.Long ); + xLBT->setULong( aRet.ULong ); + xLBT->setHyper( aRet.Hyper ); + xLBT->setUHyper( aRet.UHyper ); + xLBT->setFloat( aRet.Float ); + xLBT->setDouble( aRet.Double ); + xLBT->setEnum( aRet.Enum ); + xLBT->setString( aRet.String ); + xLBT->setInterface( aRet.Interface ); + xLBT->setAny( aRet.Any ); + xLBT->setSequence( aRet.Sequence ); + xLBT->setStruct( aRet2 ); + } + { + test::TestData aRet, aRet2; + aRet.Hyper = xLBT->getHyper(); + aRet.UHyper = xLBT->getUHyper(); + aRet.Float = xLBT->getFloat(); + aRet.Double = xLBT->getDouble(); + aRet.Byte = xLBT->getByte(); + aRet.Char = xLBT->getChar(); + aRet.Bool = xLBT->getBool(); + aRet.Short = xLBT->getShort(); + aRet.UShort = xLBT->getUShort(); + aRet.Long = xLBT->getLong(); + aRet.ULong = xLBT->getULong(); + aRet.Enum = xLBT->getEnum(); + aRet.String = xLBT->getString(); + aRet.Interface = xLBT->getInterface(); + aRet.Any = xLBT->getAny(); + aRet.Sequence = xLBT->getSequence(); + aRet2 = xLBT->getStruct(); + + return (equals( aData, aRet ) && equals( aData, aRet2 )); + } + } + return sal_False; +} + +//__________________________________________________________________________________________________ +test::TestData Test_Impl::raiseException( sal_Bool& bBool, sal_Unicode& cChar, sal_Int8& nByte, sal_Int16& nShort, sal_uInt16& nUShort, sal_Int32& nLong, sal_uInt32& nULong, sal_Int64& nHyper, sal_uInt64& nUHyper, float& fFloat, double& fDouble, test::TestEnum& eEnum, ::rtl::OUString& aString, ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xInterface, ::com::sun::star::uno::Any& aAny, ::com::sun::star::uno::Sequence< test::TestElement >& aSequence, test::TestData& aStruct ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + IllegalArgumentException aExc; + aExc.ArgumentPosition = 5; + aExc.Message = OUString::createFromAscii("dum dum dum ich tanz im kreis herum..."); + aExc.Context = *this; + throw aExc; + return test::TestData(); +} +//__________________________________________________________________________________________________ +sal_Int32 Test_Impl::getRuntimeException() throw(::com::sun::star::uno::RuntimeException) +{ + RuntimeException aExc; + aExc.Message = OUString::createFromAscii("dum dum dum ich tanz im kreis herum..."); + aExc.Context = *this; + throw aExc; + return 0; +} +//__________________________________________________________________________________________________ +void Test_Impl::setRuntimeException( sal_Int32 _runtimeexception ) throw(::com::sun::star::uno::RuntimeException) +{ + RuntimeException aExc; + aExc.Message = OUString::createFromAscii("dum dum dum ich tanz im kreis herum..."); + aExc.Context = *this; + throw aExc; +} + +//================================================================================================== +sal_Bool raiseException( const Reference<XLanguageBindingTest > & xLBT ) +{ + try + { + try + { + try + { + test::TestData aRet, aRet2; + xLBT->raiseException( + aRet.Bool, aRet.Char, aRet.Byte, aRet.Short, aRet.UShort, + aRet.Long, aRet.ULong, aRet.Hyper, aRet.UHyper, aRet.Float, aRet.Double, + aRet.Enum, aRet.String, aRet.Interface, aRet.Any, aRet.Sequence, aRet2 ); + return sal_False; + } + catch (IllegalArgumentException aExc) + { + OSL_ENSHURE( aExc.ArgumentPosition == 5 && +// aExc.Context == xLBT && + aExc.Message.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dum dum dum ich tanz im kreis herum...")), + "### unexpected exception content!" ); + + Reference<XLanguageBindingTest > xLBT( + Reference<XLanguageBindingTest >::query( aExc.Context ) ); + + OSL_ENSHURE( xLBT.is(), "### unexpected source of exception!" ); + if (xLBT.is()) + xLBT->getRuntimeException(); + else + return sal_False; + } + } + catch (const RuntimeException & rExc) + { + OSL_ENSHURE(//rExc.Context == xLBT && + rExc.Message.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dum dum dum ich tanz im kreis herum...")), + "### unexpected exception content!" ); + + Reference<XLanguageBindingTest > xLBT( + Reference<XLanguageBindingTest >::query( rExc.Context ) ); + + OSL_ENSHURE( xLBT.is(), "### unexpected source of exception!" ); + if (xLBT.is()) + xLBT->setRuntimeException( 0xcafebabe ); + else + return sal_False; + } + } + catch (Exception & aExc) + { + OSL_ENSHURE( //aExc.Context == xLBT && + aExc.Message.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dum dum dum ich tanz im kreis herum...")), + "### unexpected exception content!" ); + return (//aExc.Context == xLBT && + aExc.Message.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dum dum dum ich tanz im kreis herum..."))); + } + return sal_False; +} + +//================================================================================================== +static sal_Bool test_adapter( const Reference< XMultiServiceFactory > & xMgr ) +{ + Reference< XInvocationAdapterFactory > xAdapFac( + xMgr->createInstance( OUString::createFromAscii("com.sun.star.script.InvocationAdapterFactory") ), UNO_QUERY ); + + Reference< XLanguageBindingTest > xOriginal( (XLanguageBindingTest *)new Test_Impl() ); + Reference< XInvocation > xInvok( new XLB_Invocation( xMgr, xOriginal ) ); + Reference< XLanguageBindingTest > xLBT( xAdapFac->createAdapter( + xInvok, ::getCppuType( (const Reference< XLanguageBindingTest > *)0 ) ), UNO_QUERY ); + + return (performTest( xLBT ) && raiseException( xLBT )); +} + +#ifdef UNX +#define REG_PREFIX "lib" +#define DLL_POSTFIX ".so" +#else +#define REG_PREFIX "" +#define DLL_POSTFIX ".dll" +#endif + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int __cdecl main( int argc, char * argv[] ) +#endif +{ + Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("stoctest.rdb") ) ) ); + + sal_Bool bSucc = sal_False; + try + { + Reference< XImplementationRegistration > xImplReg( + xMgr->createInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.ImplementationRegistration") ) ), + UNO_QUERY ); + OSL_ENSHURE( xImplReg.is(), "### no impl reg!" ); + + OUString aLibName( OUString::createFromAscii(REG_PREFIX "invadp" DLL_POSTFIX) ); + xImplReg->registerImplementation( + OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), aLibName, Reference< XSimpleRegistry >() ); + + bSucc = test_adapter( xMgr ); + } + catch (Exception & rExc) + { + OSL_ENSHURE( sal_False, "### exception occured!" ); + OString aMsg( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "### exception occured: " ); + OSL_TRACE( aMsg.getStr() ); + OSL_TRACE( "\n" ); + } + + Reference< XComponent >( xMgr, UNO_QUERY )->dispose(); + + printf( "testiadapter %s !\n", (bSucc ? "succeeded" : "failed") ); + return (bSucc ? 0 : -1); +} diff --git a/stoc/test/testintrosp.cxx b/stoc/test/testintrosp.cxx new file mode 100644 index 000000000000..2e917fcbc008 --- /dev/null +++ b/stoc/test/testintrosp.cxx @@ -0,0 +1,1645 @@ +/************************************************************************* + * + * $RCSfile: testintrosp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:35 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase4.hxx> +#include <cppuhelper/servicefactory.hxx> + +#include <vos/diagnose.hxx> +#include <vos/dynload.hxx> + +#include <ModuleA/XIntroTest.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XIntrospection.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertyConcept.hpp> +#include <com/sun/star/beans/MethodConcept.hpp> +#include <com/sun/star/beans/XExactName.hpp> +#include <com/sun/star/container/XElementAccess.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> +//#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/lang/XComponent.hpp> + +#include <stdio.h> +#include <string.h> + + +using namespace rtl; +using namespace cppu; +using namespace vos; +using namespace ModuleA; +//using namespace ModuleB; +//using namespace ModuleC; +//using namespace ModuleA::ModuleB; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::registry; +using namespace com::sun::star::reflection; +using namespace com::sun::star::container; +using namespace com::sun::star::beans::PropertyAttribute; + + +typedef WeakImplHelper4< XIntroTest, XPropertySet, XNameAccess, XIndexAccess > ImplIntroTestHelper; +typedef WeakImplHelper1< XPropertySetInfo > ImplPropertySetInfoHelper; + + +#define DEFAULT_INDEX_ACCESS_COUNT 10 +#define DEFAULT_NAME_ACCESS_COUNT 5 + +#ifdef _DEBUG +#define TEST_ENSHURE(c, m) VOS_ENSHURE(c, m) +#else +#define TEST_ENSHURE(c, m) VOS_VERIFY(c) +#endif + +//class IntroTestWritelnOutput; + + + +//************************************************************** +//*** Hilfs-Funktion, um vom Type eine XIdlClass zu bekommen *** +//************************************************************** +Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr ) +{ + static Reference< XIdlReflection > xRefl; + + // void als Default-Klasse eintragen + Reference<XIdlClass> xRetClass; + typelib_TypeDescription * pTD = 0; + rType.getDescription( &pTD ); + if( pTD ) + { + OUString sOWName( pTD->pTypeName ); + if( !xRefl.is() ) + { + xRefl = Reference< XIdlReflection >( xMgr->createInstance( + OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ), UNO_QUERY ); + VOS_ENSHURE( xRefl.is(), "### no corereflection!" ); + } + xRetClass = xRefl->forName( sOWName ); + } + return xRetClass; +} + + +//**************************************************** +//*** Hilfs-Funktion, um Any als UString auszugeben *** +//**************************************************** +// ACHTUNG: Kann mal an eine zentrale Stelle uebernommen werden +// Wird zunaechst nur fuer einfache Datentypen ausgefuehrt + +OUString AnyToString( const Any& aValue, sal_Bool bIncludeType, const Reference< XMultiServiceFactory > & xMgr ) +{ + Type aValType = aValue.getValueType(); + TypeClass eType = aValType.getTypeClass(); + char pBuffer[50]; + + OUString aRetStr; + switch( eType ) + { + case TypeClass_TYPE: aRetStr = OUString::createFromAscii("TYPE TYPE"); break; + case TypeClass_INTERFACE: aRetStr = OUString::createFromAscii("TYPE INTERFACE"); break; + case TypeClass_SERVICE: aRetStr = OUString::createFromAscii("TYPE SERVICE"); break; + case TypeClass_STRUCT: aRetStr = OUString::createFromAscii("TYPE STRUCT"); break; + case TypeClass_TYPEDEF: aRetStr = OUString::createFromAscii("TYPE TYPEDEF"); break; + case TypeClass_UNION: aRetStr = OUString::createFromAscii("TYPE UNION"); break; + case TypeClass_ENUM: aRetStr = OUString::createFromAscii("TYPE ENUM"); break; + case TypeClass_EXCEPTION: aRetStr = OUString::createFromAscii("TYPE EXCEPTION"); break; + case TypeClass_ARRAY: aRetStr = OUString::createFromAscii("TYPE ARRAY"); break; + case TypeClass_SEQUENCE: aRetStr = OUString::createFromAscii("TYPE SEQUENCE"); break; + case TypeClass_VOID: aRetStr = OUString::createFromAscii("TYPE void"); break; + case TypeClass_ANY: aRetStr = OUString::createFromAscii("TYPE any"); break; + case TypeClass_UNKNOWN: aRetStr = OUString::createFromAscii("TYPE unknown"); break; + case TypeClass_BOOLEAN: + { + sal_Bool b = *(sal_Bool*)aValue.getValue(); + //aRet.setValue( &b, getCppuBooleanType() ); + //aValue >>= b; + aRetStr = OUString::valueOf( b ); + break; + } + case TypeClass_CHAR: + { + sal_Unicode c = *(sal_Unicode*)aValue.getValue(); + //aValue >>= c; + //getCppuCharType() + aRetStr = OUString::valueOf( c ); + break; + } + case TypeClass_STRING: + { + aValue >>= aRetStr; + break; + } + case TypeClass_FLOAT: + { + float f; + aValue >>= f; + sprintf( pBuffer, "%f", f ); + aRetStr = OUString( pBuffer, strlen( pBuffer ), RTL_TEXTENCODING_ASCII_US ); + break; + } + case TypeClass_DOUBLE: + { + double d; + aValue >>= d; + sprintf( pBuffer, "%f", d ); + aRetStr = OUString( pBuffer, strlen( pBuffer ), RTL_TEXTENCODING_ASCII_US ); + break; + } + case TypeClass_BYTE: + { + sal_Int8 n; + aValue >>= n; + aRetStr = OUString::valueOf( (sal_Int32) n ); + break; + } + case TypeClass_SHORT: + { + sal_Int16 n; + aValue >>= n; + aRetStr = OUString::valueOf( (sal_Int32) n ); + break; + } + case TypeClass_LONG: + { + sal_Int32 n; + aValue >>= n; + aRetStr = OUString::valueOf( n ); + break; + } + /* + case TypeClass_HYPER: + { + aRetStr = L"TYPE HYPER"; + break; + } + case TypeClass_UNSIGNED_SHORT: + { + aRetStr = StringToUString(WSString(aValue.getUINT16()), CHARSET_SYSTEM); + break; + } + case TypeClass_UNSIGNED_LONG: + { + aRetStr = StringToUString(WSString(aValue.getUINT32()), CHARSET_SYSTEM); + break; + } + case TypeClass_UNSIGNED_HYPER: + { + aRetStr = L"TYPE UNSIGNED_HYPER"; + break; + } + */ + } + + if( bIncludeType ) + { + Reference< XIdlClass > xIdlClass = TypeToIdlClass( aValType, xMgr ); + aRetStr = aRetStr + OUString( OUString::createFromAscii(" (Typ: ") ) + xIdlClass->getName() + OUString::createFromAscii(")"); + } + return aRetStr; +} + +/* +// Hilfs-Funktion, um ein UString in einen Any zu konvertieren +UsrAny StringToAny( UString aStr, TypeClass eTargetType ) +{ + UsrAny aRetAny; + switch( eTargetType ) + { + case TypeClass_INTERFACE: break; + case TypeClass_SERVICE: break; + case TypeClass_STRUCT: break; + case TypeClass_TYPEDEF: break; + case TypeClass_UNION: break; + case TypeClass_ENUM: break; + case TypeClass_EXCEPTION: break; + case TypeClass_ARRAY: break; + case TypeClass_SEQUENCE: break; + case TypeClass_VOID: break; + case TypeClass_ANY: break; + case TypeClass_UNKNOWN: break; + case TypeClass_BOOLEAN: aRetAny.setBOOL( short(aStr)!=0 ); break; + case TypeClass_CHAR: aRetAny.setChar( char(aStr) ); break; + case TypeClass_STRING: aRetAny.setString( aStr ); break; + case TypeClass_FLOAT: aRetAny.setFloat( (float)strtod( aStr.GetStr(), NULL ) ); break; + case TypeClass_DOUBLE: aRetAny.setDouble( strtod( aStr.GetStr(), NULL ) ); break; + case TypeClass_BYTE: aRetAny.setBYTE( BYTE(short(aStr)) ); break; + case TypeClass_SHORT: aRetAny.setINT16( short(aStr) ); break; + case TypeClass_LONG: aRetAny.setINT32( long(aStr) ); break; + case TypeClass_HYPER: break; + case TypeClass_UNSIGNED_SHORT: aRetAny.setUINT16( USHORT(aStr) ); break; + case TypeClass_UNSIGNED_LONG: aRetAny.setUINT32( ULONG(aStr) ); break; + case TypeClass_UNSIGNED_HYPER: break; + } + return aRetAny; +} +*/ + + +//***************************************** +//*** XPropertySetInfo fuer Test-Klasse *** +//***************************************** + +class ImplPropertySetInfo : public ImplPropertySetInfoHelper +{ + friend class ImplIntroTest; + + Reference< XMultiServiceFactory > mxMgr; + +public: + ImplPropertySetInfo( const Reference< XMultiServiceFactory > & xMgr ) + : mxMgr( xMgr ) {} + //: mxMgr( xMgr ), ImplPropertySetInfoHelper( xMgr ) {} + +/* + // Methoden von XInterface + virtual sal_Bool SAL_CALL queryInterface( const Uik & rUik, Any & ifc ) throw( RuntimeException ); + virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); } + virtual void SAL_CALL release() throw() { OWeakObject::release(); } + //ALT: sal_Bool queryInterface( Uik aUik, Reference<XInterface> & rOut ); +*/ + + // Methods of XPropertySetInfo + virtual Sequence< Property > SAL_CALL getProperties( ) + throw(RuntimeException); + virtual Property SAL_CALL getPropertyByName( const OUString& aName ) + throw(UnknownPropertyException, RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) + throw(RuntimeException); + //virtual Sequence< Property > SAL_CALL getProperties(void) throw( RuntimeException ); + //virtual Property SAL_CALL getPropertyByName(const OUString& Name) throw( RuntimeException ); + //virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& Name) throw( RuntimeException ); +}; + + +/* +// Methoden von XInterface +sal_Bool SAL_CALL ImplPropertySetInfo::queryInterface( const Uik & rUik, Any & ifc ) + throw( RuntimeException ) +{ + // PropertySet-Implementation + if( com::sun::star::uno::queryInterface( rUik, ifc, + SAL_STATIC_CAST(XPropertySetInfo*, this) ) ) + return sal_True; + + return OWeakObject::queryInterface( rUik, ifc ); +} + +sal_Bool ImplPropertySetInfo::queryInterface( Uik aUik, Reference<XInterface> & rOut ) +{ + if( aUik == XPropertySetInfo::getSmartUik() ) + rOut = (XPropertySetInfo *)this; + else + UsrObject::queryInterface( aUik, rOut ); + return rOut.is(); +} +*/ + +Sequence< Property > ImplPropertySetInfo::getProperties(void) + throw( RuntimeException ) +{ + static Sequence<Property> * pSeq = NULL; + + if( !pSeq ) + { + // die Informationen für die Properties "Width", "Height" und "Name" anlegen + pSeq = new Sequence<Property>( 3 ); + Property * pAry = pSeq->getArray(); + + pAry[0].Name = OUString::createFromAscii("Factor"); + pAry[0].Handle = -1; + pAry[0].Type = getCppuType( (double*) NULL ); + //pAry[0].Type = TypeToIdlClass( getCppuType( (double*) NULL ), mxMgr ); + //pAry[0].Type = Double_getReflection()->getIdlClass(); + pAry[0].Attributes = BOUND | TRANSIENT; + + pAry[1].Name = OUString::createFromAscii("MyCount"); + pAry[1].Handle = -1; + pAry[1].Type = getCppuType( (sal_Int32*) NULL ); + //pAry[1].Type = TypeToIdlClass( getCppuType( (sal_Int32*) NULL ), mxMgr ); + //pAry[1].Type = INT32_getReflection()->getIdlClass(); + pAry[1].Attributes = BOUND | TRANSIENT; + + pAry[2].Name = OUString::createFromAscii("Info"); + pAry[2].Handle = -1; + pAry[2].Type = getCppuType( (OUString*) NULL ); + //pAry[2].Type = TypeToIdlClass( getCppuType( (OUString*) NULL ), mxMgr ); + //pAry[2].Type = OUString_getReflection()->getIdlClass(); + pAry[2].Attributes = TRANSIENT; + } + // Die Information über alle drei Properties liefern. + return *pSeq; +} + +Property ImplPropertySetInfo::getPropertyByName(const OUString& Name) + throw( UnknownPropertyException, RuntimeException ) +{ + Sequence<Property> aSeq = getProperties(); + const Property * pAry = aSeq.getConstArray(); + + for( sal_Int32 i = aSeq.getLength(); i--; ) + { + if( pAry[i].Name == Name ) + return pAry[i]; + } + // Property unbekannt, also leere liefern + return Property(); +} + +sal_Bool ImplPropertySetInfo::hasPropertyByName(const OUString& Name) + throw( RuntimeException ) +{ + Sequence<Property> aSeq = getProperties(); + const Property * pAry = aSeq.getConstArray(); + + for( sal_Int32 i = aSeq.getLength(); i--; ) + { + if( pAry[i].Name == Name ) + return sal_True; + } + // Property unbekannt, also leere liefern + return sal_False; +} + + + + +//***************************************************************** + + + +class ImplIntroTest : public ImplIntroTestHelper +{ + Reference< XMultiServiceFactory > mxMgr; + + friend class ImplPropertySetInfo; + + // Properties fuer das PropertySet + Any aAnyArray[10]; + + // Optionale Schnittstelle fuer die writeln-Ausgabe + //IntroTestWritelnOutput* m_pOutput; + + Reference< XPropertySetInfo > m_xMyInfo; + + OUString m_ObjectName; + + int m_nMarkusAge; + int m_nMarkusChildrenCount; + + long m_lDroenk; + sal_Int16 m_nBla; + sal_Int16 m_nBlub; + sal_Int16 m_nGulp; + sal_Int16 m_nLaber; + TypeClass eTypeClass; + Sequence< OUString > aStringSeq; + Sequence< Sequence< Sequence< sal_Int16 > > > aMultSeq; + Reference< XIntroTest > m_xIntroTest; + + // Daten fuer NameAccess + Reference< XIntroTest >* pNameAccessTab; + + // Daten fuer IndexAccess + Reference< XIntroTest >* pIndexAccessTab; + sal_Int16 iIndexAccessCount; + + // struct-Properties + Property m_aFirstStruct; + PropertyValue m_aSecondStruct; + + // Listener merken (zunaechst einfach, nur einen pro Property) + Reference< XPropertyChangeListener > aPropChangeListener; + OUString aPropChangeListenerStr; + Reference< XVetoableChangeListener > aVetoPropChangeListener; + OUString aVetoPropChangeListenerStr; + + void Init( void ); + +public: + ImplIntroTest( const Reference< XMultiServiceFactory > & xMgr ) + : mxMgr( xMgr ) + //: mxMgr( xMgr ), ImplIntroTestHelper( xMgr ) + { + Init(); + } + + /* + ImplIntroTest( IntroTestWritelnOutput* pOutput_ ) + { + Init(); + m_pOutput = pOutput_; + } + */ + + //SMART_UNO_DECLARATION(ImplIntroTest,UsrObject); + + //BOOL queryInterface( Uik aUik, Reference< XInterface > & rOut ); + //Reference< XIdlClass > getIdlClass(); + + // Trotz virtual inline, um Schreibarbeit zu sparen (nur fuer Testzwecke) + // XPropertySet + virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo( ) + throw(RuntimeException); + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) + throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException); + virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + + /* + virtual void setIndexedPropertyValue(const OUString& aPropertyName, INT32 nIndex, const Any& aValue) {} + virtual Any getIndexedPropertyValue(const UString& aPropertyName, INT32 nIndex) const { return Any(); } + virtual void addPropertyChangeListener(const UString& aPropertyName, const XPropertyChangeListenerRef& aListener) + THROWS( (UnknownPropertyException, WrappedTargetException, UsrSystemException) ) {} + virtual void removePropertyChangeListener(const UString& aPropertyName, const XPropertyChangeListenerRef& aListener) + THROWS( (UnknownPropertyException, WrappedTargetException, UsrSystemException) ) {} + virtual void addVetoableChangeListener(const UString& aPropertyName, const XVetoableChangeListenerRef& aListener) + THROWS( (UnknownPropertyException, WrappedTargetException, UsrSystemException) ) {} + virtual void removeVetoableChangeListener(const UString& aPropertyName, const XVetoableChangeListenerRef& aListener) + THROWS( (UnknownPropertyException, WrappedTargetException, UsrSystemException) ) {} + */ + + // XIntroTest-Methoden + // Attributes + virtual OUString SAL_CALL getObjectName() throw(RuntimeException) + { return m_ObjectName; } + virtual void SAL_CALL setObjectName( const OUString& _objectname ) throw(RuntimeException) + { m_ObjectName = _objectname; } + virtual OUString SAL_CALL getFirstName() + throw(RuntimeException); + virtual OUString SAL_CALL getLastName() throw(RuntimeException) + { return OUString( OUString::createFromAscii("Meyer") ); } + virtual sal_Int16 SAL_CALL getAge() throw(RuntimeException) + { return m_nMarkusAge; } + virtual sal_Int16 SAL_CALL getChildrenCount() throw(RuntimeException) + { return m_nMarkusChildrenCount; } + virtual void SAL_CALL setChildrenCount( sal_Int16 _childrencount ) throw(RuntimeException) + { m_nMarkusChildrenCount = _childrencount; } + virtual Property SAL_CALL getFirstStruct() throw(RuntimeException) + { return m_aFirstStruct; } + virtual void SAL_CALL setFirstStruct( const Property& _firststruct ) throw(RuntimeException) + { m_aFirstStruct = _firststruct; } + virtual PropertyValue SAL_CALL getSecondStruct() throw(RuntimeException) + { return m_aSecondStruct; } + virtual void SAL_CALL setSecondStruct( const PropertyValue& _secondstruct ) throw(RuntimeException) + { m_aSecondStruct = _secondstruct; } + + // Methods + virtual void SAL_CALL writeln( const OUString& Text ) + throw(RuntimeException); + virtual sal_Int32 SAL_CALL getDroenk( ) throw(RuntimeException) + { return m_lDroenk; } + virtual Reference< ::ModuleA::XIntroTest > SAL_CALL getIntroTest( ) throw(RuntimeException); + virtual sal_Int32 SAL_CALL getUps( sal_Int32 l ) throw(RuntimeException) + { return 2*l; } + virtual void SAL_CALL setDroenk( sal_Int32 l ) throw(RuntimeException) + { m_lDroenk = l; } + virtual sal_Int16 SAL_CALL getBla( ) throw(RuntimeException) + { return m_nBla; } + virtual void SAL_CALL setBla( sal_Int32 n ) throw(RuntimeException) + { m_nBla = (sal_Int16)n; } + virtual sal_Int16 SAL_CALL getBlub( ) throw(RuntimeException) + { return m_nBlub; } + virtual void SAL_CALL setBlub( sal_Int16 n ) throw(RuntimeException) + { m_nBlub = n; } + virtual sal_Int16 SAL_CALL getGulp( ) throw(RuntimeException) + { return m_nGulp; } + virtual sal_Int16 SAL_CALL setGulp( sal_Int16 n ) throw(RuntimeException) + { m_nGulp = n; return 1; } + virtual TypeClass SAL_CALL getTypeClass( sal_Int16 n ) throw(RuntimeException) + { return eTypeClass; } + virtual void SAL_CALL setTypeClass( TypeClass t, double d1, double d2 ) throw(RuntimeException) + { eTypeClass = t; } + virtual Sequence< OUString > SAL_CALL getStrings( ) throw(RuntimeException) + { return aStringSeq; } + virtual void SAL_CALL setStrings( const Sequence< OUString >& Strings ) throw(RuntimeException) + { aStringSeq = Strings; } + virtual void SAL_CALL setStringsPerMethod( const Sequence< OUString >& Strings, sal_Int16 n ) throw(RuntimeException) + { aStringSeq = Strings; } + virtual Sequence< Sequence< Sequence< sal_Int16 > > > SAL_CALL getMultiSequence( ) throw(RuntimeException) + { return aMultSeq; } + virtual void SAL_CALL setMultiSequence( const Sequence< Sequence< Sequence< sal_Int16 > > >& Seq ) throw(RuntimeException) + { aMultSeq = Seq; } + virtual void SAL_CALL addPropertiesChangeListener( const Sequence< OUString >& PropertyNames, const Reference< XPropertiesChangeListener >& Listener ) + throw(RuntimeException); + virtual void SAL_CALL removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& Listener ) + throw(RuntimeException); + + + // Methods of XElementAccess + virtual Type SAL_CALL getElementType( ) + throw(RuntimeException); + virtual sal_Bool SAL_CALL hasElements( ) + throw(RuntimeException); + //virtual XIdlClassRef getElementType(void) constTHROWS( (UsrSystemException) ); + //virtual BOOL hasElements(void) const THROWS( (UsrSystemException) ); + + // XNameAccess-Methoden + // Methods + virtual Any SAL_CALL getByName( const OUString& aName ) + throw(NoSuchElementException, WrappedTargetException, RuntimeException); + virtual Sequence< OUString > SAL_CALL getElementNames( ) + throw(RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) + throw(RuntimeException); + //virtual Any getByName(const UString& Name) const + //THROWS( (NoSuchElementException, WrappedTargetException, UsrSystemException) ); + //virtual Sequence<UString> getElementNames(void) const THROWS( (UsrSystemException) ); + //virtual BOOL hasByName(const UString& Name) const THROWS( (UsrSystemException) ); + + // XIndexAccess-Methoden + // Methods + virtual sal_Int32 SAL_CALL getCount( ) + throw(RuntimeException); + virtual Any SAL_CALL getByIndex( sal_Int32 Index ) + throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException); + //virtual INT32 getCount(void) const THROWS( (UsrSystemException) ); + //virtual Any getByIndex(INT32 Index) const + //THROWS( (IndexOutOfBoundsException, WrappedTargetException, UsrSystemException) ); +}; + +//SMART_UNO_IMPLEMENTATION(ImplIntroTest,UsrObject) + +void ImplIntroTest::Init( void ) +{ + // Eindeutigen Namen verpassen + static sal_Int32 nObjCount = 0; + OUString aName( OUString::createFromAscii("IntroTest-Obj Nr. ") ); + aName += OUString::valueOf( nObjCount ); + setObjectName( aName ); + + // Properties initialisieren + aAnyArray[0] <<= 3.14; + aAnyArray[1] <<= (sal_Int32)42; + aAnyArray[2] <<= OUString( OUString::createFromAscii("Hallo") ); + + // Output-Interface + //m_pOutput = NULL; + + // Einmal fuer den internen Gebrauch die PropertySetInfo abholen + m_xMyInfo = getPropertySetInfo(); + m_xMyInfo->acquire(); // sonst raucht es am Programm-Ende ab + + m_nMarkusAge = 33; + m_nMarkusChildrenCount = 2; + + m_lDroenk = 314; + m_nBla = 42; + m_nBlub = 111; + m_nGulp = 99; + m_nLaber = 1; + eTypeClass = TypeClass_INTERFACE; + + // String-Sequence intitialisieren + aStringSeq.realloc( 3 ); + OUString* pStr = aStringSeq.getArray(); + pStr[ 0 ] = OUString( OUString::createFromAscii("String 0") ); + pStr[ 1 ] = OUString( OUString::createFromAscii("String 1") ); + pStr[ 2 ] = OUString( OUString::createFromAscii("String 2") ); + + // structs initialisieren + m_aFirstStruct.Name = OUString::createFromAscii("FirstStruct-Name"); + m_aFirstStruct.Handle = 77777; + //XIdlClassRef Type; + m_aFirstStruct.Attributes = -222; + + //XInterfaceRef Source; + Any Value; + Value <<= 2.718281828459; + m_aSecondStruct.Value = Value; + //XIdlClassRef ListenerType; + m_aSecondStruct.State = PropertyState_DIRECT_VALUE; + + // IndexAccess + iIndexAccessCount = DEFAULT_INDEX_ACCESS_COUNT; + pIndexAccessTab = NULL; + pNameAccessTab = NULL; +} + +/* +BOOL ImplIntroTest::queryInterface( Uik aUik, XInterfaceRef & rOut ) +{ + if( aUik == XIntroTest::getSmartUik() ) + rOut = (XIntroTest*)this; + else if( aUik == XPropertySet::getSmartUik() ) + rOut = (XPropertySet*)this; + else if( aUik == XNameAccess::getSmartUik() ) + rOut = (XNameAccess*)this; + else if( aUik == XIndexAccess::getSmartUik() ) + rOut = (XIndexAccess*)this; + else if( aUik == ((XElementAccess*)NULL)->getSmartUik() ) + rOut = (XElementAccess*)(XIndexAccess *)this; + else + UsrObject::queryInterface( aUik, rOut ); + return rOut.is(); +} + +XIdlClassRef ImplIntroTest::getIdlClass() +{ + static XIdlClassRef xClass = createStandardClass( L"ImplIntroTest", + UsrObject::getUsrObjectIdlClass(), 4, + XIntroTest_getReflection(), + XPropertySet_getReflection(), + XNameAccess_getReflection(), + XIndexAccess_getReflection() ); + return xClass; +} +*/ + +Reference< XPropertySetInfo > ImplIntroTest::getPropertySetInfo() + throw(RuntimeException) +{ + static ImplPropertySetInfo aInfo( mxMgr ); + // Alle Objekt haben die gleichen Properties, deshalb kann + // die Info für alle gleich sein + return &aInfo; + + //if( m_xMyInfo == NULL ) + // ((ImplIntroTest*)this)->m_xMyInfo = new ImplPropertySetInfo( this ); + //return m_xMyInfo; +} + +void ImplIntroTest::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) + throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +//void ImplIntroTest::setPropertyValue( const UString& aPropertyName, const Any& aValue ) +// THROWS( (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, UsrSystemException) ) +{ + if( aPropChangeListener.is() && aPropertyName == aPropChangeListenerStr ) + { + PropertyChangeEvent aEvt; + aEvt.Source = (OWeakObject*)this; + aEvt.PropertyName = aPropertyName; + aEvt.PropertyHandle = 0L; + //aEvt.OldValue; + //aEvt.NewValue; + //aEvt.PropagationId; + aPropChangeListener->propertyChange( aEvt ); + } + if( aVetoPropChangeListener.is() && aPropertyName == aVetoPropChangeListenerStr ) + { + PropertyChangeEvent aEvt; + aEvt.Source = (OWeakObject*)this; + aEvt.PropertyName = aVetoPropChangeListenerStr; + aEvt.PropertyHandle = 0L; + //aEvt.OldValue; + //aEvt.NewValue; + //aEvt.PropagationId; + aVetoPropChangeListener->vetoableChange( aEvt ); + } + + Sequence<Property> aPropSeq = m_xMyInfo->getProperties(); + sal_Int32 nLen = aPropSeq.getLength(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + Property aProp = aPropSeq.getArray()[ i ]; + if( aProp.Name == aPropertyName ) + aAnyArray[i] = aValue; + } +} + +Any ImplIntroTest::getPropertyValue( const OUString& PropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +//Any ImplIntroTest::getPropertyValue(const UString& aPropertyName) const + //THROWS( (UnknownPropertyException, WrappedTargetException, UsrSystemException) ) +{ + Sequence<Property> aPropSeq = m_xMyInfo->getProperties(); + sal_Int32 nLen = aPropSeq.getLength(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + Property aProp = aPropSeq.getArray()[ i ]; + if( aProp.Name == PropertyName ) + return aAnyArray[i]; + } + return Any(); +} + +OUString ImplIntroTest::getFirstName(void) + throw(RuntimeException) +{ + return OUString( OUString::createFromAscii("Markus") ); +} + +void ImplIntroTest::writeln( const OUString& Text ) + throw(RuntimeException) +{ + OString aStr( Text.getStr(), Text.getLength(), RTL_TEXTENCODING_ASCII_US ); + + // Haben wir ein Output? + //if( m_pOutput ) + //{ + //m_pOutput->doWriteln( TextStr ); + //} + // Sonst einfach rausbraten + //else + { + printf( "%s", aStr.getStr() ); + } +} + +Reference< XIntroTest > ImplIntroTest::getIntroTest() + throw(RuntimeException) +//XIntroTestRef ImplIntroTest::getIntroTest(void) THROWS( (UsrSystemException) ) +{ + if( !m_xIntroTest.is() ) + m_xIntroTest = new ImplIntroTest( mxMgr ); + return m_xIntroTest; +} + +// Methoden von XElementAccess +Type ImplIntroTest::getElementType( ) + throw(RuntimeException) +//XIdlClassRef ImplIntroTest::getElementType(void) const THROWS( (UsrSystemException) ) +{ + // TODO + Type aRetType; + return aRetType; + //return Reference< XIdlClass >(); + //return Void_getReflection()->getIdlClass(); +} + +sal_Bool ImplIntroTest::hasElements( ) + throw(RuntimeException) +//BOOL ImplIntroTest::hasElements(void) const THROWS( (UsrSystemException) ) +{ + return sal_True; +} + +// XNameAccess-Methoden +sal_Int32 getIndexForName( const OUString& ItemName ) +{ + OUString aLeftStr = ItemName.copy( 0, 4 ); + if( aLeftStr == OUString::createFromAscii("Item") ) + { + // TODO + OUString aNumStr = ItemName.copy( 4 ); + //sal_Int32 iIndex = (INT32)UStringToString( aNumStr, CHARSET_SYSTEM ); + //if( iIndex < DEFAULT_NAME_ACCESS_COUNT ) + //return iIndex; + } + return -1; +} + + +Any ImplIntroTest::getByName( const OUString& aName ) + throw(NoSuchElementException, WrappedTargetException, RuntimeException) +//Any ImplIntroTest::getByName(const UString& Name) const + //THROWS( (NoSuchElementException, WrappedTargetException, UsrSystemException) ) +{ + Any aRetAny; + + if( !pNameAccessTab ) + ((ImplIntroTest*)this)->pNameAccessTab = new Reference< XIntroTest >[ DEFAULT_NAME_ACCESS_COUNT ]; + + sal_Int32 iIndex = getIndexForName( aName ); + if( iIndex != -1 ) + { + if( !pNameAccessTab[iIndex].is() ) + { + ImplIntroTest* p = new ImplIntroTest( mxMgr ); + OUString aName( OUString::createFromAscii("IntroTest by Name-Access, Index = ") ); + aName += OUString::valueOf( iIndex ); + //aName = aName + StringToUString( String( iIndex ), CHARSET_SYSTEM ); + p->setObjectName( aName ); + pNameAccessTab[iIndex] = p; + } + + Reference< XIntroTest > xRet = pNameAccessTab[iIndex]; + aRetAny = makeAny( xRet ); + + //aRetAny.set( &xRet, XIntroTest_getReflection() ); + //return (UsrObject*)(XIntroTest*)pNameAccessTab[iIndex]; + } + return aRetAny; +} + +Sequence< OUString > ImplIntroTest::getElementNames( ) + throw(RuntimeException) +//Sequence<UString> ImplIntroTest::getElementNames(void) const THROWS( (UsrSystemException) ) +{ + Sequence<OUString> aStrSeq( DEFAULT_NAME_ACCESS_COUNT ); + OUString* pStr = aStrSeq.getArray(); + for( sal_Int32 i = 0 ; i < DEFAULT_NAME_ACCESS_COUNT ; i++ ) + { + OUString aName( OUString::createFromAscii("Item") ); + aName += OUString::valueOf( i ); + //aName = aName + StringToUString( i, CHARSET_SYSTEM ); + pStr[i] = aName; + } + return aStrSeq; +} + +sal_Bool ImplIntroTest::hasByName( const OUString& aName ) + throw(RuntimeException) +//BOOL ImplIntroTest::hasByName(const UString& Name) const THROWS( (UsrSystemException) ) +{ + return ( getIndexForName( aName ) != -1 ); +} + +// XIndexAccess-Methoden +sal_Int32 ImplIntroTest::getCount( ) + throw(RuntimeException) +//sal_Int32 ImplIntroTest::getCount(void) const THROWS( (UsrSystemException) ) +{ + return iIndexAccessCount; +} + +Any ImplIntroTest::getByIndex( sal_Int32 Index ) + throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException) +//Any ImplIntroTest::getByIndex( sal_Int32 Index ) const + //THROWS( (IndexOutOfBoundsException, WrappedTargetException, UsrSystemException) ) +{ + Any aRetAny; + + if( !pIndexAccessTab ) + ((ImplIntroTest*)this)->pIndexAccessTab = new Reference< XIntroTest >[ iIndexAccessCount ]; + + if( Index < iIndexAccessCount ) + { + if( !pNameAccessTab[Index].is() ) + { + ImplIntroTest* p = new ImplIntroTest( mxMgr ); + OUString aName( OUString::createFromAscii("IntroTest by Index-Access, Index = ") ); + aName += OUString::valueOf( Index ); + //aName = aName + StringToUString( String( iIndex ), CHARSET_SYSTEM ); + p->setObjectName( aName ); + pIndexAccessTab[Index] = p; + } + Reference< XIntroTest > xRet = pIndexAccessTab[Index]; + aRetAny = makeAny( xRet ); + } + return aRetAny; +} + +void ImplIntroTest::addPropertiesChangeListener( const Sequence< OUString >& PropertyNames, + const Reference< XPropertiesChangeListener >& Listener ) + throw(RuntimeException) +//void ImplIntroTest::addPropertiesChangeListener +//(const Sequence< UString >& PropertyNames, const XPropertiesChangeListenerRef& Listener) + //THROWS( (UsrSystemException) ) +{ +} + +void ImplIntroTest::removePropertiesChangeListener + ( const Reference< XPropertiesChangeListener >& Listener ) + throw(RuntimeException) +//void ImplIntroTest::removePropertiesChangeListener(const XPropertiesChangeListenerRef& Listener) + //THROWS( (UsrSystemException) ) +{ +} + + + +struct DefItem +{ + char* pName; + sal_Int32 nConcept; +}; + +// Spezial-Wert fuer Method-Concept, um "normale" Funktionen kennzeichnen zu koennen +#define MethodConcept_NORMAL_IMPL 0x80000000 + + +// Test-Objekt liefern +Any getIntrospectionTestObject( const Reference< XMultiServiceFactory > & xMgr ) +{ + Any aObjAny; + Reference< XIntroTest > xTestObj = new ImplIntroTest( xMgr ); + aObjAny.setValue( &xTestObj, ::getCppuType( (const Reference< XIntroTest > *)0 ) ); + return aObjAny; +} + +static sal_Bool test_introsp( Reference< XMultiServiceFactory > xMgr, + Reference< XIdlReflection > xRefl, Reference< XIntrospection > xIntrospection ) +{ + DefItem pPropertyDefs[] = + { + { "Factor", PropertyConcept::PROPERTYSET }, + { "MyCount", PropertyConcept::PROPERTYSET }, + { "Info", PropertyConcept::PROPERTYSET }, + { "ObjectName", PropertyConcept::ATTRIBUTES }, + { "FirstName", PropertyConcept::ATTRIBUTES }, + { "LastName", PropertyConcept::ATTRIBUTES }, + { "Age", PropertyConcept::ATTRIBUTES }, + { "ChildrenCount", PropertyConcept::ATTRIBUTES }, + { "FirstStruct", PropertyConcept::ATTRIBUTES }, + { "SecondStruct", PropertyConcept::ATTRIBUTES }, + { "Droenk", PropertyConcept::METHODS }, + { "IntroTest", PropertyConcept::METHODS }, + { "Bla", PropertyConcept::METHODS }, + { "Blub", PropertyConcept::METHODS }, + { "Gulp", PropertyConcept::METHODS }, + { "Strings", PropertyConcept::METHODS }, + { "MultiSequence", PropertyConcept::METHODS }, + { "PropertySetInfo", PropertyConcept::METHODS }, + { "ElementType", PropertyConcept::METHODS }, + { "ElementNames", PropertyConcept::METHODS }, + { "Count", PropertyConcept::METHODS }, + { "Types", PropertyConcept::METHODS }, + { "ImplementationId", PropertyConcept::METHODS }, + { NULL, 0 } + }; + + // Tabelle der Property-Namen, die gefunden werden muessen + char* pDemandedPropNames[] = + { + "Factor", + "MyCount", + "Info", + "ObjectName", + "FirstName", + "LastName", + "Age", + "ChildrenCount", + "FirstStruct", + "SecondStruct", + "Droenk", + "IntroTest", + "Bla", + "Blub", + "Gulp", + "Strings", + "MultiSequence", + "PropertySetInfo", + "ElementType", + "ElementNames", + "Count", + "Types" + "ImplementationId" + }; + + char* pDemandedPropVals[] = + { + "3.140000", + "42", + "Hallo", + "IntroTest-Obj Nr. 0", + "Markus", + "Meyer", + "33", + "2", + "TYPE STRUCT", + "TYPE STRUCT", + "314", + "TYPE INTERFACE", + "42", + "111", + "99", + "TYPE SEQUENCE", + "TYPE SEQUENCE", + "TYPE INTERFACE", + "TYPE TYPE", + "TYPE SEQUENCE", + "10", + "TYPE SEQUENCE", + "TYPE SEQUENCE", + }; + + char* pDemandedModifiedPropVals[] = + { + "4.140000", + "43", + "Hallo (Modified!)", + "IntroTest-Obj Nr. 0 (Modified!)", + "Markus", + "Meyer", + "33", + "3", + "Wert wurde nicht modifiziert", + "Wert wurde nicht modifiziert", + "315", + "Wert wurde nicht modifiziert", + "42", + "112", + "99", + "Wert wurde nicht modifiziert", + "Wert wurde nicht modifiziert", + "Wert wurde nicht modifiziert", + "Wert wurde nicht modifiziert", + "Wert wurde nicht modifiziert", + "10", + "Wert wurde nicht modifiziert" + "Wert wurde nicht modifiziert" + }; + + char* pDemandedPropTypes[] = + { + "double", + "long", + "string", + "string", + "string", + "string", + "short", + "short", + "com.sun.star.beans.Property", + "com.sun.star.beans.PropertyValue", + "long", + "ModuleA.XIntroTest", + "short", + "short", + "short", + "[]string", + "[][][]short", + "com.sun.star.beans.XPropertySetInfo", + "type", + "[]string", + "long", + "[]type", + "[]byte", + }; + //is() nDemandedPropCount = 22; + + + DefItem pMethodDefs[] = + { + { "queryInterface", MethodConcept_NORMAL_IMPL }, + { "acquire", MethodConcept::DANGEROUS }, + { "release", MethodConcept::DANGEROUS }, + { "writeln", MethodConcept_NORMAL_IMPL }, + { "getDroenk", MethodConcept::PROPERTY }, + { "getIntroTest", MethodConcept::PROPERTY }, + { "getUps", MethodConcept_NORMAL_IMPL }, + { "setDroenk", MethodConcept::PROPERTY }, + { "getBla", MethodConcept::PROPERTY }, + { "setBla", MethodConcept_NORMAL_IMPL }, + { "getBlub", MethodConcept::PROPERTY }, + { "setBlub", MethodConcept::PROPERTY }, + { "getGulp", MethodConcept::PROPERTY }, + { "setGulp", MethodConcept_NORMAL_IMPL }, + { "getTypeClass", MethodConcept_NORMAL_IMPL }, + { "setTypeClass", MethodConcept_NORMAL_IMPL }, + { "getStrings", MethodConcept::PROPERTY }, + { "setStrings", MethodConcept::PROPERTY }, + { "setStringsPerMethod", MethodConcept_NORMAL_IMPL }, + { "getMultiSequence", MethodConcept::PROPERTY }, + { "setMultiSequence", MethodConcept::PROPERTY }, + { "addPropertiesChangeListener", MethodConcept::LISTENER }, + { "removePropertiesChangeListener", MethodConcept::LISTENER }, + { "getPropertySetInfo", MethodConcept::PROPERTY }, + { "setPropertyValue", MethodConcept_NORMAL_IMPL }, + { "getPropertyValue", MethodConcept_NORMAL_IMPL }, + { "addPropertyChangeListener", MethodConcept::LISTENER }, + { "removePropertyChangeListener", MethodConcept::LISTENER }, + { "addVetoableChangeListener", MethodConcept::LISTENER }, + { "removeVetoableChangeListener", MethodConcept::LISTENER }, + { "getElementType", MethodConcept::PROPERTY | MethodConcept::NAMECONTAINER| MethodConcept::INDEXCONTAINER | MethodConcept::ENUMERATION }, + { "hasElements", MethodConcept::NAMECONTAINER | MethodConcept::INDEXCONTAINER | MethodConcept::ENUMERATION }, + { "getByName", MethodConcept::NAMECONTAINER }, + { "getElementNames", MethodConcept::PROPERTY | MethodConcept::NAMECONTAINER }, + { "hasByName", MethodConcept::NAMECONTAINER }, + { "getCount", MethodConcept::PROPERTY | MethodConcept::INDEXCONTAINER }, + { "getByIndex", MethodConcept::INDEXCONTAINER }, + { "getTypes", MethodConcept::PROPERTY }, + { "getImplementationId", MethodConcept::PROPERTY }, + { "queryAdapter", MethodConcept_NORMAL_IMPL }, + { NULL, 0 } + }; + + OString aErrorStr; + + //****************************************************** + + // Test-Objekt anlegen + Any aObjAny = getIntrospectionTestObject( xMgr ); + + // Introspection-Service holen + //Reference< XMultiServiceFactory > xServiceManager(getProcessServiceManager(), USR_QUERY); + //Reference< XIntrospection > xIntrospection( xMgr->createInstance(L"com.sun.star.beans.Introspection"), UNO_QUERY ); + //TEST_ENSHURE( xIntrospection.is(), "Creation of introspection instance failed" ); + //if( !xIntrospection.is() ) + //return sal_False; + + // und unspecten + Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny ); + xAccess = xIntrospection->inspect( aObjAny ); + xAccess = xIntrospection->inspect( aObjAny ); + TEST_ENSHURE( xAccess.is(), "introspection failed, no XIntrospectionAccess returned" ); + if( !xAccess.is() ) + return sal_False; + + // Ergebnis der Introspection pruefen + + // XPropertySet-UIK ermitteln + Type aType = getCppuType( (Reference< XPropertySet >*) NULL ); + //typelib_InterfaceTypeDescription* pTypeDesc = NULL; + //aType.getDescription( (typelib_TypeDescription**)&pTypeDesc ); + //Uik aPropertySetUik = *(Uik*)&pTypeDesc->aUik; + //typelib_typedescription_release( (typelib_TypeDescription*)pTypeDesc ); + + Reference< XInterface > xPropSetIface = xAccess->queryAdapter( aType ); + //Reference< XInterface > xPropSetIface = xAccess->queryAdapter( aPropertySetUik ); + Reference< XPropertySet > xPropSet( xPropSetIface, UNO_QUERY ); + //XPropertySetRef xPropSet = (XPropertySet*)xPropSetIface-> + // queryInterface( XPropertySet::getSmartUik() ); + TEST_ENSHURE( xPropSet.is(), "Could not get XPropertySet by queryAdapter()" ); + + // XExactName + Reference< XExactName > xExactName( xAccess, UNO_QUERY ); + TEST_ENSHURE( xExactName.is(), "Introspection unterstuetzt kein ExactName" ); + + // Schleife ueber alle Kombinationen von Concepts + for( sal_Int32 nConcepts = 0 ; nConcepts < 16 ; nConcepts++ ) + { +//printf( "*******************************************************\n" ); +//printf( "nConcepts = %ld\n", nConcepts ); + + // Wieviele Properties sollten es sein + sal_Int32 nDemandedPropCount = 0; + sal_Int32 iList = 0; + while( pPropertyDefs[ iList ].pName ) + { + if( pPropertyDefs[ iList ].nConcept & nConcepts ) + nDemandedPropCount++; + iList++; + } + + if( xPropSet.is() ) + { + Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); + //Sequence<Property> aRetSeq = xPropSetInfo->getProperties(); + Sequence<Property> aRetSeq = xAccess->getProperties( nConcepts ); + + sal_Int32 nLen = aRetSeq.getLength(); + + aErrorStr = "Expected to find "; + aErrorStr += OString::valueOf( nDemandedPropCount ); + aErrorStr += " properties but found "; + aErrorStr += OString::valueOf( nLen ); + TEST_ENSHURE( nLen == nDemandedPropCount, aErrorStr.getStr() ); + + // cout << "**********************************\n"; + // cout << "*** Ergebnis der Introspection ***\n"; + // cout << "**********************************\n"; + // cout << "\nIntrospection hat " << nLen << " Properties gefunden:\n"; + + const Property* pProps = aRetSeq.getConstArray(); + Any aPropVal; + sal_Int32 i; + iList = 0; + for( i = 0 ; i < nLen ; i++ ) + { + const Property aProp = pProps[ i ]; + + // Naechste Passende Methode in der Liste suchen + while( pPropertyDefs[ iList ].pName ) + { + if( pPropertyDefs[ iList ].nConcept & nConcepts ) + break; + iList++; + } + sal_Int32 iDemanded = iList; + iList++; + + OUString aPropName = aProp.Name; + OString aNameStr( aPropName.getStr(), aPropName.getLength(), RTL_TEXTENCODING_ASCII_US ); + //UStringToString(aPropName, CHARSET_SYSTEM); + +//printf( "Property = %s\n", aNameStr.getStr() ); + + OString aDemandedName = pPropertyDefs[ iDemanded ].pName; + //OString aDemandedName = pDemandedPropNames[ i ]; + aErrorStr = "Expected property \""; + aErrorStr += aDemandedName; + aErrorStr += "\", found \""; + aErrorStr += aNameStr; + aErrorStr += "\""; + TEST_ENSHURE( aNameStr == aDemandedName, aErrorStr.getStr() ); + // cout << "Property " << (i+1) << ": \"" << (const char*)UStringToString(aPropName, CHARSET_SYSTEM) << "\""; + + + Type aPropType = aProp.Type; + OString aTypeNameStr( OUStringToOString(aPropType.getTypeName(), RTL_TEXTENCODING_ASCII_US) ); + //Reference< XIdlClass > xPropType = aProp.Type; + //OString aTypeNameStr( xPropType->getName(), xPropType->getName().getLength(), RTL_TEXTENCODING_ASCII_US ); + OString aDemandedTypeNameStr = pDemandedPropTypes[ iDemanded ]; + //OString aDemandedTypeNameStr = pDemandedPropTypes[ i ]; + aErrorStr = "Property \""; + aErrorStr += aDemandedName; + aErrorStr += "\", expected type >"; + aErrorStr += aDemandedTypeNameStr; + aErrorStr += "< found type >"; + aErrorStr += aTypeNameStr; + aErrorStr += "<"; + TEST_ENSHURE( aTypeNameStr == aDemandedTypeNameStr, aErrorStr.getStr() ); + // cout << " (Prop-Typ: " << (const char*)UStringToString(xPropType->getName(), CHARSET_SYSTEM) << ")"; + + // Wert des Property lesen und ausgeben + aPropVal = xPropSet->getPropertyValue( aPropName ); + // cout << "\n\tWert = " << (const char*)UStringToString(AnyToString( aPropVal, sal_True ), CHARSET_SYSTEM); + + OString aValStr = OUStringToOString( AnyToString( aPropVal, sal_False, xMgr ), RTL_TEXTENCODING_ASCII_US ); + OString aDemandedValStr = pDemandedPropVals[ iDemanded ]; + //OString aDemandedValStr = pDemandedPropVals[ i ]; + aErrorStr = "Property \""; + aErrorStr += aDemandedName; + aErrorStr += "\", expected val >"; + aErrorStr += aDemandedValStr; + aErrorStr += "< found val >"; + aErrorStr += aValStr; + aErrorStr += "<"; + TEST_ENSHURE( aValStr == aDemandedValStr, aErrorStr.getStr() ); + + // Wert pruefen und typgerecht modifizieren + TypeClass eType = aPropVal.getValueType().getTypeClass(); + //Reference< XIdlClass > xIdlClass = aPropVal.getReflection()->getIdlClass(); + //TypeClass eType = xIdlClass->getTypeClass(); + Any aNewVal; + sal_Bool bModify = sal_True; + switch( eType ) + { + case TypeClass_STRING: + { + OUString aStr; + aPropVal >>= aStr; + //OString aStr = aPropVal.getString(); + aStr = aStr + OUString::createFromAscii(" (Modified!)"); + aNewVal <<= aStr; + break; + } + case TypeClass_DOUBLE: + { + double d; + aPropVal >>= d; + aNewVal <<= d + 1.0; + break; + } + case TypeClass_SHORT: + { + sal_Int16 n; + aPropVal >>= n; + aNewVal <<= sal_Int16( n + 1 ); + break; + } + case TypeClass_LONG: + { + sal_Int32 n; + aPropVal >>= n; + aNewVal <<= sal_Int32( n + 1 ); + break; + } + default: + bModify = sal_False; + break; + } + + // Modifizieren nur beim letzten Durchlauf + if( nConcepts == 15 ) + { + // XExactName pruefen, dafuer alles gross machen + // (Introspection ist mit LowerCase implementiert, also anders machen) + OUString aUpperUStr = aPropName.toUpperCase(); + OUString aExactName = xExactName->getExactName( aUpperUStr ); + if( aExactName != aPropName ) + { + aErrorStr = "Property \""; + aErrorStr += OUStringToOString( aPropName, RTL_TEXTENCODING_ASCII_US ); + aErrorStr += "\", not found as \""; + aErrorStr += OUStringToOString(aUpperUStr, RTL_TEXTENCODING_ASCII_US ); + aErrorStr += "\" using XExactName"; + TEST_ENSHURE( sal_False, aErrorStr.getStr() ); + } + } + else + { + bModify = sal_False; + } + + // Neuen Wert setzen, wieder lesen und ausgeben + if( bModify ) + { + // cout.flush(); + + // 1.7.1999, UnknownPropertyException bei ReadOnly-Properties abfangen + try + { + xPropSet->setPropertyValue( aPropName, aNewVal ); + } + catch(UnknownPropertyException e1) + { + } + + aPropVal = xPropSet->getPropertyValue( aPropName ); + // cout << "\n\tModifizierter Wert = " << (const char*) UStringToString(AnyToString( aPropVal, sal_True ), CHARSET_SYSTEM) << "\n"; + + OUString aStr = AnyToString( aPropVal, sal_False, xMgr ); + OString aModifiedValStr = OUStringToOString( aStr, RTL_TEXTENCODING_ASCII_US ); + OString aDemandedModifiedValStr = pDemandedModifiedPropVals[ i ]; + aErrorStr = "Property \""; + aErrorStr += aDemandedName; + aErrorStr += "\", expected modified val >"; + aErrorStr += aDemandedModifiedValStr; + aErrorStr += "< found val >"; + aErrorStr += aModifiedValStr; + aErrorStr += "<"; + TEST_ENSHURE( aModifiedValStr == aDemandedModifiedValStr, aErrorStr.getStr() ); + } + else + { + // cout << "\n\tWert wurde nicht modifiziert\n"; + } + + // Checken, ob alle Properties auch einzeln gefunden werden + aErrorStr = "property \""; + aErrorStr += aDemandedName; + aErrorStr += "\" not found with hasProperty()"; + OUString aWDemandedName = OStringToOUString(aDemandedName, RTL_TEXTENCODING_ASCII_US ); + sal_Bool bProperty = xAccess->hasProperty( aWDemandedName, nConcepts ); + //sal_Bool bProperty = xAccess->hasProperty( aWDemandedName, PropertyConcept::ALL - PropertyConcept::DANGEROUS ); + TEST_ENSHURE( bProperty, aErrorStr.getStr() ); + + aErrorStr = "property \""; + aErrorStr += aDemandedName; + aErrorStr += "\" not equal to same Property in sequence returned by getProperties()"; + try + { + Property aGetProp = xAccess->getProperty( aWDemandedName, nConcepts ); + //Property aGetProp = xAccess->getProperty( aWDemandedName, PropertyConcept::ALL ); + //TEST_ENSHURE( aGetProp == aProp , aErrorStr.getStr() ); + } + catch (RuntimeException e1) + { + aErrorStr = "property \""; + aErrorStr += aDemandedName; + aErrorStr += "\", exception was thrown when trying getProperty()"; + TEST_ENSHURE( sal_False, aErrorStr.getStr() ); + } + + } + } + } + + // Schleife ueber alle Kombinationen von Concepts + for( nConcepts = 0 ; nConcepts < 128 ; nConcepts++ ) + { +//printf( "*******************************************************\n" ); +//printf( "nConcepts = %ld\n", nConcepts ); + + // Das 2^6-Bit steht fuer "den Rest" + sal_Int32 nRealConcepts = nConcepts; + if( nConcepts & 0x40 ) + nRealConcepts |= (0xFFFFFFFF - 0x3F); + + // Wieviele Methoden sollten es sein + sal_Int32 nDemandedMethCount = 0; + sal_Int32 iList = 0; + while( pMethodDefs[ iList ].pName ) + { + if( pMethodDefs[ iList ].nConcept & nRealConcepts ) + nDemandedMethCount++; + iList++; + } + + // Methoden-Array ausgeben + //aMethodSeq = xAccess->getMethods + Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( nRealConcepts ); + //Sequence<XIdlMethodRef> aMethodSeq = xAccess->getMethods + // ( MethodConcept::ALL - MethodConcept::DANGEROUS - MethodConcept::PROPERTY ); + sal_Int32 nLen = aMethodSeq.getLength(); + // cout << "\n\n*** Methoden ***\n"; + // cout << "Introspection hat " << nLen << " Methoden gefunden:\n"; + + aErrorStr = "Expected to find "; + aErrorStr += OString::valueOf( nDemandedMethCount ); + aErrorStr += " methods but found "; + aErrorStr += OString::valueOf( nLen ); + TEST_ENSHURE( nLen == nDemandedMethCount, aErrorStr.getStr() ); + + const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray(); + sal_Int32 i; + iList = 0; + + for( i = 0 ; i < nLen ; i++ ) + { + // Methode ansprechen + const Reference< XIdlMethod >& rxMethod = pMethods[i]; + + // Methode ausgeben + OUString aMethName = rxMethod->getName(); + OString aNameStr = OUStringToOString(aMethName, RTL_TEXTENCODING_ASCII_US ); + +//printf( "Method = %s\n", aNameStr.getStr() ); + + // Naechste Passende Methode in der Liste suchen + while( pMethodDefs[ iList ].pName ) + { + if( pMethodDefs[ iList ].nConcept & nRealConcepts ) + break; + iList++; + } + OString aDemandedName = pMethodDefs[ iList ].pName; + iList++; + + //OString aDemandedName = pDemandedMethNames[ i ]; + aErrorStr = "Expected method \""; + aErrorStr += aDemandedName; + aErrorStr += "\", found \""; + aErrorStr += aNameStr; + aErrorStr += "\""; + TEST_ENSHURE( aNameStr == aDemandedName, aErrorStr.getStr() ); + // cout << "Methode " << (i+1) << ": " << (const char*) UStringToString(rxMethod->getReturnType()->getName(), CHARSET_SYSTEM) + // << " " << (const char*) UStringToString(rxMethod->getName(), CHARSET_SYSTEM) << "( "; + + // Checken, ob alle Methoden auch einzeln gefunden werden + aErrorStr = "method \""; + aErrorStr += aDemandedName; + aErrorStr += "\" not found with hasMethod()"; + OUString aWDemandedName = OStringToOUString(aDemandedName, RTL_TEXTENCODING_ASCII_US ); + sal_Bool bMethod = xAccess->hasMethod( aWDemandedName, nRealConcepts ); + //sal_Bool bMethod = xAccess->hasMethod( aWDemandedName, MethodConcept::ALL ); + TEST_ENSHURE( bMethod, aErrorStr.getStr() ); + + aErrorStr = "method \""; + aErrorStr += aDemandedName; + aErrorStr += "\" not equal to same method in sequence returned by getMethods()"; + try + { + Reference< XIdlMethod > xGetMethod = xAccess->getMethod( aWDemandedName, nRealConcepts ); + //XIdlMethodRef xGetMethod = xAccess->getMethod( aWDemandedName, MethodConcept::ALL ); + TEST_ENSHURE( xGetMethod == rxMethod , aErrorStr.getStr() ); + } + catch (RuntimeException e1) + { + aErrorStr = "method \""; + aErrorStr += aDemandedName; + aErrorStr += "\", exception was thrown when trying getMethod()"; + TEST_ENSHURE( sal_False, aErrorStr.getStr() ); + } + } + } + + // Listener-Klassen ausgeben + Sequence< Type > aClassSeq = xAccess->getSupportedListeners(); + sal_Int32 nLen = aClassSeq.getLength(); + // cout << "\n\n*** Anmeldbare Listener ***\n"; + // cout << "Introspection hat " << nLen << " Listener gefunden:\n"; + + const Type* pListeners = aClassSeq.getConstArray(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + // Methode ansprechen + const Type& aListenerType = pListeners[i]; + + // Namen besorgen + OUString aListenerClassName = aListenerType.getTypeName(); + // cout << "Listener " << (i+1) << ": " << (const char*)UStringToString(aListenerClassName, CHARSET_SYSTEM) << "\n"; + } + + + // Performance bei hasMethod testen. + //CheckMethodPerformance( xAccess, "queryInterface", 100000 ); + //CheckMethodPerformance( xAccess, "getIdlClasses", 100000 ); + + // cout.flush(); + + + + + return sal_True; +} + + + + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int __cdecl main( int argc, char * argv[] ) +#endif +{ + Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( OUString::createFromAscii("stoctest.rdb") ) ); + + sal_Bool bSucc = sal_False; + try + { + Reference< XImplementationRegistration > xImplReg( + xMgr->createInstance( OUString::createFromAscii("com.sun.star.registry.ImplementationRegistration") ), UNO_QUERY ); + VOS_ENSHURE( xImplReg.is(), "### no impl reg!" ); + + // Register services + OUString libName; + + // CoreReflection + ORealDynamicLoader::computeLibraryName( OUString::createFromAscii("corefl"), libName); + xImplReg->registerImplementation(OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), + libName, Reference< XSimpleRegistry >() ); + Reference< XIdlReflection > xRefl( xMgr->createInstance( OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ), UNO_QUERY ); + VOS_ENSHURE( xRefl.is(), "### no corereflection!" ); + + // Introspection + ORealDynamicLoader::computeLibraryName( OUString::createFromAscii("insp"), libName); + xImplReg->registerImplementation(OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), + libName, Reference< XSimpleRegistry >() ); + Reference< XIntrospection > xIntrosp( xMgr->createInstance( OUString::createFromAscii("com.sun.star.beans.Introspection") ), UNO_QUERY ); + VOS_ENSHURE( xRefl.is(), "### no corereflection!" ); + + bSucc = test_introsp( xMgr, xRefl, xIntrosp ); + //bSucc = test_corefl( xRefl ); + } + catch (Exception & rExc) + { + VOS_ENSHURE( sal_False, "### exception occured!" ); + OString aMsg( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) ); + VOS_TRACE( "### exception occured: " ); + VOS_TRACE( aMsg.getStr() ); + VOS_TRACE( "\n" ); + } + + Reference< XComponent >( xMgr, UNO_QUERY )->dispose(); + + printf( "testintrosp %s !\n", (bSucc ? "succeeded" : "failed") ); + return (bSucc ? 0 : -1); +} + + + + + + + +//***************************** +//*** TEST-Implementationen *** +//***************************** +// Bleibt auf Dauer nicht drin, dient als exportierbare Test-Klasse +// z.B. fuer Basic-Anbindung + + + + + + diff --git a/stoc/test/testintrosp.idl b/stoc/test/testintrosp.idl new file mode 100644 index 000000000000..74d3ee7610e3 --- /dev/null +++ b/stoc/test/testintrosp.idl @@ -0,0 +1,255 @@ +/************************************************************************* + * + * $RCSfile: testintrosp.idl,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef __com_sun_star_beans_XIntroTest_idl__ +#define __com_sun_star_beans_XIntroTest_idl__ + +#ifndef __com_sun_star_uno_XInterface_idl__ +#include <com/sun/star/uno/XInterface.idl> +#endif + +#ifndef __com_sun_star_beans_Property_idl__ +#include <com/sun/star/beans/Property.idl> +#endif + +#ifndef __com_sun_star_beans_PropertyValue_idl__ +#include <com/sun/star/beans/PropertyValue.idl> +#endif + +#ifndef __com_sun_star_uno_TypeClass_idl__ +#include <com/sun/star/uno/TypeClass.idl> +#endif + +#ifndef __com_sun_star_beans_XPropertiesChangeListener_idl__ +#include <com/sun/star/beans/XPropertiesChangeListener.idl> +#endif + + +//============================================================================= + +module ModuleA +{ +//module com { module sun { module star { module beans { + +//interface XPropertyChangeListener; +//interface XPropertiesChangeListener; + +//============================================================================= +/** This is a test interface for introspection. + + <p>IMPORTANT: FOR TEST ONLY! + + <p>The following interface is just for testing purposes. It will not + stay in the product. It is only used as an exportable test class, + i.e. for BASIC integration. + + @deprecated +*/ +[ uik(E227A4AB-33D6-11D1-AABE00A0-249D5590), ident( "XIntroTest", 1.0 ) ] +interface XIntroTest: com::sun::star::uno::XInterface +{ + //------------------------------------------------------------------------- + /** contains the ID-String of the implementation. + */ + [attribute] string ObjectName; + + //------------------------------------------------------------------------- + /** contains the first name of a person. + */ + [readonly, attribute] string FirstName; + + //------------------------------------------------------------------------- + /** contains the last name of a person. + */ + [readonly, attribute] string LastName; + + //------------------------------------------------------------------------- + /** contains the age of a person. + */ + [readonly, attribute] short Age; + + //------------------------------------------------------------------------- + /** contains the number of children person has. + */ + [attribute] short ChildrenCount; + + //------------------------------------------------------------------------- + /** contains a struct of type Property. + */ + [attribute] com::sun::star::beans::Property FirstStruct; + + //------------------------------------------------------------------------- + /** contains a struct of type PropertyValue. + */ + [attribute] com::sun::star::beans::PropertyValue SecondStruct; + + //------------------------------------------------------------------------- + /** Ausgabe-Methode + */ + void writeln( [in] string Text ); + + //------------------------------------------------------------------------- + /** ... + */ + long getDroenk(); + + //------------------------------------------------------------------------- + /** Weitere Introspection-Test-Objekt holen + */ + XIntroTest getIntroTest(); + //com::sun::star::beans::XIntroTest getIntroTest(); + + //------------------------------------------------------------------------- + /** !!! No property, because parameter exists + */ + long getUps( [in] long l ); + + //------------------------------------------------------------------------- + /** ... + */ + void setDroenk( [in] long l ); + + //------------------------------------------------------------------------- + /** ... + */ + short getBla(); + + //------------------------------------------------------------------------- + /** !!! Not the set method for property Bla, because param type != return type. + */ + void setBla( [in] long n ); + + //------------------------------------------------------------------------- + /** ... + */ + short getBlub(); + + //------------------------------------------------------------------------- + /** ... + */ + void setBlub( [in] short n ); + + //------------------------------------------------------------------------- + /** ... + */ + short getGulp(); + + //------------------------------------------------------------------------- + /** !!! Not the set method for property Gulp, because return type != void. + */ + short setGulp( [in] short n ); + + //------------------------------------------------------------------------- + /** ... + */ + com::sun::star::uno::TypeClass getTypeClass( [in] short n ); + + //------------------------------------------------------------------------- + /** ... + */ + void setTypeClass( [in] com::sun::star::uno::TypeClass t, + [in] double d1, + [in] double d2 ); + + //------------------------------------------------------------------------- + /** + */ + sequence<string> getStrings(); + + //------------------------------------------------------------------------- + /** ... + */ + void setStrings( [in] sequence<string> Strings ); + + //------------------------------------------------------------------------- + /** ... + */ + void setStringsPerMethod( [in] sequence<string> Strings, + [in] short n ); + + //------------------------------------------------------------------------- + /** + */ + sequence< sequence< sequence< short > > > getMultiSequence(); + + //------------------------------------------------------------------------- + /** ... + */ + void setMultiSequence( [in] sequence< sequence< sequence< short > > > Seq ); + + //------------------------------------------------------------------------- + /**Add a PropertiesChangeListener + */ + [oneway] void addPropertiesChangeListener( [in] sequence< string > PropertyNames, + [in] com::sun::star::beans::XPropertiesChangeListener Listener ); + + //------------------------------------------------------------------------- + /**Remove a PropertiesChangeListener + */ + [oneway] void removePropertiesChangeListener( [in] com::sun::star::beans::XPropertiesChangeListener Listener ); + +}; + +//============================================================================= + +}; +//}; }; }; }; + +#endif diff --git a/stoc/test/testloader.cxx b/stoc/test/testloader.cxx new file mode 100644 index 000000000000..c2a664f46eed --- /dev/null +++ b/stoc/test/testloader.cxx @@ -0,0 +1,162 @@ +/************************************************************************* + * + * $RCSfile: testloader.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <stdio.h> + +#ifndef _VOS_MODULE_HXX_ +#include <vos/module.hxx> +#endif +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif + + +#include <com/sun/star/loader/XImplementationLoader.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif + +#ifndef _VOS_DYNLOAD_HXX_ +#include <vos/dynload.hxx> +#endif + +#if defined ( UNX ) || defined ( MAC ) +#include <limits.h> +#define _MAX_PATH PATH_MAX +#endif + +using namespace com::sun::star::uno; +using namespace com::sun::star::loader; +using namespace com::sun::star::lang; +using namespace vos; +using namespace rtl; + +#ifdef _DEBUG +#define TEST_ENSHURE(c, m) VOS_ENSHURE(c, m) +#else +#define TEST_ENSHURE(c, m) VOS_VERIFY(c) +#endif + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int _cdecl main( int argc, char * argv[] ) +#endif +{ + Reference<XInterface> xIFace; + + OModule* pModule = new OModule(OUString()); + + OUString dllName; + NAMESPACE_VOS(ORealDynamicLoader)::computeLibraryName(OUString::createFromAscii("cpld"), dllName); + + if (pModule->load(dllName)) + { + // try to get provider from module + component_getFactoryFunc pCompFactoryFunc = (component_getFactoryFunc) + pModule->getSymbol( OUString::createFromAscii(COMPONENT_GETFACTORY) ); + + if (pCompFactoryFunc) + { + XSingleServiceFactory * pRet = (XSingleServiceFactory *)(*pCompFactoryFunc)( + "com.sun.star.comp.stoc.DLLComponentLoader", 0, 0 ); + if (pRet) + { + xIFace = pRet; + pRet->release(); + } + } + } + + TEST_ENSHURE( xIFace.is(), "testloader error1"); + + Reference<XSingleServiceFactory> xFactory( Reference<XSingleServiceFactory>::query(xIFace) ); + + TEST_ENSHURE( xFactory.is(), "testloader error2"); + + Reference<XInterface> xLoader = xFactory->createInstance(); + + TEST_ENSHURE( xLoader.is(), "testloader error3"); + + Reference<XServiceInfo> xServInfo( Reference<XServiceInfo>::query(xLoader) ); + + TEST_ENSHURE( xServInfo.is(), "testloader error4"); + + TEST_ENSHURE( xServInfo->getImplementationName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.comp.stoc.DLLComponentLoader") ), "testloader error5"); + TEST_ENSHURE( xServInfo->supportsService(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary")) ), "testloader error6"); + TEST_ENSHURE( xServInfo->getSupportedServiceNames().getLength() == 1, "testloader error7"); + + xIFace.clear(); + xFactory.clear(); + xLoader.clear(); + xServInfo.clear(); + + delete pModule; + + printf("Test Dll ComponentLoader, OK!\n"); + + return(0); +} + + diff --git a/stoc/test/testproxyfac.cxx b/stoc/test/testproxyfac.cxx new file mode 100644 index 000000000000..61772e08be74 --- /dev/null +++ b/stoc/test/testproxyfac.cxx @@ -0,0 +1,243 @@ +/************************************************************************* + * + * $RCSfile: testproxyfac.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <osl/diagnose.h> + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/queryinterface.hxx> + +#include <com/sun/star/uno/XAggregation.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/util/XProxyFactory.hpp> + +#include <rtl/ustrbuf.hxx> + +#include <stdio.h> + + +using namespace rtl; +using namespace cppu; +using namespace osl; +using namespace com::sun::star::uno; +using namespace com::sun::star::util; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; + + +static sal_Int32 s_n = 0; + +//================================================================================================== +class Test1 : public WeakImplHelper2< XServiceInfo, XProxyFactory > +{ +public: + virtual ~Test1() + { ++s_n; } + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw (RuntimeException) + { return OUString::createFromAscii( "a" ); } + virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException) + { return sal_False; } + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException) + { return Sequence< OUString >(); } + // XProxyFactory + virtual Reference< XAggregation > SAL_CALL createProxy( const Reference< XInterface > & xTarget ) throw (RuntimeException) + { return Reference< XAggregation >(); } +}; +//================================================================================================== +class Test2 : public WeakImplHelper1< XServiceInfo > +{ + Reference< XAggregation > _xAgg; +public: + static Reference< XInterface > createTest2( const Reference< XAggregation > & xAgg ) + { + Test2 * p = new Test2(); + Reference< XInterface > xRet( (XInterface *)(XServiceInfo *)p ); + p->_xAgg = xAgg; + xAgg->release(); // ref to 1 + p->acquire(); // for xAgg dtor + p->_xAgg->setDelegator( xRet ); + return xRet; + } + virtual ~Test2() + { ++s_n; } + + virtual Any SAL_CALL queryInterface( const Type & rType ) throw (RuntimeException) + { + Any aRet( OWeakObject::queryInterface( rType ) ); + if (! aRet.hasValue()) + { + aRet = cppu::queryInterface( rType, (XServiceInfo *)this ); + if (! aRet.hasValue()) + return _xAgg->queryAggregation( rType ); + } + return aRet; + } + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw (RuntimeException) + { return OUString::createFromAscii( "b" ); } + virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException) + { return sal_False; } + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException) + { return Sequence< OUString >(); } +}; + +static sal_Bool test_proxyfac( const Reference< XProxyFactory > & xProxyFac ) +{ + { + Reference< XServiceInfo > x1( new Test1() ); + Reference< XServiceInfo > x1p( xProxyFac->createProxy( x1 ), UNO_QUERY ); +// if (x1->getImplementationName() != x1p->getImplementationName() || +// !x1->getImplementationName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("a") )) +// { +// return sal_False; +// } +// if (x1 == x1p) +// return sal_False; + // + + Reference< XAggregation > xAgg( xProxyFac->createProxy( x1 ) ); + Reference< XInterface > xMaster( Test2::createTest2( xAgg ) ); + + Reference< XServiceInfo > x2( xMaster, UNO_QUERY ); + Test2 * pt2 = static_cast< Test2 * >( x2.get() ); + + if ((Test2 *)(XServiceInfo *)xMaster.get() != pt2 || + !pt2->getImplementationName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("b") ) || + !x2->getImplementationName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("b") )) + { + return sal_False; + } + + if (x2 == x1 || x2 == x1p) + return sal_False; + if (x2 != xAgg) + return sal_False; + + if (x1->getImplementationName() == x2->getImplementationName() || + x1p->getImplementationName() == x2->getImplementationName()) + { + return sal_False; + } + + if (s_n) + return sal_False; + } + return s_n == 2; +} + +#ifdef UNX +#define REG_PREFIX "lib" +#define DLL_POSTFIX ".so" +#else +#define REG_PREFIX "" +#define DLL_POSTFIX ".dll" +#endif + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int __cdecl main( int argc, char * argv[] ) +#endif +{ + Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("stoctest.rdb") ) ) ); + + sal_Bool bSucc = sal_False; + try + { + Reference< XImplementationRegistration > xImplReg( + xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.ImplementationRegistration") ) ), UNO_QUERY ); + OSL_ENSHURE( xImplReg.is(), "### no impl reg!" ); + + OUString aLibName( OUString::createFromAscii(REG_PREFIX) ); + aLibName += OUString::createFromAscii("proxyfac"); +#ifndef OS2 + aLibName += OUString::createFromAscii(DLL_POSTFIX); +#endif + xImplReg->registerImplementation( + OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), aLibName, Reference< XSimpleRegistry >() ); + + Reference< XProxyFactory > xProxyFac( xMgr->createInstance( OUString::createFromAscii("com.sun.star.util.ProxyFactory") ), UNO_QUERY ); + OSL_ENSHURE( xProxyFac.is(), "### no proxy factory!" ); + + bSucc = test_proxyfac( xProxyFac ); + } + catch (Exception & rExc) + { + OSL_ENSHURE( sal_False, "### exception occured!" ); + OString aMsg( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( "### exception occured: " ); + OSL_TRACE( aMsg.getStr() ); + OSL_TRACE( "\n" ); + } + + Reference< XComponent >( xMgr, UNO_QUERY )->dispose(); + + printf( "testproxyfac %s !\n", (bSucc ? "succeeded" : "failed") ); + return (bSucc ? 0 : -1); +} diff --git a/stoc/test/testregistry.cxx b/stoc/test/testregistry.cxx new file mode 100644 index 000000000000..8ff0cf91bd36 --- /dev/null +++ b/stoc/test/testregistry.cxx @@ -0,0 +1,671 @@ +/************************************************************************* + * + * $RCSfile: testregistry.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef _VOS_MODULE_HXX_ +#include <vos/module.hxx> +#endif +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#ifndef _VOS_PROCESS_HXX_ +#include <vos/process.hxx> +#endif +#ifndef _VOS_DYNLOAD_HXX_ +#include <vos/dynload.hxx> +#endif + +#ifndef _REGISTRY_REGISTRY_HXX_ +#include <registry/registry.hxx> +#endif + + +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif + +#ifndef _CPPUHELPER_SERVICEFACTORY_HXX_ +#include <cppuhelper/servicefactory.hxx> +#endif + +#include <com/sun/star/lang/XComponent.hpp> + +#if defined ( UNX ) || defined ( MAC ) +#include <limits.h> +#define _MAX_PATH PATH_MAX +#endif + +using namespace com::sun::star::uno; +using namespace com::sun::star::registry; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace vos; +using namespace rtl; + +#ifdef _DEBUG +#define TEST_ENSHURE(c, m) VOS_ENSHURE(c, m) +#else +#define TEST_ENSHURE(c, m) VOS_VERIFY(c) +#endif + +OString userRegEnv("STAR_USER_REGISTRY="); + +OUString getExePath() +{ + OStartupInfo startupInfo; + OUString exe; + + VOS_VERIFY(startupInfo.getExecutableFile(exe) == OStartupInfo::E_None); + +#if defined(WIN32) || defined(__OS2__) || defined(WNT) + exe = exe.copy(0, exe.getLength() - 16); +#else + exe = exe.copy(0, exe.getLength() - 12); +#endif + return exe; +} + +void setStarUserRegistry() +{ + RegistryLoader* pLoader = new RegistryLoader(); + + if (!pLoader->isLoaded()) + { + delete pLoader; + return; + } + + Registry *myRegistry = new Registry(*pLoader); + delete pLoader; + + RegistryKey rootKey, rKey, rKey2; + + OUString userReg = getExePath(); + userReg += OUString::createFromAscii("user.rdb"); + if(myRegistry->open(userReg, REG_READWRITE)) + { + TEST_ENSHURE(!myRegistry->create(userReg), "setStarUserRegistry error 1"); + } + + TEST_ENSHURE(!myRegistry->close(), "setStarUserRegistry error 9"); + delete myRegistry; + + userRegEnv += OUStringToOString(userReg, RTL_TEXTENCODING_ASCII_US); + putenv((char *)userRegEnv.getStr()); +} + +void setLinkInDefaultRegistry(const OUString& linkName, const OUString& linkTarget) +{ + RegistryLoader* pLoader = new RegistryLoader(); + + if (!pLoader->isLoaded()) + { + delete pLoader; + return; + } + + Registry *myRegistry = new Registry(*pLoader); + delete pLoader; + + RegistryKey rootKey; + + OUString appReg = getExePath(); + appReg += OUString::createFromAscii("stoctest.rdb"); + + TEST_ENSHURE(!myRegistry->open(appReg, REG_READWRITE), "setLinkInDefaultRegistry error 1"); + TEST_ENSHURE(!myRegistry->openRootKey(rootKey), "setLinkInDefaultRegistry error 2"); + + TEST_ENSHURE(!rootKey.createLink(linkName, linkTarget), "setLinkInDefaultRegistry error 3"); + + TEST_ENSHURE(!rootKey.closeKey(), "setLinkInDefaultRegistry error 4"); + TEST_ENSHURE(!myRegistry->close(), "setLinkInDefaultRegistry error 5"); + + delete myRegistry; +} + + +void test_SimpleRegistry() +{ + Reference<XInterface> xIFace; + OModule* pModule = new OModule(OUString()); + + OUString dllName; + NAMESPACE_VOS(ORealDynamicLoader)::computeLibraryName(OUString::createFromAscii("simreg"), dllName); + + if (pModule->load(dllName)) + { + // try to get provider from module + component_getFactoryFunc pCompFactoryFunc = (component_getFactoryFunc) + pModule->getSymbol( OUString::createFromAscii(COMPONENT_GETFACTORY) ); + + if (pCompFactoryFunc) + { + XSingleServiceFactory * pRet = (XSingleServiceFactory *)(*pCompFactoryFunc)( + "com.sun.star.comp.stoc.SimpleRegistry", 0, 0 ); + if (pRet) + { + xIFace = pRet; + pRet->release(); + } + } + } + + TEST_ENSHURE( xIFace.is(), "test_SimpleRegistry error1"); + + Reference<XSingleServiceFactory> xFactory( Reference<XSingleServiceFactory>::query(xIFace) ); + xIFace.clear(); + + TEST_ENSHURE( xFactory.is(), "testloader error11"); + + Reference<XInterface> xIFace2 = xFactory->createInstance(); + xFactory.clear(); + + TEST_ENSHURE( xIFace2.is(), "testloader error12"); + + Reference<XServiceInfo> xServInfo( Reference<XServiceInfo>::query(xIFace2) ); + + TEST_ENSHURE( xServInfo.is(), "test_SimpleRegistry error2"); + + TEST_ENSHURE( xServInfo->getImplementationName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.comp.stoc.SimpleRegistry") ), "test_SimpleRegistry error3"); + TEST_ENSHURE( xServInfo->supportsService(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry"))), "test_SimpleRegistry error4"); + TEST_ENSHURE( xServInfo->getSupportedServiceNames().getLength() == 1, "test_SimpleRegistry error5"); + xServInfo.clear(); + + Reference<XSimpleRegistry> xReg( Reference<XSimpleRegistry>::query(xIFace2) ); + xIFace2.clear(); + + TEST_ENSHURE( xReg.is(), "test_SimpleRegistry error6"); + + try + { + xReg->open(OUString( RTL_CONSTASCII_USTRINGPARAM("testreg.rdb") ), sal_False, sal_True); + + TEST_ENSHURE( xReg->isValid() != sal_False, "test_SimpleRegistry error 7" ); + TEST_ENSHURE( xReg->isReadOnly() == sal_False, "test_SimpleRegistry error 8" ); + + Reference<XRegistryKey> xRootKey(xReg->getRootKey()); + TEST_ENSHURE( xRootKey->isValid(), "test_SimpleRegistry error 9" ); + + Reference<XRegistryKey> xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("FirstKey") )); + + Reference<XRegistryKey> xSubKey = xKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("FirstSubKey") )); + xSubKey->setLongValue(123456789); + + xSubKey = xKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("SecondSubKey") )); + xSubKey->setAsciiValue(OUString( RTL_CONSTASCII_USTRINGPARAM("ich bin ein acsii value") )); + + xSubKey = xKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("ThirdSubKey") )); + xSubKey->setStringValue(OUString( RTL_CONSTASCII_USTRINGPARAM("ich bin ein unicode value") )); + + xSubKey = xKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("FourthSubKey") )); + Sequence<sal_Int8> aSeq((sal_Int8*)"ich bin ein binary value", 25); + xSubKey->setBinaryValue(aSeq); + + Sequence<OUString> seqNames = xKey->getKeyNames(); + Sequence< Reference<XRegistryKey> > seqKeys = xKey->openKeys(); + + OUString name; + for (sal_Int32 i=0; i < seqNames.getLength(); i++) + { + name = seqNames.getArray()[i]; + xSubKey = seqKeys.getArray()[i]; + + if (name == OUString( RTL_CONSTASCII_USTRINGPARAM("/FirstKey/FirstSubKey") )) + { + TEST_ENSHURE( xSubKey->getLongValue() == 123456789, + "test_SimpleRegistry error 10" ); + } else + if (name == OUString( RTL_CONSTASCII_USTRINGPARAM("/FirstKey/SecondSubKey") )) + { + TEST_ENSHURE( xSubKey->getAsciiValue() == OUString( RTL_CONSTASCII_USTRINGPARAM("ich bin ein acsii value") ), + "test_SimpleRegistry error 11" ); + } else + if (name == OUString( RTL_CONSTASCII_USTRINGPARAM("/FirstKey/ThirdSubKey") )) + { + TEST_ENSHURE( xSubKey->getStringValue() == OUString( RTL_CONSTASCII_USTRINGPARAM("ich bin ein unicode value") ), + "test_SimpleRegistry error 12" ); + } else + if (name == OUString( RTL_CONSTASCII_USTRINGPARAM("/FirstKey/FourthSubKey") )) + { + Sequence<sal_Int8> seqByte = xSubKey->getBinaryValue(); + TEST_ENSHURE(!strcmp(((const char*)seqByte.getArray()), "ich bin ein binary value"), + "test_SimpleRegistry error 13" ); + } + + seqKeys.getArray()[i]->closeKey(); + } + + xKey->closeKey(); + + xRootKey->deleteKey(OUString( RTL_CONSTASCII_USTRINGPARAM("FirstKey") )); + xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("SecondFirstKey" ))); + + xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("SecondKey") )); + sal_Int32 pLongs[3] = {123, 456, 789}; + Sequence<sal_Int32> seqLongs(pLongs, 3); + xKey->setLongListValue(seqLongs); + + Sequence<sal_Int32> seqLongs2; + seqLongs2 = xKey->getLongListValue(); + TEST_ENSHURE( seqLongs.getLength() == 3, "test_SimpleRegistry error 14" ); + TEST_ENSHURE( seqLongs.getArray()[0] == 123, "test_SimpleRegistry error 15" ); + TEST_ENSHURE( seqLongs.getArray()[1] == 456, "test_SimpleRegistry error 16" ); + TEST_ENSHURE( seqLongs.getArray()[2] == 789, "test_SimpleRegistry error 17" ); + + + xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("ThirdKey") )); + OUString pAscii[3]; + pAscii[0] = OUString( RTL_CONSTASCII_USTRINGPARAM("Hallo") ); + pAscii[1] = OUString( RTL_CONSTASCII_USTRINGPARAM("jetzt komm") ); + pAscii[2] = OUString( RTL_CONSTASCII_USTRINGPARAM("ich") ); + + Sequence<OUString> seqAscii(pAscii, 3); + xKey->setAsciiListValue(seqAscii); + + Sequence<OUString> seqAscii2; + seqAscii2 = xKey->getAsciiListValue(); + TEST_ENSHURE( seqAscii2.getLength() == 3, "test_SimpleRegistry error 18" ); + TEST_ENSHURE( seqAscii2.getArray()[0] == OUString( RTL_CONSTASCII_USTRINGPARAM("Hallo") ), "test_SimpleRegistry error 19"); + TEST_ENSHURE( seqAscii2.getArray()[1] == OUString( RTL_CONSTASCII_USTRINGPARAM("jetzt komm") ), "test_SimpleRegistry error 20"); + TEST_ENSHURE( seqAscii2.getArray()[2] == OUString( RTL_CONSTASCII_USTRINGPARAM("ich") ), "test_SimpleRegistry error 21"); + + xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("FourthKey") )); + OUString pUnicode[3]; + pUnicode[0] = OUString( RTL_CONSTASCII_USTRINGPARAM("Hallo") ); + pUnicode[1] = OUString( RTL_CONSTASCII_USTRINGPARAM("jetzt komm") ); + pUnicode[2] = OUString( RTL_CONSTASCII_USTRINGPARAM("ich als unicode") ); + + Sequence<OUString> seqUnicode(pUnicode, 3); + xKey->setStringListValue(seqUnicode); + + Sequence<OUString> seqUnicode2; + seqUnicode2 = xKey->getStringListValue(); + TEST_ENSHURE( seqUnicode2.getLength() == 3, "test_SimpleRegistry error 22" ); + TEST_ENSHURE( seqUnicode2.getArray()[0] == OUString( RTL_CONSTASCII_USTRINGPARAM("Hallo") ), "test_SimpleRegistry error 23"); + TEST_ENSHURE( seqUnicode2.getArray()[1] == OUString( RTL_CONSTASCII_USTRINGPARAM("jetzt komm") ), "test_SimpleRegistry error 24"); + TEST_ENSHURE( seqUnicode2.getArray()[2] == OUString( RTL_CONSTASCII_USTRINGPARAM("ich als unicode") ), "test_SimpleRegistry error 25"); + + + xReg->open(OUString( RTL_CONSTASCII_USTRINGPARAM("testreg2.rdb") ), False, True); + TEST_ENSHURE( xReg->isValid() != sal_False, "test_SimpleRegistry error 25" ); + xRootKey = xReg->getRootKey(); + xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("ThirdKey/FirstSubKey/WithSubSubKey") )); + xKey->closeKey(); + xRootKey->closeKey(); + xReg->close(); + + xReg->open(OUString( RTL_CONSTASCII_USTRINGPARAM("testreg.rdb") ), False, False); + TEST_ENSHURE( xReg->isValid() != sal_False, "test_SimpleRegistry error 26" ); + + xReg->mergeKey(OUString(), OUString( RTL_CONSTASCII_USTRINGPARAM("testreg2.rdb") )); + + xRootKey = xReg->getRootKey(); + xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("FirstKey/SecondSubKey") )); + TEST_ENSHURE( !xKey.is(), "test_SimpleRegistry error 27" ); + + // Test Links + xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("FifthKey") )); + xKey->createLink(OUString( RTL_CONSTASCII_USTRINGPARAM("MyFirstLink") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("/ThirdKey/FirstSubKey") )); + + xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/FifthKey/MyFirstLink") )); + TEST_ENSHURE( xKey->isValid(), "test_SimpleRegistry error 27" ); + TEST_ENSHURE( xKey->getKeyName() == OUString( RTL_CONSTASCII_USTRINGPARAM("/ThirdKey/FirstSubKey") ), "test_SimpleRegistry error 28" ); + + xKey->createLink(OUString( RTL_CONSTASCII_USTRINGPARAM("/WithSubSubKey/MyFourthLink") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("/FourthKey/MySecondLink") )); + + TEST_ENSHURE( xKey->getLinkTarget(OUString( RTL_CONSTASCII_USTRINGPARAM("/WithSubSubKey/MyFourthLink") )) + == OUString( RTL_CONSTASCII_USTRINGPARAM("/FourthKey/MySecondLink") ), "test_SimpleRegistry error 29" ); + + try + { + TEST_ENSHURE( xKey->getResolvedName(OUString( RTL_CONSTASCII_USTRINGPARAM("/WithSubSubKey/MyFourthLink/BlaBlaBla") )) + == OUString( RTL_CONSTASCII_USTRINGPARAM("/FourthKey/MySecondLink/BlaBlaBla") ), "test_SimpleRegistry error 30" ); + } + catch(InvalidRegistryException&) + { + } + + xRootKey->createLink(OUString( RTL_CONSTASCII_USTRINGPARAM("/FourthKey/MySecondLink") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("/SixthKey/MyThirdLink") )); + xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("SixthKey") )); + xKey->createLink(OUString( RTL_CONSTASCII_USTRINGPARAM("MyThirdLink") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("/FourthKey/MySecondLink") )); + + xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/SixthKey/SixthSubKey") )); + + try + { + xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink") )); + } + catch(InvalidRegistryException&) + { + } + + TEST_ENSHURE( xRootKey->getLinkTarget(OUString( RTL_CONSTASCII_USTRINGPARAM("/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink") )) + == OUString( RTL_CONSTASCII_USTRINGPARAM("/FourthKey/MySecondLink") ), "test_SimpleRegistry error 31" ); + + xRootKey->deleteLink(OUString( RTL_CONSTASCII_USTRINGPARAM("/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink") )); + + xRootKey->createLink(OUString( RTL_CONSTASCII_USTRINGPARAM("/FourthKey/MySecondLink") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("/ThirdKey/FirstSubKey/WithSubSubKey") )); + + xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("SixthKey") )); + seqNames = xKey->getKeyNames(); + seqKeys = xKey->openKeys(); + + TEST_ENSHURE( seqNames.getArray()[0] == OUString( RTL_CONSTASCII_USTRINGPARAM("/SixthKey/SixthSubKey") ), + "test_SimpleRegistry error 32" ); + TEST_ENSHURE( seqNames.getArray()[1] == OUString( RTL_CONSTASCII_USTRINGPARAM("/SixthKey/MyThirdLink") ), + "test_SimpleRegistry error 33" ); + + TEST_ENSHURE( seqKeys.getArray()[0]->getKeyName() == OUString( RTL_CONSTASCII_USTRINGPARAM("/SixthKey/SixthSubKey") ), + "test_SimpleRegistry error 34" ); + TEST_ENSHURE( seqKeys.getArray()[1]->getKeyName() == OUString( RTL_CONSTASCII_USTRINGPARAM("/ThirdKey/FirstSubKey/WithSubSubKey") ), + "test_SimpleRegistry error 35" ); + + xRootKey->deleteLink(OUString( RTL_CONSTASCII_USTRINGPARAM("/FourthKey/MySecondLink") )); + +// xRootKey->closeKey(); + +// xReg->open(L"testreg2.rdb", False, True); +// xReg->destroy(); + } + catch(InvalidRegistryException&) + { + TEST_ENSHURE(0, "exception InvalidRegistryExcption raised while doing test_SimpleRegistry"); + } + catch(InvalidValueException&) + { + TEST_ENSHURE(0, "exception InvalidValueExcption raised while doing test_SimpleRegistry()"); + } + + xReg.clear(); + + delete pModule; + + printf("Test SimpleRegistry, OK!\n"); +} + + +void test_DefaultRegistry() +{ +// Reference < XMultiServiceFactory > rSMgr = ::cppu::createDefaultRegistryServiceFactory( ); + + // Test NestedRegistry + OUString exePath( getExePath() ); + OUString userRdb(exePath); + OUString applicatRdb(exePath); + + userRdb += OUString::createFromAscii("user.rdb"); + applicatRdb += OUString::createFromAscii("stoctest.rdb"); + + Reference < XMultiServiceFactory > rSMgr = ::cppu::createRegistryServiceFactory( userRdb, applicatRdb, sal_False, + OUString::createFromAscii("//./e:/src596/stoc/wntmsci3/bin") ); + + Reference< XPropertySet > xPropSet( rSMgr, UNO_QUERY); + TEST_ENSHURE( xPropSet.is(), "test_DefaultRegistry error0"); + + Any aPropertyAny( xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("Registry")) ) ); + TEST_ENSHURE( aPropertyAny.hasValue(), "test_DefaultRegistry error1"); + + Reference<XSimpleRegistry> xReg; + aPropertyAny >>= xReg; + TEST_ENSHURE( xReg.is(), "test_DefaultRegistry error1a"); + + Reference<XServiceInfo> xServInfo( Reference<XServiceInfo>::query(xReg) ); + + TEST_ENSHURE( xServInfo.is(), "test_DefaultRegistry error2"); + + TEST_ENSHURE( xServInfo->getImplementationName() == OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.NestedRegistry") ), "test_DefualtRegistry error3"); + TEST_ENSHURE( xServInfo->supportsService(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.NestedRegistry") )), "test_DefaultRegistry error4"); + TEST_ENSHURE( xServInfo->getSupportedServiceNames().getLength() == 1, "test_DefaultRegistry error5"); + xServInfo.clear(); + + TEST_ENSHURE( xReg.is(), "test_DefaultRegistry error6"); + + try + { + Reference<XRegistryKey> xRootKey(xReg->getRootKey()); + + Reference<XRegistryKey> xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/UCR/com/sun/star/registry/XSimpleRegistry") )); + + TEST_ENSHURE( xKey->getKeyName() == OUString( RTL_CONSTASCII_USTRINGPARAM("/UCR/com/sun/star/registry/XSimpleRegistry") ), + "test_DefaultRegistry error 7" ); + + xReg->mergeKey(OUString( RTL_CONSTASCII_USTRINGPARAM("Test") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("testreg.rdb") )); + + xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("Test/ThirdKey/FirstSubKey/WithSubSubKey") )); + if (xKey.is()) + xKey->setLongValue(123456789); + + xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("Test/ThirdKey/FirstSubKey") )); + if (xKey.is()) + { + xKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("SecondSubSubKey") )); + + Sequence<OUString> seqNames = xKey->getKeyNames(); + + TEST_ENSHURE( seqNames.getLength() == 2, "test_DefaultRegistry error 8" ); + } + + xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/ThirdKey") )); + if (xKey.is()) + { + RegistryValueType valueType = xKey->getValueType(); + TEST_ENSHURE( valueType == RegistryValueType_ASCIILIST, "test_DefaultRegistry error 9" ); + + Sequence<OUString> seqValue = xKey->getAsciiListValue(); + + TEST_ENSHURE( seqValue.getLength() == 3, "test_DefaultRegistry error 10" ); + TEST_ENSHURE( seqValue.getArray()[0] == OUString( RTL_CONSTASCII_USTRINGPARAM("Hallo") ), + "test_DefaultRegistry error 11" ); + TEST_ENSHURE( seqValue.getArray()[1] == OUString( RTL_CONSTASCII_USTRINGPARAM("jetzt komm") ), + "test_DefaultRegistry error 12" ); + TEST_ENSHURE( seqValue.getArray()[2] == OUString( RTL_CONSTASCII_USTRINGPARAM("ich") ), + "test_DefaultRegistry error 13" ); + + Sequence<sal_Int32> seqLong(3); + seqLong.getArray()[0] = 1234; + seqLong.getArray()[1] = 4567; + seqLong.getArray()[2] = 7890; + + xKey->setLongListValue(seqLong); + + Sequence<sal_Int32> seqLongValue = xKey->getLongListValue(); + + TEST_ENSHURE( seqLongValue.getLength() == 3, "test_DefaultRegistry error 14" ); + TEST_ENSHURE( seqLongValue.getArray()[0] == 1234, "test_DefaultRegistry error 15" ); + TEST_ENSHURE( seqLongValue.getArray()[1] == 4567, "test_DefaultRegistry error 16" ); + TEST_ENSHURE( seqLongValue.getArray()[2] == 7890, "test_DefaultRegistry error 17" ); + } + + // Test Links + xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FifthKey") )); + xKey->createLink(OUString( RTL_CONSTASCII_USTRINGPARAM("MyFirstLink") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/ThirdKey/FirstSubKey") )); + + xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FifthKey/MyFirstLink") )); + TEST_ENSHURE( xKey->isValid(), "test_DefaultRegistry error 18" ); + TEST_ENSHURE( xKey->getKeyName() == OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/ThirdKey/FirstSubKey") ), + "test_DefaultRegistry error 19" ); + + xKey->createLink(OUString( RTL_CONSTASCII_USTRINGPARAM("/WithSubSubKey/MyFourthLink") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FourthKey/MySecondLink") )); + + TEST_ENSHURE( xKey->getLinkTarget(OUString( RTL_CONSTASCII_USTRINGPARAM("/WithSubSubKey/MyFourthLink") )) + == OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FourthKey/MySecondLink") ), + "test_DefaultRegistry error 20" ); + + try + { + TEST_ENSHURE( xKey->getResolvedName(OUString( RTL_CONSTASCII_USTRINGPARAM("/WithSubSubKey/MyFourthLink/BlaBlaBla") )) + == OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FourthKey/MySecondLink/BlaBlaBla") ), + "test_DefaultRegistry error 21" ); + } + catch(InvalidRegistryException&) + { + } + + xRootKey->createLink(OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FourthKey/MySecondLink") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/SixthKey/MyThirdLink") )); + xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/SixthKey") )); + xKey->createLink(OUString( RTL_CONSTASCII_USTRINGPARAM("MyThirdLink") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FourthKey/MySecondLink") )); + + try + { + xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink") )); + } + catch(InvalidRegistryException&) + { + printf("test InvalidRegistryExcption OK!\n"); + } + + TEST_ENSHURE( xRootKey->getLinkTarget(OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink") )) + == OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FourthKey/MySecondLink") ), + "test_DefaultRegistry error 22" ); + + xRootKey->deleteLink(OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink") )); + + xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/DefaultLink/SecondSubSubKey") )); + if (xKey.is()) + { + TEST_ENSHURE( xKey->getKeyName() == OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/ThirdKey/FirstSubKey/SecondSubSubKey") ), "test_DefaultRegistry error 23" ); + } + xKey = xRootKey->createKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/DefaultLink/ThirdSubSubKey") )); + if (xKey.is()) + { + TEST_ENSHURE( xKey->getKeyName() == OUString( RTL_CONSTASCII_USTRINGPARAM("/Test/ThirdKey/FirstSubKey/ThirdSubSubKey") ), + "test_DefaultRegistry error 24" ); + } + + xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("Test") )); + TEST_ENSHURE( xKey->isValid(), "test_DefaultRegistry error 25" ); + + xRootKey->deleteKey(OUString( RTL_CONSTASCII_USTRINGPARAM("Test") )); + + xReg->mergeKey(OUString( RTL_CONSTASCII_USTRINGPARAM("AllFromTestreg2") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("testreg2.rdb") )); + + xKey = xRootKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/AllFromTestreg2/ThirdKey/FirstSubKey") )); + if (xKey.is()) + { + xRootKey->deleteKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/AllFromTestreg2") )); + } +/* + Reference<XSimpleRegistry> xSimplReg( xMgr->createInstance(L"com.sun.star.registry.SimpleRegistry"), USR_QUERY ); + + xSimplReg->open(L"testreg2.rdb", False, True); + xSimplReg->destroy(); + + xSimplReg->open(L"testreg.rdb", False, True); + xSimplReg->destroy(); +*/ + } + catch(InvalidRegistryException&) + { + TEST_ENSHURE(0, "exception InvalidRegistryExcption raised while doing test_DefaultRegistry"); + } + catch(InvalidValueException&) + { + TEST_ENSHURE(0, "exception InvalidValueExcption raised while doing test_DefaultRegistry()"); + } + xReg.clear(); + + // shutdown + Reference< ::com::sun::star::lang::XComponent > xComp( rSMgr, UNO_QUERY ); + VOS_ENSHURE( xComp.is(), "### serivce manager has to implement XComponent!" ); + xComp->dispose(); + + printf("Test DefaultRegistry, OK!\n"); +} + + + + +#if (defined UNX) || (defined OS2) +int main( int argc, char * argv[] ) +#else +int _cdecl main( int argc, char * argv[] ) +#endif +{ + setStarUserRegistry(); + setLinkInDefaultRegistry(OUString::createFromAscii("/Test/DefaultLink"), + OUString::createFromAscii("/Test/FifthKey/MyFirstLink")); + + test_SimpleRegistry(); + test_DefaultRegistry(); + + return(0); +} + + diff --git a/stoc/test/testsmgr.cxx b/stoc/test/testsmgr.cxx new file mode 100644 index 000000000000..a711898bad74 --- /dev/null +++ b/stoc/test/testsmgr.cxx @@ -0,0 +1,162 @@ +/************************************************************************* + * + * $RCSfile: testsmgr.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:29:36 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <stdio.h> +#ifndef _VOS_MODULE_HXX_ +#include <vos/module.hxx> +#endif +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#ifndef _VOS_PROCESS_HXX_ +#include <vos/process.hxx> +#endif +#ifndef _VOS_DYNLOAD_HXX_ +#include <vos/dynload.hxx> +#endif + +#ifndef _REGISTRY_REGISTRY_HXX_ +#include <registry/registry.hxx> +#endif + +#ifndef _UNO_MAPPING_HXX_ +#include <uno/mapping.hxx> +#endif + +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include "testsmgr_cpnt/testsmgr_cpnt.hxx" + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifdef _DEBUG +#define TEST_ENSHURE(c, m) VOS_ENSHURE(c, m) +#else +#define TEST_ENSHURE(c, m) VOS_VERIFY(c) +#endif + + +using namespace ::rtl; +using namespace ::vos; +OString userRegEnv("STAR_USER_REGISTRY="); + +OUString getExePath() +{ + OStartupInfo startupInfo; + OUString exe; + + VOS_VERIFY(startupInfo.getExecutableFile(exe) == OStartupInfo::E_None); + +#if defined(WIN32) || defined(__OS2__) || defined(WNT) + exe = exe.copy(0, exe.getLength() - 16); +#else + exe = exe.copy(0, exe.getLength() - 12); +#endif + return exe; +} + +void setStarUserRegistry() +{ + RegistryLoader* pLoader = new RegistryLoader(); + + if (!pLoader->isLoaded()) + { + delete pLoader; + return; + } + + Registry *myRegistry = new Registry(*pLoader); + delete pLoader; + + RegistryKey rootKey, rKey, rKey2; + + OUString userReg = getExePath(); + userReg += OUString::createFromAscii("user.rdb"); + if(myRegistry->open(userReg, REG_READWRITE)) + { + TEST_ENSHURE(!myRegistry->create(userReg), "setStarUserRegistry error 1"); + } + + TEST_ENSHURE(!myRegistry->close(), "setStarUserRegistry error 9"); + delete myRegistry; + + userRegEnv += OUStringToOString(userReg, RTL_TEXTENCODING_ASCII_US); + putenv((char *)userRegEnv.getStr()); +} + + + +void SAL_CALL main() +{ + printf( "ServiceManagerTest : \r"); + setStarUserRegistry(); + fflush( stdout ); + test_ServiceManager(); + + printf( "ServiceManagerTest : OK\n" ); +} diff --git a/stoc/unosdk.mk b/stoc/unosdk.mk new file mode 100644 index 000000000000..8dce4dc6c673 --- /dev/null +++ b/stoc/unosdk.mk @@ -0,0 +1,69 @@ +#************************************************************************* +# +# $RCSfile: unosdk.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PPATH=inc + +FILES= \ + $(PPATH)\stoc\component.hxx + +unosdk: $(FILES) + docpp -H -m -f -u -d ..\..\doc\stoc $(FILES) |