LCOV - code coverage report
Current view: top level - eventattacher/source - eventattacher.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 206 332 62.0 %
Date: 2014-04-11 Functions: 25 37 67.6 %
Legend: Lines: hit not hit

          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          40 : 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          97 : Reference< XInterface > createAllListenerAdapter
      89             : (
      90             :     const Reference< XInvocationAdapterFactory2 >& xInvocationAdapterFactory,
      91             :     const Reference< XIdlClass >& xListenerType,
      92             :     const Reference< XAllListener >& xListener,
      93             :     const Any& Helper
      94             : )
      95             : {
      96          97 :     Reference< XInterface > xAdapter;
      97          97 :     if( xInvocationAdapterFactory.is() && xListenerType.is() && xListener.is() )
      98             :     {
      99             :        Reference< XInvocation > xInvocationToAllListenerMapper =
     100          97 :             (XInvocation*)new InvocationToAllListenerMapper( xListenerType, xListener, Helper );
     101         194 :         Type aListenerType( xListenerType->getTypeClass(), xListenerType->getName());
     102         194 :         Sequence<Type> arg2(1);
     103          97 :         arg2[0] = aListenerType;
     104         194 :         xAdapter = xInvocationAdapterFactory->createAdapter( xInvocationToAllListenerMapper, arg2 );
     105             :     }
     106          97 :     return xAdapter;
     107             : }
     108             : 
     109             : 
     110             : 
     111             : // InvocationToAllListenerMapper
     112          97 : InvocationToAllListenerMapper::InvocationToAllListenerMapper
     113             :     ( const Reference< XIdlClass >& ListenerType, const Reference< XAllListener >& AllListener, const Any& Helper )
     114             :         : m_xAllListener( AllListener )
     115             :         , m_xListenerType( ListenerType )
     116          97 :         , m_Helper( Helper )
     117             : {
     118          97 : }
     119             : 
     120             : 
     121           0 : Reference< XIntrospectionAccess > SAL_CALL InvocationToAllListenerMapper::getIntrospection(void)
     122             :     throw( RuntimeException, std::exception )
     123             : {
     124           0 :     return Reference< XIntrospectionAccess >();
     125             : }
     126             : 
     127             : 
     128           1 : 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           1 :     Any aRet;
     134             : 
     135             :     // Check if to firing or approveFiring has to be called
     136           2 :     Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( FunctionName );
     137           1 :     sal_Bool bApproveFiring = sal_False;
     138           1 :     if( !xMethod.is() )
     139           0 :         return aRet;
     140           2 :     Reference< XIdlClass > xReturnType = xMethod->getReturnType();
     141           2 :     Sequence< Reference< XIdlClass > > aExceptionSeq = xMethod->getExceptionTypes();
     142           2 :     if( ( xReturnType.is() && xReturnType->getTypeClass() != TypeClass_VOID ) ||
     143           1 :         aExceptionSeq.getLength() > 0 )
     144             :     {
     145           0 :         bApproveFiring = sal_True;
     146             :     }
     147             :     else
     148             :     {
     149           1 :         Sequence< ParamInfo > aParamSeq = xMethod->getParameterInfos();
     150           1 :         sal_uInt32 nParamCount = aParamSeq.getLength();
     151           1 :         if( nParamCount > 1 )
     152             :         {
     153           0 :             const ParamInfo* pInfos = aParamSeq.getConstArray();
     154           0 :             for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
     155             :             {
     156           0 :                 if( pInfos[ i ].aMode != ParamMode_IN )
     157             :                 {
     158           0 :                     bApproveFiring = sal_True;
     159           0 :                     break;
     160             :                 }
     161             :             }
     162           1 :         }
     163             :     }
     164             : 
     165           2 :     AllEventObject aAllEvent;
     166           1 :     aAllEvent.Source = (OWeakObject*) this;
     167           1 :     aAllEvent.Helper = m_Helper;
     168           1 :     aAllEvent.ListenerType = Type(m_xListenerType->getTypeClass(), m_xListenerType->getName());
     169           1 :     aAllEvent.MethodName = FunctionName;
     170           1 :     aAllEvent.Arguments = Params;
     171           1 :     if( bApproveFiring )
     172           0 :         aRet = m_xAllListener->approveFiring( aAllEvent );
     173             :     else
     174           1 :         m_xAllListener->firing( aAllEvent );
     175           1 :     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          16 : EventAttacherImpl::EventAttacherImpl( const Reference< XComponentContext >& rxContext )
     288          16 :     : m_xContext( rxContext )
     289             : {
     290          16 : }
     291             : 
     292             : 
     293          22 : EventAttacherImpl::~EventAttacherImpl()
     294             : {
     295          22 : }
     296             : 
     297             : 
     298          16 : Reference< XInterface > SAL_CALL EventAttacherImpl_CreateInstance( const Reference< XMultiServiceFactory >& rSMgr ) throw( Exception )
     299             : {
     300          16 :     Reference< XInterface > xRet;
     301          16 :     XEventAttacher *pEventAttacher = (XEventAttacher*) new EventAttacherImpl( comphelper::getComponentContext(rSMgr) );
     302             : 
     303          16 :     if (pEventAttacher)
     304             :     {
     305          16 :         xRet = Reference<XInterface>::query(pEventAttacher);
     306             :     }
     307             : 
     308          16 :     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          16 : Sequence<OUString> SAL_CALL EventAttacherImpl::getSupportedServiceNames_Static(  )
     332             : {
     333          16 :     OUString aStr(  SERVICENAME  );
     334          16 :     return Sequence< OUString >( &aStr, 1 );
     335             : }
     336             : 
     337         355 : void SAL_CALL EventAttacherImpl::initialize(const Sequence< Any >& Arguments) throw( Exception, RuntimeException, std::exception )
     338             : {
     339             :     // get services from the argument list
     340         355 :     const Any * pArray = Arguments.getConstArray();
     341         710 :     for( sal_Int32 i = 0; i < Arguments.getLength(); i++ )
     342             :     {
     343         355 :         if( pArray[i].getValueType().getTypeClass() != TypeClass_INTERFACE )
     344           0 :             throw IllegalArgumentException();
     345             : 
     346             :         // InvocationAdapter service ?
     347         355 :         Reference< XInvocationAdapterFactory2 > xALAS;
     348         355 :         pArray[i] >>= xALAS;
     349         355 :         if( xALAS.is() )
     350             :         {
     351           0 :             Guard< Mutex > aGuard( m_aMutex );
     352           0 :             m_xInvocationAdapterFactory = xALAS;
     353             :         }
     354             :         // Introspection service ?
     355         710 :         Reference< XIntrospection > xI;
     356         355 :         pArray[i] >>= xI;
     357         355 :         if( xI.is() )
     358             :         {
     359         355 :             Guard< Mutex > aGuard( m_aMutex );
     360         355 :             m_xIntrospection = xI;
     361             :         }
     362             :         // Reflection service ?
     363         710 :         Reference< XIdlReflection > xIdlR;
     364         355 :         pArray[i] >>= xIdlR;
     365         355 :         if( xIdlR.is() )
     366             :         {
     367           0 :             Guard< Mutex > aGuard( m_aMutex );
     368           0 :             m_xReflection = xIdlR;
     369             :         }
     370             :         // Converter Service ?
     371         710 :         Reference< XTypeConverter > xC;
     372         355 :         pArray[i] >>= xC;
     373         355 :         if( xC.is() )
     374             :         {
     375           0 :             Guard< Mutex > aGuard( m_aMutex );
     376           0 :             m_xConverter = xC;
     377             :         }
     378             : 
     379             :         // no right interface
     380         355 :         if( !xALAS.is() && !xI.is() && !xIdlR.is() && !xC.is() )
     381           0 :             throw IllegalArgumentException();
     382         355 :     }
     383         355 : }
     384             : 
     385             : 
     386             : //*** Private helper methods ***
     387         195 : Reference< XIntrospection > EventAttacherImpl::getIntrospection() throw( Exception )
     388             : {
     389         195 :     Guard< Mutex > aGuard( m_aMutex );
     390         195 :     if( !m_xIntrospection.is() )
     391             :     {
     392           0 :         m_xIntrospection = theIntrospection::get( m_xContext );
     393             :     }
     394         195 :     return m_xIntrospection;
     395             : }
     396             : 
     397             : 
     398             : //*** Private helper methods ***
     399         195 : Reference< XIdlReflection > EventAttacherImpl::getReflection() throw( Exception )
     400             : {
     401         195 :     Guard< Mutex > aGuard( m_aMutex );
     402         195 :     if( !m_xReflection.is() )
     403             :     {
     404           4 :         m_xReflection = theCoreReflection::get(m_xContext);
     405             :     }
     406         195 :     return m_xReflection;
     407             : }
     408             : 
     409             : 
     410             : //*** Private helper methods ***
     411         175 : Reference< XInvocationAdapterFactory2 > EventAttacherImpl::getInvocationAdapterService() throw( Exception )
     412             : {
     413         175 :     Guard< Mutex > aGuard( m_aMutex );
     414         175 :     if( !m_xInvocationAdapterFactory.is() )
     415             :     {
     416           4 :         m_xInvocationAdapterFactory = InvocationAdapterFactory::create(m_xContext);
     417             :     }
     418         175 :     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         236 : 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         195 : 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         195 :         , m_AllListener( AllListener_ )
     470             : {
     471         195 : }
     472             : 
     473             : 
     474           1 : void SAL_CALL FilterAllListenerImpl::firing(const AllEventObject& Event)
     475             :     throw( RuntimeException, std::exception )
     476             : {
     477           1 :     if( Event.MethodName == m_EventMethod && m_AllListener.is() )
     478           1 :         m_AllListener->firing( Event );
     479           1 : }
     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         156 : 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         156 :     if( !xObject.is() || !AllListener.is() )
     577           0 :         throw IllegalArgumentException();
     578             : 
     579         156 :     Reference< XInvocationAdapterFactory2 > xInvocationAdapterFactory = getInvocationAdapterService();
     580         156 :     if( !xInvocationAdapterFactory.is() )
     581           0 :         throw ServiceNotRegisteredException();
     582             : 
     583         312 :     Reference< XIdlReflection > xReflection = getReflection();
     584         156 :     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         312 :     Reference< XIntrospection > xIntrospection = getIntrospection();
     592         156 :     if( !xIntrospection.is() )
     593           0 :         return Reference<XEventListener>();
     594             : 
     595             :     // Inspect Introspection
     596         312 :     Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
     597             : 
     598         312 :     Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
     599         156 :     if( !xAccess.is() )
     600           0 :         return Reference<XEventListener>();
     601             : 
     602             :     return attachListenerForTarget(
     603             :         xAccess, xInvocationAdapterFactory, AllListener, aObjAny, Helper,
     604         312 :         ListenerType, AddListenerParam);
     605             : }
     606             : 
     607         195 : 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         195 :     Reference< XEventListener > xRet = NULL;
     617             : 
     618             :     // Construct the name of the addListener-Method.
     619         195 :     sal_Int32 nIndex = aListenerType.lastIndexOf('.');
     620             :     // set index to the interface name without package name
     621         195 :     if( nIndex == -1 )
     622             :         // not found
     623          41 :         nIndex = 0;
     624             :     else
     625         154 :         nIndex++;
     626             : 
     627         390 :     OUString aListenerName = (!aListenerType.isEmpty() && aListenerType[nIndex] == 'X') ? aListenerType.copy(nIndex+1) : aListenerType;
     628         390 :     OUString aAddListenerName = "add" + aListenerName;
     629             : 
     630             :     // Send Methods to the correct addListener-Method
     631         390 :     Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER );
     632         195 :     const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
     633        2211 :     for (sal_Int32 i = 0, n = aMethodSeq.getLength(); i < n ; ++i)
     634             :     {
     635        2113 :         const Reference< XIdlMethod >& rxMethod = pMethods[i];
     636             : 
     637             :         // Is it the correct method?
     638        2113 :         OUString aMethName = rxMethod->getName();
     639             : 
     640        2113 :         if (aAddListenerName != aMethName)
     641        2016 :             continue;
     642             : 
     643         194 :         Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes();
     644          97 :         sal_uInt32 nParamCount = params.getLength();
     645             : 
     646         194 :         Reference< XIdlClass > xListenerType;
     647          97 :         if( nParamCount == 1 )
     648          97 :             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         194 :             xInvocationAdapterFactory, xListenerType, xAllListener, aHelper );
     655             : 
     656          97 :         if( !xAdapter.is() )
     657           0 :             throw CannotCreateAdapterException();
     658          97 :         xRet = Reference< XEventListener >( xAdapter, UNO_QUERY );
     659             : 
     660             :         // Just the Listener as parameter?
     661          97 :         if( nParamCount == 1 )
     662             :         {
     663          97 :             Sequence< Any > args( 1 );
     664          97 :             args.getArray()[0] <<= xAdapter;
     665             :             try
     666             :             {
     667          97 :                 rxMethod->invoke( aObject, args );
     668             :             }
     669           0 :             catch( const InvocationTargetException& )
     670             :             {
     671           0 :                 throw IntrospectionException();
     672          97 :             }
     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          97 :         break;
     702             :         // else...
     703             :         // Anything else is not supported
     704           0 :     }
     705             : 
     706         390 :     return xRet;
     707             : }
     708             : 
     709          19 : 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          19 :     sal_Int32 nCount = aListeners.getLength();
     715          19 :     if (nCount != AllListeners.getLength())
     716             :         // This is a prerequisite!
     717           0 :         throw RuntimeException();
     718             : 
     719          19 :     if (!xObject.is())
     720           0 :         throw IllegalArgumentException();
     721             : 
     722          19 :     Reference< XInvocationAdapterFactory2 > xInvocationAdapterFactory = getInvocationAdapterService();
     723          19 :     if( !xInvocationAdapterFactory.is() )
     724           0 :         throw ServiceNotRegisteredException();
     725             : 
     726          38 :     Reference< XIdlReflection > xReflection = getReflection();
     727          19 :     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          38 :     Reference< XIntrospection > xIntrospection = getIntrospection();
     735          19 :     if( !xIntrospection.is() )
     736           0 :         return Sequence< Reference<XEventListener> >();
     737             : 
     738             :     // Inspect Introspection
     739          38 :     Any aObjAny( &xObject, ::getCppuType(static_cast<const Reference<XInterface>*>(0)) );
     740             : 
     741          38 :     Reference<XIntrospectionAccess> xAccess = xIntrospection->inspect(aObjAny);
     742          19 :     if (!xAccess.is())
     743           0 :         return Sequence< Reference<XEventListener> >();
     744             : 
     745          38 :     Sequence< Reference<XEventListener> > aRet(nCount);
     746          19 :     Reference<XEventListener>* pArray = aRet.getArray();
     747             : 
     748          58 :     for (sal_Int32 i = 0; i < nCount; ++i)
     749             :     {
     750         195 :         pArray[i] = attachListenerForTarget(
     751          39 :             xAccess, xInvocationAdapterFactory, AllListeners[ i ],
     752         156 :             aObjAny, aListeners[i].Helper, aListeners[i].ListenerType, aListeners[i].AddListenerParam);
     753             :     }
     754             : 
     755          38 :     return aRet;
     756             : }
     757             : 
     758             : // XEventAttacher
     759         156 : 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         156 :         new FilterAllListenerImpl( this, EventMethod, AllListener );
     773         156 :     return attachListener( xObject, aFilterListener, Helper, ListenerType, AddListenerParam);
     774             : }
     775             : 
     776             : // XEventAttacher
     777          20 : 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          20 :     if( !xObject.is() || !aToRemoveListener.is() )
     787           0 :         throw IllegalArgumentException();
     788             : 
     789          20 :     Reference< XIdlReflection > xReflection = getReflection();
     790          20 :     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          40 :     Reference< XIntrospection > xIntrospection = getIntrospection();
     798          20 :     if( !xIntrospection.is() )
     799           0 :         throw IntrospectionException();
     800             : 
     801             :     //Inspect Introspection
     802          40 :     Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) );
     803          40 :     Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny );
     804          20 :     if( !xAccess.is() )
     805           0 :         throw IntrospectionException();
     806             : 
     807             :     // Create name of the removeListener-Method
     808          40 :     OUString aRemoveListenerName;
     809          40 :     OUString aListenerName( ListenerType );
     810          20 :     sal_Int32 nIndex = aListenerName.lastIndexOf( '.' );
     811             :     // set index to the interface name without package name
     812          20 :     if( nIndex == -1 )
     813             :         // not found
     814          20 :         nIndex = 0;
     815             :     else
     816           0 :         nIndex++;
     817          20 :     if( aListenerName[nIndex] == 'X' )
     818             :         // erase X from the interface name
     819          20 :         aListenerName = aListenerName.copy( nIndex +1 );
     820          20 :     aRemoveListenerName = "remove" + aListenerName;
     821             : 
     822             :     // Search methods for the correct removeListener method
     823          40 :     Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER );
     824          20 :     sal_uInt32 i, nLen = aMethodSeq.getLength();
     825          20 :     const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
     826         180 :     for( i = 0 ; i < nLen ; i++ )
     827             :     {
     828             :         // Call Methode
     829         180 :         const Reference< XIdlMethod >& rxMethod = pMethods[i];
     830             : 
     831             :         // Is it the right method?
     832         180 :         if( aRemoveListenerName == rxMethod->getName() )
     833             :         {
     834          20 :             Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes();
     835          20 :             sal_uInt32 nParamCount = params.getLength();
     836             : 
     837             :             // Just the Listener as parameter?
     838          20 :             if( nParamCount == 1 )
     839             :             {
     840          20 :                 Sequence< Any > args( 1 );
     841          20 :                 args.getArray()[0] <<= aToRemoveListener;
     842             :                 try
     843             :                 {
     844          20 :                     rxMethod->invoke( aObjAny, args );
     845             :                 }
     846           0 :                 catch( const InvocationTargetException& )
     847             :                 {
     848           0 :                     throw IntrospectionException();
     849          20 :                 }
     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          20 :             break;
     877             :         }
     878          20 :     }
     879          20 : }
     880             : 
     881          19 : 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          19 :     sal_Int32 nCount = aListeners.getLength();
     886          19 :     Sequence< Reference<XAllListener> > aFilterListeners(nCount);
     887          58 :     for (sal_Int32 i = 0; i < nCount; ++i)
     888             :     {
     889          39 :         aFilterListeners[i] = (XAllListener*)
     890          78 :             new FilterAllListenerImpl(this, aListeners[i].EventMethod, aListeners[i].AllListener);
     891             :     }
     892             : 
     893          19 :     return attachListeners(xObject, aFilterListeners, aListeners);
     894             : }
     895             : 
     896             : }
     897             : 
     898             : extern "C"
     899             : {
     900          16 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL evtatt_component_getFactory(
     901             :     const sal_Char * pImplName, void * pServiceManager, void * )
     902             : {
     903          16 :     void * pRet = 0;
     904             : 
     905          16 :     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          16 :             ::comp_EventAttacher::EventAttacherImpl::getSupportedServiceNames_Static() ) );
     912             : 
     913          16 :         if (xFactory.is())
     914             :         {
     915          16 :             xFactory->acquire();
     916          16 :             pRet = xFactory.get();
     917          16 :         }
     918             :     }
     919             : 
     920          16 :     return pRet;
     921             : }
     922             : }
     923             : 
     924             : 
     925             : 
     926             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10