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 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_stoc.hxx" 30 31 #include <string.h> 32 33 // Schalter fuer Introspection-Caching 34 #ifndef OS2 35 #define USE_INTROSPECTION_CACHE 36 #endif 37 38 #ifdef USE_INTROSPECTION_CACHE 39 #define INTROSPECTION_CACHE_MAX_SIZE 100 40 #endif 41 #include <osl/diagnose.h> 42 #include <osl/mutex.hxx> 43 #include <osl/thread.h> 44 #include <cppuhelper/queryinterface.hxx> 45 #include <cppuhelper/weak.hxx> 46 #include <cppuhelper/component.hxx> 47 #include <cppuhelper/factory.hxx> 48 #include <cppuhelper/implbase3.hxx> 49 #include <cppuhelper/typeprovider.hxx> 50 51 #include <com/sun/star/uno/DeploymentException.hpp> 52 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 53 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 54 #include <com/sun/star/lang/XServiceInfo.hpp> 55 #include <com/sun/star/lang/XEventListener.hpp> 56 #include <com/sun/star/reflection/XIdlReflection.hpp> 57 #include <com/sun/star/reflection/XIdlClassProvider.hpp> 58 #include <com/sun/star/reflection/XIdlClass.hpp> 59 #include <com/sun/star/reflection/XIdlField2.hpp> 60 #include <com/sun/star/beans/UnknownPropertyException.hpp> 61 #include <com/sun/star/beans/Property.hpp> 62 #include <com/sun/star/beans/XPropertySet.hpp> 63 #include <com/sun/star/beans/XFastPropertySet.hpp> 64 #include <com/sun/star/beans/XIntrospection.hpp> 65 #include <com/sun/star/beans/XIntrospectionAccess.hpp> 66 #include <com/sun/star/beans/XMaterialHolder.hpp> 67 #include <com/sun/star/beans/XExactName.hpp> 68 #include <com/sun/star/beans/PropertyAttribute.hpp> 69 #include <com/sun/star/beans/PropertyConcept.hpp> 70 #include <com/sun/star/beans/MethodConcept.hpp> 71 #include <com/sun/star/container/XNameContainer.hpp> 72 #include <com/sun/star/container/XIndexContainer.hpp> 73 #include <com/sun/star/container/XEnumerationAccess.hpp> 74 75 #include <rtl/ustrbuf.hxx> 76 #include <rtl/ref.hxx> 77 #include <rtl/strbuf.hxx> 78 #include <hash_map> 79 80 using namespace com::sun::star::uno; 81 using namespace com::sun::star::lang; 82 using namespace com::sun::star::reflection; 83 using namespace com::sun::star::container; 84 using namespace com::sun::star::registry; 85 using namespace com::sun::star::beans; 86 using namespace com::sun::star::beans::PropertyAttribute; 87 using namespace com::sun::star::beans::PropertyConcept; 88 using namespace com::sun::star::beans::MethodConcept; 89 using namespace cppu; 90 using namespace osl; 91 92 #define IMPLEMENTATION_NAME "com.sun.star.comp.stoc.Introspection" 93 #define SERVICE_NAME "com.sun.star.beans.Introspection" 94 95 namespace stoc_inspect 96 { 97 98 typedef WeakImplHelper3< XIntrospectionAccess, XMaterialHolder, XExactName > IntrospectionAccessHelper; 99 100 101 //================================================================================================== 102 103 // Spezial-Wert fuer Method-Concept, um "normale" Funktionen kennzeichnen zu koennen 104 #define MethodConcept_NORMAL_IMPL 0x80000000 105 106 107 // Methode zur Feststellung, ob eine Klasse von einer anderen abgeleitet ist 108 sal_Bool isDerivedFrom( Reference<XIdlClass> xToTestClass, Reference<XIdlClass> xDerivedFromClass ) 109 { 110 Sequence< Reference<XIdlClass> > aClassesSeq = xToTestClass->getSuperclasses(); 111 const Reference<XIdlClass>* pClassesArray = aClassesSeq.getConstArray(); 112 sal_Int32 nSuperClassCount = aClassesSeq.getLength(); 113 sal_Int32 i; 114 for( i = 0 ; i < nSuperClassCount ; i++ ) 115 { 116 const Reference<XIdlClass>& rxClass = pClassesArray[i]; 117 if( xDerivedFromClass->equals( rxClass ) ) 118 { 119 // Treffer 120 return sal_True; 121 } 122 else 123 { 124 // Rekursiv weitersuchen 125 return isDerivedFrom( rxClass, xDerivedFromClass ); 126 } 127 } 128 return sal_False; 129 } 130 131 //======================================================================== 132 133 // *** Klassifizierung der Properties (kein enum, um Sequence verwenden zu koennen) *** 134 // Properties aus einem PropertySet-Interface 135 #define MAP_PROPERTY_SET 0 136 // Properties aus Fields 137 #define MAP_FIELD 1 138 // Properties, die durch get/set-Methoden beschrieben werden 139 #define MAP_GETSET 2 140 // Properties, die nur eine set-Methode haben 141 #define MAP_SETONLY 3 142 143 144 // Schrittweite, in der die Groesse der Sequences angepasst wird 145 #define ARRAY_SIZE_STEP 20 146 147 148 149 //************************************** 150 //*** IntrospectionAccessStatic_Impl *** 151 //************************************** 152 // Entspricht dem alten IntrospectionAccessImpl, bildet jetzt den statischen 153 // Anteil des neuen Instanz-bezogenen ImplIntrospectionAccess 154 155 // ACHTUNG !!! Von Hand refcounten !!! 156 157 158 // Hashtable fuer die Suche nach Namen 159 struct hashName_Impl 160 { 161 size_t operator()(const ::rtl::OUString Str) const 162 { 163 return (size_t)Str.hashCode(); 164 } 165 }; 166 167 struct eqName_Impl 168 { 169 sal_Bool operator()(const ::rtl::OUString Str1, const ::rtl::OUString Str2) const 170 { 171 return ( Str1 == Str2 ); 172 } 173 }; 174 175 typedef std::hash_map 176 < 177 ::rtl::OUString, 178 sal_Int32, 179 hashName_Impl, 180 eqName_Impl 181 > 182 IntrospectionNameMap; 183 184 185 // Hashtable zur Zuordnung der exakten Namen zu den zu Lower-Case 186 // konvertierten Namen, dient zur Unterst�tzung von XExactName 187 typedef std::hash_map 188 < 189 ::rtl::OUString, 190 ::rtl::OUString, 191 hashName_Impl, 192 eqName_Impl 193 > 194 LowerToExactNameMap; 195 196 197 class ImplIntrospectionAccess; 198 class IntrospectionAccessStatic_Impl 199 { 200 friend class ImplIntrospection; 201 friend class ImplIntrospectionAccess; 202 203 // CoreReflection halten 204 Reference< XIdlReflection > mxCoreReflection; 205 206 // InterfaceSequences, um Zusatz-Infos zu einer Property speichern zu koennen. 207 // z.B. das Field bei MAP_FIELD, die get/set-Methoden bei MAP_GETSET usw. 208 Sequence< Reference<XInterface> > aInterfaceSeq1; 209 Sequence< Reference<XInterface> > aInterfaceSeq2; 210 211 // Hashtables fuer die Namen 212 IntrospectionNameMap maPropertyNameMap; 213 IntrospectionNameMap maMethodNameMap; 214 LowerToExactNameMap maLowerToExactNameMap; 215 216 // Sequence aller Properties, auch zum Liefern aus getProperties() 217 Sequence<Property> maAllPropertySeq; 218 219 // Mapping der Properties auf Zugriffs-Arten 220 Sequence<sal_Int16> maMapTypeSeq; 221 222 // Klassifizierung der gefundenen Methoden 223 Sequence<sal_Int32> maPropertyConceptSeq; 224 225 // Anzahl der Properties 226 sal_Int32 mnPropCount; 227 228 // Anzahl der Properties, die den jeweiligen Konzepten zugeordnet sind 229 //sal_Int32 mnDangerousPropCount; 230 sal_Int32 mnPropertySetPropCount; 231 sal_Int32 mnAttributePropCount; 232 sal_Int32 mnMethodPropCount; 233 234 // Flag, ob ein FastPropertySet unterstuetzt wird 235 sal_Bool mbFastPropSet; 236 237 // Original-Handles eines FastPropertySets 238 sal_Int32* mpOrgPropertyHandleArray; 239 240 // MethodSequence, die alle Methoden aufnimmt 241 Sequence< Reference<XIdlMethod> > maAllMethodSeq; 242 243 // Klassifizierung der gefundenen Methoden 244 Sequence<sal_Int32> maMethodConceptSeq; 245 246 // Anzahl der Methoden 247 sal_Int32 mnMethCount; 248 249 // Sequence der Listener, die angemeldet werden koennen 250 Sequence< Type > maSupportedListenerSeq; 251 252 // BaseInit (soll spaeter in der Applikation erfolgen!) 253 void BaseInit( void ); 254 255 // Hilfs-Methoden zur Groessen-Anpassung der Sequences 256 void checkPropertyArraysSize 257 ( 258 Property*& rpAllPropArray, 259 sal_Int16*& rpMapTypeArray, 260 sal_Int32*& rpPropertyConceptArray, 261 sal_Int32 iNextIndex 262 ); 263 void checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, Reference<XInterface>*& rpInterfaceArray, 264 sal_Int32 iNextIndex ); 265 266 // RefCount 267 sal_Int32 nRefCount; 268 269 270 public: 271 IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ ); 272 ~IntrospectionAccessStatic_Impl() 273 { 274 delete[] mpOrgPropertyHandleArray; 275 } 276 sal_Int32 getPropertyIndex( const ::rtl::OUString& aPropertyName ) const; 277 sal_Int32 getMethodIndex( const ::rtl::OUString& aMethodName ) const; 278 279 void acquire() { nRefCount++; } 280 void release() 281 { 282 nRefCount--; 283 if( nRefCount <= 0 ) 284 delete this; 285 } 286 287 // Methoden von XIntrospectionAccess (ALT, jetzt nur Impl) 288 void setPropertyValue(const Any& obj, const ::rtl::OUString& aPropertyName, const Any& aValue) const; 289 // void setPropertyValue(Any& obj, const ::rtl::OUString& aPropertyName, const Any& aValue) const; 290 Any getPropertyValue(const Any& obj, const ::rtl::OUString& aPropertyName) const; 291 void setPropertyValueByIndex(const Any& obj, sal_Int32 nIndex, const Any& aValue) const; 292 // void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const; 293 Any getPropertyValueByIndex(const Any& obj, sal_Int32 nIndex) const; 294 295 Sequence<Property> getProperties(void) const { return maAllPropertySeq; } 296 Sequence< Reference<XIdlMethod> > getMethods(void) const { return maAllMethodSeq; } 297 Sequence< Type > getSupportedListeners(void) const { return maSupportedListenerSeq; } 298 Sequence<sal_Int32> getPropertyConcepts(void) const { return maPropertyConceptSeq; } 299 Sequence<sal_Int32> getMethodConcepts(void) const { return maMethodConceptSeq; } 300 }; 301 302 303 // Ctor 304 IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ ) 305 : mxCoreReflection( xCoreReflection_ ) 306 { 307 aInterfaceSeq1.realloc( ARRAY_SIZE_STEP ); 308 aInterfaceSeq2.realloc( ARRAY_SIZE_STEP ); 309 310 // Property-Daten 311 maAllPropertySeq.realloc( ARRAY_SIZE_STEP ); 312 maMapTypeSeq.realloc( ARRAY_SIZE_STEP ); 313 maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP ); 314 315 mbFastPropSet = sal_False; 316 mpOrgPropertyHandleArray = NULL; 317 318 mnPropCount = 0; 319 //mnDangerousPropCount = 0; 320 mnPropertySetPropCount = 0; 321 mnAttributePropCount = 0; 322 mnMethodPropCount = 0; 323 324 // Method-Daten 325 mnMethCount = 0; 326 327 // Eigenens RefCounting 328 nRefCount = 0; 329 } 330 331 // Von Hand refcounten !!! 332 333 334 sal_Int32 IntrospectionAccessStatic_Impl::getPropertyIndex( const ::rtl::OUString& aPropertyName ) const 335 { 336 sal_Int32 iHashResult = -1; 337 IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this; 338 IntrospectionNameMap::iterator aIt = pThis->maPropertyNameMap.find( aPropertyName ); 339 if( !( aIt == pThis->maPropertyNameMap.end() ) ) 340 iHashResult = (*aIt).second; 341 return iHashResult; 342 } 343 344 sal_Int32 IntrospectionAccessStatic_Impl::getMethodIndex( const ::rtl::OUString& aMethodName ) const 345 { 346 sal_Int32 iHashResult = -1; 347 IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this; 348 IntrospectionNameMap::iterator aIt = pThis->maMethodNameMap.find( aMethodName ); 349 if( !( aIt == pThis->maMethodNameMap.end() ) ) 350 { 351 iHashResult = (*aIt).second; 352 } 353 // #95159 Check if full qualified name matches 354 else 355 { 356 sal_Int32 nSearchFrom = aMethodName.getLength(); 357 nSearchFrom = aMethodName.getLength(); 358 while( true ) 359 { 360 // Strategy: Search back until the first '_' is found 361 sal_Int32 nFound = aMethodName.lastIndexOf( '_', nSearchFrom ); 362 if( nFound == -1 ) 363 break; 364 365 ::rtl::OUString aPureMethodName = aMethodName.copy( nFound + 1 ); 366 367 aIt = pThis->maMethodNameMap.find( aPureMethodName ); 368 if( !( aIt == pThis->maMethodNameMap.end() ) ) 369 { 370 // Check if it can be a type? 371 // Problem: Does not work if package names contain _ ?! 372 ::rtl::OUString aStr = aMethodName.copy( 0, nFound ); 373 ::rtl::OUString aTypeName = aStr.replace( '_', '.' ); 374 Reference< XIdlClass > xClass = mxCoreReflection->forName( aTypeName ); 375 if( xClass.is() ) 376 { 377 // If this is a valid class it could be the right method 378 379 // Could be the right method, type has to be checked 380 iHashResult = (*aIt).second; 381 382 const Reference<XIdlMethod>* pMethods = maAllMethodSeq.getConstArray(); 383 const Reference<XIdlMethod> xMethod = pMethods[ iHashResult ]; 384 385 Reference< XIdlClass > xMethClass = xMethod->getDeclaringClass(); 386 if( xClass->equals( xMethClass ) ) 387 { 388 break; 389 } 390 else 391 { 392 iHashResult = -1; 393 394 // Could also be another method with the same name 395 // Iterate over all methods 396 sal_Int32 nLen = maAllMethodSeq.getLength(); 397 for( int i = 0 ; i < nLen ; ++i ) 398 { 399 const Reference<XIdlMethod> xMethod2 = pMethods[ i ]; 400 401 ::rtl::OUString aTestClassName = xMethod2->getDeclaringClass()->getName(); 402 ::rtl::OUString aTestMethodName = xMethod2->getName(); 403 404 if( xMethod2->getName() == aPureMethodName ) 405 { 406 Reference< XIdlClass > xMethClass2 = xMethod2->getDeclaringClass(); 407 408 if( xClass->equals( xMethClass2 ) ) 409 { 410 iHashResult = i; 411 break; 412 } 413 } 414 } 415 416 if( iHashResult != -1 ) 417 break; 418 } 419 } 420 } 421 422 nSearchFrom = nFound - 1; 423 if( nSearchFrom < 0 ) 424 break; 425 } 426 } 427 return iHashResult; 428 } 429 430 void IntrospectionAccessStatic_Impl::setPropertyValue( const Any& obj, const ::rtl::OUString& aPropertyName, const Any& aValue ) const 431 //void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const ::rtl::OUString& aPropertyName, const Any& aValue ) const 432 { 433 sal_Int32 i = getPropertyIndex( aPropertyName ); 434 if( i != -1 ) 435 setPropertyValueByIndex( obj, (sal_Int32)i, aValue ); 436 else 437 throw UnknownPropertyException(); 438 } 439 440 void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const 441 //void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const 442 { 443 // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes? 444 TypeClass eObjType = obj.getValueType().getTypeClass(); 445 446 Reference<XInterface> xInterface; 447 if( eObjType == TypeClass_INTERFACE ) 448 { 449 xInterface = *( Reference<XInterface>*)obj.getValue(); 450 } 451 else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) ) 452 { 453 throw IllegalArgumentException(); 454 } 455 456 // Flags pruefen 457 const Property* pProps = maAllPropertySeq.getConstArray(); 458 if( (pProps[ nSequenceIndex ].Attributes & READONLY) != 0 ) 459 { 460 throw UnknownPropertyException(); 461 } 462 463 const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray(); 464 switch( pMapTypeArray[ nSequenceIndex ] ) 465 { 466 case MAP_PROPERTY_SET: 467 { 468 // Property besorgen 469 const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ]; 470 471 // Interface-Parameter auf den richtigen Typ bringen 472 sal_Bool bUseCopy = sal_False; 473 Any aRealValue; 474 475 TypeClass eValType = aValue.getValueType().getTypeClass(); 476 if( eValType == TypeClass_INTERFACE ) 477 { 478 Type aPropType = rProp.Type; 479 ::rtl::OUString aTypeName( aPropType.getTypeName() ); 480 Reference< XIdlClass > xPropClass = mxCoreReflection->forName( aTypeName ); 481 //Reference<XIdlClass> xPropClass = rProp.Type; 482 if( xPropClass.is() && xPropClass->getTypeClass() == TypeClass_INTERFACE ) 483 { 484 Reference<XInterface> valInterface = *(Reference<XInterface>*)aValue.getValue(); 485 if( valInterface.is() ) 486 { 487 //Any queryInterface( const Type& rType ); 488 aRealValue = valInterface->queryInterface( aPropType ); 489 if( aRealValue.hasValue() ) 490 bUseCopy = sal_True; 491 } 492 } 493 } 494 495 // Haben wir ein FastPropertySet und ein gueltiges Handle? 496 // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet 497 // zu Beginn des Introspection-Vorgangs abgefragt wird. 498 sal_Int32 nOrgHandle; 499 if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 ) 500 { 501 // PropertySet-Interface holen 502 Reference<XFastPropertySet> xFastPropSet = 503 Reference<XFastPropertySet>::query( xInterface ); 504 if( xFastPropSet.is() ) 505 { 506 xFastPropSet->setFastPropertyValue( nOrgHandle, bUseCopy ? aRealValue : aValue ); 507 } 508 else 509 { 510 // throw UnknownPropertyException 511 } 512 } 513 // sonst eben das normale nehmen 514 else 515 { 516 // PropertySet-Interface holen 517 Reference<XPropertySet> xPropSet = 518 Reference<XPropertySet>::query( xInterface ); 519 if( xPropSet.is() ) 520 { 521 xPropSet->setPropertyValue( rProp.Name, bUseCopy ? aRealValue : aValue ); 522 } 523 else 524 { 525 // throw UnknownPropertyException 526 } 527 } 528 } 529 break; 530 531 case MAP_FIELD: 532 { 533 Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get()); 534 Reference<XIdlField2> xField2(xField, UNO_QUERY); 535 if( xField2.is() ) 536 { 537 xField2->set( (Any&)obj, aValue ); 538 // IllegalArgumentException 539 // NullPointerException 540 } else 541 if( xField.is() ) 542 { 543 xField->set( obj, aValue ); 544 // IllegalArgumentException 545 // NullPointerException 546 } 547 else 548 { 549 // throw IllegalArgumentException(); 550 } 551 } 552 break; 553 554 case MAP_GETSET: 555 case MAP_SETONLY: 556 { 557 // set-Methode holen 558 Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq2.getConstArray()[ nSequenceIndex ].get()); 559 if( xMethod.is() ) 560 { 561 Sequence<Any> args( 1 ); 562 args.getArray()[0] = aValue; 563 xMethod->invoke( obj, args ); 564 } 565 else 566 { 567 // throw IllegalArgumentException(); 568 } 569 } 570 break; 571 } 572 } 573 574 Any IntrospectionAccessStatic_Impl::getPropertyValue( const Any& obj, const ::rtl::OUString& aPropertyName ) const 575 { 576 sal_Int32 i = getPropertyIndex( aPropertyName ); 577 if( i != -1 ) 578 return getPropertyValueByIndex( obj, i ); 579 580 throw UnknownPropertyException(); 581 } 582 583 Any IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex) const 584 { 585 Any aRet; 586 587 // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes? 588 TypeClass eObjType = obj.getValueType().getTypeClass(); 589 590 Reference<XInterface> xInterface; 591 if( eObjType == TypeClass_INTERFACE ) 592 { 593 xInterface = *(Reference<XInterface>*)obj.getValue(); 594 } 595 else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) ) 596 { 597 // throw IllegalArgumentException(); 598 return aRet; 599 } 600 601 const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray(); 602 switch( pMapTypeArray[ nSequenceIndex ] ) 603 { 604 case MAP_PROPERTY_SET: 605 { 606 // Property besorgen 607 const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ]; 608 609 // Haben wir ein FastPropertySet und ein gueltiges Handle? 610 // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet 611 // zu Beginn des Introspection-Vorgangs abgefragt wird. 612 sal_Int32 nOrgHandle; 613 if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 ) 614 { 615 // PropertySet-Interface holen 616 Reference<XFastPropertySet> xFastPropSet = 617 Reference<XFastPropertySet>::query( xInterface ); 618 if( xFastPropSet.is() ) 619 { 620 aRet = xFastPropSet->getFastPropertyValue( nOrgHandle); 621 } 622 else 623 { 624 // throw UnknownPropertyException 625 return aRet; 626 } 627 } 628 // sonst eben das normale nehmen 629 else 630 { 631 // PropertySet-Interface holen 632 Reference<XPropertySet> xPropSet = 633 Reference<XPropertySet>::query( xInterface ); 634 if( xPropSet.is() ) 635 { 636 aRet = xPropSet->getPropertyValue( rProp.Name ); 637 } 638 else 639 { 640 // throw UnknownPropertyException 641 return aRet; 642 } 643 } 644 } 645 break; 646 647 case MAP_FIELD: 648 { 649 Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get()); 650 if( xField.is() ) 651 { 652 aRet = xField->get( obj ); 653 // IllegalArgumentException 654 // NullPointerException 655 } 656 else 657 { 658 // throw IllegalArgumentException(); 659 return aRet; 660 } 661 } 662 break; 663 664 case MAP_GETSET: 665 { 666 // get-Methode holen 667 Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get()); 668 if( xMethod.is() ) 669 { 670 Sequence<Any> args; 671 aRet = xMethod->invoke( obj, args ); 672 } 673 else 674 { 675 // throw IllegalArgumentException(); 676 return aRet; 677 } 678 } 679 break; 680 681 case MAP_SETONLY: 682 // get-Methode gibt es nicht 683 // throw WriteOnlyPropertyException(); 684 return aRet; 685 } 686 return aRet; 687 } 688 689 690 // Hilfs-Methoden zur Groessen-Anpassung der Sequences 691 void IntrospectionAccessStatic_Impl::checkPropertyArraysSize 692 ( 693 Property*& rpAllPropArray, 694 sal_Int16*& rpMapTypeArray, 695 sal_Int32*& rpPropertyConceptArray, 696 sal_Int32 iNextIndex 697 ) 698 { 699 sal_Int32 nLen = maAllPropertySeq.getLength(); 700 if( iNextIndex >= nLen ) 701 { 702 maAllPropertySeq.realloc( nLen + ARRAY_SIZE_STEP ); 703 rpAllPropArray = maAllPropertySeq.getArray(); 704 705 maMapTypeSeq.realloc( nLen + ARRAY_SIZE_STEP ); 706 rpMapTypeArray = maMapTypeSeq.getArray(); 707 708 maPropertyConceptSeq.realloc( nLen + ARRAY_SIZE_STEP ); 709 rpPropertyConceptArray = maPropertyConceptSeq.getArray(); 710 } 711 } 712 713 void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, 714 Reference<XInterface>*& rpInterfaceArray, sal_Int32 iNextIndex ) 715 { 716 sal_Int32 nLen = rSeq.getLength(); 717 if( iNextIndex >= nLen ) 718 { 719 // Neue Groesse mit ARRAY_SIZE_STEP abgleichen 720 sal_Int32 nMissingSize = iNextIndex - nLen + 1; 721 sal_Int32 nSteps = nMissingSize / ARRAY_SIZE_STEP + 1; 722 sal_Int32 nNewSize = nLen + nSteps * ARRAY_SIZE_STEP; 723 724 rSeq.realloc( nNewSize ); 725 rpInterfaceArray = rSeq.getArray(); 726 } 727 } 728 729 730 //******************************* 731 //*** ImplIntrospectionAccess *** 732 //******************************* 733 734 // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene 735 // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse 736 // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl 737 class ImplIntrospectionAccess : public IntrospectionAccessHelper 738 { 739 friend class ImplIntrospection; 740 741 // Untersuchtes Objekt 742 Any maInspectedObject; 743 744 // Als Interface 745 Reference<XInterface> mxIface; 746 747 // Statische Daten der Introspection 748 IntrospectionAccessStatic_Impl* mpStaticImpl; 749 750 // Adapter-Implementation 751 WeakReference< XInterface > maAdapter; 752 753 // Letzte Sequence, die bei getProperties geliefert wurde (Optimierung) 754 Sequence<Property> maLastPropertySeq; 755 sal_Int32 mnLastPropertyConcept; 756 757 // Letzte Sequence, die bei getMethods geliefert wurde (Optimierung) 758 Sequence<Reference<XIdlMethod> > maLastMethodSeq; 759 sal_Int32 mnLastMethodConcept; 760 761 public: 762 ImplIntrospectionAccess( const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ ); 763 ~ImplIntrospectionAccess(); 764 765 // Methoden von XIntrospectionAccess 766 virtual sal_Int32 SAL_CALL getSuppliedMethodConcepts(void) 767 throw( RuntimeException ); 768 virtual sal_Int32 SAL_CALL getSuppliedPropertyConcepts(void) 769 throw( RuntimeException ); 770 virtual Property SAL_CALL getProperty(const ::rtl::OUString& Name, sal_Int32 PropertyConcepts) 771 throw( NoSuchElementException, RuntimeException ); 772 virtual sal_Bool SAL_CALL hasProperty(const ::rtl::OUString& Name, sal_Int32 PropertyConcepts) 773 throw( RuntimeException ); 774 virtual Sequence< Property > SAL_CALL getProperties(sal_Int32 PropertyConcepts) 775 throw( RuntimeException ); 776 virtual Reference<XIdlMethod> SAL_CALL getMethod(const ::rtl::OUString& Name, sal_Int32 MethodConcepts) 777 throw( NoSuchMethodException, RuntimeException ); 778 virtual sal_Bool SAL_CALL hasMethod(const ::rtl::OUString& Name, sal_Int32 MethodConcepts) 779 throw( RuntimeException ); 780 virtual Sequence< Reference<XIdlMethod> > SAL_CALL getMethods(sal_Int32 MethodConcepts) 781 throw( RuntimeException ); 782 virtual Sequence< Type > SAL_CALL getSupportedListeners(void) 783 throw( RuntimeException ); 784 using OWeakObject::queryAdapter; 785 virtual Reference<XInterface> SAL_CALL queryAdapter( const Type& rType ) 786 throw( IllegalTypeException, RuntimeException ); 787 788 // Methoden von XMaterialHolder 789 virtual Any SAL_CALL getMaterial(void) throw(RuntimeException); 790 791 // Methoden von XExactName 792 virtual ::rtl::OUString SAL_CALL getExactName( const ::rtl::OUString& rApproximateName ) throw( RuntimeException ); 793 }; 794 795 ImplIntrospectionAccess::ImplIntrospectionAccess 796 ( const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ ) 797 : maInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ), maAdapter() 798 { 799 mpStaticImpl->acquire(); 800 801 // Objekt als Interface merken, wenn moeglich 802 TypeClass eType = maInspectedObject.getValueType().getTypeClass(); 803 if( eType == TypeClass_INTERFACE ) 804 mxIface = *(Reference<XInterface>*)maInspectedObject.getValue(); 805 806 mnLastPropertyConcept = -1; 807 mnLastMethodConcept = -1; 808 } 809 810 ImplIntrospectionAccess::~ImplIntrospectionAccess() 811 { 812 mpStaticImpl->release(); 813 } 814 815 816 //******************************* 817 //*** ImplIntrospectionAdapter *** 818 //******************************* 819 820 // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene 821 // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse 822 // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl 823 class ImplIntrospectionAdapter : 824 public XPropertySet, public XFastPropertySet, public XPropertySetInfo, 825 public XNameContainer, public XIndexContainer, 826 public XEnumerationAccess, public XIdlArray, 827 public OWeakObject 828 { 829 // Parent-Objekt 830 ::rtl::Reference< ImplIntrospectionAccess > mpAccess; 831 832 // Untersuchtes Objekt 833 const Any& mrInspectedObject; 834 835 // Statische Daten der Introspection 836 IntrospectionAccessStatic_Impl* mpStaticImpl; 837 838 // Objekt als Interface 839 Reference<XInterface> mxIface; 840 841 // Original-Interfaces des Objekts 842 Reference<XElementAccess> mxObjElementAccess; 843 Reference<XNameContainer> mxObjNameContainer; 844 Reference<XNameAccess> mxObjNameAccess; 845 Reference<XIndexAccess> mxObjIndexAccess; 846 Reference<XIndexContainer> mxObjIndexContainer; 847 Reference<XEnumerationAccess> mxObjEnumerationAccess; 848 Reference<XIdlArray> mxObjIdlArray; 849 850 public: 851 ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_, 852 const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ ); 853 ~ImplIntrospectionAdapter(); 854 855 // Methoden von XInterface 856 virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException ); 857 virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); } 858 virtual void SAL_CALL release() throw() { OWeakObject::release(); } 859 860 // Methoden von XPropertySet 861 virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( RuntimeException ); 862 virtual void SAL_CALL setPropertyValue(const ::rtl::OUString& aPropertyName, const Any& aValue) 863 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ); 864 virtual Any SAL_CALL getPropertyValue(const ::rtl::OUString& aPropertyName) 865 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); 866 virtual void SAL_CALL addPropertyChangeListener(const ::rtl::OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener) 867 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); 868 virtual void SAL_CALL removePropertyChangeListener(const ::rtl::OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener) 869 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); 870 virtual void SAL_CALL addVetoableChangeListener(const ::rtl::OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener) 871 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); 872 virtual void SAL_CALL removeVetoableChangeListener(const ::rtl::OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener) 873 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); 874 875 // Methoden von XFastPropertySet 876 virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const Any& aValue) 877 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ); 878 virtual Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) 879 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ); 880 881 // Methoden von XPropertySetInfo 882 virtual Sequence< Property > SAL_CALL getProperties(void) throw( RuntimeException ); 883 virtual Property SAL_CALL getPropertyByName(const ::rtl::OUString& Name) throw( RuntimeException ); 884 virtual sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& Name) throw( RuntimeException ); 885 886 // Methoden von XElementAccess 887 virtual Type SAL_CALL getElementType(void) throw( RuntimeException ); 888 virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException ); 889 890 // Methoden von XNameAccess 891 virtual Any SAL_CALL getByName(const ::rtl::OUString& Name) 892 throw( NoSuchElementException, WrappedTargetException, RuntimeException ); 893 virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames(void) throw( RuntimeException ); 894 virtual sal_Bool SAL_CALL hasByName(const ::rtl::OUString& Name) throw( RuntimeException ); 895 896 // Methoden von XNameContainer 897 virtual void SAL_CALL insertByName(const ::rtl::OUString& Name, const Any& Element) 898 throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException ); 899 virtual void SAL_CALL replaceByName(const ::rtl::OUString& Name, const Any& Element) 900 throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException ); 901 virtual void SAL_CALL removeByName(const ::rtl::OUString& Name) 902 throw( NoSuchElementException, WrappedTargetException, RuntimeException ); 903 904 // Methoden von XIndexAccess 905 virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException ); 906 virtual Any SAL_CALL getByIndex(sal_Int32 Index) 907 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); 908 909 // Methoden von XIndexContainer 910 virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element) 911 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); 912 virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element) 913 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); 914 virtual void SAL_CALL removeByIndex(sal_Int32 Index) 915 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); 916 917 // Methoden von XEnumerationAccess 918 virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException ); 919 920 // Methoden von XIdlArray 921 virtual void SAL_CALL realloc(Any& array, sal_Int32 length) 922 throw( IllegalArgumentException, RuntimeException ); 923 virtual sal_Int32 SAL_CALL getLen(const Any& array) throw( IllegalArgumentException, RuntimeException ); 924 virtual Any SAL_CALL get(const Any& array, sal_Int32 index) 925 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException ); 926 virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value) 927 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException ); 928 }; 929 930 ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_, 931 const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ ) 932 : mpAccess( pAccess_), mrInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ) 933 { 934 mpStaticImpl->acquire(); 935 936 // Objekt als Interfaceholen 937 TypeClass eType = mrInspectedObject.getValueType().getTypeClass(); 938 if( eType == TypeClass_INTERFACE ) 939 { 940 mxIface = *( Reference< XInterface >*)mrInspectedObject.getValue(); 941 942 mxObjElementAccess = Reference<XElementAccess>::query( mxIface ); 943 mxObjNameAccess = Reference<XNameAccess>::query( mxIface ); 944 mxObjNameContainer = Reference<XNameContainer>::query( mxIface ); 945 mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface ); 946 mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface ); 947 mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface ); 948 mxObjIdlArray = Reference<XIdlArray>::query( mxIface ); 949 } 950 } 951 952 ImplIntrospectionAdapter::~ImplIntrospectionAdapter() 953 { 954 mpStaticImpl->release(); 955 } 956 957 // Methoden von XInterface 958 Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType ) 959 throw( RuntimeException ) 960 { 961 Any aRet( ::cppu::queryInterface( 962 rType, 963 static_cast< XPropertySet * >( this ), 964 static_cast< XFastPropertySet * >( this ), 965 static_cast< XPropertySetInfo * >( this ) ) ); 966 if( !aRet.hasValue() ) 967 aRet = OWeakObject::queryInterface( rType ); 968 969 if( !aRet.hasValue() ) 970 { 971 // Wrapper fuer die Objekt-Interfaces 972 if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface 973 ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() ) 974 || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() ) 975 || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() ) 976 || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() ) 977 || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() ) 978 || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() ) 979 || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() ) 980 ) 981 { 982 } 983 } 984 return aRet; 985 } 986 987 988 //*************************************************** 989 //*** Implementation von ImplIntrospectionAdapter *** 990 //*************************************************** 991 992 // Methoden von XPropertySet 993 Reference<XPropertySetInfo> ImplIntrospectionAdapter::getPropertySetInfo(void) 994 throw( RuntimeException ) 995 { 996 return (XPropertySetInfo *)this; 997 } 998 999 void ImplIntrospectionAdapter::setPropertyValue(const ::rtl::OUString& aPropertyName, const Any& aValue) 1000 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ) 1001 { 1002 mpStaticImpl->setPropertyValue( mrInspectedObject, aPropertyName, aValue ); 1003 } 1004 1005 Any ImplIntrospectionAdapter::getPropertyValue(const ::rtl::OUString& aPropertyName) 1006 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) 1007 { 1008 return mpStaticImpl->getPropertyValue( mrInspectedObject, aPropertyName ); 1009 } 1010 1011 void ImplIntrospectionAdapter::addPropertyChangeListener(const ::rtl::OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener) 1012 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) 1013 { 1014 if( mxIface.is() ) 1015 { 1016 Reference<XPropertySet> xPropSet = 1017 Reference<XPropertySet>::query( mxIface ); 1018 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY ); 1019 if( xPropSet.is() ) 1020 xPropSet->addPropertyChangeListener(aPropertyName, aListener); 1021 } 1022 } 1023 1024 void ImplIntrospectionAdapter::removePropertyChangeListener(const ::rtl::OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener) 1025 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) 1026 { 1027 if( mxIface.is() ) 1028 { 1029 Reference<XPropertySet> xPropSet = 1030 Reference<XPropertySet>::query( mxIface ); 1031 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY ); 1032 if( xPropSet.is() ) 1033 xPropSet->removePropertyChangeListener(aPropertyName, aListener); 1034 } 1035 } 1036 1037 void ImplIntrospectionAdapter::addVetoableChangeListener(const ::rtl::OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener) 1038 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) 1039 { 1040 if( mxIface.is() ) 1041 { 1042 Reference<XPropertySet> xPropSet = 1043 Reference<XPropertySet>::query( mxIface ); 1044 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY ); 1045 if( xPropSet.is() ) 1046 xPropSet->addVetoableChangeListener(aPropertyName, aListener); 1047 } 1048 } 1049 1050 void ImplIntrospectionAdapter::removeVetoableChangeListener(const ::rtl::OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener) 1051 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) 1052 { 1053 if( mxIface.is() ) 1054 { 1055 Reference<XPropertySet> xPropSet = 1056 Reference<XPropertySet>::query( mxIface ); 1057 if( xPropSet.is() ) 1058 xPropSet->removeVetoableChangeListener(aPropertyName, aListener); 1059 } 1060 } 1061 1062 1063 // Methoden von XFastPropertySet 1064 void ImplIntrospectionAdapter::setFastPropertyValue(sal_Int32, const Any&) 1065 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ) 1066 { 1067 } 1068 1069 Any ImplIntrospectionAdapter::getFastPropertyValue(sal_Int32) 1070 throw( UnknownPropertyException, WrappedTargetException, RuntimeException ) 1071 { 1072 return Any(); 1073 } 1074 1075 // Methoden von XPropertySetInfo 1076 Sequence< Property > ImplIntrospectionAdapter::getProperties(void) throw( RuntimeException ) 1077 { 1078 return mpStaticImpl->getProperties(); 1079 } 1080 1081 Property ImplIntrospectionAdapter::getPropertyByName(const ::rtl::OUString& Name) 1082 throw( RuntimeException ) 1083 { 1084 return mpAccess->getProperty( Name, PropertyConcept::ALL ); 1085 } 1086 1087 sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const ::rtl::OUString& Name) 1088 throw( RuntimeException ) 1089 { 1090 return mpAccess->hasProperty( Name, PropertyConcept::ALL ); 1091 } 1092 1093 // Methoden von XElementAccess 1094 Type ImplIntrospectionAdapter::getElementType(void) throw( RuntimeException ) 1095 { 1096 return mxObjElementAccess->getElementType(); 1097 } 1098 1099 sal_Bool ImplIntrospectionAdapter::hasElements(void) throw( RuntimeException ) 1100 { 1101 return mxObjElementAccess->hasElements(); 1102 } 1103 1104 // Methoden von XNameAccess 1105 Any ImplIntrospectionAdapter::getByName(const ::rtl::OUString& Name) 1106 throw( NoSuchElementException, WrappedTargetException, RuntimeException ) 1107 { 1108 return mxObjNameAccess->getByName( Name ); 1109 } 1110 1111 Sequence< ::rtl::OUString > ImplIntrospectionAdapter::getElementNames(void) 1112 throw( RuntimeException ) 1113 { 1114 return mxObjNameAccess->getElementNames(); 1115 } 1116 1117 sal_Bool ImplIntrospectionAdapter::hasByName(const ::rtl::OUString& Name) 1118 throw( RuntimeException ) 1119 { 1120 return mxObjNameAccess->hasByName( Name ); 1121 } 1122 1123 // Methoden von XNameContainer 1124 void ImplIntrospectionAdapter::insertByName(const ::rtl::OUString& Name, const Any& Element) 1125 throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException ) 1126 { 1127 mxObjNameContainer->insertByName( Name, Element ); 1128 } 1129 1130 void ImplIntrospectionAdapter::replaceByName(const ::rtl::OUString& Name, const Any& Element) 1131 throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException ) 1132 { 1133 mxObjNameContainer->replaceByName( Name, Element ); 1134 } 1135 1136 void ImplIntrospectionAdapter::removeByName(const ::rtl::OUString& Name) 1137 throw( NoSuchElementException, WrappedTargetException, RuntimeException ) 1138 { 1139 mxObjNameContainer->removeByName( Name ); 1140 } 1141 1142 // Methoden von XIndexAccess 1143 // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const 1144 sal_Int32 ImplIntrospectionAdapter::getCount(void) throw( RuntimeException ) 1145 { 1146 return mxObjIndexAccess->getCount(); 1147 } 1148 1149 Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index) 1150 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 1151 { 1152 return mxObjIndexAccess->getByIndex( Index ); 1153 } 1154 1155 // Methoden von XIndexContainer 1156 void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element) 1157 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 1158 { 1159 mxObjIndexContainer->insertByIndex( Index, Element ); 1160 } 1161 1162 void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element) 1163 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 1164 { 1165 mxObjIndexContainer->replaceByIndex( Index, Element ); 1166 } 1167 1168 void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index) 1169 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 1170 { 1171 mxObjIndexContainer->removeByIndex( Index ); 1172 } 1173 1174 // Methoden von XEnumerationAccess 1175 // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const; 1176 Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration(void) throw( RuntimeException ) 1177 { 1178 return mxObjEnumerationAccess->createEnumeration(); 1179 } 1180 1181 // Methoden von XIdlArray 1182 void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length) 1183 throw( IllegalArgumentException, RuntimeException ) 1184 { 1185 mxObjIdlArray->realloc( array, length ); 1186 } 1187 1188 sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array) 1189 throw( IllegalArgumentException, RuntimeException ) 1190 { 1191 return mxObjIdlArray->getLen( array ); 1192 } 1193 1194 Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index) 1195 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException ) 1196 { 1197 return mxObjIdlArray->get( array, index ); 1198 } 1199 1200 void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value) 1201 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException ) 1202 { 1203 mxObjIdlArray->set( array, index, value ); 1204 } 1205 1206 1207 //************************************************** 1208 //*** Implementation von ImplIntrospectionAccess *** 1209 //************************************************** 1210 1211 // Methoden von XIntrospectionAccess 1212 sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts(void) 1213 throw( RuntimeException ) 1214 { 1215 return MethodConcept::DANGEROUS | 1216 PROPERTY | 1217 LISTENER | 1218 ENUMERATION | 1219 NAMECONTAINER | 1220 INDEXCONTAINER; 1221 } 1222 1223 sal_Int32 ImplIntrospectionAccess::getSuppliedPropertyConcepts(void) 1224 throw( RuntimeException ) 1225 { 1226 return PropertyConcept::DANGEROUS | 1227 PROPERTYSET | 1228 ATTRIBUTES | 1229 METHODS; 1230 } 1231 1232 Property ImplIntrospectionAccess::getProperty(const ::rtl::OUString& Name, sal_Int32 PropertyConcepts) 1233 throw( NoSuchElementException, RuntimeException ) 1234 { 1235 Property aRet; 1236 sal_Int32 i = mpStaticImpl->getPropertyIndex( Name ); 1237 sal_Bool bFound = sal_False; 1238 if( i != -1 ) 1239 { 1240 sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ]; 1241 if( (PropertyConcepts & nConcept) != 0 ) 1242 { 1243 const Property* pProps = mpStaticImpl->getProperties().getConstArray(); 1244 aRet = pProps[ i ]; 1245 bFound = sal_True; 1246 } 1247 } 1248 if( !bFound ) 1249 throw NoSuchElementException() ; 1250 return aRet; 1251 } 1252 1253 sal_Bool ImplIntrospectionAccess::hasProperty(const ::rtl::OUString& Name, sal_Int32 PropertyConcepts) 1254 throw( RuntimeException ) 1255 { 1256 sal_Int32 i = mpStaticImpl->getPropertyIndex( Name ); 1257 sal_Bool bRet = sal_False; 1258 if( i != -1 ) 1259 { 1260 sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ]; 1261 if( (PropertyConcepts & nConcept) != 0 ) 1262 bRet = sal_True; 1263 } 1264 return bRet; 1265 } 1266 1267 Sequence< Property > ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts) 1268 throw( RuntimeException ) 1269 { 1270 // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen 1271 sal_Int32 nAllSupportedMask = PROPERTYSET | 1272 ATTRIBUTES | 1273 METHODS; 1274 if( ( PropertyConcepts & nAllSupportedMask ) == nAllSupportedMask ) 1275 { 1276 return mpStaticImpl->getProperties(); 1277 } 1278 1279 // Gleiche Sequence wie beim vorigen mal? 1280 if( mnLastPropertyConcept == PropertyConcepts ) 1281 { 1282 return maLastPropertySeq; 1283 } 1284 1285 // Anzahl der zu liefernden Properties 1286 sal_Int32 nCount = 0; 1287 1288 // Es gibt zur Zeit keine DANGEROUS-Properties 1289 // if( PropertyConcepts & DANGEROUS ) 1290 // nCount += mpStaticImpl->mnDangerousPropCount; 1291 if( PropertyConcepts & PROPERTYSET ) 1292 nCount += mpStaticImpl->mnPropertySetPropCount; 1293 if( PropertyConcepts & ATTRIBUTES ) 1294 nCount += mpStaticImpl->mnAttributePropCount; 1295 if( PropertyConcepts & METHODS ) 1296 nCount += mpStaticImpl->mnMethodPropCount; 1297 1298 // Sequence entsprechend der geforderten Anzahl reallocieren 1299 ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen 1300 pThis->maLastPropertySeq.realloc( nCount ); 1301 Property* pDestProps = pThis->maLastPropertySeq.getArray(); 1302 1303 // Alle Properties durchgehen und entsprechend der Concepte uebernehmen 1304 Sequence<Property> aPropSeq = mpStaticImpl->getProperties(); 1305 const Property* pSourceProps = aPropSeq.getConstArray(); 1306 const sal_Int32* pConcepts = mpStaticImpl->getPropertyConcepts().getConstArray(); 1307 sal_Int32 nLen = aPropSeq.getLength(); 1308 1309 sal_Int32 iDest = 0; 1310 for( sal_Int32 i = 0 ; i < nLen ; i++ ) 1311 { 1312 sal_Int32 nConcept = pConcepts[ i ]; 1313 if( nConcept & PropertyConcepts ) 1314 pDestProps[ iDest++ ] = pSourceProps[ i ]; 1315 1316 /* 1317 // Property mit Concepts ausgeben 1318 ::rtl::OUString aPropName = pSourceProps[ i ].Name; 1319 String aNameStr = OOUStringToString(aPropName, CHARSET_SYSTEM); 1320 String ConceptStr; 1321 if( nConcept & PROPERTYSET ) 1322 ConceptStr += "PROPERTYSET"; 1323 if( nConcept & ATTRIBUTES ) 1324 ConceptStr += "ATTRIBUTES"; 1325 if( nConcept & METHODS ) 1326 ConceptStr += "METHODS"; 1327 printf( "Property %ld: %s, Concept = %s\n", i, aNameStr.GetStr(), ConceptStr.GetStr() ); 1328 */ 1329 } 1330 1331 // PropertyConcept merken, dies entspricht maLastPropertySeq 1332 pThis->mnLastPropertyConcept = PropertyConcepts; 1333 1334 // Zusammengebastelte Sequence liefern 1335 return maLastPropertySeq; 1336 } 1337 1338 Reference<XIdlMethod> ImplIntrospectionAccess::getMethod(const ::rtl::OUString& Name, sal_Int32 MethodConcepts) 1339 throw( NoSuchMethodException, RuntimeException ) 1340 { 1341 Reference<XIdlMethod> xRet; 1342 sal_Int32 i = mpStaticImpl->getMethodIndex( Name ); 1343 if( i != -1 ) 1344 { 1345 1346 sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ]; 1347 if( (MethodConcepts & nConcept) != 0 ) 1348 { 1349 const Reference<XIdlMethod>* pMethods = mpStaticImpl->getMethods().getConstArray(); 1350 xRet = pMethods[i]; 1351 } 1352 } 1353 if( !xRet.is() ) 1354 throw NoSuchMethodException(); 1355 return xRet; 1356 } 1357 1358 sal_Bool ImplIntrospectionAccess::hasMethod(const ::rtl::OUString& Name, sal_Int32 MethodConcepts) 1359 throw( RuntimeException ) 1360 { 1361 sal_Int32 i = mpStaticImpl->getMethodIndex( Name ); 1362 sal_Bool bRet = sal_False; 1363 if( i != -1 ) 1364 { 1365 sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ]; 1366 if( (MethodConcepts & nConcept) != 0 ) 1367 bRet = sal_True; 1368 } 1369 return bRet; 1370 } 1371 1372 Sequence< Reference<XIdlMethod> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts) 1373 throw( RuntimeException ) 1374 { 1375 ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen 1376 1377 // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen 1378 sal_Int32 nAllSupportedMask = MethodConcept::DANGEROUS | 1379 PROPERTY | 1380 LISTENER | 1381 ENUMERATION | 1382 NAMECONTAINER | 1383 INDEXCONTAINER | 1384 MethodConcept_NORMAL_IMPL; 1385 if( ( MethodConcepts & nAllSupportedMask ) == nAllSupportedMask ) 1386 { 1387 return mpStaticImpl->getMethods(); 1388 } 1389 1390 // Gleiche Sequence wie beim vorigen mal? 1391 if( mnLastMethodConcept == MethodConcepts ) 1392 { 1393 return maLastMethodSeq; 1394 } 1395 1396 // Methoden-Sequences besorgen 1397 Sequence< Reference<XIdlMethod> > aMethodSeq = mpStaticImpl->getMethods(); 1398 const Reference<XIdlMethod>* pSourceMethods = aMethodSeq.getConstArray(); 1399 const sal_Int32* pConcepts = mpStaticImpl->getMethodConcepts().getConstArray(); 1400 sal_Int32 nLen = aMethodSeq.getLength(); 1401 1402 // Sequence entsprechend der geforderten Anzahl reallocieren 1403 // Anders als bei den Properties kann die Anzahl nicht durch 1404 // Zaehler in inspect() vorher ermittelt werden, da Methoden 1405 // mehreren Konzepten angehoeren koennen 1406 pThis->maLastMethodSeq.realloc( nLen ); 1407 Reference<XIdlMethod>* pDestMethods = pThis->maLastMethodSeq.getArray(); 1408 1409 // Alle Methods durchgehen und entsprechend der Concepte uebernehmen 1410 sal_Int32 iDest = 0; 1411 for( sal_Int32 i = 0 ; i < nLen ; i++ ) 1412 { 1413 sal_Int32 nConcept = pConcepts[ i ]; 1414 if( nConcept & MethodConcepts ) 1415 pDestMethods[ iDest++ ] = pSourceMethods[ i ]; 1416 1417 #if OSL_DEBUG_LEVEL > 0 1418 static bool debug = false; 1419 if ( debug ) 1420 { 1421 // Methode mit Concepts ausgeben 1422 const Reference< XIdlMethod >& rxMethod = pSourceMethods[ i ]; 1423 ::rtl::OString aNameStr = ::rtl::OUStringToOString( rxMethod->getName(), osl_getThreadTextEncoding() ); 1424 ::rtl::OString ConceptStr; 1425 if( nConcept & MethodConcept::DANGEROUS ) 1426 ConceptStr += "DANGEROUS |"; 1427 if( nConcept & MethodConcept::PROPERTY ) 1428 ConceptStr += "PROPERTY |"; 1429 if( nConcept & MethodConcept::LISTENER ) 1430 ConceptStr += "LISTENER |"; 1431 if( nConcept & MethodConcept::ENUMERATION ) 1432 ConceptStr += "ENUMERATION |"; 1433 if( nConcept & MethodConcept::NAMECONTAINER ) 1434 ConceptStr += "NAMECONTAINER |"; 1435 if( nConcept & MethodConcept::INDEXCONTAINER ) 1436 ConceptStr += "INDEXCONTAINER |"; 1437 OSL_TRACE( "Method %ld: %s, Concepts = %s", i, aNameStr.getStr(), ConceptStr.getStr() ); 1438 } 1439 #endif 1440 } 1441 1442 // Auf die richtige Laenge bringen 1443 pThis->maLastMethodSeq.realloc( iDest ); 1444 1445 // MethodConcept merken, dies entspricht maLastMethodSeq 1446 pThis->mnLastMethodConcept = MethodConcepts; 1447 1448 // Zusammengebastelte Sequence liefern 1449 return maLastMethodSeq; 1450 } 1451 1452 Sequence< Type > ImplIntrospectionAccess::getSupportedListeners(void) 1453 throw( RuntimeException ) 1454 { 1455 return mpStaticImpl->getSupportedListeners(); 1456 } 1457 1458 Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type& rType ) 1459 throw( IllegalTypeException, RuntimeException ) 1460 { 1461 // Gibt es schon einen Adapter? 1462 Reference< XInterface > xAdapter( maAdapter ); 1463 if( !xAdapter.is() ) 1464 { 1465 xAdapter = *( new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl ) ); 1466 maAdapter = xAdapter; 1467 } 1468 1469 Reference<XInterface> xRet; 1470 xAdapter->queryInterface( rType ) >>= xRet; 1471 return xRet; 1472 } 1473 1474 // Methoden von XMaterialHolder 1475 Any ImplIntrospectionAccess::getMaterial(void) throw(RuntimeException) 1476 { 1477 return maInspectedObject; 1478 } 1479 1480 // Hilfs-Funktion zur LowerCase-Wandlung eines ::rtl::OUString 1481 ::rtl::OUString toLower( ::rtl::OUString aUStr ) 1482 { 1483 // Tabelle fuer XExactName pflegen 1484 ::rtl::OUString aOWStr( aUStr.getStr() ); 1485 ::rtl::OUString aOWLowerStr = aOWStr.toAsciiLowerCase(); 1486 ::rtl::OUString aLowerUStr( aOWLowerStr.getStr() ); 1487 return aLowerUStr; 1488 } 1489 1490 // Methoden von XExactName 1491 ::rtl::OUString ImplIntrospectionAccess::getExactName( const ::rtl::OUString& rApproximateName ) throw( RuntimeException ) 1492 { 1493 ::rtl::OUString aRetStr; 1494 LowerToExactNameMap::iterator aIt = 1495 mpStaticImpl->maLowerToExactNameMap.find( toLower( rApproximateName ) ); 1496 if( !( aIt == mpStaticImpl->maLowerToExactNameMap.end() ) ) 1497 aRetStr = (*aIt).second; 1498 return aRetStr; 1499 } 1500 1501 1502 //----------------------------------------------------------------------------- 1503 1504 #ifdef USE_INTROSPECTION_CACHE 1505 1506 struct hashIntrospectionKey_Impl 1507 { 1508 Sequence< Reference<XIdlClass> > aIdlClasses; 1509 Reference<XPropertySetInfo> xPropInfo; 1510 Reference<XIdlClass> xImplClass; 1511 sal_Int32 nHitCount; 1512 1513 void IncHitCount() const { ((hashIntrospectionKey_Impl*)this)->nHitCount++; } 1514 hashIntrospectionKey_Impl() : nHitCount( 0 ) {} 1515 hashIntrospectionKey_Impl( const Sequence< Reference<XIdlClass> > & rIdlClasses, 1516 const Reference<XPropertySetInfo> & rxPropInfo, 1517 const Reference<XIdlClass> & rxImplClass ); 1518 }; 1519 1520 hashIntrospectionKey_Impl::hashIntrospectionKey_Impl 1521 ( 1522 const Sequence< Reference<XIdlClass> > & rIdlClasses, 1523 const Reference<XPropertySetInfo> & rxPropInfo, 1524 const Reference<XIdlClass> & rxImplClass 1525 ) 1526 : aIdlClasses( rIdlClasses ) 1527 , xPropInfo( rxPropInfo ) 1528 , xImplClass( rxImplClass ) 1529 , nHitCount( 0 ) 1530 {} 1531 1532 1533 struct hashIntrospectionAccessCache_Impl 1534 { 1535 size_t operator()(const hashIntrospectionKey_Impl & rObj ) const 1536 { 1537 return (size_t)rObj.xImplClass.get() ^ (size_t)rObj.xPropInfo.get(); 1538 } 1539 1540 bool operator()( const hashIntrospectionKey_Impl & rObj1, 1541 const hashIntrospectionKey_Impl & rObj2 ) const 1542 { 1543 if( rObj1.xPropInfo != rObj2.xPropInfo 1544 || rObj1.xImplClass != rObj2.xImplClass ) 1545 return sal_False; 1546 1547 sal_Int32 nCount1 = rObj1.aIdlClasses.getLength(); 1548 sal_Int32 nCount2 = rObj2.aIdlClasses.getLength(); 1549 if( nCount1 != nCount2 ) 1550 return sal_False; 1551 1552 const Reference<XIdlClass>* pRefs1 = rObj1.aIdlClasses.getConstArray(); 1553 const Reference<XIdlClass>* pRefs2 = rObj2.aIdlClasses.getConstArray(); 1554 return memcmp( pRefs1, pRefs2, nCount1 * sizeof( Reference<XIdlClass> ) ) == 0; 1555 } 1556 1557 }; 1558 1559 typedef std::hash_map 1560 < 1561 hashIntrospectionKey_Impl, 1562 IntrospectionAccessStatic_Impl*, 1563 hashIntrospectionAccessCache_Impl, 1564 hashIntrospectionAccessCache_Impl 1565 > 1566 IntrospectionAccessCacheMap_Impl; 1567 1568 class IntrospectionAccessCacheMap : public IntrospectionAccessCacheMap_Impl 1569 { 1570 public: 1571 ~IntrospectionAccessCacheMap() 1572 { 1573 IntrospectionAccessCacheMap::iterator iter = begin(); 1574 IntrospectionAccessCacheMap::iterator stop = this->end(); 1575 while( iter != stop ) 1576 { 1577 1578 (*iter).second->release(); 1579 (*iter).second = NULL; 1580 iter++; 1581 } 1582 } 1583 }; 1584 1585 1586 // For XTypeProvider 1587 struct hashTypeProviderKey_Impl 1588 { 1589 Reference<XPropertySetInfo> xPropInfo; 1590 Sequence< sal_Int8 > maImpIdSeq; 1591 sal_Int32 nHitCount; 1592 1593 void IncHitCount() const { ((hashTypeProviderKey_Impl*)this)->nHitCount++; } 1594 hashTypeProviderKey_Impl() : nHitCount( 0 ) {} 1595 hashTypeProviderKey_Impl( const Reference<XPropertySetInfo> & rxPropInfo, const Sequence< sal_Int8 > & aImpIdSeq_ ); 1596 }; 1597 1598 hashTypeProviderKey_Impl::hashTypeProviderKey_Impl 1599 ( 1600 const Reference<XPropertySetInfo> & rxPropInfo, 1601 const Sequence< sal_Int8 > & aImpIdSeq_ 1602 ) 1603 : xPropInfo( rxPropInfo ) 1604 , maImpIdSeq( aImpIdSeq_ ) 1605 , nHitCount( 0 ) 1606 {} 1607 1608 1609 struct TypeProviderAccessCache_Impl 1610 { 1611 size_t operator()(const hashTypeProviderKey_Impl & rObj ) const; 1612 1613 bool operator()( const hashTypeProviderKey_Impl & rObj1, 1614 const hashTypeProviderKey_Impl & rObj2 ) const 1615 { 1616 if( rObj1.xPropInfo != rObj2.xPropInfo ) 1617 return sal_False; 1618 1619 bool bEqual = false; 1620 sal_Int32 nLen1 = rObj1.maImpIdSeq.getLength(); 1621 sal_Int32 nLen2 = rObj2.maImpIdSeq.getLength(); 1622 if( nLen1 == nLen2 && nLen1 > 0 ) 1623 { 1624 const sal_Int8* pId1 = rObj1.maImpIdSeq.getConstArray(); 1625 const sal_Int8* pId2 = rObj2.maImpIdSeq.getConstArray(); 1626 bEqual = (memcmp( pId1, pId2, nLen1 * sizeof( sal_Int8 ) ) == 0 ); 1627 } 1628 return bEqual; 1629 } 1630 }; 1631 1632 size_t TypeProviderAccessCache_Impl::operator()(const hashTypeProviderKey_Impl & rObj ) const 1633 { 1634 const sal_Int32* pBytesAsInt32Array = (const sal_Int32*)rObj.maImpIdSeq.getConstArray(); 1635 sal_Int32 nLen = rObj.maImpIdSeq.getLength(); 1636 sal_Int32 nCount32 = nLen / 4; 1637 sal_Int32 nMod32 = nLen % 4; 1638 1639 // XOR with full 32 bit values 1640 sal_Int32 nId32 = 0; 1641 sal_Int32 i; 1642 for( i = 0 ; i < nCount32 ; i++ ) 1643 nId32 ^= *(pBytesAsInt32Array++); 1644 1645 // XOR with remaining byte values 1646 if( nMod32 ) 1647 { 1648 const sal_Int8* pBytes = (const sal_Int8*)pBytesAsInt32Array; 1649 sal_Int8* pInt8_Id32 = (sal_Int8*)&nId32; 1650 for( i = 0 ; i < nMod32 ; i++ ) 1651 *(pInt8_Id32++) ^= *(pBytes++); 1652 } 1653 1654 return (size_t)nId32; 1655 } 1656 1657 1658 typedef std::hash_map 1659 < 1660 hashTypeProviderKey_Impl, 1661 IntrospectionAccessStatic_Impl*, 1662 TypeProviderAccessCache_Impl, 1663 TypeProviderAccessCache_Impl 1664 > 1665 TypeProviderAccessCacheMap_Impl; 1666 1667 class TypeProviderAccessCacheMap : public TypeProviderAccessCacheMap_Impl 1668 { 1669 public: 1670 ~TypeProviderAccessCacheMap() 1671 { 1672 TypeProviderAccessCacheMap::iterator iter = begin(); 1673 TypeProviderAccessCacheMap::iterator stop = this->end(); 1674 while( iter != stop ) 1675 { 1676 (*iter).second->release(); 1677 (*iter).second = NULL; 1678 iter++; 1679 } 1680 } 1681 }; 1682 1683 #endif 1684 1685 1686 //************************* 1687 //*** ImplIntrospection *** 1688 //************************* 1689 1690 struct OIntrospectionMutex 1691 { 1692 Mutex m_mutex; 1693 }; 1694 1695 class ImplIntrospection : public XIntrospection 1696 , public XServiceInfo 1697 , public OIntrospectionMutex 1698 , public OComponentHelper 1699 { 1700 friend class ImplMergeIntrospection; 1701 friend class ImplMVCIntrospection; 1702 1703 // Implementation der Introspection. 1704 // ACHTUNG: RefCounting von Hand !!! 1705 IntrospectionAccessStatic_Impl* implInspect(const Any& aToInspectObj); 1706 1707 // Save XMultiServiceFactory from createComponent 1708 Reference<XMultiServiceFactory> m_xSMgr; 1709 1710 // CoreReflection halten 1711 Reference< XIdlReflection > mxCoreReflection; 1712 1713 // Klassen, deren Methoden eine spezielle Rolle spielen 1714 Reference<XIdlClass> mxElementAccessClass; 1715 Reference<XIdlClass> mxNameContainerClass; 1716 Reference<XIdlClass> mxNameAccessClass; 1717 Reference<XIdlClass> mxIndexContainerClass; 1718 Reference<XIdlClass> mxIndexAccessClass; 1719 Reference<XIdlClass> mxEnumerationAccessClass; 1720 Reference<XIdlClass> mxInterfaceClass; 1721 Reference<XIdlClass> mxAggregationClass; 1722 sal_Bool mbDisposed; 1723 1724 #ifdef USE_INTROSPECTION_CACHE 1725 sal_uInt16 mnCacheEntryCount; 1726 sal_uInt16 mnTPCacheEntryCount; 1727 IntrospectionAccessCacheMap* mpCache; 1728 TypeProviderAccessCacheMap* mpTypeProviderCache; 1729 #endif 1730 1731 public: 1732 ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr ); 1733 1734 // Methoden von XInterface 1735 virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException ); 1736 virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); } 1737 virtual void SAL_CALL release() throw() { OComponentHelper::release(); } 1738 1739 // XTypeProvider 1740 Sequence< Type > SAL_CALL getTypes( ) throw( RuntimeException ); 1741 Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw( RuntimeException ); 1742 1743 // XServiceInfo 1744 ::rtl::OUString SAL_CALL getImplementationName() throw(); 1745 sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw(); 1746 Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw(); 1747 static ::rtl::OUString SAL_CALL getImplementationName_Static( ); 1748 static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_Static(void) throw(); 1749 1750 // Methoden von XIntrospection 1751 virtual Reference<XIntrospectionAccess> SAL_CALL inspect(const Any& aToInspectObj) 1752 throw( RuntimeException ); 1753 1754 protected: 1755 // some XComponent part from OComponentHelper 1756 virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); 1757 }; 1758 1759 enum MethodType 1760 { 1761 STANDARD_METHOD, // normale Methode, kein Bezug zu Properties oder Listenern 1762 GETSET_METHOD, // gehoert zu einer get/set-Property 1763 ADD_LISTENER_METHOD, // add-Methode einer Listener-Schnittstelle 1764 REMOVE_LISTENER_METHOD, // remove-Methode einer Listener-Schnittstelle 1765 INVALID_METHOD // Methode, deren Klasse nicht beruecksichtigt wird, z.B. XPropertySet 1766 }; 1767 1768 // Ctor 1769 ImplIntrospection::ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr ) 1770 : OComponentHelper( m_mutex ) 1771 , m_xSMgr( rXSMgr ) 1772 { 1773 #ifdef USE_INTROSPECTION_CACHE 1774 mnCacheEntryCount = 0; 1775 mnTPCacheEntryCount = 0; 1776 mpCache = NULL; 1777 mpTypeProviderCache = NULL; 1778 #endif 1779 1780 // Spezielle Klassen holen 1781 // Reference< XInterface > xServiceIface = m_xSMgr->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) ); 1782 // if( xServiceIface.is() ) 1783 // mxCoreReflection = Reference< XIdlReflection >::query( xServiceIface ); 1784 Reference< XPropertySet > xProps( rXSMgr, UNO_QUERY ); 1785 OSL_ASSERT( xProps.is() ); 1786 if (xProps.is()) 1787 { 1788 Reference< XComponentContext > xContext; 1789 xProps->getPropertyValue( 1790 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext; 1791 OSL_ASSERT( xContext.is() ); 1792 if (xContext.is()) 1793 { 1794 xContext->getValueByName( 1795 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection") ) ) >>= mxCoreReflection; 1796 OSL_ENSURE( mxCoreReflection.is(), "### CoreReflection singleton not accessible!?" ); 1797 } 1798 } 1799 if (! mxCoreReflection.is()) 1800 { 1801 throw DeploymentException( 1802 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible") ), 1803 Reference< XInterface >() ); 1804 } 1805 1806 mxElementAccessClass = mxCoreReflection->forName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XElementAccess")) ); 1807 mxNameContainerClass = mxCoreReflection->forName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XNameContainer")) ); 1808 mxNameAccessClass = mxCoreReflection->forName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XNameAccess")) ); 1809 mxIndexContainerClass = mxCoreReflection->forName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XIndexContainer")) ); 1810 mxIndexAccessClass = mxCoreReflection->forName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XIndexAccess")) ); 1811 mxEnumerationAccessClass = mxCoreReflection->forName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XEnumerationAccess")) ); 1812 mxInterfaceClass = mxCoreReflection->forName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface")) ); 1813 mxAggregationClass = mxCoreReflection->forName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XAggregation")) ); 1814 mbDisposed = sal_False; 1815 } 1816 1817 // XComponent 1818 void ImplIntrospection::dispose() throw(::com::sun::star::uno::RuntimeException) 1819 { 1820 OComponentHelper::dispose(); 1821 1822 #ifdef USE_INTROSPECTION_CACHE 1823 // Cache loeschen 1824 delete mpCache; 1825 mpCache = NULL; 1826 delete mpTypeProviderCache; 1827 mpTypeProviderCache = NULL; 1828 #endif 1829 1830 mxElementAccessClass = NULL; 1831 mxNameContainerClass = NULL; 1832 mxNameAccessClass = NULL; 1833 mxIndexContainerClass = NULL; 1834 mxIndexAccessClass = NULL; 1835 mxEnumerationAccessClass = NULL; 1836 mxInterfaceClass = NULL; 1837 mxAggregationClass = NULL; 1838 mbDisposed = sal_True; 1839 } 1840 1841 1842 //----------------------------------------------------------------------------- 1843 1844 // XInterface 1845 Any ImplIntrospection::queryInterface( const Type & rType ) 1846 throw(::com::sun::star::uno::RuntimeException) 1847 { 1848 Any aRet( ::cppu::queryInterface( 1849 rType, 1850 static_cast< XIntrospection * >( this ), 1851 static_cast< XServiceInfo * >( this ) ) ); 1852 1853 return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType )); 1854 } 1855 1856 // XTypeProvider 1857 Sequence< Type > ImplIntrospection::getTypes() 1858 throw( RuntimeException ) 1859 { 1860 static OTypeCollection * s_pTypes = 0; 1861 if (! s_pTypes) 1862 { 1863 MutexGuard aGuard( Mutex::getGlobalMutex() ); 1864 if (! s_pTypes) 1865 { 1866 static OTypeCollection s_aTypes( 1867 ::getCppuType( (const Reference< XIntrospection > *)0 ), 1868 ::getCppuType( (const Reference< XServiceInfo > *)0 ), 1869 OComponentHelper::getTypes() ); 1870 s_pTypes = &s_aTypes; 1871 } 1872 } 1873 return s_pTypes->getTypes(); 1874 } 1875 1876 Sequence< sal_Int8 > ImplIntrospection::getImplementationId() 1877 throw( RuntimeException ) 1878 { 1879 static OImplementationId * s_pId = 0; 1880 if (! s_pId) 1881 { 1882 MutexGuard aGuard( Mutex::getGlobalMutex() ); 1883 if (! s_pId) 1884 { 1885 static OImplementationId s_aId; 1886 s_pId = &s_aId; 1887 } 1888 } 1889 return s_pId->getImplementationId(); 1890 } 1891 1892 1893 // XServiceInfo 1894 ::rtl::OUString ImplIntrospection::getImplementationName() throw() 1895 { 1896 return getImplementationName_Static(); 1897 } 1898 1899 // XServiceInfo 1900 sal_Bool ImplIntrospection::supportsService(const ::rtl::OUString& ServiceName) throw() 1901 { 1902 Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames(); 1903 const ::rtl::OUString * pArray = aSNL.getConstArray(); 1904 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 1905 if( pArray[i] == ServiceName ) 1906 return sal_True; 1907 return sal_False; 1908 } 1909 1910 // XServiceInfo 1911 Sequence< ::rtl::OUString > ImplIntrospection::getSupportedServiceNames(void) throw() 1912 { 1913 return getSupportedServiceNames_Static(); 1914 } 1915 1916 //************************************************************************* 1917 // Helper XServiceInfo 1918 ::rtl::OUString ImplIntrospection::getImplementationName_Static( ) 1919 { 1920 return ::rtl::OUString::createFromAscii( IMPLEMENTATION_NAME ); 1921 } 1922 1923 // ORegistryServiceManager_Static 1924 Sequence< ::rtl::OUString > ImplIntrospection::getSupportedServiceNames_Static(void) throw() 1925 { 1926 Sequence< ::rtl::OUString > aSNS( 1 ); 1927 aSNS.getArray()[0] = ::rtl::OUString::createFromAscii( SERVICE_NAME ); 1928 return aSNS; 1929 } 1930 1931 //************************************************************************* 1932 1933 // Methoden von XIntrospection 1934 Reference<XIntrospectionAccess> ImplIntrospection::inspect(const Any& aToInspectObj) 1935 throw( RuntimeException ) 1936 { 1937 Reference<XIntrospectionAccess> xAccess; 1938 1939 if ( aToInspectObj.getValueType().getTypeClass() == TypeClass_TYPE ) 1940 { 1941 Type aType; 1942 aToInspectObj >>= aType; 1943 1944 Reference< XIdlClass > xIdlClass = mxCoreReflection->forName(((Type*)(aToInspectObj.getValue()))->getTypeName()); 1945 1946 if ( xIdlClass.is() ) 1947 { 1948 Any aRealInspectObj; 1949 aRealInspectObj <<= xIdlClass; 1950 1951 IntrospectionAccessStatic_Impl* pStaticImpl = implInspect( aRealInspectObj ); 1952 if( pStaticImpl ) 1953 xAccess = new ImplIntrospectionAccess( aRealInspectObj, pStaticImpl ); 1954 } 1955 } 1956 else 1957 { 1958 IntrospectionAccessStatic_Impl* pStaticImpl = implInspect( aToInspectObj ); 1959 if( pStaticImpl ) 1960 xAccess = new ImplIntrospectionAccess( aToInspectObj, pStaticImpl ); 1961 } 1962 1963 return xAccess; 1964 } 1965 1966 //----------------------------------------------------------------------------- 1967 1968 // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces 1969 struct hashInterface_Impl 1970 { 1971 size_t operator()(const void* p) const 1972 { 1973 return (size_t)p; 1974 } 1975 }; 1976 1977 struct eqInterface_Impl 1978 { 1979 bool operator()(const void* p1, const void* p2) const 1980 { 1981 return ( p1 == p2 ); 1982 } 1983 }; 1984 1985 typedef std::hash_map 1986 < 1987 void*, 1988 void*, 1989 hashInterface_Impl, 1990 eqInterface_Impl 1991 > 1992 CheckedInterfacesMap; 1993 1994 1995 1996 // TODO: Spaeter auslagern 1997 Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr ) 1998 { 1999 static Reference< XIdlReflection > xRefl; 2000 2001 // void als Default-Klasse eintragen 2002 Reference<XIdlClass> xRetClass; 2003 typelib_TypeDescription * pTD = 0; 2004 rType.getDescription( &pTD ); 2005 if( pTD ) 2006 { 2007 ::rtl::OUString sOWName( pTD->pTypeName ); 2008 if( !xRefl.is() ) 2009 { 2010 xRefl = Reference< XIdlReflection >( xMgr->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) ), UNO_QUERY ); 2011 OSL_ENSURE( xRefl.is(), "### no corereflection!" ); 2012 } 2013 xRetClass = xRefl->forName( sOWName ); 2014 } 2015 return xRetClass; 2016 } 2017 2018 // Implementation der Introspection. 2019 IntrospectionAccessStatic_Impl* ImplIntrospection::implInspect(const Any& aToInspectObj) 2020 { 2021 MutexGuard aGuard( m_mutex ); 2022 2023 // Wenn die Introspection schon disposed ist, wird nur ein leeres Ergebnis geliefert 2024 if( mbDisposed ) 2025 return NULL; 2026 2027 // Objekt untersuchen 2028 TypeClass eType = aToInspectObj.getValueType().getTypeClass(); 2029 if( eType != TypeClass_INTERFACE && eType != TypeClass_STRUCT && eType != TypeClass_EXCEPTION ) 2030 return NULL; 2031 2032 Reference<XInterface> x; 2033 if( eType == TypeClass_INTERFACE ) 2034 { 2035 // Interface aus dem Any besorgen 2036 x = *(Reference<XInterface>*)aToInspectObj.getValue(); 2037 if( !x.is() ) 2038 return NULL; 2039 } 2040 2041 #ifdef USE_INTROSPECTION_CACHE 2042 // Haben wir schon eine Cache-Instanz 2043 if( !mpCache ) 2044 mpCache = new IntrospectionAccessCacheMap; 2045 if( !mpTypeProviderCache ) 2046 mpTypeProviderCache = new TypeProviderAccessCacheMap; 2047 IntrospectionAccessCacheMap& aCache = *mpCache; 2048 TypeProviderAccessCacheMap& aTPCache = *mpTypeProviderCache; 2049 2050 // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz 2051 IntrospectionAccessStatic_Impl* pAccess = NULL; 2052 #else 2053 // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz 2054 IntrospectionAccessStatic_Impl* pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection ); 2055 #endif 2056 2057 // Pruefen: Ist schon ein passendes Access-Objekt gecached? 2058 Sequence< Reference<XIdlClass> > SupportedClassSeq; 2059 Sequence< Type > SupportedTypesSeq; 2060 Reference<XIdlClassProvider> xClassProvider; 2061 Reference<XTypeProvider> xTypeProvider; 2062 Reference<XIdlClass> xImplClass; 2063 Reference<XPropertySetInfo> xPropSetInfo; 2064 Reference<XPropertySet> xPropSet; 2065 2066 // Bei Interfaces XTypeProvider / XIdlClassProvider- und PropertySet-Interface anfordern 2067 if( eType == TypeClass_INTERFACE ) 2068 { 2069 // XIdlClassProvider 2070 xTypeProvider = Reference<XTypeProvider>::query( x ); 2071 if( xTypeProvider.is() ) 2072 { 2073 SupportedTypesSeq = xTypeProvider->getTypes(); 2074 sal_Int32 nTypeCount = SupportedTypesSeq.getLength(); 2075 if( nTypeCount ) 2076 { 2077 SupportedClassSeq.realloc( nTypeCount ); 2078 Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray(); 2079 2080 const Type* pTypes = SupportedTypesSeq.getConstArray(); 2081 for( sal_Int32 i = 0 ; i < nTypeCount ; i++ ) 2082 { 2083 pClasses[ i ] = TypeToIdlClass( pTypes[ i ], m_xSMgr ); 2084 } 2085 // TODO: Caching! 2086 } 2087 } 2088 else 2089 { 2090 // XIdlClassProvider 2091 xClassProvider = Reference<XIdlClassProvider>::query( x ); 2092 if( xClassProvider.is() ) 2093 { 2094 SupportedClassSeq = xClassProvider->getIdlClasses(); 2095 if( SupportedClassSeq.getLength() ) 2096 xImplClass = SupportedClassSeq.getConstArray()[0]; 2097 } 2098 } 2099 // #70197, fuer InvocationAdapter: Interface-Typ im Any auch ohne 2100 // ClassProvider unterstuetzen 2101 if( !xClassProvider.is() && !xTypeProvider.is() ) 2102 { 2103 xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr ); 2104 SupportedClassSeq.realloc( 1 ); 2105 SupportedClassSeq.getArray()[ 0 ] = xImplClass; 2106 } 2107 2108 xPropSet = Reference<XPropertySet>::query( x ); 2109 // Jetzt versuchen, das PropertySetInfo zu bekommen 2110 if( xPropSet.is() ) 2111 xPropSetInfo = xPropSet->getPropertySetInfo(); 2112 } 2113 else 2114 { 2115 xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr ); 2116 } 2117 2118 #ifdef USE_INTROSPECTION_CACHE 2119 if( xTypeProvider.is() ) 2120 { 2121 Sequence< sal_Int8 > aImpIdSeq = xTypeProvider->getImplementationId(); 2122 sal_Int32 nIdLen = aImpIdSeq.getLength(); 2123 2124 if( nIdLen ) 2125 { 2126 // cache only, if the descriptor class is set 2127 hashTypeProviderKey_Impl aKeySeq( xPropSetInfo, aImpIdSeq ); 2128 2129 TypeProviderAccessCacheMap::iterator aIt = aTPCache.find( aKeySeq ); 2130 if( aIt == aTPCache.end() ) 2131 { 2132 // not found 2133 // Neue Instanz anlegen und unter dem gegebenen Key einfuegen 2134 pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection ); 2135 2136 // RefCount von Hand erhoehen, muss beim Entfernen 2137 // aus der Hashtable wieder released werden 2138 pAccess->acquire(); 2139 2140 // Groesse begrenzen, alten Eintrag wieder rausschmeissen 2141 if( mnTPCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE ) 2142 { 2143 // Access mit dem kleinsten HitCount suchen 2144 TypeProviderAccessCacheMap::iterator iter = aTPCache.begin(); 2145 TypeProviderAccessCacheMap::iterator end = aTPCache.end(); 2146 TypeProviderAccessCacheMap::iterator toDelete = iter; 2147 while( iter != end ) 2148 { 2149 if( (*iter).first.nHitCount < (*toDelete).first.nHitCount ) 2150 toDelete = iter; 2151 ++iter; 2152 } 2153 2154 // Gefundenen Eintrag entfernen 2155 if( (*toDelete).second ) 2156 (*toDelete).second->release(); 2157 (*toDelete).second = NULL; 2158 aTPCache.erase( toDelete ); 2159 } 2160 else 2161 mnTPCacheEntryCount++; 2162 2163 // Neuer Eintrage rein in die Table 2164 aKeySeq.nHitCount = 1; 2165 aTPCache[ aKeySeq ] = pAccess; 2166 2167 } 2168 else 2169 { 2170 // Hit-Count erhoehen 2171 (*aIt).first.IncHitCount(); 2172 return (*aIt).second; 2173 } 2174 } 2175 } 2176 else if( xImplClass.is() ) 2177 { 2178 // cache only, if the descriptor class is set 2179 hashIntrospectionKey_Impl aKeySeq( SupportedClassSeq, xPropSetInfo, xImplClass ); 2180 2181 IntrospectionAccessCacheMap::iterator aIt = aCache.find( aKeySeq ); 2182 if( aIt == aCache.end() ) 2183 { 2184 // not found 2185 // Neue Instanz anlegen und unter dem gegebenen Key einfuegen 2186 pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection ); 2187 2188 // RefCount von Hand erhoehen, muss beim Entfernen 2189 // aus der Hashtable wieder released werden 2190 pAccess->acquire(); 2191 2192 // Groesse begrenzen, alten Eintrag wieder rausschmeissen 2193 if( mnCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE ) 2194 { 2195 // Access mit dem kleinsten HitCount suchen 2196 IntrospectionAccessCacheMap::iterator iter = aCache.begin(); 2197 IntrospectionAccessCacheMap::iterator end = aCache.end(); 2198 IntrospectionAccessCacheMap::iterator toDelete = iter; 2199 while( iter != end ) 2200 { 2201 if( (*iter).first.nHitCount < (*toDelete).first.nHitCount ) 2202 toDelete = iter; 2203 ++iter; 2204 } 2205 2206 // Gefundenen Eintrag entfernen 2207 if( (*toDelete).second ) 2208 (*toDelete).second->release(); 2209 (*toDelete).second = NULL; 2210 aCache.erase( toDelete ); 2211 } 2212 else 2213 mnCacheEntryCount++; 2214 2215 // Neuer Eintrage rein in die Table 2216 aKeySeq.nHitCount = 1; 2217 aCache[ aKeySeq ] = pAccess; 2218 2219 } 2220 else 2221 { 2222 // Hit-Count erhoehen 2223 (*aIt).first.IncHitCount(); 2224 return (*aIt).second; 2225 } 2226 } 2227 #endif 2228 2229 // Kein Access gecached -> neu anlegen 2230 Property* pAllPropArray; 2231 Reference<XInterface>* pInterfaces1; 2232 Reference<XInterface>* pInterfaces2; 2233 sal_Int16* pMapTypeArray; 2234 sal_Int32* pPropertyConceptArray; 2235 sal_Int32 i; 2236 2237 if( !pAccess ) 2238 pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection ); 2239 2240 // Referenzen auf wichtige Daten von pAccess 2241 sal_Int32& rPropCount = pAccess->mnPropCount; 2242 IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap; 2243 IntrospectionNameMap& rMethodNameMap = pAccess->maMethodNameMap; 2244 LowerToExactNameMap& rLowerToExactNameMap = pAccess->maLowerToExactNameMap; 2245 2246 // Schon mal Pointer auf das eigene Property-Feld holen 2247 pAllPropArray = pAccess->maAllPropertySeq.getArray(); 2248 pInterfaces1 = pAccess->aInterfaceSeq1.getArray(); 2249 pInterfaces2 = pAccess->aInterfaceSeq2.getArray(); 2250 pMapTypeArray = pAccess->maMapTypeSeq.getArray(); 2251 pPropertyConceptArray = pAccess->maPropertyConceptSeq.getArray(); 2252 2253 //************************* 2254 //*** Analyse vornehmen *** 2255 //************************* 2256 if( eType == TypeClass_INTERFACE ) 2257 { 2258 // Zunaechst nach speziellen Interfaces suchen, die fuer 2259 // die Introspection von besonderer Bedeutung sind. 2260 2261 // XPropertySet vorhanden? 2262 if( xPropSet.is() && xPropSetInfo.is() ) 2263 { 2264 // Gibt es auch ein FastPropertySet? 2265 Reference<XFastPropertySet> xDummy = Reference<XFastPropertySet>::query( x ); 2266 sal_Bool bFast = pAccess->mbFastPropSet = xDummy.is(); 2267 2268 Sequence<Property> aPropSeq = xPropSetInfo->getProperties(); 2269 const Property* pProps = aPropSeq.getConstArray(); 2270 sal_Int32 nLen = aPropSeq.getLength(); 2271 2272 // Bei FastPropertySet muessen wir uns die Original-Handles merken 2273 if( bFast ) 2274 pAccess->mpOrgPropertyHandleArray = new sal_Int32[ nLen ]; 2275 2276 for( i = 0 ; i < nLen ; i++ ) 2277 { 2278 // Property in eigene Liste uebernehmen 2279 pAccess->checkPropertyArraysSize 2280 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount ); 2281 Property& rProp = pAllPropArray[ rPropCount ]; 2282 rProp = pProps[ i ]; 2283 2284 if( bFast ) 2285 pAccess->mpOrgPropertyHandleArray[ i ] = rProp.Handle; 2286 2287 // PropCount als Handle fuer das eigene FastPropertySet eintragen 2288 rProp.Handle = rPropCount; 2289 2290 // Art der Property merken 2291 pMapTypeArray[ rPropCount ] = MAP_PROPERTY_SET; 2292 pPropertyConceptArray[ rPropCount ] = PROPERTYSET; 2293 pAccess->mnPropertySetPropCount++; 2294 2295 // Namen in Hashtable eintragen, wenn nicht schon bekannt 2296 ::rtl::OUString aPropName = rProp.Name; 2297 2298 // Haben wir den Namen schon? 2299 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName ); 2300 if( aIt == rPropNameMap.end() ) 2301 { 2302 // Neuer Eintrag in die Hashtable 2303 rPropNameMap[ aPropName ] = rPropCount; 2304 2305 // Tabelle fuer XExactName pflegen 2306 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName; 2307 } 2308 else 2309 { 2310 OSL_ENSURE( sal_False, 2311 ::rtl::OString( "Introspection: Property \"" ) + 2312 ::rtl::OUStringToOString( aPropName, RTL_TEXTENCODING_ASCII_US ) + 2313 ::rtl::OString( "\" found more than once in PropertySet" ) ); 2314 } 2315 2316 // Count pflegen 2317 rPropCount++; 2318 } 2319 } 2320 2321 2322 // Jetzt alle weiteren implementierten Interfaces durchgehen 2323 // Diese muessen durch das XIdlClassProvider-Interface geliefert werden. 2324 // #70197, fuer InvocationAdapter: Interface-Typ im Any auch ohne 2325 // ClassProvider unterstuetzen 2326 //if( xClassProvider.is() ) 2327 { 2328 // Indizes in die Export-Tabellen 2329 sal_Int32 iAllExportedMethod = 0; 2330 sal_Int32 iAllSupportedListener = 0; 2331 2332 // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces 2333 CheckedInterfacesMap aCheckedInterfacesMap; 2334 2335 // Flag, ob XInterface-Methoden erfasst werden sollen 2336 // (das darf nur einmal erfolgen, initial zulassen) 2337 sal_Bool bXInterfaceIsInvalid = sal_False; 2338 2339 // Flag, ob die XInterface-Methoden schon erfasst wurden. Wenn sal_True, 2340 // wird bXInterfaceIsInvalid am Ende der Iface-Schleife aktiviert und 2341 // XInterface-Methoden werden danach abgeklemmt. 2342 sal_Bool bFoundXInterface = sal_False; 2343 2344 // Schleife ueber alle vom ClassProvider angegebenen Klassen 2345 sal_Int32 nClassCount = SupportedClassSeq.getLength(); 2346 for( sal_Int32 nIdx = 0 ; nIdx < nClassCount; nIdx++ ) 2347 { 2348 Reference<XIdlClass> xImplClass2 = SupportedClassSeq.getConstArray()[nIdx]; 2349 while( xImplClass2.is() ) 2350 { 2351 // Interfaces der Implementation holen 2352 Sequence< Reference<XIdlClass> > aClassSeq = xImplClass2->getInterfaces(); 2353 sal_Int32 nIfaceCount = aClassSeq.getLength(); 2354 2355 aClassSeq.realloc( nIfaceCount + 1 ); 2356 aClassSeq.getArray()[ nIfaceCount ] = xImplClass2; 2357 nIfaceCount++; 2358 2359 const Reference<XIdlClass>* pParamArray = aClassSeq.getConstArray(); 2360 2361 for( sal_Int32 j = 0 ; j < nIfaceCount ; j++ ) 2362 { 2363 const Reference<XIdlClass>& rxIfaceClass = pParamArray[j]; 2364 2365 // Pruefen, ob das Interface schon beruecksichtigt wurde. 2366 XInterface* pIface = SAL_STATIC_CAST( XInterface*, rxIfaceClass.get() ); 2367 if( aCheckedInterfacesMap.count( pIface ) > 0 ) 2368 { 2369 // Kennen wir schon 2370 continue; 2371 } 2372 else 2373 { 2374 // Sonst eintragen 2375 aCheckedInterfacesMap[ pIface ] = pIface; 2376 } 2377 2378 //******************************************************************** 2379 2380 // 2. Fields als Properties registrieren 2381 2382 // Felder holen 2383 Sequence< Reference<XIdlField> > fields = rxIfaceClass->getFields(); 2384 const Reference<XIdlField>* pFields = fields.getConstArray(); 2385 sal_Int32 nLen = fields.getLength(); 2386 2387 for( i = 0 ; i < nLen ; i++ ) 2388 { 2389 Reference<XIdlField> xField = pFields[i]; 2390 Reference<XIdlClass> xPropType = xField->getType(); 2391 2392 // Ist die PropertySequence gross genug? 2393 pAccess->checkPropertyArraysSize 2394 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount ); 2395 2396 // In eigenes Property-Array eintragen 2397 Property& rProp = pAllPropArray[ rPropCount ]; 2398 ::rtl::OUString aFieldName = xField->getName(); 2399 rProp.Name = aFieldName; 2400 rProp.Handle = rPropCount; 2401 Type aFieldType( xPropType->getTypeClass(), xPropType->getName() ); 2402 rProp.Type = aFieldType; 2403 FieldAccessMode eAccessMode = xField->getAccessMode(); 2404 rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY || 2405 eAccessMode == FieldAccessMode_CONST) 2406 ? READONLY : 0; 2407 2408 // Namen in Hashtable eintragen 2409 ::rtl::OUString aPropName = rProp.Name; 2410 2411 // Haben wir den Namen schon? 2412 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName ); 2413 if( !( aIt == rPropNameMap.end() ) ) 2414 { 2415 /* TODO 2416 OSL_TRACE( 2417 String( "Introspection: Property \"" ) + 2418 OOUStringToString( aPropName, CHARSET_SYSTEM ) + 2419 String( "\" found more than once" ) ); 2420 */ 2421 continue; 2422 } 2423 2424 // Neuer Eintrag in die Hashtable 2425 rPropNameMap[ aPropName ] = rPropCount; 2426 2427 // Tabelle fuer XExactName pflegen 2428 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName; 2429 2430 // Field merken 2431 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1, 2432 pInterfaces1, rPropCount ); 2433 pInterfaces1[ rPropCount ] = xField; 2434 2435 // Art der Property merken 2436 pMapTypeArray[ rPropCount ] = MAP_FIELD; 2437 pPropertyConceptArray[ rPropCount ] = ATTRIBUTES; 2438 pAccess->mnAttributePropCount++; 2439 2440 // Count pflegen 2441 rPropCount++; 2442 } 2443 2444 //******************************************************************** 2445 2446 // 3. Methoden 2447 2448 // Zaehler fuer die gefundenen Listener 2449 sal_Int32 nListenerCount = 0; 2450 2451 // Alle Methoden holen und merken 2452 Sequence< Reference<XIdlMethod> > methods = rxIfaceClass->getMethods(); 2453 const Reference<XIdlMethod>* pSourceMethods = methods.getConstArray(); 2454 sal_Int32 nSourceMethodCount = methods.getLength(); 2455 2456 // 3. a) get/set- und Listener-Methoden suchen 2457 2458 // Feld fuer Infos ueber die Methoden anlegen, damit spaeter leicht die Methoden 2459 // gefunden werden koennen, die nicht im Zusammenhang mit Properties oder Listenern 2460 // stehen. NEU: auch MethodConceptArray initialisieren 2461 MethodType* pMethodTypes = new MethodType[ nSourceMethodCount ]; 2462 sal_Int32* pLocalMethodConcepts = new sal_Int32[ nSourceMethodCount ]; 2463 for( i = 0 ; i < nSourceMethodCount ; i++ ) 2464 { 2465 pMethodTypes[ i ] = STANDARD_METHOD; 2466 pLocalMethodConcepts[ i ] = 0; 2467 } 2468 2469 ::rtl::OUString aMethName; 2470 ::rtl::OUString aPropName; 2471 ::rtl::OUString aStartStr; 2472 for( i = 0 ; i < nSourceMethodCount ; i++ ) 2473 { 2474 // Methode ansprechen 2475 const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i]; 2476 sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ]; 2477 2478 // Namen besorgen 2479 aMethName = rxMethod_i->getName(); 2480 2481 // Methoden katalogisieren 2482 // Alle (?) Methoden von XInterface filtern, damit z.B. nicht 2483 // vom Scripting aus aquire oder release gerufen werden kann 2484 if( rxMethod_i->getDeclaringClass()->equals( mxInterfaceClass ) ) 2485 { 2486 // XInterface-Methoden sind hiermit einmal beruecksichtigt 2487 bFoundXInterface = sal_True; 2488 2489 if( bXInterfaceIsInvalid ) 2490 { 2491 pMethodTypes[ i ] = INVALID_METHOD; 2492 continue; 2493 } 2494 else 2495 { 2496 if( aMethName != ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("queryInterface")) ) 2497 { 2498 rMethodConcept_i |= MethodConcept::DANGEROUS; 2499 continue; 2500 } 2501 } 2502 } 2503 else if( rxMethod_i->getDeclaringClass()->equals( mxAggregationClass ) ) 2504 { 2505 if( aMethName == ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("setDelegator")) ) 2506 { 2507 rMethodConcept_i |= MethodConcept::DANGEROUS; 2508 continue; 2509 } 2510 } 2511 else if( rxMethod_i->getDeclaringClass()->equals( mxElementAccessClass ) ) 2512 { 2513 rMethodConcept_i |= ( NAMECONTAINER | 2514 INDEXCONTAINER | 2515 ENUMERATION ); 2516 } 2517 else if( rxMethod_i->getDeclaringClass()->equals( mxNameContainerClass ) || 2518 rxMethod_i->getDeclaringClass()->equals( mxNameAccessClass ) ) 2519 { 2520 rMethodConcept_i |= NAMECONTAINER; 2521 } 2522 else if( rxMethod_i->getDeclaringClass()->equals( mxIndexContainerClass ) || 2523 rxMethod_i->getDeclaringClass()->equals( mxIndexAccessClass ) ) 2524 { 2525 rMethodConcept_i |= INDEXCONTAINER; 2526 } 2527 else if( rxMethod_i->getDeclaringClass()->equals( mxEnumerationAccessClass ) ) 2528 { 2529 rMethodConcept_i |= ENUMERATION; 2530 } 2531 2532 // Wenn der Name zu kurz ist, wird's sowieso nichts 2533 if( aMethName.getLength() <= 3 ) 2534 continue; 2535 2536 // Ist es eine get-Methode? 2537 aStartStr = aMethName.copy( 0, 3 ); 2538 if( aStartStr == ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("get")) ) 2539 { 2540 // Namen der potentiellen Property 2541 aPropName = aMethName.copy( 3 ); 2542 2543 // get-Methode darf keinen Parameter haben 2544 Sequence< Reference<XIdlClass> > getParams = rxMethod_i->getParameterTypes(); 2545 if( getParams.getLength() > 0 ) 2546 { 2547 continue; 2548 } 2549 2550 // Haben wir den Namen schon? 2551 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName ); 2552 if( !( aIt == rPropNameMap.end() ) ) 2553 { 2554 /* TODO 2555 OSL_TRACE( 2556 String( "Introspection: Property \"" ) + 2557 OOUStringToString( aPropName, CHARSET_SYSTEM ) + 2558 String( "\" found more than once" ) ); 2559 */ 2560 continue; 2561 } 2562 2563 // Eine readonly-Property ist es jetzt mindestens schon 2564 rMethodConcept_i |= PROPERTY; 2565 2566 pMethodTypes[i] = GETSET_METHOD; 2567 Reference<XIdlClass> xGetRetType = rxMethod_i->getReturnType(); 2568 2569 // Ist die PropertySequence gross genug? 2570 pAccess->checkPropertyArraysSize 2571 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount ); 2572 2573 // In eigenes Property-Array eintragen 2574 Property& rProp = pAllPropArray[ rPropCount ]; 2575 rProp.Name = aPropName; 2576 rProp.Handle = rPropCount; 2577 rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() ); 2578 rProp.Attributes = READONLY; 2579 2580 // Neuer Eintrag in die Hashtable 2581 rPropNameMap[ aPropName ] = rPropCount; 2582 2583 // Tabelle fuer XExactName pflegen 2584 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName; 2585 2586 // get-Methode merken 2587 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1, 2588 pInterfaces1, rPropCount ); 2589 pInterfaces1[ rPropCount ] = rxMethod_i; 2590 2591 // Art der Property merken 2592 pMapTypeArray[ rPropCount ] = MAP_GETSET; 2593 pPropertyConceptArray[ rPropCount ] = METHODS; 2594 pAccess->mnMethodPropCount++; 2595 2596 // Passende set-Methode suchen 2597 sal_Int32 k; 2598 for( k = 0 ; k < nSourceMethodCount ; k++ ) 2599 { 2600 // Methode ansprechen 2601 const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k]; 2602 2603 // Nur Methoden nehmen, die nicht schon zugeordnet sind 2604 if( k == i || pMethodTypes[k] != STANDARD_METHOD ) 2605 continue; 2606 2607 // Name holen und auswerten 2608 ::rtl::OUString aMethName2 = rxMethod_k->getName(); 2609 ::rtl::OUString aStartStr2 = aMethName2.copy( 0, 3 ); 2610 // ACHTUNG: Wegen SDL-Bug NICHT != bei ::rtl::OUString verwenden !!! 2611 if( !( aStartStr2 == ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("set")) ) ) 2612 continue; 2613 2614 // Ist es denn der gleiche Name? 2615 ::rtl::OUString aPropName2 = aMethName2.copy( 3 ); 2616 // ACHTUNG: Wegen SDL-Bug NICHT != bei ::rtl::OUString verwenden !!! 2617 if( !( aPropName == aPropName2 ) ) 2618 continue; 2619 2620 // set-Methode muss void returnen 2621 Reference<XIdlClass> xSetRetType = rxMethod_k->getReturnType(); 2622 if( xSetRetType->getTypeClass() != TypeClass_VOID ) 2623 { 2624 continue; 2625 } 2626 2627 // set-Methode darf nur einen Parameter haben 2628 Sequence< Reference<XIdlClass> > setParams = rxMethod_k->getParameterTypes(); 2629 sal_Int32 nParamCount = setParams.getLength(); 2630 if( nParamCount != 1 ) 2631 { 2632 continue; 2633 } 2634 2635 // Jetzt muss nur noch der return-Typ dem Parameter-Typ entsprechen 2636 const Reference<XIdlClass>* pParamArray2 = setParams.getConstArray(); 2637 Reference<XIdlClass> xParamType = pParamArray2[ 0 ]; 2638 if( xParamType->equals( xGetRetType ) ) 2639 { 2640 pLocalMethodConcepts[ k ] = PROPERTY; 2641 2642 pMethodTypes[k] = GETSET_METHOD; 2643 2644 // ReadOnly-Flag wieder loschen 2645 rProp.Attributes &= ~READONLY; 2646 2647 // set-Methode merken 2648 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2, 2649 pInterfaces2, rPropCount ); 2650 pInterfaces2[ rPropCount ] = rxMethod_k; 2651 } 2652 } 2653 2654 // Count pflegen 2655 rPropCount++; 2656 } 2657 2658 // Ist es eine addListener-Methode? 2659 else if( aStartStr == ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("add")) ) 2660 { 2661 ::rtl::OUString aListenerStr( RTL_CONSTASCII_USTRINGPARAM("Listener" ) ); 2662 2663 // Namen der potentiellen Property 2664 sal_Int32 nStrLen = aMethName.getLength(); 2665 sal_Int32 nCopyLen = nStrLen - aListenerStr.getLength(); 2666 ::rtl::OUString aEndStr = aMethName.copy( nCopyLen > 0 ? nCopyLen : 0 ); 2667 2668 // Endet das Teil auf Listener? 2669 // ACHTUNG: Wegen SDL-Bug NICHT != bei ::rtl::OUString verwenden !!! 2670 if( !( aEndStr == aListenerStr ) ) 2671 continue; 2672 2673 // Welcher Listener? 2674 ::rtl::OUString aListenerName = aMethName.copy( 3, nStrLen - aListenerStr.getLength() - 3 ); 2675 2676 // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden 2677 // - Rueckgabe-Typ 2678 // - Anzahl und Art der Parameter 2679 2680 2681 // Passende remove-Methode suchen, sonst gilt's nicht 2682 sal_Int32 k; 2683 for( k = 0 ; k < nSourceMethodCount ; k++ ) 2684 { 2685 // Methode ansprechen 2686 const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k]; 2687 2688 // Nur Methoden nehmen, die nicht schon zugeordnet sind 2689 if( k == i || pMethodTypes[k] != STANDARD_METHOD ) 2690 continue; 2691 2692 // Name holen und auswerten 2693 ::rtl::OUString aMethName2 = rxMethod_k->getName(); 2694 sal_Int32 nNameLen = aMethName2.getLength(); 2695 sal_Int32 nCopyLen2 = (nNameLen < 6) ? nNameLen : 6; 2696 ::rtl::OUString aStartStr2 = aMethName2.copy( 0, nCopyLen2 ); 2697 ::rtl::OUString aRemoveStr( RTL_CONSTASCII_USTRINGPARAM("remove" ) ); 2698 // ACHTUNG: Wegen SDL-Bug NICHT != bei ::rtl::OUString verwenden !!! 2699 if( !( aStartStr2 == aRemoveStr ) ) 2700 continue; 2701 2702 // Ist es denn der gleiche Listener? 2703 if( aMethName2.getLength() - aRemoveStr.getLength() <= aListenerStr.getLength() ) 2704 continue; 2705 ::rtl::OUString aListenerName2 = aMethName2.copy 2706 ( 6, aMethName2.getLength() - aRemoveStr.getLength() - aListenerStr.getLength() ); 2707 // ACHTUNG: Wegen SDL-Bug NICHT != bei ::rtl::OUString verwenden !!! 2708 if( !( aListenerName == aListenerName2 ) ) 2709 continue; 2710 2711 // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden 2712 // - Rueckgabe-Typ 2713 // - Anzahl und Art der Parameter 2714 2715 2716 // Methoden sind als Listener-Schnittstelle erkannt 2717 rMethodConcept_i |= LISTENER; 2718 pLocalMethodConcepts[ k ] |= LISTENER; 2719 2720 pMethodTypes[i] = ADD_LISTENER_METHOD; 2721 pMethodTypes[k] = REMOVE_LISTENER_METHOD; 2722 nListenerCount++; 2723 } 2724 } 2725 } 2726 2727 2728 // Jetzt koennen noch SET-Methoden ohne zugehoerige GET-Methode existieren, 2729 // diese muessen zu Write-Only-Properties gemachte werden. 2730 for( i = 0 ; i < nSourceMethodCount ; i++ ) 2731 { 2732 // Methode ansprechen 2733 const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i]; 2734 2735 // Nur Methoden nehmen, die nicht schon zugeordnet sind 2736 if( pMethodTypes[i] != STANDARD_METHOD ) 2737 continue; 2738 2739 // Namen besorgen 2740 aMethName = rxMethod_i->getName(); 2741 2742 // Wenn der Name zu kurz ist, wird's sowieso nichts 2743 if( aMethName.getLength() <= 3 ) 2744 continue; 2745 2746 // Ist es eine set-Methode ohne zugehoerige get-Methode? 2747 aStartStr = aMethName.copy( 0, 3 ); 2748 if( aStartStr == ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("set")) ) 2749 { 2750 // Namen der potentiellen Property 2751 aPropName = aMethName.copy( 3 ); 2752 2753 // set-Methode muss void returnen 2754 Reference<XIdlClass> xSetRetType = rxMethod_i->getReturnType(); 2755 if( xSetRetType->getTypeClass() != TypeClass_VOID ) 2756 { 2757 continue; 2758 } 2759 2760 // set-Methode darf nur einen Parameter haben 2761 Sequence< Reference<XIdlClass> > setParams = rxMethod_i->getParameterTypes(); 2762 sal_Int32 nParamCount = setParams.getLength(); 2763 if( nParamCount != 1 ) 2764 { 2765 continue; 2766 } 2767 2768 // Haben wir den Namen schon? 2769 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName ); 2770 if( !( aIt == rPropNameMap.end() ) ) 2771 { 2772 /* TODO: 2773 OSL_TRACE( 2774 String( "Introspection: Property \"" ) + 2775 OOUStringToString( aPropName, CHARSET_SYSTEM ) + 2776 String( "\" found more than once" ) ); 2777 */ 2778 continue; 2779 } 2780 2781 // Alles klar, es ist eine Write-Only-Property 2782 pLocalMethodConcepts[ i ] = PROPERTY; 2783 2784 pMethodTypes[i] = GETSET_METHOD; 2785 Reference<XIdlClass> xGetRetType = setParams.getConstArray()[0]; 2786 2787 // Ist die PropertySequence gross genug? 2788 pAccess->checkPropertyArraysSize 2789 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount ); 2790 2791 // In eigenes Property-Array eintragen 2792 Property& rProp = pAllPropArray[ rPropCount ]; 2793 rProp.Name = aPropName; 2794 rProp.Handle = rPropCount; 2795 rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() ); 2796 rProp.Attributes = 0; // PROPERTY_WRITEONLY ??? 2797 2798 // Neuer Eintrag in die Hashtable 2799 rPropNameMap[ aPropName ] = rPropCount; 2800 2801 // Tabelle fuer XExactName pflegen 2802 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName; 2803 2804 // set-Methode merken 2805 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2, 2806 pInterfaces2, rPropCount ); 2807 pInterfaces2[ rPropCount ] = rxMethod_i; 2808 2809 // Art der Property merken 2810 pMapTypeArray[ rPropCount ] = MAP_SETONLY; 2811 pPropertyConceptArray[ rPropCount ] = METHODS; 2812 pAccess->mnMethodPropCount++; 2813 2814 // Count pflegen 2815 rPropCount++; 2816 } 2817 } 2818 2819 2820 //******************************************************************** 2821 2822 // 4. Methoden in die Gesamt-Sequence uebernehmen 2823 2824 // Wieviele Methoden muessen in die Method-Sequence? 2825 sal_Int32 nExportedMethodCount = 0; 2826 sal_Int32 nSupportedListenerCount = 0; 2827 for( i = 0 ; i < nSourceMethodCount ; i++ ) 2828 { 2829 if( pMethodTypes[ i ] != INVALID_METHOD ) 2830 { 2831 nExportedMethodCount++; 2832 } 2833 if( pMethodTypes[ i ] == ADD_LISTENER_METHOD ) 2834 { 2835 nSupportedListenerCount++; 2836 } 2837 } 2838 2839 // Sequences im Access-Objekt entsprechend aufbohren 2840 pAccess->maAllMethodSeq.realloc( nExportedMethodCount + iAllExportedMethod ); 2841 pAccess->maMethodConceptSeq.realloc( nExportedMethodCount + iAllExportedMethod ); 2842 pAccess->maSupportedListenerSeq.realloc( nSupportedListenerCount + iAllSupportedListener ); 2843 2844 // Methoden reinschreiben 2845 Reference<XIdlMethod>* pDestMethods = pAccess->maAllMethodSeq.getArray(); 2846 sal_Int32* pMethodConceptArray = pAccess->maMethodConceptSeq.getArray(); 2847 Type* pListenerClassRefs = pAccess->maSupportedListenerSeq.getArray(); 2848 for( i = 0 ; i < nSourceMethodCount ; i++ ) 2849 { 2850 if( pMethodTypes[ i ] != INVALID_METHOD ) 2851 { 2852 // Methode ansprechen 2853 const Reference<XIdlMethod>& rxMethod = pSourceMethods[i]; 2854 2855 // Namen in Hashtable eintragen, wenn nicht schon bekannt 2856 ::rtl::OUString aMethName2 = rxMethod->getName(); 2857 IntrospectionNameMap::iterator aIt = rMethodNameMap.find( aMethName2 ); 2858 if( aIt == rMethodNameMap.end() ) 2859 { 2860 // Eintragen 2861 rMethodNameMap[ aMethName2 ] = iAllExportedMethod; 2862 2863 // Tabelle fuer XExactName pflegen 2864 rLowerToExactNameMap[ toLower( aMethName2 ) ] = aMethName2; 2865 } 2866 else 2867 { 2868 sal_Int32 iHashResult = (*aIt).second; 2869 2870 Reference<XIdlMethod> xExistingMethod = pDestMethods[ iHashResult ]; 2871 2872 Reference< XIdlClass > xExistingMethClass = 2873 xExistingMethod->getDeclaringClass(); 2874 Reference< XIdlClass > xNewMethClass = rxMethod->getDeclaringClass(); 2875 if( xExistingMethClass->equals( xNewMethClass ) ) 2876 continue; 2877 } 2878 2879 pDestMethods[ iAllExportedMethod ] = rxMethod; 2880 2881 // Wenn kein Concept gesetzt wurde, ist die Methode "normal" 2882 sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ]; 2883 if( !rMethodConcept_i ) 2884 rMethodConcept_i = MethodConcept_NORMAL_IMPL; 2885 pMethodConceptArray[ iAllExportedMethod ] = rMethodConcept_i; 2886 iAllExportedMethod++; 2887 } 2888 if( pMethodTypes[ i ] == ADD_LISTENER_METHOD ) 2889 { 2890 // Klasse des Listeners ermitteln 2891 const Reference<XIdlMethod>& rxMethod = pSourceMethods[i]; 2892 2893 // void als Default-Klasse eintragen 2894 Reference<XIdlClass> xListenerClass = TypeToIdlClass( getCppuVoidType(), m_xSMgr ); 2895 // ALT: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass(); 2896 2897 // 1. Moeglichkeit: Parameter nach einer Listener-Klasse durchsuchen 2898 // Nachteil: Superklassen muessen rekursiv durchsucht werden 2899 Sequence< Reference<XIdlClass> > aParams = rxMethod->getParameterTypes(); 2900 const Reference<XIdlClass>* pParamArray2 = aParams.getConstArray(); 2901 2902 Reference<XIdlClass> xEventListenerClass = TypeToIdlClass( getCppuType( (Reference<XEventListener>*) NULL ), m_xSMgr ); 2903 // ALT: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass(); 2904 sal_Int32 nParamCount = aParams.getLength(); 2905 sal_Int32 k; 2906 for( k = 0 ; k < nParamCount ; k++ ) 2907 { 2908 const Reference<XIdlClass>& rxClass = pParamArray2[k]; 2909 2910 // Sind wir von einem Listener abgeleitet? 2911 if( rxClass->equals( xEventListenerClass ) || 2912 isDerivedFrom( rxClass, xEventListenerClass ) ) 2913 { 2914 xListenerClass = rxClass; 2915 break; 2916 } 2917 } 2918 2919 // 2. Moeglichkeit: Namen der Methode auswerden 2920 // Nachteil: geht nicht bei Test-Listenern, die es nicht gibt 2921 //aMethName = rxMethod->getName(); 2922 //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 ); 2923 //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName ); 2924 Type aListenerType( TypeClass_INTERFACE, xListenerClass->getName() ); 2925 pListenerClassRefs[ iAllSupportedListener ] = aListenerType; 2926 iAllSupportedListener++; 2927 } 2928 } 2929 2930 // Wenn in diesem Durchlauf XInterface-Methoden 2931 // dabei waren, diese zukuenftig ignorieren 2932 if( bFoundXInterface ) 2933 bXInterfaceIsInvalid = sal_True; 2934 2935 delete[] pMethodTypes; 2936 delete[] pLocalMethodConcepts; 2937 } 2938 2939 // Super-Klasse(n) vorhanden? Dann dort fortsetzen 2940 Sequence< Reference<XIdlClass> > aSuperClassSeq = xImplClass2->getSuperclasses(); 2941 2942 // Zur Zeit wird nur von einer Superklasse ausgegangen 2943 if( aSuperClassSeq.getLength() >= 1 ) 2944 { 2945 xImplClass2 = aSuperClassSeq.getConstArray()[0]; 2946 OSL_ENSURE( xImplClass2.is(), "super class null" ); 2947 } 2948 else 2949 { 2950 xImplClass2 = NULL; 2951 } 2952 } 2953 } 2954 2955 // Anzahl der exportierten Methoden uebernehmen und Sequences anpassen 2956 // (kann abweichen, weil doppelte Methoden erst nach der Ermittlung 2957 // von nExportedMethodCount herausgeworfen werden) 2958 sal_Int32& rMethCount = pAccess->mnMethCount; 2959 rMethCount = iAllExportedMethod; 2960 pAccess->maAllMethodSeq.realloc( rMethCount ); 2961 pAccess->maMethodConceptSeq.realloc( rMethCount ); 2962 2963 // Groesse der Property-Sequences anpassen 2964 pAccess->maAllPropertySeq.realloc( rPropCount ); 2965 pAccess->maPropertyConceptSeq.realloc( rPropCount ); 2966 pAccess->maMapTypeSeq.realloc( rPropCount ); 2967 2968 // Ende der Schleife ueber alle vom ClassProvider angegebenen Klassen 2969 } 2970 } 2971 // Bei structs Fields als Properties registrieren 2972 else //if( eType == TypeClass_STRUCT ) 2973 { 2974 // Ist es ein Interface oder eine struct? 2975 //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass(); 2976 Reference<XIdlClass> xClassRef = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr ); 2977 if( !xClassRef.is() ) 2978 { 2979 OSL_ENSURE( sal_False, "Can't get XIdlClass from Reflection" ); 2980 return pAccess; 2981 } 2982 2983 // Felder holen 2984 Sequence< Reference<XIdlField> > fields = xClassRef->getFields(); 2985 const Reference<XIdlField>* pFields = fields.getConstArray(); 2986 sal_Int32 nLen = fields.getLength(); 2987 2988 for( i = 0 ; i < nLen ; i++ ) 2989 { 2990 Reference<XIdlField> xField = pFields[i]; 2991 Reference<XIdlClass> xPropType = xField->getType(); 2992 ::rtl::OUString aPropName = xField->getName(); 2993 2994 // Ist die PropertySequence gross genug? 2995 pAccess->checkPropertyArraysSize 2996 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount ); 2997 2998 // In eigenes Property-Array eintragen 2999 Property& rProp = pAllPropArray[ rPropCount ]; 3000 rProp.Name = aPropName; 3001 rProp.Handle = rPropCount; 3002 rProp.Type = Type( xPropType->getTypeClass(), xPropType->getName() ); 3003 FieldAccessMode eAccessMode = xField->getAccessMode(); 3004 rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY || 3005 eAccessMode == FieldAccessMode_CONST) 3006 ? READONLY : 0; 3007 3008 //FieldAccessMode eAccessMode = xField->getAccessMode(); 3009 //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST) 3010 //? PropertyAttribute::READONLY : 0; 3011 3012 // Namen in Hashtable eintragen 3013 rPropNameMap[ aPropName ] = rPropCount; 3014 3015 // Tabelle fuer XExactName pflegen 3016 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName; 3017 3018 // Field merken 3019 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1, 3020 pInterfaces1, rPropCount ); 3021 pInterfaces1[ rPropCount ] = xField; 3022 3023 // Art der Property merken 3024 pMapTypeArray[ rPropCount ] = MAP_FIELD; 3025 pPropertyConceptArray[ rPropCount ] = ATTRIBUTES; 3026 pAccess->mnAttributePropCount++; 3027 3028 // Count pflegen 3029 rPropCount++; 3030 } 3031 } 3032 3033 // Property-Sequence auf die richtige Laenge bringen 3034 pAccess->maAllPropertySeq.realloc( pAccess->mnPropCount ); 3035 3036 return pAccess; 3037 } 3038 3039 //************************************************************************* 3040 Reference< XInterface > SAL_CALL ImplIntrospection_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr ) 3041 throw( RuntimeException ) 3042 { 3043 Reference< XInterface > xService = (OWeakObject*)(OComponentHelper*)new ImplIntrospection( rSMgr ); 3044 return xService; 3045 } 3046 3047 } 3048 3049 extern "C" 3050 { 3051 //================================================================================================== 3052 void SAL_CALL component_getImplementationEnvironment( 3053 const sal_Char ** ppEnvTypeName, uno_Environment ** ) 3054 { 3055 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 3056 } 3057 //================================================================================================== 3058 void * SAL_CALL component_getFactory( 3059 const sal_Char * pImplName, void * pServiceManager, void * ) 3060 { 3061 void * pRet = 0; 3062 3063 if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0) 3064 { 3065 Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory( 3066 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), 3067 ::rtl::OUString::createFromAscii( pImplName ), 3068 stoc_inspect::ImplIntrospection_CreateInstance, 3069 stoc_inspect::ImplIntrospection::getSupportedServiceNames_Static() ) ); 3070 3071 if (xFactory.is()) 3072 { 3073 xFactory->acquire(); 3074 pRet = xFactory.get(); 3075 } 3076 } 3077 3078 return pRet; 3079 } 3080 } 3081 3082 3083