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