1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include <osl/diagnose.h>
20 #include <com/sun/star/lang/XServiceInfo.hpp>
21 #include <com/sun/star/lang/XInitialization.hpp>
22 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
23 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
24 #include <com/sun/star/registry/XRegistryKey.hpp>
25 #include <com/sun/star/beans/theIntrospection.hpp>
26 #include <com/sun/star/beans/MethodConcept.hpp>
27 #include <com/sun/star/script/XEventAttacher2.hpp>
28 #include <com/sun/star/script/Converter.hpp>
29 #include <com/sun/star/script/XAllListener.hpp>
30 #include <com/sun/star/script/InvocationAdapterFactory.hpp>
31 #include <com/sun/star/reflection/theCoreReflection.hpp>
32 #include <com/sun/star/reflection/XIdlReflection.hpp>
34 // InvocationToAllListenerMapper
35 #include <com/sun/star/script/XInvocation.hpp>
36 #include <comphelper/processfactory.hxx>
37 #include <cppuhelper/weak.hxx>
38 #include <cppuhelper/factory.hxx>
39 #include <cppuhelper/implbase1.hxx>
40 #include <cppuhelper/implbase3.hxx>
41 #include <cppuhelper/supportsservice.hxx>
43 using namespace com::sun::star::uno
;
44 using namespace com::sun::star::registry
;
45 using namespace com::sun::star::lang
;
46 using namespace com::sun::star::beans
;
47 using namespace com::sun::star::script
;
48 using namespace com::sun::star::reflection
;
54 #define SERVICENAME "com.sun.star.script.EventAttacher"
55 #define IMPLNAME "com.sun.star.comp.EventAttacher"
57 namespace comp_EventAttacher
{
60 // class InvocationToAllListenerMapper
61 // helper class to map XInvocation to XAllListener
63 class InvocationToAllListenerMapper
: public WeakImplHelper1
< XInvocation
>
66 InvocationToAllListenerMapper( const Reference
< XIdlClass
>& ListenerType
,
67 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
);
70 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection() throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
71 virtual Any SAL_CALL
invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
, Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
)
72 throw( IllegalArgumentException
, CannotConvertException
, InvocationTargetException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
73 virtual void SAL_CALL
setValue(const OUString
& PropertyName
, const Any
& Value
)
74 throw( UnknownPropertyException
, CannotConvertException
, InvocationTargetException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
75 virtual Any SAL_CALL
getValue(const OUString
& PropertyName
) throw( UnknownPropertyException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
76 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
) throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
77 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
) throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
80 Reference
< XIdlReflection
> m_xCoreReflection
;
81 Reference
< XAllListener
> m_xAllListener
;
82 Reference
< XIdlClass
> m_xListenerType
;
87 // Function to replace AllListenerAdapterService::createAllListerAdapter
88 Reference
< XInterface
> createAllListenerAdapter
90 const Reference
< XInvocationAdapterFactory2
>& xInvocationAdapterFactory
,
91 const Reference
< XIdlClass
>& xListenerType
,
92 const Reference
< XAllListener
>& xListener
,
96 Reference
< XInterface
> xAdapter
;
97 if( xInvocationAdapterFactory
.is() && xListenerType
.is() && xListener
.is() )
99 Reference
< XInvocation
> xInvocationToAllListenerMapper
=
100 (XInvocation
*)new InvocationToAllListenerMapper( xListenerType
, xListener
, Helper
);
101 Type
aListenerType( xListenerType
->getTypeClass(), xListenerType
->getName());
102 Sequence
<Type
> arg2(1);
103 arg2
[0] = aListenerType
;
104 xAdapter
= xInvocationAdapterFactory
->createAdapter( xInvocationToAllListenerMapper
, arg2
);
111 // InvocationToAllListenerMapper
112 InvocationToAllListenerMapper::InvocationToAllListenerMapper
113 ( const Reference
< XIdlClass
>& ListenerType
, const Reference
< XAllListener
>& AllListener
, const Any
& Helper
)
114 : m_xAllListener( AllListener
)
115 , m_xListenerType( ListenerType
)
121 Reference
< XIntrospectionAccess
> SAL_CALL
InvocationToAllListenerMapper::getIntrospection()
122 throw( RuntimeException
, std::exception
)
124 return Reference
< XIntrospectionAccess
>();
128 Any SAL_CALL
InvocationToAllListenerMapper::invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
,
129 Sequence
< sal_Int16
>& , Sequence
< Any
>& )
130 throw( IllegalArgumentException
, CannotConvertException
,
131 InvocationTargetException
, RuntimeException
, std::exception
)
135 // Check if to firing or approveFiring has to be called
136 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( FunctionName
);
137 bool bApproveFiring
= false;
140 Reference
< XIdlClass
> xReturnType
= xMethod
->getReturnType();
141 Sequence
< Reference
< XIdlClass
> > aExceptionSeq
= xMethod
->getExceptionTypes();
142 if( ( xReturnType
.is() && xReturnType
->getTypeClass() != TypeClass_VOID
) ||
143 aExceptionSeq
.getLength() > 0 )
145 bApproveFiring
= true;
149 Sequence
< ParamInfo
> aParamSeq
= xMethod
->getParameterInfos();
150 sal_uInt32 nParamCount
= aParamSeq
.getLength();
151 if( nParamCount
> 1 )
153 const ParamInfo
* pInfos
= aParamSeq
.getConstArray();
154 for( sal_uInt32 i
= 0 ; i
< nParamCount
; i
++ )
156 if( pInfos
[ i
].aMode
!= ParamMode_IN
)
158 bApproveFiring
= true;
165 AllEventObject aAllEvent
;
166 aAllEvent
.Source
= (OWeakObject
*) this;
167 aAllEvent
.Helper
= m_Helper
;
168 aAllEvent
.ListenerType
= Type(m_xListenerType
->getTypeClass(), m_xListenerType
->getName());
169 aAllEvent
.MethodName
= FunctionName
;
170 aAllEvent
.Arguments
= Params
;
172 aRet
= m_xAllListener
->approveFiring( aAllEvent
);
174 m_xAllListener
->firing( aAllEvent
);
179 void SAL_CALL
InvocationToAllListenerMapper::setValue(const OUString
& , const Any
& )
180 throw( UnknownPropertyException
, CannotConvertException
,
181 InvocationTargetException
, RuntimeException
, std::exception
)
186 Any SAL_CALL
InvocationToAllListenerMapper::getValue(const OUString
& )
187 throw( UnknownPropertyException
, RuntimeException
, std::exception
)
193 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasMethod(const OUString
& Name
)
194 throw( RuntimeException
, std::exception
)
196 Reference
< XIdlMethod
> xMethod
= m_xListenerType
->getMethod( Name
);
201 sal_Bool SAL_CALL
InvocationToAllListenerMapper::hasProperty(const OUString
& Name
)
202 throw( RuntimeException
, std::exception
)
204 Reference
< XIdlField
> xField
= m_xListenerType
->getField( Name
);
209 // class EventAttacherImpl
210 // represents an implementation of the EventAttacher service
212 class EventAttacherImpl
: public WeakImplHelper3
< XEventAttacher2
, XInitialization
, XServiceInfo
>
215 EventAttacherImpl( const Reference
< XComponentContext
>& );
216 virtual ~EventAttacherImpl();
219 virtual OUString SAL_CALL
getImplementationName( ) throw(RuntimeException
, std::exception
) SAL_OVERRIDE
;
220 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) throw(RuntimeException
, std::exception
) SAL_OVERRIDE
;
221 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) throw(RuntimeException
, std::exception
) SAL_OVERRIDE
;
222 static Sequence
< OUString
> SAL_CALL
getSupportedServiceNames_Static( );
225 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
)
226 throw( Exception
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
228 // Methoden von XEventAttacher
229 virtual Reference
< XEventListener
> SAL_CALL
attachListener(const Reference
< XInterface
>& xObject
,
230 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
,
231 const OUString
& ListenerType
, const OUString
& AddListenerParam
)
232 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
233 virtual Reference
< XEventListener
> SAL_CALL
attachSingleEventListener(const Reference
< XInterface
>& xObject
,
234 const Reference
< XAllListener
>& AllListener
, const Any
& Helper
,
235 const OUString
& ListenerType
, const OUString
& AddListenerParam
,
236 const OUString
& EventMethod
)
237 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
238 virtual void SAL_CALL
removeListener(const Reference
< XInterface
>& xObject
,
239 const OUString
& ListenerType
, const OUString
& AddListenerParam
,
240 const Reference
< XEventListener
>& aToRemoveListener
)
241 throw( IllegalArgumentException
, IntrospectionException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
244 virtual Sequence
< Reference
<XEventListener
> > SAL_CALL
attachMultipleEventListeners(
245 const Reference
<XInterface
>& xObject
, const Sequence
<com::sun::star::script::EventListener
>& aListeners
)
246 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
248 // used by FilterAllListener_Impl
249 Reference
< XTypeConverter
> getConverter() throw( Exception
);
251 friend class FilterAllListenerImpl
;
254 static Reference
<XEventListener
> attachListenerForTarget(
255 const Reference
<XIntrospectionAccess
>& xAccess
,
256 const Reference
<XInvocationAdapterFactory2
>& xInvocationAdapterFactory
,
257 const Reference
<XAllListener
>& xAllListener
,
260 const OUString
& aListenerType
,
261 const OUString
& aAddListenerParam
);
263 Sequence
< Reference
<XEventListener
> > attachListeners(
264 const Reference
<XInterface
>& xObject
,
265 const Sequence
< Reference
<XAllListener
> >& AllListeners
,
266 const Sequence
<com::sun::star::script::EventListener
>& aListeners
);
270 Reference
< XComponentContext
> m_xContext
;
273 Reference
< XIntrospection
> m_xIntrospection
;
274 Reference
< XIdlReflection
> m_xReflection
;
275 Reference
< XTypeConverter
> m_xConverter
;
276 Reference
< XInvocationAdapterFactory2
> m_xInvocationAdapterFactory
;
279 Reference
< XIntrospection
> getIntrospection() throw( Exception
);
280 Reference
< XIdlReflection
> getReflection() throw( Exception
);
281 Reference
< XInvocationAdapterFactory2
> getInvocationAdapterService() throw( Exception
);
286 EventAttacherImpl::EventAttacherImpl( const Reference
< XComponentContext
>& rxContext
)
287 : m_xContext( rxContext
)
292 EventAttacherImpl::~EventAttacherImpl()
297 Reference
< XInterface
> SAL_CALL
EventAttacherImpl_CreateInstance( const Reference
< XMultiServiceFactory
>& rSMgr
) throw( Exception
)
299 XEventAttacher
*pEventAttacher
= (XEventAttacher
*) new EventAttacherImpl( comphelper::getComponentContext(rSMgr
) );
301 Reference
< XInterface
> xRet
= Reference
<XInterface
>::query(pEventAttacher
);
307 OUString SAL_CALL
EventAttacherImpl::getImplementationName( )
308 throw(RuntimeException
, std::exception
)
310 return OUString( IMPLNAME
);
313 sal_Bool SAL_CALL
EventAttacherImpl::supportsService( const OUString
& ServiceName
)
314 throw(RuntimeException
, std::exception
)
316 return cppu::supportsService(this, ServiceName
);
319 Sequence
<OUString
> SAL_CALL
EventAttacherImpl::getSupportedServiceNames( )
320 throw(RuntimeException
, std::exception
)
322 return getSupportedServiceNames_Static();
326 Sequence
<OUString
> SAL_CALL
EventAttacherImpl::getSupportedServiceNames_Static( )
328 OUString
aStr( SERVICENAME
);
329 return Sequence
< OUString
>( &aStr
, 1 );
332 void SAL_CALL
EventAttacherImpl::initialize(const Sequence
< Any
>& Arguments
) throw( Exception
, RuntimeException
, std::exception
)
334 // get services from the argument list
335 const Any
* pArray
= Arguments
.getConstArray();
336 for( sal_Int32 i
= 0; i
< Arguments
.getLength(); i
++ )
338 if( pArray
[i
].getValueType().getTypeClass() != TypeClass_INTERFACE
)
339 throw IllegalArgumentException();
341 // InvocationAdapter service ?
342 Reference
< XInvocationAdapterFactory2
> xALAS
;
346 Guard
< Mutex
> aGuard( m_aMutex
);
347 m_xInvocationAdapterFactory
= xALAS
;
349 // Introspection service ?
350 Reference
< XIntrospection
> xI
;
354 Guard
< Mutex
> aGuard( m_aMutex
);
355 m_xIntrospection
= xI
;
357 // Reflection service ?
358 Reference
< XIdlReflection
> xIdlR
;
362 Guard
< Mutex
> aGuard( m_aMutex
);
363 m_xReflection
= xIdlR
;
365 // Converter Service ?
366 Reference
< XTypeConverter
> xC
;
370 Guard
< Mutex
> aGuard( m_aMutex
);
374 // no right interface
375 if( !xALAS
.is() && !xI
.is() && !xIdlR
.is() && !xC
.is() )
376 throw IllegalArgumentException();
381 //*** Private helper methods ***
382 Reference
< XIntrospection
> EventAttacherImpl::getIntrospection() throw( Exception
)
384 Guard
< Mutex
> aGuard( m_aMutex
);
385 if( !m_xIntrospection
.is() )
387 m_xIntrospection
= theIntrospection::get( m_xContext
);
389 return m_xIntrospection
;
393 //*** Private helper methods ***
394 Reference
< XIdlReflection
> EventAttacherImpl::getReflection() throw( Exception
)
396 Guard
< Mutex
> aGuard( m_aMutex
);
397 if( !m_xReflection
.is() )
399 m_xReflection
= theCoreReflection::get(m_xContext
);
401 return m_xReflection
;
405 //*** Private helper methods ***
406 Reference
< XInvocationAdapterFactory2
> EventAttacherImpl::getInvocationAdapterService() throw( Exception
)
408 Guard
< Mutex
> aGuard( m_aMutex
);
409 if( !m_xInvocationAdapterFactory
.is() )
411 m_xInvocationAdapterFactory
= InvocationAdapterFactory::create(m_xContext
);
413 return m_xInvocationAdapterFactory
;
418 //*** Private helper methods ***
419 Reference
< XTypeConverter
> EventAttacherImpl::getConverter() throw( Exception
)
421 Guard
< Mutex
> aGuard( m_aMutex
);
422 if( !m_xConverter
.is() )
424 m_xConverter
= Converter::create(m_xContext
);
432 // Implementation of an EventAttacher-related AllListeners, which brings
433 // a few Events to a general AllListener
434 class FilterAllListenerImpl
: public WeakImplHelper1
< XAllListener
>
437 FilterAllListenerImpl( EventAttacherImpl
* pEA_
, const OUString
& EventMethod_
,
438 const Reference
< XAllListener
>& AllListener_
);
441 virtual void SAL_CALL
firing(const AllEventObject
& Event
) throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
442 virtual Any SAL_CALL
approveFiring(const AllEventObject
& Event
) throw( InvocationTargetException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
445 virtual void SAL_CALL
disposing(const EventObject
& Source
) throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
449 void convertToEventReturn( Any
& rRet
, const Type
& rRetType
)
450 throw (CannotConvertException
, RuntimeException
);
452 EventAttacherImpl
* m_pEA
;
453 Reference
< XInterface
> m_xEAHold
;
454 OUString m_EventMethod
;
455 Reference
< XAllListener
> m_AllListener
;
459 FilterAllListenerImpl::FilterAllListenerImpl( EventAttacherImpl
* pEA_
, const OUString
& EventMethod_
,
460 const Reference
< XAllListener
>& AllListener_
)
463 , m_EventMethod( EventMethod_
)
464 , m_AllListener( AllListener_
)
469 void SAL_CALL
FilterAllListenerImpl::firing(const AllEventObject
& Event
)
470 throw( RuntimeException
, std::exception
)
472 if( Event
.MethodName
== m_EventMethod
&& m_AllListener
.is() )
473 m_AllListener
->firing( Event
);
476 // Convert to the standard event return
477 void FilterAllListenerImpl::convertToEventReturn( Any
& rRet
, const Type
& rRetType
)
478 throw (CannotConvertException
, RuntimeException
)
480 // no return value? Set to the specified values
481 if( rRet
.getValueType().getTypeClass() == TypeClass_VOID
)
483 switch( rRetType
.getTypeClass() )
485 case TypeClass_INTERFACE
:
487 rRet
<<= Reference
< XInterface
>();
491 case TypeClass_BOOLEAN
:
495 case TypeClass_STRING
:
499 case TypeClass_FLOAT
: rRet
<<= float(0); break;
500 case TypeClass_DOUBLE
: rRet
<<= double(0.0); break;
501 case TypeClass_BYTE
: rRet
<<= sal_uInt8( 0 ); break;
502 case TypeClass_SHORT
: rRet
<<= sal_Int16( 0 ); break;
503 case TypeClass_LONG
: rRet
<<= sal_Int32( 0 ); break;
504 case TypeClass_UNSIGNED_SHORT
: rRet
<<= sal_uInt16( 0 ); break;
505 case TypeClass_UNSIGNED_LONG
: rRet
<<= sal_uInt32( 0 ); break;
510 else if( !rRet
.getValueType().equals( rRetType
) )
512 Reference
< XTypeConverter
> xConverter
= m_pEA
->getConverter();
513 if( xConverter
.is() )
514 rRet
= xConverter
->convertTo( rRet
, rRetType
);
516 throw CannotConvertException(); // TODO TypeConversionException
521 Any SAL_CALL
FilterAllListenerImpl::approveFiring( const AllEventObject
& Event
)
522 throw( InvocationTargetException
, RuntimeException
, std::exception
)
526 if( Event
.MethodName
== m_EventMethod
&& m_AllListener
.is() )
527 aRet
= m_AllListener
->approveFiring( Event
);
530 // Convert to the standard event return
533 Reference
< XIdlClass
> xListenerType
= m_pEA
->getReflection()->
534 forName( Event
.ListenerType
.getTypeName() );
535 Reference
< XIdlMethod
> xMeth
= xListenerType
->getMethod( Event
.MethodName
);
538 Reference
< XIdlClass
> xRetType
= xMeth
->getReturnType();
539 Type
aRetType( xRetType
->getTypeClass(), xRetType
->getName() );
540 convertToEventReturn( aRet
, aRetType
);
543 catch( const CannotConvertException
& e
)
545 throw InvocationTargetException( OUString(), Reference
< XInterface
>(), Any(&e
, cppu::UnoType
<CannotConvertException
>::get()) );
552 void FilterAllListenerImpl::disposing(const EventObject
& )
553 throw( RuntimeException
, std::exception
)
560 Reference
< XEventListener
> EventAttacherImpl::attachListener
562 const Reference
< XInterface
>& xObject
,
563 const Reference
< XAllListener
>& AllListener
,
565 const OUString
& ListenerType
,
566 const OUString
& AddListenerParam
568 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
, std::exception
)
570 if( !xObject
.is() || !AllListener
.is() )
571 throw IllegalArgumentException();
573 Reference
< XInvocationAdapterFactory2
> xInvocationAdapterFactory
= getInvocationAdapterService();
574 if( !xInvocationAdapterFactory
.is() )
575 throw ServiceNotRegisteredException();
577 Reference
< XIdlReflection
> xReflection
= getReflection();
578 if( !xReflection
.is() )
579 throw ServiceNotRegisteredException();
581 // Sign in, Call the fitting addListener method
582 // First Introspection, as the Methods can be analyzed in the same way
583 // For better performance it is implemented here again or make the Impl-Method
584 // of the Introspection configurable for this purpose.
585 Reference
< XIntrospection
> xIntrospection
= getIntrospection();
586 if( !xIntrospection
.is() )
587 return Reference
<XEventListener
>();
589 // Inspect Introspection
590 Any
aObjAny( &xObject
, cppu::UnoType
<XInterface
>::get());
592 Reference
< XIntrospectionAccess
> xAccess
= xIntrospection
->inspect( aObjAny
);
594 return Reference
<XEventListener
>();
596 return attachListenerForTarget(
597 xAccess
, xInvocationAdapterFactory
, AllListener
, aObjAny
, Helper
,
598 ListenerType
, AddListenerParam
);
601 Reference
<XEventListener
> EventAttacherImpl::attachListenerForTarget(
602 const Reference
<XIntrospectionAccess
>& xAccess
,
603 const Reference
<XInvocationAdapterFactory2
>& xInvocationAdapterFactory
,
604 const Reference
<XAllListener
>& xAllListener
,
607 const OUString
& aListenerType
,
608 const OUString
& aAddListenerParam
)
610 Reference
< XEventListener
> xRet
= NULL
;
612 // Construct the name of the addListener-Method.
613 sal_Int32 nIndex
= aListenerType
.lastIndexOf('.');
614 // set index to the interface name without package name
621 OUString aListenerName
= (!aListenerType
.isEmpty() && aListenerType
[nIndex
] == 'X') ? aListenerType
.copy(nIndex
+1) : aListenerType
;
622 OUString aAddListenerName
= "add" + aListenerName
;
624 // Send Methods to the correct addListener-Method
625 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( MethodConcept::LISTENER
);
626 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
627 for (sal_Int32 i
= 0, n
= aMethodSeq
.getLength(); i
< n
; ++i
)
629 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
631 // Is it the correct method?
632 OUString aMethName
= rxMethod
->getName();
634 if (aAddListenerName
!= aMethName
)
637 Sequence
< Reference
< XIdlClass
> > params
= rxMethod
->getParameterTypes();
638 sal_uInt32 nParamCount
= params
.getLength();
640 Reference
< XIdlClass
> xListenerType
;
641 if( nParamCount
== 1 )
642 xListenerType
= params
.getConstArray()[0];
643 else if( nParamCount
== 2 )
644 xListenerType
= params
.getConstArray()[1];
646 // Request Adapter for the actual Listener type
647 Reference
< XInterface
> xAdapter
= createAllListenerAdapter(
648 xInvocationAdapterFactory
, xListenerType
, xAllListener
, aHelper
);
651 throw CannotCreateAdapterException();
652 xRet
= Reference
< XEventListener
>( xAdapter
, UNO_QUERY
);
654 // Just the Listener as parameter?
655 if( nParamCount
== 1 )
657 Sequence
< Any
> args( 1 );
658 args
.getArray()[0] <<= xAdapter
;
661 rxMethod
->invoke( aObject
, args
);
663 catch( const InvocationTargetException
& )
665 throw IntrospectionException();
668 // Else, pass the other parameter now
669 else if( nParamCount
== 2 )
671 Sequence
< Any
> args( 2 );
672 Any
* pAnys
= args
.getArray();
674 // Check the type of the 1st parameter
675 Reference
< XIdlClass
> xParamClass
= params
.getConstArray()[0];
676 if( xParamClass
->getTypeClass() == TypeClass_STRING
)
678 pAnys
[0] <<= aAddListenerParam
;
681 // 2nd Parameter == Listener? TODO: Test!
682 pAnys
[1] <<= xAdapter
;
684 // TODO: Convert String -> ?
688 rxMethod
->invoke( aObject
, args
);
690 catch( const InvocationTargetException
& )
692 throw IntrospectionException();
697 // Anything else is not supported
703 Sequence
< Reference
<XEventListener
> > EventAttacherImpl::attachListeners(
704 const Reference
<XInterface
>& xObject
,
705 const Sequence
< Reference
<XAllListener
> >& AllListeners
,
706 const Sequence
<com::sun::star::script::EventListener
>& aListeners
)
708 sal_Int32 nCount
= aListeners
.getLength();
709 if (nCount
!= AllListeners
.getLength())
710 // This is a prerequisite!
711 throw RuntimeException();
714 throw IllegalArgumentException();
716 Reference
< XInvocationAdapterFactory2
> xInvocationAdapterFactory
= getInvocationAdapterService();
717 if( !xInvocationAdapterFactory
.is() )
718 throw ServiceNotRegisteredException();
720 Reference
< XIdlReflection
> xReflection
= getReflection();
721 if( !xReflection
.is() )
722 throw ServiceNotRegisteredException();
724 // Sign in, Call the fitting addListener method
725 // First Introspection, as the Methods can be analyzed in the same way
726 // For better performance it is implemented here again or make the Impl-Method
727 // of the Introspection configurable for this purpose.
728 Reference
< XIntrospection
> xIntrospection
= getIntrospection();
729 if( !xIntrospection
.is() )
730 return Sequence
< Reference
<XEventListener
> >();
732 // Inspect Introspection
733 Any
aObjAny( &xObject
, cppu::UnoType
<XInterface
>::get() );
735 Reference
<XIntrospectionAccess
> xAccess
= xIntrospection
->inspect(aObjAny
);
737 return Sequence
< Reference
<XEventListener
> >();
739 Sequence
< Reference
<XEventListener
> > aRet(nCount
);
740 Reference
<XEventListener
>* pArray
= aRet
.getArray();
742 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
744 pArray
[i
] = attachListenerForTarget(
745 xAccess
, xInvocationAdapterFactory
, AllListeners
[ i
],
746 aObjAny
, aListeners
[i
].Helper
, aListeners
[i
].ListenerType
, aListeners
[i
].AddListenerParam
);
753 Reference
< XEventListener
> EventAttacherImpl::attachSingleEventListener
755 const Reference
< XInterface
>& xObject
,
756 const Reference
< XAllListener
>& AllListener
,
758 const OUString
& ListenerType
,
759 const OUString
& AddListenerParam
,
760 const OUString
& EventMethod
762 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
, std::exception
)
764 // Subscribe FilterListener
765 Reference
< XAllListener
> aFilterListener
= (XAllListener
*)
766 new FilterAllListenerImpl( this, EventMethod
, AllListener
);
767 return attachListener( xObject
, aFilterListener
, Helper
, ListenerType
, AddListenerParam
);
771 void EventAttacherImpl::removeListener
773 const Reference
< XInterface
>& xObject
,
774 const OUString
& ListenerType
,
775 const OUString
& AddListenerParam
,
776 const Reference
< XEventListener
>& aToRemoveListener
778 throw( IllegalArgumentException
, IntrospectionException
, RuntimeException
, std::exception
)
780 if( !xObject
.is() || !aToRemoveListener
.is() )
781 throw IllegalArgumentException();
783 Reference
< XIdlReflection
> xReflection
= getReflection();
784 if( !xReflection
.is() )
785 throw IntrospectionException();
787 // Sign off, Call the fitting removeListener method
788 // First Introspection, as the Methods can be analyzed in the same way
789 // For better performance it is implemented here again or make the Impl-Method
790 // of the Introspection configurable for this purpose.
791 Reference
< XIntrospection
> xIntrospection
= getIntrospection();
792 if( !xIntrospection
.is() )
793 throw IntrospectionException();
795 //Inspect Introspection
796 Any
aObjAny( &xObject
, cppu::UnoType
<XInterface
>::get());
797 Reference
< XIntrospectionAccess
> xAccess
= xIntrospection
->inspect( aObjAny
);
799 throw IntrospectionException();
801 // Create name of the removeListener-Method
802 OUString aRemoveListenerName
;
803 OUString
aListenerName( ListenerType
);
804 sal_Int32 nIndex
= aListenerName
.lastIndexOf( '.' );
805 // set index to the interface name without package name
811 if( aListenerName
[nIndex
] == 'X' )
812 // erase X from the interface name
813 aListenerName
= aListenerName
.copy( nIndex
+1 );
814 aRemoveListenerName
= "remove" + aListenerName
;
816 // Search methods for the correct removeListener method
817 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
= xAccess
->getMethods( MethodConcept::LISTENER
);
818 sal_uInt32 i
, nLen
= aMethodSeq
.getLength();
819 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
820 for( i
= 0 ; i
< nLen
; i
++ )
823 const Reference
< XIdlMethod
>& rxMethod
= pMethods
[i
];
825 // Is it the right method?
826 if( aRemoveListenerName
== rxMethod
->getName() )
828 Sequence
< Reference
< XIdlClass
> > params
= rxMethod
->getParameterTypes();
829 sal_uInt32 nParamCount
= params
.getLength();
831 // Just the Listener as parameter?
832 if( nParamCount
== 1 )
834 Sequence
< Any
> args( 1 );
835 args
.getArray()[0] <<= aToRemoveListener
;
838 rxMethod
->invoke( aObjAny
, args
);
840 catch( const InvocationTargetException
& )
842 throw IntrospectionException();
845 // Else pass the other parameter
846 else if( nParamCount
== 2 )
848 Sequence
< Any
> args( 2 );
849 Any
* pAnys
= args
.getArray();
851 // Check the type of the 1st parameter
852 Reference
< XIdlClass
> xParamClass
= params
.getConstArray()[0];
853 if( xParamClass
->getTypeClass() == TypeClass_STRING
)
854 pAnys
[0] <<= AddListenerParam
;
856 // 2nd parameter == Listener? TODO: Test!
857 pAnys
[1] <<= aToRemoveListener
;
859 // TODO: Convert String -> ?
863 rxMethod
->invoke( aObjAny
, args
);
865 catch( const InvocationTargetException
& )
867 throw IntrospectionException();
875 Sequence
< Reference
<XEventListener
> > EventAttacherImpl::attachMultipleEventListeners(
876 const Reference
<XInterface
>& xObject
, const Sequence
<com::sun::star::script::EventListener
>& aListeners
)
877 throw( IllegalArgumentException
, ServiceNotRegisteredException
, CannotCreateAdapterException
, IntrospectionException
, RuntimeException
, std::exception
)
879 sal_Int32 nCount
= aListeners
.getLength();
880 Sequence
< Reference
<XAllListener
> > aFilterListeners(nCount
);
881 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
883 aFilterListeners
[i
] = (XAllListener
*)
884 new FilterAllListenerImpl(this, aListeners
[i
].EventMethod
, aListeners
[i
].AllListener
);
887 return attachListeners(xObject
, aFilterListeners
, aListeners
);
894 SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
evtatt_component_getFactory(
895 const sal_Char
* pImplName
, void * pServiceManager
, void * )
899 if (pServiceManager
&& rtl_str_compare( pImplName
, IMPLNAME
) == 0)
901 Reference
< XSingleServiceFactory
> xFactory( createOneInstanceFactory(
902 static_cast< XMultiServiceFactory
* >( pServiceManager
),
903 OUString( IMPLNAME
),
904 ::comp_EventAttacher::EventAttacherImpl_CreateInstance
,
905 ::comp_EventAttacher::EventAttacherImpl::getSupportedServiceNames_Static() ) );
910 pRet
= xFactory
.get();
920 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */