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