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