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