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