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 SAL_DLLPUBLIC_EXPORT 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 SAL_DLLPUBLIC_EXPORT 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