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