1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
28 #include <osl/diagnose.h>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/lang/XInitialization.hpp>
31 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
33 #include <com/sun/star/registry/XRegistryKey.hpp>
34 #include <com/sun/star/beans/XIntrospection.hpp>
35 #include <com/sun/star/beans/MethodConcept.hpp>
36 #include <com/sun/star/script/XEventAttacher2.hpp>
37 #include <com/sun/star/script/XTypeConverter.hpp>
38 #include <com/sun/star/script/XAllListener.hpp>
39 #include <com/sun/star/script/XInvocationAdapterFactory.hpp>
40 #include <com/sun/star/reflection/XIdlReflection.hpp>
42 // InvocationToAllListenerMapper
43 #include <com/sun/star/script/XInvocation.hpp>
44 #include <cppuhelper/weak.hxx>
45 #include <cppuhelper/factory.hxx>
46 #include <cppuhelper/implbase1.hxx>
47 #include <cppuhelper/implbase3.hxx>
49 using namespace com::sun::star::uno
;
50 using namespace com::sun::star::registry
;
51 using namespace com::sun::star::lang
;
52 using namespace com::sun::star::beans
;
53 using namespace com::sun::star::script
;
54 using namespace com::sun::star::reflection
;
58 using ::rtl::OUString
;
61 #define SERVICENAME "com.sun.star.script.EventAttacher"
62 #define IMPLNAME "com.sun.star.comp.EventAttacher"
64 namespace comp_EventAttacher
{
66 //*************************************************************************
67 // class InvocationToAllListenerMapper
68 // helper class to map XInvocation to XAllListener
69 //*************************************************************************
70 class InvocationToAllListenerMapper
: public WeakImplHelper1
< XInvocation
>
73 InvocationToAllListenerMapper( const Reference
< XIdlClass
>& ListenerType
,
74 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
);
77 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection(void) throw( RuntimeException
);
78 virtual Any SAL_CALL
invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
, Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
)
79 throw( IllegalArgumentException
, CannotConvertException
, InvocationTargetException
, RuntimeException
);
80 virtual void SAL_CALL
setValue(const OUString
& PropertyName
, const Any
& Value
)
81 throw( UnknownPropertyException
, CannotConvertException
, InvocationTargetException
, RuntimeException
);
82 virtual Any SAL_CALL
getValue(const OUString
& PropertyName
) throw( UnknownPropertyException
, RuntimeException
);
83 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
) throw( RuntimeException
);
84 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
) throw( RuntimeException
);
87 Reference
< XIdlReflection
> m_xCoreReflection
;
88 Reference
< XAllListener
> m_xAllListener
;
89 Reference
< XIdlClass
> m_xListenerType
;
94 // Function to replace AllListenerAdapterService::createAllListerAdapter
95 Reference
< XInterface
> createAllListenerAdapter
97 const Reference
< XInvocationAdapterFactory
>& xInvocationAdapterFactory
,
98 const Reference
< XIdlClass
>& xListenerType
,
99 const Reference
< XAllListener
>& xListener
,
103 Reference
< XInterface
> xAdapter
;
104 if( xInvocationAdapterFactory
.is() && xListenerType
.is() && xListener
.is() )
106 Reference
< XInvocation
> xInvocationToAllListenerMapper
=
107 (XInvocation
*)new InvocationToAllListenerMapper( xListenerType
, xListener
, Helper
);
108 Type
aListenerType( xListenerType
->getTypeClass(), xListenerType
->getName());
109 xAdapter
= xInvocationAdapterFactory
->createAdapter( xInvocationToAllListenerMapper
, aListenerType
);
115 //--------------------------------------------------------------------------------------------------
116 // InvocationToAllListenerMapper
117 InvocationToAllListenerMapper::InvocationToAllListenerMapper
118 ( const Reference
< XIdlClass
>& ListenerType
, const Reference
< XAllListener
>& AllListener
, const Any
& Helper
)
119 : m_xAllListener( AllListener
)
120 , m_xListenerType( ListenerType
)
125 //*************************************************************************
126 Reference
< XIntrospectionAccess
> SAL_CALL
InvocationToAllListenerMapper::getIntrospection(void)
127 throw( RuntimeException
)
129 return Reference
< XIntrospectionAccess
>();
132 //*************************************************************************
133 Any SAL_CALL
InvocationToAllListenerMapper::invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
,
134 Sequence
< sal_Int16
>& , Sequence
< Any
>& )
135 throw( IllegalArgumentException
, CannotConvertException
,
136 InvocationTargetException
, RuntimeException
)
140 // Check if to firing or approveFiring has to be called
141 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( FunctionName
);
142 sal_Bool bApproveFiring
= sal_False
;
145 Reference
< XIdlClass
> xReturnType
= xMethod
->getReturnType();
146 Sequence
< Reference
< XIdlClass
> > aExceptionSeq
= xMethod
->getExceptionTypes();
147 if( ( xReturnType
.is() && xReturnType
->getTypeClass() != TypeClass_VOID
) ||
148 aExceptionSeq
.getLength() > 0 )
150 bApproveFiring
= sal_True
;
154 Sequence
< ParamInfo
> aParamSeq
= xMethod
->getParameterInfos();
155 sal_uInt32 nParamCount
= aParamSeq
.getLength();
156 if( nParamCount
> 1 )
158 const ParamInfo
* pInfos
= aParamSeq
.getConstArray();
159 for( sal_uInt32 i
= 0 ; i
< nParamCount
; i
++ )
161 if( pInfos
[ i
].aMode
!= ParamMode_IN
)
163 bApproveFiring
= sal_True
;
170 AllEventObject aAllEvent
;
171 aAllEvent
.Source
= (OWeakObject
*) this;
172 aAllEvent
.Helper
= m_Helper
;
173 aAllEvent
.ListenerType
= Type(m_xListenerType
->getTypeClass(), m_xListenerType
->getName());
174 aAllEvent
.MethodName
= FunctionName
;
175 aAllEvent
.Arguments
= Params
;
177 aRet
= m_xAllListener
->approveFiring( aAllEvent
);
179 m_xAllListener
->firing( aAllEvent
);
183 //*************************************************************************
184 void SAL_CALL
InvocationToAllListenerMapper::setValue(const OUString
& , const Any
& )
185 throw( UnknownPropertyException
, CannotConvertException
,
186 InvocationTargetException
, RuntimeException
)
190 //*************************************************************************
191 Any SAL_CALL
InvocationToAllListenerMapper::getValue(const OUString
& )
192 throw( UnknownPropertyException
, RuntimeException
)
197 //*************************************************************************
198 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasMethod(const OUString
& Name
)
199 throw( RuntimeException
)
201 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( Name
);
205 //*************************************************************************
206 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasProperty(const OUString
& Name
)
207 throw( RuntimeException
)
209 Reference
< XIdlField
> xField
= m_xListenerType
->getField( Name
);
213 //*************************************************************************
214 // class EventAttacherImpl
215 // represents an implementation of the EventAttacher service
216 //*************************************************************************
217 class EventAttacherImpl
: public WeakImplHelper3
< XEventAttacher2
, XInitialization
, XServiceInfo
>
220 EventAttacherImpl( const Reference
< XMultiServiceFactory
>& );
221 ~EventAttacherImpl();
224 virtual OUString SAL_CALL
getImplementationName( ) throw(RuntimeException
);
225 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) throw(RuntimeException
);
226 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) throw(RuntimeException
);
227 static OUString SAL_CALL
getImplementationName_Static( );
228 static Sequence
< OUString
> SAL_CALL
getSupportedServiceNames_Static( );
231 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
)
232 throw( Exception
, RuntimeException
);
234 // Methoden von XEventAttacher
235 virtual Reference
< XEventListener
> SAL_CALL
attachListener(const Reference
< XInterface
>& xObject
,
236 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
,
237 const OUString
& ListenerType
, const OUString
& AddListenerParam
)
238 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
);
239 virtual Reference
< XEventListener
> SAL_CALL
attachSingleEventListener(const Reference
< XInterface
>& xObject
,
240 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
,
241 const OUString
& ListenerType
, const OUString
& AddListenerParam
,
242 const OUString
& EventMethod
)
243 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
);
244 virtual void SAL_CALL
removeListener(const Reference
< XInterface
>& xObject
,
245 const OUString
& ListenerType
, const OUString
& AddListenerParam
,
246 const Reference
< XEventListener
>& aToRemoveListener
)
247 throw( IllegalArgumentException
, IntrospectionException
, RuntimeException
);
250 virtual Sequence
< Reference
<XEventListener
> > SAL_CALL
attachMultipleEventListeners(
251 const Reference
<XInterface
>& xObject
, const Sequence
<com::sun::star::script::EventListener
>& aListeners
)
252 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
);
254 // used by FilterAllListener_Impl
255 Reference
< XTypeConverter
> getConverter() throw( Exception
);
257 friend class FilterAllListenerImpl
;
260 Reference
<XEventListener
> attachListenerForTarget(
261 const Reference
<XIntrospectionAccess
>& xAccess
,
262 const Reference
<XInvocationAdapterFactory
>& xInvocationAdapterFactory
,
263 const Reference
<XAllListener
>& xAllListener
,
266 const OUString
& aListenerType
,
267 const OUString
& aAddListenerParam
);
269 Sequence
< Reference
<XEventListener
> > attachListeners(
270 const Reference
<XInterface
>& xObject
,
271 const Sequence
< Reference
<XAllListener
> >& AllListeners
,
272 const Sequence
<com::sun::star::script::EventListener
>& aListeners
);
276 Reference
< XMultiServiceFactory
> m_xSMgr
;
279 Reference
< XIntrospection
> m_xIntrospection
;
280 Reference
< XIdlReflection
> m_xReflection
;
281 Reference
< XTypeConverter
> m_xConverter
;
282 Reference
< XInvocationAdapterFactory
> m_xInvocationAdapterFactory
;
285 Reference
< XIntrospection
> getIntrospection() throw( Exception
);
286 Reference
< XIdlReflection
> getReflection() throw( Exception
);
287 Reference
< XInvocationAdapterFactory
> getInvocationAdapterService() throw( Exception
);
291 //*************************************************************************
292 EventAttacherImpl::EventAttacherImpl( const Reference
< XMultiServiceFactory
>& rSMgr
)
297 //*************************************************************************
298 EventAttacherImpl::~EventAttacherImpl()
302 //*************************************************************************
303 Reference
< XInterface
> SAL_CALL
EventAttacherImpl_CreateInstance( const Reference
< XMultiServiceFactory
>& rSMgr
) throw( Exception
)
305 Reference
< XInterface
> xRet
;
306 XEventAttacher
*pEventAttacher
= (XEventAttacher
*) new EventAttacherImpl(rSMgr
);
310 xRet
= Reference
<XInterface
>::query(pEventAttacher
);
316 //*************************************************************************
317 OUString SAL_CALL
EventAttacherImpl::getImplementationName( )
318 throw(RuntimeException
)
320 return OUString( IMPLNAME
);
323 //*************************************************************************
324 sal_Bool SAL_CALL
EventAttacherImpl::supportsService( const OUString
& ServiceName
)
325 throw(RuntimeException
)
327 Sequence
< OUString
> aSNL
= getSupportedServiceNames();
328 const OUString
* pArray
= aSNL
.getArray();
329 for( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
330 if( pArray
[i
] == ServiceName
)
335 //*************************************************************************
336 Sequence
<OUString
> SAL_CALL
EventAttacherImpl::getSupportedServiceNames( )
337 throw(RuntimeException
)
339 return getSupportedServiceNames_Static();
342 //*************************************************************************
343 Sequence
<OUString
> SAL_CALL
EventAttacherImpl::getSupportedServiceNames_Static( )
345 OUString
aStr( SERVICENAME
);
346 return Sequence
< OUString
>( &aStr
, 1 );
349 //*************************************************************************
350 void SAL_CALL
EventAttacherImpl::initialize(const Sequence
< Any
>& Arguments
) throw( Exception
, RuntimeException
)
352 // get services from the argument list
353 const Any
* pArray
= Arguments
.getConstArray();
354 for( sal_Int32 i
= 0; i
< Arguments
.getLength(); i
++ )
356 if( pArray
[i
].getValueType().getTypeClass() != TypeClass_INTERFACE
)
357 throw IllegalArgumentException();
359 // InvocationAdapter service ?
360 Reference
< XInvocationAdapterFactory
> xALAS
;
364 Guard
< Mutex
> aGuard( m_aMutex
);
365 m_xInvocationAdapterFactory
= xALAS
;
367 // Introspection service ?
368 Reference
< XIntrospection
> xI
;
372 Guard
< Mutex
> aGuard( m_aMutex
);
373 m_xIntrospection
= xI
;
375 // Reflection service ?
376 Reference
< XIdlReflection
> xIdlR
;
380 Guard
< Mutex
> aGuard( m_aMutex
);
381 m_xReflection
= xIdlR
;
383 // Converter Service ?
384 Reference
< XTypeConverter
> xC
;
388 Guard
< Mutex
> aGuard( m_aMutex
);
392 // no right interface
393 if( !xALAS
.is() && !xI
.is() && !xIdlR
.is() && !xC
.is() )
394 throw IllegalArgumentException();
398 //*************************************************************************
399 //*** Private helper methods ***
400 Reference
< XIntrospection
> EventAttacherImpl::getIntrospection() throw( Exception
)
402 Guard
< Mutex
> aGuard( m_aMutex
);
403 if( !m_xIntrospection
.is() )
405 Reference
< XInterface
> xIFace( m_xSMgr
->createInstance( rtl::OUString("com.sun.star.beans.Introspection") ) );
406 m_xIntrospection
= Reference
< XIntrospection
>( xIFace
, UNO_QUERY
);
408 return m_xIntrospection
;
411 //*************************************************************************
412 //*** Private helper methods ***
413 Reference
< XIdlReflection
> EventAttacherImpl::getReflection() throw( Exception
)
415 Guard
< Mutex
> aGuard( m_aMutex
);
416 if( !m_xReflection
.is() )
418 Reference
< XInterface
> xIFace( m_xSMgr
->createInstance( rtl::OUString("com.sun.star.reflection.CoreReflection") ) );
419 m_xReflection
= Reference
< XIdlReflection
>( xIFace
, UNO_QUERY
);
421 return m_xReflection
;
424 //*************************************************************************
425 //*** Private helper methods ***
426 Reference
< XInvocationAdapterFactory
> EventAttacherImpl::getInvocationAdapterService() throw( Exception
)
428 Guard
< Mutex
> aGuard( m_aMutex
);
429 if( !m_xInvocationAdapterFactory
.is() )
431 Reference
< XInterface
> xIFace( m_xSMgr
->createInstance( rtl::OUString("com.sun.star.script.InvocationAdapterFactory") ) );
432 m_xInvocationAdapterFactory
= Reference
< XInvocationAdapterFactory
>( xIFace
, UNO_QUERY
);
434 return m_xInvocationAdapterFactory
;
438 //*************************************************************************
439 //*** Private helper methods ***
440 Reference
< XTypeConverter
> EventAttacherImpl::getConverter() throw( Exception
)
442 Guard
< Mutex
> aGuard( m_aMutex
);
443 if( !m_xConverter
.is() )
445 Reference
< XInterface
> xIFace( m_xSMgr
->createInstance( rtl::OUString("com.sun.star.script.Converter") ) );
446 m_xConverter
= Reference
< XTypeConverter
>( xIFace
, UNO_QUERY
);
451 //------------------------------------------------------------------------
452 //------------------------------------------------------------------------
453 //------------------------------------------------------------------------
454 // Implementation of an EventAttacher-related AllListeners, which brings
455 // a few Events to a general AllListener
456 class FilterAllListenerImpl
: public WeakImplHelper1
< XAllListener
>
459 FilterAllListenerImpl( EventAttacherImpl
* pEA_
, const OUString
& EventMethod_
,
460 const Reference
< XAllListener
>& AllListener_
);
463 virtual void SAL_CALL
firing(const AllEventObject
& Event
) throw( RuntimeException
);
464 virtual Any SAL_CALL
approveFiring(const AllEventObject
& Event
) throw( InvocationTargetException
, RuntimeException
);
467 virtual void SAL_CALL
disposing(const EventObject
& Source
) throw( RuntimeException
);
471 void convertToEventReturn( Any
& rRet
, const Type
& rRetType
)
472 throw( CannotConvertException
);
474 EventAttacherImpl
* m_pEA
;
475 Reference
< XInterface
> m_xEAHold
;
476 OUString m_EventMethod
;
477 Reference
< XAllListener
> m_AllListener
;
480 //*************************************************************************
481 FilterAllListenerImpl::FilterAllListenerImpl( EventAttacherImpl
* pEA_
, const OUString
& EventMethod_
,
482 const Reference
< XAllListener
>& AllListener_
)
485 , m_EventMethod( EventMethod_
)
486 , m_AllListener( AllListener_
)
490 //*************************************************************************
491 void SAL_CALL
FilterAllListenerImpl::firing(const AllEventObject
& Event
)
492 throw( RuntimeException
)
494 if( Event
.MethodName
== m_EventMethod
&& m_AllListener
.is() )
495 m_AllListener
->firing( Event
);
498 //*************************************************************************
499 // Convert to the standard event return
500 void FilterAllListenerImpl::convertToEventReturn( Any
& rRet
, const Type
& rRetType
)
501 throw( CannotConvertException
)
503 // no return value? Set to the specified values
504 if( rRet
.getValueType().getTypeClass() == TypeClass_VOID
)
506 switch( rRetType
.getTypeClass() )
508 case TypeClass_INTERFACE
:
510 rRet
<<= Reference
< XInterface
>();
514 case TypeClass_BOOLEAN
:
518 case TypeClass_STRING
:
522 case TypeClass_FLOAT
: rRet
<<= float(0); break;
523 case TypeClass_DOUBLE
: rRet
<<= double(0.0); break;
524 case TypeClass_BYTE
: rRet
<<= sal_uInt8( 0 ); break;
525 case TypeClass_SHORT
: rRet
<<= sal_Int16( 0 ); break;
526 case TypeClass_LONG
: rRet
<<= sal_Int32( 0 ); break;
527 case TypeClass_UNSIGNED_SHORT
: rRet
<<= sal_uInt16( 0 ); break;
528 case TypeClass_UNSIGNED_LONG
: rRet
<<= sal_uInt32( 0 ); break;
533 else if( !rRet
.getValueType().equals( rRetType
) )
535 Reference
< XTypeConverter
> xConverter
= m_pEA
->getConverter();
536 if( xConverter
.is() )
537 rRet
= xConverter
->convertTo( rRet
, rRetType
);
539 throw CannotConvertException(); // TODO TypeConversionException
543 //*************************************************************************
544 Any SAL_CALL
FilterAllListenerImpl::approveFiring( const AllEventObject
& Event
)
545 throw( InvocationTargetException
, RuntimeException
)
549 if( Event
.MethodName
== m_EventMethod
&& m_AllListener
.is() )
550 aRet
= m_AllListener
->approveFiring( Event
);
553 // Convert to the standard event return
556 Reference
< XIdlClass
> xListenerType
= m_pEA
->getReflection()->
557 forName( Event
.ListenerType
.getTypeName() );
558 Reference
< XIdlMethod
> xMeth
= xListenerType
->getMethod( Event
.MethodName
);
561 Reference
< XIdlClass
> xRetType
= xMeth
->getReturnType();
562 Type
aRetType( xRetType
->getTypeClass(), xRetType
->getName() );
563 convertToEventReturn( aRet
, aRetType
);
566 catch( const CannotConvertException
& e
)
568 throw InvocationTargetException( OUString(), Reference
< XInterface
>(), Any(&e
, ::getCppuType( (CannotConvertException
*)0)) );
574 //*************************************************************************
575 void FilterAllListenerImpl::disposing(const EventObject
& )
576 throw( RuntimeException
)
582 //*************************************************************************
583 Reference
< XEventListener
> EventAttacherImpl::attachListener
585 const Reference
< XInterface
>& xObject
,
586 const Reference
< XAllListener
>& AllListener
,
588 const OUString
& ListenerType
,
589 const OUString
& AddListenerParam
591 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
)
593 if( !xObject
.is() || !AllListener
.is() )
594 throw IllegalArgumentException();
596 Reference
< XInvocationAdapterFactory
> xInvocationAdapterFactory
= getInvocationAdapterService();
597 if( !xInvocationAdapterFactory
.is() )
598 throw ServiceNotRegisteredException();
600 Reference
< XIdlReflection
> xReflection
= getReflection();
601 if( !xReflection
.is() )
602 throw ServiceNotRegisteredException();
604 // Sign in, Call the fitting addListener method
605 // First Introspection, as the Methods can be analyzed in the same way
606 // For better perfomance it is implemented here again or make the Impl-Method
607 // of the Introspection configurable for this purpose.
608 Reference
< XIntrospection
> xIntrospection
= getIntrospection();
609 if( !xIntrospection
.is() )
610 return Reference
<XEventListener
>();
612 // Inspect Introspection
613 Any
aObjAny( &xObject
, ::getCppuType( (const Reference
< XInterface
> *)0) );
615 Reference
< XIntrospectionAccess
> xAccess
= xIntrospection
->inspect( aObjAny
);
617 return Reference
<XEventListener
>();
619 return attachListenerForTarget(
620 xAccess
, xInvocationAdapterFactory
, AllListener
, aObjAny
, Helper
,
621 ListenerType
, AddListenerParam
);
624 Reference
<XEventListener
> EventAttacherImpl::attachListenerForTarget(
625 const Reference
<XIntrospectionAccess
>& xAccess
,
626 const Reference
<XInvocationAdapterFactory
>& xInvocationAdapterFactory
,
627 const Reference
<XAllListener
>& xAllListener
,
630 const OUString
& aListenerType
,
631 const OUString
& aAddListenerParam
)
633 Reference
< XEventListener
> xRet
= NULL
;
635 // Construct the name of the addListener-Method.
636 sal_Int32 nIndex
= aListenerType
.lastIndexOf('.');
637 // set index to the interface name without package name
644 OUString aListenerName
= (aListenerType
[nIndex
] == 'X') ? aListenerType
.copy(nIndex
+1) : aListenerType
;
645 OUString aAddListenerName
= OUString("add") + aListenerName
;
647 // Send Methods to the correct addListener-Method
648 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( MethodConcept::LISTENER
);
649 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
650 for (sal_Int32 i
= 0, n
= aMethodSeq
.getLength(); i
< n
; ++i
)
652 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
654 // Is it the correct method?
655 OUString aMethName
= rxMethod
->getName();
657 if (aAddListenerName
!= aMethName
)
660 Sequence
< Reference
< XIdlClass
> > params
= rxMethod
->getParameterTypes();
661 sal_uInt32 nParamCount
= params
.getLength();
663 Reference
< XIdlClass
> xListenerType
;
664 if( nParamCount
== 1 )
665 xListenerType
= params
.getConstArray()[0];
666 else if( nParamCount
== 2 )
667 xListenerType
= params
.getConstArray()[1];
669 // Request Adapter for the actual Listener type
670 Reference
< XInterface
> xAdapter
= createAllListenerAdapter(
671 xInvocationAdapterFactory
, xListenerType
, xAllListener
, aHelper
);
674 throw CannotCreateAdapterException();
675 xRet
= Reference
< XEventListener
>( xAdapter
, UNO_QUERY
);
677 // Just the Listener as parameter?
678 if( nParamCount
== 1 )
680 Sequence
< Any
> args( 1 );
681 args
.getArray()[0] <<= xAdapter
;
684 rxMethod
->invoke( aObject
, args
);
686 catch( const InvocationTargetException
& )
688 throw IntrospectionException();
691 // Else, pass the other parameter now
692 else if( nParamCount
== 2 )
694 Sequence
< Any
> args( 2 );
695 Any
* pAnys
= args
.getArray();
697 // Check the type of the 1st parameter
698 Reference
< XIdlClass
> xParamClass
= params
.getConstArray()[0];
699 if( xParamClass
->getTypeClass() == TypeClass_STRING
)
701 pAnys
[0] <<= aAddListenerParam
;
704 // 2nd Parameter == Listener? TODO: Test!
705 pAnys
[1] <<= xAdapter
;
707 // TODO: Convert String -> ?
711 rxMethod
->invoke( aObject
, args
);
713 catch( const InvocationTargetException
& )
715 throw IntrospectionException();
720 // Anything else is not supported
726 Sequence
< Reference
<XEventListener
> > EventAttacherImpl::attachListeners(
727 const Reference
<XInterface
>& xObject
,
728 const Sequence
< Reference
<XAllListener
> >& AllListeners
,
729 const Sequence
<com::sun::star::script::EventListener
>& aListeners
)
731 sal_Int32 nCount
= aListeners
.getLength();
732 if (nCount
!= AllListeners
.getLength())
733 // This is a prerequisite!
734 throw RuntimeException();
737 throw IllegalArgumentException();
739 Reference
< XInvocationAdapterFactory
> xInvocationAdapterFactory
= getInvocationAdapterService();
740 if( !xInvocationAdapterFactory
.is() )
741 throw ServiceNotRegisteredException();
743 Reference
< XIdlReflection
> xReflection
= getReflection();
744 if( !xReflection
.is() )
745 throw ServiceNotRegisteredException();
747 // Sign in, Call the fitting addListener method
748 // First Introspection, as the Methods can be analyzed in the same way
749 // For better perfomance it is implemented here again or make the Impl-Method
750 // of the Introspection configurable for this purpose.
751 Reference
< XIntrospection
> xIntrospection
= getIntrospection();
752 if( !xIntrospection
.is() )
753 return Sequence
< Reference
<XEventListener
> >();
755 // Inspect Introspection
756 Any
aObjAny( &xObject
, ::getCppuType(static_cast<const Reference
<XInterface
>*>(0)) );
758 Reference
<XIntrospectionAccess
> xAccess
= xIntrospection
->inspect(aObjAny
);
760 return Sequence
< Reference
<XEventListener
> >();
762 Sequence
< Reference
<XEventListener
> > aRet(nCount
);
763 Reference
<XEventListener
>* pArray
= aRet
.getArray();
765 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
767 pArray
[i
] = attachListenerForTarget(
768 xAccess
, xInvocationAdapterFactory
, AllListeners
[ i
],
769 aObjAny
, aListeners
[i
].Helper
, aListeners
[i
].ListenerType
, aListeners
[i
].AddListenerParam
);
776 Reference
< XEventListener
> EventAttacherImpl::attachSingleEventListener
778 const Reference
< XInterface
>& xObject
,
779 const Reference
< XAllListener
>& AllListener
,
781 const OUString
& ListenerType
,
782 const OUString
& AddListenerParam
,
783 const OUString
& EventMethod
785 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
)
787 // Subscribe FilterListener
788 Reference
< XAllListener
> aFilterListener
= (XAllListener
*)
789 new FilterAllListenerImpl( this, EventMethod
, AllListener
);
790 return attachListener( xObject
, aFilterListener
, Helper
, ListenerType
, AddListenerParam
);
794 void EventAttacherImpl::removeListener
796 const Reference
< XInterface
>& xObject
,
797 const OUString
& ListenerType
,
798 const OUString
& AddListenerParam
,
799 const Reference
< XEventListener
>& aToRemoveListener
801 throw( IllegalArgumentException
, IntrospectionException
, RuntimeException
)
803 if( !xObject
.is() || !aToRemoveListener
.is() )
804 throw IllegalArgumentException();
806 Reference
< XIdlReflection
> xReflection
= getReflection();
807 if( !xReflection
.is() )
808 throw IntrospectionException();
810 // Sign off, Call the fitting removeListener method
811 // First Introspection, as the Methods can be analyzed in the same way
812 // For better perfomance it is implemented here again or make the Impl-Method
813 // of the Introspection configurable for this purpose.
814 Reference
< XIntrospection
> xIntrospection
= getIntrospection();
815 if( !xIntrospection
.is() )
816 throw IntrospectionException();
818 //Inspect Introspection
819 Any
aObjAny( &xObject
, ::getCppuType( (const Reference
< XInterface
> *)0) );
820 Reference
< XIntrospectionAccess
> xAccess
= xIntrospection
->inspect( aObjAny
);
822 throw IntrospectionException();
824 // Create name of the removeListener-Method
825 OUString aRemoveListenerName
;
826 OUString
aListenerName( ListenerType
);
827 sal_Int32 nIndex
= aListenerName
.lastIndexOf( '.' );
828 // set index to the interface name without package name
834 if( aListenerName
[nIndex
] == 'X' )
835 // erase X from the interface name
836 aListenerName
= aListenerName
.copy( nIndex
+1 );
837 aRemoveListenerName
= OUString( "remove" ) + aListenerName
;
839 // Search methods for the correct removeListener method
840 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( MethodConcept::LISTENER
);
841 sal_uInt32 i
, nLen
= aMethodSeq
.getLength();
842 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
843 for( i
= 0 ; i
< nLen
; i
++ )
846 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
848 // Is it the right method?
849 if( aRemoveListenerName
== rxMethod
->getName() )
851 Sequence
< Reference
< XIdlClass
> > params
= rxMethod
->getParameterTypes();
852 sal_uInt32 nParamCount
= params
.getLength();
854 // Just the Listener as parameter?
855 if( nParamCount
== 1 )
857 Sequence
< Any
> args( 1 );
858 args
.getArray()[0] <<= aToRemoveListener
;
861 rxMethod
->invoke( aObjAny
, args
);
863 catch( const InvocationTargetException
& )
865 throw IntrospectionException();
868 // Else pass the other parameter
869 else if( nParamCount
== 2 )
871 Sequence
< Any
> args( 2 );
872 Any
* pAnys
= args
.getArray();
874 // Check the type of the 1st parameter
875 Reference
< XIdlClass
> xParamClass
= params
.getConstArray()[0];
876 if( xParamClass
->getTypeClass() == TypeClass_STRING
)
877 pAnys
[0] <<= AddListenerParam
;
879 // 2nd parameter == Listener? TODO: Test!
880 pAnys
[1] <<= aToRemoveListener
;
882 // TODO: Convert String -> ?
886 rxMethod
->invoke( aObjAny
, args
);
888 catch( const InvocationTargetException
& )
890 throw IntrospectionException();
898 Sequence
< Reference
<XEventListener
> > EventAttacherImpl::attachMultipleEventListeners(
899 const Reference
<XInterface
>& xObject
, const Sequence
<com::sun::star::script::EventListener
>& aListeners
)
900 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
)
902 sal_Int32 nCount
= aListeners
.getLength();
903 Sequence
< Reference
<XAllListener
> > aFilterListeners(nCount
);
904 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
906 aFilterListeners
[i
] = (XAllListener
*)
907 new FilterAllListenerImpl(this, aListeners
[i
].EventMethod
, aListeners
[i
].AllListener
);
910 return attachListeners(xObject
, aFilterListeners
, aListeners
);
917 SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
component_getFactory(
918 const sal_Char
* pImplName
, void * pServiceManager
, void * )
922 if (pServiceManager
&& rtl_str_compare( pImplName
, IMPLNAME
) == 0)
924 Reference
< XSingleServiceFactory
> xFactory( createOneInstanceFactory(
925 reinterpret_cast< XMultiServiceFactory
* >( pServiceManager
),
926 OUString( IMPLNAME
),
927 ::comp_EventAttacher::EventAttacherImpl_CreateInstance
,
928 ::comp_EventAttacher::EventAttacherImpl::getSupportedServiceNames_Static() ) );
933 pRet
= xFactory
.get();
943 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */