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

Generated by: LCOV version 1.11