Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #include <osl/diagnose.h>
20 : #include <com/sun/star/lang/XServiceInfo.hpp>
21 : #include <com/sun/star/lang/XInitialization.hpp>
22 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
23 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
24 : #include <com/sun/star/registry/XRegistryKey.hpp>
25 : #include <com/sun/star/beans/Introspection.hpp>
26 : #include <com/sun/star/beans/MethodConcept.hpp>
27 : #include <com/sun/star/script/XEventAttacher2.hpp>
28 : #include <com/sun/star/script/Converter.hpp>
29 : #include <com/sun/star/script/XAllListener.hpp>
30 : #include <com/sun/star/script/XInvocationAdapterFactory.hpp>
31 : #include <com/sun/star/reflection/theCoreReflection.hpp>
32 : #include <com/sun/star/reflection/XIdlReflection.hpp>
33 :
34 : // InvocationToAllListenerMapper
35 : #include <com/sun/star/script/XInvocation.hpp>
36 : #include <comphelper/processfactory.hxx>
37 : #include <cppuhelper/weak.hxx>
38 : #include <cppuhelper/factory.hxx>
39 : #include <cppuhelper/implbase1.hxx>
40 : #include <cppuhelper/implbase3.hxx>
41 :
42 : using namespace com::sun::star::uno;
43 : using namespace com::sun::star::registry;
44 : using namespace com::sun::star::lang;
45 : using namespace com::sun::star::beans;
46 : using namespace com::sun::star::script;
47 : using namespace com::sun::star::reflection;
48 : using namespace cppu;
49 : using namespace osl;
50 :
51 : using ::rtl::OUString;
52 :
53 :
54 : #define SERVICENAME "com.sun.star.script.EventAttacher"
55 : #define IMPLNAME "com.sun.star.comp.EventAttacher"
56 :
57 : namespace comp_EventAttacher {
58 :
59 : //*************************************************************************
60 : // class InvocationToAllListenerMapper
61 : // helper class to map XInvocation to XAllListener
62 : //*************************************************************************
63 0 : class InvocationToAllListenerMapper : public WeakImplHelper1< XInvocation >
64 : {
65 : public:
66 : InvocationToAllListenerMapper( const Reference< XIdlClass >& ListenerType,
67 : const Reference< XAllListener >& AllListener, const Any& Helper );
68 :
69 : // XInvocation
70 : virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection(void) throw( RuntimeException );
71 : virtual Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
72 : throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException );
73 : virtual void SAL_CALL setValue(const OUString& PropertyName, const Any& Value)
74 : throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException );
75 : virtual Any SAL_CALL getValue(const OUString& PropertyName) throw( UnknownPropertyException, RuntimeException );
76 : virtual sal_Bool SAL_CALL hasMethod(const OUString& Name) throw( RuntimeException );
77 : virtual sal_Bool SAL_CALL hasProperty(const OUString& Name) throw( RuntimeException );
78 :
79 : private:
80 : Reference< XIdlReflection > m_xCoreReflection;
81 : Reference< XAllListener > m_xAllListener;
82 : Reference< XIdlClass > m_xListenerType;
83 : Any m_Helper;
84 : };
85 :
86 :
87 : // Function to replace AllListenerAdapterService::createAllListerAdapter
88 0 : Reference< XInterface > createAllListenerAdapter
89 : (
90 : const Reference< XInvocationAdapterFactory >& xInvocationAdapterFactory,
91 : const Reference< XIdlClass >& xListenerType,
92 : const Reference< XAllListener >& xListener,
93 : const Any& Helper
94 : )
95 : {
96 0 : Reference< XInterface > xAdapter;
97 0 : if( xInvocationAdapterFactory.is() && xListenerType.is() && xListener.is() )
98 : {
99 : Reference< XInvocation > xInvocationToAllListenerMapper =
100 0 : (XInvocation*)new InvocationToAllListenerMapper( xListenerType, xListener, Helper );
101 0 : Type aListenerType( xListenerType->getTypeClass(), xListenerType->getName());
102 0 : xAdapter = xInvocationAdapterFactory->createAdapter( xInvocationToAllListenerMapper, aListenerType );
103 : }
104 0 : return xAdapter;
105 : }
106 :
107 :
108 : //--------------------------------------------------------------------------------------------------
109 : // InvocationToAllListenerMapper
110 0 : InvocationToAllListenerMapper::InvocationToAllListenerMapper
111 : ( const Reference< XIdlClass >& ListenerType, const Reference< XAllListener >& AllListener, const Any& Helper )
112 : : m_xAllListener( AllListener )
113 : , m_xListenerType( ListenerType )
114 0 : , m_Helper( Helper )
115 : {
116 0 : }
117 :
118 : //*************************************************************************
119 0 : Reference< XIntrospectionAccess > SAL_CALL InvocationToAllListenerMapper::getIntrospection(void)
120 : throw( RuntimeException )
121 : {
122 0 : return Reference< XIntrospectionAccess >();
123 : }
124 :
125 : //*************************************************************************
126 0 : Any SAL_CALL InvocationToAllListenerMapper::invoke(const OUString& FunctionName, const Sequence< Any >& Params,
127 : Sequence< sal_Int16 >& , Sequence< Any >& )
128 : throw( IllegalArgumentException, CannotConvertException,
129 : InvocationTargetException, RuntimeException )
130 : {
131 0 : Any aRet;
132 :
133 : // Check if to firing or approveFiring has to be called
134 0 : Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( FunctionName );
135 0 : sal_Bool bApproveFiring = sal_False;
136 0 : if( !xMethod.is() )
137 : return aRet;
138 0 : Reference< XIdlClass > xReturnType = xMethod->getReturnType();
139 0 : Sequence< Reference< XIdlClass > > aExceptionSeq = xMethod->getExceptionTypes();
140 0 : if( ( xReturnType.is() && xReturnType->getTypeClass() != TypeClass_VOID ) ||
141 0 : aExceptionSeq.getLength() > 0 )
142 : {
143 0 : bApproveFiring = sal_True;
144 : }
145 : else
146 : {
147 0 : Sequence< ParamInfo > aParamSeq = xMethod->getParameterInfos();
148 0 : sal_uInt32 nParamCount = aParamSeq.getLength();
149 0 : if( nParamCount > 1 )
150 : {
151 0 : const ParamInfo* pInfos = aParamSeq.getConstArray();
152 0 : for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
153 : {
154 0 : if( pInfos[ i ].aMode != ParamMode_IN )
155 : {
156 0 : bApproveFiring = sal_True;
157 0 : break;
158 : }
159 : }
160 0 : }
161 : }
162 :
163 0 : AllEventObject aAllEvent;
164 0 : aAllEvent.Source = (OWeakObject*) this;
165 0 : aAllEvent.Helper = m_Helper;
166 0 : aAllEvent.ListenerType = Type(m_xListenerType->getTypeClass(), m_xListenerType->getName());
167 0 : aAllEvent.MethodName = FunctionName;
168 0 : aAllEvent.Arguments = Params;
169 0 : if( bApproveFiring )
170 0 : aRet = m_xAllListener->approveFiring( aAllEvent );
171 : else
172 0 : m_xAllListener->firing( aAllEvent );
173 0 : return aRet;
174 : }
175 :
176 : //*************************************************************************
177 0 : void SAL_CALL InvocationToAllListenerMapper::setValue(const OUString& , const Any& )
178 : throw( UnknownPropertyException, CannotConvertException,
179 : InvocationTargetException, RuntimeException )
180 : {
181 0 : }
182 :
183 : //*************************************************************************
184 0 : Any SAL_CALL InvocationToAllListenerMapper::getValue(const OUString& )
185 : throw( UnknownPropertyException, RuntimeException )
186 : {
187 0 : return Any();
188 : }
189 :
190 : //*************************************************************************
191 0 : sal_Bool SAL_CALL InvocationToAllListenerMapper::hasMethod(const OUString& Name)
192 : throw( RuntimeException )
193 : {
194 0 : Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( Name );
195 0 : return xMethod.is();
196 : }
197 :
198 : //*************************************************************************
199 0 : sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const OUString& Name)
200 : throw( RuntimeException )
201 : {
202 0 : Reference< XIdlField > xField = m_xListenerType->getField( Name );
203 0 : return xField.is();
204 : }
205 :
206 : //*************************************************************************
207 : // class EventAttacherImpl
208 : // represents an implementation of the EventAttacher service
209 : //*************************************************************************
210 : class EventAttacherImpl : public WeakImplHelper3 < XEventAttacher2, XInitialization, XServiceInfo >
211 : {
212 : public:
213 : EventAttacherImpl( const Reference< XMultiServiceFactory >& );
214 : ~EventAttacherImpl();
215 :
216 : // XServiceInfo
217 : virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException);
218 : virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
219 : virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException);
220 : static OUString SAL_CALL getImplementationName_Static( );
221 : static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( );
222 :
223 : // XInitialization
224 : virtual void SAL_CALL initialize( const Sequence< Any >& aArguments )
225 : throw( Exception, RuntimeException);
226 :
227 : // Methoden von XEventAttacher
228 : virtual Reference< XEventListener > SAL_CALL attachListener(const Reference< XInterface >& xObject,
229 : const Reference< XAllListener >& AllListener, const Any& Helper,
230 : const OUString& ListenerType, const OUString& AddListenerParam)
231 : throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException );
232 : virtual Reference< XEventListener > SAL_CALL attachSingleEventListener(const Reference< XInterface >& xObject,
233 : const Reference< XAllListener >& AllListener, const Any& Helper,
234 : const OUString& ListenerType, const OUString& AddListenerParam,
235 : const OUString& EventMethod)
236 : throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException );
237 : virtual void SAL_CALL removeListener(const Reference< XInterface >& xObject,
238 : const OUString& ListenerType, const OUString& AddListenerParam,
239 : const Reference< XEventListener >& aToRemoveListener)
240 : throw( IllegalArgumentException, IntrospectionException, RuntimeException );
241 :
242 : // XEventAttacher2
243 : virtual Sequence< Reference<XEventListener> > SAL_CALL attachMultipleEventListeners(
244 : const Reference<XInterface>& xObject, const Sequence<com::sun::star::script::EventListener>& aListeners )
245 : throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException );
246 :
247 : // used by FilterAllListener_Impl
248 : Reference< XTypeConverter > getConverter() throw( Exception );
249 :
250 : friend class FilterAllListenerImpl;
251 :
252 : private:
253 : Reference<XEventListener> attachListenerForTarget(
254 : const Reference<XIntrospectionAccess>& xAccess,
255 : const Reference<XInvocationAdapterFactory>& xInvocationAdapterFactory,
256 : const Reference<XAllListener>& xAllListener,
257 : const Any& aObject,
258 : const Any& aHelper,
259 : const OUString& aListenerType,
260 : const OUString& aAddListenerParam );
261 :
262 : Sequence< Reference<XEventListener> > attachListeners(
263 : const Reference<XInterface>& xObject,
264 : const Sequence< Reference<XAllListener> >& AllListeners,
265 : const Sequence<com::sun::star::script::EventListener>& aListeners );
266 :
267 : private:
268 : Mutex m_aMutex;
269 : Reference< XMultiServiceFactory > m_xSMgr;
270 :
271 : // Save Services
272 : Reference< XIntrospection > m_xIntrospection;
273 : Reference< XIdlReflection > m_xReflection;
274 : Reference< XTypeConverter > m_xConverter;
275 : Reference< XInvocationAdapterFactory > m_xInvocationAdapterFactory;
276 :
277 : // needed services
278 : Reference< XIntrospection > getIntrospection() throw( Exception );
279 : Reference< XIdlReflection > getReflection() throw( Exception );
280 : Reference< XInvocationAdapterFactory > getInvocationAdapterService() throw( Exception );
281 : };
282 :
283 :
284 : //*************************************************************************
285 2 : EventAttacherImpl::EventAttacherImpl( const Reference< XMultiServiceFactory >& rSMgr )
286 2 : : m_xSMgr( rSMgr )
287 : {
288 2 : }
289 :
290 : //*************************************************************************
291 2 : EventAttacherImpl::~EventAttacherImpl()
292 : {
293 2 : }
294 :
295 : //*************************************************************************
296 2 : Reference< XInterface > SAL_CALL EventAttacherImpl_CreateInstance( const Reference< XMultiServiceFactory >& rSMgr ) throw( Exception )
297 : {
298 2 : Reference< XInterface > xRet;
299 2 : XEventAttacher *pEventAttacher = (XEventAttacher*) new EventAttacherImpl(rSMgr);
300 :
301 2 : if (pEventAttacher)
302 : {
303 2 : xRet = Reference<XInterface>::query(pEventAttacher);
304 : }
305 :
306 2 : return xRet;
307 : }
308 :
309 : //*************************************************************************
310 0 : OUString SAL_CALL EventAttacherImpl::getImplementationName( )
311 : throw(RuntimeException)
312 : {
313 0 : return OUString( IMPLNAME );
314 : }
315 :
316 : //*************************************************************************
317 0 : sal_Bool SAL_CALL EventAttacherImpl::supportsService( const OUString& ServiceName )
318 : throw(RuntimeException)
319 : {
320 0 : Sequence< OUString > aSNL = getSupportedServiceNames();
321 0 : const OUString * pArray = aSNL.getArray();
322 0 : for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
323 0 : if( pArray[i] == ServiceName )
324 0 : return sal_True;
325 0 : return sal_False;
326 : }
327 :
328 : //*************************************************************************
329 0 : Sequence<OUString> SAL_CALL EventAttacherImpl::getSupportedServiceNames( )
330 : throw(RuntimeException)
331 : {
332 0 : return getSupportedServiceNames_Static();
333 : }
334 :
335 : //*************************************************************************
336 2 : Sequence<OUString> SAL_CALL EventAttacherImpl::getSupportedServiceNames_Static( )
337 : {
338 2 : OUString aStr( SERVICENAME );
339 2 : return Sequence< OUString >( &aStr, 1 );
340 : }
341 :
342 : //*************************************************************************
343 4 : void SAL_CALL EventAttacherImpl::initialize(const Sequence< Any >& Arguments) throw( Exception, RuntimeException )
344 : {
345 : // get services from the argument list
346 4 : const Any * pArray = Arguments.getConstArray();
347 8 : for( sal_Int32 i = 0; i < Arguments.getLength(); i++ )
348 : {
349 4 : if( pArray[i].getValueType().getTypeClass() != TypeClass_INTERFACE )
350 0 : throw IllegalArgumentException();
351 :
352 : // InvocationAdapter service ?
353 4 : Reference< XInvocationAdapterFactory > xALAS;
354 4 : pArray[i] >>= xALAS;
355 4 : if( xALAS.is() )
356 : {
357 0 : Guard< Mutex > aGuard( m_aMutex );
358 0 : m_xInvocationAdapterFactory = xALAS;
359 : }
360 : // Introspection service ?
361 4 : Reference< XIntrospection > xI;
362 4 : pArray[i] >>= xI;
363 4 : if( xI.is() )
364 : {
365 4 : Guard< Mutex > aGuard( m_aMutex );
366 4 : m_xIntrospection = xI;
367 : }
368 : // Reflection service ?
369 4 : Reference< XIdlReflection > xIdlR;
370 4 : pArray[i] >>= xIdlR;
371 4 : if( xIdlR.is() )
372 : {
373 0 : Guard< Mutex > aGuard( m_aMutex );
374 0 : m_xReflection = xIdlR;
375 : }
376 : // Converter Service ?
377 4 : Reference< XTypeConverter > xC;
378 4 : pArray[i] >>= xC;
379 4 : if( xC.is() )
380 : {
381 0 : Guard< Mutex > aGuard( m_aMutex );
382 0 : m_xConverter = xC;
383 : }
384 :
385 : // no right interface
386 4 : if( !xALAS.is() && !xI.is() && !xIdlR.is() && !xC.is() )
387 0 : throw IllegalArgumentException();
388 4 : }
389 4 : }
390 :
391 : //*************************************************************************
392 : //*** Private helper methods ***
393 0 : Reference< XIntrospection > EventAttacherImpl::getIntrospection() throw( Exception )
394 : {
395 0 : Guard< Mutex > aGuard( m_aMutex );
396 0 : if( !m_xIntrospection.is() )
397 : {
398 0 : m_xIntrospection = Introspection::create( comphelper::getComponentContext(m_xSMgr) );
399 : }
400 0 : return m_xIntrospection;
401 : }
402 :
403 : //*************************************************************************
404 : //*** Private helper methods ***
405 0 : Reference< XIdlReflection > EventAttacherImpl::getReflection() throw( Exception )
406 : {
407 0 : Guard< Mutex > aGuard( m_aMutex );
408 0 : if( !m_xReflection.is() )
409 : {
410 0 : m_xReflection = theCoreReflection::get(comphelper::getComponentContext(m_xSMgr));
411 : }
412 0 : return m_xReflection;
413 : }
414 :
415 : //*************************************************************************
416 : //*** Private helper methods ***
417 0 : Reference< XInvocationAdapterFactory > EventAttacherImpl::getInvocationAdapterService() throw( Exception )
418 : {
419 0 : Guard< Mutex > aGuard( m_aMutex );
420 0 : if( !m_xInvocationAdapterFactory.is() )
421 : {
422 0 : Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString("com.sun.star.script.InvocationAdapterFactory") ) );
423 0 : m_xInvocationAdapterFactory = Reference< XInvocationAdapterFactory >( xIFace, UNO_QUERY );
424 : }
425 0 : return m_xInvocationAdapterFactory;
426 : }
427 :
428 :
429 : //*************************************************************************
430 : //*** Private helper methods ***
431 0 : Reference< XTypeConverter > EventAttacherImpl::getConverter() throw( Exception )
432 : {
433 0 : Guard< Mutex > aGuard( m_aMutex );
434 0 : if( !m_xConverter.is() )
435 : {
436 0 : m_xConverter = Converter::create(comphelper::getComponentContext(m_xSMgr));
437 : }
438 0 : return m_xConverter;
439 : }
440 :
441 : //------------------------------------------------------------------------
442 : //------------------------------------------------------------------------
443 : //------------------------------------------------------------------------
444 : // Implementation of an EventAttacher-related AllListeners, which brings
445 : // a few Events to a general AllListener
446 0 : class FilterAllListenerImpl : public WeakImplHelper1< XAllListener >
447 : {
448 : public:
449 : FilterAllListenerImpl( EventAttacherImpl * pEA_, const OUString& EventMethod_,
450 : const Reference< XAllListener >& AllListener_ );
451 :
452 : // XAllListener
453 : virtual void SAL_CALL firing(const AllEventObject& Event) throw( RuntimeException );
454 : virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw( InvocationTargetException, RuntimeException );
455 :
456 : // XEventListener
457 : virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException );
458 :
459 : private:
460 : // convert
461 : void convertToEventReturn( Any & rRet, const Type& rRetType )
462 : throw( CannotConvertException );
463 :
464 : EventAttacherImpl * m_pEA;
465 : Reference< XInterface > m_xEAHold;
466 : OUString m_EventMethod;
467 : Reference< XAllListener > m_AllListener;
468 : };
469 :
470 : //*************************************************************************
471 0 : FilterAllListenerImpl::FilterAllListenerImpl( EventAttacherImpl * pEA_, const OUString& EventMethod_,
472 : const Reference< XAllListener >& AllListener_ )
473 : : m_pEA( pEA_ )
474 : , m_xEAHold( *pEA_ )
475 : , m_EventMethod( EventMethod_ )
476 0 : , m_AllListener( AllListener_ )
477 : {
478 0 : }
479 :
480 : //*************************************************************************
481 0 : void SAL_CALL FilterAllListenerImpl::firing(const AllEventObject& Event)
482 : throw( RuntimeException )
483 : {
484 0 : if( Event.MethodName == m_EventMethod && m_AllListener.is() )
485 0 : m_AllListener->firing( Event );
486 0 : }
487 :
488 : //*************************************************************************
489 : // Convert to the standard event return
490 0 : void FilterAllListenerImpl::convertToEventReturn( Any & rRet, const Type & rRetType )
491 : throw( CannotConvertException )
492 : {
493 : // no return value? Set to the specified values
494 0 : if( rRet.getValueType().getTypeClass() == TypeClass_VOID )
495 : {
496 0 : switch( rRetType.getTypeClass() )
497 : {
498 : case TypeClass_INTERFACE:
499 : {
500 0 : rRet <<= Reference< XInterface >();
501 : }
502 0 : break;
503 :
504 : case TypeClass_BOOLEAN:
505 0 : rRet <<= sal_True;
506 0 : break;
507 :
508 : case TypeClass_STRING:
509 0 : rRet <<= OUString();
510 0 : break;
511 :
512 0 : case TypeClass_FLOAT: rRet <<= float(0); break;
513 0 : case TypeClass_DOUBLE: rRet <<= double(0.0); break;
514 0 : case TypeClass_BYTE: rRet <<= sal_uInt8( 0 ); break;
515 0 : case TypeClass_SHORT: rRet <<= sal_Int16( 0 ); break;
516 0 : case TypeClass_LONG: rRet <<= sal_Int32( 0 ); break;
517 0 : case TypeClass_UNSIGNED_SHORT: rRet <<= sal_uInt16( 0 ); break;
518 0 : case TypeClass_UNSIGNED_LONG: rRet <<= sal_uInt32( 0 ); break;
519 : default:
520 0 : break;
521 : }
522 : }
523 0 : else if( !rRet.getValueType().equals( rRetType ) )
524 : {
525 0 : Reference< XTypeConverter > xConverter = m_pEA->getConverter();
526 0 : if( xConverter.is() )
527 0 : rRet = xConverter->convertTo( rRet, rRetType );
528 : else
529 0 : throw CannotConvertException(); // TODO TypeConversionException
530 : }
531 0 : }
532 :
533 : //*************************************************************************
534 0 : Any SAL_CALL FilterAllListenerImpl::approveFiring( const AllEventObject& Event )
535 : throw( InvocationTargetException, RuntimeException )
536 : {
537 0 : Any aRet;
538 :
539 0 : if( Event.MethodName == m_EventMethod && m_AllListener.is() )
540 0 : aRet = m_AllListener->approveFiring( Event );
541 : else
542 : {
543 : // Convert to the standard event return
544 : try
545 : {
546 0 : Reference< XIdlClass > xListenerType = m_pEA->getReflection()->
547 0 : forName( Event.ListenerType.getTypeName() );
548 0 : Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName );
549 0 : if( xMeth.is() )
550 : {
551 0 : Reference< XIdlClass > xRetType = xMeth->getReturnType();
552 0 : Type aRetType( xRetType->getTypeClass(), xRetType->getName() );
553 0 : convertToEventReturn( aRet, aRetType );
554 0 : }
555 : }
556 0 : catch( const CannotConvertException& e )
557 : {
558 0 : throw InvocationTargetException( OUString(), Reference< XInterface >(), Any(&e, ::getCppuType( (CannotConvertException*)0)) );
559 : }
560 : }
561 0 : return aRet;
562 : }
563 :
564 : //*************************************************************************
565 0 : void FilterAllListenerImpl::disposing(const EventObject& )
566 : throw( RuntimeException )
567 : {
568 : // TODO: ???
569 0 : }
570 :
571 :
572 : //*************************************************************************
573 0 : Reference< XEventListener > EventAttacherImpl::attachListener
574 : (
575 : const Reference< XInterface >& xObject,
576 : const Reference< XAllListener >& AllListener,
577 : const Any& Helper,
578 : const OUString& ListenerType,
579 : const OUString& AddListenerParam
580 : )
581 : throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException )
582 : {
583 0 : if( !xObject.is() || !AllListener.is() )
584 0 : throw IllegalArgumentException();
585 :
586 0 : Reference< XInvocationAdapterFactory > xInvocationAdapterFactory = getInvocationAdapterService();
587 0 : if( !xInvocationAdapterFactory.is() )
588 0 : throw ServiceNotRegisteredException();
589 :
590 0 : Reference< XIdlReflection > xReflection = getReflection();
591 0 : if( !xReflection.is() )
592 0 : throw ServiceNotRegisteredException();
593 :
594 : // Sign in, Call the fitting addListener method
595 : // First Introspection, as the Methods can be analyzed in the same way
596 : // For better perfomance it is implemented here again or make the Impl-Method
597 : // of the Introspection configurable for this purpose.
598 0 : Reference< XIntrospection > xIntrospection = getIntrospection();
599 0 : if( !xIntrospection.is() )
600 0 : return Reference<XEventListener>();
601 :
602 : // Inspect Introspection
603 0 : Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
604 :
605 0 : Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
606 0 : if( !xAccess.is() )
607 0 : return Reference<XEventListener>();
608 :
609 : return attachListenerForTarget(
610 : xAccess, xInvocationAdapterFactory, AllListener, aObjAny, Helper,
611 0 : ListenerType, AddListenerParam);
612 : }
613 :
614 0 : Reference<XEventListener> EventAttacherImpl::attachListenerForTarget(
615 : const Reference<XIntrospectionAccess>& xAccess,
616 : const Reference<XInvocationAdapterFactory>& xInvocationAdapterFactory,
617 : const Reference<XAllListener>& xAllListener,
618 : const Any& aObject,
619 : const Any& aHelper,
620 : const OUString& aListenerType,
621 : const OUString& aAddListenerParam)
622 : {
623 0 : Reference< XEventListener > xRet = NULL;
624 :
625 : // Construct the name of the addListener-Method.
626 0 : sal_Int32 nIndex = aListenerType.lastIndexOf('.');
627 : // set index to the interface name without package name
628 0 : if( nIndex == -1 )
629 : // not found
630 0 : nIndex = 0;
631 : else
632 0 : nIndex++;
633 :
634 0 : OUString aListenerName = (aListenerType[nIndex] == 'X') ? aListenerType.copy(nIndex+1) : aListenerType;
635 0 : OUString aAddListenerName = OUString("add") + aListenerName;
636 :
637 : // Send Methods to the correct addListener-Method
638 0 : Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER );
639 0 : const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
640 0 : for (sal_Int32 i = 0, n = aMethodSeq.getLength(); i < n ; ++i)
641 : {
642 0 : const Reference< XIdlMethod >& rxMethod = pMethods[i];
643 :
644 : // Is it the correct method?
645 0 : OUString aMethName = rxMethod->getName();
646 :
647 0 : if (aAddListenerName != aMethName)
648 0 : continue;
649 :
650 0 : Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes();
651 0 : sal_uInt32 nParamCount = params.getLength();
652 :
653 0 : Reference< XIdlClass > xListenerType;
654 0 : if( nParamCount == 1 )
655 0 : xListenerType = params.getConstArray()[0];
656 0 : else if( nParamCount == 2 )
657 0 : xListenerType = params.getConstArray()[1];
658 :
659 : // Request Adapter for the actual Listener type
660 : Reference< XInterface > xAdapter = createAllListenerAdapter(
661 0 : xInvocationAdapterFactory, xListenerType, xAllListener, aHelper );
662 :
663 0 : if( !xAdapter.is() )
664 0 : throw CannotCreateAdapterException();
665 0 : xRet = Reference< XEventListener >( xAdapter, UNO_QUERY );
666 :
667 : // Just the Listener as parameter?
668 0 : if( nParamCount == 1 )
669 : {
670 0 : Sequence< Any > args( 1 );
671 0 : args.getArray()[0] <<= xAdapter;
672 : try
673 : {
674 0 : rxMethod->invoke( aObject, args );
675 : }
676 0 : catch( const InvocationTargetException& )
677 : {
678 0 : throw IntrospectionException();
679 0 : }
680 : }
681 : // Else, pass the other parameter now
682 0 : else if( nParamCount == 2 )
683 : {
684 0 : Sequence< Any > args( 2 );
685 0 : Any* pAnys = args.getArray();
686 :
687 : // Check the type of the 1st parameter
688 0 : Reference< XIdlClass > xParamClass = params.getConstArray()[0];
689 0 : if( xParamClass->getTypeClass() == TypeClass_STRING )
690 : {
691 0 : pAnys[0] <<= aAddListenerParam;
692 : }
693 :
694 : // 2nd Parameter == Listener? TODO: Test!
695 0 : pAnys[1] <<= xAdapter;
696 :
697 : // TODO: Convert String -> ?
698 : // else
699 : try
700 : {
701 0 : rxMethod->invoke( aObject, args );
702 : }
703 0 : catch( const InvocationTargetException& )
704 : {
705 0 : throw IntrospectionException();
706 0 : }
707 : }
708 : break;
709 : // else...
710 : // Anything else is not supported
711 0 : }
712 :
713 0 : return xRet;
714 : }
715 :
716 0 : Sequence< Reference<XEventListener> > EventAttacherImpl::attachListeners(
717 : const Reference<XInterface>& xObject,
718 : const Sequence< Reference<XAllListener> >& AllListeners,
719 : const Sequence<com::sun::star::script::EventListener>& aListeners )
720 : {
721 0 : sal_Int32 nCount = aListeners.getLength();
722 0 : if (nCount != AllListeners.getLength())
723 : // This is a prerequisite!
724 0 : throw RuntimeException();
725 :
726 0 : if (!xObject.is())
727 0 : throw IllegalArgumentException();
728 :
729 0 : Reference< XInvocationAdapterFactory > xInvocationAdapterFactory = getInvocationAdapterService();
730 0 : if( !xInvocationAdapterFactory.is() )
731 0 : throw ServiceNotRegisteredException();
732 :
733 0 : Reference< XIdlReflection > xReflection = getReflection();
734 0 : if( !xReflection.is() )
735 0 : throw ServiceNotRegisteredException();
736 :
737 : // Sign in, Call the fitting addListener method
738 : // First Introspection, as the Methods can be analyzed in the same way
739 : // For better perfomance it is implemented here again or make the Impl-Method
740 : // of the Introspection configurable for this purpose.
741 0 : Reference< XIntrospection > xIntrospection = getIntrospection();
742 0 : if( !xIntrospection.is() )
743 0 : return Sequence< Reference<XEventListener> >();
744 :
745 : // Inspect Introspection
746 0 : Any aObjAny( &xObject, ::getCppuType(static_cast<const Reference<XInterface>*>(0)) );
747 :
748 0 : Reference<XIntrospectionAccess> xAccess = xIntrospection->inspect(aObjAny);
749 0 : if (!xAccess.is())
750 0 : return Sequence< Reference<XEventListener> >();
751 :
752 0 : Sequence< Reference<XEventListener> > aRet(nCount);
753 0 : Reference<XEventListener>* pArray = aRet.getArray();
754 :
755 0 : for (sal_Int32 i = 0; i < nCount; ++i)
756 : {
757 : pArray[i] = attachListenerForTarget(
758 0 : xAccess, xInvocationAdapterFactory, AllListeners[ i ],
759 0 : aObjAny, aListeners[i].Helper, aListeners[i].ListenerType, aListeners[i].AddListenerParam);
760 : }
761 :
762 0 : return aRet;
763 : }
764 :
765 : // XEventAttacher
766 0 : Reference< XEventListener > EventAttacherImpl::attachSingleEventListener
767 : (
768 : const Reference< XInterface >& xObject,
769 : const Reference< XAllListener >& AllListener,
770 : const Any& Helper,
771 : const OUString& ListenerType,
772 : const OUString& AddListenerParam,
773 : const OUString& EventMethod
774 : )
775 : throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException )
776 : {
777 : // Subscribe FilterListener
778 : Reference< XAllListener > aFilterListener = (XAllListener*)
779 0 : new FilterAllListenerImpl( this, EventMethod, AllListener );
780 0 : return attachListener( xObject, aFilterListener, Helper, ListenerType, AddListenerParam);
781 : }
782 :
783 : // XEventAttacher
784 0 : void EventAttacherImpl::removeListener
785 : (
786 : const Reference< XInterface >& xObject,
787 : const OUString& ListenerType,
788 : const OUString& AddListenerParam,
789 : const Reference< XEventListener >& aToRemoveListener
790 : )
791 : throw( IllegalArgumentException, IntrospectionException, RuntimeException )
792 : {
793 0 : if( !xObject.is() || !aToRemoveListener.is() )
794 0 : throw IllegalArgumentException();
795 :
796 0 : Reference< XIdlReflection > xReflection = getReflection();
797 0 : if( !xReflection.is() )
798 0 : throw IntrospectionException();
799 :
800 : // Sign off, Call the fitting removeListener method
801 : // First Introspection, as the Methods can be analyzed in the same way
802 : // For better perfomance it is implemented here again or make the Impl-Method
803 : // of the Introspection configurable for this purpose.
804 0 : Reference< XIntrospection > xIntrospection = getIntrospection();
805 0 : if( !xIntrospection.is() )
806 0 : throw IntrospectionException();
807 :
808 : //Inspect Introspection
809 0 : Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
810 0 : Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
811 0 : if( !xAccess.is() )
812 0 : throw IntrospectionException();
813 :
814 : // Create name of the removeListener-Method
815 0 : OUString aRemoveListenerName;
816 0 : OUString aListenerName( ListenerType );
817 0 : sal_Int32 nIndex = aListenerName.lastIndexOf( '.' );
818 : // set index to the interface name without package name
819 0 : if( nIndex == -1 )
820 : // not found
821 0 : nIndex = 0;
822 : else
823 0 : nIndex++;
824 0 : if( aListenerName[nIndex] == 'X' )
825 : // erase X from the interface name
826 0 : aListenerName = aListenerName.copy( nIndex +1 );
827 0 : aRemoveListenerName = OUString( "remove" ) + aListenerName;
828 :
829 : // Search methods for the correct removeListener method
830 0 : Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER );
831 0 : sal_uInt32 i, nLen = aMethodSeq.getLength();
832 0 : const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
833 0 : for( i = 0 ; i < nLen ; i++ )
834 : {
835 : // Call Methode
836 0 : const Reference< XIdlMethod >& rxMethod = pMethods[i];
837 :
838 : // Is it the right method?
839 0 : if( aRemoveListenerName == rxMethod->getName() )
840 : {
841 0 : Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes();
842 0 : sal_uInt32 nParamCount = params.getLength();
843 :
844 : // Just the Listener as parameter?
845 0 : if( nParamCount == 1 )
846 : {
847 0 : Sequence< Any > args( 1 );
848 0 : args.getArray()[0] <<= aToRemoveListener;
849 : try
850 : {
851 0 : rxMethod->invoke( aObjAny, args );
852 : }
853 0 : catch( const InvocationTargetException& )
854 : {
855 0 : throw IntrospectionException();
856 0 : }
857 : }
858 : // Else pass the other parameter
859 0 : else if( nParamCount == 2 )
860 : {
861 0 : Sequence< Any > args( 2 );
862 0 : Any* pAnys = args.getArray();
863 :
864 : // Check the type of the 1st parameter
865 0 : Reference< XIdlClass > xParamClass = params.getConstArray()[0];
866 0 : if( xParamClass->getTypeClass() == TypeClass_STRING )
867 0 : pAnys[0] <<= AddListenerParam;
868 :
869 : // 2nd parameter == Listener? TODO: Test!
870 0 : pAnys[1] <<= aToRemoveListener;
871 :
872 : // TODO: Convert String -> ?
873 : // else
874 : try
875 : {
876 0 : rxMethod->invoke( aObjAny, args );
877 : }
878 0 : catch( const InvocationTargetException& )
879 : {
880 0 : throw IntrospectionException();
881 0 : }
882 : }
883 0 : break;
884 : }
885 0 : }
886 0 : }
887 :
888 0 : Sequence< Reference<XEventListener> > EventAttacherImpl::attachMultipleEventListeners(
889 : const Reference<XInterface>& xObject, const Sequence<com::sun::star::script::EventListener>& aListeners )
890 : throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException )
891 : {
892 0 : sal_Int32 nCount = aListeners.getLength();
893 0 : Sequence< Reference<XAllListener> > aFilterListeners(nCount);
894 0 : for (sal_Int32 i = 0; i < nCount; ++i)
895 : {
896 0 : aFilterListeners[i] = (XAllListener*)
897 0 : new FilterAllListenerImpl(this, aListeners[i].EventMethod, aListeners[i].AllListener);
898 : }
899 :
900 0 : return attachListeners(xObject, aFilterListeners, aListeners);
901 : }
902 :
903 : }
904 :
905 : extern "C"
906 : {
907 2 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL evtatt_component_getFactory(
908 : const sal_Char * pImplName, void * pServiceManager, void * )
909 : {
910 2 : void * pRet = 0;
911 :
912 2 : if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0)
913 : {
914 : Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory(
915 : reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
916 : OUString( IMPLNAME ),
917 : ::comp_EventAttacher::EventAttacherImpl_CreateInstance,
918 2 : ::comp_EventAttacher::EventAttacherImpl::getSupportedServiceNames_Static() ) );
919 :
920 2 : if (xFactory.is())
921 : {
922 2 : xFactory->acquire();
923 2 : pRet = xFactory.get();
924 2 : }
925 : }
926 :
927 2 : return pRet;
928 : }
929 : }
930 :
931 :
932 :
933 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|