LCOV - code coverage report
Current view: top level - stoc/source/inspect - introspection.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 772 947 81.5 %
Date: 2014-11-03 Functions: 73 104 70.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <sal/config.h>
      21             : 
      22             : #include <cassert>
      23             : #include <cstddef>
      24             : #include <limits>
      25             : #include <map>
      26             : #include <set>
      27             : 
      28             : #include <osl/diagnose.h>
      29             : #include <osl/mutex.hxx>
      30             : #include <osl/thread.h>
      31             : #include <cppuhelper/basemutex.hxx>
      32             : #include <cppuhelper/compbase2.hxx>
      33             : #include <cppuhelper/queryinterface.hxx>
      34             : #include <cppuhelper/weak.hxx>
      35             : #include <cppuhelper/component.hxx>
      36             : #include <cppuhelper/factory.hxx>
      37             : #include <cppuhelper/implbase3.hxx>
      38             : #include <cppuhelper/supportsservice.hxx>
      39             : #include <cppuhelper/typeprovider.hxx>
      40             : #include <salhelper/simplereferenceobject.hxx>
      41             : 
      42             : #include <com/sun/star/uno/DeploymentException.hpp>
      43             : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
      44             : #include <com/sun/star/lang/XServiceInfo.hpp>
      45             : #include <com/sun/star/lang/XEventListener.hpp>
      46             : #include <com/sun/star/reflection/XIdlReflection.hpp>
      47             : #include <com/sun/star/reflection/XIdlClass.hpp>
      48             : #include <com/sun/star/reflection/XIdlField2.hpp>
      49             : #include <com/sun/star/reflection/theCoreReflection.hpp>
      50             : #include <com/sun/star/beans/UnknownPropertyException.hpp>
      51             : #include <com/sun/star/beans/Property.hpp>
      52             : #include <com/sun/star/beans/XPropertySet.hpp>
      53             : #include <com/sun/star/beans/XFastPropertySet.hpp>
      54             : #include <com/sun/star/beans/XIntrospection.hpp>
      55             : #include <com/sun/star/beans/XIntrospectionAccess.hpp>
      56             : #include <com/sun/star/beans/XMaterialHolder.hpp>
      57             : #include <com/sun/star/beans/XExactName.hpp>
      58             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      59             : #include <com/sun/star/beans/PropertyConcept.hpp>
      60             : #include <com/sun/star/beans/MethodConcept.hpp>
      61             : #include <com/sun/star/container/XNameContainer.hpp>
      62             : #include <com/sun/star/container/XIndexContainer.hpp>
      63             : #include <com/sun/star/container/XEnumerationAccess.hpp>
      64             : 
      65             : #include <rtl/ref.hxx>
      66             : #include <rtl/ustrbuf.hxx>
      67             : #include <rtl/strbuf.hxx>
      68             : #include <boost/unordered_map.hpp>
      69             : 
      70             : using namespace css::uno;
      71             : using namespace css::lang;
      72             : using namespace css::reflection;
      73             : using namespace css::container;
      74             : using namespace css::registry;
      75             : using namespace css::beans;
      76             : using namespace css::beans::PropertyAttribute;
      77             : using namespace css::beans::PropertyConcept;
      78             : using namespace css::beans::MethodConcept;
      79             : using namespace cppu;
      80             : using namespace osl;
      81             : 
      82             : namespace
      83             : {
      84             : 
      85             : typedef WeakImplHelper3< XIntrospectionAccess, XMaterialHolder, XExactName > IntrospectionAccessHelper;
      86             : 
      87             : 
      88             : 
      89             : 
      90             : // Special value for Method-Concept, to be able to mark "normal" functions
      91             : #define  MethodConcept_NORMAL_IMPL        0x80000000
      92             : 
      93             : 
      94             : // Method to assert, if a class is derived from another class
      95        5356 : bool isDerivedFrom( Reference<XIdlClass> xToTestClass, Reference<XIdlClass> xDerivedFromClass )
      96             : {
      97        5356 :     Sequence< Reference<XIdlClass> > aClassesSeq = xToTestClass->getSuperclasses();
      98        5356 :     const Reference<XIdlClass>* pClassesArray = aClassesSeq.getConstArray();
      99             : 
     100        5356 :     sal_Int32 nSuperClassCount = aClassesSeq.getLength();
     101        5358 :     for ( sal_Int32 i = 0; i < nSuperClassCount; ++i )
     102             :     {
     103        4178 :         const Reference<XIdlClass>& rxClass = pClassesArray[i];
     104             : 
     105       12538 :         if ( xDerivedFromClass->equals( rxClass ) ||
     106        4186 :              isDerivedFrom( rxClass, xDerivedFromClass )
     107             :            )
     108        4176 :             return true;
     109             :     }
     110             : 
     111        1180 :     return false;
     112             : }
     113             : 
     114             : 
     115             : 
     116             : // *** Classification of Properties (no enum, to be able to use Sequence) ***
     117             : // Properties from a PropertySet-Interface
     118             : #define MAP_PROPERTY_SET    0
     119             : // Properties from Fields
     120             : #define MAP_FIELD            1
     121             : // Properties, that get described with get/set-Methods
     122             : #define MAP_GETSET            2
     123             : // Properties, with only a set-Method
     124             : #define MAP_SETONLY            3
     125             : 
     126             : 
     127             : // Increments, in which the size of Sequences get adjusted
     128             : #define ARRAY_SIZE_STEP        20
     129             : 
     130             : 
     131             : 
     132             : 
     133             : //*** IntrospectionAccessStatic_Impl ***
     134             : 
     135             : // Equals to the old IntrospectionAccessImpl, forms now a static
     136             : // part of the new Instance-related ImplIntrospectionAccess
     137             : 
     138             : // Hashtable for the search of names
     139             : typedef boost::unordered_map
     140             : <
     141             :     OUString,
     142             :     sal_Int32,
     143             :     OUStringHash
     144             : >
     145             : IntrospectionNameMap;
     146             : 
     147             : 
     148             : // Hashtable to assign exact names to the Lower-Case
     149             : // converted names, for the support of XExactName
     150             : typedef boost::unordered_map
     151             : <
     152             :     OUString,
     153             :     OUString,
     154             :     OUStringHash
     155             : >
     156             : LowerToExactNameMap;
     157             : 
     158             : 
     159             : class ImplIntrospectionAccess;
     160             : class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject
     161             : {
     162             :     friend class Implementation;
     163             :     friend class ImplIntrospectionAccess;
     164             : 
     165             :     // Holding CoreReflection
     166             :     Reference< XIdlReflection > mxCoreReflection;
     167             : 
     168             :     // InterfaceSequences, to save additional information in a property
     169             :     // for example the Field at MAP_FIELD, the get/set-Methods at MAP_GETSET, et cetera
     170             :     Sequence< Reference<XInterface> > aInterfaceSeq1;
     171             :     Sequence< Reference<XInterface> > aInterfaceSeq2;
     172             : 
     173             :     // Hashtables for names
     174             :     IntrospectionNameMap maPropertyNameMap;
     175             :     IntrospectionNameMap maMethodNameMap;
     176             :     LowerToExactNameMap  maLowerToExactNameMap;
     177             : 
     178             :     // Sequence of all Properties, also for delivering from getProperties()
     179             :     Sequence<Property> maAllPropertySeq;
     180             : 
     181             :     // Mapping of properties to Access-Types
     182             :     Sequence<sal_Int16> maMapTypeSeq;
     183             : 
     184             :     // Classification of found methods
     185             :     Sequence<sal_Int32> maPropertyConceptSeq;
     186             : 
     187             :     // Number of Properties
     188             :     sal_Int32 mnPropCount;
     189             : 
     190             :     // Number of Properties, which are assigned to particular concepts
     191             :     //sal_Int32 mnDangerousPropCount;
     192             :     sal_Int32 mnPropertySetPropCount;
     193             :     sal_Int32 mnAttributePropCount;
     194             :     sal_Int32 mnMethodPropCount;
     195             : 
     196             :     // Flag, if a FastPropertySet is supported
     197             :     bool mbFastPropSet;
     198             : 
     199             :     // Original-Handles of FastPropertySets
     200             :     sal_Int32* mpOrgPropertyHandleArray;
     201             : 
     202             :     // MethodSequence, that accepts all methods
     203             :     Sequence< Reference<XIdlMethod> > maAllMethodSeq;
     204             : 
     205             :     // Classification of found methods
     206             :     Sequence<sal_Int32> maMethodConceptSeq;
     207             : 
     208             :     // Number of methods
     209             :     sal_Int32 mnMethCount;
     210             : 
     211             :     // Sequence of Listener, that can be registered
     212             :     Sequence< Type > maSupportedListenerSeq;
     213             : 
     214             :     // Helper-methods for adjusting sizes of Sequences
     215             :     void checkPropertyArraysSize
     216             :     (
     217             :         Property*& rpAllPropArray,
     218             :         sal_Int16*& rpMapTypeArray,
     219             :         sal_Int32*& rpPropertyConceptArray,
     220             :         sal_Int32 iNextIndex
     221             :     );
     222             :     void checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, Reference<XInterface>*& rpInterfaceArray,
     223             :         sal_Int32 iNextIndex );
     224             : 
     225             : public:
     226             :     IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ );
     227        1456 :     virtual ~IntrospectionAccessStatic_Impl()
     228        1456 :     {
     229         728 :         delete[] mpOrgPropertyHandleArray;
     230        1456 :     }
     231             :     sal_Int32 getPropertyIndex( const OUString& aPropertyName ) const;
     232             :     sal_Int32 getMethodIndex( const OUString& aMethodName ) const;
     233             : 
     234             :     // Methods of XIntrospectionAccess (OLD, now only Impl)
     235             :     void setPropertyValue(const Any& obj, const OUString& aPropertyName, const Any& aValue) const;
     236             : //    void setPropertyValue(Any& obj, const OUString& aPropertyName, const Any& aValue) const;
     237             :     Any getPropertyValue(const Any& obj, const OUString& aPropertyName) const;
     238             :     void setPropertyValueByIndex(const Any& obj, sal_Int32 nIndex, const Any& aValue) const;
     239             : //    void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const;
     240             :     Any getPropertyValueByIndex(const Any& obj, sal_Int32 nIndex) const;
     241             : 
     242        2660 :     Sequence<Property> getProperties(void) const                        { return maAllPropertySeq; }
     243        3232 :     Sequence< Reference<XIdlMethod> > getMethods(void) const            { return maAllMethodSeq; }
     244          18 :     Sequence< Type > getSupportedListeners(void) const                    { return maSupportedListenerSeq; }
     245        7138 :     Sequence<sal_Int32> getPropertyConcepts(void) const                    { return maPropertyConceptSeq; }
     246        5966 :     Sequence<sal_Int32> getMethodConcepts(void) const                    { return maMethodConceptSeq; }
     247             : };
     248             : 
     249             : 
     250             : // Ctor
     251         896 : IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ )
     252         896 :     : mxCoreReflection( xCoreReflection_ )
     253             : {
     254         896 :     aInterfaceSeq1.realloc( ARRAY_SIZE_STEP );
     255         896 :     aInterfaceSeq2.realloc( ARRAY_SIZE_STEP );
     256             : 
     257             :     // Property-Data
     258         896 :     maAllPropertySeq.realloc( ARRAY_SIZE_STEP );
     259         896 :     maMapTypeSeq.realloc( ARRAY_SIZE_STEP );
     260         896 :     maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
     261             : 
     262         896 :     mbFastPropSet = false;
     263         896 :     mpOrgPropertyHandleArray = NULL;
     264             : 
     265         896 :     mnPropCount = 0;
     266             :     //mnDangerousPropCount = 0;
     267         896 :     mnPropertySetPropCount = 0;
     268         896 :     mnAttributePropCount = 0;
     269         896 :     mnMethodPropCount = 0;
     270             : 
     271             :     // Method-Data
     272         896 :     mnMethCount = 0;
     273         896 : }
     274             : 
     275       14748 : sal_Int32 IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString& aPropertyName ) const
     276             : {
     277       14748 :     sal_Int32 iHashResult = -1;
     278       14748 :     IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
     279       14748 :     IntrospectionNameMap::iterator aIt = pThis->maPropertyNameMap.find( aPropertyName );
     280       14748 :     if( !( aIt == pThis->maPropertyNameMap.end() ) )
     281       12304 :         iHashResult = (*aIt).second;
     282       14748 :     return iHashResult;
     283             : }
     284             : 
     285        6808 : sal_Int32 IntrospectionAccessStatic_Impl::getMethodIndex( const OUString& aMethodName ) const
     286             : {
     287        6808 :     sal_Int32 iHashResult = -1;
     288        6808 :     IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
     289        6808 :     IntrospectionNameMap::iterator aIt = pThis->maMethodNameMap.find( aMethodName );
     290        6808 :     if( !( aIt == pThis->maMethodNameMap.end() ) )
     291             :     {
     292        5576 :         iHashResult = (*aIt).second;
     293             :     }
     294             :     // #95159 Check if full qualified name matches
     295             :     else
     296             :     {
     297        1232 :         sal_Int32 nSearchFrom = aMethodName.getLength();
     298             :         while( true )
     299             :         {
     300             :             // Strategy: Search back until the first '_' is found
     301        1240 :             sal_Int32 nFound = aMethodName.lastIndexOf( '_', nSearchFrom );
     302        1240 :             if( nFound == -1 )
     303        2464 :                 break;
     304             : 
     305           8 :             OUString aPureMethodName = aMethodName.copy( nFound + 1 );
     306             : 
     307           8 :             aIt = pThis->maMethodNameMap.find( aPureMethodName );
     308           8 :             if( !( aIt == pThis->maMethodNameMap.end() ) )
     309             :             {
     310             :                 // Check if it can be a type?
     311             :                 // Problem: Does not work if package names contain _ ?!
     312           0 :                 OUString aStr = aMethodName.copy( 0, nFound );
     313           0 :                 OUString aTypeName = aStr.replace( '_', '.' );
     314           0 :                 Reference< XIdlClass > xClass = mxCoreReflection->forName( aTypeName );
     315           0 :                 if( xClass.is() )
     316             :                 {
     317             :                     // If this is a valid class it could be the right method
     318             : 
     319             :                     // Could be the right method, type has to be checked
     320           0 :                     iHashResult = (*aIt).second;
     321             : 
     322           0 :                     const Reference<XIdlMethod>* pMethods = maAllMethodSeq.getConstArray();
     323           0 :                     const Reference<XIdlMethod> xMethod = pMethods[ iHashResult ];
     324             : 
     325           0 :                     Reference< XIdlClass > xMethClass = xMethod->getDeclaringClass();
     326           0 :                     if( xClass->equals( xMethClass ) )
     327             :                     {
     328           0 :                         break;
     329             :                     }
     330             :                     else
     331             :                     {
     332           0 :                         iHashResult = -1;
     333             : 
     334             :                         // Could also be another method with the same name
     335             :                         // Iterate over all methods
     336           0 :                         sal_Int32 nLen = maAllMethodSeq.getLength();
     337           0 :                         for( int i = 0 ; i < nLen ; ++i )
     338             :                         {
     339           0 :                             const Reference<XIdlMethod> xMethod2 = pMethods[ i ];
     340           0 :                             if( xMethod2->getName() == aPureMethodName )
     341             :                             {
     342           0 :                                 Reference< XIdlClass > xMethClass2 = xMethod2->getDeclaringClass();
     343             : 
     344           0 :                                 if( xClass->equals( xMethClass2 ) )
     345             :                                 {
     346           0 :                                     iHashResult = i;
     347           0 :                                     break;
     348           0 :                                 }
     349             :                             }
     350           0 :                         }
     351             : 
     352           0 :                         if( iHashResult != -1 )
     353           0 :                             break;
     354           0 :                     }
     355           0 :                 }
     356             :             }
     357             : 
     358           8 :             nSearchFrom = nFound - 1;
     359           8 :             if( nSearchFrom < 0 )
     360           0 :                 break;
     361           8 :         }
     362             :     }
     363        6808 :     return iHashResult;
     364             : }
     365             : 
     366        1258 : void IntrospectionAccessStatic_Impl::setPropertyValue( const Any& obj, const OUString& aPropertyName, const Any& aValue ) const
     367             : //void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const OUString& aPropertyName, const Any& aValue ) const
     368             : {
     369        1258 :     sal_Int32 i = getPropertyIndex( aPropertyName );
     370        1258 :     if( i != -1 )
     371        1258 :         setPropertyValueByIndex( obj, (sal_Int32)i, aValue );
     372             :     else
     373           0 :         throw UnknownPropertyException();
     374        1258 : }
     375             : 
     376        1258 : void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
     377             : //void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
     378             : {
     379             :     // Is the passed object something that fits?
     380        1258 :     TypeClass eObjType = obj.getValueType().getTypeClass();
     381             : 
     382        1258 :     Reference<XInterface> xInterface;
     383        1258 :     if( eObjType == TypeClass_INTERFACE )
     384             :     {
     385        1012 :         xInterface = *( Reference<XInterface>*)obj.getValue();
     386             :     }
     387         246 :     else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
     388             :     {
     389           0 :         throw IllegalArgumentException();
     390             :     }
     391             : 
     392             :     // Test flags
     393        1258 :     const Property* pProps = maAllPropertySeq.getConstArray();
     394        1258 :     if( (pProps[ nSequenceIndex ].Attributes & READONLY) != 0 )
     395             :     {
     396           0 :         throw UnknownPropertyException();
     397             :     }
     398             : 
     399        1258 :     const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
     400        1258 :     switch( pMapTypeArray[ nSequenceIndex ] )
     401             :     {
     402             :         case MAP_PROPERTY_SET:
     403             :         {
     404             :             // Get Property
     405           6 :             const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
     406             : 
     407             :             // Convert Interface-Parameter to the correct type
     408           6 :             bool bUseCopy = false;
     409           6 :             Any aRealValue;
     410             : 
     411           6 :             TypeClass eValType = aValue.getValueType().getTypeClass();
     412           6 :             if( eValType == TypeClass_INTERFACE )
     413             :             {
     414           2 :                 Type aPropType = rProp.Type;
     415           4 :                 OUString aTypeName( aPropType.getTypeName() );
     416           4 :                 Reference< XIdlClass > xPropClass = mxCoreReflection->forName( aTypeName );
     417             :                 //Reference<XIdlClass> xPropClass = rProp.Type;
     418           2 :                 if( xPropClass.is() && xPropClass->getTypeClass() == TypeClass_INTERFACE )
     419             :                 {
     420           2 :                     Reference<XInterface> valInterface = *(Reference<XInterface>*)aValue.getValue();
     421           2 :                     if( valInterface.is() )
     422             :                     {
     423             :                         //Any queryInterface( const Type& rType );
     424           2 :                         aRealValue = valInterface->queryInterface( aPropType );
     425           2 :                         if( aRealValue.hasValue() )
     426           2 :                             bUseCopy = true;
     427           2 :                     }
     428           2 :                 }
     429             :             }
     430             : 
     431             :             // Do we have a FastPropertySet and a valid Handle?
     432             :             // CAUTION: At this point we exploit, that the PropertySet
     433             :             // gets queried at the beginning of the Introspection-Process.
     434             :             sal_Int32 nOrgHandle;
     435           6 :             if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
     436             :             {
     437             :                 // Retrieve PropertySet-Interface
     438             :                 Reference<XFastPropertySet> xFastPropSet =
     439           6 :                     Reference<XFastPropertySet>::query( xInterface );
     440           6 :                 if( xFastPropSet.is() )
     441             :                 {
     442           6 :                     xFastPropSet->setFastPropertyValue( nOrgHandle, bUseCopy ? aRealValue : aValue );
     443             :                 }
     444             :                 else
     445             :                 {
     446             :                     // throw UnknownPropertyException
     447           6 :                 }
     448             :             }
     449             :             // else take the normal one
     450             :             else
     451             :             {
     452             :                 // Retrieve PropertySet-Interface
     453             :                 Reference<XPropertySet> xPropSet =
     454           0 :                     Reference<XPropertySet>::query( xInterface );
     455           0 :                 if( xPropSet.is() )
     456             :                 {
     457           0 :                     xPropSet->setPropertyValue( rProp.Name, bUseCopy ? aRealValue : aValue );
     458             :                 }
     459             :                 else
     460             :                 {
     461             :                     // throw UnknownPropertyException
     462           0 :                 }
     463           6 :             }
     464             :         }
     465           6 :         break;
     466             : 
     467             :         case MAP_FIELD:
     468             :         {
     469        1174 :             Reference<XIdlField> xField = static_cast<XIdlField*>(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
     470        2348 :             Reference<XIdlField2> xField2(xField, UNO_QUERY);
     471        1174 :             if( xField2.is() )
     472             :             {
     473        1174 :                 xField2->set( (Any&)obj, aValue );
     474             :                 // IllegalArgumentException
     475             :                 // NullPointerException
     476             :             } else
     477           0 :             if( xField.is() )
     478             :             {
     479           0 :                 xField->set( obj, aValue );
     480             :                 // IllegalArgumentException
     481             :                 // NullPointerException
     482             :             }
     483             :             else
     484             :             {
     485             :                 // throw IllegalArgumentException();
     486        1174 :             }
     487             :         }
     488        1174 :         break;
     489             : 
     490             :         case MAP_GETSET:
     491             :         case MAP_SETONLY:
     492             :         {
     493             :             // Retrieve set-Methods
     494          78 :             Reference<XIdlMethod> xMethod = static_cast<XIdlMethod*>(aInterfaceSeq2.getConstArray()[ nSequenceIndex ].get());
     495          78 :             if( xMethod.is() )
     496             :             {
     497          78 :                 Sequence<Any> args( 1 );
     498          78 :                 args.getArray()[0] = aValue;
     499          78 :                 xMethod->invoke( obj, args );
     500             :             }
     501             :             else
     502             :             {
     503             :                 // throw IllegalArgumentException();
     504          78 :             }
     505             :         }
     506          78 :         break;
     507        1258 :     }
     508        1258 : }
     509             : 
     510        3908 : Any IntrospectionAccessStatic_Impl::getPropertyValue( const Any& obj, const OUString& aPropertyName ) const
     511             : {
     512        3908 :     sal_Int32 i = getPropertyIndex( aPropertyName );
     513        3908 :     if( i != -1 )
     514        7816 :         return getPropertyValueByIndex( obj, i );
     515             : 
     516           0 :     throw UnknownPropertyException();
     517             : }
     518             : 
     519        3908 : Any IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex) const
     520             : {
     521        3908 :     Any aRet;
     522             : 
     523             :     // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
     524        3908 :     TypeClass eObjType = obj.getValueType().getTypeClass();
     525             : 
     526        7816 :     Reference<XInterface> xInterface;
     527        3908 :     if( eObjType == TypeClass_INTERFACE )
     528             :     {
     529        3032 :         xInterface = *(Reference<XInterface>*)obj.getValue();
     530             :     }
     531         876 :     else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
     532             :     {
     533             :         // throw IllegalArgumentException();
     534           0 :         return aRet;
     535             :     }
     536             : 
     537        3908 :     const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
     538        3908 :     switch( pMapTypeArray[ nSequenceIndex ] )
     539             :     {
     540             :         case MAP_PROPERTY_SET:
     541             :         {
     542             :             // Property besorgen
     543           6 :             const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
     544             : 
     545             :             // Haben wir ein FastPropertySet und ein gueltiges Handle?
     546             :             // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
     547             :             // zu Beginn des Introspection-Vorgangs abgefragt wird.
     548             :             sal_Int32 nOrgHandle;
     549           6 :             if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
     550             :             {
     551             :                 // PropertySet-Interface holen
     552             :                 Reference<XFastPropertySet> xFastPropSet =
     553           6 :                     Reference<XFastPropertySet>::query( xInterface );
     554           6 :                 if( xFastPropSet.is() )
     555             :                 {
     556           6 :                     aRet = xFastPropSet->getFastPropertyValue( nOrgHandle);
     557             :                 }
     558             :                 else
     559             :                 {
     560             :                     // throw UnknownPropertyException
     561           0 :                     return aRet;
     562           6 :                 }
     563             :             }
     564             :             // sonst eben das normale nehmen
     565             :             else
     566             :             {
     567             :                 // PropertySet-Interface holen
     568             :                 Reference<XPropertySet> xPropSet =
     569           0 :                     Reference<XPropertySet>::query( xInterface );
     570           0 :                 if( xPropSet.is() )
     571             :                 {
     572           0 :                     aRet = xPropSet->getPropertyValue( rProp.Name );
     573             :                 }
     574             :                 else
     575             :                 {
     576             :                     // throw UnknownPropertyException
     577           0 :                     return aRet;
     578           0 :                 }
     579             :             }
     580             :         }
     581           6 :         break;
     582             : 
     583             :         case MAP_FIELD:
     584             :         {
     585        3396 :             Reference<XIdlField> xField = static_cast<XIdlField*>(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
     586        3396 :             if( xField.is() )
     587             :             {
     588        3396 :                 aRet = xField->get( obj );
     589             :                 // IllegalArgumentException
     590             :                 // NullPointerException
     591             :             }
     592             :             else
     593             :             {
     594             :                 // throw IllegalArgumentException();
     595           0 :                 return aRet;
     596        3396 :             }
     597             :         }
     598        3396 :         break;
     599             : 
     600             :         case MAP_GETSET:
     601             :         {
     602             :             // get-Methode holen
     603         506 :             Reference<XIdlMethod> xMethod = static_cast<XIdlMethod*>(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
     604         506 :             if( xMethod.is() )
     605             :             {
     606         506 :                 Sequence<Any> args;
     607         506 :                 aRet = xMethod->invoke( obj, args );
     608             :             }
     609             :             else
     610             :             {
     611             :                 // throw IllegalArgumentException();
     612           0 :                 return aRet;
     613         506 :             }
     614             :         }
     615         506 :         break;
     616             : 
     617             :         case MAP_SETONLY:
     618             :             // get-Methode gibt es nicht
     619             :             // throw WriteOnlyPropertyException();
     620           0 :             return aRet;
     621             :     }
     622        3908 :     return aRet;
     623             : }
     624             : 
     625             : 
     626             : // Hilfs-Methoden zur Groessen-Anpassung der Sequences
     627       42952 : void IntrospectionAccessStatic_Impl::checkPropertyArraysSize
     628             : (
     629             :     Property*& rpAllPropArray,
     630             :     sal_Int16*& rpMapTypeArray,
     631             :     sal_Int32*& rpPropertyConceptArray,
     632             :     sal_Int32 iNextIndex
     633             : )
     634             : {
     635       42952 :     sal_Int32 nLen = maAllPropertySeq.getLength();
     636       42952 :     if( iNextIndex >= nLen )
     637             :     {
     638        1666 :         maAllPropertySeq.realloc( nLen + ARRAY_SIZE_STEP );
     639        1666 :         rpAllPropArray = maAllPropertySeq.getArray();
     640             : 
     641        1666 :         maMapTypeSeq.realloc( nLen + ARRAY_SIZE_STEP );
     642        1666 :         rpMapTypeArray = maMapTypeSeq.getArray();
     643             : 
     644        1666 :         maPropertyConceptSeq.realloc( nLen + ARRAY_SIZE_STEP );
     645        1666 :         rpPropertyConceptArray = maPropertyConceptSeq.getArray();
     646             :     }
     647       42952 : }
     648             : 
     649       22254 : void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq,
     650             :     Reference<XInterface>*& rpInterfaceArray, sal_Int32 iNextIndex )
     651             : {
     652       22254 :     sal_Int32 nLen = rSeq.getLength();
     653       22254 :     if( iNextIndex >= nLen )
     654             :     {
     655             :         // Neue Groesse mit ARRAY_SIZE_STEP abgleichen
     656        2152 :         sal_Int32 nMissingSize = iNextIndex - nLen + 1;
     657        2152 :         sal_Int32 nSteps = nMissingSize / ARRAY_SIZE_STEP + 1;
     658        2152 :         sal_Int32 nNewSize = nLen + nSteps * ARRAY_SIZE_STEP;
     659             : 
     660        2152 :         rSeq.realloc( nNewSize );
     661        2152 :         rpInterfaceArray = rSeq.getArray();
     662             :     }
     663       22254 : }
     664             : 
     665             : 
     666             : 
     667             : //*** ImplIntrospectionAccess ***
     668             : 
     669             : 
     670             : // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
     671             : // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
     672             : // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
     673             : class ImplIntrospectionAccess : public IntrospectionAccessHelper
     674             : {
     675             :     friend class Implementation;
     676             : 
     677             :     // Untersuchtes Objekt
     678             :     Any maInspectedObject;
     679             : 
     680             :     // Als Interface
     681             :     Reference<XInterface> mxIface;
     682             : 
     683             :     // Statische Daten der Introspection
     684             :     rtl::Reference< IntrospectionAccessStatic_Impl > mpStaticImpl;
     685             : 
     686             :     // Adapter-Implementation
     687             :     WeakReference< XInterface > maAdapter;
     688             : 
     689             :     // Letzte Sequence, die bei getProperties geliefert wurde (Optimierung)
     690             :     Sequence<Property> maLastPropertySeq;
     691             :     sal_Int32 mnLastPropertyConcept;
     692             : 
     693             :     // Letzte Sequence, die bei getMethods geliefert wurde (Optimierung)
     694             :     Sequence<Reference<XIdlMethod> > maLastMethodSeq;
     695             :     sal_Int32 mnLastMethodConcept;
     696             : 
     697             : public:
     698             :     ImplIntrospectionAccess( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ );
     699             :     virtual ~ImplIntrospectionAccess();
     700             : 
     701             :     // Methoden von XIntrospectionAccess
     702             :     virtual sal_Int32 SAL_CALL getSuppliedMethodConcepts(void)
     703             :         throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     704             :     virtual sal_Int32 SAL_CALL getSuppliedPropertyConcepts(void)
     705             :         throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     706             :     virtual Property SAL_CALL getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
     707             :         throw( NoSuchElementException, RuntimeException, std::exception ) SAL_OVERRIDE;
     708             :     virtual sal_Bool SAL_CALL hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
     709             :         throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     710             :     virtual Sequence< Property > SAL_CALL getProperties(sal_Int32 PropertyConcepts)
     711             :           throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     712             :     virtual Reference<XIdlMethod> SAL_CALL getMethod(const OUString& Name, sal_Int32 MethodConcepts)
     713             :           throw( NoSuchMethodException, RuntimeException, std::exception ) SAL_OVERRIDE;
     714             :     virtual sal_Bool SAL_CALL hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
     715             :           throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     716             :     virtual Sequence< Reference<XIdlMethod> > SAL_CALL getMethods(sal_Int32 MethodConcepts)
     717             :           throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     718             :     virtual Sequence< Type > SAL_CALL getSupportedListeners(void)
     719             :           throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     720             :     using OWeakObject::queryAdapter;
     721             :     virtual Reference<XInterface> SAL_CALL queryAdapter( const Type& rType )
     722             :           throw( IllegalTypeException, RuntimeException, std::exception ) SAL_OVERRIDE;
     723             : 
     724             :     // Methoden von XMaterialHolder
     725             :     virtual Any SAL_CALL getMaterial(void) throw(RuntimeException, std::exception) SAL_OVERRIDE;
     726             : 
     727             :     // Methoden von XExactName
     728             :     virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     729             : };
     730             : 
     731       16928 : ImplIntrospectionAccess::ImplIntrospectionAccess
     732             :     ( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
     733       16928 :         : maInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ), maAdapter()
     734             : {
     735             :     // Objekt als Interface merken, wenn moeglich
     736       16928 :     TypeClass eType = maInspectedObject.getValueType().getTypeClass();
     737       16928 :     if( eType == TypeClass_INTERFACE )
     738       15786 :         mxIface = *(Reference<XInterface>*)maInspectedObject.getValue();
     739             : 
     740       16928 :     mnLastPropertyConcept = -1;
     741       16928 :     mnLastMethodConcept = -1;
     742       16928 : }
     743             : 
     744       33600 : ImplIntrospectionAccess::~ImplIntrospectionAccess()
     745             : {
     746       33600 : }
     747             : 
     748             : 
     749             : 
     750             : //*** ImplIntrospectionAdapter ***
     751             : 
     752             : 
     753             : // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
     754             : // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
     755             : // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
     756       21696 : class ImplIntrospectionAdapter :
     757             :     public XPropertySet, public XFastPropertySet, public XPropertySetInfo,
     758             :     public XNameContainer, public XIndexContainer,
     759             :     public XEnumerationAccess, public  XIdlArray,
     760             :     public OWeakObject
     761             : {
     762             :     // Parent-Objekt
     763             :     ::rtl::Reference< ImplIntrospectionAccess > mpAccess;
     764             : 
     765             :     // Untersuchtes Objekt
     766             :     const Any& mrInspectedObject;
     767             : 
     768             :     // Statische Daten der Introspection
     769             :     rtl::Reference< IntrospectionAccessStatic_Impl > mpStaticImpl;
     770             : 
     771             :     // Objekt als Interface
     772             :     Reference<XInterface> mxIface;
     773             : 
     774             :     // Original-Interfaces des Objekts
     775             :     Reference<XElementAccess>        mxObjElementAccess;
     776             :     Reference<XNameContainer>        mxObjNameContainer;
     777             :     Reference<XNameAccess>            mxObjNameAccess;
     778             :     Reference<XIndexAccess>            mxObjIndexAccess;
     779             :     Reference<XIndexContainer>        mxObjIndexContainer;
     780             :     Reference<XEnumerationAccess>    mxObjEnumerationAccess;
     781             :     Reference<XIdlArray>            mxObjIdlArray;
     782             : 
     783             : public:
     784             :     ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
     785             :         const Any& obj,
     786             :         rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ );
     787             : 
     788             :     // Methoden von XInterface
     789             :     virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     790       70424 :     virtual void        SAL_CALL acquire() throw() SAL_OVERRIDE { OWeakObject::acquire(); }
     791       70344 :     virtual void        SAL_CALL release() throw() SAL_OVERRIDE { OWeakObject::release(); }
     792             : 
     793             :     // Methoden von XPropertySet
     794             :     virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     795             :     virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, const Any& aValue)
     796             :         throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     797             :     virtual Any SAL_CALL getPropertyValue(const OUString& aPropertyName)
     798             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     799             :     virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
     800             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     801             :     virtual void SAL_CALL removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
     802             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     803             :     virtual void SAL_CALL addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
     804             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     805             :     virtual void SAL_CALL removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
     806             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     807             : 
     808             :     // Methoden von XFastPropertySet
     809             :     virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const Any& aValue)
     810             :         throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     811             :     virtual Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle)
     812             :         throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     813             : 
     814             :     // Methoden von XPropertySetInfo
     815             :     virtual Sequence< Property > SAL_CALL getProperties(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     816             :     virtual Property SAL_CALL getPropertyByName(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     817             :     virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     818             : 
     819             :     // Methoden von XElementAccess
     820             :     virtual Type SAL_CALL getElementType(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     821             :     virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     822             : 
     823             :     // Methoden von XNameAccess
     824             :     virtual Any SAL_CALL getByName(const OUString& Name)
     825             :         throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     826             :     virtual Sequence< OUString > SAL_CALL getElementNames(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     827             :     virtual sal_Bool SAL_CALL hasByName(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     828             : 
     829             :     // Methoden von XNameContainer
     830             :     virtual void SAL_CALL insertByName(const OUString& Name, const Any& Element)
     831             :         throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     832             :     virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element)
     833             :         throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     834             :     virtual void SAL_CALL removeByName(const OUString& Name)
     835             :         throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     836             : 
     837             :     // Methoden von XIndexAccess
     838             :     virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     839             :     virtual Any SAL_CALL getByIndex(sal_Int32 Index)
     840             :         throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     841             : 
     842             :     // Methoden von XIndexContainer
     843             :     virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element)
     844             :         throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     845             :     virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element)
     846             :         throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     847             :     virtual void SAL_CALL removeByIndex(sal_Int32 Index)
     848             :         throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
     849             : 
     850             :     // Methoden von XEnumerationAccess
     851             :     virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
     852             : 
     853             :     // Methoden von XIdlArray
     854             :     virtual void SAL_CALL realloc(Any& array, sal_Int32 length)
     855             :         throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     856             :     virtual sal_Int32 SAL_CALL getLen(const Any& array) throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
     857             :     virtual Any SAL_CALL get(const Any& array, sal_Int32 index)
     858             :         throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception ) SAL_OVERRIDE;
     859             :     virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value)
     860             :         throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception ) SAL_OVERRIDE;
     861             : };
     862             : 
     863       10868 : ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
     864             :     const Any& obj,
     865             :     rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
     866       10868 :         : mpAccess( pAccess_), mrInspectedObject( obj ), mpStaticImpl( pStaticImpl_ )
     867             : {
     868             :     // Objekt als Interfaceholen
     869       10868 :     TypeClass eType = mrInspectedObject.getValueType().getTypeClass();
     870       10868 :     if( eType == TypeClass_INTERFACE )
     871             :     {
     872        5170 :         mxIface = *( Reference< XInterface >*)mrInspectedObject.getValue();
     873             : 
     874        5170 :         mxObjElementAccess = Reference<XElementAccess>::query( mxIface );
     875        5170 :         mxObjNameAccess = Reference<XNameAccess>::query( mxIface );
     876        5170 :         mxObjNameContainer = Reference<XNameContainer>::query( mxIface );
     877        5170 :         mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface );
     878        5170 :         mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface );
     879        5170 :         mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
     880        5170 :         mxObjIdlArray = Reference<XIdlArray>::query( mxIface );
     881             :     }
     882       10868 : }
     883             : 
     884             : // Methoden von XInterface
     885       34484 : Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType )
     886             :     throw( RuntimeException, std::exception )
     887             : {
     888             :     Any aRet( ::cppu::queryInterface(
     889             :         rType,
     890             :         static_cast< XPropertySet * >( this ),
     891             :         static_cast< XFastPropertySet * >( this ),
     892       34484 :         static_cast< XPropertySetInfo * >( this ) ) );
     893       34484 :     if( !aRet.hasValue() )
     894       24062 :         aRet = OWeakObject::queryInterface( rType );
     895             : 
     896       34484 :     if( !aRet.hasValue() )
     897             :     {
     898             :         // Wrapper fuer die Objekt-Interfaces
     899       22588 :         if(   ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface
     900        1022 :                     ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() )
     901       13464 :             || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
     902       13368 :             || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
     903       13280 :             || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
     904       13276 :             || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
     905       13276 :             || ( mxObjEnumerationAccess    .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
     906       26836 :             || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
     907             :           )
     908             :         {
     909             :         }
     910             :     }
     911       34484 :     return aRet;
     912             : }
     913             : 
     914             : 
     915             : 
     916             : //*** Implementation von ImplIntrospectionAdapter ***
     917             : 
     918             : 
     919             : // Methoden von XPropertySet
     920           8 : Reference<XPropertySetInfo> ImplIntrospectionAdapter::getPropertySetInfo(void)
     921             :     throw( RuntimeException, std::exception )
     922             : {
     923           8 :     return (XPropertySetInfo *)this;
     924             : }
     925             : 
     926        1258 : void ImplIntrospectionAdapter::setPropertyValue(const OUString& aPropertyName, const Any& aValue)
     927             :     throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception )
     928             : {
     929        1258 :     mpStaticImpl->setPropertyValue( mrInspectedObject, aPropertyName, aValue );
     930        1258 : }
     931             : 
     932        3908 : Any ImplIntrospectionAdapter::getPropertyValue(const OUString& aPropertyName)
     933             :     throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
     934             : {
     935        3908 :     return mpStaticImpl->getPropertyValue( mrInspectedObject, aPropertyName );
     936             : }
     937             : 
     938           0 : void ImplIntrospectionAdapter::addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
     939             :     throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
     940             : {
     941           0 :     if( mxIface.is() )
     942             :     {
     943             :         Reference<XPropertySet> xPropSet =
     944           0 :             Reference<XPropertySet>::query( mxIface );
     945             :         //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
     946           0 :         if( xPropSet.is() )
     947           0 :             xPropSet->addPropertyChangeListener(aPropertyName, aListener);
     948             :     }
     949           0 : }
     950             : 
     951           0 : void ImplIntrospectionAdapter::removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
     952             :     throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
     953             : {
     954           0 :     if( mxIface.is() )
     955             :     {
     956             :         Reference<XPropertySet> xPropSet =
     957           0 :             Reference<XPropertySet>::query( mxIface );
     958             :         //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
     959           0 :         if( xPropSet.is() )
     960           0 :             xPropSet->removePropertyChangeListener(aPropertyName, aListener);
     961             :     }
     962           0 : }
     963             : 
     964           0 : void ImplIntrospectionAdapter::addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
     965             :     throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
     966             : {
     967           0 :     if( mxIface.is() )
     968             :     {
     969             :         Reference<XPropertySet> xPropSet =
     970           0 :             Reference<XPropertySet>::query( mxIface );
     971             :         //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
     972           0 :         if( xPropSet.is() )
     973           0 :             xPropSet->addVetoableChangeListener(aPropertyName, aListener);
     974             :     }
     975           0 : }
     976             : 
     977           0 : void ImplIntrospectionAdapter::removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
     978             :     throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
     979             : {
     980           0 :     if( mxIface.is() )
     981             :     {
     982             :         Reference<XPropertySet> xPropSet =
     983           0 :             Reference<XPropertySet>::query( mxIface );
     984           0 :         if( xPropSet.is() )
     985           0 :             xPropSet->removeVetoableChangeListener(aPropertyName, aListener);
     986             :     }
     987           0 : }
     988             : 
     989             : 
     990             : // Methoden von XFastPropertySet
     991           0 : void ImplIntrospectionAdapter::setFastPropertyValue(sal_Int32, const Any&)
     992             :     throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception )
     993             : {
     994           0 : }
     995             : 
     996           0 : Any ImplIntrospectionAdapter::getFastPropertyValue(sal_Int32)
     997             :     throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
     998             : {
     999           0 :     return Any();
    1000             : }
    1001             : 
    1002             : // Methoden von XPropertySetInfo
    1003           8 : Sequence< Property > ImplIntrospectionAdapter::getProperties(void) throw( RuntimeException, std::exception )
    1004             : {
    1005           8 :     return mpStaticImpl->getProperties();
    1006             : }
    1007             : 
    1008           0 : Property ImplIntrospectionAdapter::getPropertyByName(const OUString& Name)
    1009             :     throw( RuntimeException, std::exception )
    1010             : {
    1011           0 :     return mpAccess->getProperty( Name, PropertyConcept::ALL );
    1012             : }
    1013             : 
    1014           0 : sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name)
    1015             :     throw( RuntimeException, std::exception )
    1016             : {
    1017           0 :     return mpAccess->hasProperty( Name, PropertyConcept::ALL );
    1018             : }
    1019             : 
    1020             : // Methoden von XElementAccess
    1021           0 : Type ImplIntrospectionAdapter::getElementType(void) throw( RuntimeException, std::exception )
    1022             : {
    1023           0 :     return mxObjElementAccess->getElementType();
    1024             : }
    1025             : 
    1026           0 : sal_Bool ImplIntrospectionAdapter::hasElements(void) throw( RuntimeException, std::exception )
    1027             : {
    1028           0 :     return mxObjElementAccess->hasElements();
    1029             : }
    1030             : 
    1031             : // Methoden von XNameAccess
    1032           0 : Any ImplIntrospectionAdapter::getByName(const OUString& Name)
    1033             :     throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
    1034             : {
    1035           0 :     return mxObjNameAccess->getByName( Name );
    1036             : }
    1037             : 
    1038           0 : Sequence< OUString > ImplIntrospectionAdapter::getElementNames(void)
    1039             :     throw( RuntimeException, std::exception )
    1040             : {
    1041           0 :     return mxObjNameAccess->getElementNames();
    1042             : }
    1043             : 
    1044           2 : sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name)
    1045             :     throw( RuntimeException, std::exception )
    1046             : {
    1047           2 :     return mxObjNameAccess->hasByName( Name );
    1048             : }
    1049             : 
    1050             : // Methoden von XNameContainer
    1051           0 : void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element)
    1052             :     throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception )
    1053             : {
    1054           0 :     mxObjNameContainer->insertByName( Name, Element );
    1055           0 : }
    1056             : 
    1057           0 : void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element)
    1058             :     throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
    1059             : {
    1060           0 :     mxObjNameContainer->replaceByName( Name, Element );
    1061           0 : }
    1062             : 
    1063           0 : void ImplIntrospectionAdapter::removeByName(const OUString& Name)
    1064             :     throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
    1065             : {
    1066           0 :     mxObjNameContainer->removeByName( Name );
    1067           0 : }
    1068             : 
    1069             : // Methoden von XIndexAccess
    1070             : // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const
    1071           0 : sal_Int32 ImplIntrospectionAdapter::getCount(void) throw( RuntimeException, std::exception )
    1072             : {
    1073           0 :     return mxObjIndexAccess->getCount();
    1074             : }
    1075             : 
    1076           0 : Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index)
    1077             :     throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
    1078             : {
    1079           0 :     return mxObjIndexAccess->getByIndex( Index );
    1080             : }
    1081             : 
    1082             : // Methoden von XIndexContainer
    1083           0 : void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element)
    1084             :     throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
    1085             : {
    1086           0 :     mxObjIndexContainer->insertByIndex( Index, Element );
    1087           0 : }
    1088             : 
    1089           0 : void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element)
    1090             :     throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
    1091             : {
    1092           0 :     mxObjIndexContainer->replaceByIndex( Index, Element );
    1093           0 : }
    1094             : 
    1095           0 : void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index)
    1096             :     throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
    1097             : {
    1098           0 :     mxObjIndexContainer->removeByIndex( Index );
    1099           0 : }
    1100             : 
    1101             : // Methoden von XEnumerationAccess
    1102             : // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const;
    1103           0 : Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration(void) throw( RuntimeException, std::exception )
    1104             : {
    1105           0 :     return mxObjEnumerationAccess->createEnumeration();
    1106             : }
    1107             : 
    1108             : // Methoden von XIdlArray
    1109           0 : void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length)
    1110             :     throw( IllegalArgumentException, RuntimeException, std::exception )
    1111             : {
    1112           0 :     mxObjIdlArray->realloc( array, length );
    1113           0 : }
    1114             : 
    1115           0 : sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array)
    1116             :     throw( IllegalArgumentException, RuntimeException, std::exception )
    1117             : {
    1118           0 :     return mxObjIdlArray->getLen( array );
    1119             : }
    1120             : 
    1121           0 : Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index)
    1122             :     throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception )
    1123             : {
    1124           0 :     return mxObjIdlArray->get( array, index );
    1125             : }
    1126             : 
    1127           0 : void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value)
    1128             :     throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception )
    1129             : {
    1130           0 :     mxObjIdlArray->set( array, index, value );
    1131           0 : }
    1132             : 
    1133             : 
    1134             : 
    1135             : //*** Implementation von ImplIntrospectionAccess ***
    1136             : 
    1137             : 
    1138             : // Methoden von XIntrospectionAccess
    1139           0 : sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts(void)
    1140             :     throw( RuntimeException, std::exception )
    1141             : {
    1142             :     return    MethodConcept::DANGEROUS |
    1143             :             PROPERTY |
    1144             :             LISTENER |
    1145             :             ENUMERATION |
    1146             :             NAMECONTAINER |
    1147           0 :             INDEXCONTAINER;
    1148             : }
    1149             : 
    1150           0 : sal_Int32 ImplIntrospectionAccess::getSuppliedPropertyConcepts(void)
    1151             :     throw( RuntimeException, std::exception )
    1152             : {
    1153             :     return    PropertyConcept::DANGEROUS |
    1154             :             PROPERTYSET |
    1155             :             ATTRIBUTES |
    1156           0 :             METHODS;
    1157             : }
    1158             : 
    1159        2652 : Property ImplIntrospectionAccess::getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
    1160             :     throw( NoSuchElementException, RuntimeException, std::exception )
    1161             : {
    1162        2652 :     Property aRet;
    1163        2652 :     sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
    1164        2652 :     bool bFound = false;
    1165        2652 :     if( i != -1 )
    1166             :     {
    1167        2652 :         sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
    1168        2652 :         if( (PropertyConcepts & nConcept) != 0 )
    1169             :         {
    1170        2652 :             const Property* pProps = mpStaticImpl->getProperties().getConstArray();
    1171        2652 :             aRet = pProps[ i ];
    1172        2652 :             bFound = true;
    1173             :         }
    1174             :     }
    1175        2652 :     if( !bFound )
    1176           0 :         throw NoSuchElementException() ;
    1177        2652 :     return aRet;
    1178             : }
    1179             : 
    1180        6930 : sal_Bool ImplIntrospectionAccess::hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
    1181             :     throw( RuntimeException, std::exception )
    1182             : {
    1183        6930 :     sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
    1184        6930 :     bool bRet = false;
    1185        6930 :     if( i != -1 )
    1186             :     {
    1187        4486 :         sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
    1188        4486 :         if( (PropertyConcepts & nConcept) != 0 )
    1189        4486 :             bRet = true;
    1190             :     }
    1191        6930 :     return bRet;
    1192             : }
    1193             : 
    1194           0 : Sequence< Property > ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts)
    1195             :     throw( RuntimeException, std::exception )
    1196             : {
    1197             :     // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
    1198             :     sal_Int32 nAllSupportedMask =    PROPERTYSET |
    1199             :                                     ATTRIBUTES |
    1200           0 :                                     METHODS;
    1201           0 :     if( ( PropertyConcepts & nAllSupportedMask ) == nAllSupportedMask )
    1202             :     {
    1203           0 :         return mpStaticImpl->getProperties();
    1204             :     }
    1205             : 
    1206             :     // Gleiche Sequence wie beim vorigen mal?
    1207           0 :     if( mnLastPropertyConcept == PropertyConcepts )
    1208             :     {
    1209           0 :         return maLastPropertySeq;
    1210             :     }
    1211             : 
    1212             :     // Anzahl der zu liefernden Properties
    1213           0 :     sal_Int32 nCount = 0;
    1214             : 
    1215             :     // Es gibt zur Zeit keine DANGEROUS-Properties
    1216             :     // if( PropertyConcepts & DANGEROUS )
    1217             :     //    nCount += mpStaticImpl->mnDangerousPropCount;
    1218           0 :     if( PropertyConcepts & PROPERTYSET )
    1219           0 :         nCount += mpStaticImpl->mnPropertySetPropCount;
    1220           0 :     if( PropertyConcepts & ATTRIBUTES )
    1221           0 :         nCount += mpStaticImpl->mnAttributePropCount;
    1222           0 :     if( PropertyConcepts & METHODS )
    1223           0 :         nCount += mpStaticImpl->mnMethodPropCount;
    1224             : 
    1225             :     // Sequence entsprechend der geforderten Anzahl reallocieren
    1226           0 :     ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this;    // const umgehen
    1227           0 :     pThis->maLastPropertySeq.realloc( nCount );
    1228           0 :     Property* pDestProps = pThis->maLastPropertySeq.getArray();
    1229             : 
    1230             :     // Alle Properties durchgehen und entsprechend der Concepte uebernehmen
    1231           0 :     Sequence<Property> aPropSeq = mpStaticImpl->getProperties();
    1232           0 :     const Property* pSourceProps = aPropSeq.getConstArray();
    1233           0 :     const sal_Int32* pConcepts = mpStaticImpl->getPropertyConcepts().getConstArray();
    1234           0 :     sal_Int32 nLen = aPropSeq.getLength();
    1235             : 
    1236           0 :     sal_Int32 iDest = 0;
    1237           0 :     for( sal_Int32 i = 0 ; i < nLen ; i++ )
    1238             :     {
    1239           0 :         sal_Int32 nConcept = pConcepts[ i ];
    1240           0 :         if( nConcept & PropertyConcepts )
    1241           0 :             pDestProps[ iDest++ ] = pSourceProps[ i ];
    1242             :     }
    1243             : 
    1244             :     // PropertyConcept merken, dies entspricht maLastPropertySeq
    1245           0 :     pThis->mnLastPropertyConcept = PropertyConcepts;
    1246             : 
    1247             :     // Zusammengebastelte Sequence liefern
    1248           0 :     return maLastPropertySeq;
    1249             : }
    1250             : 
    1251        2788 : Reference<XIdlMethod> ImplIntrospectionAccess::getMethod(const OUString& Name, sal_Int32 MethodConcepts)
    1252             :     throw( NoSuchMethodException, RuntimeException, std::exception )
    1253             : {
    1254        2788 :     Reference<XIdlMethod> xRet;
    1255        2788 :     sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
    1256        2788 :     if( i != -1 )
    1257             :     {
    1258             : 
    1259        2788 :         sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
    1260        2788 :         if( (MethodConcepts & nConcept) != 0 )
    1261             :         {
    1262        2788 :             const Reference<XIdlMethod>* pMethods = mpStaticImpl->getMethods().getConstArray();
    1263        2788 :             xRet = pMethods[i];
    1264             :         }
    1265             :     }
    1266        2788 :     if( !xRet.is() )
    1267           0 :         throw NoSuchMethodException();
    1268        2788 :     return xRet;
    1269             : }
    1270             : 
    1271        4020 : sal_Bool ImplIntrospectionAccess::hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
    1272             :     throw( RuntimeException, std::exception )
    1273             : {
    1274        4020 :     sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
    1275        4020 :     bool bRet = false;
    1276        4020 :     if( i != -1 )
    1277             :     {
    1278        2788 :         sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
    1279        2788 :         if( (MethodConcepts & nConcept) != 0 )
    1280        2788 :             bRet = true;
    1281             :     }
    1282        4020 :     return bRet;
    1283             : }
    1284             : 
    1285         484 : Sequence< Reference<XIdlMethod> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts)
    1286             :     throw( RuntimeException, std::exception )
    1287             : {
    1288         484 :     ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this;    // const umgehen
    1289             : 
    1290             :     // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
    1291             :     sal_Int32 nAllSupportedMask =     MethodConcept::DANGEROUS |
    1292             :                                     PROPERTY |
    1293             :                                     LISTENER |
    1294             :                                     ENUMERATION |
    1295             :                                     NAMECONTAINER |
    1296             :                                     INDEXCONTAINER |
    1297         484 :                                     MethodConcept_NORMAL_IMPL;
    1298         484 :     if( ( MethodConcepts & nAllSupportedMask ) == nAllSupportedMask )
    1299             :     {
    1300          54 :         return mpStaticImpl->getMethods();
    1301             :     }
    1302             : 
    1303             :     // Gleiche Sequence wie beim vorigen mal?
    1304         430 :     if( mnLastMethodConcept == MethodConcepts )
    1305             :     {
    1306          40 :         return maLastMethodSeq;
    1307             :     }
    1308             : 
    1309             :     // Methoden-Sequences besorgen
    1310         390 :     Sequence< Reference<XIdlMethod> > aMethodSeq = mpStaticImpl->getMethods();
    1311         390 :     const Reference<XIdlMethod>* pSourceMethods = aMethodSeq.getConstArray();
    1312         390 :     const sal_Int32* pConcepts = mpStaticImpl->getMethodConcepts().getConstArray();
    1313         390 :     sal_Int32 nLen = aMethodSeq.getLength();
    1314             : 
    1315             :     // Sequence entsprechend der geforderten Anzahl reallocieren
    1316             :     // Anders als bei den Properties kann die Anzahl nicht durch
    1317             :     // Zaehler in inspect() vorher ermittelt werden, da Methoden
    1318             :     // mehreren Konzepten angehoeren koennen
    1319         390 :     pThis->maLastMethodSeq.realloc( nLen );
    1320         390 :     Reference<XIdlMethod>* pDestMethods = pThis->maLastMethodSeq.getArray();
    1321             : 
    1322             :     // Alle Methods durchgehen und entsprechend der Concepte uebernehmen
    1323         390 :     sal_Int32 iDest = 0;
    1324       30502 :     for( sal_Int32 i = 0 ; i < nLen ; i++ )
    1325             :     {
    1326       30112 :         sal_Int32 nConcept = pConcepts[ i ];
    1327       30112 :         if( nConcept & MethodConcepts )
    1328        7188 :             pDestMethods[ iDest++ ] = pSourceMethods[ i ];
    1329             : 
    1330             :     #if OSL_DEBUG_LEVEL > 0
    1331             :         static bool debug = false;
    1332             :         if ( debug )
    1333             :         {
    1334             :             // Methode mit Concepts ausgeben
    1335             :             const Reference< XIdlMethod >& rxMethod = pSourceMethods[ i ];
    1336             :             OString aNameStr = OUStringToOString( rxMethod->getName(), osl_getThreadTextEncoding() );
    1337             :             OString ConceptStr;
    1338             :             if( nConcept & MethodConcept::DANGEROUS )
    1339             :                 ConceptStr += "DANGEROUS |";
    1340             :             if( nConcept & MethodConcept::PROPERTY )
    1341             :                 ConceptStr += "PROPERTY |";
    1342             :             if( nConcept & MethodConcept::LISTENER )
    1343             :                 ConceptStr += "LISTENER |";
    1344             :             if( nConcept & MethodConcept::ENUMERATION )
    1345             :                 ConceptStr += "ENUMERATION |";
    1346             :             if( nConcept & MethodConcept::NAMECONTAINER )
    1347             :                 ConceptStr += "NAMECONTAINER |";
    1348             :             if( nConcept & MethodConcept::INDEXCONTAINER )
    1349             :                 ConceptStr += "INDEXCONTAINER |";
    1350             :             OSL_TRACE( "Method %ld: %s, Concepts = %s", i, aNameStr.getStr(), ConceptStr.getStr() );
    1351             :         }
    1352             :     #endif
    1353             :     }
    1354             : 
    1355             :     // Auf die richtige Laenge bringen
    1356         390 :     pThis->maLastMethodSeq.realloc( iDest );
    1357             : 
    1358             :     // MethodConcept merken, dies entspricht maLastMethodSeq
    1359         390 :     pThis->mnLastMethodConcept = MethodConcepts;
    1360             : 
    1361             :     // Zusammengebastelte Sequence liefern
    1362         390 :     return maLastMethodSeq;
    1363             : }
    1364             : 
    1365          18 : Sequence< Type > ImplIntrospectionAccess::getSupportedListeners(void)
    1366             :     throw( RuntimeException, std::exception )
    1367             : {
    1368          18 :     return mpStaticImpl->getSupportedListeners();
    1369             : }
    1370             : 
    1371       11564 : Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type& rType )
    1372             :     throw( IllegalTypeException, RuntimeException, std::exception )
    1373             : {
    1374             :     // Gibt es schon einen Adapter?
    1375       11564 :     Reference< XInterface > xAdapter( maAdapter );
    1376       11564 :     if( !xAdapter.is() )
    1377             :     {
    1378       10868 :         xAdapter = *( new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl ) );
    1379       10868 :         maAdapter = xAdapter;
    1380             :     }
    1381             : 
    1382       11564 :     Reference<XInterface> xRet;
    1383       11564 :     xAdapter->queryInterface( rType ) >>= xRet;
    1384       11564 :     return xRet;
    1385             : }
    1386             : 
    1387             : // Methoden von XMaterialHolder
    1388       53134 : Any ImplIntrospectionAccess::getMaterial(void) throw(RuntimeException, std::exception)
    1389             : {
    1390       53134 :     return maInspectedObject;
    1391             : }
    1392             : 
    1393             : // Hilfs-Funktion zur LowerCase-Wandlung eines OUString
    1394      111652 : OUString toLower( const OUString& aUStr )
    1395             : {
    1396             :     // Tabelle fuer XExactName pflegen
    1397      111652 :     OUString aOWStr( aUStr.getStr() );
    1398      223304 :     OUString aOWLowerStr = aOWStr.toAsciiLowerCase();
    1399      111652 :     OUString aLowerUStr( aOWLowerStr.getStr() );
    1400      223304 :     return aLowerUStr;
    1401             : }
    1402             : 
    1403             : // Methoden von XExactName
    1404        4708 : OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName ) throw( RuntimeException, std::exception )
    1405             : {
    1406        4708 :     OUString aRetStr;
    1407             :     LowerToExactNameMap::iterator aIt =
    1408        4708 :         mpStaticImpl->maLowerToExactNameMap.find( toLower( rApproximateName ) );
    1409        4708 :     if( !( aIt == mpStaticImpl->maLowerToExactNameMap.end() ) )
    1410        4386 :         aRetStr = (*aIt).second;
    1411        4708 :     return aRetStr;
    1412             : }
    1413             : 
    1414        1412 : struct ClassKey {
    1415        1162 :     ClassKey(
    1416             :         css::uno::Reference<css::beans::XPropertySetInfo> const & theProperties,
    1417             :         css::uno::Reference<css::reflection::XIdlClass> const &
    1418             :             theImplementation,
    1419             :         css::uno::Sequence< css::uno::Reference<css::reflection::XIdlClass> >
    1420             :             const & theClasses):
    1421             :         properties(theProperties), implementation(theImplementation),
    1422        1162 :         classes(theClasses)
    1423        1162 :     {}
    1424             : 
    1425             :     css::uno::Reference<css::beans::XPropertySetInfo> properties;
    1426             :     css::uno::Reference<css::reflection::XIdlClass> implementation;
    1427             :     css::uno::Sequence< css::uno::Reference<css::reflection::XIdlClass> >
    1428             :         classes;
    1429             : };
    1430             : 
    1431             : struct ClassKeyLess {
    1432        4317 :     bool operator ()(ClassKey const & key1, ClassKey const & key2) const {
    1433        4317 :         if (key1.properties.get() < key2.properties.get()) {
    1434           0 :             return true;
    1435             :         }
    1436        4317 :         if (key1.properties.get() > key2.properties.get()) {
    1437           0 :             return false;
    1438             :         }
    1439        4317 :         if (key1.implementation.get() < key2.implementation.get()) {
    1440        1726 :             return true;
    1441             :         }
    1442        2591 :         if (key1.implementation.get() > key2.implementation.get()) {
    1443         407 :             return false;
    1444             :         }
    1445        2184 :         if (key1.classes.getLength() < key2.classes.getLength()) {
    1446           0 :             return true;
    1447             :         }
    1448        2184 :         if (key1.classes.getLength() > key2.classes.getLength()) {
    1449           0 :             return false;
    1450             :         }
    1451        2216 :         for (sal_Int32 i = 0; i != key1.classes.getLength(); ++i) {
    1452          32 :             if (key1.classes[i].get() < key2.classes[i].get()) {
    1453           0 :                 return true;
    1454             :             }
    1455          32 :             if (key1.classes[i].get() > key2.classes[i].get()) {
    1456           0 :                 return false;
    1457             :             }
    1458             :         }
    1459        2184 :         return false;
    1460             :     }
    1461             : };
    1462             : 
    1463       18982 : struct TypeKey {
    1464       15766 :     TypeKey(
    1465             :         css::uno::Reference<css::beans::XPropertySetInfo> const & theProperties,
    1466             :         css::uno::Sequence<css::uno::Type> const & theTypes):
    1467       15766 :         properties(theProperties)
    1468             :     {
    1469             :         //TODO: Could even sort the types lexicographically first, to increase
    1470             :         // the chance of matches between different implementations' getTypes(),
    1471             :         // but the old scheme of using getImplementationId() would have missed
    1472             :         // those matches, too:
    1473       15766 :         OUStringBuffer b;
    1474      819572 :         for (sal_Int32 i = 0; i != theTypes.getLength(); ++i) {
    1475      803806 :             b.append(theTypes[i].getTypeName());
    1476      803806 :             b.append('*'); // arbitrary delimiter not used by type grammar
    1477             :         }
    1478       15766 :         types = b.makeStringAndClear();
    1479       15766 :     }
    1480             : 
    1481             :     css::uno::Reference<css::beans::XPropertySetInfo> properties;
    1482             :     OUString types;
    1483             : };
    1484             : 
    1485             : struct TypeKeyLess {
    1486       66895 :     bool operator ()(TypeKey const & key1, TypeKey const & key2) const {
    1487       66895 :         if (key1.properties.get() < key2.properties.get()) {
    1488       12484 :             return true;
    1489             :         }
    1490       54411 :         if (key1.properties.get() > key2.properties.get()) {
    1491        4363 :             return false;
    1492             :         }
    1493       50048 :         return key1.types < key2.types;
    1494             :     }
    1495             : };
    1496             : 
    1497         684 : template<typename Key, typename Less> class Cache {
    1498             : public:
    1499       16928 :     rtl::Reference<IntrospectionAccessStatic_Impl> find(Key const & key) const {
    1500       16928 :         typename Map::const_iterator i(map_.find(key));
    1501       16928 :         if (i == map_.end()) {
    1502         896 :             return rtl::Reference<IntrospectionAccessStatic_Impl>();
    1503             :         } else {
    1504       16032 :             if (i->second.hits < std::numeric_limits<unsigned>::max()) {
    1505       16032 :                 ++i->second.hits;
    1506             :             }
    1507             :             assert(i->second.access.is());
    1508       16032 :             return i->second.access;
    1509             :         }
    1510             :     }
    1511             : 
    1512         896 :     void insert(
    1513             :         Key const & key,
    1514             :         rtl::Reference<IntrospectionAccessStatic_Impl> const & access)
    1515             :     {
    1516             :         assert(access.is());
    1517         896 :         typename Map::size_type const MAX = 100;
    1518             :         assert(map_.size() <= MAX);
    1519         896 :         if (map_.size() == MAX) {
    1520         142 :             typename Map::iterator del(map_.begin());
    1521       14342 :             for (typename Map::iterator i(map_.begin()); i != map_.end(); ++i) {
    1522       14200 :                 if (i->second.hits < del->second.hits) {
    1523         518 :                     del = i;
    1524             :                 }
    1525             :             }
    1526         142 :             map_.erase(del);
    1527             :         }
    1528             :         bool ins = map_.insert(typename Map::value_type(key, Data(access)))
    1529         896 :             .second;
    1530             :         assert(ins); (void)ins;
    1531         896 :     }
    1532             : 
    1533         348 :     void clear() { map_.clear(); }
    1534             : 
    1535             : private:
    1536        4362 :     struct Data {
    1537         896 :         explicit Data(
    1538             :             rtl::Reference<IntrospectionAccessStatic_Impl> const & theAccess):
    1539         896 :             access(theAccess), hits(1)
    1540         896 :         {}
    1541             : 
    1542             :         rtl::Reference<IntrospectionAccessStatic_Impl> access;
    1543             :         mutable unsigned hits;
    1544             :     };
    1545             : 
    1546             :     typedef std::map<Key, Data, Less> Map;
    1547             : 
    1548             :     Map map_;
    1549             : };
    1550             : 
    1551             : typedef
    1552             :     cppu::WeakComponentImplHelper2<
    1553             :         css::lang::XServiceInfo, css::beans::XIntrospection>
    1554             :     Implementation_Base;
    1555             : 
    1556         328 : class Implementation: private cppu::BaseMutex, public Implementation_Base {
    1557             : public:
    1558         178 :     explicit Implementation(
    1559             :         css::uno::Reference<css::uno::XComponentContext> const & context):
    1560             :         Implementation_Base(m_aMutex),
    1561         178 :         reflection_(css::reflection::theCoreReflection::get(context))
    1562         178 :     {}
    1563             : 
    1564             : private:
    1565         174 :     virtual void SAL_CALL disposing() SAL_OVERRIDE {
    1566         174 :         reflection_.clear();
    1567         174 :         classCache_.clear();
    1568         174 :         typeCache_.clear();
    1569         174 :     }
    1570             : 
    1571           0 :     virtual OUString SAL_CALL getImplementationName()
    1572             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1573           0 :     { return OUString("com.sun.star.comp.stoc.Introspection"); }
    1574             : 
    1575           0 :     virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
    1576             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1577           0 :     { return cppu::supportsService(this, ServiceName); }
    1578             : 
    1579             :     virtual css::uno::Sequence<OUString> SAL_CALL
    1580           0 :     getSupportedServiceNames()
    1581             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
    1582             :     {
    1583           0 :         Sequence<OUString> s(1);
    1584           0 :         s[0] = "com.sun.star.beans.Introspection";
    1585           0 :         return s;
    1586             :     }
    1587             : 
    1588             :     virtual css::uno::Reference<css::beans::XIntrospectionAccess> SAL_CALL
    1589             :     inspect(css::uno::Any const & aObject)
    1590             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
    1591             : 
    1592             :     css::uno::Reference<css::reflection::XIdlReflection> reflection_;
    1593             :     Cache<ClassKey, ClassKeyLess> classCache_;
    1594             :     Cache<TypeKey, TypeKeyLess> typeCache_;
    1595             : };
    1596             : 
    1597       32732 : css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
    1598             :     css::uno::Any const & aObject)
    1599             :     throw (css::uno::RuntimeException, std::exception)
    1600             : {
    1601       32732 :     osl::MutexGuard g(m_aMutex);
    1602       32732 :     if (rBHelper.bDisposed) {
    1603             :         throw css::lang::DisposedException(
    1604           0 :             getImplementationName(), static_cast<OWeakObject *>(this));
    1605             :     }
    1606       65464 :     css::uno::Any aToInspectObj;
    1607       65464 :     css::uno::Type t;
    1608       32732 :     if (aObject >>= t) {
    1609             :         css::uno::Reference<css::reflection::XIdlClass> c(
    1610           0 :             reflection_->forName(t.getTypeName()));
    1611           0 :         if (!c.is()) {
    1612             :             SAL_WARN("stoc", "cannot reflect type " << t.getTypeName());
    1613           0 :             return css::uno::Reference<css::beans::XIntrospectionAccess>();
    1614             :         }
    1615           0 :         aToInspectObj <<= c;
    1616             :     } else {
    1617       32732 :         aToInspectObj = aObject;
    1618             :     }
    1619             : 
    1620             :     // Objekt untersuchen
    1621       32732 :     TypeClass eType = aToInspectObj.getValueType().getTypeClass();
    1622       32732 :     if( eType != TypeClass_INTERFACE && eType != TypeClass_STRUCT  && eType != TypeClass_EXCEPTION )
    1623       15804 :         return css::uno::Reference<css::beans::XIntrospectionAccess>();
    1624             : 
    1625       33856 :     Reference<XInterface> x;
    1626       16928 :     if( eType == TypeClass_INTERFACE )
    1627             :     {
    1628             :         // Interface aus dem Any besorgen
    1629       15786 :         x = *(Reference<XInterface>*)aToInspectObj.getValue();
    1630       15786 :         if( !x.is() )
    1631           0 :             return css::uno::Reference<css::beans::XIntrospectionAccess>();
    1632             :     }
    1633             : 
    1634             :     // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
    1635       33856 :     rtl::Reference< IntrospectionAccessStatic_Impl > pAccess;
    1636             : 
    1637             :     // Pruefen: Ist schon ein passendes Access-Objekt gecached?
    1638       33856 :     Sequence< Reference<XIdlClass> >    SupportedClassSeq;
    1639       33856 :     Sequence< Type >                    SupportedTypesSeq;
    1640       33856 :     Reference<XTypeProvider>            xTypeProvider;
    1641       33856 :     Reference<XIdlClass>                xImplClass;
    1642       33856 :     Reference<XPropertySetInfo>            xPropSetInfo;
    1643       33856 :     Reference<XPropertySet>                xPropSet;
    1644             : 
    1645             :     // Look for interfaces XTypeProvider and PropertySet
    1646       16928 :     if( eType == TypeClass_INTERFACE )
    1647             :     {
    1648       15786 :         xTypeProvider = Reference<XTypeProvider>::query( x );
    1649       15786 :         if( xTypeProvider.is() )
    1650             :         {
    1651       15766 :             SupportedTypesSeq = xTypeProvider->getTypes();
    1652       15766 :             sal_Int32 nTypeCount = SupportedTypesSeq.getLength();
    1653       15766 :             if( nTypeCount )
    1654             :             {
    1655       15766 :                 SupportedClassSeq.realloc( nTypeCount );
    1656       15766 :                 Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray();
    1657             : 
    1658       15766 :                 const Type* pTypes = SupportedTypesSeq.getConstArray();
    1659      819572 :                 for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
    1660             :                 {
    1661      803806 :                     pClasses[i] = reflection_->forName(pTypes[i].getTypeName());
    1662             :                 }
    1663             :                 // TODO: Caching!
    1664             :             }
    1665             :         } else {
    1666             :             SAL_WARN(
    1667             :                 "stoc",
    1668             :                 "object of type \"" << aToInspectObj.getValueTypeName()
    1669             :                     << "\" lacks XTypeProvider");
    1670          20 :             xImplClass = reflection_->forName(aToInspectObj.getValueTypeName());
    1671          20 :             SupportedClassSeq.realloc(1);
    1672          20 :             SupportedClassSeq[0] = xImplClass;
    1673             :         }
    1674             : 
    1675       15786 :         xPropSet = Reference<XPropertySet>::query( x );
    1676             :         // Jetzt versuchen, das PropertySetInfo zu bekommen
    1677       15786 :         if( xPropSet.is() )
    1678       11204 :             xPropSetInfo = xPropSet->getPropertySetInfo();
    1679             :     } else {
    1680        1142 :         xImplClass = reflection_->forName(aToInspectObj.getValueTypeName());
    1681             :     }
    1682             : 
    1683       16928 :     if (xTypeProvider.is()) {
    1684       15766 :         TypeKey key(xPropSetInfo, xTypeProvider->getTypes());
    1685       15766 :         pAccess = typeCache_.find(key);
    1686       15766 :         if (pAccess.is()) {
    1687       14940 :             return new ImplIntrospectionAccess(aToInspectObj, pAccess);
    1688             :         }
    1689         826 :         pAccess = new IntrospectionAccessStatic_Impl(reflection_);
    1690         826 :         typeCache_.insert(key, pAccess);
    1691        1162 :     } else if (xImplClass.is()) {
    1692        1162 :         ClassKey key(xPropSetInfo, xImplClass, SupportedClassSeq);
    1693        1162 :         pAccess = classCache_.find(key);
    1694        1162 :         if (pAccess.is()) {
    1695        1092 :             return new ImplIntrospectionAccess(aToInspectObj, pAccess);
    1696             :         }
    1697          70 :         pAccess = new IntrospectionAccessStatic_Impl(reflection_);
    1698          70 :         classCache_.insert(key, pAccess);
    1699             :     }
    1700             : 
    1701             :     // Kein Access gecached -> neu anlegen
    1702             :     Property* pAllPropArray;
    1703             :     Reference<XInterface>* pInterfaces1;
    1704             :     Reference<XInterface>* pInterfaces2;
    1705             :     sal_Int16* pMapTypeArray;
    1706             :     sal_Int32* pPropertyConceptArray;
    1707             :     sal_Int32 i;
    1708             : 
    1709         896 :     if( !pAccess.is() )
    1710           0 :         pAccess = new IntrospectionAccessStatic_Impl( reflection_ );
    1711             : 
    1712             :     // Referenzen auf wichtige Daten von pAccess
    1713         896 :     sal_Int32& rPropCount = pAccess->mnPropCount;
    1714         896 :     IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
    1715         896 :     IntrospectionNameMap& rMethodNameMap = pAccess->maMethodNameMap;
    1716         896 :     LowerToExactNameMap& rLowerToExactNameMap = pAccess->maLowerToExactNameMap;
    1717             : 
    1718             :     // Schon mal Pointer auf das eigene Property-Feld holen
    1719         896 :     pAllPropArray = pAccess->maAllPropertySeq.getArray();
    1720         896 :     pInterfaces1 = pAccess->aInterfaceSeq1.getArray();
    1721         896 :     pInterfaces2 = pAccess->aInterfaceSeq2.getArray();
    1722         896 :     pMapTypeArray = pAccess->maMapTypeSeq.getArray();
    1723         896 :     pPropertyConceptArray = pAccess->maPropertyConceptSeq.getArray();
    1724             : 
    1725             : 
    1726             :     //*** Analyse vornehmen ***
    1727             : 
    1728         896 :     if( eType == TypeClass_INTERFACE )
    1729             :     {
    1730             :         // Zunaechst nach speziellen Interfaces suchen, die fuer
    1731             :         // die Introspection von besonderer Bedeutung sind.
    1732             : 
    1733             :         // XPropertySet vorhanden?
    1734         830 :         if( xPropSet.is() && xPropSetInfo.is() )
    1735             :         {
    1736             :             // Gibt es auch ein FastPropertySet?
    1737         468 :             Reference<XFastPropertySet> xDummy = Reference<XFastPropertySet>::query( x );
    1738         468 :             bool bFast = pAccess->mbFastPropSet = xDummy.is();
    1739             : 
    1740         936 :             Sequence<Property> aPropSeq = xPropSetInfo->getProperties();
    1741         468 :             const Property* pProps = aPropSeq.getConstArray();
    1742         468 :             sal_Int32 nLen = aPropSeq.getLength();
    1743             : 
    1744             :             // Bei FastPropertySet muessen wir uns die Original-Handles merken
    1745         468 :             if( bFast )
    1746         190 :                 pAccess->mpOrgPropertyHandleArray = new sal_Int32[ nLen ];
    1747             : 
    1748       21744 :             for( i = 0 ; i < nLen ; i++ )
    1749             :             {
    1750             :                 // Property in eigene Liste uebernehmen
    1751             :                 pAccess->checkPropertyArraysSize
    1752       21276 :                     ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
    1753       21276 :                 Property& rProp = pAllPropArray[ rPropCount ];
    1754       21276 :                 rProp = pProps[ i ];
    1755             : 
    1756       21276 :                 if( bFast )
    1757       10592 :                     pAccess->mpOrgPropertyHandleArray[ i ] = rProp.Handle;
    1758             : 
    1759             :                 // PropCount als Handle fuer das eigene FastPropertySet eintragen
    1760       21276 :                 rProp.Handle = rPropCount;
    1761             : 
    1762             :                 // Art der Property merken
    1763       21276 :                 pMapTypeArray[ rPropCount ] = MAP_PROPERTY_SET;
    1764       21276 :                 pPropertyConceptArray[ rPropCount ] = PROPERTYSET;
    1765       21276 :                 pAccess->mnPropertySetPropCount++;
    1766             : 
    1767             :                 // Namen in Hashtable eintragen, wenn nicht schon bekannt
    1768       21276 :                 OUString aPropName = rProp.Name;
    1769             : 
    1770             :                 // Haben wir den Namen schon?
    1771       21276 :                 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
    1772       21276 :                 if( aIt == rPropNameMap.end() )
    1773             :                 {
    1774             :                     // Neuer Eintrag in die Hashtable
    1775       21276 :                     rPropNameMap[ aPropName ] = rPropCount;
    1776             : 
    1777             :                     // Tabelle fuer XExactName pflegen
    1778       21276 :                     rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
    1779             :                 }
    1780             :                 else
    1781             :                 {
    1782             :                     SAL_WARN( "stoc", "Introspection: Property \"" <<
    1783             :                         aPropName << "\" found more than once in PropertySet" );
    1784             :                 }
    1785             : 
    1786             :                 // Count pflegen
    1787       21276 :                 rPropCount++;
    1788       21744 :             }
    1789             :         }
    1790             : 
    1791             :         // Indizes in die Export-Tabellen
    1792         830 :         sal_Int32 iAllExportedMethod = 0;
    1793         830 :         sal_Int32 iAllSupportedListener = 0;
    1794             : 
    1795         830 :         std::set<OUString> seen;
    1796             : 
    1797             :         // Flag, ob XInterface-Methoden erfasst werden sollen
    1798             :         // (das darf nur einmal erfolgen, initial zulassen)
    1799         830 :         bool bXInterfaceIsInvalid = false;
    1800             : 
    1801             :         // Flag, ob die XInterface-Methoden schon erfasst wurden. Wenn sal_True,
    1802             :         // wird bXInterfaceIsInvalid am Ende der Iface-Schleife aktiviert und
    1803             :         // XInterface-Methoden werden danach abgeklemmt.
    1804         830 :         bool bFoundXInterface = false;
    1805             : 
    1806         830 :         sal_Int32 nClassCount = SupportedClassSeq.getLength();
    1807       23654 :         for( sal_Int32 nIdx = 0 ; nIdx < nClassCount; nIdx++ )
    1808             :         {
    1809       22824 :             Reference<XIdlClass> xImplClass2 = SupportedClassSeq.getConstArray()[nIdx];
    1810       95718 :             while( xImplClass2.is() )
    1811             :             {
    1812             :                 // Interfaces der Implementation holen
    1813       50070 :                 Sequence< Reference<XIdlClass> > aClassSeq = xImplClass2->getInterfaces();
    1814       50070 :                 sal_Int32 nIfaceCount = aClassSeq.getLength();
    1815             : 
    1816       50070 :                 aClassSeq.realloc( nIfaceCount + 1 );
    1817       50070 :                 aClassSeq.getArray()[ nIfaceCount ] = xImplClass2;
    1818       50070 :                 nIfaceCount++;
    1819             : 
    1820       50070 :                 const Reference<XIdlClass>* pParamArray = aClassSeq.getConstArray();
    1821             : 
    1822      100140 :                 for( sal_Int32 j = 0 ; j < nIfaceCount ; j++ )
    1823             :                 {
    1824       50070 :                     const Reference<XIdlClass>& rxIfaceClass = pParamArray[j];
    1825       50070 :                     if (!seen.insert(rxIfaceClass->getName()).second) {
    1826       25504 :                         continue;
    1827             :                     }
    1828             : 
    1829             :                     // 2. Fields als Properties registrieren
    1830             : 
    1831             :                     // Felder holen
    1832       24566 :                     Sequence< Reference<XIdlField> > fields = rxIfaceClass->getFields();
    1833       24566 :                     const Reference<XIdlField>* pFields = fields.getConstArray();
    1834       24566 :                     sal_Int32 nLen = fields.getLength();
    1835             : 
    1836       29288 :                     for( i = 0 ; i < nLen ; i++ )
    1837             :                     {
    1838        4722 :                         Reference<XIdlField> xField = pFields[i];
    1839        7692 :                         Reference<XIdlClass> xPropType = xField->getType();
    1840             : 
    1841             :                         // Ist die PropertySequence gross genug?
    1842             :                         pAccess->checkPropertyArraysSize
    1843        4722 :                             ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
    1844             : 
    1845             :                         // In eigenes Property-Array eintragen
    1846        4722 :                         Property& rProp = pAllPropArray[ rPropCount ];
    1847        7692 :                         OUString aFieldName = xField->getName();
    1848        4722 :                         rProp.Name = aFieldName;
    1849        4722 :                         rProp.Handle = rPropCount;
    1850        7692 :                         Type aFieldType( xPropType->getTypeClass(), xPropType->getName() );
    1851        4722 :                         rProp.Type = aFieldType;
    1852        4722 :                         FieldAccessMode eAccessMode = xField->getAccessMode();
    1853        1390 :                         rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
    1854             :                                             eAccessMode == FieldAccessMode_CONST)
    1855        8054 :                             ? READONLY : 0;
    1856             : 
    1857             :                         // Namen in Hashtable eintragen
    1858        7692 :                         OUString aPropName = rProp.Name;
    1859             : 
    1860             :                         // Haben wir den Namen schon?
    1861        4722 :                         IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
    1862        4722 :                         if( !( aIt == rPropNameMap.end() ) )
    1863        1752 :                             continue;
    1864             : 
    1865             :                         // Neuer Eintrag in die Hashtable
    1866        2970 :                         rPropNameMap[ aPropName ] = rPropCount;
    1867             : 
    1868             :                         // Tabelle fuer XExactName pflegen
    1869        2970 :                         rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
    1870             : 
    1871             :                         // Field merken
    1872        2970 :                         pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
    1873        5940 :                                                           pInterfaces1, rPropCount );
    1874        2970 :                         pInterfaces1[ rPropCount ] = xField;
    1875             : 
    1876             :                         // Art der Property merken
    1877        2970 :                         pMapTypeArray[ rPropCount ] = MAP_FIELD;
    1878        2970 :                         pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
    1879        2970 :                         pAccess->mnAttributePropCount++;
    1880             : 
    1881             :                         // Count pflegen
    1882        2970 :                         rPropCount++;
    1883        2970 :                     }
    1884             : 
    1885             : 
    1886             : 
    1887             :                     // 3. Methoden
    1888             : 
    1889             :                     // Zaehler fuer die gefundenen Listener
    1890       24566 :                     sal_Int32 nListenerCount = 0;
    1891             : 
    1892             :                     // Alle Methoden holen und merken
    1893       49132 :                     Sequence< Reference<XIdlMethod> > methods = rxIfaceClass->getMethods();
    1894       24566 :                     const Reference<XIdlMethod>* pSourceMethods = methods.getConstArray();
    1895       24566 :                     sal_Int32 nSourceMethodCount = methods.getLength();
    1896             : 
    1897             :                     // 3. a) get/set- und Listener-Methoden suchen
    1898             : 
    1899             :                     // Feld fuer Infos ueber die Methoden anlegen, damit spaeter leicht die Methoden
    1900             :                     // gefunden werden koennen, die nicht im Zusammenhang mit Properties oder Listenern
    1901             :                     // stehen. NEU: auch MethodConceptArray initialisieren
    1902             :                     enum MethodType
    1903             :                     {
    1904             :                         STANDARD_METHOD,            // normale Methode, kein Bezug zu Properties oder Listenern
    1905             :                         GETSET_METHOD,                // gehoert zu einer get/set-Property
    1906             :                         ADD_LISTENER_METHOD,        // add-Methode einer Listener-Schnittstelle
    1907             :                         REMOVE_LISTENER_METHOD,        // remove-Methode einer Listener-Schnittstelle
    1908             :                         INVALID_METHOD                // Methode, deren Klasse nicht beruecksichtigt wird, z.B. XPropertySet
    1909             :                     };
    1910       24566 :                     MethodType* pMethodTypes = new MethodType[ nSourceMethodCount ];
    1911       24566 :                     sal_Int32* pLocalMethodConcepts = new sal_Int32[ nSourceMethodCount ];
    1912      181156 :                     for( i = 0 ; i < nSourceMethodCount ; i++ )
    1913             :                     {
    1914      156590 :                         pMethodTypes[ i ] = STANDARD_METHOD;
    1915      156590 :                         pLocalMethodConcepts[ i ] = 0;
    1916             :                     }
    1917             : 
    1918       49132 :                     OUString aMethName;
    1919       49132 :                     OUString aPropName;
    1920       49132 :                     OUString aStartStr;
    1921      181156 :                     for( i = 0 ; i < nSourceMethodCount ; i++ )
    1922             :                     {
    1923             :                         // Methode ansprechen
    1924      156590 :                         const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
    1925      156590 :                         sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
    1926             : 
    1927             :                         // Namen besorgen
    1928      156590 :                         aMethName = rxMethod_i->getName();
    1929             : 
    1930             :                         // Methoden katalogisieren
    1931             :                         // Alle (?) Methoden von XInterface filtern, damit z.B. nicht
    1932             :                         // vom Scripting aus acquire oder release gerufen werden kann
    1933             :                         rtl::OUString className(
    1934      156590 :                             rxMethod_i->getDeclaringClass()->getName());
    1935      156590 :                         if (className == "com.sun.star.uno.XInterface") {
    1936       73698 :                             bFoundXInterface = true;
    1937             : 
    1938       73698 :                             if( bXInterfaceIsInvalid )
    1939             :                             {
    1940       71208 :                                 pMethodTypes[ i ] = INVALID_METHOD;
    1941       71208 :                                 continue;
    1942             :                             }
    1943             :                             else
    1944             :                             {
    1945        2490 :                                 if( aMethName != "queryInterface" )
    1946             :                                 {
    1947        1660 :                                     rMethodConcept_i |= MethodConcept::DANGEROUS;
    1948        1660 :                                     continue;
    1949             :                                 }
    1950             :                             }
    1951       82892 :                         } else if (className == "com.sun.star.uno.XAggregation")
    1952             :                         {
    1953         780 :                             if( aMethName == "setDelegator" )
    1954             :                             {
    1955         390 :                                 rMethodConcept_i |= MethodConcept::DANGEROUS;
    1956         390 :                                 continue;
    1957             :                             }
    1958       82112 :                         } else if (className
    1959             :                                    == "com.sun.star.container.XElementAccess")
    1960             :                         {
    1961             :                             rMethodConcept_i |= ( NAMECONTAINER  |
    1962             :                                                   INDEXCONTAINER |
    1963        1592 :                                                   ENUMERATION );
    1964       80520 :                         } else if ((className
    1965       80520 :                                     == "com.sun.star.container.XNameContainer")
    1966      160920 :                                    || (className
    1967       80400 :                                        == "com.sun.star.container.XNameAccess"))
    1968             :                         {
    1969        1764 :                             rMethodConcept_i |= NAMECONTAINER;
    1970       78756 :                         } else if ((className
    1971       78756 :                                     == "com.sun.star.container.XIndexContainer")
    1972      157512 :                                    || (className
    1973       78756 :                                        == "com.sun.star.container.XIndexAccess"))
    1974             :                         {
    1975          24 :                             rMethodConcept_i |= INDEXCONTAINER;
    1976       78732 :                         } else if (className
    1977             :                                    == "com.sun.star.container.XEnumerationAccess")
    1978             :                         {
    1979          88 :                             rMethodConcept_i |= ENUMERATION;
    1980             :                         }
    1981             : 
    1982             :                         // Wenn der Name zu kurz ist, wird's sowieso nichts
    1983       83332 :                         if( aMethName.getLength() <= 3 )
    1984          30 :                             continue;
    1985             : 
    1986             :                         // Ist es eine get-Methode?
    1987       83302 :                         aStartStr = aMethName.copy( 0, 3 );
    1988       83302 :                         if( aStartStr == "get" )
    1989             :                         {
    1990             :                             // Namen der potentiellen Property
    1991       28178 :                             aPropName = aMethName.copy( 3 );
    1992             : 
    1993             :                             // get-Methode darf keinen Parameter haben
    1994       28178 :                             Sequence< Reference<XIdlClass> > getParams = rxMethod_i->getParameterTypes();
    1995       28178 :                             if( getParams.getLength() > 0 )
    1996             :                             {
    1997        8792 :                                 continue;
    1998             :                             }
    1999             : 
    2000             :                             // Haben wir den Namen schon?
    2001       19386 :                             IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
    2002       19386 :                             if( !( aIt == rPropNameMap.end() ) )
    2003             :                             {
    2004             :                                 /* TODO
    2005             :                                    OSL_TRACE(
    2006             :                                    String( "Introspection: Property \"" ) +
    2007             :                                    OOUStringToString( aPropName, CHARSET_SYSTEM ) +
    2008             :                                    String( "\" found more than once" ) );
    2009             :                                 */
    2010        4032 :                                 continue;
    2011             :                             }
    2012             : 
    2013             :                             // Eine readonly-Property ist es jetzt mindestens schon
    2014       15354 :                             rMethodConcept_i |= PROPERTY;
    2015             : 
    2016       15354 :                             pMethodTypes[i] = GETSET_METHOD;
    2017       30708 :                             Reference<XIdlClass> xGetRetType = rxMethod_i->getReturnType();
    2018             : 
    2019             :                             // Ist die PropertySequence gross genug?
    2020             :                             pAccess->checkPropertyArraysSize
    2021       15354 :                                 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
    2022             : 
    2023             :                             // In eigenes Property-Array eintragen
    2024       15354 :                             Property& rProp = pAllPropArray[ rPropCount ];
    2025       15354 :                             rProp.Name = aPropName;
    2026       15354 :                             rProp.Handle = rPropCount;
    2027       15354 :                             rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
    2028       15354 :                             rProp.Attributes = READONLY;
    2029             : 
    2030             :                             // Neuer Eintrag in die Hashtable
    2031       15354 :                             rPropNameMap[ aPropName ] = rPropCount;
    2032             : 
    2033             :                             // Tabelle fuer XExactName pflegen
    2034       15354 :                             rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
    2035             : 
    2036             :                             // get-Methode merken
    2037       15354 :                             pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
    2038       30708 :                                                               pInterfaces1, rPropCount );
    2039       15354 :                             pInterfaces1[ rPropCount ] = rxMethod_i;
    2040             : 
    2041             :                             // Art der Property merken
    2042       15354 :                             pMapTypeArray[ rPropCount ] = MAP_GETSET;
    2043       15354 :                             pPropertyConceptArray[ rPropCount ] = METHODS;
    2044       15354 :                             pAccess->mnMethodPropCount++;
    2045             : 
    2046             :                             // Passende set-Methode suchen
    2047             :                             sal_Int32 k;
    2048      154276 :                             for( k = 0 ; k < nSourceMethodCount ; k++ )
    2049             :                             {
    2050             :                                 // Methode ansprechen
    2051      138922 :                                 const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
    2052             : 
    2053             :                                 // Nur Methoden nehmen, die nicht schon zugeordnet sind
    2054      138922 :                                 if( k == i || pMethodTypes[k] != STANDARD_METHOD )
    2055      211450 :                                     continue;
    2056             : 
    2057             :                                 // Name holen und auswerten
    2058       64064 :                                 OUString aMethName2 = rxMethod_k->getName();
    2059       66394 :                                 OUString aStartStr2 = aMethName2.copy( 0, 3 );
    2060             :                                 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
    2061       64064 :                                 if( !( aStartStr2 == "set" ) )
    2062       57360 :                                     continue;
    2063             : 
    2064             :                                 // Ist es denn der gleiche Name?
    2065        9034 :                                 OUString aPropName2 = aMethName2.copy( 3 );
    2066             :                                 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
    2067        6704 :                                 if( !( aPropName == aPropName2 ) )
    2068        4176 :                                     continue;
    2069             : 
    2070             :                                 // set-Methode muss void returnen
    2071        4858 :                                 Reference<XIdlClass> xSetRetType = rxMethod_k->getReturnType();
    2072        2528 :                                 if( xSetRetType->getTypeClass() != TypeClass_VOID )
    2073             :                                 {
    2074         132 :                                     continue;
    2075             :                                 }
    2076             : 
    2077             :                                 // set-Methode darf nur einen Parameter haben
    2078        4726 :                                 Sequence< Reference<XIdlClass> > setParams = rxMethod_k->getParameterTypes();
    2079        2396 :                                 sal_Int32 nParamCount = setParams.getLength();
    2080        2396 :                                 if( nParamCount != 1 )
    2081             :                                 {
    2082          66 :                                     continue;
    2083             :                                 }
    2084             : 
    2085             :                                 // Jetzt muss nur noch der return-Typ dem Parameter-Typ entsprechen
    2086        2330 :                                 const Reference<XIdlClass>* pParamArray2 = setParams.getConstArray();
    2087        4660 :                                 Reference<XIdlClass> xParamType = pParamArray2[ 0 ];
    2088        2330 :                                 if( xParamType->equals( xGetRetType ) )
    2089             :                                 {
    2090        2330 :                                     pLocalMethodConcepts[ k ] = PROPERTY;
    2091             : 
    2092        2330 :                                     pMethodTypes[k] = GETSET_METHOD;
    2093             : 
    2094             :                                     // ReadOnly-Flag wieder loschen
    2095        2330 :                                     rProp.Attributes &= ~READONLY;
    2096             : 
    2097             :                                     // set-Methode merken
    2098        2330 :                                     pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
    2099        4660 :                                                                       pInterfaces2, rPropCount );
    2100        2330 :                                     pInterfaces2[ rPropCount ] = rxMethod_k;
    2101             :                                 }
    2102        2330 :                             }
    2103             : 
    2104             :                             // Count pflegen
    2105       30708 :                             rPropCount++;
    2106             :                         }
    2107             : 
    2108             :                         // Ist es eine addListener-Methode?
    2109       55124 :                         else if( aStartStr == "add" )
    2110             :                         {
    2111        8032 :                             OUString aListenerStr( "Listener" );
    2112             : 
    2113             :                             // Namen der potentiellen Property
    2114        8032 :                             sal_Int32 nStrLen = aMethName.getLength();
    2115        8032 :                             sal_Int32 nCopyLen = nStrLen - aListenerStr.getLength();
    2116       14938 :                             OUString aEndStr = aMethName.copy( nCopyLen > 0 ? nCopyLen : 0 );
    2117             : 
    2118             :                             // Endet das Teil auf Listener?
    2119             :                             // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
    2120        8032 :                             if( !( aEndStr == aListenerStr ) )
    2121        1126 :                                 continue;
    2122             : 
    2123             :                             // Welcher Listener?
    2124       13812 :                             OUString aListenerName = aMethName.copy( 3, nStrLen - aListenerStr.getLength() - 3 );
    2125             : 
    2126             :                             // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
    2127             :                             // - Rueckgabe-Typ
    2128             :                             // - Anzahl und Art der Parameter
    2129             : 
    2130             : 
    2131             :                             // Passende remove-Methode suchen, sonst gilt's nicht
    2132             :                             sal_Int32 k;
    2133       85722 :                             for( k = 0 ; k < nSourceMethodCount ; k++ )
    2134             :                             {
    2135             :                                 // Methode ansprechen
    2136       78816 :                                 const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
    2137             : 
    2138             :                                 // Nur Methoden nehmen, die nicht schon zugeordnet sind
    2139       78816 :                                 if( k == i || pMethodTypes[k] != STANDARD_METHOD )
    2140      106978 :                                     continue;
    2141             : 
    2142             :                                 // Name holen und auswerten
    2143       43748 :                                 OUString aMethName2 = rxMethod_k->getName();
    2144       43748 :                                 sal_Int32 nNameLen = aMethName2.getLength();
    2145       43748 :                                 sal_Int32 nCopyLen2 = (nNameLen < 6) ? nNameLen : 6;
    2146       50654 :                                 OUString aStartStr2 = aMethName2.copy( 0, nCopyLen2 );
    2147       50654 :                                 OUString aRemoveStr("remove" );
    2148             :                                 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
    2149       43748 :                                 if( !( aStartStr2 == aRemoveStr ) )
    2150       33072 :                                     continue;
    2151             : 
    2152             :                                 // Ist es denn der gleiche Listener?
    2153       10676 :                                 if( aMethName2.getLength() - aRemoveStr.getLength() <= aListenerStr.getLength() )
    2154         324 :                                     continue;
    2155             :                                 OUString aListenerName2 = aMethName2.copy
    2156       17258 :                                       ( 6, aMethName2.getLength() - aRemoveStr.getLength() - aListenerStr.getLength() );
    2157             :                                 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
    2158       10352 :                                 if( !( aListenerName == aListenerName2 ) )
    2159        3446 :                                     continue;
    2160             : 
    2161             :                                 // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
    2162             :                                 // - Rueckgabe-Typ
    2163             :                                 // - Anzahl und Art der Parameter
    2164             : 
    2165             : 
    2166             :                                 // Methoden sind als Listener-Schnittstelle erkannt
    2167        6906 :                                 rMethodConcept_i |= LISTENER;
    2168        6906 :                                 pLocalMethodConcepts[ k ] |= LISTENER;
    2169             : 
    2170        6906 :                                 pMethodTypes[i] = ADD_LISTENER_METHOD;
    2171        6906 :                                 pMethodTypes[k] = REMOVE_LISTENER_METHOD;
    2172        6906 :                                 nListenerCount++;
    2173       13812 :                             }
    2174             :                         }
    2175       69352 :                     }
    2176             : 
    2177             : 
    2178             :                     // Jetzt koennen noch SET-Methoden ohne zugehoerige GET-Methode existieren,
    2179             :                     // diese muessen zu Write-Only-Properties gemachte werden.
    2180      181156 :                     for( i = 0 ; i < nSourceMethodCount ; i++ )
    2181             :                     {
    2182             :                         // Methode ansprechen
    2183      156590 :                         const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
    2184             : 
    2185             :                         // Nur Methoden nehmen, die nicht schon zugeordnet sind
    2186      156590 :                         if( pMethodTypes[i] != STANDARD_METHOD )
    2187      102704 :                             continue;
    2188             : 
    2189             :                         // Namen besorgen
    2190       53886 :                         aMethName = rxMethod_i->getName();
    2191             : 
    2192             :                         // Wenn der Name zu kurz ist, wird's sowieso nichts
    2193       53886 :                         if( aMethName.getLength() <= 3 )
    2194          30 :                             continue;
    2195             : 
    2196             :                         // Ist es eine set-Methode ohne zugehoerige get-Methode?
    2197       53856 :                         aStartStr = aMethName.copy( 0, 3 );
    2198       53856 :                         if( aStartStr == "set" )
    2199             :                         {
    2200             :                             // Namen der potentiellen Property
    2201        4516 :                             aPropName = aMethName.copy( 3 );
    2202             : 
    2203             :                             // set-Methode muss void returnen
    2204        4516 :                             Reference<XIdlClass> xSetRetType = rxMethod_i->getReturnType();
    2205        4516 :                             if( xSetRetType->getTypeClass() != TypeClass_VOID )
    2206             :                             {
    2207         146 :                                 continue;
    2208             :                             }
    2209             : 
    2210             :                             // set-Methode darf nur einen Parameter haben
    2211        5664 :                             Sequence< Reference<XIdlClass> > setParams = rxMethod_i->getParameterTypes();
    2212        4370 :                             sal_Int32 nParamCount = setParams.getLength();
    2213        4370 :                             if( nParamCount != 1 )
    2214             :                             {
    2215        1972 :                                 continue;
    2216             :                             }
    2217             : 
    2218             :                             // Haben wir den Namen schon?
    2219        2398 :                             IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
    2220        2398 :                             if( !( aIt == rPropNameMap.end() ) )
    2221             :                             {
    2222             :                                 /* TODO:
    2223             :                                    OSL_TRACE(
    2224             :                                    String( "Introspection: Property \"" ) +
    2225             :                                    OOUStringToString( aPropName, CHARSET_SYSTEM ) +
    2226             :                                    String( "\" found more than once" ) );
    2227             :                                 */
    2228        1104 :                                 continue;
    2229             :                             }
    2230             : 
    2231             :                             // Alles klar, es ist eine Write-Only-Property
    2232        1294 :                             pLocalMethodConcepts[ i ] = PROPERTY;
    2233             : 
    2234        1294 :                             pMethodTypes[i] = GETSET_METHOD;
    2235        2588 :                             Reference<XIdlClass> xGetRetType = setParams.getConstArray()[0];
    2236             : 
    2237             :                             // Ist die PropertySequence gross genug?
    2238             :                             pAccess->checkPropertyArraysSize
    2239        1294 :                                 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
    2240             : 
    2241             :                             // In eigenes Property-Array eintragen
    2242        1294 :                             Property& rProp = pAllPropArray[ rPropCount ];
    2243        1294 :                             rProp.Name = aPropName;
    2244        1294 :                             rProp.Handle = rPropCount;
    2245        1294 :                             rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
    2246        1294 :                             rProp.Attributes = 0;    // PROPERTY_WRITEONLY ???
    2247             : 
    2248             :                             // Neuer Eintrag in die Hashtable
    2249        1294 :                             rPropNameMap[ aPropName ] = rPropCount;
    2250             : 
    2251             :                             // Tabelle fuer XExactName pflegen
    2252        1294 :                             rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
    2253             : 
    2254             :                             // set-Methode merken
    2255        1294 :                             pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
    2256        2588 :                                                               pInterfaces2, rPropCount );
    2257        1294 :                             pInterfaces2[ rPropCount ] = rxMethod_i;
    2258             : 
    2259             :                             // Art der Property merken
    2260        1294 :                             pMapTypeArray[ rPropCount ] = MAP_SETONLY;
    2261        1294 :                             pPropertyConceptArray[ rPropCount ] = METHODS;
    2262        1294 :                             pAccess->mnMethodPropCount++;
    2263             : 
    2264             :                             // Count pflegen
    2265        2588 :                             rPropCount++;
    2266             :                         }
    2267             :                     }
    2268             : 
    2269             : 
    2270             : 
    2271             : 
    2272             :                     // 4. Methoden in die Gesamt-Sequence uebernehmen
    2273             : 
    2274             :                     // Wieviele Methoden muessen in die Method-Sequence?
    2275       24566 :                     sal_Int32 nExportedMethodCount = 0;
    2276       24566 :                     sal_Int32 nSupportedListenerCount = 0;
    2277      181156 :                     for( i = 0 ; i < nSourceMethodCount ; i++ )
    2278             :                     {
    2279      156590 :                         if( pMethodTypes[ i ] != INVALID_METHOD )
    2280             :                         {
    2281       85382 :                             nExportedMethodCount++;
    2282             :                         }
    2283      156590 :                         if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
    2284             :                         {
    2285        6906 :                             nSupportedListenerCount++;
    2286             :                         }
    2287             :                     }
    2288             : 
    2289             :                     // Sequences im Access-Objekt entsprechend aufbohren
    2290       24566 :                     pAccess->maAllMethodSeq.realloc( nExportedMethodCount + iAllExportedMethod );
    2291       24566 :                     pAccess->maMethodConceptSeq.realloc( nExportedMethodCount + iAllExportedMethod );
    2292       24566 :                     pAccess->maSupportedListenerSeq.realloc( nSupportedListenerCount + iAllSupportedListener );
    2293             : 
    2294             :                     // Methoden reinschreiben
    2295       24566 :                     Reference<XIdlMethod>* pDestMethods = pAccess->maAllMethodSeq.getArray();
    2296       24566 :                     sal_Int32* pMethodConceptArray = pAccess->maMethodConceptSeq.getArray();
    2297       24566 :                     Type* pListenerClassRefs = pAccess->maSupportedListenerSeq.getArray();
    2298      181156 :                     for( i = 0 ; i < nSourceMethodCount ; i++ )
    2299             :                     {
    2300      156590 :                         if( pMethodTypes[ i ] != INVALID_METHOD )
    2301             :                         {
    2302             :                             // Methode ansprechen
    2303       85382 :                             const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
    2304             : 
    2305             :                             // Namen in Hashtable eintragen, wenn nicht schon bekannt
    2306       85382 :                             OUString aMethName2 = rxMethod->getName();
    2307       85382 :                             IntrospectionNameMap::iterator aIt = rMethodNameMap.find( aMethName2 );
    2308       85382 :                             if( aIt == rMethodNameMap.end() )
    2309             :                             {
    2310             :                                 // Eintragen
    2311       65744 :                                 rMethodNameMap[ aMethName2 ] = iAllExportedMethod;
    2312             : 
    2313             :                                 // Tabelle fuer XExactName pflegen
    2314       65744 :                                 rLowerToExactNameMap[ toLower( aMethName2 ) ] = aMethName2;
    2315             :                             }
    2316             :                             else
    2317             :                             {
    2318       19638 :                                 sal_Int32 iHashResult = (*aIt).second;
    2319             : 
    2320       19638 :                                 Reference<XIdlMethod> xExistingMethod = pDestMethods[ iHashResult ];
    2321             : 
    2322             :                                 Reference< XIdlClass > xExistingMethClass =
    2323       21536 :                                     xExistingMethod->getDeclaringClass();
    2324       21536 :                                 Reference< XIdlClass > xNewMethClass = rxMethod->getDeclaringClass();
    2325       19638 :                                 if( xExistingMethClass->equals( xNewMethClass ) )
    2326       19638 :                                     continue;
    2327             :                             }
    2328             : 
    2329       67642 :                             pDestMethods[ iAllExportedMethod ] = rxMethod;
    2330             : 
    2331             :                             // Wenn kein Concept gesetzt wurde, ist die Methode "normal"
    2332       67642 :                             sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
    2333       67642 :                             if( !rMethodConcept_i )
    2334       35858 :                                 rMethodConcept_i = MethodConcept_NORMAL_IMPL;
    2335       67642 :                             pMethodConceptArray[ iAllExportedMethod ] = rMethodConcept_i;
    2336       67642 :                             iAllExportedMethod++;
    2337             :                         }
    2338      138850 :                         if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
    2339             :                         {
    2340             :                             // Klasse des Listeners ermitteln
    2341        5280 :                             const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
    2342             : 
    2343             :                             // void als Default-Klasse eintragen
    2344             :                             css::uno::Reference<css::reflection::XIdlClass>
    2345             :                                 xListenerClass(
    2346        5280 :                                     reflection_->forName(
    2347        5280 :                                         cppu::UnoType<cppu::UnoVoidType>::get()
    2348       10560 :                                         .getTypeName()));
    2349             :                             // ALT: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass();
    2350             : 
    2351             :                             // 1. Moeglichkeit: Parameter nach einer Listener-Klasse durchsuchen
    2352             :                             // Nachteil: Superklassen muessen rekursiv durchsucht werden
    2353       10560 :                             Sequence< Reference<XIdlClass> > aParams = rxMethod->getParameterTypes();
    2354        5280 :                             const Reference<XIdlClass>* pParamArray2 = aParams.getConstArray();
    2355             : 
    2356             :                             css::uno::Reference<css::reflection::XIdlClass>
    2357             :                                 xEventListenerClass(
    2358        5280 :                                     reflection_->forName(
    2359             :                                         cppu::UnoType<
    2360        5280 :                                             css::lang::XEventListener>::get()
    2361       15840 :                                         .getTypeName()));
    2362             :                             // ALT: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass();
    2363        5280 :                             sal_Int32 nParamCount = aParams.getLength();
    2364             :                             sal_Int32 k;
    2365        6458 :                             for( k = 0 ; k < nParamCount ; k++ )
    2366             :                             {
    2367        6456 :                                 const Reference<XIdlClass>& rxClass = pParamArray2[k];
    2368             : 
    2369             :                                 // Sind wir von einem Listener abgeleitet?
    2370       30076 :                                 if( rxClass->equals( xEventListenerClass ) ||
    2371       27872 :                                     isDerivedFrom( rxClass, xEventListenerClass ) )
    2372             :                                 {
    2373        5278 :                                     xListenerClass = rxClass;
    2374        5278 :                                     break;
    2375             :                                 }
    2376             :                             }
    2377             : 
    2378             :                             // 2. Moeglichkeit: Namen der Methode auswerden
    2379             :                             // Nachteil: geht nicht bei Test-Listenern, die es nicht gibt
    2380             :                             //aMethName = rxMethod->getName();
    2381             :                             //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 );
    2382             :                             //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName );
    2383       10560 :                             Type aListenerType( TypeClass_INTERFACE, xListenerClass->getName() );
    2384        5280 :                             pListenerClassRefs[ iAllSupportedListener ] = aListenerType;
    2385       10560 :                             iAllSupportedListener++;
    2386             :                         }
    2387             :                     }
    2388             : 
    2389             :                     // Wenn in diesem Durchlauf XInterface-Methoden
    2390             :                     // dabei waren, diese zukuenftig ignorieren
    2391       24566 :                     if( bFoundXInterface )
    2392       24566 :                         bXInterfaceIsInvalid = true;
    2393             : 
    2394       24566 :                     delete[] pMethodTypes;
    2395       24566 :                     delete[] pLocalMethodConcepts;
    2396       24566 :                 }
    2397             : 
    2398             :                 // Super-Klasse(n) vorhanden? Dann dort fortsetzen
    2399      100140 :                 Sequence< Reference<XIdlClass> > aSuperClassSeq = xImplClass2->getSuperclasses();
    2400             : 
    2401             :                 // Zur Zeit wird nur von einer Superklasse ausgegangen
    2402       50070 :                 if( aSuperClassSeq.getLength() >= 1 )
    2403             :                 {
    2404       27246 :                     xImplClass2 = aSuperClassSeq.getConstArray()[0];
    2405             :                     OSL_ENSURE( xImplClass2.is(), "super class null" );
    2406             :                 }
    2407             :                 else
    2408             :                 {
    2409       22824 :                     xImplClass2 = NULL;
    2410             :                 }
    2411       50070 :             }
    2412       22824 :         }
    2413             : 
    2414             :         // Anzahl der exportierten Methoden uebernehmen und Sequences anpassen
    2415             :         // (kann abweichen, weil doppelte Methoden erst nach der Ermittlung
    2416             :         //  von nExportedMethodCount herausgeworfen werden)
    2417         830 :         sal_Int32& rMethCount = pAccess->mnMethCount;
    2418         830 :         rMethCount = iAllExportedMethod;
    2419         830 :         pAccess->maAllMethodSeq.realloc( rMethCount );
    2420         830 :         pAccess->maMethodConceptSeq.realloc( rMethCount );
    2421             : 
    2422             :         // Groesse der Property-Sequences anpassen
    2423         830 :         pAccess->maAllPropertySeq.realloc( rPropCount );
    2424         830 :         pAccess->maPropertyConceptSeq.realloc( rPropCount );
    2425         830 :         pAccess->maMapTypeSeq.realloc( rPropCount );
    2426             :     }
    2427             :     // Bei structs Fields als Properties registrieren
    2428             :     else //if( eType == TypeClass_STRUCT )
    2429             :     {
    2430             :         // Ist es ein Interface oder eine struct?
    2431             :         //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass();
    2432             :         css::uno::Reference<css::reflection::XIdlClass> xClassRef(
    2433          66 :             reflection_->forName(aToInspectObj.getValueTypeName()));
    2434          66 :         if( !xClassRef.is() )
    2435             :         {
    2436             :             SAL_WARN( "stoc", "Can't get XIdlClass from Reflection" );
    2437           0 :             return new ImplIntrospectionAccess(aToInspectObj, pAccess);
    2438             :         }
    2439             : 
    2440             :         // Felder holen
    2441         132 :         Sequence< Reference<XIdlField> > fields = xClassRef->getFields();
    2442          66 :         const Reference<XIdlField>* pFields = fields.getConstArray();
    2443          66 :         sal_Int32 nLen = fields.getLength();
    2444             : 
    2445         372 :         for( i = 0 ; i < nLen ; i++ )
    2446             :         {
    2447         306 :             Reference<XIdlField> xField = pFields[i];
    2448         612 :             Reference<XIdlClass> xPropType = xField->getType();
    2449         612 :             OUString aPropName = xField->getName();
    2450             : 
    2451             :             // Ist die PropertySequence gross genug?
    2452             :             pAccess->checkPropertyArraysSize
    2453         306 :                 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
    2454             : 
    2455             :             // In eigenes Property-Array eintragen
    2456         306 :             Property& rProp = pAllPropArray[ rPropCount ];
    2457         306 :             rProp.Name = aPropName;
    2458         306 :             rProp.Handle = rPropCount;
    2459         306 :             rProp.Type = Type( xPropType->getTypeClass(), xPropType->getName() );
    2460         306 :             FieldAccessMode eAccessMode = xField->getAccessMode();
    2461         306 :             rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
    2462             :                                 eAccessMode == FieldAccessMode_CONST)
    2463         306 :                                 ? READONLY : 0;
    2464             : 
    2465             :             //FieldAccessMode eAccessMode = xField->getAccessMode();
    2466             :             //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST)
    2467             :                 //? PropertyAttribute::READONLY : 0;
    2468             : 
    2469             :             // Namen in Hashtable eintragen
    2470         306 :             rPropNameMap[ aPropName ] = rPropCount;
    2471             : 
    2472             :             // Tabelle fuer XExactName pflegen
    2473         306 :             rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
    2474             : 
    2475             :             // Field merken
    2476         306 :             pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
    2477         612 :                 pInterfaces1, rPropCount );
    2478         306 :             pInterfaces1[ rPropCount ] = xField;
    2479             : 
    2480             :             // Art der Property merken
    2481         306 :             pMapTypeArray[ rPropCount ] = MAP_FIELD;
    2482         306 :             pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
    2483         306 :             pAccess->mnAttributePropCount++;
    2484             : 
    2485             :             // Count pflegen
    2486         306 :             rPropCount++;
    2487         372 :         }
    2488             :     }
    2489             : 
    2490             :     // Property-Sequence auf die richtige Laenge bringen
    2491         896 :     pAccess->maAllPropertySeq.realloc( pAccess->mnPropCount );
    2492             : 
    2493       33628 :     return new ImplIntrospectionAccess(aToInspectObj, pAccess);
    2494             : }
    2495             : 
    2496         178 : struct Instance {
    2497         178 :     explicit Instance(
    2498             :         css::uno::Reference<css::uno::XComponentContext> const & context):
    2499         178 :         instance(new Implementation(context))
    2500         178 :     {}
    2501             : 
    2502             :     rtl::Reference<cppu::OWeakObject> instance;
    2503             : };
    2504             : 
    2505             : struct Singleton:
    2506             :     public rtl::StaticWithArg<
    2507             :         Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
    2508             : {};
    2509             : 
    2510             : }
    2511             : 
    2512             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    2513         180 : com_sun_star_comp_stoc_Introspection_get_implementation(
    2514             :     css::uno::XComponentContext * context,
    2515             :     css::uno::Sequence<css::uno::Any> const & arguments)
    2516             : {
    2517             :     SAL_WARN_IF(
    2518             :         arguments.hasElements(), "stoc", "unexpected singleton arguments");
    2519         180 :     return cppu::acquire(Singleton::get(context).instance.get());
    2520             : }
    2521             : 
    2522             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10