24#include <osl/diagnose.h>
27#include <com/sun/star/beans/theIntrospection.hpp>
28#include <com/sun/star/io/XObjectInputStream.hpp>
29#include <com/sun/star/io/XPersistObject.hpp>
30#include <com/sun/star/io/XObjectOutputStream.hpp>
31#include <com/sun/star/io/XMarkableStream.hpp>
32#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
33#include <com/sun/star/lang/XInitialization.hpp>
34#include <com/sun/star/reflection/theCoreReflection.hpp>
35#include <com/sun/star/reflection/XIdlClass.hpp>
36#include <com/sun/star/reflection/XIdlReflection.hpp>
37#include <com/sun/star/reflection/XIdlMethod.hpp>
38#include <com/sun/star/script/CannotConvertException.hpp>
39#include <com/sun/star/script/Converter.hpp>
40#include <com/sun/star/script/XEventAttacher2.hpp>
41#include <com/sun/star/script/XEventAttacherManager.hpp>
42#include <com/sun/star/script/XScriptListener.hpp>
69struct AttachedObject_Impl
76struct AttacherIndex_Impl
83class ImplEventAttacherManager
84 :
public WeakImplHelper< XEventAttacherManager, XPersistObject >
86 friend class AttacherAllListener_Impl;
87 std::deque< AttacherIndex_Impl >
aIndex;
102 virtual void SAL_CALL registerScriptEvent(sal_Int32
Index,
const ScriptEventDescriptor& ScriptEvent)
override;
104 virtual void SAL_CALL revokeScriptEvent(sal_Int32
Index,
const OUString& ListenerType,
const OUString& EventMethod,
const OUString& removeListenerParam)
override;
105 virtual void SAL_CALL revokeScriptEvents(sal_Int32
Index)
override;
106 virtual void SAL_CALL insertEntry(sal_Int32
Index)
override;
107 virtual void SAL_CALL removeEntry(sal_Int32
Index)
override;
115 virtual OUString SAL_CALL getServiceName()
override;
120 void registerScriptEvent(std::unique_lock<std::mutex>&, sal_Int32
Index,
const ScriptEventDescriptor& ScriptEvent);
124 void insertEntry(std::unique_lock<std::mutex>&, sal_Int32
Index);
135 std::deque<AttacherIndex_Impl>::iterator implCheckIndex( sal_Int32 _nIndex );
141class AttacherAllListener_Impl :
public WeakImplHelper< XAllListener >
148 void convertToEventReturn( Any & rRet,
const Type & rRetType );
150 AttacherAllListener_Impl( ImplEventAttacherManager* pManager_, OUString aScriptType_,
151 OUString aScriptCode_ );
154 virtual void SAL_CALL firing(
const AllEventObject& Event)
override;
155 virtual Any SAL_CALL approveFiring(
const AllEventObject& Event)
override;
158 virtual void SAL_CALL disposing(
const EventObject& Source)
override;
163AttacherAllListener_Impl::AttacherAllListener_Impl
165 ImplEventAttacherManager* pManager_,
166 OUString aScriptType_,
167 OUString aScriptCode_
177void SAL_CALL AttacherAllListener_Impl::firing(
const AllEventObject& Event)
179 ScriptEvent aScriptEvent;
181 aScriptEvent.ListenerType = Event.ListenerType;
182 aScriptEvent.MethodName = Event.MethodName;
183 aScriptEvent.Arguments = Event.Arguments;
184 aScriptEvent.Helper = Event.Helper;
190 mxManager->aScriptListeners.notifyEach( l, &XScriptListener::firing, aScriptEvent );
195void AttacherAllListener_Impl::convertToEventReturn( Any & rRet,
const Type & rRetType )
198 if( rRet.getValueType().getTypeClass() == TypeClass_VOID )
200 switch( rRetType.getTypeClass() )
202 case TypeClass_INTERFACE:
204 rRet <<= Reference< XInterface >();
208 case TypeClass_BOOLEAN:
212 case TypeClass_STRING:
216 case TypeClass_FLOAT: rRet <<= float(0);
break;
217 case TypeClass_DOUBLE: rRet <<= 0.0;
break;
218 case TypeClass_BYTE: rRet <<=
sal_uInt8(0);
break;
219 case TypeClass_SHORT: rRet <<= sal_Int16( 0 );
break;
220 case TypeClass_LONG: rRet <<= sal_Int32( 0 );
break;
221 case TypeClass_UNSIGNED_SHORT: rRet <<= sal_uInt16( 0 );
break;
222 case TypeClass_UNSIGNED_LONG: rRet <<= sal_uInt32( 0 );
break;
229 else if( !rRet.getValueType().equals( rRetType ) )
232 throw CannotConvertException();
233 rRet =
mxManager->xConverter->convertTo( rRet, rRetType );
238Any SAL_CALL AttacherAllListener_Impl::approveFiring(
const AllEventObject& Event )
240 ScriptEvent aScriptEvent;
242 aScriptEvent.ListenerType = Event.ListenerType;
243 aScriptEvent.MethodName = Event.MethodName;
244 aScriptEvent.Arguments = Event.Arguments;
245 aScriptEvent.Helper = Event.Helper;
252 OInterfaceIteratorHelper4 aIt( l,
mxManager->aScriptListeners );
253 while( aIt.hasMoreElements() )
255 aRet = aIt.next()->approveFiring( aScriptEvent );
259 forName( Event.ListenerType.getTypeName() );
264 Type aRetType(xRetType->getTypeClass(), xRetType->getName());
265 convertToEventReturn( aRet, aRetType );
268 switch( aRet.getValueType().getTypeClass() )
270 case TypeClass_INTERFACE:
280 case TypeClass_BOOLEAN:
282 if( !(*o3tl::forceAccess<bool>(aRet)) )
286 case TypeClass_STRING:
288 if( !o3tl::forceAccess<OUString>(aRet)->isEmpty() )
293 case TypeClass_FLOAT:
if( *o3tl::forceAccess<float>(aRet) )
return aRet;
break;
294 case TypeClass_DOUBLE:
if( *o3tl::forceAccess<double>(aRet) )
return aRet;
break;
295 case TypeClass_BYTE:
if( *o3tl::forceAccess<sal_Int8>(aRet) )
return aRet;
break;
296 case TypeClass_SHORT:
if( *o3tl::forceAccess<sal_Int16>(aRet) )
return aRet;
break;
297 case TypeClass_LONG:
if( *o3tl::forceAccess<sal_Int32>(aRet) )
return aRet;
break;
298 case TypeClass_UNSIGNED_SHORT:
if( *o3tl::forceAccess<sal_uInt16>(aRet) )
return aRet;
break;
299 case TypeClass_UNSIGNED_LONG:
if( *o3tl::forceAccess<sal_uInt32>(aRet) )
return aRet;
break;
306 catch (
const CannotConvertException&)
310 forName( Event.ListenerType.getTypeName() );
315 Type aRetType(xRetType->getTypeClass(), xRetType->getName());
319 convertToEventReturn( aRet, aRetType );
321 catch (
const CannotConvertException& e)
324 throw css::lang::WrappedTargetRuntimeException(
325 "wrapped CannotConvertException " + e.Message,
326 css::uno::Reference<css::uno::XInterface>(), anyEx);
335void SAL_CALL AttacherAllListener_Impl::disposing(
const EventObject& )
356 "com.sun.star.script.EventAttacher", rContext) );
367 xInit->initialize({
Any(rIntrospection) });
382std::deque< AttacherIndex_Impl >::iterator ImplEventAttacherManager::implCheckIndex( sal_Int32 _nIndex )
385 throw IllegalArgumentException(
"wrong index",
static_cast<cppu::OWeakObject*
>(
this), 1);
387 std::deque<AttacherIndex_Impl>::iterator aIt =
aIndex.begin() + _nIndex;
392void SAL_CALL ImplEventAttacherManager::registerScriptEvent
395 const ScriptEventDescriptor& ScriptEvent
399 registerScriptEvent(l, nIndex, ScriptEvent);
402void ImplEventAttacherManager::registerScriptEvent
404 std::unique_lock<std::mutex>&,
406 const ScriptEventDescriptor& ScriptEvent
410 std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
412 ScriptEventDescriptor aEvt = ScriptEvent;
413 sal_Int32 nLastDot = aEvt.ListenerType.lastIndexOf(
'.');
415 aEvt.ListenerType = aEvt.ListenerType.copy(nLastDot+1);
416 aIt->aEventList.push_back( aEvt );
419 for(
auto& rObj : aIt->aObjList )
422 new AttacherAllListener_Impl(
this, ScriptEvent.ScriptType, ScriptEvent.ScriptCode );
425 rObj.aAttachedListenerSeq.push_back(
xAttacher->attachSingleEventListener( rObj.xTarget, xAll,
426 rObj.aHelper, ScriptEvent.ListenerType,
427 ScriptEvent.AddListenerParam, ScriptEvent.EventMethod ) );
436void SAL_CALL ImplEventAttacherManager::registerScriptEvents
443 registerScriptEvents(l, nIndex, ScriptEvents);
446void ImplEventAttacherManager::registerScriptEvents
448 std::unique_lock<std::mutex>& l,
454 std::deque< AttachedObject_Impl > aList = implCheckIndex( nIndex )->aObjList;
455 for(
const auto& rObj : aList )
456 detach( l, nIndex, rObj.xTarget );
458 const ScriptEventDescriptor* pArray = ScriptEvents.getConstArray();
459 sal_Int32 nLen = ScriptEvents.getLength();
460 for( sal_Int32 i = 0 ;
i < nLen ;
i++ )
461 registerScriptEvent( l, nIndex, pArray[ i ] );
463 for(
const auto& rObj : aList )
464 attach( l, nIndex, rObj.xTarget, rObj.aHelper );
468void SAL_CALL ImplEventAttacherManager::revokeScriptEvent
471 const OUString& ListenerType,
472 const OUString& EventMethod,
473 const OUString& ToRemoveListenerParam
478 std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
480 std::deque< AttachedObject_Impl > aList = aIt->aObjList;
481 for(
const auto& rObj : aList )
482 detach( l, nIndex, rObj.xTarget );
484 std::u16string_view aLstType = ListenerType;
485 size_t nLastDot = aLstType.rfind(
'.');
486 if (nLastDot != std::u16string_view::npos)
487 aLstType = aLstType.substr(nLastDot+1);
489 auto aEvtIt = std::find_if(aIt->aEventList.begin(), aIt->aEventList.end(),
490 [&aLstType, &EventMethod, &ToRemoveListenerParam](
const ScriptEventDescriptor& rEvent) {
491 return aLstType == rEvent.ListenerType
492 && EventMethod == rEvent.EventMethod
493 && ToRemoveListenerParam == rEvent.AddListenerParam;
495 if (aEvtIt != aIt->aEventList.end())
496 aIt->aEventList.erase( aEvtIt );
498 for(
const auto& rObj : aList )
499 attach( l, nIndex, rObj.xTarget, rObj.aHelper );
503void SAL_CALL ImplEventAttacherManager::revokeScriptEvents(sal_Int32 nIndex )
506 std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
508 std::deque< AttachedObject_Impl > aList = aIt->aObjList;
509 for(
const auto& rObj : aList )
510 detach( l, nIndex, rObj.xTarget );
511 aIt->aEventList.clear();
512 for(
const auto& rObj : aList )
513 attach( l, nIndex, rObj.xTarget, rObj.aHelper );
517void SAL_CALL ImplEventAttacherManager::insertEntry(sal_Int32 nIndex)
521 throw IllegalArgumentException(
"negative index",
static_cast<cppu::OWeakObject*
>(
this), 1);
523 insertEntry(l, nIndex);
526void ImplEventAttacherManager::insertEntry(std::unique_lock<std::mutex>&, sal_Int32 nIndex)
531 AttacherIndex_Impl aTmp;
535void SAL_CALL ImplEventAttacherManager::removeEntry(sal_Int32 nIndex)
538 std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
540 std::deque< AttachedObject_Impl > aList = aIt->aObjList;
541 for(
const auto& rObj : aList )
542 detach( l, nIndex, rObj.xTarget );
551 std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
556void SAL_CALL ImplEventAttacherManager::attach(sal_Int32 nIndex,
const Reference< XInterface >& xObject,
const Any & Helper)
559 if( nIndex < 0 || !xObject.is() )
560 throw IllegalArgumentException(
"negative index, or null object",
static_cast<cppu::OWeakObject*
>(
this), -1);
561 attach(l, nIndex, xObject, Helper);
564void ImplEventAttacherManager::attach(std::unique_lock<std::mutex>& l, sal_Int32 nIndex,
const Reference< XInterface >& xObject,
const Any & Helper)
570 throw IllegalArgumentException();
571 insertEntry( l, nIndex );
572 attach( l, nIndex, xObject, Helper );
576 std::deque< AttacherIndex_Impl >::iterator aCurrentPosition =
aIndex.begin() +
nIndex;
578 AttachedObject_Impl aTmp;
579 aTmp.xTarget = xObject;
580 aTmp.aHelper = Helper;
581 aCurrentPosition->aObjList.push_back( aTmp );
583 AttachedObject_Impl & rCurObj = aCurrentPosition->aObjList.back();
584 rCurObj.aAttachedListenerSeq = std::vector< Reference< XEventListener > >( aCurrentPosition->aEventList.size() );
586 if (aCurrentPosition->aEventList.empty())
590 css::script::EventListener*
p = aEvents.getArray();
592 for (
const auto& rEvent : aCurrentPosition->aEventList)
594 css::script::EventListener aListener;
595 aListener.AllListener =
596 new AttacherAllListener_Impl(
this, rEvent.ScriptType, rEvent.ScriptCode);
597 aListener.Helper = rCurObj.aHelper;
598 aListener.ListenerType = rEvent.ListenerType;
599 aListener.EventMethod = rEvent.EventMethod;
600 aListener.AddListenerParam = rEvent.AddListenerParam;
606 rCurObj.aAttachedListenerSeq = comphelper::sequenceToContainer<std::vector<Reference< XEventListener >>>(
607 xAttacher->attachMultipleEventListeners(rCurObj.xTarget, aEvents));
609 catch (
const Exception&)
621 throw IllegalArgumentException(
"bad index or null object",
static_cast<cppu::OWeakObject*
>(
this), 1);
622 detach(l, nIndex, xObject);
625void ImplEventAttacherManager::detach(std::unique_lock<std::mutex>&, sal_Int32 nIndex,
const Reference< XInterface >& xObject)
627 std::deque< AttacherIndex_Impl >::iterator aCurrentPosition =
aIndex.begin() +
nIndex;
628 auto aObjIt = std::find_if(aCurrentPosition->aObjList.begin(), aCurrentPosition->aObjList.end(),
629 [&xObject](
const AttachedObject_Impl& rObj) { return rObj.xTarget == xObject; });
630 if (aObjIt == aCurrentPosition->aObjList.end())
634 for(
const auto& rEvt : aCurrentPosition->aEventList )
636 if( aObjIt->aAttachedListenerSeq[i].is() )
640 xAttacher->removeListener( aObjIt->xTarget, rEvt.ListenerType,
641 rEvt.AddListenerParam, aObjIt->aAttachedListenerSeq[i] );
649 aCurrentPosition->aObjList.erase( aObjIt );
666OUString SAL_CALL ImplEventAttacherManager::getServiceName()
668 return "com.sun.star.uno.script.EventAttacherManager";
676 if( !xMarkStream.is() )
680 OutStream->writeShort( 2 );
683 sal_Int32 nObjLenMark = xMarkStream->createMark();
684 OutStream->writeLong( 0 );
686 OutStream->writeLong(
aIndex.size() );
689 for(
const auto& rIx :
aIndex )
691 OutStream->writeLong( rIx.aEventList.size() );
692 for(
const auto& rDesc : rIx.aEventList )
694 OutStream->writeUTF( rDesc.ListenerType );
695 OutStream->writeUTF( rDesc.EventMethod );
696 OutStream->writeUTF( rDesc.AddListenerParam );
697 OutStream->writeUTF( rDesc.ScriptType );
698 OutStream->writeUTF( rDesc.ScriptCode );
703 sal_Int32 nObjLen = xMarkStream->offsetToMark( nObjLenMark ) -4;
704 xMarkStream->jumpToMark( nObjLenMark );
705 OutStream->writeLong( nObjLen );
706 xMarkStream->jumpToFurthest();
707 xMarkStream->deleteMark( nObjLenMark );
715 if( !xMarkStream.is() )
723 sal_Int32 nLen = InStream->readLong();
726 sal_Int32 nObjLenMark = xMarkStream->createMark();
729 sal_Int32 nItemCount = InStream->readLong();
731 for( sal_Int32 i = 0 ;
i < nItemCount ;
i++ )
735 sal_Int32 nSeqLen = InStream->readLong();
739 ScriptEventDescriptor* pArray = aSEDSeq.getArray();
740 for( sal_Int32 j = 0 ; j < nSeqLen ; j++ )
742 ScriptEventDescriptor& rDesc = pArray[ j ];
743 rDesc.ListenerType = InStream->readUTF();
744 rDesc.EventMethod = InStream->readUTF();
745 rDesc.AddListenerParam = InStream->readUTF();
746 rDesc.ScriptType = InStream->readUTF();
747 rDesc.ScriptCode = InStream->readUTF();
749 registerScriptEvents( l, i, aSEDSeq );
753 sal_Int32 nRealLen = xMarkStream->offsetToMark( nObjLenMark );
754 if( nRealLen != nLen )
758 if( nRealLen > nLen ||
nVersion == 1 )
760 OSL_FAIL(
"ImplEventAttacherManager::read(): Fatal Error, wrong object length" );
765 sal_Int32 nSkipCount = nLen - nRealLen;
766 InStream->skipBytes( nSkipCount );
769 xMarkStream->jumpToFurthest();
770 xMarkStream->deleteMark( nObjLenMark );
rtl::Reference< ImplEventAttacherManager > mxManager
std::deque< AttachedObject_Impl > aObjList
OUString const aScriptCode
Reference< XComponentContext > mxContext
std::vector< Reference< XEventListener > > aAttachedListenerSeq
Reference< XEventAttacher2 > xAttacher
Reference< XInterface > xTarget
std::deque< AttacherIndex_Impl > aIndex
OUString const aScriptType
Reference< XIdlReflection > mxCoreReflection
Reference< XTypeConverter > xConverter
OInterfaceContainerHelper4< XScriptListener > aScriptListeners
std::deque< ScriptEventDescriptor > aEventList
Reference< XIntrospection > xIntrospection
Reference< XEventAttacherManager > createEventAttacherManager(const Reference< XComponentContext > &rxContext)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Copy from a container into a Sequence.
Any SAL_CALL getCaughtException()
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)