xref: /trunk/main/eventattacher/source/eventattacher.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #include <osl/diagnose.h>
24 #include <com/sun/star/lang/XServiceInfo.hpp>
25 #include <com/sun/star/lang/XInitialization.hpp>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
28 #include <com/sun/star/registry/XRegistryKey.hpp>
29 #include <com/sun/star/beans/XIntrospection.hpp>
30 #include <com/sun/star/beans/MethodConcept.hpp>
31 #include <com/sun/star/script/XEventAttacher.hpp>
32 #include <com/sun/star/script/XTypeConverter.hpp>
33 #include <com/sun/star/script/XAllListener.hpp>
34 #include <com/sun/star/script/XInvocationAdapterFactory.hpp>
35 #include <com/sun/star/reflection/XIdlReflection.hpp>
36 
37 // InvocationToAllListenerMapper
38 #include <com/sun/star/script/XInvocation.hpp>
39 #include <cppuhelper/weak.hxx>
40 #include <cppuhelper/factory.hxx>
41 #include <cppuhelper/implbase1.hxx>
42 #include <cppuhelper/implbase3.hxx>
43 
44 using namespace com::sun::star::uno;
45 using namespace com::sun::star::registry;
46 using namespace com::sun::star::lang;
47 using namespace com::sun::star::beans;
48 using namespace com::sun::star::script;
49 using namespace com::sun::star::reflection;
50 using namespace cppu;
51 using namespace osl;
52 using namespace rtl;
53 
54 
55 #define SERVICENAME "com.sun.star.script.EventAttacher"
56 #define IMPLNAME    "com.sun.star.comp.EventAttacher"
57 
58 namespace comp_EventAttacher {
59 
60 //*************************************************************************
61 //  class InvocationToAllListenerMapper
62 //  helper class to map XInvocation to XAllListener
63 //*************************************************************************
64 class InvocationToAllListenerMapper : public WeakImplHelper1< XInvocation >
65 {
66 public:
67     InvocationToAllListenerMapper( const Reference< XIdlClass >& ListenerType,
68         const Reference< XAllListener >& AllListener, const Any& Helper );
69 
70     // XInvocation
71     virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection(void);
72     virtual Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam);
73     virtual void SAL_CALL setValue(const OUString& PropertyName, const Any& Value);
74     virtual Any SAL_CALL getValue(const OUString& PropertyName);
75     virtual sal_Bool SAL_CALL hasMethod(const OUString& Name);
76     virtual sal_Bool SAL_CALL hasProperty(const OUString& Name);
77 
78 private:
79     Reference< XIdlReflection >  m_xCoreReflection;
80     Reference< XAllListener >    m_xAllListener;
81     Reference< XIdlClass >       m_xListenerType;
82     Any                          m_Helper;
83 };
84 
85 
86 // Function to replace AllListenerAdapterService::createAllListerAdapter
createAllListenerAdapter(const Reference<XInvocationAdapterFactory> & xInvocationAdapterFactory,const Reference<XIdlClass> & xListenerType,const Reference<XAllListener> & xListener,const Any & Helper)87 Reference< XInterface > createAllListenerAdapter
88 (
89     const Reference< XInvocationAdapterFactory >& xInvocationAdapterFactory,
90     const Reference< XIdlClass >& xListenerType,
91     const Reference< XAllListener >& xListener,
92     const Any& Helper
93 )
94 {
95     Reference< XInterface > xAdapter;
96     if( xInvocationAdapterFactory.is() && xListenerType.is() && xListener.is() )
97     {
98        Reference< XInvocation > xInvocationToAllListenerMapper =
99             (XInvocation*)new InvocationToAllListenerMapper( xListenerType, xListener, Helper );
100         Type aListenerType( xListenerType->getTypeClass(), xListenerType->getName());
101         xAdapter = xInvocationAdapterFactory->createAdapter( xInvocationToAllListenerMapper, aListenerType );
102     }
103     return xAdapter;
104 }
105 
106 
107 //--------------------------------------------------------------------------------------------------
108 // InvocationToAllListenerMapper
InvocationToAllListenerMapper(const Reference<XIdlClass> & ListenerType,const Reference<XAllListener> & AllListener,const Any & Helper)109 InvocationToAllListenerMapper::InvocationToAllListenerMapper
110     ( const Reference< XIdlClass >& ListenerType, const Reference< XAllListener >& AllListener, const Any& Helper )
111         : m_xAllListener( AllListener )
112         , m_xListenerType( ListenerType )
113         , m_Helper( Helper )
114 {
115 }
116 
117 //*************************************************************************
getIntrospection(void)118 Reference< XIntrospectionAccess > SAL_CALL InvocationToAllListenerMapper::getIntrospection(void)
119 {
120     return Reference< XIntrospectionAccess >();
121 }
122 
123 //*************************************************************************
invoke(const OUString & FunctionName,const Sequence<Any> & Params,Sequence<sal_Int16> &,Sequence<Any> &)124 Any SAL_CALL InvocationToAllListenerMapper::invoke(const OUString& FunctionName, const Sequence< Any >& Params,
125     Sequence< sal_Int16 >& , Sequence< Any >& )
126 {
127     Any aRet;
128 
129     // Check if to firing or approveFiring has to be called
130     Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( FunctionName );
131     sal_Bool bApproveFiring = sal_False;
132     if( !xMethod.is() )
133         return aRet;
134     Reference< XIdlClass > xReturnType = xMethod->getReturnType();
135     Sequence< Reference< XIdlClass > > aExceptionSeq = xMethod->getExceptionTypes();
136     if( ( xReturnType.is() && xReturnType->getTypeClass() != TypeClass_VOID ) ||
137         aExceptionSeq.getLength() > 0 )
138     {
139         bApproveFiring = sal_True;
140     }
141     else
142     {
143         Sequence< ParamInfo > aParamSeq = xMethod->getParameterInfos();
144         sal_uInt32 nParamCount = aParamSeq.getLength();
145         if( nParamCount > 1 )
146         {
147             const ParamInfo* pInfos = aParamSeq.getConstArray();
148             for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
149             {
150                 if( pInfos[ i ].aMode != ParamMode_IN )
151                 {
152                     bApproveFiring = sal_True;
153                     break;
154                 }
155             }
156         }
157     }
158 
159     AllEventObject aAllEvent;
160     aAllEvent.Source = (OWeakObject*) this;
161     aAllEvent.Helper = m_Helper;
162     aAllEvent.ListenerType = Type(m_xListenerType->getTypeClass(), m_xListenerType->getName());
163     aAllEvent.MethodName = FunctionName;
164     aAllEvent.Arguments = Params;
165     if( bApproveFiring )
166         aRet = m_xAllListener->approveFiring( aAllEvent );
167     else
168         m_xAllListener->firing( aAllEvent );
169     return aRet;
170 }
171 
172 //*************************************************************************
setValue(const OUString &,const Any &)173 void SAL_CALL InvocationToAllListenerMapper::setValue(const OUString& , const Any& )
174 {
175 }
176 
177 //*************************************************************************
getValue(const OUString &)178 Any SAL_CALL InvocationToAllListenerMapper::getValue(const OUString& )
179 {
180     return Any();
181 }
182 
183 //*************************************************************************
hasMethod(const OUString & Name)184 sal_Bool SAL_CALL InvocationToAllListenerMapper::hasMethod(const OUString& Name)
185 {
186     Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( Name );
187     return xMethod.is();
188 }
189 
190 //*************************************************************************
hasProperty(const OUString & Name)191 sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const OUString& Name)
192 {
193     Reference< XIdlField > xField = m_xListenerType->getField( Name );
194     return xField.is();
195 }
196 
197 //*************************************************************************
198 //  class EventAttacherImpl
199 //  represents an implementation of the EventAttacher service
200 //*************************************************************************
201 class EventAttacherImpl : public WeakImplHelper3 < XEventAttacher, XInitialization, XServiceInfo >
202 {
203 public:
204     EventAttacherImpl( const Reference< XMultiServiceFactory >& );
205     ~EventAttacherImpl();
206 
207     // XServiceInfo
208     virtual OUString SAL_CALL getImplementationName(  );
209     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName );
210     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(  );
211     static OUString SAL_CALL getImplementationName_Static(  );
212     static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(  );
213 
214     // XInitialization
215     virtual void SAL_CALL initialize( const Sequence< Any >& aArguments );
216 
217     // Methoden von XEventAttacher
218     virtual Reference< XEventListener > SAL_CALL attachListener(const Reference< XInterface >& xObject,
219             const Reference< XAllListener >& AllListener, const Any& Helper,
220             const OUString& ListenerType, const OUString& AddListenerParam);
221     virtual Reference< XEventListener > SAL_CALL attachSingleEventListener(const Reference< XInterface >& xObject,
222             const Reference< XAllListener >& AllListener, const Any& Helper,
223             const OUString& ListenerType, const OUString& AddListenerParam,
224             const OUString& EventMethod);
225     virtual void SAL_CALL removeListener(const Reference< XInterface >& xObject,
226             const OUString& ListenerType, const OUString& AddListenerParam,
227             const Reference< XEventListener >& aToRemoveListener);
228 
229     // used by FilterAllListener_Impl
230     Reference< XTypeConverter > getConverter();
231 
232     friend class FilterAllListenerImpl;
233 private:
234     Mutex                               m_aMutex;
235     Reference< XMultiServiceFactory >   m_xSMgr;
236 
237     // Services merken
238     Reference< XIntrospection >             m_xIntrospection;
239     Reference< XIdlReflection >             m_xReflection;
240     Reference< XTypeConverter >             m_xConverter;
241     Reference< XInvocationAdapterFactory >  m_xInvocationAdapterFactory;
242 
243     // needed services
244     Reference< XIntrospection >             getIntrospection();
245     Reference< XIdlReflection >             getReflection();
246     Reference< XInvocationAdapterFactory >  getInvocationAdapterService();
247 };
248 
249 
250 //*************************************************************************
EventAttacherImpl(const Reference<XMultiServiceFactory> & rSMgr)251 EventAttacherImpl::EventAttacherImpl( const Reference< XMultiServiceFactory >& rSMgr )
252     : m_xSMgr( rSMgr )
253 {
254 }
255 
256 //*************************************************************************
~EventAttacherImpl()257 EventAttacherImpl::~EventAttacherImpl()
258 {
259 }
260 
261 //*************************************************************************
EventAttacherImpl_CreateInstance(const Reference<XMultiServiceFactory> & rSMgr)262 Reference< XInterface > SAL_CALL EventAttacherImpl_CreateInstance( const Reference< XMultiServiceFactory >& rSMgr )
263 {
264     Reference< XInterface > xRet;
265     XEventAttacher *pEventAttacher = (XEventAttacher*) new EventAttacherImpl(rSMgr);
266 
267     if (pEventAttacher)
268     {
269         xRet = Reference<XInterface>::query(pEventAttacher);
270     }
271 
272     return xRet;
273 }
274 
275 //*************************************************************************
getImplementationName()276 OUString SAL_CALL EventAttacherImpl::getImplementationName(  )
277 {
278     return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
279 }
280 
281 //*************************************************************************
supportsService(const OUString & ServiceName)282 sal_Bool SAL_CALL EventAttacherImpl::supportsService( const OUString& ServiceName )
283 {
284     Sequence< OUString > aSNL = getSupportedServiceNames();
285     const OUString * pArray = aSNL.getArray();
286     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
287         if( pArray[i] == ServiceName )
288             return sal_True;
289     return sal_False;
290 }
291 
292 //*************************************************************************
getSupportedServiceNames()293 Sequence<OUString> SAL_CALL EventAttacherImpl::getSupportedServiceNames(  )
294 {
295     return getSupportedServiceNames_Static();
296 }
297 
298 //*************************************************************************
getSupportedServiceNames_Static()299 Sequence<OUString> SAL_CALL EventAttacherImpl::getSupportedServiceNames_Static(  )
300 {
301     OUString aStr( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME ) );
302     return Sequence< OUString >( &aStr, 1 );
303 }
304 
305 //*************************************************************************
initialize(const Sequence<Any> & Arguments)306 void SAL_CALL EventAttacherImpl::initialize(const Sequence< Any >& Arguments)
307 {
308     // get services from the argument list
309     const Any * pArray = Arguments.getConstArray();
310     for( sal_Int32 i = 0; i < Arguments.getLength(); i++ )
311     {
312         if( pArray[i].getValueType().getTypeClass() != TypeClass_INTERFACE )
313             throw IllegalArgumentException();
314 
315         // InvocationAdapter service ?
316         Reference< XInvocationAdapterFactory > xALAS;
317         pArray[i] >>= xALAS;
318         if( xALAS.is() )
319         {
320             Guard< Mutex > aGuard( m_aMutex );
321             m_xInvocationAdapterFactory = xALAS;
322         }
323         // Introspection service ?
324         Reference< XIntrospection > xI;
325         pArray[i] >>= xI;
326         if( xI.is() )
327         {
328             Guard< Mutex > aGuard( m_aMutex );
329             m_xIntrospection = xI;
330         }
331         // Reflection service ?
332         Reference< XIdlReflection > xIdlR;
333         pArray[i] >>= xIdlR;
334         if( xIdlR.is() )
335         {
336             Guard< Mutex > aGuard( m_aMutex );
337             m_xReflection = xIdlR;
338         }
339         // Converter Service ?
340         Reference< XTypeConverter > xC;
341         pArray[i] >>= xC;
342         if( xC.is() )
343         {
344             Guard< Mutex > aGuard( m_aMutex );
345             m_xConverter = xC;
346         }
347 
348         // no right interface
349         if( !xALAS.is() && !xI.is() && !xIdlR.is() && !xC.is() )
350             throw IllegalArgumentException();
351     }
352 }
353 
354 //*************************************************************************
355 //*** Private Hilfs-Methoden ***
getIntrospection()356 Reference< XIntrospection > EventAttacherImpl::getIntrospection()
357 {
358     Guard< Mutex > aGuard( m_aMutex );
359     // Haben wir den Service schon? Sonst anlegen
360     if( !m_xIntrospection.is() )
361     {
362         Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection") ) );
363         m_xIntrospection = Reference< XIntrospection >( xIFace, UNO_QUERY );
364     }
365     return m_xIntrospection;
366 }
367 
368 //*************************************************************************
369 //*** Private Hilfs-Methoden ***
getReflection()370 Reference< XIdlReflection > EventAttacherImpl::getReflection()
371 {
372     Guard< Mutex > aGuard( m_aMutex );
373     // Haben wir den Service schon? Sonst anlegen
374     if( !m_xReflection.is() )
375     {
376         Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ) );
377         m_xReflection = Reference< XIdlReflection >( xIFace, UNO_QUERY);
378     }
379     return m_xReflection;
380 }
381 
382 //*************************************************************************
383 //*** Private Hilfs-Methoden ***
getInvocationAdapterService()384 Reference< XInvocationAdapterFactory > EventAttacherImpl::getInvocationAdapterService()
385 {
386     Guard< Mutex > aGuard( m_aMutex );
387     // Haben wir den Service schon? Sonst anlegen
388     if( !m_xInvocationAdapterFactory.is() )
389     {
390         Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.script.InvocationAdapterFactory") ) );
391         m_xInvocationAdapterFactory = Reference< XInvocationAdapterFactory >( xIFace, UNO_QUERY );
392     }
393     return m_xInvocationAdapterFactory;
394 }
395 
396 
397 //*************************************************************************
398 //*** Private Hilfs-Methoden ***
getConverter()399 Reference< XTypeConverter > EventAttacherImpl::getConverter()
400 {
401     Guard< Mutex > aGuard( m_aMutex );
402     // Haben wir den Service schon? Sonst anlegen
403     if( !m_xConverter.is() )
404     {
405         Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.script.Converter") ) );
406         m_xConverter = Reference< XTypeConverter >( xIFace, UNO_QUERY );
407     }
408     return m_xConverter;
409 }
410 
411 //------------------------------------------------------------------------
412 //------------------------------------------------------------------------
413 //------------------------------------------------------------------------
414 // Implementation eines EventAttacher-bezogenen AllListeners, der
415 // nur einzelne Events an einen allgemeinen AllListener weiterleitet
416 class FilterAllListenerImpl : public WeakImplHelper1< XAllListener  >
417 {
418 public:
419     FilterAllListenerImpl( EventAttacherImpl * pEA_, const OUString& EventMethod_,
420                            const Reference< XAllListener >& AllListener_ );
421 
422     // XAllListener
423     virtual void SAL_CALL firing(const AllEventObject& Event);
424     virtual Any SAL_CALL approveFiring(const AllEventObject& Event);
425 
426     // XEventListener
427     virtual void SAL_CALL disposing(const EventObject& Source);
428 
429 private:
430     // convert
431     void convertToEventReturn( Any & rRet, const Type& rRetType );
432 
433     EventAttacherImpl *         m_pEA;
434     Reference< XInterface >     m_xEAHold;
435     OUString                    m_EventMethod;
436     Reference< XAllListener >   m_AllListener;
437 };
438 
439 //*************************************************************************
FilterAllListenerImpl(EventAttacherImpl * pEA_,const OUString & EventMethod_,const Reference<XAllListener> & AllListener_)440 FilterAllListenerImpl::FilterAllListenerImpl( EventAttacherImpl * pEA_, const OUString& EventMethod_,
441                                               const Reference< XAllListener >& AllListener_ )
442         : m_pEA( pEA_ )
443         , m_xEAHold( *pEA_ )
444         , m_EventMethod( EventMethod_ )
445         , m_AllListener( AllListener_ )
446 {
447 }
448 
449 //*************************************************************************
firing(const AllEventObject & Event)450 void SAL_CALL FilterAllListenerImpl::firing(const AllEventObject& Event)
451 {
452     // Nur durchreichen, wenn es die richtige Methode ist
453     if( Event.MethodName == m_EventMethod && m_AllListener.is() )
454         m_AllListener->firing( Event );
455 }
456 
457 //*************************************************************************
458 // Convert to the standard event return
convertToEventReturn(Any & rRet,const Type & rRetType)459 void FilterAllListenerImpl::convertToEventReturn( Any & rRet, const Type & rRetType )
460 {
461     // no return value? Set to the specified values
462     if( rRet.getValueType().getTypeClass() == TypeClass_VOID )
463     {
464         switch( rRetType.getTypeClass()  )
465         {
466             case TypeClass_INTERFACE:
467                 {
468                 rRet <<= Reference< XInterface >();
469                 }
470                 break;
471 
472             case TypeClass_BOOLEAN:
473                 rRet <<= sal_True;
474                 break;
475 
476             case TypeClass_STRING:
477                 rRet <<= OUString();
478                 break;
479 
480             case TypeClass_FLOAT:           rRet <<= float(0);  break;
481             case TypeClass_DOUBLE:          rRet <<= double(0.0);   break;
482             case TypeClass_BYTE:            rRet <<= sal_uInt8( 0 );    break;
483             case TypeClass_SHORT:           rRet <<= sal_Int16( 0 );    break;
484             case TypeClass_LONG:            rRet <<= sal_Int32( 0 );    break;
485             case TypeClass_UNSIGNED_SHORT:  rRet <<= sal_uInt16( 0 );   break;
486             case TypeClass_UNSIGNED_LONG:   rRet <<= sal_uInt32( 0 );   break;
487                      default:
488             break;
489         }
490     }
491     else if( !rRet.getValueType().equals( rRetType ) )
492     {
493         Reference< XTypeConverter > xConverter = m_pEA->getConverter();
494         if( xConverter.is() )
495             rRet = xConverter->convertTo( rRet, rRetType );
496         else
497             throw CannotConvertException(); // TODO TypeConversionException
498     }
499 }
500 
501 //*************************************************************************
approveFiring(const AllEventObject & Event)502 Any SAL_CALL FilterAllListenerImpl::approveFiring( const AllEventObject& Event )
503 {
504     Any aRet;
505 
506     // Nur durchreichen, wenn es die richtige Methode ist
507     if( Event.MethodName == m_EventMethod && m_AllListener.is() )
508         aRet = m_AllListener->approveFiring( Event );
509     else
510     {
511         // Convert to the standard event return
512         try
513         {
514             Reference< XIdlClass > xListenerType = m_pEA->getReflection()->
515                         forName( Event.ListenerType.getTypeName() );
516             Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName );
517             if( xMeth.is() )
518             {
519                 Reference< XIdlClass > xRetType = xMeth->getReturnType();
520                 Type aRetType( xRetType->getTypeClass(), xRetType->getName() );
521                 convertToEventReturn( aRet, aRetType );
522             }
523         }
524         catch( CannotConvertException& e )
525         {
526             throw InvocationTargetException( OUString(), Reference< XInterface >(), Any(&e, ::getCppuType( (CannotConvertException*)0)) );
527         }
528     }
529     return aRet;
530 }
531 
532 //*************************************************************************
disposing(const EventObject &)533 void FilterAllListenerImpl::disposing(const EventObject& )
534 {
535     // TODO: ???
536 }
537 
538 
539 //*************************************************************************
attachListener(const Reference<XInterface> & xObject,const Reference<XAllListener> & AllListener,const Any & Helper,const OUString & ListenerType,const OUString & AddListenerParam)540 Reference< XEventListener > EventAttacherImpl::attachListener
541 (
542     const Reference< XInterface >& xObject,
543     const Reference< XAllListener >& AllListener,
544     const Any& Helper,
545     const OUString& ListenerType,
546     const OUString& AddListenerParam
547 )
548 {
549     if( !xObject.is() || !AllListener.is() )
550         throw IllegalArgumentException();
551 
552     Reference< XEventListener > xRet = NULL;
553 
554     // InvocationAdapterService holen
555     Reference< XInvocationAdapterFactory > xInvocationAdapterFactory = getInvocationAdapterService();
556     if( !xInvocationAdapterFactory.is() )
557         throw ServiceNotRegisteredException();
558 
559     // Listener-Klasse per Reflection besorgen
560     Reference< XIdlReflection > xReflection = getReflection();
561     if( !xReflection.is() )
562         throw ServiceNotRegisteredException();
563 
564     // Anmelden, dazu passende addListener-Methode aufrufen
565     // Zunaechst ueber Introspection gehen, da die Methoden in der gleichen
566     // Weise analysiert werden koennen. Fuer bessere Performance entweder
567     // hier nochmal implementieren oder die Impl-Methode der Introspection
568     // fuer diesen Zweck konfigurierbar machen.
569 
570     // Introspection-Service holen
571     Reference< XIntrospection > xIntrospection = getIntrospection();
572     if( !xIntrospection.is() )
573         return xRet;
574 
575     // und unspecten
576     Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
577 
578     Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
579     if( !xAccess.is() )
580         return xRet;
581 
582     // Name der addListener-Methode zusammenbasteln
583     OUString aAddListenerName;
584     OUString aListenerName( ListenerType );
585     sal_Int32 nIndex = aListenerName.lastIndexOf( '.' );
586     // set index to the interface name without package name
587     if( nIndex == -1 )
588         // not found
589         nIndex = 0;
590     else
591         nIndex++;
592     if( aListenerName[nIndex] == 'X' )
593         // erase X from the interface name
594         aListenerName = aListenerName.copy( nIndex +1 );
595     aAddListenerName = OUString( RTL_CONSTASCII_USTRINGPARAM( "add" ) ) + aListenerName;
596 
597     // Methoden nach der passenden addListener-Methode durchsuchen
598     Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER );
599     sal_uInt32 i, nLen = aMethodSeq.getLength();
600     const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
601 
602     for( i = 0 ; i < nLen ; i++ )
603     {
604         // Methode ansprechen
605         const Reference< XIdlMethod >& rxMethod = pMethods[i];
606 
607         // Ist es die richtige Methode?
608         OUString aMethName = rxMethod->getName();
609 
610         if( aAddListenerName == aMethName )
611         {
612             Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes();
613             sal_uInt32 nParamCount = params.getLength();
614 
615             Reference< XIdlClass > xListenerType;
616             if( nParamCount == 1 )
617                 xListenerType = params.getConstArray()[0];
618             else if( nParamCount == 2 )
619                 xListenerType = params.getConstArray()[1];
620 
621             // Adapter zum eigentlichen Listener-Typ anfordern
622             Reference< XInterface > xAdapter = createAllListenerAdapter
623                 ( xInvocationAdapterFactory, xListenerType, AllListener, Helper );
624 
625             if( !xAdapter.is() )
626                 throw CannotCreateAdapterException();
627             xRet = Reference< XEventListener >( xAdapter, UNO_QUERY );
628 
629 
630             // Nur der Listener als Parameter?
631             if( nParamCount == 1 )
632             {
633                 Sequence< Any > args( 1 );
634                 args.getArray()[0] <<= xAdapter;
635                 try
636                 {
637                     rxMethod->invoke( aObjAny, args );
638                 }
639                 catch( InvocationTargetException& )
640                 {
641                     throw IntrospectionException();
642                 }
643             }
644             // Sonst den Zusatzparameter mit uebergeben
645             else if( nParamCount == 2 )
646             {
647                 Sequence< Any > args( 2 );
648                 Any* pAnys = args.getArray();
649 
650                 // Typ des 1. Parameters pruefen
651                 Reference< XIdlClass > xParamClass = params.getConstArray()[0];
652                 if( xParamClass->getTypeClass() == TypeClass_STRING )
653                 {
654                     pAnys[0] <<= AddListenerParam;
655                 }
656 
657                 // 2. Parameter == Listener? TODO: Pruefen!
658                 pAnys[1] <<= xAdapter;
659 
660                 // TODO: Konvertierung String -> ?
661                 // else
662                 try
663                 {
664                     rxMethod->invoke( aObjAny, args );
665                 }
666                 catch( InvocationTargetException& )
667                 {
668                     throw IntrospectionException();
669                 }
670             }
671             break;
672             // else...
673             // Alles andere wird nicht unterstuetzt
674         }
675     }
676 
677     return xRet;
678 }
679 
680 // XEventAttacher
attachSingleEventListener(const Reference<XInterface> & xObject,const Reference<XAllListener> & AllListener,const Any & Helper,const OUString & ListenerType,const OUString & AddListenerParam,const OUString & EventMethod)681 Reference< XEventListener > EventAttacherImpl::attachSingleEventListener
682 (
683     const Reference< XInterface >& xObject,
684     const Reference< XAllListener >& AllListener,
685     const Any& Helper,
686     const OUString& ListenerType,
687     const OUString& AddListenerParam,
688     const OUString& EventMethod
689 )
690 {
691     // FilterListener anmelden
692     Reference< XAllListener > aFilterListener = (XAllListener*)
693         new FilterAllListenerImpl( this, EventMethod, AllListener );
694     return attachListener( xObject, aFilterListener, Helper, ListenerType, AddListenerParam);
695 }
696 
697 // XEventAttacher
removeListener(const Reference<XInterface> & xObject,const OUString & ListenerType,const OUString & AddListenerParam,const Reference<XEventListener> & aToRemoveListener)698 void EventAttacherImpl::removeListener
699 (
700     const Reference< XInterface >& xObject,
701     const OUString& ListenerType,
702     const OUString& AddListenerParam,
703     const Reference< XEventListener >& aToRemoveListener
704 )
705 {
706     if( !xObject.is() || !aToRemoveListener.is() )
707         throw IllegalArgumentException();
708 
709     // Listener-Klasse per Reflection besorgen
710     Reference< XIdlReflection > xReflection = getReflection();
711     if( !xReflection.is() )
712         throw IntrospectionException();
713 
714     // Abmelden, dazu passende removeListener-Methode aufrufen
715     // Zunaechst ueber Introspection gehen, da die Methoden in der gleichen
716     // Weise analysiert werden koennen. Fuer bessere Performance entweder
717     // hier nochmal implementieren oder die Impl-Methode der Introspection
718     // fuer diesen Zweck konfigurierbar machen.
719 
720     // Introspection-Service holen
721     Reference< XIntrospection > xIntrospection = getIntrospection();
722     if( !xIntrospection.is() )
723         throw IntrospectionException();
724 
725     // und inspecten
726     Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
727     Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
728     if( !xAccess.is() )
729         throw IntrospectionException();
730 
731     // Name der removeListener-Methode zusammenbasteln
732     OUString aRemoveListenerName;
733     OUString aListenerName( ListenerType );
734     sal_Int32 nIndex = aListenerName.lastIndexOf( '.' );
735     // set index to the interface name without package name
736     if( nIndex == -1 )
737         // not found
738         nIndex = 0;
739     else
740         nIndex++;
741     if( aListenerName[nIndex] == 'X' )
742         // erase X from the interface name
743         aListenerName = aListenerName.copy( nIndex +1 );
744     aRemoveListenerName = OUString( RTL_CONSTASCII_USTRINGPARAM("remove") ) + aListenerName;
745 
746     // Methoden nach der passenden addListener-Methode durchsuchen
747     Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER );
748     sal_uInt32 i, nLen = aMethodSeq.getLength();
749     const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
750     for( i = 0 ; i < nLen ; i++ )
751     {
752         // Methode ansprechen
753         const Reference< XIdlMethod >& rxMethod = pMethods[i];
754 
755         // Ist es die richtige Methode?
756         if( aRemoveListenerName == rxMethod->getName() )
757         {
758             Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes();
759             sal_uInt32 nParamCount = params.getLength();
760 
761             // Nur der Listener als Parameter?
762             if( nParamCount == 1 )
763             {
764                 Sequence< Any > args( 1 );
765                 args.getArray()[0] <<= aToRemoveListener;
766                 try
767                 {
768                     rxMethod->invoke( aObjAny, args );
769                 }
770                 catch( InvocationTargetException& )
771                 {
772                     throw IntrospectionException();
773                 }
774             }
775             // Sonst den Zusatzparameter mit uebergeben
776             else if( nParamCount == 2 )
777             {
778                 Sequence< Any > args( 2 );
779                 Any* pAnys = args.getArray();
780 
781                 // Typ des 1. Parameters pruefen
782                 Reference< XIdlClass > xParamClass = params.getConstArray()[0];
783                 if( xParamClass->getTypeClass() == TypeClass_STRING )
784                     pAnys[0] <<= AddListenerParam;
785 
786                 // 2. Parameter == Listener? TODO: Pruefen!
787                 pAnys[1] <<= aToRemoveListener;
788 
789                 // TODO: Konvertierung String -> ?
790                 // else
791                 try
792                 {
793                     rxMethod->invoke( aObjAny, args );
794                 }
795                 catch( InvocationTargetException& )
796                 {
797                     throw IntrospectionException();
798                 }
799             }
800             break;
801         }
802     }
803 }
804 
805 }
806 
807 extern "C"
808 {
809 //==================================================================================================
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)810 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
811     const sal_Char ** ppEnvTypeName, uno_Environment ** )
812 {
813     *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
814 }
815 //==================================================================================================
component_getFactory(const sal_Char * pImplName,void * pServiceManager,void *)816 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
817     const sal_Char * pImplName, void * pServiceManager, void * )
818 {
819     void * pRet = 0;
820 
821     if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0)
822     {
823         Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory(
824             reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
825             OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) ),
826             ::comp_EventAttacher::EventAttacherImpl_CreateInstance,
827             ::comp_EventAttacher::EventAttacherImpl::getSupportedServiceNames_Static() ) );
828 
829         if (xFactory.is())
830         {
831             xFactory->acquire();
832             pRet = xFactory.get();
833         }
834     }
835 
836     return pRet;
837 }
838 }
839