1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #include <osl/diagnose.h> 24 #include <com/sun/star/lang/XServiceInfo.hpp> 25 #include <com/sun/star/lang/XInitialization.hpp> 26 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 27 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 28 #include <com/sun/star/registry/XRegistryKey.hpp> 29 #include <com/sun/star/beans/XIntrospection.hpp> 30 #include <com/sun/star/beans/MethodConcept.hpp> 31 #include <com/sun/star/script/XEventAttacher.hpp> 32 #include <com/sun/star/script/XTypeConverter.hpp> 33 #include <com/sun/star/script/XAllListener.hpp> 34 #include <com/sun/star/script/XInvocationAdapterFactory.hpp> 35 #include <com/sun/star/reflection/XIdlReflection.hpp> 36 37 // InvocationToAllListenerMapper 38 #include <com/sun/star/script/XInvocation.hpp> 39 #include <cppuhelper/weak.hxx> 40 #include <cppuhelper/factory.hxx> 41 #include <cppuhelper/implbase1.hxx> 42 #include <cppuhelper/implbase3.hxx> 43 44 using namespace com::sun::star::uno; 45 using namespace com::sun::star::registry; 46 using namespace com::sun::star::lang; 47 using namespace com::sun::star::beans; 48 using namespace com::sun::star::script; 49 using namespace com::sun::star::reflection; 50 using namespace cppu; 51 using namespace osl; 52 using namespace rtl; 53 54 55 #define SERVICENAME "com.sun.star.script.EventAttacher" 56 #define IMPLNAME "com.sun.star.comp.EventAttacher" 57 58 namespace comp_EventAttacher { 59 60 //************************************************************************* 61 // class InvocationToAllListenerMapper 62 // helper class to map XInvocation to XAllListener 63 //************************************************************************* 64 class InvocationToAllListenerMapper : public WeakImplHelper1< XInvocation > 65 { 66 public: 67 InvocationToAllListenerMapper( const Reference< XIdlClass >& ListenerType, 68 const Reference< XAllListener >& AllListener, const Any& Helper ); 69 70 // XInvocation 71 virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection(void); 72 virtual Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam); 73 virtual void SAL_CALL setValue(const OUString& PropertyName, const Any& Value); 74 virtual Any SAL_CALL getValue(const OUString& PropertyName); 75 virtual sal_Bool SAL_CALL hasMethod(const OUString& Name); 76 virtual sal_Bool SAL_CALL hasProperty(const OUString& Name); 77 78 private: 79 Reference< XIdlReflection > m_xCoreReflection; 80 Reference< XAllListener > m_xAllListener; 81 Reference< XIdlClass > m_xListenerType; 82 Any m_Helper; 83 }; 84 85 86 // Function to replace AllListenerAdapterService::createAllListerAdapter 87 Reference< XInterface > createAllListenerAdapter 88 ( 89 const Reference< XInvocationAdapterFactory >& xInvocationAdapterFactory, 90 const Reference< XIdlClass >& xListenerType, 91 const Reference< XAllListener >& xListener, 92 const Any& Helper 93 ) 94 { 95 Reference< XInterface > xAdapter; 96 if( xInvocationAdapterFactory.is() && xListenerType.is() && xListener.is() ) 97 { 98 Reference< XInvocation > xInvocationToAllListenerMapper = 99 (XInvocation*)new InvocationToAllListenerMapper( xListenerType, xListener, Helper ); 100 Type aListenerType( xListenerType->getTypeClass(), xListenerType->getName()); 101 xAdapter = xInvocationAdapterFactory->createAdapter( xInvocationToAllListenerMapper, aListenerType ); 102 } 103 return xAdapter; 104 } 105 106 107 //-------------------------------------------------------------------------------------------------- 108 // InvocationToAllListenerMapper 109 InvocationToAllListenerMapper::InvocationToAllListenerMapper 110 ( const Reference< XIdlClass >& ListenerType, const Reference< XAllListener >& AllListener, const Any& Helper ) 111 : m_xAllListener( AllListener ) 112 , m_xListenerType( ListenerType ) 113 , m_Helper( Helper ) 114 { 115 } 116 117 //************************************************************************* 118 Reference< XIntrospectionAccess > SAL_CALL InvocationToAllListenerMapper::getIntrospection(void) 119 { 120 return Reference< XIntrospectionAccess >(); 121 } 122 123 //************************************************************************* 124 Any SAL_CALL InvocationToAllListenerMapper::invoke(const OUString& FunctionName, const Sequence< Any >& Params, 125 Sequence< sal_Int16 >& , Sequence< Any >& ) 126 { 127 Any aRet; 128 129 // Check if to firing or approveFiring has to be called 130 Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( FunctionName ); 131 sal_Bool bApproveFiring = sal_False; 132 if( !xMethod.is() ) 133 return aRet; 134 Reference< XIdlClass > xReturnType = xMethod->getReturnType(); 135 Sequence< Reference< XIdlClass > > aExceptionSeq = xMethod->getExceptionTypes(); 136 if( ( xReturnType.is() && xReturnType->getTypeClass() != TypeClass_VOID ) || 137 aExceptionSeq.getLength() > 0 ) 138 { 139 bApproveFiring = sal_True; 140 } 141 else 142 { 143 Sequence< ParamInfo > aParamSeq = xMethod->getParameterInfos(); 144 sal_uInt32 nParamCount = aParamSeq.getLength(); 145 if( nParamCount > 1 ) 146 { 147 const ParamInfo* pInfos = aParamSeq.getConstArray(); 148 for( sal_uInt32 i = 0 ; i < nParamCount ; i++ ) 149 { 150 if( pInfos[ i ].aMode != ParamMode_IN ) 151 { 152 bApproveFiring = sal_True; 153 break; 154 } 155 } 156 } 157 } 158 159 AllEventObject aAllEvent; 160 aAllEvent.Source = (OWeakObject*) this; 161 aAllEvent.Helper = m_Helper; 162 aAllEvent.ListenerType = Type(m_xListenerType->getTypeClass(), m_xListenerType->getName()); 163 aAllEvent.MethodName = FunctionName; 164 aAllEvent.Arguments = Params; 165 if( bApproveFiring ) 166 aRet = m_xAllListener->approveFiring( aAllEvent ); 167 else 168 m_xAllListener->firing( aAllEvent ); 169 return aRet; 170 } 171 172 //************************************************************************* 173 void SAL_CALL InvocationToAllListenerMapper::setValue(const OUString& , const Any& ) 174 { 175 } 176 177 //************************************************************************* 178 Any SAL_CALL InvocationToAllListenerMapper::getValue(const OUString& ) 179 { 180 return Any(); 181 } 182 183 //************************************************************************* 184 sal_Bool SAL_CALL InvocationToAllListenerMapper::hasMethod(const OUString& Name) 185 { 186 Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( Name ); 187 return xMethod.is(); 188 } 189 190 //************************************************************************* 191 sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const OUString& Name) 192 { 193 Reference< XIdlField > xField = m_xListenerType->getField( Name ); 194 return xField.is(); 195 } 196 197 //************************************************************************* 198 // class EventAttacherImpl 199 // represents an implementation of the EventAttacher service 200 //************************************************************************* 201 class EventAttacherImpl : public WeakImplHelper3 < XEventAttacher, XInitialization, XServiceInfo > 202 { 203 public: 204 EventAttacherImpl( const Reference< XMultiServiceFactory >& ); 205 ~EventAttacherImpl(); 206 207 // XServiceInfo 208 virtual OUString SAL_CALL getImplementationName( ); 209 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ); 210 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ); 211 static OUString SAL_CALL getImplementationName_Static( ); 212 static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( ); 213 214 // XInitialization 215 virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ); 216 217 // Methoden von XEventAttacher 218 virtual Reference< XEventListener > SAL_CALL attachListener(const Reference< XInterface >& xObject, 219 const Reference< XAllListener >& AllListener, const Any& Helper, 220 const OUString& ListenerType, const OUString& AddListenerParam); 221 virtual Reference< XEventListener > SAL_CALL attachSingleEventListener(const Reference< XInterface >& xObject, 222 const Reference< XAllListener >& AllListener, const Any& Helper, 223 const OUString& ListenerType, const OUString& AddListenerParam, 224 const OUString& EventMethod); 225 virtual void SAL_CALL removeListener(const Reference< XInterface >& xObject, 226 const OUString& ListenerType, const OUString& AddListenerParam, 227 const Reference< XEventListener >& aToRemoveListener); 228 229 // used by FilterAllListener_Impl 230 Reference< XTypeConverter > getConverter(); 231 232 friend class FilterAllListenerImpl; 233 private: 234 Mutex m_aMutex; 235 Reference< XMultiServiceFactory > m_xSMgr; 236 237 // Services merken 238 Reference< XIntrospection > m_xIntrospection; 239 Reference< XIdlReflection > m_xReflection; 240 Reference< XTypeConverter > m_xConverter; 241 Reference< XInvocationAdapterFactory > m_xInvocationAdapterFactory; 242 243 // needed services 244 Reference< XIntrospection > getIntrospection(); 245 Reference< XIdlReflection > getReflection(); 246 Reference< XInvocationAdapterFactory > getInvocationAdapterService(); 247 }; 248 249 250 //************************************************************************* 251 EventAttacherImpl::EventAttacherImpl( const Reference< XMultiServiceFactory >& rSMgr ) 252 : m_xSMgr( rSMgr ) 253 { 254 } 255 256 //************************************************************************* 257 EventAttacherImpl::~EventAttacherImpl() 258 { 259 } 260 261 //************************************************************************* 262 Reference< XInterface > SAL_CALL EventAttacherImpl_CreateInstance( const Reference< XMultiServiceFactory >& rSMgr ) 263 { 264 Reference< XInterface > xRet; 265 XEventAttacher *pEventAttacher = (XEventAttacher*) new EventAttacherImpl(rSMgr); 266 267 if (pEventAttacher) 268 { 269 xRet = Reference<XInterface>::query(pEventAttacher); 270 } 271 272 return xRet; 273 } 274 275 //************************************************************************* 276 OUString SAL_CALL EventAttacherImpl::getImplementationName( ) 277 { 278 return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) ); 279 } 280 281 //************************************************************************* 282 sal_Bool SAL_CALL EventAttacherImpl::supportsService( const OUString& ServiceName ) 283 { 284 Sequence< OUString > aSNL = getSupportedServiceNames(); 285 const OUString * pArray = aSNL.getArray(); 286 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 287 if( pArray[i] == ServiceName ) 288 return sal_True; 289 return sal_False; 290 } 291 292 //************************************************************************* 293 Sequence<OUString> SAL_CALL EventAttacherImpl::getSupportedServiceNames( ) 294 { 295 return getSupportedServiceNames_Static(); 296 } 297 298 //************************************************************************* 299 Sequence<OUString> SAL_CALL EventAttacherImpl::getSupportedServiceNames_Static( ) 300 { 301 OUString aStr( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME ) ); 302 return Sequence< OUString >( &aStr, 1 ); 303 } 304 305 //************************************************************************* 306 void SAL_CALL EventAttacherImpl::initialize(const Sequence< Any >& Arguments) 307 { 308 // get services from the argument list 309 const Any * pArray = Arguments.getConstArray(); 310 for( sal_Int32 i = 0; i < Arguments.getLength(); i++ ) 311 { 312 if( pArray[i].getValueType().getTypeClass() != TypeClass_INTERFACE ) 313 throw IllegalArgumentException(); 314 315 // InvocationAdapter service ? 316 Reference< XInvocationAdapterFactory > xALAS; 317 pArray[i] >>= xALAS; 318 if( xALAS.is() ) 319 { 320 Guard< Mutex > aGuard( m_aMutex ); 321 m_xInvocationAdapterFactory = xALAS; 322 } 323 // Introspection service ? 324 Reference< XIntrospection > xI; 325 pArray[i] >>= xI; 326 if( xI.is() ) 327 { 328 Guard< Mutex > aGuard( m_aMutex ); 329 m_xIntrospection = xI; 330 } 331 // Reflection service ? 332 Reference< XIdlReflection > xIdlR; 333 pArray[i] >>= xIdlR; 334 if( xIdlR.is() ) 335 { 336 Guard< Mutex > aGuard( m_aMutex ); 337 m_xReflection = xIdlR; 338 } 339 // Converter Service ? 340 Reference< XTypeConverter > xC; 341 pArray[i] >>= xC; 342 if( xC.is() ) 343 { 344 Guard< Mutex > aGuard( m_aMutex ); 345 m_xConverter = xC; 346 } 347 348 // no right interface 349 if( !xALAS.is() && !xI.is() && !xIdlR.is() && !xC.is() ) 350 throw IllegalArgumentException(); 351 } 352 } 353 354 //************************************************************************* 355 //*** Private Hilfs-Methoden *** 356 Reference< XIntrospection > EventAttacherImpl::getIntrospection() 357 { 358 Guard< Mutex > aGuard( m_aMutex ); 359 // Haben wir den Service schon? Sonst anlegen 360 if( !m_xIntrospection.is() ) 361 { 362 Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection") ) ); 363 m_xIntrospection = Reference< XIntrospection >( xIFace, UNO_QUERY ); 364 } 365 return m_xIntrospection; 366 } 367 368 //************************************************************************* 369 //*** Private Hilfs-Methoden *** 370 Reference< XIdlReflection > EventAttacherImpl::getReflection() 371 { 372 Guard< Mutex > aGuard( m_aMutex ); 373 // Haben wir den Service schon? Sonst anlegen 374 if( !m_xReflection.is() ) 375 { 376 Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ) ); 377 m_xReflection = Reference< XIdlReflection >( xIFace, UNO_QUERY); 378 } 379 return m_xReflection; 380 } 381 382 //************************************************************************* 383 //*** Private Hilfs-Methoden *** 384 Reference< XInvocationAdapterFactory > EventAttacherImpl::getInvocationAdapterService() 385 { 386 Guard< Mutex > aGuard( m_aMutex ); 387 // Haben wir den Service schon? Sonst anlegen 388 if( !m_xInvocationAdapterFactory.is() ) 389 { 390 Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.script.InvocationAdapterFactory") ) ); 391 m_xInvocationAdapterFactory = Reference< XInvocationAdapterFactory >( xIFace, UNO_QUERY ); 392 } 393 return m_xInvocationAdapterFactory; 394 } 395 396 397 //************************************************************************* 398 //*** Private Hilfs-Methoden *** 399 Reference< XTypeConverter > EventAttacherImpl::getConverter() 400 { 401 Guard< Mutex > aGuard( m_aMutex ); 402 // Haben wir den Service schon? Sonst anlegen 403 if( !m_xConverter.is() ) 404 { 405 Reference< XInterface > xIFace( m_xSMgr->createInstance( rtl::OUString::createFromAscii("com.sun.star.script.Converter") ) ); 406 m_xConverter = Reference< XTypeConverter >( xIFace, UNO_QUERY ); 407 } 408 return m_xConverter; 409 } 410 411 //------------------------------------------------------------------------ 412 //------------------------------------------------------------------------ 413 //------------------------------------------------------------------------ 414 // Implementation eines EventAttacher-bezogenen AllListeners, der 415 // nur einzelne Events an einen allgemeinen AllListener weiterleitet 416 class FilterAllListenerImpl : public WeakImplHelper1< XAllListener > 417 { 418 public: 419 FilterAllListenerImpl( EventAttacherImpl * pEA_, const OUString& EventMethod_, 420 const Reference< XAllListener >& AllListener_ ); 421 422 // XAllListener 423 virtual void SAL_CALL firing(const AllEventObject& Event); 424 virtual Any SAL_CALL approveFiring(const AllEventObject& Event); 425 426 // XEventListener 427 virtual void SAL_CALL disposing(const EventObject& Source); 428 429 private: 430 // convert 431 void convertToEventReturn( Any & rRet, const Type& rRetType ); 432 433 EventAttacherImpl * m_pEA; 434 Reference< XInterface > m_xEAHold; 435 OUString m_EventMethod; 436 Reference< XAllListener > m_AllListener; 437 }; 438 439 //************************************************************************* 440 FilterAllListenerImpl::FilterAllListenerImpl( EventAttacherImpl * pEA_, const OUString& EventMethod_, 441 const Reference< XAllListener >& AllListener_ ) 442 : m_pEA( pEA_ ) 443 , m_xEAHold( *pEA_ ) 444 , m_EventMethod( EventMethod_ ) 445 , m_AllListener( AllListener_ ) 446 { 447 } 448 449 //************************************************************************* 450 void SAL_CALL FilterAllListenerImpl::firing(const AllEventObject& Event) 451 { 452 // Nur durchreichen, wenn es die richtige Methode ist 453 if( Event.MethodName == m_EventMethod && m_AllListener.is() ) 454 m_AllListener->firing( Event ); 455 } 456 457 //************************************************************************* 458 // Convert to the standard event return 459 void FilterAllListenerImpl::convertToEventReturn( Any & rRet, const Type & rRetType ) 460 { 461 // no return value? Set to the specified values 462 if( rRet.getValueType().getTypeClass() == TypeClass_VOID ) 463 { 464 switch( rRetType.getTypeClass() ) 465 { 466 case TypeClass_INTERFACE: 467 { 468 rRet <<= Reference< XInterface >(); 469 } 470 break; 471 472 case TypeClass_BOOLEAN: 473 rRet <<= sal_True; 474 break; 475 476 case TypeClass_STRING: 477 rRet <<= OUString(); 478 break; 479 480 case TypeClass_FLOAT: rRet <<= float(0); break; 481 case TypeClass_DOUBLE: rRet <<= double(0.0); break; 482 case TypeClass_BYTE: rRet <<= sal_uInt8( 0 ); break; 483 case TypeClass_SHORT: rRet <<= sal_Int16( 0 ); break; 484 case TypeClass_LONG: rRet <<= sal_Int32( 0 ); break; 485 case TypeClass_UNSIGNED_SHORT: rRet <<= sal_uInt16( 0 ); break; 486 case TypeClass_UNSIGNED_LONG: rRet <<= sal_uInt32( 0 ); break; 487 default: 488 break; 489 } 490 } 491 else if( !rRet.getValueType().equals( rRetType ) ) 492 { 493 Reference< XTypeConverter > xConverter = m_pEA->getConverter(); 494 if( xConverter.is() ) 495 rRet = xConverter->convertTo( rRet, rRetType ); 496 else 497 throw CannotConvertException(); // TODO TypeConversionException 498 } 499 } 500 501 //************************************************************************* 502 Any SAL_CALL FilterAllListenerImpl::approveFiring( const AllEventObject& Event ) 503 { 504 Any aRet; 505 506 // Nur durchreichen, wenn es die richtige Methode ist 507 if( Event.MethodName == m_EventMethod && m_AllListener.is() ) 508 aRet = m_AllListener->approveFiring( Event ); 509 else 510 { 511 // Convert to the standard event return 512 try 513 { 514 Reference< XIdlClass > xListenerType = m_pEA->getReflection()-> 515 forName( Event.ListenerType.getTypeName() ); 516 Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName ); 517 if( xMeth.is() ) 518 { 519 Reference< XIdlClass > xRetType = xMeth->getReturnType(); 520 Type aRetType( xRetType->getTypeClass(), xRetType->getName() ); 521 convertToEventReturn( aRet, aRetType ); 522 } 523 } 524 catch( CannotConvertException& e ) 525 { 526 throw InvocationTargetException( OUString(), Reference< XInterface >(), Any(&e, ::getCppuType( (CannotConvertException*)0)) ); 527 } 528 } 529 return aRet; 530 } 531 532 //************************************************************************* 533 void FilterAllListenerImpl::disposing(const EventObject& ) 534 { 535 // TODO: ??? 536 } 537 538 539 //************************************************************************* 540 Reference< XEventListener > EventAttacherImpl::attachListener 541 ( 542 const Reference< XInterface >& xObject, 543 const Reference< XAllListener >& AllListener, 544 const Any& Helper, 545 const OUString& ListenerType, 546 const OUString& AddListenerParam 547 ) 548 { 549 if( !xObject.is() || !AllListener.is() ) 550 throw IllegalArgumentException(); 551 552 Reference< XEventListener > xRet = NULL; 553 554 // InvocationAdapterService holen 555 Reference< XInvocationAdapterFactory > xInvocationAdapterFactory = getInvocationAdapterService(); 556 if( !xInvocationAdapterFactory.is() ) 557 throw ServiceNotRegisteredException(); 558 559 // Listener-Klasse per Reflection besorgen 560 Reference< XIdlReflection > xReflection = getReflection(); 561 if( !xReflection.is() ) 562 throw ServiceNotRegisteredException(); 563 564 // Anmelden, dazu passende addListener-Methode aufrufen 565 // Zunaechst ueber Introspection gehen, da die Methoden in der gleichen 566 // Weise analysiert werden koennen. Fuer bessere Performance entweder 567 // hier nochmal implementieren oder die Impl-Methode der Introspection 568 // fuer diesen Zweck konfigurierbar machen. 569 570 // Introspection-Service holen 571 Reference< XIntrospection > xIntrospection = getIntrospection(); 572 if( !xIntrospection.is() ) 573 return xRet; 574 575 // und unspecten 576 Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) ); 577 578 Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny ); 579 if( !xAccess.is() ) 580 return xRet; 581 582 // Name der addListener-Methode zusammenbasteln 583 OUString aAddListenerName; 584 OUString aListenerName( ListenerType ); 585 sal_Int32 nIndex = aListenerName.lastIndexOf( '.' ); 586 // set index to the interface name without package name 587 if( nIndex == -1 ) 588 // not found 589 nIndex = 0; 590 else 591 nIndex++; 592 if( aListenerName[nIndex] == 'X' ) 593 // erase X from the interface name 594 aListenerName = aListenerName.copy( nIndex +1 ); 595 aAddListenerName = OUString( RTL_CONSTASCII_USTRINGPARAM( "add" ) ) + aListenerName; 596 597 // Methoden nach der passenden addListener-Methode durchsuchen 598 Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER ); 599 sal_uInt32 i, nLen = aMethodSeq.getLength(); 600 const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray(); 601 602 for( i = 0 ; i < nLen ; i++ ) 603 { 604 // Methode ansprechen 605 const Reference< XIdlMethod >& rxMethod = pMethods[i]; 606 607 // Ist es die richtige Methode? 608 OUString aMethName = rxMethod->getName(); 609 610 if( aAddListenerName == aMethName ) 611 { 612 Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes(); 613 sal_uInt32 nParamCount = params.getLength(); 614 615 Reference< XIdlClass > xListenerType; 616 if( nParamCount == 1 ) 617 xListenerType = params.getConstArray()[0]; 618 else if( nParamCount == 2 ) 619 xListenerType = params.getConstArray()[1]; 620 621 // Adapter zum eigentlichen Listener-Typ anfordern 622 Reference< XInterface > xAdapter = createAllListenerAdapter 623 ( xInvocationAdapterFactory, xListenerType, AllListener, Helper ); 624 625 if( !xAdapter.is() ) 626 throw CannotCreateAdapterException(); 627 xRet = Reference< XEventListener >( xAdapter, UNO_QUERY ); 628 629 630 // Nur der Listener als Parameter? 631 if( nParamCount == 1 ) 632 { 633 Sequence< Any > args( 1 ); 634 args.getArray()[0] <<= xAdapter; 635 try 636 { 637 rxMethod->invoke( aObjAny, args ); 638 } 639 catch( InvocationTargetException& ) 640 { 641 throw IntrospectionException(); 642 } 643 } 644 // Sonst den Zusatzparameter mit uebergeben 645 else if( nParamCount == 2 ) 646 { 647 Sequence< Any > args( 2 ); 648 Any* pAnys = args.getArray(); 649 650 // Typ des 1. Parameters pruefen 651 Reference< XIdlClass > xParamClass = params.getConstArray()[0]; 652 if( xParamClass->getTypeClass() == TypeClass_STRING ) 653 { 654 pAnys[0] <<= AddListenerParam; 655 } 656 657 // 2. Parameter == Listener? TODO: Pruefen! 658 pAnys[1] <<= xAdapter; 659 660 // TODO: Konvertierung String -> ? 661 // else 662 try 663 { 664 rxMethod->invoke( aObjAny, args ); 665 } 666 catch( InvocationTargetException& ) 667 { 668 throw IntrospectionException(); 669 } 670 } 671 break; 672 // else... 673 // Alles andere wird nicht unterstuetzt 674 } 675 } 676 677 return xRet; 678 } 679 680 // XEventAttacher 681 Reference< XEventListener > EventAttacherImpl::attachSingleEventListener 682 ( 683 const Reference< XInterface >& xObject, 684 const Reference< XAllListener >& AllListener, 685 const Any& Helper, 686 const OUString& ListenerType, 687 const OUString& AddListenerParam, 688 const OUString& EventMethod 689 ) 690 { 691 // FilterListener anmelden 692 Reference< XAllListener > aFilterListener = (XAllListener*) 693 new FilterAllListenerImpl( this, EventMethod, AllListener ); 694 return attachListener( xObject, aFilterListener, Helper, ListenerType, AddListenerParam); 695 } 696 697 // XEventAttacher 698 void EventAttacherImpl::removeListener 699 ( 700 const Reference< XInterface >& xObject, 701 const OUString& ListenerType, 702 const OUString& AddListenerParam, 703 const Reference< XEventListener >& aToRemoveListener 704 ) 705 { 706 if( !xObject.is() || !aToRemoveListener.is() ) 707 throw IllegalArgumentException(); 708 709 // Listener-Klasse per Reflection besorgen 710 Reference< XIdlReflection > xReflection = getReflection(); 711 if( !xReflection.is() ) 712 throw IntrospectionException(); 713 714 // Abmelden, dazu passende removeListener-Methode aufrufen 715 // Zunaechst ueber Introspection gehen, da die Methoden in der gleichen 716 // Weise analysiert werden koennen. Fuer bessere Performance entweder 717 // hier nochmal implementieren oder die Impl-Methode der Introspection 718 // fuer diesen Zweck konfigurierbar machen. 719 720 // Introspection-Service holen 721 Reference< XIntrospection > xIntrospection = getIntrospection(); 722 if( !xIntrospection.is() ) 723 throw IntrospectionException(); 724 725 // und inspecten 726 Any aObjAny( &xObject, ::getCppuType( (const Reference< XInterface > *)0) ); 727 Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny ); 728 if( !xAccess.is() ) 729 throw IntrospectionException(); 730 731 // Name der removeListener-Methode zusammenbasteln 732 OUString aRemoveListenerName; 733 OUString aListenerName( ListenerType ); 734 sal_Int32 nIndex = aListenerName.lastIndexOf( '.' ); 735 // set index to the interface name without package name 736 if( nIndex == -1 ) 737 // not found 738 nIndex = 0; 739 else 740 nIndex++; 741 if( aListenerName[nIndex] == 'X' ) 742 // erase X from the interface name 743 aListenerName = aListenerName.copy( nIndex +1 ); 744 aRemoveListenerName = OUString( RTL_CONSTASCII_USTRINGPARAM("remove") ) + aListenerName; 745 746 // Methoden nach der passenden addListener-Methode durchsuchen 747 Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER ); 748 sal_uInt32 i, nLen = aMethodSeq.getLength(); 749 const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray(); 750 for( i = 0 ; i < nLen ; i++ ) 751 { 752 // Methode ansprechen 753 const Reference< XIdlMethod >& rxMethod = pMethods[i]; 754 755 // Ist es die richtige Methode? 756 if( aRemoveListenerName == rxMethod->getName() ) 757 { 758 Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes(); 759 sal_uInt32 nParamCount = params.getLength(); 760 761 // Nur der Listener als Parameter? 762 if( nParamCount == 1 ) 763 { 764 Sequence< Any > args( 1 ); 765 args.getArray()[0] <<= aToRemoveListener; 766 try 767 { 768 rxMethod->invoke( aObjAny, args ); 769 } 770 catch( InvocationTargetException& ) 771 { 772 throw IntrospectionException(); 773 } 774 } 775 // Sonst den Zusatzparameter mit uebergeben 776 else if( nParamCount == 2 ) 777 { 778 Sequence< Any > args( 2 ); 779 Any* pAnys = args.getArray(); 780 781 // Typ des 1. Parameters pruefen 782 Reference< XIdlClass > xParamClass = params.getConstArray()[0]; 783 if( xParamClass->getTypeClass() == TypeClass_STRING ) 784 pAnys[0] <<= AddListenerParam; 785 786 // 2. Parameter == Listener? TODO: Pruefen! 787 pAnys[1] <<= aToRemoveListener; 788 789 // TODO: Konvertierung String -> ? 790 // else 791 try 792 { 793 rxMethod->invoke( aObjAny, args ); 794 } 795 catch( InvocationTargetException& ) 796 { 797 throw IntrospectionException(); 798 } 799 } 800 break; 801 } 802 } 803 } 804 805 } 806 807 extern "C" 808 { 809 //================================================================================================== 810 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( 811 const sal_Char ** ppEnvTypeName, uno_Environment ** ) 812 { 813 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 814 } 815 //================================================================================================== 816 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( 817 const sal_Char * pImplName, void * pServiceManager, void * ) 818 { 819 void * pRet = 0; 820 821 if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0) 822 { 823 Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( 824 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), 825 OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) ), 826 ::comp_EventAttacher::EventAttacherImpl_CreateInstance, 827 ::comp_EventAttacher::EventAttacherImpl::getSupportedServiceNames_Static() ) ); 828 829 if (xFactory.is()) 830 { 831 xFactory->acquire(); 832 pRet = xFactory.get(); 833 } 834 } 835 836 return pRet; 837 } 838 } 839