LCOV - code coverage report
Current view: top level - comphelper/source/eventattachermgr - eventattachermgr.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 360 0.0 %
Date: 2014-04-14 Functions: 0 40 0.0 %
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             : 
      20             : #include <osl/mutex.hxx>
      21             : #include <osl/diagnose.h>
      22             : #include <comphelper/eventattachermgr.hxx>
      23             : #include <comphelper/processfactory.hxx>
      24             : #include <com/sun/star/beans/theIntrospection.hpp>
      25             : #include <com/sun/star/io/XObjectInputStream.hpp>
      26             : #include <com/sun/star/io/XPersistObject.hpp>
      27             : #include <com/sun/star/io/XObjectOutputStream.hpp>
      28             : #include <com/sun/star/io/XMarkableStream.hpp>
      29             : #include <com/sun/star/lang/XInitialization.hpp>
      30             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      31             : #include <com/sun/star/reflection/theCoreReflection.hpp>
      32             : #include <com/sun/star/reflection/XIdlClass.hpp>
      33             : #include <com/sun/star/reflection/XIdlReflection.hpp>
      34             : #include <com/sun/star/reflection/XIdlMethod.hpp>
      35             : #include <com/sun/star/script/Converter.hpp>
      36             : #include <com/sun/star/script/XEngineListener.hpp>
      37             : #include <com/sun/star/script/XEventAttacher2.hpp>
      38             : #include <com/sun/star/script/XEventAttacherManager.hpp>
      39             : #include <com/sun/star/script/XScriptListener.hpp>
      40             : #include <cppuhelper/weak.hxx>
      41             : #include <cppuhelper/interfacecontainer.hxx>
      42             : #include <cppuhelper/implbase1.hxx>
      43             : #include <cppuhelper/implbase2.hxx>
      44             : 
      45             : #include <deque>
      46             : #include <algorithm>
      47             : #include <functional>
      48             : 
      49             : using namespace com::sun::star::uno;
      50             : using namespace com::sun::star::io;
      51             : using namespace com::sun::star::lang;
      52             : using namespace com::sun::star::beans;
      53             : using namespace com::sun::star::script;
      54             : using namespace com::sun::star::reflection;
      55             : using namespace cppu;
      56             : using namespace osl;
      57             : 
      58             : 
      59             : namespace comphelper
      60             : {
      61             : 
      62             : 
      63           0 : struct AttachedObject_Impl
      64             : {
      65             :     Reference< XInterface >                 xTarget;
      66             :     Sequence< Reference< XEventListener > > aAttachedListenerSeq;
      67             :     Any                                     aHelper;
      68             : };
      69             : 
      70           0 : struct AttacherIndex_Impl
      71             : {
      72             :     ::std::deque< ScriptEventDescriptor > aEventList;
      73             :     ::std::deque< AttachedObject_Impl > aObjList;
      74             : };
      75             : 
      76             : 
      77             : class ImplEventAttacherManager
      78             :     : public WeakImplHelper2< XEventAttacherManager, XPersistObject >
      79             : {
      80             :     friend class AttacherAllListener_Impl;
      81             :     ::std::deque< AttacherIndex_Impl >  aIndex;
      82             :     Mutex aLock;
      83             :     // Container for the ScriptListener
      84             :     OInterfaceContainerHelper           aScriptListeners;
      85             :     // Instance of EventAttacher
      86             :     Reference< XEventAttacher2 >        xAttacher;
      87             :     Reference< XComponentContext >      mxContext;
      88             :     Reference< XIdlReflection >         mxCoreReflection;
      89             :     Reference< XIntrospection >         mxIntrospection;
      90             :     Reference< XTypeConverter >         xConverter;
      91             :     sal_Int16                           nVersion;
      92             : public:
      93             :     ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection,
      94             :                               const Reference< XComponentContext > xContext );
      95             :     virtual ~ImplEventAttacherManager();
      96             : 
      97             :     // Methods of XEventAttacherManager
      98             :     virtual void SAL_CALL registerScriptEvent(sal_Int32 Index, const ScriptEventDescriptor& ScriptEvent)
      99             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     100             :     virtual void SAL_CALL registerScriptEvents(sal_Int32 Index, const Sequence< ScriptEventDescriptor >& ScriptEvents)
     101             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     102             :     virtual void SAL_CALL revokeScriptEvent(sal_Int32 Index, const OUString& ListenerType, const OUString& EventMethod, const OUString& removeListenerParam)
     103             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     104             :     virtual void SAL_CALL revokeScriptEvents(sal_Int32 Index)
     105             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     106             :     virtual void SAL_CALL insertEntry(sal_Int32 Index)
     107             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     108             :     virtual void SAL_CALL removeEntry(sal_Int32 Index)
     109             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     110             :     virtual Sequence< ScriptEventDescriptor > SAL_CALL getScriptEvents(sal_Int32 Index)
     111             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     112             :     virtual void SAL_CALL attach(sal_Int32 Index, const Reference< XInterface >& Object, const Any& Helper)
     113             :         throw( IllegalArgumentException, ServiceNotRegisteredException, RuntimeException, std::exception ) SAL_OVERRIDE;
     114             :     virtual void SAL_CALL detach(sal_Int32 nIndex, const Reference< XInterface >& xObject)
     115             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     116             :     virtual void SAL_CALL addScriptListener(const Reference< XScriptListener >& aListener)
     117             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     118             :     virtual void SAL_CALL removeScriptListener(const Reference< XScriptListener >& Listener)
     119             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     120             : 
     121             :     // Methods of XPersistObject
     122             :     virtual OUString SAL_CALL getServiceName(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     123             :     virtual void SAL_CALL write(const Reference< XObjectOutputStream >& OutStream) throw( IOException, RuntimeException, std::exception ) SAL_OVERRIDE;
     124             :     virtual void SAL_CALL read(const Reference< XObjectInputStream >& InStream) throw( IOException, RuntimeException, std::exception ) SAL_OVERRIDE;
     125             : 
     126             : private:
     127             :     Reference< XIdlReflection > getReflection() throw( Exception );
     128             : 
     129             :     /** checks if <arg>_nIndex</arg> is a valid index, throws an <type>IllegalArgumentException</type> if not
     130             :     @param _nIndex
     131             :         the index to check
     132             :     @return
     133             :         the iterator pointing to the position indicated by the index
     134             :     */
     135             :     ::std::deque<AttacherIndex_Impl>::iterator implCheckIndex( sal_Int32 _nIndex ) SAL_THROW ( ( IllegalArgumentException ) );
     136             : };
     137             : 
     138             : 
     139             : 
     140             : 
     141             : 
     142             : 
     143             : // Implementation of an EventAttacher-subclass 'AllListeners', which
     144             : // only passes individual events of the general AllListeners.
     145           0 : class AttacherAllListener_Impl : public WeakImplHelper1< XAllListener >
     146             : {
     147             :     ImplEventAttacherManager*           mpManager;
     148             :     Reference< XEventAttacherManager >  xManager;
     149             :     OUString                            aScriptType;
     150             :     OUString                            aScriptCode;
     151             : 
     152             :     void convertToEventReturn( Any & rRet, const Type & rRetType )
     153             :         throw( CannotConvertException );
     154             : public:
     155             :     AttacherAllListener_Impl( ImplEventAttacherManager* pManager_, const OUString &rScriptType_,
     156             :                                 const OUString & rScriptCode_ );
     157             : 
     158             :     // Methods of XAllListener
     159             :     virtual void SAL_CALL firing(const AllEventObject& Event) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     160             :     virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw( InvocationTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     161             : 
     162             :     // Methods of XEventListener
     163             :     virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     164             : };
     165             : 
     166             : 
     167           0 : AttacherAllListener_Impl::AttacherAllListener_Impl
     168             : (
     169             :     ImplEventAttacherManager*   pManager_,
     170             :     const OUString &             rScriptType_,
     171             :     const OUString &             rScriptCode_
     172             : )
     173             :     : mpManager( pManager_ )
     174             :     , xManager( pManager_ )
     175             :     , aScriptType( rScriptType_ )
     176           0 :     , aScriptCode( rScriptCode_ )
     177             : {
     178           0 : }
     179             : 
     180             : 
     181             : 
     182             : // Methods of XAllListener
     183           0 : void SAL_CALL AttacherAllListener_Impl::firing(const AllEventObject& Event)
     184             :     throw( RuntimeException, std::exception )
     185             : {
     186           0 :     ScriptEvent aScriptEvent;
     187           0 :     aScriptEvent.Source         = (OWeakObject *)mpManager; // get correct XInterface
     188           0 :     aScriptEvent.ListenerType   = Event.ListenerType;
     189           0 :     aScriptEvent.MethodName     = Event.MethodName;
     190           0 :     aScriptEvent.Arguments      = Event.Arguments;
     191           0 :     aScriptEvent.Helper         = Event.Helper;
     192           0 :     aScriptEvent.ScriptType     = aScriptType;
     193           0 :     aScriptEvent.ScriptCode     = aScriptCode;
     194             : 
     195             :     // Iterate over all listeners and pass events.
     196           0 :     OInterfaceIteratorHelper aIt( mpManager->aScriptListeners );
     197           0 :     while( aIt.hasMoreElements() )
     198           0 :         ((XScriptListener *)aIt.next())->firing( aScriptEvent );
     199           0 : }
     200             : 
     201             : 
     202             : // Convert to the standard event return
     203           0 : void AttacherAllListener_Impl::convertToEventReturn( Any & rRet, const Type & rRetType )
     204             :     throw( CannotConvertException )
     205             : {
     206             :     // no return value? Set to the specified values
     207           0 :     if( rRet.getValueType().getTypeClass() == TypeClass_VOID )
     208             :     {
     209           0 :         switch( rRetType.getTypeClass()  )
     210             :         {
     211             :             case TypeClass_INTERFACE:
     212             :                 {
     213           0 :                 rRet <<= Reference< XInterface >();
     214             :                 }
     215           0 :                 break;
     216             : 
     217             :             case TypeClass_BOOLEAN:
     218           0 :                 rRet <<= sal_True;
     219           0 :                 break;
     220             : 
     221             :             case TypeClass_STRING:
     222           0 :                 rRet <<= OUString();
     223           0 :                 break;
     224             : 
     225           0 :             case TypeClass_FLOAT:           rRet <<= float(0);  break;
     226           0 :             case TypeClass_DOUBLE:          rRet <<= double(0.0);  break;
     227           0 :             case TypeClass_BYTE:            rRet <<= sal_uInt8(0);      break;
     228           0 :             case TypeClass_SHORT:           rRet <<= sal_Int16( 0 );    break;
     229           0 :             case TypeClass_LONG:            rRet <<= sal_Int32( 0 );    break;
     230           0 :             case TypeClass_UNSIGNED_SHORT:  rRet <<= sal_uInt16( 0 );   break;
     231           0 :             case TypeClass_UNSIGNED_LONG:   rRet <<= sal_uInt32( 0 );   break;
     232             : 
     233             :             default:
     234             :                 OSL_ASSERT(false);
     235           0 :                 break;
     236             :         }
     237             :     }
     238           0 :     else if( !rRet.getValueType().equals( rRetType ) )
     239             :     {
     240           0 :         if( mpManager->xConverter.is() )
     241           0 :             rRet = mpManager->xConverter->convertTo( rRet, rRetType );
     242             :         else
     243           0 :             throw CannotConvertException();
     244             :     }
     245           0 : }
     246             : 
     247             : 
     248             : // Methods of XAllListener
     249           0 : Any SAL_CALL AttacherAllListener_Impl::approveFiring( const AllEventObject& Event )
     250             :     throw( InvocationTargetException, RuntimeException, std::exception )
     251             : {
     252           0 :     ScriptEvent aScriptEvent;
     253           0 :     aScriptEvent.Source         = (OWeakObject *)mpManager; // get correct XInterface
     254           0 :     aScriptEvent.ListenerType   = Event.ListenerType;
     255           0 :     aScriptEvent.MethodName     = Event.MethodName;
     256           0 :     aScriptEvent.Arguments      = Event.Arguments;
     257           0 :     aScriptEvent.Helper         = Event.Helper;
     258           0 :     aScriptEvent.ScriptType     = aScriptType;
     259           0 :     aScriptEvent.ScriptCode     = aScriptCode;
     260             : 
     261           0 :     Any aRet;
     262             :     // Iterate over all listeners and pass events.
     263           0 :     OInterfaceIteratorHelper aIt( mpManager->aScriptListeners );
     264           0 :     while( aIt.hasMoreElements() )
     265             :     {
     266           0 :         aRet = ((XScriptListener *)aIt.next())->approveFiring( aScriptEvent );
     267             :         try
     268             :         {
     269           0 :             Reference< XIdlClass > xListenerType = mpManager->getReflection()->
     270           0 :                         forName( Event.ListenerType.getTypeName() );
     271           0 :             Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName );
     272           0 :             if( xMeth.is() )
     273             :             {
     274           0 :                 Reference< XIdlClass > xRetType = xMeth->getReturnType();
     275           0 :                 Type aRetType(xRetType->getTypeClass(), xRetType->getName());
     276           0 :                 convertToEventReturn( aRet, aRetType );
     277             :             }
     278             : 
     279           0 :             switch( aRet.getValueType().getTypeClass()  )
     280             :             {
     281             :                 case TypeClass_INTERFACE:
     282             :                     {
     283             :                     // Interface not null, return
     284           0 :                     Reference< XInterface > x;
     285           0 :                     aRet >>= x;
     286           0 :                     if( x.is() )
     287           0 :                         return aRet;
     288             :                     }
     289           0 :                     break;
     290             : 
     291             :                 case TypeClass_BOOLEAN:
     292             :                     // FALSE -> Return
     293           0 :                     if( !(*(sal_Bool*)aRet.getValue()) )
     294           0 :                         return aRet;
     295           0 :                     break;
     296             : 
     297             :                 case TypeClass_STRING:
     298             :                     // none empty string -> return
     299           0 :                     if( !((OUString*)aRet.getValue())->isEmpty() )
     300           0 :                         return aRet;
     301           0 :                     break;
     302             : 
     303             :                     // none zero number -> return
     304           0 :                 case TypeClass_FLOAT:           if( *((float*)aRet.getValue()) )    return aRet; break;
     305           0 :                 case TypeClass_DOUBLE:          if( *((double*)aRet.getValue()) )   return aRet; break;
     306           0 :                 case TypeClass_BYTE:            if( *((sal_uInt8*)aRet.getValue()) )    return aRet; break;
     307           0 :                 case TypeClass_SHORT:           if( *((sal_Int16*)aRet.getValue()) )    return aRet; break;
     308           0 :                 case TypeClass_LONG:            if( *((sal_Int32*)aRet.getValue()) )    return aRet; break;
     309           0 :                 case TypeClass_UNSIGNED_SHORT:  if( *((sal_uInt16*)aRet.getValue()) )   return aRet; break;
     310           0 :                 case TypeClass_UNSIGNED_LONG:   if( *((sal_uInt32*)aRet.getValue()) )   return aRet; break;
     311             : 
     312             :                 default:
     313             :                     OSL_ASSERT(false);
     314           0 :                     break;
     315           0 :             }
     316             :         }
     317           0 :         catch( CannotConvertException& )
     318             :         {
     319             :             // silent ignore conversions errors from a script call
     320           0 :             Reference< XIdlClass > xListenerType = mpManager->getReflection()->
     321           0 :                         forName( Event.ListenerType.getTypeName() );
     322           0 :             Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName );
     323           0 :             if( xMeth.is() )
     324             :             {
     325           0 :                 Reference< XIdlClass > xRetType = xMeth->getReturnType();
     326           0 :                 Type aRetType(xRetType->getTypeClass(), xRetType->getName());
     327           0 :                 aRet.clear();
     328           0 :                 convertToEventReturn( aRet, aRetType );
     329           0 :             }
     330             :         }
     331             :     }
     332           0 :     return aRet;
     333             : }
     334             : 
     335             : 
     336             : // Methods of XEventListener
     337           0 : void SAL_CALL AttacherAllListener_Impl::disposing(const EventObject& )
     338             :     throw( RuntimeException, std::exception )
     339             : {
     340             :     // It is up to the container to release the object
     341           0 : }
     342             : 
     343             : 
     344             : // Constructor method for EventAttacherManager
     345           0 : Reference< XEventAttacherManager > createEventAttacherManager( const Reference< XComponentContext > & rxContext )
     346             :     throw( Exception )
     347             : {
     348           0 :     Reference< XIntrospection > xIntrospection = theIntrospection::get( rxContext );
     349           0 :     return new ImplEventAttacherManager( xIntrospection, rxContext );
     350             : }
     351             : 
     352             : 
     353           0 : ImplEventAttacherManager::ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection,
     354             :                                                     const Reference< XComponentContext > xContext )
     355             :     : aScriptListeners( aLock )
     356             :     , mxContext( xContext )
     357             :     , mxIntrospection( rIntrospection )
     358           0 :     , nVersion(0)
     359             : {
     360           0 :     if ( xContext.is() )
     361             :     {
     362           0 :         Reference< XInterface > xIFace( xContext->getServiceManager()->createInstanceWithContext(
     363           0 :              OUString( "com.sun.star.script.EventAttacher" ), xContext)  );
     364           0 :         if ( xIFace.is() )
     365             :         {
     366           0 :             xAttacher = Reference< XEventAttacher2 >::query( xIFace );
     367             :         }
     368           0 :         xConverter = Converter::create(xContext);
     369             :     }
     370             : 
     371           0 :     Reference< XInitialization > xInit( xAttacher, UNO_QUERY );
     372           0 :     if( xInit.is() )
     373             :     {
     374           0 :         Sequence< Any > Arguments( 1 );
     375           0 :         Arguments[0] <<= rIntrospection;
     376           0 :         xInit->initialize( Arguments );
     377           0 :     }
     378           0 : }
     379             : 
     380             : 
     381           0 : ImplEventAttacherManager::~ImplEventAttacherManager()
     382             : {
     383           0 : }
     384             : 
     385           0 : Reference< XIdlReflection > ImplEventAttacherManager::getReflection() throw( Exception )
     386             : {
     387           0 :     Guard< Mutex > aGuard( aLock );
     388             :     // Do we already have a service? If not, create one.
     389           0 :     if( !mxCoreReflection.is() )
     390             :     {
     391           0 :         mxCoreReflection = theCoreReflection::get(mxContext);
     392             :     }
     393           0 :     return mxCoreReflection;
     394             : }
     395             : 
     396             : 
     397             : 
     398           0 : ::std::deque<AttacherIndex_Impl>::iterator ImplEventAttacherManager::implCheckIndex( sal_Int32 _nIndex ) SAL_THROW ( ( IllegalArgumentException ) )
     399             : {
     400           0 :     if (_nIndex < 0)
     401           0 :         throw IllegalArgumentException();
     402             : 
     403           0 :     ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin();
     404           0 :     for ( sal_Int32 i = 0; (i < _nIndex) && (aIt != aIndex.end()); ++i, ++aIt )
     405             :         ;
     406             : 
     407           0 :     if( aIt == aIndex.end() )
     408           0 :         throw IllegalArgumentException();
     409             : 
     410           0 :     return aIt;
     411             : }
     412             : 
     413             : namespace {
     414             : 
     415             : class DetachObject : public std::unary_function<AttachedObject_Impl, void>
     416             : {
     417             :     ImplEventAttacherManager& mrMgr;
     418             :     sal_Int32 mnIdx;
     419             : public:
     420           0 :     DetachObject(ImplEventAttacherManager& rMgr, sal_Int32 nIdx) :
     421           0 :         mrMgr(rMgr), mnIdx(nIdx) {}
     422             : 
     423           0 :     void operator() (AttachedObject_Impl& rObj)
     424             :     {
     425           0 :         mrMgr.detach(mnIdx, rObj.xTarget);
     426           0 :     }
     427             : };
     428             : 
     429             : class AttachObject : public std::unary_function<AttachedObject_Impl, void>
     430             : {
     431             :     ImplEventAttacherManager& mrMgr;
     432             :     sal_Int32 mnIdx;
     433             : public:
     434           0 :     AttachObject(ImplEventAttacherManager& rMgr, sal_Int32 nIdx) :
     435           0 :         mrMgr(rMgr), mnIdx(nIdx) {}
     436             : 
     437           0 :     void operator() (AttachedObject_Impl& rObj)
     438             :     {
     439           0 :         mrMgr.attach(mnIdx, rObj.xTarget, rObj.aHelper);
     440           0 :     }
     441             : };
     442             : 
     443             : }
     444             : 
     445             : 
     446             : // Methods of XEventAttacherManager
     447           0 : void SAL_CALL ImplEventAttacherManager::registerScriptEvent
     448             : (
     449             :     sal_Int32 nIndex,
     450             :     const ScriptEventDescriptor& ScriptEvent
     451             : )
     452             :     throw( IllegalArgumentException, RuntimeException, std::exception )
     453             : {
     454           0 :     Guard< Mutex > aGuard( aLock );
     455             : 
     456             :     // Examine the index and apply the array
     457           0 :     ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
     458             : 
     459           0 :     ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
     460             : 
     461           0 :     ScriptEventDescriptor aEvt = ScriptEvent;
     462           0 :     sal_Int32 nLastDot = aEvt.ListenerType.lastIndexOf('.');
     463           0 :     if (nLastDot != -1)
     464           0 :         aEvt.ListenerType = aEvt.ListenerType.copy(nLastDot+1);
     465           0 :     (*aIt).aEventList.push_back( aEvt );
     466             : 
     467             :     // register new new Event
     468           0 :     ::std::deque< AttachedObject_Impl >::iterator aObjIt =  (*aIt).aObjList.begin();
     469           0 :     ::std::deque< AttachedObject_Impl >::iterator aObjEnd = (*aIt).aObjList.end();
     470           0 :     while( aObjIt != aObjEnd )
     471             :     {
     472             :         // resize
     473           0 :         sal_Int32 nPos = (*aObjIt).aAttachedListenerSeq.getLength();
     474           0 :         (*aObjIt).aAttachedListenerSeq.realloc( nPos + 1 );
     475           0 :         Reference< XEventListener > * pArray = (*aObjIt).aAttachedListenerSeq.getArray();
     476             : 
     477             :         Reference< XAllListener > xAll =
     478           0 :             new AttacherAllListener_Impl( this, ScriptEvent.ScriptType, ScriptEvent.ScriptCode );
     479             :         try
     480             :         {
     481           0 :         pArray[nPos] = xAttacher->attachSingleEventListener( (*aObjIt).xTarget, xAll,
     482           0 :                         (*aObjIt).aHelper, ScriptEvent.ListenerType,
     483           0 :                         ScriptEvent.AddListenerParam, ScriptEvent.EventMethod );
     484             :         }
     485           0 :         catch( Exception& )
     486             :         {
     487             :         }
     488             : 
     489           0 :         ++aObjIt;
     490           0 :     }
     491           0 : }
     492             : 
     493             : 
     494           0 : void SAL_CALL ImplEventAttacherManager::registerScriptEvents
     495             : (
     496             :     sal_Int32 nIndex,
     497             :     const Sequence< ScriptEventDescriptor >& ScriptEvents
     498             : )
     499             :     throw( IllegalArgumentException, RuntimeException, std::exception )
     500             : {
     501           0 :     Guard< Mutex > aGuard( aLock );
     502             : 
     503             :     // Examine the index and apply the array
     504           0 :     ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
     505             : 
     506           0 :     ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
     507           0 :     ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex));
     508             : 
     509           0 :     const ScriptEventDescriptor* pArray = ScriptEvents.getConstArray();
     510           0 :     sal_Int32 nLen = ScriptEvents.getLength();
     511           0 :     for( sal_Int32 i = 0 ; i < nLen ; i++ )
     512           0 :         registerScriptEvent( nIndex, pArray[ i ] );
     513             : 
     514           0 :     ::std::for_each(aList.begin(), aList.end(), AttachObject(*this, nIndex));
     515           0 : }
     516             : 
     517             : 
     518           0 : void SAL_CALL ImplEventAttacherManager::revokeScriptEvent
     519             : (
     520             :     sal_Int32 nIndex,
     521             :     const OUString& ListenerType,
     522             :     const OUString& EventMethod,
     523             :     const OUString& ToRemoveListenerParam
     524             : )
     525             :     throw( IllegalArgumentException, RuntimeException, std::exception )
     526             : {
     527           0 :     Guard< Mutex > aGuard( aLock );
     528             : 
     529           0 :     ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
     530             : 
     531           0 :     ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
     532           0 :     ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex));
     533             : 
     534           0 :     OUString aLstType = ListenerType;
     535           0 :     sal_Int32 nLastDot = aLstType.lastIndexOf('.');
     536           0 :     if (nLastDot != -1)
     537           0 :         aLstType = aLstType.copy(nLastDot+1);
     538             : 
     539           0 :     ::std::deque< ScriptEventDescriptor >::iterator aEvtIt =    (*aIt).aEventList.begin();
     540           0 :     ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd =   (*aIt).aEventList.end();
     541           0 :     while( aEvtIt != aEvtEnd )
     542             :     {
     543           0 :         if( aLstType            == (*aEvtIt).ListenerType
     544           0 :           && EventMethod            == (*aEvtIt).EventMethod
     545           0 :           && ToRemoveListenerParam  == (*aEvtIt).AddListenerParam )
     546             :         {
     547           0 :             (*aIt).aEventList.erase( aEvtIt );
     548           0 :             break;
     549             :         }
     550             : 
     551           0 :         ++aEvtIt;
     552             :     }
     553           0 :     ::std::for_each(aList.begin(), aList.end(), AttachObject(*this, nIndex));
     554           0 : }
     555             : 
     556             : 
     557           0 : void SAL_CALL ImplEventAttacherManager::revokeScriptEvents(sal_Int32 nIndex )
     558             :     throw( IllegalArgumentException, RuntimeException, std::exception )
     559             : {
     560           0 :     Guard< Mutex > aGuard( aLock );
     561           0 :     ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
     562             : 
     563           0 :     ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
     564           0 :     ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex));
     565           0 :     (*aIt).aEventList.clear();
     566           0 :     ::std::for_each(aList.begin(), aList.end(), AttachObject(*this, nIndex));
     567           0 : }
     568             : 
     569             : 
     570           0 : void SAL_CALL ImplEventAttacherManager::insertEntry(sal_Int32 nIndex)
     571             :     throw( IllegalArgumentException, RuntimeException, std::exception )
     572             : {
     573           0 :     Guard< Mutex > aGuard( aLock );
     574           0 :     if( nIndex < 0 )
     575           0 :         throw IllegalArgumentException();
     576             : 
     577           0 :     if ( static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() )
     578           0 :         aIndex.resize(nIndex+1);
     579             : 
     580           0 :     AttacherIndex_Impl aTmp;
     581           0 :     aIndex.insert( aIndex.begin() + nIndex, aTmp );
     582           0 : }
     583             : 
     584             : 
     585           0 : void SAL_CALL ImplEventAttacherManager::removeEntry(sal_Int32 nIndex)
     586             :     throw( IllegalArgumentException, RuntimeException, std::exception )
     587             : {
     588           0 :     Guard< Mutex > aGuard( aLock );
     589           0 :     ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
     590             : 
     591           0 :     ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
     592           0 :     ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex));
     593           0 :     aIndex.erase( aIt );
     594           0 : }
     595             : 
     596             : 
     597           0 : Sequence< ScriptEventDescriptor > SAL_CALL ImplEventAttacherManager::getScriptEvents(sal_Int32 nIndex)
     598             :     throw( IllegalArgumentException, RuntimeException, std::exception )
     599             : {
     600           0 :     Guard< Mutex > aGuard( aLock );
     601           0 :     ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
     602             : 
     603           0 :     Sequence< ScriptEventDescriptor > aSeq( (*aIt).aEventList.size() );
     604           0 :     ScriptEventDescriptor * pArray = aSeq.getArray();
     605             : 
     606           0 :     ::std::deque< ScriptEventDescriptor >::iterator aEvtIt =    (*aIt).aEventList.begin();
     607           0 :     ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd =   (*aIt).aEventList.end();
     608           0 :     sal_Int32 i = 0;
     609           0 :     while( aEvtIt != aEvtEnd )
     610             :     {
     611           0 :         pArray[i++] = *aEvtIt;
     612           0 :         ++aEvtIt;
     613             :     }
     614           0 :     return aSeq;
     615             : }
     616             : 
     617             : 
     618           0 : void SAL_CALL ImplEventAttacherManager::attach(sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any & Helper)
     619             :     throw( IllegalArgumentException, ServiceNotRegisteredException, RuntimeException, std::exception )
     620             : {
     621           0 :     Guard< Mutex > aGuard( aLock );
     622           0 :     if( nIndex < 0 || !xObject.is() )
     623           0 :         throw IllegalArgumentException();
     624             : 
     625           0 :     if( static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() )
     626             :     {
     627             :         // read older files
     628           0 :         if( nVersion == 1 )
     629             :         {
     630           0 :             insertEntry( nIndex );
     631           0 :             attach( nIndex, xObject, Helper );
     632           0 :             return;
     633             :         }
     634             :         else
     635           0 :             throw IllegalArgumentException();
     636             :     }
     637             : 
     638           0 :     ::std::deque< AttacherIndex_Impl >::iterator aCurrentPosition = aIndex.begin() + nIndex;
     639             : 
     640           0 :     AttachedObject_Impl aTmp;
     641           0 :     aTmp.xTarget = xObject;
     642           0 :     aTmp.aHelper = Helper;
     643           0 :     aCurrentPosition->aObjList.push_back( aTmp );
     644             : 
     645             :     //::std::deque< AttachedObject_Impl >::iterator aObjIt = (*aIt).aObjList.back();
     646           0 :     AttachedObject_Impl & rCurObj = aCurrentPosition->aObjList.back();
     647           0 :     rCurObj.aAttachedListenerSeq = Sequence< Reference< XEventListener > >( aCurrentPosition->aEventList.size() );
     648             : 
     649           0 :     if (aCurrentPosition->aEventList.empty())
     650           0 :         return;
     651             : 
     652           0 :     Sequence<com::sun::star::script::EventListener> aEvents(aCurrentPosition->aEventList.size());
     653           0 :     std::deque<ScriptEventDescriptor>::iterator itr = aCurrentPosition->aEventList.begin();
     654           0 :     std::deque<ScriptEventDescriptor>::iterator itrEnd = aCurrentPosition->aEventList.end();
     655           0 :     ::com::sun::star::script::EventListener* p = aEvents.getArray();
     656           0 :     size_t i = 0;
     657           0 :     for (; itr != itrEnd; ++itr)
     658             :     {
     659           0 :         com::sun::star::script::EventListener aListener;
     660           0 :         aListener.AllListener =
     661           0 :             new AttacherAllListener_Impl(this, itr->ScriptType, itr->ScriptCode);
     662           0 :         aListener.Helper = rCurObj.aHelper;
     663           0 :         aListener.ListenerType = itr->ListenerType;
     664           0 :         aListener.EventMethod = itr->EventMethod;
     665           0 :         aListener.AddListenerParam = itr->AddListenerParam;
     666           0 :         p[i++] = aListener;
     667           0 :     }
     668             : 
     669             :     try
     670             :     {
     671           0 :         rCurObj.aAttachedListenerSeq =
     672           0 :             xAttacher->attachMultipleEventListeners(rCurObj.xTarget, aEvents);
     673             :     }
     674           0 :     catch (const Exception&)
     675             :     {
     676             :         // Fail gracefully.
     677           0 :     }
     678             : }
     679             : 
     680             : 
     681           0 : void SAL_CALL ImplEventAttacherManager::detach(sal_Int32 nIndex, const Reference< XInterface >& xObject)
     682             :     throw( IllegalArgumentException, RuntimeException, std::exception )
     683             : {
     684           0 :     Guard< Mutex > aGuard( aLock );
     685             :     //return;
     686           0 :     if( nIndex < 0 || static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() || !xObject.is() )
     687           0 :         throw IllegalArgumentException();
     688             : 
     689           0 :     ::std::deque< AttacherIndex_Impl >::iterator aCurrentPosition = aIndex.begin() + nIndex;
     690           0 :     ::std::deque< AttachedObject_Impl >::iterator aObjIt =  aCurrentPosition->aObjList.begin();
     691           0 :     ::std::deque< AttachedObject_Impl >::iterator aObjEnd = aCurrentPosition->aObjList.end();
     692           0 :     while( aObjIt != aObjEnd )
     693             :     {
     694           0 :         if( (*aObjIt).xTarget == xObject )
     695             :         {
     696           0 :             Reference< XEventListener > * pArray = (*aObjIt).aAttachedListenerSeq.getArray();
     697             : 
     698           0 :             ::std::deque< ScriptEventDescriptor >::iterator aEvtIt =    aCurrentPosition->aEventList.begin();
     699           0 :             ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd =   aCurrentPosition->aEventList.end();
     700           0 :             sal_Int32 i = 0;
     701           0 :             while( aEvtIt != aEvtEnd )
     702             :             {
     703           0 :                 if( pArray[i].is() )
     704             :                 {
     705             :                     try
     706             :                     {
     707           0 :                     xAttacher->removeListener( (*aObjIt).xTarget, (*aEvtIt).ListenerType,
     708           0 :                                                 (*aEvtIt).AddListenerParam, pArray[i] );
     709             :                     }
     710           0 :                     catch( Exception& )
     711             :                     {
     712             :                     }
     713             :                 }
     714           0 :                 i++;
     715           0 :                 ++aEvtIt;
     716             :             }
     717           0 :             aCurrentPosition->aObjList.erase( aObjIt );
     718           0 :             break;
     719             :         }
     720           0 :         ++aObjIt;
     721           0 :     }
     722           0 : }
     723             : 
     724           0 : void SAL_CALL ImplEventAttacherManager::addScriptListener(const Reference< XScriptListener >& aListener)
     725             :     throw( IllegalArgumentException, RuntimeException, std::exception )
     726             : {
     727           0 :     Guard< Mutex > aGuard( aLock );
     728           0 :     aScriptListeners.addInterface( aListener );
     729           0 : }
     730             : 
     731           0 : void SAL_CALL ImplEventAttacherManager::removeScriptListener(const Reference< XScriptListener >& aListener)
     732             :     throw( IllegalArgumentException, RuntimeException, std::exception )
     733             : {
     734           0 :     Guard< Mutex > aGuard( aLock );
     735           0 :     aScriptListeners.removeInterface( aListener );
     736           0 : }
     737             : 
     738             : 
     739             : // Methods of XPersistObject
     740           0 : OUString SAL_CALL ImplEventAttacherManager::getServiceName(void)
     741             :     throw( RuntimeException, std::exception )
     742             : {
     743           0 :     return OUString( "com.sun.star.uno.script.EventAttacherManager" );
     744             : }
     745             : 
     746           0 : void SAL_CALL ImplEventAttacherManager::write(const Reference< XObjectOutputStream >& OutStream)
     747             :     throw( IOException, RuntimeException, std::exception )
     748             : {
     749           0 :     Guard< Mutex > aGuard( aLock );
     750             :     // Don't run without XMarkableStream
     751           0 :     Reference< XMarkableStream > xMarkStream( OutStream, UNO_QUERY );
     752           0 :     if( !xMarkStream.is() )
     753           0 :         return;
     754             : 
     755             :     // Write out the version
     756           0 :     OutStream->writeShort( 2 );
     757             : 
     758             :     // Remember position for length
     759           0 :     sal_Int32 nObjLenMark = xMarkStream->createMark();
     760           0 :     OutStream->writeLong( 0L );
     761             : 
     762           0 :     OutStream->writeLong( aIndex.size() );
     763             : 
     764             :     // Write out sequences
     765           0 :     ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin();
     766           0 :     ::std::deque<AttacherIndex_Impl>::iterator aEnd = aIndex.end();
     767           0 :     while( aIt != aEnd )
     768             :     {
     769             :         // Write out the length of the sequence and all descriptions
     770           0 :         OutStream->writeLong( (*aIt).aEventList.size() );
     771           0 :         ::std::deque< ScriptEventDescriptor >::iterator aEvtIt =    (*aIt).aEventList.begin();
     772           0 :         ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = (*aIt).aEventList.end();
     773           0 :         while( aEvtIt != aEvtEnd )
     774             :         {
     775           0 :             const ScriptEventDescriptor& rDesc = (*aEvtIt);
     776           0 :             OutStream->writeUTF( rDesc.ListenerType );
     777           0 :             OutStream->writeUTF( rDesc.EventMethod );
     778           0 :             OutStream->writeUTF( rDesc.AddListenerParam );
     779           0 :             OutStream->writeUTF( rDesc.ScriptType );
     780           0 :             OutStream->writeUTF( rDesc.ScriptCode );
     781             : 
     782           0 :             ++aEvtIt;
     783             :         }
     784           0 :         ++aIt;
     785             :     }
     786             : 
     787             :     // The length is now known
     788           0 :     sal_Int32 nObjLen = xMarkStream->offsetToMark( nObjLenMark ) -4;
     789           0 :     xMarkStream->jumpToMark( nObjLenMark );
     790           0 :     OutStream->writeLong( nObjLen );
     791           0 :     xMarkStream->jumpToFurthest();
     792           0 :     xMarkStream->deleteMark( nObjLenMark );
     793             : }
     794             : 
     795           0 : void SAL_CALL ImplEventAttacherManager::read(const Reference< XObjectInputStream >& InStream)
     796             :     throw( IOException, RuntimeException, std::exception )
     797             : {
     798           0 :     Guard< Mutex > aGuard( aLock );
     799             :     // Don't run without XMarkableStream
     800           0 :     Reference< XMarkableStream > xMarkStream( InStream, UNO_QUERY );
     801           0 :     if( !xMarkStream.is() )
     802           0 :         return;
     803             : 
     804             :     // Read in the version
     805           0 :     nVersion = InStream->readShort();
     806             : 
     807             :     // At first there's the data according to version 1 --
     808             :     // this part needs to be kept in later versions.
     809           0 :     sal_Int32 nLen = InStream->readLong();
     810             : 
     811             :     // Position for comparative purposes
     812           0 :     sal_Int32 nObjLenMark = xMarkStream->createMark();
     813             : 
     814             :     // Number of read sequences
     815           0 :     sal_Int32 nItemCount = InStream->readLong();
     816             : 
     817           0 :     for( sal_Int32 i = 0 ; i < nItemCount ; i++ )
     818             :     {
     819           0 :         insertEntry( i );
     820             :         // Read the length of the sequence
     821           0 :         sal_Int32 nSeqLen = InStream->readLong();
     822             : 
     823             :         // Display the sequences and read the descriptions
     824           0 :         Sequence< ScriptEventDescriptor > aSEDSeq( nSeqLen );
     825           0 :         ScriptEventDescriptor* pArray = aSEDSeq.getArray();
     826           0 :         for( sal_Int32 j = 0 ; j < nSeqLen ; j++ )
     827             :         {
     828           0 :             ScriptEventDescriptor& rDesc = pArray[ j ];
     829           0 :             rDesc.ListenerType = InStream->readUTF();
     830           0 :             rDesc.EventMethod = InStream->readUTF();
     831           0 :             rDesc.AddListenerParam = InStream->readUTF();
     832           0 :             rDesc.ScriptType = InStream->readUTF();
     833           0 :             rDesc.ScriptCode = InStream->readUTF();
     834             :         }
     835           0 :         registerScriptEvents( i, aSEDSeq );
     836           0 :     }
     837             : 
     838             :     // Have we read the specified length?
     839           0 :     sal_Int32 nRealLen = xMarkStream->offsetToMark( nObjLenMark );
     840           0 :     if( nRealLen != nLen )
     841             :     {
     842             :         // Only if the StreamVersion is > 1 and the date still follows, can
     843             :         // this be true. Otherwise, something is completely gone.
     844           0 :         if( nRealLen > nLen || nVersion == 1 )
     845             :         {
     846             :             OSL_FAIL( "ImplEventAttacherManager::read(): Fatal Error, wrong object length" );
     847             :         }
     848             :         else
     849             :         {   // TODO: Examine if caching the dates would be useful
     850             :             // But for now, it's easier to skip it.
     851           0 :             sal_Int32 nSkipCount = nLen - nRealLen;
     852           0 :             InStream->skipBytes( nSkipCount );
     853             :         }
     854             :     }
     855           0 :     xMarkStream->jumpToFurthest();
     856           0 :     xMarkStream->deleteMark( nObjLenMark );
     857             : }
     858             : 
     859             : } // namesapce comphelper
     860             : 
     861             : 
     862             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10