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