| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| #include <osl/diagnose.h> |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/lang/XInitialization.hpp> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/lang/XSingleServiceFactory.hpp> |
| #include <com/sun/star/registry/XRegistryKey.hpp> |
| #include <com/sun/star/beans/XIntrospection.hpp> |
| #include <com/sun/star/beans/MethodConcept.hpp> |
| #include <com/sun/star/script/XEventAttacher.hpp> |
| #include <com/sun/star/script/XTypeConverter.hpp> |
| #include <com/sun/star/script/XAllListener.hpp> |
| #include <com/sun/star/script/XInvocationAdapterFactory.hpp> |
| #include <com/sun/star/reflection/XIdlReflection.hpp> |
| |
| // InvocationToAllListenerMapper |
| #include <com/sun/star/script/XInvocation.hpp> |
| #include <cppuhelper/weak.hxx> |
| #include <cppuhelper/factory.hxx> |
| #include <cppuhelper/implbase1.hxx> |
| #include <cppuhelper/implbase3.hxx> |
| |
| 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 com::sun::star::script; |
| using namespace com::sun::star::reflection; |
| using namespace cppu; |
| using namespace osl; |
| using namespace rtl; |
| |
| |
| #define SERVICENAME "com.sun.star.script.EventAttacher" |
| #define IMPLNAME "com.sun.star.comp.EventAttacher" |
| |
| namespace comp_EventAttacher { |
| |
| //************************************************************************* |
| // class InvocationToAllListenerMapper |
| // helper class to map XInvocation to XAllListener |
| //************************************************************************* |
| class InvocationToAllListenerMapper : public WeakImplHelper1< XInvocation > |
| { |
| public: |
| InvocationToAllListenerMapper( const Reference< XIdlClass >& ListenerType, |
| const Reference< XAllListener >& AllListener, const Any& Helper ); |
| |
| // 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 ); |
| |
| private: |
| Reference< XIdlReflection > m_xCoreReflection; |
| Reference< XAllListener > m_xAllListener; |
| Reference< XIdlClass > m_xListenerType; |
| Any m_Helper; |
| }; |
| |
| |
| // Function to replace AllListenerAdapterService::createAllListerAdapter |
| Reference< XInterface > createAllListenerAdapter |
| ( |
| const Reference< XInvocationAdapterFactory >& xInvocationAdapterFactory, |
| const Reference< XIdlClass >& xListenerType, |
| const Reference< XAllListener >& xListener, |
| const Any& Helper |
| ) |
| { |
| Reference< XInterface > xAdapter; |
| if( xInvocationAdapterFactory.is() && xListenerType.is() && xListener.is() ) |
| { |
| Reference< XInvocation > xInvocationToAllListenerMapper = |
| (XInvocation*)new InvocationToAllListenerMapper( xListenerType, xListener, Helper ); |
| Type aListenerType( xListenerType->getTypeClass(), xListenerType->getName()); |
| xAdapter = xInvocationAdapterFactory->createAdapter( xInvocationToAllListenerMapper, aListenerType ); |
| } |
| return xAdapter; |
| } |
| |
| |
| //-------------------------------------------------------------------------------------------------- |
| // InvocationToAllListenerMapper |
| InvocationToAllListenerMapper::InvocationToAllListenerMapper |
| ( const Reference< XIdlClass >& ListenerType, const Reference< XAllListener >& AllListener, const Any& Helper ) |
| : m_xAllListener( AllListener ) |
| , m_xListenerType( ListenerType ) |
| , m_Helper( Helper ) |
| { |
| } |
| |
| //************************************************************************* |
| Reference< XIntrospectionAccess > SAL_CALL InvocationToAllListenerMapper::getIntrospection(void) |
| throw( RuntimeException ) |
| { |
| return Reference< XIntrospectionAccess >(); |
| } |
| |
| //************************************************************************* |
| Any SAL_CALL InvocationToAllListenerMapper::invoke(const OUString& FunctionName, const Sequence< Any >& Params, |
| Sequence< sal_Int16 >& , Sequence< Any >& ) |
| throw( IllegalArgumentException, CannotConvertException, |
| InvocationTargetException, RuntimeException ) |
| { |
| Any aRet; |
| |
| // Check if to firing or approveFiring has to be called |
| Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( FunctionName ); |
| sal_Bool bApproveFiring = sal_False; |
| if( !xMethod.is() ) |
| return aRet; |
| Reference< XIdlClass > xReturnType = xMethod->getReturnType(); |
| Sequence< Reference< XIdlClass > > aExceptionSeq = xMethod->getExceptionTypes(); |
| if( ( xReturnType.is() && xReturnType->getTypeClass() != TypeClass_VOID ) || |
| aExceptionSeq.getLength() > 0 ) |
| { |
| bApproveFiring = sal_True; |
| } |
| else |
| { |
| Sequence< ParamInfo > aParamSeq = xMethod->getParameterInfos(); |
| sal_uInt32 nParamCount = aParamSeq.getLength(); |
| if( nParamCount > 1 ) |
| { |
| const ParamInfo* pInfos = aParamSeq.getConstArray(); |
| for( sal_uInt32 i = 0 ; i < nParamCount ; i++ ) |
| { |
| if( pInfos[ i ].aMode != ParamMode_IN ) |
| { |
| bApproveFiring = sal_True; |
| break; |
| } |
| } |
| } |
| } |
| |
| AllEventObject aAllEvent; |
| aAllEvent.Source = (OWeakObject*) this; |
| aAllEvent.Helper = m_Helper; |
| aAllEvent.ListenerType = Type(m_xListenerType->getTypeClass(), m_xListenerType->getName()); |
| aAllEvent.MethodName = FunctionName; |
| aAllEvent.Arguments = Params; |
| if( bApproveFiring ) |
| aRet = m_xAllListener->approveFiring( aAllEvent ); |
| else |
| m_xAllListener->firing( aAllEvent ); |
| return aRet; |
| } |
| |
| //************************************************************************* |
| void SAL_CALL InvocationToAllListenerMapper::setValue(const OUString& , const Any& ) |
| throw( UnknownPropertyException, CannotConvertException, |
| InvocationTargetException, RuntimeException ) |
| { |
| } |
| |
| //************************************************************************* |
| Any SAL_CALL InvocationToAllListenerMapper::getValue(const OUString& ) |
| throw( UnknownPropertyException, RuntimeException ) |
| { |
| return Any(); |
| } |
| |
| //************************************************************************* |
| sal_Bool SAL_CALL InvocationToAllListenerMapper::hasMethod(const OUString& Name) |
| throw( RuntimeException ) |
| { |
| Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( Name ); |
| return xMethod.is(); |
| } |
| |
| //************************************************************************* |
| sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const OUString& Name) |
| throw( RuntimeException ) |
| { |
| Reference< XIdlField > xField = m_xListenerType->getField( Name ); |
| return xField.is(); |
| } |
| |
| //************************************************************************* |
| // class EventAttacherImpl |
| // represents an implementation of the EventAttacher service |
| //************************************************************************* |
| class EventAttacherImpl : public WeakImplHelper3 < XEventAttacher, XInitialization, XServiceInfo > |
| { |
| public: |
| EventAttacherImpl( const Reference< XMultiServiceFactory >& ); |
| ~EventAttacherImpl(); |
| |
| // 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); |
| |
| // Methoden von XEventAttacher |
| virtual Reference< XEventListener > SAL_CALL attachListener(const Reference< XInterface >& xObject, |
| const Reference< XAllListener >& AllListener, const Any& Helper, |
| const OUString& ListenerType, const OUString& AddListenerParam) |
| throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException ); |
| virtual Reference< XEventListener > SAL_CALL attachSingleEventListener(const Reference< XInterface >& xObject, |
| const Reference< XAllListener >& AllListener, const Any& Helper, |
| const OUString& ListenerType, const OUString& AddListenerParam, |
| const OUString& EventMethod) |
| throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException ); |
| virtual void SAL_CALL removeListener(const Reference< XInterface >& xObject, |
| const OUString& ListenerType, const OUString& AddListenerParam, |
| const Reference< XEventListener >& aToRemoveListener) |
| throw( IllegalArgumentException, IntrospectionException, RuntimeException ); |
| |
| // used by FilterAllListener_Impl |
| Reference< XTypeConverter > getConverter() throw( Exception ); |
| |
| friend class FilterAllListenerImpl; |
| private: |
| Mutex m_aMutex; |
| Reference< XMultiServiceFactory > m_xSMgr; |
| |
| // Services merken |
| Reference< XIntrospection > m_xIntrospection; |
| Reference< XIdlReflection > m_xReflection; |
| Reference< XTypeConverter > m_xConverter; |
| Reference< XInvocationAdapterFactory > m_xInvocationAdapterFactory; |
| |
| // needed services |
| Reference< XIntrospection > getIntrospection() throw( Exception ); |
| Reference< XIdlReflection > getReflection() throw( Exception ); |
| Reference< XInvocationAdapterFactory > getInvocationAdapterService() throw( Exception ); |
| }; |
| |
| |
| //************************************************************************* |
| EventAttacherImpl::EventAttacherImpl( const Reference< XMultiServiceFactory >& rSMgr ) |
| : m_xSMgr( rSMgr ) |
| { |
| } |
| |
| //************************************************************************* |
| EventAttacherImpl::~EventAttacherImpl() |
| { |
| } |
| |
| //************************************************************************* |
| Reference< XInterface > SAL_CALL EventAttacherImpl_CreateInstance( const Reference< XMultiServiceFactory >& rSMgr ) throw( Exception ) |
| { |
| Reference< XInterface > xRet; |
| XEventAttacher *pEventAttacher = (XEventAttacher*) new EventAttacherImpl(rSMgr); |
| |
| if (pEventAttacher) |
| { |
| xRet = Reference<XInterface>::query(pEventAttacher); |
| } |
| |
| return xRet; |
| } |
| |
| //************************************************************************* |
| OUString SAL_CALL EventAttacherImpl::getImplementationName( ) |
| throw(RuntimeException) |
| { |
| return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) ); |
| } |
| |
| //************************************************************************* |
| sal_Bool SAL_CALL EventAttacherImpl::supportsService( const OUString& ServiceName ) |
| throw(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 EventAttacherImpl::getSupportedServiceNames( ) |
| throw(RuntimeException) |
| { |
| return getSupportedServiceNames_Static(); |
| } |
| |
| //************************************************************************* |
| Sequence<OUString> SAL_CALL EventAttacherImpl::getSupportedServiceNames_Static( ) |
| { |
| OUString aStr( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME ) ); |
| return Sequence< OUString >( &aStr, 1 ); |
| } |
| |
| //************************************************************************* |
| void SAL_CALL EventAttacherImpl::initialize(const Sequence< Any >& Arguments) throw( Exception, RuntimeException ) |
| { |
| // get services from the argument list |
| const Any * pArray = Arguments.getConstArray(); |
| for( sal_Int32 i = 0; i < Arguments.getLength(); i++ ) |
| { |
| if( pArray[i].getValueType().getTypeClass() != TypeClass_INTERFACE ) |
| throw IllegalArgumentException(); |
| |
| // InvocationAdapter service ? |
| Reference< XInvocationAdapterFactory > xALAS; |
| pArray[i] >>= xALAS; |
| if( xALAS.is() ) |
| { |
| Guard< Mutex > aGuard( m_aMutex ); |
| m_xInvocationAdapterFactory = xALAS; |
| } |
| // Introspection service ? |
| Reference< XIntrospection > xI; |
| pArray[i] >>= xI; |
| if( xI.is() ) |
| { |
| Guard< Mutex > aGuard( m_aMutex ); |
| m_xIntrospection = xI; |
| } |
| // Reflection service ? |
| Reference< XIdlReflection > xIdlR; |
| pArray[i] >>= xIdlR; |
| if( xIdlR.is() ) |
| { |
| Guard< Mutex > aGuard( m_aMutex ); |
| m_xReflection = xIdlR; |
| } |
| // Converter Service ? |
| Reference< XTypeConverter > xC; |
| pArray[i] >>= xC; |
| if( xC.is() ) |
| { |
| Guard< Mutex > aGuard( m_aMutex ); |
| m_xConverter = xC; |
| } |
| |
| // no right interface |
| if( !xALAS.is() && !xI.is() && !xIdlR.is() && !xC.is() ) |
| throw IllegalArgumentException(); |
| } |
| } |
| |
| //************************************************************************* |
| //*** Private Hilfs-Methoden *** |
| Reference< XIntrospection > EventAttacherImpl::getIntrospection() throw( Exception ) |
| { |
| Guard< Mutex > aGuard( m_aMutex ); |
| // Haben wir den Service schon? Sonst anlegen |
| if( !m_xIntrospection.is() ) |
| { |
| Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection") ) ); |
| m_xIntrospection = Reference< XIntrospection >( xIFace, UNO_QUERY ); |
| } |
| return m_xIntrospection; |
| } |
| |
| //************************************************************************* |
| //*** Private Hilfs-Methoden *** |
| Reference< XIdlReflection > EventAttacherImpl::getReflection() throw( Exception ) |
| { |
| Guard< Mutex > aGuard( m_aMutex ); |
| // Haben wir den Service schon? Sonst anlegen |
| if( !m_xReflection.is() ) |
| { |
| Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ) ); |
| m_xReflection = Reference< XIdlReflection >( xIFace, UNO_QUERY); |
| } |
| return m_xReflection; |
| } |
| |
| //************************************************************************* |
| //*** Private Hilfs-Methoden *** |
| Reference< XInvocationAdapterFactory > EventAttacherImpl::getInvocationAdapterService() throw( Exception ) |
| { |
| Guard< Mutex > aGuard( m_aMutex ); |
| // Haben wir den Service schon? Sonst anlegen |
| if( !m_xInvocationAdapterFactory.is() ) |
| { |
| Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.script.InvocationAdapterFactory") ) ); |
| m_xInvocationAdapterFactory = Reference< XInvocationAdapterFactory >( xIFace, UNO_QUERY ); |
| } |
| return m_xInvocationAdapterFactory; |
| } |
| |
| |
| //************************************************************************* |
| //*** Private Hilfs-Methoden *** |
| Reference< XTypeConverter > EventAttacherImpl::getConverter() throw( Exception ) |
| { |
| Guard< Mutex > aGuard( m_aMutex ); |
| // Haben wir den Service schon? Sonst anlegen |
| if( !m_xConverter.is() ) |
| { |
| Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.script.Converter") ) ); |
| m_xConverter = Reference< XTypeConverter >( xIFace, UNO_QUERY ); |
| } |
| return m_xConverter; |
| } |
| |
| //------------------------------------------------------------------------ |
| //------------------------------------------------------------------------ |
| //------------------------------------------------------------------------ |
| // Implementation eines EventAttacher-bezogenen AllListeners, der |
| // nur einzelne Events an einen allgemeinen AllListener weiterleitet |
| class FilterAllListenerImpl : public WeakImplHelper1< XAllListener > |
| { |
| public: |
| FilterAllListenerImpl( EventAttacherImpl * pEA_, const OUString& EventMethod_, |
| const Reference< XAllListener >& AllListener_ ); |
| |
| // XAllListener |
| virtual void SAL_CALL firing(const AllEventObject& Event) throw( RuntimeException ); |
| virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw( InvocationTargetException, RuntimeException ); |
| |
| // XEventListener |
| virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException ); |
| |
| private: |
| // convert |
| void convertToEventReturn( Any & rRet, const Type& rRetType ) |
| throw( CannotConvertException ); |
| |
| EventAttacherImpl * m_pEA; |
| Reference< XInterface > m_xEAHold; |
| OUString m_EventMethod; |
| Reference< XAllListener > m_AllListener; |
| }; |
| |
| //************************************************************************* |
| FilterAllListenerImpl::FilterAllListenerImpl( EventAttacherImpl * pEA_, const OUString& EventMethod_, |
| const Reference< XAllListener >& AllListener_ ) |
| : m_pEA( pEA_ ) |
| , m_xEAHold( *pEA_ ) |
| , m_EventMethod( EventMethod_ ) |
| , m_AllListener( AllListener_ ) |
| { |
| } |
| |
| //************************************************************************* |
| void SAL_CALL FilterAllListenerImpl::firing(const AllEventObject& Event) |
| throw( RuntimeException ) |
| { |
| // Nur durchreichen, wenn es die richtige Methode ist |
| if( Event.MethodName == m_EventMethod && m_AllListener.is() ) |
| m_AllListener->firing( Event ); |
| } |
| |
| //************************************************************************* |
| // Convert to the standard event return |
| void FilterAllListenerImpl::convertToEventReturn( Any & rRet, const Type & rRetType ) |
| throw( CannotConvertException ) |
| { |
| // no return value? Set to the specified values |
| if( rRet.getValueType().getTypeClass() == TypeClass_VOID ) |
| { |
| switch( rRetType.getTypeClass() ) |
| { |
| case TypeClass_INTERFACE: |
| { |
| rRet <<= Reference< XInterface >(); |
| } |
| break; |
| |
| case TypeClass_BOOLEAN: |
| rRet <<= sal_True; |
| break; |
| |
| case TypeClass_STRING: |
| rRet <<= OUString(); |
| break; |
| |
| case TypeClass_FLOAT: rRet <<= float(0); break; |
| case TypeClass_DOUBLE: rRet <<= double(0.0); break; |
| case TypeClass_BYTE: rRet <<= sal_uInt8( 0 ); break; |
| case TypeClass_SHORT: rRet <<= sal_Int16( 0 ); break; |
| case TypeClass_LONG: rRet <<= sal_Int32( 0 ); break; |
| case TypeClass_UNSIGNED_SHORT: rRet <<= sal_uInt16( 0 ); break; |
| case TypeClass_UNSIGNED_LONG: rRet <<= sal_uInt32( 0 ); break; |
| default: |
| break; |
| } |
| } |
| else if( !rRet.getValueType().equals( rRetType ) ) |
| { |
| Reference< XTypeConverter > xConverter = m_pEA->getConverter(); |
| if( xConverter.is() ) |
| rRet = xConverter->convertTo( rRet, rRetType ); |
| else |
| throw CannotConvertException(); // TODO TypeConversionException |
| } |
| } |
| |
| //************************************************************************* |
| Any SAL_CALL FilterAllListenerImpl::approveFiring( const AllEventObject& Event ) |
| throw( InvocationTargetException, RuntimeException ) |
| { |
| Any aRet; |
| |
| // Nur durchreichen, wenn es die richtige Methode ist |
| if( Event.MethodName == m_EventMethod && m_AllListener.is() ) |
| aRet = m_AllListener->approveFiring( Event ); |
| else |
| { |
| // Convert to the standard event return |
| try |
| { |
| Reference< XIdlClass > xListenerType = m_pEA->getReflection()-> |
| forName( Event.ListenerType.getTypeName() ); |
| Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName ); |
| if( xMeth.is() ) |
| { |
| Reference< XIdlClass > xRetType = xMeth->getReturnType(); |
| Type aRetType( xRetType->getTypeClass(), xRetType->getName() ); |
| convertToEventReturn( aRet, aRetType ); |
| } |
| } |
| catch( CannotConvertException& e ) |
| { |
| throw InvocationTargetException( OUString(), Reference< XInterface >(), Any(&e, ::getCppuType( (CannotConvertException*)0)) ); |
| } |
| } |
| return aRet; |
| } |
| |
| //************************************************************************* |
| void FilterAllListenerImpl::disposing(const EventObject& ) |
| throw( RuntimeException ) |
| { |
| // TODO: ??? |
| } |
| |
| |
| //************************************************************************* |
| Reference< XEventListener > EventAttacherImpl::attachListener |
| ( |
| const Reference< XInterface >& xObject, |
| const Reference< XAllListener >& AllListener, |
| const Any& Helper, |
| const OUString& ListenerType, |
| const OUString& AddListenerParam |
| ) |
| throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException ) |
| { |
| if( !xObject.is() || !AllListener.is() ) |
| throw IllegalArgumentException(); |
| |
| Reference< XEventListener > xRet = NULL; |
| |
| // InvocationAdapterService holen |
| Reference< XInvocationAdapterFactory > xInvocationAdapterFactory = getInvocationAdapterService(); |
| if( !xInvocationAdapterFactory.is() ) |
| throw ServiceNotRegisteredException(); |
| |
| // Listener-Klasse per Reflection besorgen |
| Reference< XIdlReflection > xReflection = getReflection(); |
| if( !xReflection.is() ) |
| throw ServiceNotRegisteredException(); |
| |
| // Anmelden, dazu passende addListener-Methode aufrufen |
| // Zunaechst ueber Introspection gehen, da die Methoden in der gleichen |
| // Weise analysiert werden koennen. Fuer bessere Performance entweder |
| // hier nochmal implementieren oder die Impl-Methode der Introspection |
| // fuer diesen Zweck konfigurierbar machen. |
| |
| // Introspection-Service holen |
| Reference< XIntrospection > xIntrospection = getIntrospection(); |
| if( !xIntrospection.is() ) |
| return xRet; |
| |
| // und unspecten |
| Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) ); |
| |
| Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny ); |
| if( !xAccess.is() ) |
| return xRet; |
| |
| // Name der addListener-Methode zusammenbasteln |
| OUString aAddListenerName; |
| OUString aListenerName( ListenerType ); |
| sal_Int32 nIndex = aListenerName.lastIndexOf( '.' ); |
| // set index to the interface name without package name |
| if( nIndex == -1 ) |
| // not found |
| nIndex = 0; |
| else |
| nIndex++; |
| if( aListenerName[nIndex] == 'X' ) |
| // erase X from the interface name |
| aListenerName = aListenerName.copy( nIndex +1 ); |
| aAddListenerName = OUString( RTL_CONSTASCII_USTRINGPARAM( "add" ) ) + aListenerName; |
| |
| // Methoden nach der passenden addListener-Methode durchsuchen |
| Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER ); |
| sal_uInt32 i, nLen = aMethodSeq.getLength(); |
| const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray(); |
| |
| for( i = 0 ; i < nLen ; i++ ) |
| { |
| // Methode ansprechen |
| const Reference< XIdlMethod >& rxMethod = pMethods[i]; |
| |
| // Ist es die richtige Methode? |
| OUString aMethName = rxMethod->getName(); |
| |
| if( aAddListenerName == aMethName ) |
| { |
| Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes(); |
| sal_uInt32 nParamCount = params.getLength(); |
| |
| Reference< XIdlClass > xListenerType; |
| if( nParamCount == 1 ) |
| xListenerType = params.getConstArray()[0]; |
| else if( nParamCount == 2 ) |
| xListenerType = params.getConstArray()[1]; |
| |
| // Adapter zum eigentlichen Listener-Typ anfordern |
| Reference< XInterface > xAdapter = createAllListenerAdapter |
| ( xInvocationAdapterFactory, xListenerType, AllListener, Helper ); |
| |
| if( !xAdapter.is() ) |
| throw CannotCreateAdapterException(); |
| xRet = Reference< XEventListener >( xAdapter, UNO_QUERY ); |
| |
| |
| // Nur der Listener als Parameter? |
| if( nParamCount == 1 ) |
| { |
| Sequence< Any > args( 1 ); |
| args.getArray()[0] <<= xAdapter; |
| try |
| { |
| rxMethod->invoke( aObjAny, args ); |
| } |
| catch( InvocationTargetException& ) |
| { |
| throw IntrospectionException(); |
| } |
| } |
| // Sonst den Zusatzparameter mit uebergeben |
| else if( nParamCount == 2 ) |
| { |
| Sequence< Any > args( 2 ); |
| Any* pAnys = args.getArray(); |
| |
| // Typ des 1. Parameters pruefen |
| Reference< XIdlClass > xParamClass = params.getConstArray()[0]; |
| if( xParamClass->getTypeClass() == TypeClass_STRING ) |
| { |
| pAnys[0] <<= AddListenerParam; |
| } |
| |
| // 2. Parameter == Listener? TODO: Pruefen! |
| pAnys[1] <<= xAdapter; |
| |
| // TODO: Konvertierung String -> ? |
| // else |
| try |
| { |
| rxMethod->invoke( aObjAny, args ); |
| } |
| catch( InvocationTargetException& ) |
| { |
| throw IntrospectionException(); |
| } |
| } |
| break; |
| // else... |
| // Alles andere wird nicht unterstuetzt |
| } |
| } |
| |
| return xRet; |
| } |
| |
| // XEventAttacher |
| Reference< XEventListener > EventAttacherImpl::attachSingleEventListener |
| ( |
| const Reference< XInterface >& xObject, |
| const Reference< XAllListener >& AllListener, |
| const Any& Helper, |
| const OUString& ListenerType, |
| const OUString& AddListenerParam, |
| const OUString& EventMethod |
| ) |
| throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException ) |
| { |
| // FilterListener anmelden |
| Reference< XAllListener > aFilterListener = (XAllListener*) |
| new FilterAllListenerImpl( this, EventMethod, AllListener ); |
| return attachListener( xObject, aFilterListener, Helper, ListenerType, AddListenerParam); |
| } |
| |
| // XEventAttacher |
| void EventAttacherImpl::removeListener |
| ( |
| const Reference< XInterface >& xObject, |
| const OUString& ListenerType, |
| const OUString& AddListenerParam, |
| const Reference< XEventListener >& aToRemoveListener |
| ) |
| throw( IllegalArgumentException, IntrospectionException, RuntimeException ) |
| { |
| if( !xObject.is() || !aToRemoveListener.is() ) |
| throw IllegalArgumentException(); |
| |
| // Listener-Klasse per Reflection besorgen |
| Reference< XIdlReflection > xReflection = getReflection(); |
| if( !xReflection.is() ) |
| throw IntrospectionException(); |
| |
| // Abmelden, dazu passende removeListener-Methode aufrufen |
| // Zunaechst ueber Introspection gehen, da die Methoden in der gleichen |
| // Weise analysiert werden koennen. Fuer bessere Performance entweder |
| // hier nochmal implementieren oder die Impl-Methode der Introspection |
| // fuer diesen Zweck konfigurierbar machen. |
| |
| // Introspection-Service holen |
| Reference< XIntrospection > xIntrospection = getIntrospection(); |
| if( !xIntrospection.is() ) |
| throw IntrospectionException(); |
| |
| // und inspecten |
| Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) ); |
| Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny ); |
| if( !xAccess.is() ) |
| throw IntrospectionException(); |
| |
| // Name der removeListener-Methode zusammenbasteln |
| OUString aRemoveListenerName; |
| OUString aListenerName( ListenerType ); |
| sal_Int32 nIndex = aListenerName.lastIndexOf( '.' ); |
| // set index to the interface name without package name |
| if( nIndex == -1 ) |
| // not found |
| nIndex = 0; |
| else |
| nIndex++; |
| if( aListenerName[nIndex] == 'X' ) |
| // erase X from the interface name |
| aListenerName = aListenerName.copy( nIndex +1 ); |
| aRemoveListenerName = OUString( RTL_CONSTASCII_USTRINGPARAM("remove") ) + aListenerName; |
| |
| // Methoden nach der passenden addListener-Methode durchsuchen |
| Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER ); |
| sal_uInt32 i, nLen = aMethodSeq.getLength(); |
| const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray(); |
| for( i = 0 ; i < nLen ; i++ ) |
| { |
| // Methode ansprechen |
| const Reference< XIdlMethod >& rxMethod = pMethods[i]; |
| |
| // Ist es die richtige Methode? |
| if( aRemoveListenerName == rxMethod->getName() ) |
| { |
| Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes(); |
| sal_uInt32 nParamCount = params.getLength(); |
| |
| // Nur der Listener als Parameter? |
| if( nParamCount == 1 ) |
| { |
| Sequence< Any > args( 1 ); |
| args.getArray()[0] <<= aToRemoveListener; |
| try |
| { |
| rxMethod->invoke( aObjAny, args ); |
| } |
| catch( InvocationTargetException& ) |
| { |
| throw IntrospectionException(); |
| } |
| } |
| // Sonst den Zusatzparameter mit uebergeben |
| else if( nParamCount == 2 ) |
| { |
| Sequence< Any > args( 2 ); |
| Any* pAnys = args.getArray(); |
| |
| // Typ des 1. Parameters pruefen |
| Reference< XIdlClass > xParamClass = params.getConstArray()[0]; |
| if( xParamClass->getTypeClass() == TypeClass_STRING ) |
| pAnys[0] <<= AddListenerParam; |
| |
| // 2. Parameter == Listener? TODO: Pruefen! |
| pAnys[1] <<= aToRemoveListener; |
| |
| // TODO: Konvertierung String -> ? |
| // else |
| try |
| { |
| rxMethod->invoke( aObjAny, args ); |
| } |
| catch( InvocationTargetException& ) |
| { |
| throw IntrospectionException(); |
| } |
| } |
| break; |
| } |
| } |
| } |
| |
| } |
| |
| extern "C" |
| { |
| //================================================================================================== |
| void SAL_CALL component_getImplementationEnvironment( |
| const sal_Char ** ppEnvTypeName, uno_Environment ** ) |
| { |
| *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; |
| } |
| //================================================================================================== |
| void * SAL_CALL component_getFactory( |
| const sal_Char * pImplName, void * pServiceManager, void * ) |
| { |
| void * pRet = 0; |
| |
| if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0) |
| { |
| Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( |
| reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), |
| OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) ), |
| ::comp_EventAttacher::EventAttacherImpl_CreateInstance, |
| ::comp_EventAttacher::EventAttacherImpl::getSupportedServiceNames_Static() ) ); |
| |
| if (xFactory.is()) |
| { |
| xFactory->acquire(); |
| pRet = xFactory.get(); |
| } |
| } |
| |
| return pRet; |
| } |
| } |
| |
| |
| |