update dev300-m58
[ooovba.git] / eventattacher / source / eventattacher.cxx
blob2cce29fc11f877614cf7fcea9457d82c5e189764
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eventattacher.cxx,v $
10 * $Revision: 1.7 $
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;
57 using namespace cppu;
58 using namespace osl;
59 using namespace rtl;
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 >
73 public:
74 InvocationToAllListenerMapper( const Reference< XIdlClass >& ListenerType,
75 const Reference< XAllListener >& AllListener, const Any& Helper );
77 // XInvocation
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 );
87 private:
88 Reference< XIdlReflection > m_xCoreReflection;
89 Reference< XAllListener > m_xAllListener;
90 Reference< XIdlClass > m_xListenerType;
91 Any m_Helper;
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,
101 const Any& Helper
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 );
112 return xAdapter;
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 )
122 , m_Helper( Helper )
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 )
139 Any aRet;
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;
144 if( !xMethod.is() )
145 return aRet;
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;
153 else
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;
165 break;
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;
177 if( bApproveFiring )
178 aRet = m_xAllListener->approveFiring( aAllEvent );
179 else
180 m_xAllListener->firing( aAllEvent );
181 return aRet;
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 )
195 return Any();
198 //*************************************************************************
199 sal_Bool SAL_CALL InvocationToAllListenerMapper::hasMethod(const OUString& Name)
200 throw( RuntimeException )
202 Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( Name );
203 return xMethod.is();
206 //*************************************************************************
207 sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const OUString& Name)
208 throw( RuntimeException )
210 Reference< XIdlField > xField = m_xListenerType->getField( Name );
211 return xField.is();
214 //*************************************************************************
215 // class EventAttacherImpl
216 // represents an implementation of the EventAttacher service
217 //*************************************************************************
218 class EventAttacherImpl : public WeakImplHelper3 < XEventAttacher, XInitialization, XServiceInfo >
220 public:
221 EventAttacherImpl( const Reference< XMultiServiceFactory >& );
222 ~EventAttacherImpl();
224 // XServiceInfo
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( );
231 // XInitialization
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;
254 private:
255 Mutex m_aMutex;
256 Reference< XMultiServiceFactory > m_xSMgr;
258 // Services merken
259 Reference< XIntrospection > m_xIntrospection;
260 Reference< XIdlReflection > m_xReflection;
261 Reference< XTypeConverter > m_xConverter;
262 Reference< XInvocationAdapterFactory > m_xInvocationAdapterFactory;
264 // needed services
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 )
273 : m_xSMgr( 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);
288 if (pEventAttacher)
290 xRet = Reference<XInterface>::query(pEventAttacher);
293 return xRet;
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 )
311 return sal_True;
312 return sal_False;
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;
341 pArray[i] >>= xALAS;
342 if( xALAS.is() )
344 Guard< Mutex > aGuard( m_aMutex );
345 m_xInvocationAdapterFactory = xALAS;
347 // Introspection service ?
348 Reference< XIntrospection > xI;
349 pArray[i] >>= xI;
350 if( xI.is() )
352 Guard< Mutex > aGuard( m_aMutex );
353 m_xIntrospection = xI;
355 // Reflection service ?
356 Reference< XIdlReflection > xIdlR;
357 pArray[i] >>= xIdlR;
358 if( xIdlR.is() )
360 Guard< Mutex > aGuard( m_aMutex );
361 m_xReflection = xIdlR;
363 // Converter Service ?
364 Reference< XTypeConverter > xC;
365 pArray[i] >>= xC;
366 if( xC.is() )
368 Guard< Mutex > aGuard( m_aMutex );
369 m_xConverter = xC;
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 );
432 return m_xConverter;
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 >
442 public:
443 FilterAllListenerImpl( EventAttacherImpl * pEA_, const OUString& EventMethod_,
444 const Reference< XAllListener >& AllListener_ );
446 // XAllListener
447 virtual void SAL_CALL firing(const AllEventObject& Event) throw( RuntimeException );
448 virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw( InvocationTargetException, RuntimeException );
450 // XEventListener
451 virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException );
453 private:
454 // convert
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_ )
467 : m_pEA( pEA_ )
468 , m_xEAHold( *pEA_ )
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 >();
497 break;
499 case TypeClass_BOOLEAN:
500 rRet <<= sal_True;
501 break;
503 case TypeClass_STRING:
504 rRet <<= OUString();
505 break;
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;
514 default:
515 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 );
523 else
524 throw CannotConvertException(); // TODO TypeConversionException
528 //*************************************************************************
529 Any SAL_CALL FilterAllListenerImpl::approveFiring( const AllEventObject& Event )
530 throw( InvocationTargetException, RuntimeException )
532 Any aRet;
534 // Nur durchreichen, wenn es die richtige Methode ist
535 if( Event.MethodName == m_EventMethod && m_AllListener.is() )
536 aRet = m_AllListener->approveFiring( Event );
537 else
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 );
545 if( xMeth.is() )
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)) );
557 return aRet;
560 //*************************************************************************
561 void FilterAllListenerImpl::disposing(const EventObject& )
562 throw( RuntimeException )
564 // TODO: ???
568 //*************************************************************************
569 Reference< XEventListener > EventAttacherImpl::attachListener
571 const Reference< XInterface >& xObject,
572 const Reference< XAllListener >& AllListener,
573 const Any& Helper,
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() )
603 return xRet;
605 // und unspecten
606 Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
608 Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
609 if( !xAccess.is() )
610 return xRet;
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
617 if( nIndex == -1 )
618 // not found
619 nIndex = 0;
620 else
621 nIndex++;
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 );
655 if( !xAdapter.is() )
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 -> ?
691 // else
694 rxMethod->invoke( aObjAny, args );
696 catch( InvocationTargetException& )
698 throw IntrospectionException();
701 break;
702 // else...
703 // Alles andere wird nicht unterstuetzt
707 return xRet;
710 // XEventAttacher
711 Reference< XEventListener > EventAttacherImpl::attachSingleEventListener
713 const Reference< XInterface >& xObject,
714 const Reference< XAllListener >& AllListener,
715 const Any& Helper,
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);
728 // XEventAttacher
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();
757 // und inspecten
758 Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
759 Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
760 if( !xAccess.is() )
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
768 if( nIndex == -1 )
769 // not found
770 nIndex = 0;
771 else
772 nIndex++;
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 -> ?
822 // else
825 rxMethod->invoke( aObjAny, args );
827 catch( InvocationTargetException& )
829 throw IntrospectionException();
832 break;
839 extern "C"
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 )
851 if (pRegistryKey)
855 // DefaultRegistry
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] );
866 return sal_True;
868 catch (InvalidRegistryException &)
870 OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
873 return sal_False;
875 //==================================================================================================
876 void * SAL_CALL component_getFactory(
877 const sal_Char * pImplName, void * pServiceManager, void * )
879 void * pRet = 0;
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() ) );
889 if (xFactory.is())
891 xFactory->acquire();
892 pRet = xFactory.get();
896 return pRet;