1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eventattacher.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include <osl/diagnose.h>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
32 #include <com/sun/star/lang/XInitialization.hpp>
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35 #include <com/sun/star/registry/XRegistryKey.hpp>
36 #include <com/sun/star/beans/XIntrospection.hpp>
37 #include <com/sun/star/beans/MethodConcept.hpp>
38 #include <com/sun/star/script/XEventAttacher.hpp>
39 #include <com/sun/star/script/XTypeConverter.hpp>
40 #include <com/sun/star/script/XAllListener.hpp>
41 #include <com/sun/star/script/XInvocationAdapterFactory.hpp>
42 #include <com/sun/star/reflection/XIdlReflection.hpp>
44 // InvocationToAllListenerMapper
45 #include <com/sun/star/script/XInvocation.hpp>
46 #include <cppuhelper/weak.hxx>
47 #include <cppuhelper/factory.hxx>
48 #include <cppuhelper/implbase1.hxx>
49 #include <cppuhelper/implbase3.hxx>
51 using namespace com::sun::star::uno
;
52 using namespace com::sun::star::registry
;
53 using namespace com::sun::star::lang
;
54 using namespace com::sun::star::beans
;
55 using namespace com::sun::star::script
;
56 using namespace com::sun::star::reflection
;
62 #define SERVICENAME "com.sun.star.script.EventAttacher"
63 #define IMPLNAME "com.sun.star.comp.EventAttacher"
65 namespace comp_EventAttacher
{
67 //*************************************************************************
68 // class InvocationToAllListenerMapper
69 // helper class to map XInvocation to XAllListener
70 //*************************************************************************
71 class InvocationToAllListenerMapper
: public WeakImplHelper1
< XInvocation
>
74 InvocationToAllListenerMapper( const Reference
< XIdlClass
>& ListenerType
,
75 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
);
78 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection(void) throw( RuntimeException
);
79 virtual Any SAL_CALL
invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
, Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
)
80 throw( IllegalArgumentException
, CannotConvertException
, InvocationTargetException
, RuntimeException
);
81 virtual void SAL_CALL
setValue(const OUString
& PropertyName
, const Any
& Value
)
82 throw( UnknownPropertyException
, CannotConvertException
, InvocationTargetException
, RuntimeException
);
83 virtual Any SAL_CALL
getValue(const OUString
& PropertyName
) throw( UnknownPropertyException
, RuntimeException
);
84 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
) throw( RuntimeException
);
85 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
) throw( RuntimeException
);
88 Reference
< XIdlReflection
> m_xCoreReflection
;
89 Reference
< XAllListener
> m_xAllListener
;
90 Reference
< XIdlClass
> m_xListenerType
;
95 // Function to replace AllListenerAdapterService::createAllListerAdapter
96 Reference
< XInterface
> createAllListenerAdapter
98 const Reference
< XInvocationAdapterFactory
>& xInvocationAdapterFactory
,
99 const Reference
< XIdlClass
>& xListenerType
,
100 const Reference
< XAllListener
>& xListener
,
104 Reference
< XInterface
> xAdapter
;
105 if( xInvocationAdapterFactory
.is() && xListenerType
.is() && xListener
.is() )
107 Reference
< XInvocation
> xInvocationToAllListenerMapper
=
108 (XInvocation
*)new InvocationToAllListenerMapper( xListenerType
, xListener
, Helper
);
109 Type
aListenerType( xListenerType
->getTypeClass(), xListenerType
->getName());
110 xAdapter
= xInvocationAdapterFactory
->createAdapter( xInvocationToAllListenerMapper
, aListenerType
);
116 //--------------------------------------------------------------------------------------------------
117 // InvocationToAllListenerMapper
118 InvocationToAllListenerMapper::InvocationToAllListenerMapper
119 ( const Reference
< XIdlClass
>& ListenerType
, const Reference
< XAllListener
>& AllListener
, const Any
& Helper
)
120 : m_xAllListener( AllListener
)
121 , m_xListenerType( ListenerType
)
126 //*************************************************************************
127 Reference
< XIntrospectionAccess
> SAL_CALL
InvocationToAllListenerMapper::getIntrospection(void)
128 throw( RuntimeException
)
130 return Reference
< XIntrospectionAccess
>();
133 //*************************************************************************
134 Any SAL_CALL
InvocationToAllListenerMapper::invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
,
135 Sequence
< sal_Int16
>& , Sequence
< Any
>& )
136 throw( IllegalArgumentException
, CannotConvertException
,
137 InvocationTargetException
, RuntimeException
)
141 // Check if to firing or approveFiring has to be called
142 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( FunctionName
);
143 sal_Bool bApproveFiring
= sal_False
;
146 Reference
< XIdlClass
> xReturnType
= xMethod
->getReturnType();
147 Sequence
< Reference
< XIdlClass
> > aExceptionSeq
= xMethod
->getExceptionTypes();
148 if( ( xReturnType
.is() && xReturnType
->getTypeClass() != TypeClass_VOID
) ||
149 aExceptionSeq
.getLength() > 0 )
151 bApproveFiring
= sal_True
;
155 Sequence
< ParamInfo
> aParamSeq
= xMethod
->getParameterInfos();
156 sal_uInt32 nParamCount
= aParamSeq
.getLength();
157 if( nParamCount
> 1 )
159 const ParamInfo
* pInfos
= aParamSeq
.getConstArray();
160 for( sal_uInt32 i
= 0 ; i
< nParamCount
; i
++ )
162 if( pInfos
[ i
].aMode
!= ParamMode_IN
)
164 bApproveFiring
= sal_True
;
171 AllEventObject aAllEvent
;
172 aAllEvent
.Source
= (OWeakObject
*) this;
173 aAllEvent
.Helper
= m_Helper
;
174 aAllEvent
.ListenerType
= Type(m_xListenerType
->getTypeClass(), m_xListenerType
->getName());
175 aAllEvent
.MethodName
= FunctionName
;
176 aAllEvent
.Arguments
= Params
;
178 aRet
= m_xAllListener
->approveFiring( aAllEvent
);
180 m_xAllListener
->firing( aAllEvent
);
184 //*************************************************************************
185 void SAL_CALL
InvocationToAllListenerMapper::setValue(const OUString
& , const Any
& )
186 throw( UnknownPropertyException
, CannotConvertException
,
187 InvocationTargetException
, RuntimeException
)
191 //*************************************************************************
192 Any SAL_CALL
InvocationToAllListenerMapper::getValue(const OUString
& )
193 throw( UnknownPropertyException
, RuntimeException
)
198 //*************************************************************************
199 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasMethod(const OUString
& Name
)
200 throw( RuntimeException
)
202 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( Name
);
206 //*************************************************************************
207 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasProperty(const OUString
& Name
)
208 throw( RuntimeException
)
210 Reference
< XIdlField
> xField
= m_xListenerType
->getField( Name
);
214 //*************************************************************************
215 // class EventAttacherImpl
216 // represents an implementation of the EventAttacher service
217 //*************************************************************************
218 class EventAttacherImpl
: public WeakImplHelper3
< XEventAttacher
, XInitialization
, XServiceInfo
>
221 EventAttacherImpl( const Reference
< XMultiServiceFactory
>& );
222 ~EventAttacherImpl();
225 virtual OUString SAL_CALL
getImplementationName( ) throw(RuntimeException
);
226 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) throw(RuntimeException
);
227 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) throw(RuntimeException
);
228 static OUString SAL_CALL
getImplementationName_Static( );
229 static Sequence
< OUString
> SAL_CALL
getSupportedServiceNames_Static( );
232 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
)
233 throw( Exception
, RuntimeException
);
235 // Methoden von XEventAttacher
236 virtual Reference
< XEventListener
> SAL_CALL
attachListener(const Reference
< XInterface
>& xObject
,
237 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
,
238 const OUString
& ListenerType
, const OUString
& AddListenerParam
)
239 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
);
240 virtual Reference
< XEventListener
> SAL_CALL
attachSingleEventListener(const Reference
< XInterface
>& xObject
,
241 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
,
242 const OUString
& ListenerType
, const OUString
& AddListenerParam
,
243 const OUString
& EventMethod
)
244 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
);
245 virtual void SAL_CALL
removeListener(const Reference
< XInterface
>& xObject
,
246 const OUString
& ListenerType
, const OUString
& AddListenerParam
,
247 const Reference
< XEventListener
>& aToRemoveListener
)
248 throw( IllegalArgumentException
, IntrospectionException
, RuntimeException
);
250 // used by FilterAllListener_Impl
251 Reference
< XTypeConverter
> getConverter() throw( Exception
);
253 friend class FilterAllListenerImpl
;
256 Reference
< XMultiServiceFactory
> m_xSMgr
;
259 Reference
< XIntrospection
> m_xIntrospection
;
260 Reference
< XIdlReflection
> m_xReflection
;
261 Reference
< XTypeConverter
> m_xConverter
;
262 Reference
< XInvocationAdapterFactory
> m_xInvocationAdapterFactory
;
265 Reference
< XIntrospection
> getIntrospection() throw( Exception
);
266 Reference
< XIdlReflection
> getReflection() throw( Exception
);
267 Reference
< XInvocationAdapterFactory
> getInvocationAdapterService() throw( Exception
);
271 //*************************************************************************
272 EventAttacherImpl::EventAttacherImpl( const Reference
< XMultiServiceFactory
>& rSMgr
)
277 //*************************************************************************
278 EventAttacherImpl::~EventAttacherImpl()
282 //*************************************************************************
283 Reference
< XInterface
> SAL_CALL
EventAttacherImpl_CreateInstance( const Reference
< XMultiServiceFactory
>& rSMgr
) throw( Exception
)
285 Reference
< XInterface
> xRet
;
286 XEventAttacher
*pEventAttacher
= (XEventAttacher
*) new EventAttacherImpl(rSMgr
);
290 xRet
= Reference
<XInterface
>::query(pEventAttacher
);
296 //*************************************************************************
297 OUString SAL_CALL
EventAttacherImpl::getImplementationName( )
298 throw(RuntimeException
)
300 return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME
) );
303 //*************************************************************************
304 sal_Bool SAL_CALL
EventAttacherImpl::supportsService( const OUString
& ServiceName
)
305 throw(RuntimeException
)
307 Sequence
< OUString
> aSNL
= getSupportedServiceNames();
308 const OUString
* pArray
= aSNL
.getArray();
309 for( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
310 if( pArray
[i
] == ServiceName
)
315 //*************************************************************************
316 Sequence
<OUString
> SAL_CALL
EventAttacherImpl::getSupportedServiceNames( )
317 throw(RuntimeException
)
319 return getSupportedServiceNames_Static();
322 //*************************************************************************
323 Sequence
<OUString
> SAL_CALL
EventAttacherImpl::getSupportedServiceNames_Static( )
325 OUString
aStr( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME
) );
326 return Sequence
< OUString
>( &aStr
, 1 );
329 //*************************************************************************
330 void SAL_CALL
EventAttacherImpl::initialize(const Sequence
< Any
>& Arguments
) throw( Exception
, RuntimeException
)
332 // get services from the argument list
333 const Any
* pArray
= Arguments
.getConstArray();
334 for( sal_Int32 i
= 0; i
< Arguments
.getLength(); i
++ )
336 if( pArray
[i
].getValueType().getTypeClass() != TypeClass_INTERFACE
)
337 throw IllegalArgumentException();
339 // InvocationAdapter service ?
340 Reference
< XInvocationAdapterFactory
> xALAS
;
344 Guard
< Mutex
> aGuard( m_aMutex
);
345 m_xInvocationAdapterFactory
= xALAS
;
347 // Introspection service ?
348 Reference
< XIntrospection
> xI
;
352 Guard
< Mutex
> aGuard( m_aMutex
);
353 m_xIntrospection
= xI
;
355 // Reflection service ?
356 Reference
< XIdlReflection
> xIdlR
;
360 Guard
< Mutex
> aGuard( m_aMutex
);
361 m_xReflection
= xIdlR
;
363 // Converter Service ?
364 Reference
< XTypeConverter
> xC
;
368 Guard
< Mutex
> aGuard( m_aMutex
);
372 // no right interface
373 if( !xALAS
.is() && !xI
.is() && !xIdlR
.is() && !xC
.is() )
374 throw IllegalArgumentException();
378 //*************************************************************************
379 //*** Private Hilfs-Methoden ***
380 Reference
< XIntrospection
> EventAttacherImpl::getIntrospection() throw( Exception
)
382 Guard
< Mutex
> aGuard( m_aMutex
);
383 // Haben wir den Service schon? Sonst anlegen
384 if( !m_xIntrospection
.is() )
386 Reference
< XInterface
> xIFace( m_xSMgr
->createInstance( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection") ) );
387 m_xIntrospection
= Reference
< XIntrospection
>( xIFace
, UNO_QUERY
);
389 return m_xIntrospection
;
392 //*************************************************************************
393 //*** Private Hilfs-Methoden ***
394 Reference
< XIdlReflection
> EventAttacherImpl::getReflection() throw( Exception
)
396 Guard
< Mutex
> aGuard( m_aMutex
);
397 // Haben wir den Service schon? Sonst anlegen
398 if( !m_xReflection
.is() )
400 Reference
< XInterface
> xIFace( m_xSMgr
->createInstance( rtl::OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ) );
401 m_xReflection
= Reference
< XIdlReflection
>( xIFace
, UNO_QUERY
);
403 return m_xReflection
;
406 //*************************************************************************
407 //*** Private Hilfs-Methoden ***
408 Reference
< XInvocationAdapterFactory
> EventAttacherImpl::getInvocationAdapterService() throw( Exception
)
410 Guard
< Mutex
> aGuard( m_aMutex
);
411 // Haben wir den Service schon? Sonst anlegen
412 if( !m_xInvocationAdapterFactory
.is() )
414 Reference
< XInterface
> xIFace( m_xSMgr
->createInstance( rtl::OUString::createFromAscii("com.sun.star.script.InvocationAdapterFactory") ) );
415 m_xInvocationAdapterFactory
= Reference
< XInvocationAdapterFactory
>( xIFace
, UNO_QUERY
);
417 return m_xInvocationAdapterFactory
;
421 //*************************************************************************
422 //*** Private Hilfs-Methoden ***
423 Reference
< XTypeConverter
> EventAttacherImpl::getConverter() throw( Exception
)
425 Guard
< Mutex
> aGuard( m_aMutex
);
426 // Haben wir den Service schon? Sonst anlegen
427 if( !m_xConverter
.is() )
429 Reference
< XInterface
> xIFace( m_xSMgr
->createInstance( rtl::OUString::createFromAscii("com.sun.star.script.Converter") ) );
430 m_xConverter
= Reference
< XTypeConverter
>( xIFace
, UNO_QUERY
);
435 //------------------------------------------------------------------------
436 //------------------------------------------------------------------------
437 //------------------------------------------------------------------------
438 // Implementation eines EventAttacher-bezogenen AllListeners, der
439 // nur einzelne Events an einen allgemeinen AllListener weiterleitet
440 class FilterAllListenerImpl
: public WeakImplHelper1
< XAllListener
>
443 FilterAllListenerImpl( EventAttacherImpl
* pEA_
, const OUString
& EventMethod_
,
444 const Reference
< XAllListener
>& AllListener_
);
447 virtual void SAL_CALL
firing(const AllEventObject
& Event
) throw( RuntimeException
);
448 virtual Any SAL_CALL
approveFiring(const AllEventObject
& Event
) throw( InvocationTargetException
, RuntimeException
);
451 virtual void SAL_CALL
disposing(const EventObject
& Source
) throw( RuntimeException
);
455 void convertToEventReturn( Any
& rRet
, const Type
& rRetType
)
456 throw( CannotConvertException
);
458 EventAttacherImpl
* m_pEA
;
459 Reference
< XInterface
> m_xEAHold
;
460 OUString m_EventMethod
;
461 Reference
< XAllListener
> m_AllListener
;
464 //*************************************************************************
465 FilterAllListenerImpl::FilterAllListenerImpl( EventAttacherImpl
* pEA_
, const OUString
& EventMethod_
,
466 const Reference
< XAllListener
>& AllListener_
)
469 , m_EventMethod( EventMethod_
)
470 , m_AllListener( AllListener_
)
474 //*************************************************************************
475 void SAL_CALL
FilterAllListenerImpl::firing(const AllEventObject
& Event
)
476 throw( RuntimeException
)
478 // Nur durchreichen, wenn es die richtige Methode ist
479 if( Event
.MethodName
== m_EventMethod
&& m_AllListener
.is() )
480 m_AllListener
->firing( Event
);
483 //*************************************************************************
484 // Convert to the standard event return
485 void FilterAllListenerImpl::convertToEventReturn( Any
& rRet
, const Type
& rRetType
)
486 throw( CannotConvertException
)
488 // no return value? Set to the specified values
489 if( rRet
.getValueType().getTypeClass() == TypeClass_VOID
)
491 switch( rRetType
.getTypeClass() )
493 case TypeClass_INTERFACE
:
495 rRet
<<= Reference
< XInterface
>();
499 case TypeClass_BOOLEAN
:
503 case TypeClass_STRING
:
507 case TypeClass_FLOAT
: rRet
<<= float(0); break;
508 case TypeClass_DOUBLE
: rRet
<<= double(0.0); break;
509 case TypeClass_BYTE
: rRet
<<= sal_uInt8( 0 ); break;
510 case TypeClass_SHORT
: rRet
<<= sal_Int16( 0 ); break;
511 case TypeClass_LONG
: rRet
<<= sal_Int32( 0 ); break;
512 case TypeClass_UNSIGNED_SHORT
: rRet
<<= sal_uInt16( 0 ); break;
513 case TypeClass_UNSIGNED_LONG
: rRet
<<= sal_uInt32( 0 ); break;
518 else if( !rRet
.getValueType().equals( rRetType
) )
520 Reference
< XTypeConverter
> xConverter
= m_pEA
->getConverter();
521 if( xConverter
.is() )
522 rRet
= xConverter
->convertTo( rRet
, rRetType
);
524 throw CannotConvertException(); // TODO TypeConversionException
528 //*************************************************************************
529 Any SAL_CALL
FilterAllListenerImpl::approveFiring( const AllEventObject
& Event
)
530 throw( InvocationTargetException
, RuntimeException
)
534 // Nur durchreichen, wenn es die richtige Methode ist
535 if( Event
.MethodName
== m_EventMethod
&& m_AllListener
.is() )
536 aRet
= m_AllListener
->approveFiring( Event
);
539 // Convert to the standard event return
542 Reference
< XIdlClass
> xListenerType
= m_pEA
->getReflection()->
543 forName( Event
.ListenerType
.getTypeName() );
544 Reference
< XIdlMethod
> xMeth
= xListenerType
->getMethod( Event
.MethodName
);
547 Reference
< XIdlClass
> xRetType
= xMeth
->getReturnType();
548 Type
aRetType( xRetType
->getTypeClass(), xRetType
->getName() );
549 convertToEventReturn( aRet
, aRetType
);
552 catch( CannotConvertException
& e
)
554 throw InvocationTargetException( OUString(), Reference
< XInterface
>(), Any(&e
, ::getCppuType( (CannotConvertException
*)0)) );
560 //*************************************************************************
561 void FilterAllListenerImpl::disposing(const EventObject
& )
562 throw( RuntimeException
)
568 //*************************************************************************
569 Reference
< XEventListener
> EventAttacherImpl::attachListener
571 const Reference
< XInterface
>& xObject
,
572 const Reference
< XAllListener
>& AllListener
,
574 const OUString
& ListenerType
,
575 const OUString
& AddListenerParam
577 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
)
579 if( !xObject
.is() || !AllListener
.is() )
580 throw IllegalArgumentException();
582 Reference
< XEventListener
> xRet
= NULL
;
584 // InvocationAdapterService holen
585 Reference
< XInvocationAdapterFactory
> xInvocationAdapterFactory
= getInvocationAdapterService();
586 if( !xInvocationAdapterFactory
.is() )
587 throw ServiceNotRegisteredException();
589 // Listener-Klasse per Reflection besorgen
590 Reference
< XIdlReflection
> xReflection
= getReflection();
591 if( !xReflection
.is() )
592 throw ServiceNotRegisteredException();
594 // Anmelden, dazu passende addListener-Methode aufrufen
595 // Zunaechst ueber Introspection gehen, da die Methoden in der gleichen
596 // Weise analysiert werden koennen. Fuer bessere Performance entweder
597 // hier nochmal implementieren oder die Impl-Methode der Introspection
598 // fuer diesen Zweck konfigurierbar machen.
600 // Introspection-Service holen
601 Reference
< XIntrospection
> xIntrospection
= getIntrospection();
602 if( !xIntrospection
.is() )
606 Any
aObjAny( &xObject
, ::getCppuType( (const Reference
< XInterface
> *)0) );
608 Reference
< XIntrospectionAccess
> xAccess
= xIntrospection
->inspect( aObjAny
);
612 // Name der addListener-Methode zusammenbasteln
613 OUString aAddListenerName
;
614 OUString
aListenerName( ListenerType
);
615 sal_Int32 nIndex
= aListenerName
.lastIndexOf( '.' );
616 // set index to the interface name without package name
622 if( aListenerName
[nIndex
] == 'X' )
623 // erase X from the interface name
624 aListenerName
= aListenerName
.copy( nIndex
+1 );
625 aAddListenerName
= OUString( RTL_CONSTASCII_USTRINGPARAM( "add" ) ) + aListenerName
;
627 // Methoden nach der passenden addListener-Methode durchsuchen
628 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( MethodConcept::LISTENER
);
629 sal_uInt32 i
, nLen
= aMethodSeq
.getLength();
630 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
632 for( i
= 0 ; i
< nLen
; i
++ )
634 // Methode ansprechen
635 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
637 // Ist es die richtige Methode?
638 OUString aMethName
= rxMethod
->getName();
640 if( aAddListenerName
== aMethName
)
642 Sequence
< Reference
< XIdlClass
> > params
= rxMethod
->getParameterTypes();
643 sal_uInt32 nParamCount
= params
.getLength();
645 Reference
< XIdlClass
> xListenerType
;
646 if( nParamCount
== 1 )
647 xListenerType
= params
.getConstArray()[0];
648 else if( nParamCount
== 2 )
649 xListenerType
= params
.getConstArray()[1];
651 // Adapter zum eigentlichen Listener-Typ anfordern
652 Reference
< XInterface
> xAdapter
= createAllListenerAdapter
653 ( xInvocationAdapterFactory
, xListenerType
, AllListener
, Helper
);
656 throw CannotCreateAdapterException();
657 xRet
= Reference
< XEventListener
>( xAdapter
, UNO_QUERY
);
660 // Nur der Listener als Parameter?
661 if( nParamCount
== 1 )
663 Sequence
< Any
> args( 1 );
664 args
.getArray()[0] <<= xAdapter
;
667 rxMethod
->invoke( aObjAny
, args
);
669 catch( InvocationTargetException
& )
671 throw IntrospectionException();
674 // Sonst den Zusatzparameter mit uebergeben
675 else if( nParamCount
== 2 )
677 Sequence
< Any
> args( 2 );
678 Any
* pAnys
= args
.getArray();
680 // Typ des 1. Parameters pruefen
681 Reference
< XIdlClass
> xParamClass
= params
.getConstArray()[0];
682 if( xParamClass
->getTypeClass() == TypeClass_STRING
)
684 pAnys
[0] <<= AddListenerParam
;
687 // 2. Parameter == Listener? TODO: Pruefen!
688 pAnys
[1] <<= xAdapter
;
690 // TODO: Konvertierung String -> ?
694 rxMethod
->invoke( aObjAny
, args
);
696 catch( InvocationTargetException
& )
698 throw IntrospectionException();
703 // Alles andere wird nicht unterstuetzt
711 Reference
< XEventListener
> EventAttacherImpl::attachSingleEventListener
713 const Reference
< XInterface
>& xObject
,
714 const Reference
< XAllListener
>& AllListener
,
716 const OUString
& ListenerType
,
717 const OUString
& AddListenerParam
,
718 const OUString
& EventMethod
720 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
)
722 // FilterListener anmelden
723 Reference
< XAllListener
> aFilterListener
= (XAllListener
*)
724 new FilterAllListenerImpl( this, EventMethod
, AllListener
);
725 return attachListener( xObject
, aFilterListener
, Helper
, ListenerType
, AddListenerParam
);
729 void EventAttacherImpl::removeListener
731 const Reference
< XInterface
>& xObject
,
732 const OUString
& ListenerType
,
733 const OUString
& AddListenerParam
,
734 const Reference
< XEventListener
>& aToRemoveListener
736 throw( IllegalArgumentException
, IntrospectionException
, RuntimeException
)
738 if( !xObject
.is() || !aToRemoveListener
.is() )
739 throw IllegalArgumentException();
741 // Listener-Klasse per Reflection besorgen
742 Reference
< XIdlReflection
> xReflection
= getReflection();
743 if( !xReflection
.is() )
744 throw IntrospectionException();
746 // Abmelden, dazu passende removeListener-Methode aufrufen
747 // Zunaechst ueber Introspection gehen, da die Methoden in der gleichen
748 // Weise analysiert werden koennen. Fuer bessere Performance entweder
749 // hier nochmal implementieren oder die Impl-Methode der Introspection
750 // fuer diesen Zweck konfigurierbar machen.
752 // Introspection-Service holen
753 Reference
< XIntrospection
> xIntrospection
= getIntrospection();
754 if( !xIntrospection
.is() )
755 throw IntrospectionException();
758 Any
aObjAny( &xObject
, ::getCppuType( (const Reference
< XInterface
> *)0) );
759 Reference
< XIntrospectionAccess
> xAccess
= xIntrospection
->inspect( aObjAny
);
761 throw IntrospectionException();
763 // Name der removeListener-Methode zusammenbasteln
764 OUString aRemoveListenerName
;
765 OUString
aListenerName( ListenerType
);
766 sal_Int32 nIndex
= aListenerName
.lastIndexOf( '.' );
767 // set index to the interface name without package name
773 if( aListenerName
[nIndex
] == 'X' )
774 // erase X from the interface name
775 aListenerName
= aListenerName
.copy( nIndex
+1 );
776 aRemoveListenerName
= OUString( RTL_CONSTASCII_USTRINGPARAM("remove") ) + aListenerName
;
778 // Methoden nach der passenden addListener-Methode durchsuchen
779 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( MethodConcept::LISTENER
);
780 sal_uInt32 i
, nLen
= aMethodSeq
.getLength();
781 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
782 for( i
= 0 ; i
< nLen
; i
++ )
784 // Methode ansprechen
785 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
787 // Ist es die richtige Methode?
788 if( aRemoveListenerName
== rxMethod
->getName() )
790 Sequence
< Reference
< XIdlClass
> > params
= rxMethod
->getParameterTypes();
791 sal_uInt32 nParamCount
= params
.getLength();
793 // Nur der Listener als Parameter?
794 if( nParamCount
== 1 )
796 Sequence
< Any
> args( 1 );
797 args
.getArray()[0] <<= aToRemoveListener
;
800 rxMethod
->invoke( aObjAny
, args
);
802 catch( InvocationTargetException
& )
804 throw IntrospectionException();
807 // Sonst den Zusatzparameter mit uebergeben
808 else if( nParamCount
== 2 )
810 Sequence
< Any
> args( 2 );
811 Any
* pAnys
= args
.getArray();
813 // Typ des 1. Parameters pruefen
814 Reference
< XIdlClass
> xParamClass
= params
.getConstArray()[0];
815 if( xParamClass
->getTypeClass() == TypeClass_STRING
)
816 pAnys
[0] <<= AddListenerParam
;
818 // 2. Parameter == Listener? TODO: Pruefen!
819 pAnys
[1] <<= aToRemoveListener
;
821 // TODO: Konvertierung String -> ?
825 rxMethod
->invoke( aObjAny
, args
);
827 catch( InvocationTargetException
& )
829 throw IntrospectionException();
841 //==================================================================================================
842 void SAL_CALL
component_getImplementationEnvironment(
843 const sal_Char
** ppEnvTypeName
, uno_Environment
** )
845 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
847 //==================================================================================================
848 sal_Bool SAL_CALL
component_writeInfo(
849 void * , void * pRegistryKey
)
856 Reference
< XRegistryKey
> xNewKey(
857 reinterpret_cast< XRegistryKey
* >( pRegistryKey
)->createKey(
858 OUString( RTL_CONSTASCII_USTRINGPARAM( "/" IMPLNAME
"/UNO/SERVICES") )));
860 Sequence
< OUString
> aSNL
861 ( ::comp_EventAttacher::EventAttacherImpl::getSupportedServiceNames_Static() );
862 const OUString
* pArray
= aSNL
.getConstArray();
863 for ( sal_Int32 nPos
= aSNL
.getLength(); nPos
--; )
864 xNewKey
->createKey( pArray
[nPos
] );
868 catch (InvalidRegistryException
&)
870 OSL_ENSURE( sal_False
, "### InvalidRegistryException!" );
875 //==================================================================================================
876 void * SAL_CALL
component_getFactory(
877 const sal_Char
* pImplName
, void * pServiceManager
, void * )
881 if (pServiceManager
&& rtl_str_compare( pImplName
, IMPLNAME
) == 0)
883 Reference
< XSingleServiceFactory
> xFactory( createOneInstanceFactory(
884 reinterpret_cast< XMultiServiceFactory
* >( pServiceManager
),
885 OUString( RTL_CONSTASCII_USTRINGPARAM( pImplName
) ),
886 ::comp_EventAttacher::EventAttacherImpl_CreateInstance
,
887 ::comp_EventAttacher::EventAttacherImpl::getSupportedServiceNames_Static() ) );
892 pRet
= xFactory
.get();