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

Generated by: LCOV version 1.10