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/InvocationAdapterFactory.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 :
52 :
53 : #define SERVICENAME "com.sun.star.script.EventAttacher"
54 : #define IMPLNAME "com.sun.star.comp.EventAttacher"
55 :
56 : namespace comp_EventAttacher {
57 :
58 : //*************************************************************************
59 : // class InvocationToAllListenerMapper
60 : // helper class to map XInvocation to XAllListener
61 : //*************************************************************************
62 38 : class InvocationToAllListenerMapper : public WeakImplHelper1< XInvocation >
63 : {
64 : public:
65 : InvocationToAllListenerMapper( const Reference< XIdlClass >& ListenerType,
66 : const Reference< XAllListener >& AllListener, const Any& Helper );
67 :
68 : // XInvocation
69 : virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection(void) throw( RuntimeException );
70 : virtual Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
71 : throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException );
72 : virtual void SAL_CALL setValue(const OUString& PropertyName, const Any& Value)
73 : throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException );
74 : virtual Any SAL_CALL getValue(const OUString& PropertyName) throw( UnknownPropertyException, RuntimeException );
75 : virtual sal_Bool SAL_CALL hasMethod(const OUString& Name) throw( RuntimeException );
76 : virtual sal_Bool SAL_CALL hasProperty(const OUString& Name) throw( RuntimeException );
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
87 96 : Reference< XInterface > createAllListenerAdapter
88 : (
89 : const Reference< XInvocationAdapterFactory2 >& xInvocationAdapterFactory,
90 : const Reference< XIdlClass >& xListenerType,
91 : const Reference< XAllListener >& xListener,
92 : const Any& Helper
93 : )
94 : {
95 96 : Reference< XInterface > xAdapter;
96 96 : if( xInvocationAdapterFactory.is() && xListenerType.is() && xListener.is() )
97 : {
98 : Reference< XInvocation > xInvocationToAllListenerMapper =
99 96 : (XInvocation*)new InvocationToAllListenerMapper( xListenerType, xListener, Helper );
100 192 : Type aListenerType( xListenerType->getTypeClass(), xListenerType->getName());
101 192 : Sequence<Type> arg2(1);
102 96 : arg2[0] = aListenerType;
103 192 : xAdapter = xInvocationAdapterFactory->createAdapter( xInvocationToAllListenerMapper, arg2 );
104 : }
105 96 : return xAdapter;
106 : }
107 :
108 :
109 : //--------------------------------------------------------------------------------------------------
110 : // InvocationToAllListenerMapper
111 96 : InvocationToAllListenerMapper::InvocationToAllListenerMapper
112 : ( const Reference< XIdlClass >& ListenerType, const Reference< XAllListener >& AllListener, const Any& Helper )
113 : : m_xAllListener( AllListener )
114 : , m_xListenerType( ListenerType )
115 96 : , m_Helper( Helper )
116 : {
117 96 : }
118 :
119 : //*************************************************************************
120 0 : Reference< XIntrospectionAccess > SAL_CALL InvocationToAllListenerMapper::getIntrospection(void)
121 : throw( RuntimeException )
122 : {
123 0 : return Reference< XIntrospectionAccess >();
124 : }
125 :
126 : //*************************************************************************
127 1 : 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 1 : Any aRet;
133 :
134 : // Check if to firing or approveFiring has to be called
135 2 : Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( FunctionName );
136 1 : sal_Bool bApproveFiring = sal_False;
137 1 : if( !xMethod.is() )
138 0 : return aRet;
139 2 : Reference< XIdlClass > xReturnType = xMethod->getReturnType();
140 2 : Sequence< Reference< XIdlClass > > aExceptionSeq = xMethod->getExceptionTypes();
141 2 : if( ( xReturnType.is() && xReturnType->getTypeClass() != TypeClass_VOID ) ||
142 1 : aExceptionSeq.getLength() > 0 )
143 : {
144 0 : bApproveFiring = sal_True;
145 : }
146 : else
147 : {
148 1 : Sequence< ParamInfo > aParamSeq = xMethod->getParameterInfos();
149 1 : sal_uInt32 nParamCount = aParamSeq.getLength();
150 1 : if( nParamCount > 1 )
151 : {
152 0 : const ParamInfo* pInfos = aParamSeq.getConstArray();
153 0 : for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
154 : {
155 0 : if( pInfos[ i ].aMode != ParamMode_IN )
156 : {
157 0 : bApproveFiring = sal_True;
158 0 : break;
159 : }
160 : }
161 1 : }
162 : }
163 :
164 2 : AllEventObject aAllEvent;
165 1 : aAllEvent.Source = (OWeakObject*) this;
166 1 : aAllEvent.Helper = m_Helper;
167 1 : aAllEvent.ListenerType = Type(m_xListenerType->getTypeClass(), m_xListenerType->getName());
168 1 : aAllEvent.MethodName = FunctionName;
169 1 : aAllEvent.Arguments = Params;
170 1 : if( bApproveFiring )
171 0 : aRet = m_xAllListener->approveFiring( aAllEvent );
172 : else
173 1 : m_xAllListener->firing( aAllEvent );
174 1 : return aRet;
175 : }
176 :
177 : //*************************************************************************
178 0 : void SAL_CALL InvocationToAllListenerMapper::setValue(const OUString& , const Any& )
179 : throw( UnknownPropertyException, CannotConvertException,
180 : InvocationTargetException, RuntimeException )
181 : {
182 0 : }
183 :
184 : //*************************************************************************
185 0 : Any SAL_CALL InvocationToAllListenerMapper::getValue(const OUString& )
186 : throw( UnknownPropertyException, RuntimeException )
187 : {
188 0 : return Any();
189 : }
190 :
191 : //*************************************************************************
192 0 : sal_Bool SAL_CALL InvocationToAllListenerMapper::hasMethod(const OUString& Name)
193 : throw( RuntimeException )
194 : {
195 0 : Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( Name );
196 0 : return xMethod.is();
197 : }
198 :
199 : //*************************************************************************
200 0 : sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const OUString& Name)
201 : throw( RuntimeException )
202 : {
203 0 : Reference< XIdlField > xField = m_xListenerType->getField( Name );
204 0 : return xField.is();
205 : }
206 :
207 : //*************************************************************************
208 : // class EventAttacherImpl
209 : // represents an implementation of the EventAttacher service
210 : //*************************************************************************
211 : class EventAttacherImpl : public WeakImplHelper3 < XEventAttacher2, XInitialization, XServiceInfo >
212 : {
213 : public:
214 : EventAttacherImpl( const Reference< XComponentContext >& );
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 : // XEventAttacher2
244 : virtual Sequence< Reference<XEventListener> > SAL_CALL attachMultipleEventListeners(
245 : const Reference<XInterface>& xObject, const Sequence<com::sun::star::script::EventListener>& aListeners )
246 : throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException );
247 :
248 : // used by FilterAllListener_Impl
249 : Reference< XTypeConverter > getConverter() throw( Exception );
250 :
251 : friend class FilterAllListenerImpl;
252 :
253 : private:
254 : Reference<XEventListener> attachListenerForTarget(
255 : const Reference<XIntrospectionAccess>& xAccess,
256 : const Reference<XInvocationAdapterFactory2>& xInvocationAdapterFactory,
257 : const Reference<XAllListener>& xAllListener,
258 : const Any& aObject,
259 : const Any& aHelper,
260 : const OUString& aListenerType,
261 : const OUString& aAddListenerParam );
262 :
263 : Sequence< Reference<XEventListener> > attachListeners(
264 : const Reference<XInterface>& xObject,
265 : const Sequence< Reference<XAllListener> >& AllListeners,
266 : const Sequence<com::sun::star::script::EventListener>& aListeners );
267 :
268 : private:
269 : Mutex m_aMutex;
270 : Reference< XComponentContext > m_xContext;
271 :
272 : // Save Services
273 : Reference< XIntrospection > m_xIntrospection;
274 : Reference< XIdlReflection > m_xReflection;
275 : Reference< XTypeConverter > m_xConverter;
276 : Reference< XInvocationAdapterFactory2 > m_xInvocationAdapterFactory;
277 :
278 : // needed services
279 : Reference< XIntrospection > getIntrospection() throw( Exception );
280 : Reference< XIdlReflection > getReflection() throw( Exception );
281 : Reference< XInvocationAdapterFactory2 > getInvocationAdapterService() throw( Exception );
282 : };
283 :
284 :
285 : //*************************************************************************
286 14 : EventAttacherImpl::EventAttacherImpl( const Reference< XComponentContext >& rxContext )
287 14 : : m_xContext( rxContext )
288 : {
289 14 : }
290 :
291 : //*************************************************************************
292 20 : EventAttacherImpl::~EventAttacherImpl()
293 : {
294 20 : }
295 :
296 : //*************************************************************************
297 14 : Reference< XInterface > SAL_CALL EventAttacherImpl_CreateInstance( const Reference< XMultiServiceFactory >& rSMgr ) throw( Exception )
298 : {
299 14 : Reference< XInterface > xRet;
300 14 : XEventAttacher *pEventAttacher = (XEventAttacher*) new EventAttacherImpl( comphelper::getComponentContext(rSMgr) );
301 :
302 14 : if (pEventAttacher)
303 : {
304 14 : xRet = Reference<XInterface>::query(pEventAttacher);
305 : }
306 :
307 14 : return xRet;
308 : }
309 :
310 : //*************************************************************************
311 0 : OUString SAL_CALL EventAttacherImpl::getImplementationName( )
312 : throw(RuntimeException)
313 : {
314 0 : return OUString( IMPLNAME );
315 : }
316 :
317 : //*************************************************************************
318 0 : sal_Bool SAL_CALL EventAttacherImpl::supportsService( const OUString& ServiceName )
319 : throw(RuntimeException)
320 : {
321 0 : Sequence< OUString > aSNL = getSupportedServiceNames();
322 0 : const OUString * pArray = aSNL.getArray();
323 0 : for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
324 0 : if( pArray[i] == ServiceName )
325 0 : return sal_True;
326 0 : return sal_False;
327 : }
328 :
329 : //*************************************************************************
330 0 : Sequence<OUString> SAL_CALL EventAttacherImpl::getSupportedServiceNames( )
331 : throw(RuntimeException)
332 : {
333 0 : return getSupportedServiceNames_Static();
334 : }
335 :
336 : //*************************************************************************
337 14 : Sequence<OUString> SAL_CALL EventAttacherImpl::getSupportedServiceNames_Static( )
338 : {
339 14 : OUString aStr( SERVICENAME );
340 14 : return Sequence< OUString >( &aStr, 1 );
341 : }
342 :
343 : //*************************************************************************
344 341 : void SAL_CALL EventAttacherImpl::initialize(const Sequence< Any >& Arguments) throw( Exception, RuntimeException )
345 : {
346 : // get services from the argument list
347 341 : const Any * pArray = Arguments.getConstArray();
348 682 : for( sal_Int32 i = 0; i < Arguments.getLength(); i++ )
349 : {
350 341 : if( pArray[i].getValueType().getTypeClass() != TypeClass_INTERFACE )
351 0 : throw IllegalArgumentException();
352 :
353 : // InvocationAdapter service ?
354 341 : Reference< XInvocationAdapterFactory2 > xALAS;
355 341 : pArray[i] >>= xALAS;
356 341 : if( xALAS.is() )
357 : {
358 0 : Guard< Mutex > aGuard( m_aMutex );
359 0 : m_xInvocationAdapterFactory = xALAS;
360 : }
361 : // Introspection service ?
362 682 : Reference< XIntrospection > xI;
363 341 : pArray[i] >>= xI;
364 341 : if( xI.is() )
365 : {
366 341 : Guard< Mutex > aGuard( m_aMutex );
367 341 : m_xIntrospection = xI;
368 : }
369 : // Reflection service ?
370 682 : Reference< XIdlReflection > xIdlR;
371 341 : pArray[i] >>= xIdlR;
372 341 : if( xIdlR.is() )
373 : {
374 0 : Guard< Mutex > aGuard( m_aMutex );
375 0 : m_xReflection = xIdlR;
376 : }
377 : // Converter Service ?
378 682 : Reference< XTypeConverter > xC;
379 341 : pArray[i] >>= xC;
380 341 : if( xC.is() )
381 : {
382 0 : Guard< Mutex > aGuard( m_aMutex );
383 0 : m_xConverter = xC;
384 : }
385 :
386 : // no right interface
387 341 : if( !xALAS.is() && !xI.is() && !xIdlR.is() && !xC.is() )
388 0 : throw IllegalArgumentException();
389 341 : }
390 341 : }
391 :
392 : //*************************************************************************
393 : //*** Private helper methods ***
394 192 : Reference< XIntrospection > EventAttacherImpl::getIntrospection() throw( Exception )
395 : {
396 192 : Guard< Mutex > aGuard( m_aMutex );
397 192 : if( !m_xIntrospection.is() )
398 : {
399 0 : m_xIntrospection = Introspection::create( m_xContext );
400 : }
401 192 : return m_xIntrospection;
402 : }
403 :
404 : //*************************************************************************
405 : //*** Private helper methods ***
406 192 : Reference< XIdlReflection > EventAttacherImpl::getReflection() throw( Exception )
407 : {
408 192 : Guard< Mutex > aGuard( m_aMutex );
409 192 : if( !m_xReflection.is() )
410 : {
411 4 : m_xReflection = theCoreReflection::get(m_xContext);
412 : }
413 192 : return m_xReflection;
414 : }
415 :
416 : //*************************************************************************
417 : //*** Private helper methods ***
418 173 : Reference< XInvocationAdapterFactory2 > EventAttacherImpl::getInvocationAdapterService() throw( Exception )
419 : {
420 173 : Guard< Mutex > aGuard( m_aMutex );
421 173 : if( !m_xInvocationAdapterFactory.is() )
422 : {
423 4 : m_xInvocationAdapterFactory = InvocationAdapterFactory::create(m_xContext);
424 : }
425 173 : 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(m_xContext);
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 232 : 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 193 : 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 193 : , m_AllListener( AllListener_ )
477 : {
478 193 : }
479 :
480 : //*************************************************************************
481 1 : void SAL_CALL FilterAllListenerImpl::firing(const AllEventObject& Event)
482 : throw( RuntimeException )
483 : {
484 1 : if( Event.MethodName == m_EventMethod && m_AllListener.is() )
485 1 : m_AllListener->firing( Event );
486 1 : }
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 156 : 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 156 : if( !xObject.is() || !AllListener.is() )
584 0 : throw IllegalArgumentException();
585 :
586 156 : Reference< XInvocationAdapterFactory2 > xInvocationAdapterFactory = getInvocationAdapterService();
587 156 : if( !xInvocationAdapterFactory.is() )
588 0 : throw ServiceNotRegisteredException();
589 :
590 312 : Reference< XIdlReflection > xReflection = getReflection();
591 156 : 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 312 : Reference< XIntrospection > xIntrospection = getIntrospection();
599 156 : if( !xIntrospection.is() )
600 0 : return Reference<XEventListener>();
601 :
602 : // Inspect Introspection
603 312 : Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
604 :
605 312 : Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
606 156 : if( !xAccess.is() )
607 0 : return Reference<XEventListener>();
608 :
609 : return attachListenerForTarget(
610 : xAccess, xInvocationAdapterFactory, AllListener, aObjAny, Helper,
611 312 : ListenerType, AddListenerParam);
612 : }
613 :
614 193 : Reference<XEventListener> EventAttacherImpl::attachListenerForTarget(
615 : const Reference<XIntrospectionAccess>& xAccess,
616 : const Reference<XInvocationAdapterFactory2>& xInvocationAdapterFactory,
617 : const Reference<XAllListener>& xAllListener,
618 : const Any& aObject,
619 : const Any& aHelper,
620 : const OUString& aListenerType,
621 : const OUString& aAddListenerParam)
622 : {
623 193 : Reference< XEventListener > xRet = NULL;
624 :
625 : // Construct the name of the addListener-Method.
626 193 : sal_Int32 nIndex = aListenerType.lastIndexOf('.');
627 : // set index to the interface name without package name
628 193 : if( nIndex == -1 )
629 : // not found
630 39 : nIndex = 0;
631 : else
632 154 : nIndex++;
633 :
634 386 : OUString aListenerName = (aListenerType[nIndex] == 'X') ? aListenerType.copy(nIndex+1) : aListenerType;
635 386 : OUString aAddListenerName = OUString("add") + aListenerName;
636 :
637 : // Send Methods to the correct addListener-Method
638 386 : Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER );
639 193 : const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
640 2199 : for (sal_Int32 i = 0, n = aMethodSeq.getLength(); i < n ; ++i)
641 : {
642 2102 : const Reference< XIdlMethod >& rxMethod = pMethods[i];
643 :
644 : // Is it the correct method?
645 2102 : OUString aMethName = rxMethod->getName();
646 :
647 2102 : if (aAddListenerName != aMethName)
648 2006 : continue;
649 :
650 192 : Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes();
651 96 : sal_uInt32 nParamCount = params.getLength();
652 :
653 192 : Reference< XIdlClass > xListenerType;
654 96 : if( nParamCount == 1 )
655 96 : 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 192 : xInvocationAdapterFactory, xListenerType, xAllListener, aHelper );
662 :
663 96 : if( !xAdapter.is() )
664 0 : throw CannotCreateAdapterException();
665 96 : xRet = Reference< XEventListener >( xAdapter, UNO_QUERY );
666 :
667 : // Just the Listener as parameter?
668 96 : if( nParamCount == 1 )
669 : {
670 96 : Sequence< Any > args( 1 );
671 96 : args.getArray()[0] <<= xAdapter;
672 : try
673 : {
674 96 : rxMethod->invoke( aObject, args );
675 : }
676 0 : catch( const InvocationTargetException& )
677 : {
678 0 : throw IntrospectionException();
679 96 : }
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 96 : break;
709 : // else...
710 : // Anything else is not supported
711 0 : }
712 :
713 386 : return xRet;
714 : }
715 :
716 17 : 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 17 : sal_Int32 nCount = aListeners.getLength();
722 17 : if (nCount != AllListeners.getLength())
723 : // This is a prerequisite!
724 0 : throw RuntimeException();
725 :
726 17 : if (!xObject.is())
727 0 : throw IllegalArgumentException();
728 :
729 17 : Reference< XInvocationAdapterFactory2 > xInvocationAdapterFactory = getInvocationAdapterService();
730 17 : if( !xInvocationAdapterFactory.is() )
731 0 : throw ServiceNotRegisteredException();
732 :
733 34 : Reference< XIdlReflection > xReflection = getReflection();
734 17 : 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 34 : Reference< XIntrospection > xIntrospection = getIntrospection();
742 17 : if( !xIntrospection.is() )
743 0 : return Sequence< Reference<XEventListener> >();
744 :
745 : // Inspect Introspection
746 34 : Any aObjAny( &xObject, ::getCppuType(static_cast<const Reference<XInterface>*>(0)) );
747 :
748 34 : Reference<XIntrospectionAccess> xAccess = xIntrospection->inspect(aObjAny);
749 17 : if (!xAccess.is())
750 0 : return Sequence< Reference<XEventListener> >();
751 :
752 34 : Sequence< Reference<XEventListener> > aRet(nCount);
753 17 : Reference<XEventListener>* pArray = aRet.getArray();
754 :
755 54 : for (sal_Int32 i = 0; i < nCount; ++i)
756 : {
757 185 : pArray[i] = attachListenerForTarget(
758 37 : xAccess, xInvocationAdapterFactory, AllListeners[ i ],
759 148 : aObjAny, aListeners[i].Helper, aListeners[i].ListenerType, aListeners[i].AddListenerParam);
760 : }
761 :
762 34 : return aRet;
763 : }
764 :
765 : // XEventAttacher
766 156 : 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 156 : new FilterAllListenerImpl( this, EventMethod, AllListener );
780 156 : return attachListener( xObject, aFilterListener, Helper, ListenerType, AddListenerParam);
781 : }
782 :
783 : // XEventAttacher
784 19 : 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 19 : if( !xObject.is() || !aToRemoveListener.is() )
794 0 : throw IllegalArgumentException();
795 :
796 19 : Reference< XIdlReflection > xReflection = getReflection();
797 19 : 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 38 : Reference< XIntrospection > xIntrospection = getIntrospection();
805 19 : if( !xIntrospection.is() )
806 0 : throw IntrospectionException();
807 :
808 : //Inspect Introspection
809 38 : Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
810 38 : Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
811 19 : if( !xAccess.is() )
812 0 : throw IntrospectionException();
813 :
814 : // Create name of the removeListener-Method
815 38 : OUString aRemoveListenerName;
816 38 : OUString aListenerName( ListenerType );
817 19 : sal_Int32 nIndex = aListenerName.lastIndexOf( '.' );
818 : // set index to the interface name without package name
819 19 : if( nIndex == -1 )
820 : // not found
821 19 : nIndex = 0;
822 : else
823 0 : nIndex++;
824 19 : if( aListenerName[nIndex] == 'X' )
825 : // erase X from the interface name
826 19 : aListenerName = aListenerName.copy( nIndex +1 );
827 19 : aRemoveListenerName = OUString( "remove" ) + aListenerName;
828 :
829 : // Search methods for the correct removeListener method
830 38 : Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER );
831 19 : sal_uInt32 i, nLen = aMethodSeq.getLength();
832 19 : const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
833 178 : for( i = 0 ; i < nLen ; i++ )
834 : {
835 : // Call Methode
836 178 : const Reference< XIdlMethod >& rxMethod = pMethods[i];
837 :
838 : // Is it the right method?
839 178 : if( aRemoveListenerName == rxMethod->getName() )
840 : {
841 19 : Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes();
842 19 : sal_uInt32 nParamCount = params.getLength();
843 :
844 : // Just the Listener as parameter?
845 19 : if( nParamCount == 1 )
846 : {
847 19 : Sequence< Any > args( 1 );
848 19 : args.getArray()[0] <<= aToRemoveListener;
849 : try
850 : {
851 19 : rxMethod->invoke( aObjAny, args );
852 : }
853 0 : catch( const InvocationTargetException& )
854 : {
855 0 : throw IntrospectionException();
856 19 : }
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 19 : break;
884 : }
885 19 : }
886 19 : }
887 :
888 17 : 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 17 : sal_Int32 nCount = aListeners.getLength();
893 17 : Sequence< Reference<XAllListener> > aFilterListeners(nCount);
894 54 : for (sal_Int32 i = 0; i < nCount; ++i)
895 : {
896 37 : aFilterListeners[i] = (XAllListener*)
897 74 : new FilterAllListenerImpl(this, aListeners[i].EventMethod, aListeners[i].AllListener);
898 : }
899 :
900 17 : return attachListeners(xObject, aFilterListeners, aListeners);
901 : }
902 :
903 : }
904 :
905 : extern "C"
906 : {
907 14 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL evtatt_component_getFactory(
908 : const sal_Char * pImplName, void * pServiceManager, void * )
909 : {
910 14 : void * pRet = 0;
911 :
912 14 : 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 14 : ::comp_EventAttacher::EventAttacherImpl::getSupportedServiceNames_Static() ) );
919 :
920 14 : if (xFactory.is())
921 : {
922 14 : xFactory->acquire();
923 14 : pRet = xFactory.get();
924 14 : }
925 : }
926 :
927 14 : return pRet;
928 : }
929 : }
930 :
931 :
932 :
933 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|