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