summaryrefslogtreecommitdiff
path: root/eventattacher/source/eventattacher.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'eventattacher/source/eventattacher.cxx')
-rw-r--r--eventattacher/source/eventattacher.cxx857
1 files changed, 857 insertions, 0 deletions
diff --git a/eventattacher/source/eventattacher.cxx b/eventattacher/source/eventattacher.cxx
new file mode 100644
index 000000000000..73fcb296c190
--- /dev/null
+++ b/eventattacher/source/eventattacher.cxx
@@ -0,0 +1,857 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#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 ::rtl::OUString;
+
+
+#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;
+
+ // Save Services
+ 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 helper methods ***
+Reference< XIntrospection > EventAttacherImpl::getIntrospection() throw( Exception )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+ if( !m_xIntrospection.is() )
+ {
+ Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.Introspection")) ) );
+ m_xIntrospection = Reference< XIntrospection >( xIFace, UNO_QUERY );
+ }
+ return m_xIntrospection;
+}
+
+//*************************************************************************
+//*** Private helper methods ***
+Reference< XIdlReflection > EventAttacherImpl::getReflection() throw( Exception )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+ if( !m_xReflection.is() )
+ {
+ Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) ) );
+ m_xReflection = Reference< XIdlReflection >( xIFace, UNO_QUERY);
+ }
+ return m_xReflection;
+}
+
+//*************************************************************************
+//*** Private helper methods ***
+Reference< XInvocationAdapterFactory > EventAttacherImpl::getInvocationAdapterService() throw( Exception )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+ if( !m_xInvocationAdapterFactory.is() )
+ {
+ Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.InvocationAdapterFactory")) ) );
+ m_xInvocationAdapterFactory = Reference< XInvocationAdapterFactory >( xIFace, UNO_QUERY );
+ }
+ return m_xInvocationAdapterFactory;
+}
+
+
+//*************************************************************************
+//*** Private helper methods ***
+Reference< XTypeConverter > EventAttacherImpl::getConverter() throw( Exception )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+ if( !m_xConverter.is() )
+ {
+ Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter")) ) );
+ m_xConverter = Reference< XTypeConverter >( xIFace, UNO_QUERY );
+ }
+ return m_xConverter;
+}
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+// Implementation of an EventAttacher-related AllListeners, which brings
+// a few Events to a general AllListener
+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 )
+{
+ 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;
+
+ 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;
+
+ Reference< XInvocationAdapterFactory > xInvocationAdapterFactory = getInvocationAdapterService();
+ if( !xInvocationAdapterFactory.is() )
+ throw ServiceNotRegisteredException();
+
+ Reference< XIdlReflection > xReflection = getReflection();
+ if( !xReflection.is() )
+ throw ServiceNotRegisteredException();
+
+ // Sign in, Call the fitting addListener method
+ // First Introspection, as the Methods can be analyzed in the same way
+ // For better perfomance it is implemented here again or make the Impl-Method
+ // of the Introspection configurable for this purpose.
+ Reference< XIntrospection > xIntrospection = getIntrospection();
+ if( !xIntrospection.is() )
+ return xRet;
+
+ // Inspect Introspection
+ Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
+
+ Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
+ if( !xAccess.is() )
+ return xRet;
+
+ // Construct the name of the addListener-Method.
+ 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;
+
+ // Send Methods to the correct addListener-Method
+ 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++ )
+ {
+ const Reference< XIdlMethod >& rxMethod = pMethods[i];
+
+ // Is it the correct method?
+ 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];
+
+ // Request Adapter for the actual Listener type
+ Reference< XInterface > xAdapter = createAllListenerAdapter
+ ( xInvocationAdapterFactory, xListenerType, AllListener, Helper );
+
+ if( !xAdapter.is() )
+ throw CannotCreateAdapterException();
+ xRet = Reference< XEventListener >( xAdapter, UNO_QUERY );
+
+
+ // Just the Listener as parameter?
+ if( nParamCount == 1 )
+ {
+ Sequence< Any > args( 1 );
+ args.getArray()[0] <<= xAdapter;
+ try
+ {
+ rxMethod->invoke( aObjAny, args );
+ }
+ catch( InvocationTargetException& )
+ {
+ throw IntrospectionException();
+ }
+ }
+ // Else, pass the other parameter now
+ else if( nParamCount == 2 )
+ {
+ Sequence< Any > args( 2 );
+ Any* pAnys = args.getArray();
+
+ // Check the type of the 1st parameter
+ Reference< XIdlClass > xParamClass = params.getConstArray()[0];
+ if( xParamClass->getTypeClass() == TypeClass_STRING )
+ {
+ pAnys[0] <<= AddListenerParam;
+ }
+
+ // 2nd Parameter == Listener? TODO: Test!
+ pAnys[1] <<= xAdapter;
+
+ // TODO: Convert String -> ?
+ // else
+ try
+ {
+ rxMethod->invoke( aObjAny, args );
+ }
+ catch( InvocationTargetException& )
+ {
+ throw IntrospectionException();
+ }
+ }
+ break;
+ // else...
+ // Anything else is not supported
+ }
+ }
+
+ 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 )
+{
+ // Subscribe FilterListener
+ 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();
+
+ Reference< XIdlReflection > xReflection = getReflection();
+ if( !xReflection.is() )
+ throw IntrospectionException();
+
+ // Sign off, Call the fitting removeListener method
+ // First Introspection, as the Methods can be analyzed in the same way
+ // For better perfomance it is implemented here again or make the Impl-Method
+ // of the Introspection configurable for this purpose.
+ Reference< XIntrospection > xIntrospection = getIntrospection();
+ if( !xIntrospection.is() )
+ throw IntrospectionException();
+
+ //Inspect Introspection
+ Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
+ Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
+ if( !xAccess.is() )
+ throw IntrospectionException();
+
+ // Create name of the removeListener-Method
+ 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;
+
+ // Search methods for the correct removeListener method
+ 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++ )
+ {
+ // Call Methode
+ const Reference< XIdlMethod >& rxMethod = pMethods[i];
+
+ // Is it the right method?
+ if( aRemoveListenerName == rxMethod->getName() )
+ {
+ Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes();
+ sal_uInt32 nParamCount = params.getLength();
+
+ // Just the Listener as parameter?
+ if( nParamCount == 1 )
+ {
+ Sequence< Any > args( 1 );
+ args.getArray()[0] <<= aToRemoveListener;
+ try
+ {
+ rxMethod->invoke( aObjAny, args );
+ }
+ catch( InvocationTargetException& )
+ {
+ throw IntrospectionException();
+ }
+ }
+ // Else pass the other parameter
+ else if( nParamCount == 2 )
+ {
+ Sequence< Any > args( 2 );
+ Any* pAnys = args.getArray();
+
+ // Check the type of the 1st parameter
+ Reference< XIdlClass > xParamClass = params.getConstArray()[0];
+ if( xParamClass->getTypeClass() == TypeClass_STRING )
+ pAnys[0] <<= AddListenerParam;
+
+ // 2nd parameter == Listener? TODO: Test!
+ pAnys[1] <<= aToRemoveListener;
+
+ // TODO: Convert 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;
+}
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */