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