summaryrefslogtreecommitdiff
path: root/stoc/source/inspect/introspection.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'stoc/source/inspect/introspection.cxx')
-rw-r--r--stoc/source/inspect/introspection.cxx3091
1 files changed, 3091 insertions, 0 deletions
diff --git a/stoc/source/inspect/introspection.cxx b/stoc/source/inspect/introspection.cxx
new file mode 100644
index 000000000000..051ff3e2ae3c
--- /dev/null
+++ b/stoc/source/inspect/introspection.cxx
@@ -0,0 +1,3091 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <string.h>
+
+// Schalter fuer Introspection-Caching
+#ifndef OS2
+#define USE_INTROSPECTION_CACHE
+#endif
+
+#ifdef USE_INTROSPECTION_CACHE
+#define INTROSPECTION_CACHE_MAX_SIZE 100
+#endif
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/component.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+#include <com/sun/star/uno/DeploymentException.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <com/sun/star/reflection/XIdlClassProvider.hpp>
+#include <com/sun/star/reflection/XIdlClass.hpp>
+#include <com/sun/star/reflection/XIdlField2.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyConcept.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <hash_map>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::container;
+using namespace com::sun::star::registry;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::beans::PropertyAttribute;
+using namespace com::sun::star::beans::PropertyConcept;
+using namespace com::sun::star::beans::MethodConcept;
+using namespace cppu;
+using namespace osl;
+using namespace rtl;
+
+#define IMPLEMENTATION_NAME "com.sun.star.comp.stoc.Introspection"
+#define SERVICE_NAME "com.sun.star.beans.Introspection"
+
+namespace stoc_inspect
+{
+
+typedef WeakImplHelper3< XIntrospectionAccess, XMaterialHolder, XExactName > IntrospectionAccessHelper;
+
+
+//==================================================================================================
+
+// Spezial-Wert fuer Method-Concept, um "normale" Funktionen kennzeichnen zu koennen
+#define MethodConcept_NORMAL_IMPL 0x80000000
+
+
+// Methode zur Feststellung, ob eine Klasse von einer anderen abgeleitet ist
+sal_Bool isDerivedFrom( Reference<XIdlClass> xToTestClass, Reference<XIdlClass> xDerivedFromClass )
+{
+ Sequence< Reference<XIdlClass> > aClassesSeq = xToTestClass->getSuperclasses();
+ const Reference<XIdlClass>* pClassesArray = aClassesSeq.getConstArray();
+ sal_Int32 nSuperClassCount = aClassesSeq.getLength();
+ sal_Int32 i;
+ for( i = 0 ; i < nSuperClassCount ; i++ )
+ {
+ const Reference<XIdlClass>& rxClass = pClassesArray[i];
+ if( xDerivedFromClass->equals( rxClass ) )
+ {
+ // Treffer
+ return sal_True;
+ }
+ else
+ {
+ // Rekursiv weitersuchen
+ return isDerivedFrom( rxClass, xDerivedFromClass );
+ }
+ }
+ return sal_False;
+}
+
+//========================================================================
+
+// *** Klassifizierung der Properties (kein enum, um Sequence verwenden zu koennen) ***
+// Properties aus einem PropertySet-Interface
+#define MAP_PROPERTY_SET 0
+// Properties aus Fields
+#define MAP_FIELD 1
+// Properties, die durch get/set-Methoden beschrieben werden
+#define MAP_GETSET 2
+// Properties, die nur eine set-Methode haben
+#define MAP_SETONLY 3
+
+
+// Schrittweite, in der die Groesse der Sequences angepasst wird
+#define ARRAY_SIZE_STEP 20
+
+
+
+//**************************************
+//*** IntrospectionAccessStatic_Impl ***
+//**************************************
+// Entspricht dem alten IntrospectionAccessImpl, bildet jetzt den statischen
+// Anteil des neuen Instanz-bezogenen ImplIntrospectionAccess
+
+// ACHTUNG !!! Von Hand refcounten !!!
+
+
+// Hashtable fuer die Suche nach Namen
+struct hashName_Impl
+{
+ size_t operator()(const OUString Str) const
+ {
+ return (size_t)Str.hashCode();
+ }
+};
+
+struct eqName_Impl
+{
+ sal_Bool operator()(const OUString Str1, const OUString Str2) const
+ {
+ return ( Str1 == Str2 );
+ }
+};
+
+typedef std::hash_map
+<
+ OUString,
+ sal_Int32,
+ hashName_Impl,
+ eqName_Impl
+>
+IntrospectionNameMap;
+
+
+// Hashtable zur Zuordnung der exakten Namen zu den zu Lower-Case
+// konvertierten Namen, dient zur Unterst�tzung von XExactName
+typedef std::hash_map
+<
+ OUString,
+ OUString,
+ hashName_Impl,
+ eqName_Impl
+>
+LowerToExactNameMap;
+
+
+class ImplIntrospectionAccess;
+class IntrospectionAccessStatic_Impl
+{
+ friend class ImplIntrospection;
+ friend class ImplIntrospectionAccess;
+
+ // CoreReflection halten
+ Reference< XIdlReflection > mxCoreReflection;
+
+ // InterfaceSequences, um Zusatz-Infos zu einer Property speichern zu koennen.
+ // z.B. das Field bei MAP_FIELD, die get/set-Methoden bei MAP_GETSET usw.
+ Sequence< Reference<XInterface> > aInterfaceSeq1;
+ Sequence< Reference<XInterface> > aInterfaceSeq2;
+
+ // Hashtables fuer die Namen
+ IntrospectionNameMap maPropertyNameMap;
+ IntrospectionNameMap maMethodNameMap;
+ LowerToExactNameMap maLowerToExactNameMap;
+
+ // Sequence aller Properties, auch zum Liefern aus getProperties()
+ Sequence<Property> maAllPropertySeq;
+
+ // Mapping der Properties auf Zugriffs-Arten
+ Sequence<sal_Int16> maMapTypeSeq;
+
+ // Klassifizierung der gefundenen Methoden
+ Sequence<sal_Int32> maPropertyConceptSeq;
+
+ // Anzahl der Properties
+ sal_Int32 mnPropCount;
+
+ // Anzahl der Properties, die den jeweiligen Konzepten zugeordnet sind
+ //sal_Int32 mnDangerousPropCount;
+ sal_Int32 mnPropertySetPropCount;
+ sal_Int32 mnAttributePropCount;
+ sal_Int32 mnMethodPropCount;
+
+ // Flag, ob ein FastPropertySet unterstuetzt wird
+ sal_Bool mbFastPropSet;
+
+ // Original-Handles eines FastPropertySets
+ sal_Int32* mpOrgPropertyHandleArray;
+
+ // MethodSequence, die alle Methoden aufnimmt
+ Sequence< Reference<XIdlMethod> > maAllMethodSeq;
+
+ // Klassifizierung der gefundenen Methoden
+ Sequence<sal_Int32> maMethodConceptSeq;
+
+ // Anzahl der Methoden
+ sal_Int32 mnMethCount;
+
+ // Sequence der Listener, die angemeldet werden koennen
+ Sequence< Type > maSupportedListenerSeq;
+
+ // BaseInit (soll spaeter in der Applikation erfolgen!)
+ void BaseInit( void );
+
+ // Hilfs-Methoden zur Groessen-Anpassung der Sequences
+ void checkPropertyArraysSize
+ (
+ Property*& rpAllPropArray,
+ sal_Int16*& rpMapTypeArray,
+ sal_Int32*& rpPropertyConceptArray,
+ sal_Int32 iNextIndex
+ );
+ void checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, Reference<XInterface>*& rpInterfaceArray,
+ sal_Int32 iNextIndex );
+
+ // RefCount
+ sal_Int32 nRefCount;
+
+
+public:
+ IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ );
+ ~IntrospectionAccessStatic_Impl()
+ {
+ delete[] mpOrgPropertyHandleArray;
+ }
+ sal_Int32 getPropertyIndex( const OUString& aPropertyName ) const;
+ sal_Int32 getMethodIndex( const OUString& aMethodName ) const;
+
+ void acquire() { nRefCount++; }
+ void release()
+ {
+ nRefCount--;
+ if( nRefCount <= 0 )
+ delete this;
+ }
+
+ // Methoden von XIntrospectionAccess (ALT, jetzt nur Impl)
+ void setPropertyValue(const Any& obj, const OUString& aPropertyName, const Any& aValue) const;
+// void setPropertyValue(Any& obj, const OUString& aPropertyName, const Any& aValue) const;
+ Any getPropertyValue(const Any& obj, const OUString& aPropertyName) const;
+ void setPropertyValueByIndex(const Any& obj, sal_Int32 nIndex, const Any& aValue) const;
+// void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const;
+ Any getPropertyValueByIndex(const Any& obj, sal_Int32 nIndex) const;
+
+ Sequence<Property> getProperties(void) const { return maAllPropertySeq; }
+ Sequence< Reference<XIdlMethod> > getMethods(void) const { return maAllMethodSeq; }
+ Sequence< Type > getSupportedListeners(void) const { return maSupportedListenerSeq; }
+ Sequence<sal_Int32> getPropertyConcepts(void) const { return maPropertyConceptSeq; }
+ Sequence<sal_Int32> getMethodConcepts(void) const { return maMethodConceptSeq; }
+};
+
+
+// Ctor
+IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ )
+ : mxCoreReflection( xCoreReflection_ )
+{
+ aInterfaceSeq1.realloc( ARRAY_SIZE_STEP );
+ aInterfaceSeq2.realloc( ARRAY_SIZE_STEP );
+
+ // Property-Daten
+ maAllPropertySeq.realloc( ARRAY_SIZE_STEP );
+ maMapTypeSeq.realloc( ARRAY_SIZE_STEP );
+ maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
+
+ mbFastPropSet = sal_False;
+ mpOrgPropertyHandleArray = NULL;
+
+ mnPropCount = 0;
+ //mnDangerousPropCount = 0;
+ mnPropertySetPropCount = 0;
+ mnAttributePropCount = 0;
+ mnMethodPropCount = 0;
+
+ // Method-Daten
+ mnMethCount = 0;
+
+ // Eigenens RefCounting
+ nRefCount = 0;
+}
+
+// Von Hand refcounten !!!
+
+
+sal_Int32 IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString& aPropertyName ) const
+{
+ sal_Int32 iHashResult = -1;
+ IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
+ IntrospectionNameMap::iterator aIt = pThis->maPropertyNameMap.find( aPropertyName );
+ if( !( aIt == pThis->maPropertyNameMap.end() ) )
+ iHashResult = (*aIt).second;
+ return iHashResult;
+}
+
+sal_Int32 IntrospectionAccessStatic_Impl::getMethodIndex( const OUString& aMethodName ) const
+{
+ sal_Int32 iHashResult = -1;
+ IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
+ IntrospectionNameMap::iterator aIt = pThis->maMethodNameMap.find( aMethodName );
+ if( !( aIt == pThis->maMethodNameMap.end() ) )
+ {
+ iHashResult = (*aIt).second;
+ }
+ // #95159 Check if full qualified name matches
+ else
+ {
+ sal_Int32 nSearchFrom = aMethodName.getLength();
+ nSearchFrom = aMethodName.getLength();
+ while( true )
+ {
+ // Strategy: Search back until the first '_' is found
+ sal_Int32 nFound = aMethodName.lastIndexOf( '_', nSearchFrom );
+ if( nFound == -1 )
+ break;
+
+ OUString aPureMethodName = aMethodName.copy( nFound + 1 );
+
+ aIt = pThis->maMethodNameMap.find( aPureMethodName );
+ if( !( aIt == pThis->maMethodNameMap.end() ) )
+ {
+ // Check if it can be a type?
+ // Problem: Does not work if package names contain _ ?!
+ OUString aStr = aMethodName.copy( 0, nFound );
+ OUString aTypeName = aStr.replace( '_', '.' );
+ Reference< XIdlClass > xClass = mxCoreReflection->forName( aTypeName );
+ if( xClass.is() )
+ {
+ // If this is a valid class it could be the right method
+
+ // Could be the right method, type has to be checked
+ iHashResult = (*aIt).second;
+
+ const Reference<XIdlMethod>* pMethods = maAllMethodSeq.getConstArray();
+ const Reference<XIdlMethod> xMethod = pMethods[ iHashResult ];
+
+ Reference< XIdlClass > xMethClass = xMethod->getDeclaringClass();
+ if( xClass->equals( xMethClass ) )
+ {
+ break;
+ }
+ else
+ {
+ iHashResult = -1;
+
+ // Could also be another method with the same name
+ // Iterate over all methods
+ sal_Int32 nLen = maAllMethodSeq.getLength();
+ for( int i = 0 ; i < nLen ; ++i )
+ {
+ const Reference<XIdlMethod> xMethod2 = pMethods[ i ];
+
+ OUString aTestClassName = xMethod2->getDeclaringClass()->getName();
+ OUString aTestMethodName = xMethod2->getName();
+
+ if( xMethod2->getName() == aPureMethodName )
+ {
+ Reference< XIdlClass > xMethClass2 = xMethod2->getDeclaringClass();
+
+ if( xClass->equals( xMethClass2 ) )
+ {
+ iHashResult = i;
+ break;
+ }
+ }
+ }
+
+ if( iHashResult != -1 )
+ break;
+ }
+ }
+ }
+
+ nSearchFrom = nFound - 1;
+ if( nSearchFrom < 0 )
+ break;
+ }
+ }
+ return iHashResult;
+}
+
+void IntrospectionAccessStatic_Impl::setPropertyValue( const Any& obj, const OUString& aPropertyName, const Any& aValue ) const
+//void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const OUString& aPropertyName, const Any& aValue ) const
+{
+ sal_Int32 i = getPropertyIndex( aPropertyName );
+ if( i != -1 )
+ setPropertyValueByIndex( obj, (sal_Int32)i, aValue );
+ else
+ throw UnknownPropertyException();
+}
+
+void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
+//void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
+{
+ // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
+ TypeClass eObjType = obj.getValueType().getTypeClass();
+
+ Reference<XInterface> xInterface;
+ if( eObjType == TypeClass_INTERFACE )
+ {
+ xInterface = *( Reference<XInterface>*)obj.getValue();
+ }
+ else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
+ {
+ throw IllegalArgumentException();
+ }
+
+ // Flags pruefen
+ const Property* pProps = maAllPropertySeq.getConstArray();
+ if( (pProps[ nSequenceIndex ].Attributes & READONLY) != 0 )
+ {
+ throw UnknownPropertyException();
+ }
+
+ const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
+ switch( pMapTypeArray[ nSequenceIndex ] )
+ {
+ case MAP_PROPERTY_SET:
+ {
+ // Property besorgen
+ const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
+
+ // Interface-Parameter auf den richtigen Typ bringen
+ sal_Bool bUseCopy = sal_False;
+ Any aRealValue;
+
+ TypeClass eValType = aValue.getValueType().getTypeClass();
+ if( eValType == TypeClass_INTERFACE )
+ {
+ Type aPropType = rProp.Type;
+ OUString aTypeName( aPropType.getTypeName() );
+ Reference< XIdlClass > xPropClass = mxCoreReflection->forName( aTypeName );
+ //Reference<XIdlClass> xPropClass = rProp.Type;
+ if( xPropClass.is() && xPropClass->getTypeClass() == TypeClass_INTERFACE )
+ {
+ Reference<XInterface> valInterface = *(Reference<XInterface>*)aValue.getValue();
+ if( valInterface.is() )
+ {
+ //Any queryInterface( const Type& rType );
+ aRealValue = valInterface->queryInterface( aPropType );
+ if( aRealValue.hasValue() )
+ bUseCopy = sal_True;
+ }
+ }
+ }
+
+ // Haben wir ein FastPropertySet und ein gueltiges Handle?
+ // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
+ // zu Beginn des Introspection-Vorgangs abgefragt wird.
+ sal_Int32 nOrgHandle;
+ if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
+ {
+ // PropertySet-Interface holen
+ Reference<XFastPropertySet> xFastPropSet =
+ Reference<XFastPropertySet>::query( xInterface );
+ if( xFastPropSet.is() )
+ {
+ xFastPropSet->setFastPropertyValue( nOrgHandle, bUseCopy ? aRealValue : aValue );
+ }
+ else
+ {
+ // throw UnknownPropertyException
+ }
+ }
+ // sonst eben das normale nehmen
+ else
+ {
+ // PropertySet-Interface holen
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( xInterface );
+ if( xPropSet.is() )
+ {
+ xPropSet->setPropertyValue( rProp.Name, bUseCopy ? aRealValue : aValue );
+ }
+ else
+ {
+ // throw UnknownPropertyException
+ }
+ }
+ }
+ break;
+
+ case MAP_FIELD:
+ {
+ Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
+ Reference<XIdlField2> xField2(xField, UNO_QUERY);
+ if( xField2.is() )
+ {
+ xField2->set( (Any&)obj, aValue );
+ // IllegalArgumentException
+ // NullPointerException
+ } else
+ if( xField.is() )
+ {
+ xField->set( obj, aValue );
+ // IllegalArgumentException
+ // NullPointerException
+ }
+ else
+ {
+ // throw IllegalArgumentException();
+ }
+ }
+ break;
+
+ case MAP_GETSET:
+ case MAP_SETONLY:
+ {
+ // set-Methode holen
+ Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq2.getConstArray()[ nSequenceIndex ].get());
+ if( xMethod.is() )
+ {
+ Sequence<Any> args( 1 );
+ args.getArray()[0] = aValue;
+ xMethod->invoke( obj, args );
+ }
+ else
+ {
+ // throw IllegalArgumentException();
+ }
+ }
+ break;
+ }
+}
+
+Any IntrospectionAccessStatic_Impl::getPropertyValue( const Any& obj, const OUString& aPropertyName ) const
+{
+ sal_Int32 i = getPropertyIndex( aPropertyName );
+ if( i != -1 )
+ return getPropertyValueByIndex( obj, i );
+
+ throw UnknownPropertyException();
+}
+
+Any IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex) const
+{
+ Any aRet;
+
+ // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
+ TypeClass eObjType = obj.getValueType().getTypeClass();
+
+ Reference<XInterface> xInterface;
+ if( eObjType == TypeClass_INTERFACE )
+ {
+ xInterface = *(Reference<XInterface>*)obj.getValue();
+ }
+ else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
+ {
+ // throw IllegalArgumentException();
+ return aRet;
+ }
+
+ const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
+ switch( pMapTypeArray[ nSequenceIndex ] )
+ {
+ case MAP_PROPERTY_SET:
+ {
+ // Property besorgen
+ const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
+
+ // Haben wir ein FastPropertySet und ein gueltiges Handle?
+ // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
+ // zu Beginn des Introspection-Vorgangs abgefragt wird.
+ sal_Int32 nOrgHandle;
+ if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
+ {
+ // PropertySet-Interface holen
+ Reference<XFastPropertySet> xFastPropSet =
+ Reference<XFastPropertySet>::query( xInterface );
+ if( xFastPropSet.is() )
+ {
+ aRet = xFastPropSet->getFastPropertyValue( nOrgHandle);
+ }
+ else
+ {
+ // throw UnknownPropertyException
+ return aRet;
+ }
+ }
+ // sonst eben das normale nehmen
+ else
+ {
+ // PropertySet-Interface holen
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( xInterface );
+ if( xPropSet.is() )
+ {
+ aRet = xPropSet->getPropertyValue( rProp.Name );
+ }
+ else
+ {
+ // throw UnknownPropertyException
+ return aRet;
+ }
+ }
+ }
+ break;
+
+ case MAP_FIELD:
+ {
+ Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
+ if( xField.is() )
+ {
+ aRet = xField->get( obj );
+ // IllegalArgumentException
+ // NullPointerException
+ }
+ else
+ {
+ // throw IllegalArgumentException();
+ return aRet;
+ }
+ }
+ break;
+
+ case MAP_GETSET:
+ {
+ // get-Methode holen
+ Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
+ if( xMethod.is() )
+ {
+ Sequence<Any> args;
+ aRet = xMethod->invoke( obj, args );
+ }
+ else
+ {
+ // throw IllegalArgumentException();
+ return aRet;
+ }
+ }
+ break;
+
+ case MAP_SETONLY:
+ // get-Methode gibt es nicht
+ // throw WriteOnlyPropertyException();
+ return aRet;
+ }
+ return aRet;
+}
+
+
+// Hilfs-Methoden zur Groessen-Anpassung der Sequences
+void IntrospectionAccessStatic_Impl::checkPropertyArraysSize
+(
+ Property*& rpAllPropArray,
+ sal_Int16*& rpMapTypeArray,
+ sal_Int32*& rpPropertyConceptArray,
+ sal_Int32 iNextIndex
+)
+{
+ sal_Int32 nLen = maAllPropertySeq.getLength();
+ if( iNextIndex >= nLen )
+ {
+ maAllPropertySeq.realloc( nLen + ARRAY_SIZE_STEP );
+ rpAllPropArray = maAllPropertySeq.getArray();
+
+ maMapTypeSeq.realloc( nLen + ARRAY_SIZE_STEP );
+ rpMapTypeArray = maMapTypeSeq.getArray();
+
+ maPropertyConceptSeq.realloc( nLen + ARRAY_SIZE_STEP );
+ rpPropertyConceptArray = maPropertyConceptSeq.getArray();
+ }
+}
+
+void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq,
+ Reference<XInterface>*& rpInterfaceArray, sal_Int32 iNextIndex )
+{
+ sal_Int32 nLen = rSeq.getLength();
+ if( iNextIndex >= nLen )
+ {
+ // Neue Groesse mit ARRAY_SIZE_STEP abgleichen
+ sal_Int32 nMissingSize = iNextIndex - nLen + 1;
+ sal_Int32 nSteps = nMissingSize / ARRAY_SIZE_STEP + 1;
+ sal_Int32 nNewSize = nLen + nSteps * ARRAY_SIZE_STEP;
+
+ rSeq.realloc( nNewSize );
+ rpInterfaceArray = rSeq.getArray();
+ }
+}
+
+
+//*******************************
+//*** ImplIntrospectionAdapter ***
+//*******************************
+
+// Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
+// Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
+// ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
+class ImplIntrospectionAdapter :
+ public XPropertySet, public XFastPropertySet, public XPropertySetInfo,
+ public XNameContainer, public XIndexContainer,
+ public XEnumerationAccess, public XIdlArray,
+ public OWeakObject
+{
+ // Parent-Objekt
+ ImplIntrospectionAccess* mpAccess;
+
+ // Untersuchtes Objekt
+ const Any& mrInspectedObject;
+
+ // Statische Daten der Introspection
+ IntrospectionAccessStatic_Impl* mpStaticImpl;
+
+ // Objekt als Interface
+ Reference<XInterface> mxIface;
+
+ // Original-Interfaces des Objekts
+ Reference<XElementAccess> mxObjElementAccess;
+ Reference<XNameContainer> mxObjNameContainer;
+ Reference<XNameAccess> mxObjNameAccess;
+ Reference<XIndexAccess> mxObjIndexAccess;
+ Reference<XIndexContainer> mxObjIndexContainer;
+ Reference<XEnumerationAccess> mxObjEnumerationAccess;
+ Reference<XIdlArray> mxObjIdlArray;
+
+public:
+ ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
+ const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ );
+ ~ImplIntrospectionAdapter();
+
+ // Methoden von XInterface
+ virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
+ virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
+ virtual void SAL_CALL release() throw() { OWeakObject::release(); }
+
+ // Methoden von XPropertySet
+ virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( RuntimeException );
+ virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, const Any& aValue)
+ throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException );
+ virtual Any SAL_CALL getPropertyValue(const OUString& aPropertyName)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+
+ // Methoden von XFastPropertySet
+ virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const Any& aValue)
+ throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException );
+ virtual Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+
+ // Methoden von XPropertySetInfo
+ virtual Sequence< Property > SAL_CALL getProperties(void) throw( RuntimeException );
+ virtual Property SAL_CALL getPropertyByName(const OUString& Name) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& Name) throw( RuntimeException );
+
+ // Methoden von XElementAccess
+ virtual Type SAL_CALL getElementType(void) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException );
+
+ // Methoden von XNameAccess
+ virtual Any SAL_CALL getByName(const OUString& Name)
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException );
+ virtual Sequence<OUString> SAL_CALL getElementNames(void) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL hasByName(const OUString& Name) throw( RuntimeException );
+
+ // Methoden von XNameContainer
+ virtual void SAL_CALL insertByName(const OUString& Name, const Any& Element)
+ throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element)
+ throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL removeByName(const OUString& Name)
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException );
+
+ // Methoden von XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException );
+ virtual Any SAL_CALL getByIndex(sal_Int32 Index)
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+
+ // Methoden von XIndexContainer
+ virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element)
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element)
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL removeByIndex(sal_Int32 Index)
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+
+ // Methoden von XEnumerationAccess
+ virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException );
+
+ // Methoden von XIdlArray
+ virtual void SAL_CALL realloc(Any& array, sal_Int32 length)
+ throw( IllegalArgumentException, RuntimeException );
+ virtual sal_Int32 SAL_CALL getLen(const Any& array) throw( IllegalArgumentException, RuntimeException );
+ virtual Any SAL_CALL get(const Any& array, sal_Int32 index)
+ throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException );
+ virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value)
+ throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException );
+};
+
+ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
+ const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ )
+ : mpAccess( pAccess_), mrInspectedObject( obj ), mpStaticImpl( pStaticImpl_ )
+{
+ mpStaticImpl->acquire();
+
+ // Objekt als Interfaceholen
+ TypeClass eType = mrInspectedObject.getValueType().getTypeClass();
+ if( eType == TypeClass_INTERFACE )
+ {
+ mxIface = *( Reference< XInterface >*)mrInspectedObject.getValue();
+
+ mxObjElementAccess = Reference<XElementAccess>::query( mxIface );
+ mxObjNameAccess = Reference<XNameAccess>::query( mxIface );
+ mxObjNameContainer = Reference<XNameContainer>::query( mxIface );
+ mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface );
+ mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface );
+ mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
+ mxObjIdlArray = Reference<XIdlArray>::query( mxIface );
+ }
+}
+
+ImplIntrospectionAdapter::~ImplIntrospectionAdapter()
+{
+ mpStaticImpl->release();
+}
+
+// Methoden von XInterface
+Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet( ::cppu::queryInterface(
+ rType,
+ static_cast< XPropertySet * >( this ),
+ static_cast< XFastPropertySet * >( this ),
+ static_cast< XPropertySetInfo * >( this ) ) );
+ if( !aRet.hasValue() )
+ aRet = OWeakObject::queryInterface( rType );
+
+ if( !aRet.hasValue() )
+ {
+ // Wrapper fuer die Objekt-Interfaces
+ if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface
+ ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() )
+ || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
+ || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
+ || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
+ || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
+ || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
+ || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
+ )
+ {
+ }
+ }
+ return aRet;
+}
+
+
+//*******************************
+//*** ImplIntrospectionAccess ***
+//*******************************
+
+// Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
+// Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
+// ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
+class ImplIntrospectionAccess : IntrospectionAccessHelper
+{
+ friend class ImplIntrospection;
+
+ // Untersuchtes Objekt
+ Any maInspectedObject;
+
+ // Als Interface
+ Reference<XInterface> mxIface;
+
+ // Statische Daten der Introspection
+ IntrospectionAccessStatic_Impl* mpStaticImpl;
+
+ // Adapter-Implementation
+ ImplIntrospectionAdapter* mpAdapter;
+
+ // Letzte Sequence, die bei getProperties geliefert wurde (Optimierung)
+ Sequence<Property> maLastPropertySeq;
+ sal_Int32 mnLastPropertyConcept;
+
+ // Letzte Sequence, die bei getMethods geliefert wurde (Optimierung)
+ Sequence<Reference<XIdlMethod> > maLastMethodSeq;
+ sal_Int32 mnLastMethodConcept;
+
+public:
+ ImplIntrospectionAccess( const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ );
+ ~ImplIntrospectionAccess();
+
+ // Methoden von XIntrospectionAccess
+ virtual sal_Int32 SAL_CALL getSuppliedMethodConcepts(void)
+ throw( RuntimeException );
+ virtual sal_Int32 SAL_CALL getSuppliedPropertyConcepts(void)
+ throw( RuntimeException );
+ virtual Property SAL_CALL getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
+ throw( NoSuchElementException, RuntimeException );
+ virtual sal_Bool SAL_CALL hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
+ throw( RuntimeException );
+ virtual Sequence< Property > SAL_CALL getProperties(sal_Int32 PropertyConcepts)
+ throw( RuntimeException );
+ virtual Reference<XIdlMethod> SAL_CALL getMethod(const OUString& Name, sal_Int32 MethodConcepts)
+ throw( NoSuchMethodException, RuntimeException );
+ virtual sal_Bool SAL_CALL hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
+ throw( RuntimeException );
+ virtual Sequence< Reference<XIdlMethod> > SAL_CALL getMethods(sal_Int32 MethodConcepts)
+ throw( RuntimeException );
+ virtual Sequence< Type > SAL_CALL getSupportedListeners(void)
+ throw( RuntimeException );
+ using OWeakObject::queryAdapter;
+ virtual Reference<XInterface> SAL_CALL queryAdapter( const Type& rType )
+ throw( IllegalTypeException, RuntimeException );
+
+ // Methoden von XMaterialHolder
+ virtual Any SAL_CALL getMaterial(void) throw(RuntimeException);
+
+ // Methoden von XExactName
+ virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException );
+};
+
+ImplIntrospectionAccess::ImplIntrospectionAccess
+ ( const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ )
+ : maInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ), mpAdapter( NULL )
+{
+ mpStaticImpl->acquire();
+
+ // Objekt als Interface merken, wenn moeglich
+ TypeClass eType = maInspectedObject.getValueType().getTypeClass();
+ if( eType == TypeClass_INTERFACE )
+ mxIface = *(Reference<XInterface>*)maInspectedObject.getValue();
+
+ mnLastPropertyConcept = -1;
+ mnLastMethodConcept = -1;
+}
+
+ImplIntrospectionAccess::~ImplIntrospectionAccess()
+{
+ mpStaticImpl->release();
+
+ // Eigene Referenz loslassen
+ if (mpAdapter)
+ mpAdapter->release();
+}
+
+
+//***************************************************
+//*** Implementation von ImplIntrospectionAdapter ***
+//***************************************************
+
+// Methoden von XPropertySet
+Reference<XPropertySetInfo> ImplIntrospectionAdapter::getPropertySetInfo(void)
+ throw( RuntimeException )
+{
+ return (XPropertySetInfo *)this;
+}
+
+void ImplIntrospectionAdapter::setPropertyValue(const OUString& aPropertyName, const Any& aValue)
+ throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
+{
+ mpStaticImpl->setPropertyValue( mrInspectedObject, aPropertyName, aValue );
+}
+
+Any ImplIntrospectionAdapter::getPropertyValue(const OUString& aPropertyName)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ return mpStaticImpl->getPropertyValue( mrInspectedObject, aPropertyName );
+}
+
+void ImplIntrospectionAdapter::addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ if( mxIface.is() )
+ {
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( mxIface );
+ //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
+ if( xPropSet.is() )
+ xPropSet->addPropertyChangeListener(aPropertyName, aListener);
+ }
+}
+
+void ImplIntrospectionAdapter::removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ if( mxIface.is() )
+ {
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( mxIface );
+ //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
+ if( xPropSet.is() )
+ xPropSet->removePropertyChangeListener(aPropertyName, aListener);
+ }
+}
+
+void ImplIntrospectionAdapter::addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ if( mxIface.is() )
+ {
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( mxIface );
+ //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
+ if( xPropSet.is() )
+ xPropSet->addVetoableChangeListener(aPropertyName, aListener);
+ }
+}
+
+void ImplIntrospectionAdapter::removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ if( mxIface.is() )
+ {
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( mxIface );
+ if( xPropSet.is() )
+ xPropSet->removeVetoableChangeListener(aPropertyName, aListener);
+ }
+}
+
+
+// Methoden von XFastPropertySet
+void ImplIntrospectionAdapter::setFastPropertyValue(sal_Int32, const Any&)
+ throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
+{
+}
+
+Any ImplIntrospectionAdapter::getFastPropertyValue(sal_Int32)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ return Any();
+}
+
+// Methoden von XPropertySetInfo
+Sequence< Property > ImplIntrospectionAdapter::getProperties(void) throw( RuntimeException )
+{
+ return mpStaticImpl->getProperties();
+}
+
+Property ImplIntrospectionAdapter::getPropertyByName(const OUString& Name)
+ throw( RuntimeException )
+{
+ return mpAccess->getProperty( Name, PropertyConcept::ALL );
+}
+
+sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name)
+ throw( RuntimeException )
+{
+ return mpAccess->hasProperty( Name, PropertyConcept::ALL );
+}
+
+// Methoden von XElementAccess
+Type ImplIntrospectionAdapter::getElementType(void) throw( RuntimeException )
+{
+ return mxObjElementAccess->getElementType();
+}
+
+sal_Bool ImplIntrospectionAdapter::hasElements(void) throw( RuntimeException )
+{
+ return mxObjElementAccess->hasElements();
+}
+
+// Methoden von XNameAccess
+Any ImplIntrospectionAdapter::getByName(const OUString& Name)
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException )
+{
+ return mxObjNameAccess->getByName( Name );
+}
+
+Sequence< OUString > ImplIntrospectionAdapter::getElementNames(void)
+ throw( RuntimeException )
+{
+ return mxObjNameAccess->getElementNames();
+}
+
+sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name)
+ throw( RuntimeException )
+{
+ return mxObjNameAccess->hasByName( Name );
+}
+
+// Methoden von XNameContainer
+void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element)
+ throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
+{
+ mxObjNameContainer->insertByName( Name, Element );
+}
+
+void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element)
+ throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
+{
+ mxObjNameContainer->replaceByName( Name, Element );
+}
+
+void ImplIntrospectionAdapter::removeByName(const OUString& Name)
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException )
+{
+ mxObjNameContainer->removeByName( Name );
+}
+
+// Methoden von XIndexAccess
+// Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const
+sal_Int32 ImplIntrospectionAdapter::getCount(void) throw( RuntimeException )
+{
+ return mxObjIndexAccess->getCount();
+}
+
+Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index)
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ return mxObjIndexAccess->getByIndex( Index );
+}
+
+// Methoden von XIndexContainer
+void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element)
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ mxObjIndexContainer->insertByIndex( Index, Element );
+}
+
+void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element)
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ mxObjIndexContainer->replaceByIndex( Index, Element );
+}
+
+void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index)
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ mxObjIndexContainer->removeByIndex( Index );
+}
+
+// Methoden von XEnumerationAccess
+// Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const;
+Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration(void) throw( RuntimeException )
+{
+ return mxObjEnumerationAccess->createEnumeration();
+}
+
+// Methoden von XIdlArray
+void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length)
+ throw( IllegalArgumentException, RuntimeException )
+{
+ mxObjIdlArray->realloc( array, length );
+}
+
+sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array)
+ throw( IllegalArgumentException, RuntimeException )
+{
+ return mxObjIdlArray->getLen( array );
+}
+
+Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index)
+ throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException )
+{
+ return mxObjIdlArray->get( array, index );
+}
+
+void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value)
+ throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException )
+{
+ mxObjIdlArray->set( array, index, value );
+}
+
+
+//**************************************************
+//*** Implementation von ImplIntrospectionAccess ***
+//**************************************************
+
+// Methoden von XIntrospectionAccess
+sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts(void)
+ throw( RuntimeException )
+{
+ return MethodConcept::DANGEROUS |
+ PROPERTY |
+ LISTENER |
+ ENUMERATION |
+ NAMECONTAINER |
+ INDEXCONTAINER;
+}
+
+sal_Int32 ImplIntrospectionAccess::getSuppliedPropertyConcepts(void)
+ throw( RuntimeException )
+{
+ return PropertyConcept::DANGEROUS |
+ PROPERTYSET |
+ ATTRIBUTES |
+ METHODS;
+}
+
+Property ImplIntrospectionAccess::getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
+ throw( NoSuchElementException, RuntimeException )
+{
+ Property aRet;
+ sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
+ sal_Bool bFound = sal_False;
+ if( i != -1 )
+ {
+ sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
+ if( (PropertyConcepts & nConcept) != 0 )
+ {
+ const Property* pProps = mpStaticImpl->getProperties().getConstArray();
+ aRet = pProps[ i ];
+ bFound = sal_True;
+ }
+ }
+ if( !bFound )
+ throw NoSuchElementException() ;
+ return aRet;
+}
+
+sal_Bool ImplIntrospectionAccess::hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
+ throw( RuntimeException )
+{
+ sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
+ sal_Bool bRet = sal_False;
+ if( i != -1 )
+ {
+ sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
+ if( (PropertyConcepts & nConcept) != 0 )
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+Sequence< Property > ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts)
+ throw( RuntimeException )
+{
+ // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
+ sal_Int32 nAllSupportedMask = PROPERTYSET |
+ ATTRIBUTES |
+ METHODS;
+ if( ( PropertyConcepts & nAllSupportedMask ) == nAllSupportedMask )
+ {
+ return mpStaticImpl->getProperties();
+ }
+
+ // Gleiche Sequence wie beim vorigen mal?
+ if( mnLastPropertyConcept == PropertyConcepts )
+ {
+ return maLastPropertySeq;
+ }
+
+ // Anzahl der zu liefernden Properties
+ sal_Int32 nCount = 0;
+
+ // Es gibt zur Zeit keine DANGEROUS-Properties
+ // if( PropertyConcepts & DANGEROUS )
+ // nCount += mpStaticImpl->mnDangerousPropCount;
+ if( PropertyConcepts & PROPERTYSET )
+ nCount += mpStaticImpl->mnPropertySetPropCount;
+ if( PropertyConcepts & ATTRIBUTES )
+ nCount += mpStaticImpl->mnAttributePropCount;
+ if( PropertyConcepts & METHODS )
+ nCount += mpStaticImpl->mnMethodPropCount;
+
+ // Sequence entsprechend der geforderten Anzahl reallocieren
+ ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
+ pThis->maLastPropertySeq.realloc( nCount );
+ Property* pDestProps = pThis->maLastPropertySeq.getArray();
+
+ // Alle Properties durchgehen und entsprechend der Concepte uebernehmen
+ Sequence<Property> aPropSeq = mpStaticImpl->getProperties();
+ const Property* pSourceProps = aPropSeq.getConstArray();
+ const sal_Int32* pConcepts = mpStaticImpl->getPropertyConcepts().getConstArray();
+ sal_Int32 nLen = aPropSeq.getLength();
+
+ sal_Int32 iDest = 0;
+ for( sal_Int32 i = 0 ; i < nLen ; i++ )
+ {
+ sal_Int32 nConcept = pConcepts[ i ];
+ if( nConcept & PropertyConcepts )
+ pDestProps[ iDest++ ] = pSourceProps[ i ];
+
+ /*
+ // Property mit Concepts ausgeben
+ OUString aPropName = pSourceProps[ i ].Name;
+ String aNameStr = OOUStringToString(aPropName, CHARSET_SYSTEM);
+ String ConceptStr;
+ if( nConcept & PROPERTYSET )
+ ConceptStr += "PROPERTYSET";
+ if( nConcept & ATTRIBUTES )
+ ConceptStr += "ATTRIBUTES";
+ if( nConcept & METHODS )
+ ConceptStr += "METHODS";
+ printf( "Property %ld: %s, Concept = %s\n", i, aNameStr.GetStr(), ConceptStr.GetStr() );
+ */
+ }
+
+ // PropertyConcept merken, dies entspricht maLastPropertySeq
+ pThis->mnLastPropertyConcept = PropertyConcepts;
+
+ // Zusammengebastelte Sequence liefern
+ return maLastPropertySeq;
+}
+
+Reference<XIdlMethod> ImplIntrospectionAccess::getMethod(const OUString& Name, sal_Int32 MethodConcepts)
+ throw( NoSuchMethodException, RuntimeException )
+{
+ Reference<XIdlMethod> xRet;
+ sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
+ if( i != -1 )
+ {
+
+ sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
+ if( (MethodConcepts & nConcept) != 0 )
+ {
+ const Reference<XIdlMethod>* pMethods = mpStaticImpl->getMethods().getConstArray();
+ xRet = pMethods[i];
+ }
+ }
+ if( !xRet.is() )
+ throw NoSuchMethodException();
+ return xRet;
+}
+
+sal_Bool ImplIntrospectionAccess::hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
+ throw( RuntimeException )
+{
+ sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
+ sal_Bool bRet = sal_False;
+ if( i != -1 )
+ {
+ sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
+ if( (MethodConcepts & nConcept) != 0 )
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+Sequence< Reference<XIdlMethod> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts)
+ throw( RuntimeException )
+{
+ ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
+
+ // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
+ sal_Int32 nAllSupportedMask = MethodConcept::DANGEROUS |
+ PROPERTY |
+ LISTENER |
+ ENUMERATION |
+ NAMECONTAINER |
+ INDEXCONTAINER |
+ MethodConcept_NORMAL_IMPL;
+ if( ( MethodConcepts & nAllSupportedMask ) == nAllSupportedMask )
+ {
+ return mpStaticImpl->getMethods();
+ }
+
+ // Gleiche Sequence wie beim vorigen mal?
+ if( mnLastMethodConcept == MethodConcepts )
+ {
+ return maLastMethodSeq;
+ }
+
+ // Methoden-Sequences besorgen
+ Sequence< Reference<XIdlMethod> > aMethodSeq = mpStaticImpl->getMethods();
+ const Reference<XIdlMethod>* pSourceMethods = aMethodSeq.getConstArray();
+ const sal_Int32* pConcepts = mpStaticImpl->getMethodConcepts().getConstArray();
+ sal_Int32 nLen = aMethodSeq.getLength();
+
+ // Sequence entsprechend der geforderten Anzahl reallocieren
+ // Anders als bei den Properties kann die Anzahl nicht durch
+ // Zaehler in inspect() vorher ermittelt werden, da Methoden
+ // mehreren Konzepten angehoeren koennen
+ pThis->maLastMethodSeq.realloc( nLen );
+ Reference<XIdlMethod>* pDestMethods = pThis->maLastMethodSeq.getArray();
+
+ // Alle Methods durchgehen und entsprechend der Concepte uebernehmen
+ sal_Int32 iDest = 0;
+ for( sal_Int32 i = 0 ; i < nLen ; i++ )
+ {
+ sal_Int32 nConcept = pConcepts[ i ];
+ if( nConcept & MethodConcepts )
+ pDestMethods[ iDest++ ] = pSourceMethods[ i ];
+
+ #if OSL_DEBUG_LEVEL > 0
+ static bool debug = false;
+ if ( debug )
+ {
+ // Methode mit Concepts ausgeben
+ const Reference< XIdlMethod >& rxMethod = pSourceMethods[ i ];
+ ::rtl::OString aNameStr = ::rtl::OUStringToOString( rxMethod->getName(), osl_getThreadTextEncoding() );
+ ::rtl::OString ConceptStr;
+ if( nConcept & MethodConcept::DANGEROUS )
+ ConceptStr += "DANGEROUS |";
+ if( nConcept & MethodConcept::PROPERTY )
+ ConceptStr += "PROPERTY |";
+ if( nConcept & MethodConcept::LISTENER )
+ ConceptStr += "LISTENER |";
+ if( nConcept & MethodConcept::ENUMERATION )
+ ConceptStr += "ENUMERATION |";
+ if( nConcept & MethodConcept::NAMECONTAINER )
+ ConceptStr += "NAMECONTAINER |";
+ if( nConcept & MethodConcept::INDEXCONTAINER )
+ ConceptStr += "INDEXCONTAINER |";
+ OSL_TRACE( "Method %ld: %s, Concepts = %s", i, aNameStr.getStr(), ConceptStr.getStr() );
+ }
+ #endif
+ }
+
+ // Auf die richtige Laenge bringen
+ pThis->maLastMethodSeq.realloc( iDest );
+
+ // MethodConcept merken, dies entspricht maLastMethodSeq
+ pThis->mnLastMethodConcept = MethodConcepts;
+
+ // Zusammengebastelte Sequence liefern
+ return maLastMethodSeq;
+}
+
+Sequence< Type > ImplIntrospectionAccess::getSupportedListeners(void)
+ throw( RuntimeException )
+{
+ return mpStaticImpl->getSupportedListeners();
+}
+
+Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type& rType )
+ throw( IllegalTypeException, RuntimeException )
+{
+ // Gibt es schon einen Adapter?
+ if( !mpAdapter )
+ {
+ ((ImplIntrospectionAccess*)this)->mpAdapter =
+ new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl );
+
+ // Selbst eine Referenz halten
+ mpAdapter->acquire();
+ }
+
+ Reference<XInterface> xRet;
+ Any aIfaceAny( mpAdapter->queryInterface( rType ) );
+ if( aIfaceAny.hasValue() )
+ xRet = *(Reference<XInterface>*)aIfaceAny.getValue();
+
+ return xRet;
+}
+
+// Methoden von XMaterialHolder
+Any ImplIntrospectionAccess::getMaterial(void) throw(RuntimeException)
+{
+ return maInspectedObject;
+}
+
+// Hilfs-Funktion zur LowerCase-Wandlung eines OUString
+OUString toLower( OUString aUStr )
+{
+ // Tabelle fuer XExactName pflegen
+ ::rtl::OUString aOWStr( aUStr.getStr() );
+ ::rtl::OUString aOWLowerStr = aOWStr.toAsciiLowerCase();
+ OUString aLowerUStr( aOWLowerStr.getStr() );
+ return aLowerUStr;
+}
+
+// Methoden von XExactName
+OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName ) throw( RuntimeException )
+{
+ OUString aRetStr;
+ LowerToExactNameMap::iterator aIt =
+ mpStaticImpl->maLowerToExactNameMap.find( toLower( rApproximateName ) );
+ if( !( aIt == mpStaticImpl->maLowerToExactNameMap.end() ) )
+ aRetStr = (*aIt).second;
+ return aRetStr;
+}
+
+
+//-----------------------------------------------------------------------------
+
+#ifdef USE_INTROSPECTION_CACHE
+
+struct hashIntrospectionKey_Impl
+{
+ Sequence< Reference<XIdlClass> > aIdlClasses;
+ Reference<XPropertySetInfo> xPropInfo;
+ Reference<XIdlClass> xImplClass;
+ sal_Int32 nHitCount;
+
+ void IncHitCount() const { ((hashIntrospectionKey_Impl*)this)->nHitCount++; }
+ hashIntrospectionKey_Impl() : nHitCount( 0 ) {}
+ hashIntrospectionKey_Impl( const Sequence< Reference<XIdlClass> > & rIdlClasses,
+ const Reference<XPropertySetInfo> & rxPropInfo,
+ const Reference<XIdlClass> & rxImplClass );
+};
+
+hashIntrospectionKey_Impl::hashIntrospectionKey_Impl
+(
+ const Sequence< Reference<XIdlClass> > & rIdlClasses,
+ const Reference<XPropertySetInfo> & rxPropInfo,
+ const Reference<XIdlClass> & rxImplClass
+)
+ : aIdlClasses( rIdlClasses )
+ , xPropInfo( rxPropInfo )
+ , xImplClass( rxImplClass )
+ , nHitCount( 0 )
+{}
+
+
+struct hashIntrospectionAccessCache_Impl
+{
+ size_t operator()(const hashIntrospectionKey_Impl & rObj ) const
+ {
+ return (size_t)rObj.xImplClass.get() ^ (size_t)rObj.xPropInfo.get();
+ }
+
+ bool operator()( const hashIntrospectionKey_Impl & rObj1,
+ const hashIntrospectionKey_Impl & rObj2 ) const
+ {
+ if( rObj1.xPropInfo != rObj2.xPropInfo
+ || rObj1.xImplClass != rObj2.xImplClass )
+ return sal_False;
+
+ sal_Int32 nCount1 = rObj1.aIdlClasses.getLength();
+ sal_Int32 nCount2 = rObj2.aIdlClasses.getLength();
+ if( nCount1 != nCount2 )
+ return sal_False;
+
+ const Reference<XIdlClass>* pRefs1 = rObj1.aIdlClasses.getConstArray();
+ const Reference<XIdlClass>* pRefs2 = rObj2.aIdlClasses.getConstArray();
+ return memcmp( pRefs1, pRefs2, nCount1 * sizeof( Reference<XIdlClass> ) ) == 0;
+ }
+
+};
+
+typedef std::hash_map
+<
+ hashIntrospectionKey_Impl,
+ IntrospectionAccessStatic_Impl*,
+ hashIntrospectionAccessCache_Impl,
+ hashIntrospectionAccessCache_Impl
+>
+IntrospectionAccessCacheMap_Impl;
+
+class IntrospectionAccessCacheMap : public IntrospectionAccessCacheMap_Impl
+{
+public:
+ ~IntrospectionAccessCacheMap()
+ {
+ IntrospectionAccessCacheMap::iterator iter = begin();
+ IntrospectionAccessCacheMap::iterator stop = this->end();
+ while( iter != stop )
+ {
+
+ (*iter).second->release();
+ (*iter).second = NULL;
+ iter++;
+ }
+ }
+};
+
+
+// For XTypeProvider
+struct hashTypeProviderKey_Impl
+{
+ Reference<XPropertySetInfo> xPropInfo;
+ Sequence< sal_Int8 > maImpIdSeq;
+ sal_Int32 nHitCount;
+
+ void IncHitCount() const { ((hashTypeProviderKey_Impl*)this)->nHitCount++; }
+ hashTypeProviderKey_Impl() : nHitCount( 0 ) {}
+ hashTypeProviderKey_Impl( const Reference<XPropertySetInfo> & rxPropInfo, const Sequence< sal_Int8 > & aImpIdSeq_ );
+};
+
+hashTypeProviderKey_Impl::hashTypeProviderKey_Impl
+(
+ const Reference<XPropertySetInfo> & rxPropInfo,
+ const Sequence< sal_Int8 > & aImpIdSeq_
+)
+ : xPropInfo( rxPropInfo )
+ , maImpIdSeq( aImpIdSeq_ )
+ , nHitCount( 0 )
+{}
+
+
+struct TypeProviderAccessCache_Impl
+{
+ size_t operator()(const hashTypeProviderKey_Impl & rObj ) const;
+
+ bool operator()( const hashTypeProviderKey_Impl & rObj1,
+ const hashTypeProviderKey_Impl & rObj2 ) const
+ {
+ if( rObj1.xPropInfo != rObj2.xPropInfo )
+ return sal_False;
+
+ bool bEqual = false;
+ sal_Int32 nLen1 = rObj1.maImpIdSeq.getLength();
+ sal_Int32 nLen2 = rObj2.maImpIdSeq.getLength();
+ if( nLen1 == nLen2 && nLen1 > 0 )
+ {
+ const sal_Int8* pId1 = rObj1.maImpIdSeq.getConstArray();
+ const sal_Int8* pId2 = rObj2.maImpIdSeq.getConstArray();
+ bEqual = (memcmp( pId1, pId2, nLen1 * sizeof( sal_Int8 ) ) == 0 );
+ }
+ return bEqual;
+ }
+};
+
+size_t TypeProviderAccessCache_Impl::operator()(const hashTypeProviderKey_Impl & rObj ) const
+{
+ const sal_Int32* pBytesAsInt32Array = (const sal_Int32*)rObj.maImpIdSeq.getConstArray();
+ sal_Int32 nLen = rObj.maImpIdSeq.getLength();
+ sal_Int32 nCount32 = nLen / 4;
+ sal_Int32 nMod32 = nLen % 4;
+
+ // XOR with full 32 bit values
+ sal_Int32 nId32 = 0;
+ sal_Int32 i;
+ for( i = 0 ; i < nCount32 ; i++ )
+ nId32 ^= *(pBytesAsInt32Array++);
+
+ // XOR with remaining byte values
+ if( nMod32 )
+ {
+ const sal_Int8* pBytes = (const sal_Int8*)pBytesAsInt32Array;
+ sal_Int8* pInt8_Id32 = (sal_Int8*)&nId32;
+ for( i = 0 ; i < nMod32 ; i++ )
+ *(pInt8_Id32++) ^= *(pBytes++);
+ }
+
+ return (size_t)nId32;
+}
+
+
+typedef std::hash_map
+<
+ hashTypeProviderKey_Impl,
+ IntrospectionAccessStatic_Impl*,
+ TypeProviderAccessCache_Impl,
+ TypeProviderAccessCache_Impl
+>
+TypeProviderAccessCacheMap_Impl;
+
+class TypeProviderAccessCacheMap : public TypeProviderAccessCacheMap_Impl
+{
+public:
+ ~TypeProviderAccessCacheMap()
+ {
+ TypeProviderAccessCacheMap::iterator iter = begin();
+ TypeProviderAccessCacheMap::iterator stop = this->end();
+ while( iter != stop )
+ {
+ (*iter).second->release();
+ (*iter).second = NULL;
+ iter++;
+ }
+ }
+};
+
+#endif
+
+
+//*************************
+//*** ImplIntrospection ***
+//*************************
+
+struct OIntrospectionMutex
+{
+ Mutex m_mutex;
+};
+
+class ImplIntrospection : public XIntrospection
+ , public XServiceInfo
+ , public OIntrospectionMutex
+ , public OComponentHelper
+{
+ friend class ImplMergeIntrospection;
+ friend class ImplMVCIntrospection;
+
+ // Implementation der Introspection.
+ // ACHTUNG: RefCounting von Hand !!!
+ IntrospectionAccessStatic_Impl* implInspect(const Any& aToInspectObj);
+
+ // Save XMultiServiceFactory from createComponent
+ Reference<XMultiServiceFactory> m_xSMgr;
+
+ // CoreReflection halten
+ Reference< XIdlReflection > mxCoreReflection;
+
+ // Klassen, deren Methoden eine spezielle Rolle spielen
+ Reference<XIdlClass> mxElementAccessClass;
+ Reference<XIdlClass> mxNameContainerClass;
+ Reference<XIdlClass> mxNameAccessClass;
+ Reference<XIdlClass> mxIndexContainerClass;
+ Reference<XIdlClass> mxIndexAccessClass;
+ Reference<XIdlClass> mxEnumerationAccessClass;
+ Reference<XIdlClass> mxInterfaceClass;
+ Reference<XIdlClass> mxAggregationClass;
+ sal_Bool mbDisposed;
+
+#ifdef USE_INTROSPECTION_CACHE
+ sal_uInt16 mnCacheEntryCount;
+ sal_uInt16 mnTPCacheEntryCount;
+ IntrospectionAccessCacheMap* mpCache;
+ TypeProviderAccessCacheMap* mpTypeProviderCache;
+#endif
+
+public:
+ ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr );
+
+ // Methoden von XInterface
+ virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
+ virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); }
+ virtual void SAL_CALL release() throw() { OComponentHelper::release(); }
+
+ // XTypeProvider
+ Sequence< Type > SAL_CALL getTypes( ) throw( RuntimeException );
+ Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw( RuntimeException );
+
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() throw();
+ sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
+ Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
+ static OUString SAL_CALL getImplementationName_Static( );
+ static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(void) throw();
+
+ // Methoden von XIntrospection
+ virtual Reference<XIntrospectionAccess> SAL_CALL inspect(const Any& aToInspectObj)
+ throw( RuntimeException );
+
+protected:
+ // some XComponent part from OComponentHelper
+ virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
+};
+
+enum MethodType
+{
+ STANDARD_METHOD, // normale Methode, kein Bezug zu Properties oder Listenern
+ GETSET_METHOD, // gehoert zu einer get/set-Property
+ ADD_LISTENER_METHOD, // add-Methode einer Listener-Schnittstelle
+ REMOVE_LISTENER_METHOD, // remove-Methode einer Listener-Schnittstelle
+ INVALID_METHOD // Methode, deren Klasse nicht beruecksichtigt wird, z.B. XPropertySet
+};
+
+// Ctor
+ImplIntrospection::ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr )
+ : OComponentHelper( m_mutex )
+ , m_xSMgr( rXSMgr )
+{
+#ifdef USE_INTROSPECTION_CACHE
+ mnCacheEntryCount = 0;
+ mnTPCacheEntryCount = 0;
+ mpCache = NULL;
+ mpTypeProviderCache = NULL;
+#endif
+
+ // Spezielle Klassen holen
+// Reference< XInterface > xServiceIface = m_xSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) );
+// if( xServiceIface.is() )
+// mxCoreReflection = Reference< XIdlReflection >::query( xServiceIface );
+ Reference< XPropertySet > xProps( rXSMgr, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if (xProps.is())
+ {
+ Reference< XComponentContext > xContext;
+ xProps->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
+ OSL_ASSERT( xContext.is() );
+ if (xContext.is())
+ {
+ xContext->getValueByName(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection") ) ) >>= mxCoreReflection;
+ OSL_ENSURE( mxCoreReflection.is(), "### CoreReflection singleton not accessible!?" );
+ }
+ }
+ if (! mxCoreReflection.is())
+ {
+ throw DeploymentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible") ),
+ Reference< XInterface >() );
+ }
+
+ mxElementAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XElementAccess")) );
+ mxNameContainerClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XNameContainer")) );
+ mxNameAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XNameAccess")) );
+ mxIndexContainerClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XIndexContainer")) );
+ mxIndexAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XIndexAccess")) );
+ mxEnumerationAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XEnumerationAccess")) );
+ mxInterfaceClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface")) );
+ mxAggregationClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XAggregation")) );
+ mbDisposed = sal_False;
+}
+
+// XComponent
+void ImplIntrospection::dispose() throw(::com::sun::star::uno::RuntimeException)
+{
+ OComponentHelper::dispose();
+
+#ifdef USE_INTROSPECTION_CACHE
+ // Cache loeschen
+ delete mpCache;
+ mpCache = NULL;
+ delete mpTypeProviderCache;
+ mpTypeProviderCache = NULL;
+#endif
+
+ mxElementAccessClass = NULL;
+ mxNameContainerClass = NULL;
+ mxNameAccessClass = NULL;
+ mxIndexContainerClass = NULL;
+ mxIndexAccessClass = NULL;
+ mxEnumerationAccessClass = NULL;
+ mxInterfaceClass = NULL;
+ mxAggregationClass = NULL;
+ mbDisposed = sal_True;
+}
+
+
+//-----------------------------------------------------------------------------
+
+// XInterface
+Any ImplIntrospection::queryInterface( const Type & rType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Any aRet( ::cppu::queryInterface(
+ rType,
+ static_cast< XIntrospection * >( this ),
+ static_cast< XServiceInfo * >( this ) ) );
+
+ return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType ));
+}
+
+// XTypeProvider
+Sequence< Type > ImplIntrospection::getTypes()
+ throw( RuntimeException )
+{
+ static OTypeCollection * s_pTypes = 0;
+ if (! s_pTypes)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pTypes)
+ {
+ static OTypeCollection s_aTypes(
+ ::getCppuType( (const Reference< XIntrospection > *)0 ),
+ ::getCppuType( (const Reference< XServiceInfo > *)0 ),
+ OComponentHelper::getTypes() );
+ s_pTypes = &s_aTypes;
+ }
+ }
+ return s_pTypes->getTypes();
+}
+
+Sequence< sal_Int8 > ImplIntrospection::getImplementationId()
+ throw( RuntimeException )
+{
+ static OImplementationId * s_pId = 0;
+ if (! s_pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pId)
+ {
+ static OImplementationId s_aId;
+ s_pId = &s_aId;
+ }
+ }
+ return s_pId->getImplementationId();
+}
+
+
+// XServiceInfo
+OUString ImplIntrospection::getImplementationName() throw()
+{
+ return getImplementationName_Static();
+}
+
+// XServiceInfo
+sal_Bool ImplIntrospection::supportsService(const OUString& ServiceName) throw()
+{
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getConstArray();
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+// XServiceInfo
+Sequence< OUString > ImplIntrospection::getSupportedServiceNames(void) throw()
+{
+ return getSupportedServiceNames_Static();
+}
+
+//*************************************************************************
+// Helper XServiceInfo
+OUString ImplIntrospection::getImplementationName_Static( )
+{
+ return OUString::createFromAscii( IMPLEMENTATION_NAME );
+}
+
+// ORegistryServiceManager_Static
+Sequence< OUString > ImplIntrospection::getSupportedServiceNames_Static(void) throw()
+{
+ Sequence< OUString > aSNS( 1 );
+ aSNS.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
+ return aSNS;
+}
+
+//*************************************************************************
+
+// Methoden von XIntrospection
+Reference<XIntrospectionAccess> ImplIntrospection::inspect(const Any& aToInspectObj)
+ throw( RuntimeException )
+{
+ Reference<XIntrospectionAccess> xAccess;
+
+ if ( aToInspectObj.getValueType().getTypeClass() == TypeClass_TYPE )
+ {
+ Type aType;
+ aToInspectObj >>= aType;
+
+ Reference< XIdlClass > xIdlClass = mxCoreReflection->forName(((Type*)(aToInspectObj.getValue()))->getTypeName());
+
+ if ( xIdlClass.is() )
+ {
+ Any aRealInspectObj;
+ aRealInspectObj <<= xIdlClass;
+
+ IntrospectionAccessStatic_Impl* pStaticImpl = implInspect( aRealInspectObj );
+ if( pStaticImpl )
+ xAccess = new ImplIntrospectionAccess( aRealInspectObj, pStaticImpl );
+ }
+ }
+ else
+ {
+ IntrospectionAccessStatic_Impl* pStaticImpl = implInspect( aToInspectObj );
+ if( pStaticImpl )
+ xAccess = new ImplIntrospectionAccess( aToInspectObj, pStaticImpl );
+ }
+
+ return xAccess;
+}
+
+//-----------------------------------------------------------------------------
+
+// Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
+struct hashInterface_Impl
+{
+ size_t operator()(const void* p) const
+ {
+ return (size_t)p;
+ }
+};
+
+struct eqInterface_Impl
+{
+ bool operator()(const void* p1, const void* p2) const
+ {
+ return ( p1 == p2 );
+ }
+};
+
+typedef std::hash_map
+<
+ void*,
+ void*,
+ hashInterface_Impl,
+ eqInterface_Impl
+>
+CheckedInterfacesMap;
+
+
+
+// TODO: Spaeter auslagern
+Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr )
+{
+ static Reference< XIdlReflection > xRefl;
+
+ // void als Default-Klasse eintragen
+ Reference<XIdlClass> xRetClass;
+ typelib_TypeDescription * pTD = 0;
+ rType.getDescription( &pTD );
+ if( pTD )
+ {
+ OUString sOWName( pTD->pTypeName );
+ if( !xRefl.is() )
+ {
+ xRefl = Reference< XIdlReflection >( xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) ), UNO_QUERY );
+ OSL_ENSURE( xRefl.is(), "### no corereflection!" );
+ }
+ xRetClass = xRefl->forName( sOWName );
+ }
+ return xRetClass;
+}
+
+// Implementation der Introspection.
+IntrospectionAccessStatic_Impl* ImplIntrospection::implInspect(const Any& aToInspectObj)
+{
+ MutexGuard aGuard( m_mutex );
+
+ // Wenn die Introspection schon disposed ist, wird nur ein leeres Ergebnis geliefert
+ if( mbDisposed )
+ return NULL;
+
+ // Objekt untersuchen
+ TypeClass eType = aToInspectObj.getValueType().getTypeClass();
+ if( eType != TypeClass_INTERFACE && eType != TypeClass_STRUCT && eType != TypeClass_EXCEPTION )
+ return NULL;
+
+ Reference<XInterface> x;
+ if( eType == TypeClass_INTERFACE )
+ {
+ // Interface aus dem Any besorgen
+ x = *(Reference<XInterface>*)aToInspectObj.getValue();
+ if( !x.is() )
+ return NULL;
+ }
+
+#ifdef USE_INTROSPECTION_CACHE
+ // Haben wir schon eine Cache-Instanz
+ if( !mpCache )
+ mpCache = new IntrospectionAccessCacheMap;
+ if( !mpTypeProviderCache )
+ mpTypeProviderCache = new TypeProviderAccessCacheMap;
+ IntrospectionAccessCacheMap& aCache = *mpCache;
+ TypeProviderAccessCacheMap& aTPCache = *mpTypeProviderCache;
+
+ // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
+ IntrospectionAccessStatic_Impl* pAccess = NULL;
+#else
+ // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
+ IntrospectionAccessStatic_Impl* pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
+#endif
+
+ // Pruefen: Ist schon ein passendes Access-Objekt gecached?
+ Sequence< Reference<XIdlClass> > SupportedClassSeq;
+ Sequence< Type > SupportedTypesSeq;
+ Reference<XIdlClassProvider> xClassProvider;
+ Reference<XTypeProvider> xTypeProvider;
+ Reference<XIdlClass> xImplClass;
+ Reference<XPropertySetInfo> xPropSetInfo;
+ Reference<XPropertySet> xPropSet;
+
+ // Bei Interfaces XTypeProvider / XIdlClassProvider- und PropertySet-Interface anfordern
+ if( eType == TypeClass_INTERFACE )
+ {
+ // XIdlClassProvider
+ xTypeProvider = Reference<XTypeProvider>::query( x );
+ if( xTypeProvider.is() )
+ {
+ SupportedTypesSeq = xTypeProvider->getTypes();
+ sal_Int32 nTypeCount = SupportedTypesSeq.getLength();
+ if( nTypeCount )
+ {
+ SupportedClassSeq.realloc( nTypeCount );
+ Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray();
+
+ const Type* pTypes = SupportedTypesSeq.getConstArray();
+ for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
+ {
+ pClasses[ i ] = TypeToIdlClass( pTypes[ i ], m_xSMgr );
+ }
+ // TODO: Caching!
+ }
+ }
+ else
+ {
+ // XIdlClassProvider
+ xClassProvider = Reference<XIdlClassProvider>::query( x );
+ if( xClassProvider.is() )
+ {
+ SupportedClassSeq = xClassProvider->getIdlClasses();
+ if( SupportedClassSeq.getLength() )
+ xImplClass = SupportedClassSeq.getConstArray()[0];
+ }
+ }
+ // #70197, fuer InvocationAdapter: Interface-Typ im Any auch ohne
+ // ClassProvider unterstuetzen
+ if( !xClassProvider.is() && !xTypeProvider.is() )
+ {
+ xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
+ SupportedClassSeq.realloc( 1 );
+ SupportedClassSeq.getArray()[ 0 ] = xImplClass;
+ }
+
+ xPropSet = Reference<XPropertySet>::query( x );
+ // Jetzt versuchen, das PropertySetInfo zu bekommen
+ if( xPropSet.is() )
+ xPropSetInfo = xPropSet->getPropertySetInfo();
+ }
+ else
+ {
+ xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
+ }
+
+#ifdef USE_INTROSPECTION_CACHE
+ if( xTypeProvider.is() )
+ {
+ Sequence< sal_Int8 > aImpIdSeq = xTypeProvider->getImplementationId();
+ sal_Int32 nIdLen = aImpIdSeq.getLength();
+
+ if( nIdLen )
+ {
+ // cache only, if the descriptor class is set
+ hashTypeProviderKey_Impl aKeySeq( xPropSetInfo, aImpIdSeq );
+
+ TypeProviderAccessCacheMap::iterator aIt = aTPCache.find( aKeySeq );
+ if( aIt == aTPCache.end() )
+ {
+ // not found
+ // Neue Instanz anlegen und unter dem gegebenen Key einfuegen
+ pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
+
+ // RefCount von Hand erhoehen, muss beim Entfernen
+ // aus der Hashtable wieder released werden
+ pAccess->acquire();
+
+ // Groesse begrenzen, alten Eintrag wieder rausschmeissen
+ if( mnTPCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE )
+ {
+ // Access mit dem kleinsten HitCount suchen
+ TypeProviderAccessCacheMap::iterator iter = aTPCache.begin();
+ TypeProviderAccessCacheMap::iterator end = aTPCache.end();
+ TypeProviderAccessCacheMap::iterator toDelete = iter;
+ while( iter != end )
+ {
+ if( (*iter).first.nHitCount < (*toDelete).first.nHitCount )
+ toDelete = iter;
+ ++iter;
+ }
+
+ // Gefundenen Eintrag entfernen
+ if( (*toDelete).second )
+ (*toDelete).second->release();
+ (*toDelete).second = NULL;
+ aTPCache.erase( toDelete );
+ }
+ else
+ mnTPCacheEntryCount++;
+
+ // Neuer Eintrage rein in die Table
+ aKeySeq.nHitCount = 1;
+ aTPCache[ aKeySeq ] = pAccess;
+
+ }
+ else
+ {
+ // Hit-Count erhoehen
+ (*aIt).first.IncHitCount();
+ return (*aIt).second;
+ }
+ }
+ }
+ else if( xImplClass.is() )
+ {
+ // cache only, if the descriptor class is set
+ hashIntrospectionKey_Impl aKeySeq( SupportedClassSeq, xPropSetInfo, xImplClass );
+
+ IntrospectionAccessCacheMap::iterator aIt = aCache.find( aKeySeq );
+ if( aIt == aCache.end() )
+ {
+ // not found
+ // Neue Instanz anlegen und unter dem gegebenen Key einfuegen
+ pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
+
+ // RefCount von Hand erhoehen, muss beim Entfernen
+ // aus der Hashtable wieder released werden
+ pAccess->acquire();
+
+ // Groesse begrenzen, alten Eintrag wieder rausschmeissen
+ if( mnCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE )
+ {
+ // Access mit dem kleinsten HitCount suchen
+ IntrospectionAccessCacheMap::iterator iter = aCache.begin();
+ IntrospectionAccessCacheMap::iterator end = aCache.end();
+ IntrospectionAccessCacheMap::iterator toDelete = iter;
+ while( iter != end )
+ {
+ if( (*iter).first.nHitCount < (*toDelete).first.nHitCount )
+ toDelete = iter;
+ ++iter;
+ }
+
+ // Gefundenen Eintrag entfernen
+ if( (*toDelete).second )
+ (*toDelete).second->release();
+ (*toDelete).second = NULL;
+ aCache.erase( toDelete );
+ }
+ else
+ mnCacheEntryCount++;
+
+ // Neuer Eintrage rein in die Table
+ aKeySeq.nHitCount = 1;
+ aCache[ aKeySeq ] = pAccess;
+
+ }
+ else
+ {
+ // Hit-Count erhoehen
+ (*aIt).first.IncHitCount();
+ return (*aIt).second;
+ }
+ }
+#endif
+
+ // Kein Access gecached -> neu anlegen
+ Property* pAllPropArray;
+ Reference<XInterface>* pInterfaces1;
+ Reference<XInterface>* pInterfaces2;
+ sal_Int16* pMapTypeArray;
+ sal_Int32* pPropertyConceptArray;
+ sal_Int32 i;
+
+ if( !pAccess )
+ pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
+
+ // Referenzen auf wichtige Daten von pAccess
+ sal_Int32& rPropCount = pAccess->mnPropCount;
+ IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
+ IntrospectionNameMap& rMethodNameMap = pAccess->maMethodNameMap;
+ LowerToExactNameMap& rLowerToExactNameMap = pAccess->maLowerToExactNameMap;
+
+ // Schon mal Pointer auf das eigene Property-Feld holen
+ pAllPropArray = pAccess->maAllPropertySeq.getArray();
+ pInterfaces1 = pAccess->aInterfaceSeq1.getArray();
+ pInterfaces2 = pAccess->aInterfaceSeq2.getArray();
+ pMapTypeArray = pAccess->maMapTypeSeq.getArray();
+ pPropertyConceptArray = pAccess->maPropertyConceptSeq.getArray();
+
+ //*************************
+ //*** Analyse vornehmen ***
+ //*************************
+ if( eType == TypeClass_INTERFACE )
+ {
+ // Zunaechst nach speziellen Interfaces suchen, die fuer
+ // die Introspection von besonderer Bedeutung sind.
+
+ // XPropertySet vorhanden?
+ if( xPropSet.is() && xPropSetInfo.is() )
+ {
+ // Gibt es auch ein FastPropertySet?
+ Reference<XFastPropertySet> xDummy = Reference<XFastPropertySet>::query( x );
+ sal_Bool bFast = pAccess->mbFastPropSet = xDummy.is();
+
+ Sequence<Property> aPropSeq = xPropSetInfo->getProperties();
+ const Property* pProps = aPropSeq.getConstArray();
+ sal_Int32 nLen = aPropSeq.getLength();
+
+ // Bei FastPropertySet muessen wir uns die Original-Handles merken
+ if( bFast )
+ pAccess->mpOrgPropertyHandleArray = new sal_Int32[ nLen ];
+
+ for( i = 0 ; i < nLen ; i++ )
+ {
+ // Property in eigene Liste uebernehmen
+ pAccess->checkPropertyArraysSize
+ ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
+ Property& rProp = pAllPropArray[ rPropCount ];
+ rProp = pProps[ i ];
+
+ if( bFast )
+ pAccess->mpOrgPropertyHandleArray[ i ] = rProp.Handle;
+
+ // PropCount als Handle fuer das eigene FastPropertySet eintragen
+ rProp.Handle = rPropCount;
+
+ // Art der Property merken
+ pMapTypeArray[ rPropCount ] = MAP_PROPERTY_SET;
+ pPropertyConceptArray[ rPropCount ] = PROPERTYSET;
+ pAccess->mnPropertySetPropCount++;
+
+ // Namen in Hashtable eintragen, wenn nicht schon bekannt
+ OUString aPropName = rProp.Name;
+
+ // Haben wir den Namen schon?
+ IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
+ if( aIt == rPropNameMap.end() )
+ {
+ // Neuer Eintrag in die Hashtable
+ rPropNameMap[ aPropName ] = rPropCount;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ OString( "Introspection: Property \"" ) +
+ OUStringToOString( aPropName, RTL_TEXTENCODING_ASCII_US ) +
+ OString( "\" found more than once in PropertySet" ) );
+ }
+
+ // Count pflegen
+ rPropCount++;
+ }
+ }
+
+
+ // Jetzt alle weiteren implementierten Interfaces durchgehen
+ // Diese muessen durch das XIdlClassProvider-Interface geliefert werden.
+ // #70197, fuer InvocationAdapter: Interface-Typ im Any auch ohne
+ // ClassProvider unterstuetzen
+ //if( xClassProvider.is() )
+ {
+ // Indizes in die Export-Tabellen
+ sal_Int32 iAllExportedMethod = 0;
+ sal_Int32 iAllSupportedListener = 0;
+
+ // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
+ CheckedInterfacesMap aCheckedInterfacesMap;
+
+ // Flag, ob XInterface-Methoden erfasst werden sollen
+ // (das darf nur einmal erfolgen, initial zulassen)
+ sal_Bool bXInterfaceIsInvalid = sal_False;
+
+ // Flag, ob die XInterface-Methoden schon erfasst wurden. Wenn sal_True,
+ // wird bXInterfaceIsInvalid am Ende der Iface-Schleife aktiviert und
+ // XInterface-Methoden werden danach abgeklemmt.
+ sal_Bool bFoundXInterface = sal_False;
+
+ // Schleife ueber alle vom ClassProvider angegebenen Klassen
+ sal_Int32 nClassCount = SupportedClassSeq.getLength();
+ for( sal_Int32 nIdx = 0 ; nIdx < nClassCount; nIdx++ )
+ {
+ Reference<XIdlClass> xImplClass2 = SupportedClassSeq.getConstArray()[nIdx];
+ while( xImplClass2.is() )
+ {
+ // Interfaces der Implementation holen
+ Sequence< Reference<XIdlClass> > aClassSeq = xImplClass2->getInterfaces();
+ sal_Int32 nIfaceCount = aClassSeq.getLength();
+
+ aClassSeq.realloc( nIfaceCount + 1 );
+ aClassSeq.getArray()[ nIfaceCount ] = xImplClass2;
+ nIfaceCount++;
+
+ const Reference<XIdlClass>* pParamArray = aClassSeq.getConstArray();
+
+ for( sal_Int32 j = 0 ; j < nIfaceCount ; j++ )
+ {
+ const Reference<XIdlClass>& rxIfaceClass = pParamArray[j];
+
+ // Pruefen, ob das Interface schon beruecksichtigt wurde.
+ XInterface* pIface = SAL_STATIC_CAST( XInterface*, rxIfaceClass.get() );
+ if( aCheckedInterfacesMap.count( pIface ) > 0 )
+ {
+ // Kennen wir schon
+ continue;
+ }
+ else
+ {
+ // Sonst eintragen
+ aCheckedInterfacesMap[ pIface ] = pIface;
+ }
+
+ //********************************************************************
+
+ // 2. Fields als Properties registrieren
+
+ // Felder holen
+ Sequence< Reference<XIdlField> > fields = rxIfaceClass->getFields();
+ const Reference<XIdlField>* pFields = fields.getConstArray();
+ sal_Int32 nLen = fields.getLength();
+
+ for( i = 0 ; i < nLen ; i++ )
+ {
+ Reference<XIdlField> xField = pFields[i];
+ Reference<XIdlClass> xPropType = xField->getType();
+
+ // Ist die PropertySequence gross genug?
+ pAccess->checkPropertyArraysSize
+ ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
+
+ // In eigenes Property-Array eintragen
+ Property& rProp = pAllPropArray[ rPropCount ];
+ OUString aFieldName = xField->getName();
+ rProp.Name = aFieldName;
+ rProp.Handle = rPropCount;
+ Type aFieldType( xPropType->getTypeClass(), xPropType->getName() );
+ rProp.Type = aFieldType;
+ FieldAccessMode eAccessMode = xField->getAccessMode();
+ rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
+ eAccessMode == FieldAccessMode_CONST)
+ ? READONLY : 0;
+
+ // Namen in Hashtable eintragen
+ OUString aPropName = rProp.Name;
+
+ // Haben wir den Namen schon?
+ IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
+ if( !( aIt == rPropNameMap.end() ) )
+ {
+ /* TODO
+ OSL_TRACE(
+ String( "Introspection: Property \"" ) +
+ OOUStringToString( aPropName, CHARSET_SYSTEM ) +
+ String( "\" found more than once" ) );
+ */
+ continue;
+ }
+
+ // Neuer Eintrag in die Hashtable
+ rPropNameMap[ aPropName ] = rPropCount;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
+
+ // Field merken
+ pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
+ pInterfaces1, rPropCount );
+ pInterfaces1[ rPropCount ] = xField;
+
+ // Art der Property merken
+ pMapTypeArray[ rPropCount ] = MAP_FIELD;
+ pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
+ pAccess->mnAttributePropCount++;
+
+ // Count pflegen
+ rPropCount++;
+ }
+
+ //********************************************************************
+
+ // 3. Methoden
+
+ // Zaehler fuer die gefundenen Listener
+ sal_Int32 nListenerCount = 0;
+
+ // Alle Methoden holen und merken
+ Sequence< Reference<XIdlMethod> > methods = rxIfaceClass->getMethods();
+ const Reference<XIdlMethod>* pSourceMethods = methods.getConstArray();
+ sal_Int32 nSourceMethodCount = methods.getLength();
+
+ // 3. a) get/set- und Listener-Methoden suchen
+
+ // Feld fuer Infos ueber die Methoden anlegen, damit spaeter leicht die Methoden
+ // gefunden werden koennen, die nicht im Zusammenhang mit Properties oder Listenern
+ // stehen. NEU: auch MethodConceptArray initialisieren
+ MethodType* pMethodTypes = new MethodType[ nSourceMethodCount ];
+ sal_Int32* pLocalMethodConcepts = new sal_Int32[ nSourceMethodCount ];
+ for( i = 0 ; i < nSourceMethodCount ; i++ )
+ {
+ pMethodTypes[ i ] = STANDARD_METHOD;
+ pLocalMethodConcepts[ i ] = 0;
+ }
+
+ OUString aMethName;
+ OUString aPropName;
+ OUString aStartStr;
+ for( i = 0 ; i < nSourceMethodCount ; i++ )
+ {
+ // Methode ansprechen
+ const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
+ sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
+
+ // Namen besorgen
+ aMethName = rxMethod_i->getName();
+
+ // Methoden katalogisieren
+ // Alle (?) Methoden von XInterface filtern, damit z.B. nicht
+ // vom Scripting aus aquire oder release gerufen werden kann
+ if( rxMethod_i->getDeclaringClass()->equals( mxInterfaceClass ) )
+ {
+ // XInterface-Methoden sind hiermit einmal beruecksichtigt
+ bFoundXInterface = sal_True;
+
+ if( bXInterfaceIsInvalid )
+ {
+ pMethodTypes[ i ] = INVALID_METHOD;
+ continue;
+ }
+ else
+ {
+ if( aMethName != OUString( RTL_CONSTASCII_USTRINGPARAM("queryInterface")) )
+ {
+ rMethodConcept_i |= MethodConcept::DANGEROUS;
+ continue;
+ }
+ }
+ }
+ else if( rxMethod_i->getDeclaringClass()->equals( mxAggregationClass ) )
+ {
+ if( aMethName == OUString( RTL_CONSTASCII_USTRINGPARAM("setDelegator")) )
+ {
+ rMethodConcept_i |= MethodConcept::DANGEROUS;
+ continue;
+ }
+ }
+ else if( rxMethod_i->getDeclaringClass()->equals( mxElementAccessClass ) )
+ {
+ rMethodConcept_i |= ( NAMECONTAINER |
+ INDEXCONTAINER |
+ ENUMERATION );
+ }
+ else if( rxMethod_i->getDeclaringClass()->equals( mxNameContainerClass ) ||
+ rxMethod_i->getDeclaringClass()->equals( mxNameAccessClass ) )
+ {
+ rMethodConcept_i |= NAMECONTAINER;
+ }
+ else if( rxMethod_i->getDeclaringClass()->equals( mxIndexContainerClass ) ||
+ rxMethod_i->getDeclaringClass()->equals( mxIndexAccessClass ) )
+ {
+ rMethodConcept_i |= INDEXCONTAINER;
+ }
+ else if( rxMethod_i->getDeclaringClass()->equals( mxEnumerationAccessClass ) )
+ {
+ rMethodConcept_i |= ENUMERATION;
+ }
+
+ // Wenn der Name zu kurz ist, wird's sowieso nichts
+ if( aMethName.getLength() <= 3 )
+ continue;
+
+ // Ist es eine get-Methode?
+ aStartStr = aMethName.copy( 0, 3 );
+ if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("get")) )
+ {
+ // Namen der potentiellen Property
+ aPropName = aMethName.copy( 3 );
+
+ // get-Methode darf keinen Parameter haben
+ Sequence< Reference<XIdlClass> > getParams = rxMethod_i->getParameterTypes();
+ if( getParams.getLength() > 0 )
+ {
+ continue;
+ }
+
+ // Haben wir den Namen schon?
+ IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
+ if( !( aIt == rPropNameMap.end() ) )
+ {
+ /* TODO
+ OSL_TRACE(
+ String( "Introspection: Property \"" ) +
+ OOUStringToString( aPropName, CHARSET_SYSTEM ) +
+ String( "\" found more than once" ) );
+ */
+ continue;
+ }
+
+ // Eine readonly-Property ist es jetzt mindestens schon
+ rMethodConcept_i |= PROPERTY;
+
+ pMethodTypes[i] = GETSET_METHOD;
+ Reference<XIdlClass> xGetRetType = rxMethod_i->getReturnType();
+
+ // Ist die PropertySequence gross genug?
+ pAccess->checkPropertyArraysSize
+ ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
+
+ // In eigenes Property-Array eintragen
+ Property& rProp = pAllPropArray[ rPropCount ];
+ rProp.Name = aPropName;
+ rProp.Handle = rPropCount;
+ rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
+ rProp.Attributes = READONLY;
+
+ // Neuer Eintrag in die Hashtable
+ rPropNameMap[ aPropName ] = rPropCount;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
+
+ // get-Methode merken
+ pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
+ pInterfaces1, rPropCount );
+ pInterfaces1[ rPropCount ] = rxMethod_i;
+
+ // Art der Property merken
+ pMapTypeArray[ rPropCount ] = MAP_GETSET;
+ pPropertyConceptArray[ rPropCount ] = METHODS;
+ pAccess->mnMethodPropCount++;
+
+ // Passende set-Methode suchen
+ sal_Int32 k;
+ for( k = 0 ; k < nSourceMethodCount ; k++ )
+ {
+ // Methode ansprechen
+ const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
+
+ // Nur Methoden nehmen, die nicht schon zugeordnet sind
+ if( k == i || pMethodTypes[k] != STANDARD_METHOD )
+ continue;
+
+ // Name holen und auswerten
+ OUString aMethName2 = rxMethod_k->getName();
+ OUString aStartStr2 = aMethName2.copy( 0, 3 );
+ // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
+ if( !( aStartStr2 == OUString( RTL_CONSTASCII_USTRINGPARAM("set")) ) )
+ continue;
+
+ // Ist es denn der gleiche Name?
+ OUString aPropName2 = aMethName2.copy( 3 );
+ // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
+ if( !( aPropName == aPropName2 ) )
+ continue;
+
+ // set-Methode muss void returnen
+ Reference<XIdlClass> xSetRetType = rxMethod_k->getReturnType();
+ if( xSetRetType->getTypeClass() != TypeClass_VOID )
+ {
+ continue;
+ }
+
+ // set-Methode darf nur einen Parameter haben
+ Sequence< Reference<XIdlClass> > setParams = rxMethod_k->getParameterTypes();
+ sal_Int32 nParamCount = setParams.getLength();
+ if( nParamCount != 1 )
+ {
+ continue;
+ }
+
+ // Jetzt muss nur noch der return-Typ dem Parameter-Typ entsprechen
+ const Reference<XIdlClass>* pParamArray2 = setParams.getConstArray();
+ Reference<XIdlClass> xParamType = pParamArray2[ 0 ];
+ if( xParamType->equals( xGetRetType ) )
+ {
+ pLocalMethodConcepts[ k ] = PROPERTY;
+
+ pMethodTypes[k] = GETSET_METHOD;
+
+ // ReadOnly-Flag wieder loschen
+ rProp.Attributes &= ~READONLY;
+
+ // set-Methode merken
+ pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
+ pInterfaces2, rPropCount );
+ pInterfaces2[ rPropCount ] = rxMethod_k;
+ }
+ }
+
+ // Count pflegen
+ rPropCount++;
+ }
+
+ // Ist es eine addListener-Methode?
+ else if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("add")) )
+ {
+ OUString aListenerStr( RTL_CONSTASCII_USTRINGPARAM("Listener" ) );
+
+ // Namen der potentiellen Property
+ sal_Int32 nStrLen = aMethName.getLength();
+ sal_Int32 nCopyLen = nStrLen - aListenerStr.getLength();
+ OUString aEndStr = aMethName.copy( nCopyLen > 0 ? nCopyLen : 0 );
+
+ // Endet das Teil auf Listener?
+ // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
+ if( !( aEndStr == aListenerStr ) )
+ continue;
+
+ // Welcher Listener?
+ OUString aListenerName = aMethName.copy( 3, nStrLen - aListenerStr.getLength() - 3 );
+
+ // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
+ // - Rueckgabe-Typ
+ // - Anzahl und Art der Parameter
+
+
+ // Passende remove-Methode suchen, sonst gilt's nicht
+ sal_Int32 k;
+ for( k = 0 ; k < nSourceMethodCount ; k++ )
+ {
+ // Methode ansprechen
+ const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
+
+ // Nur Methoden nehmen, die nicht schon zugeordnet sind
+ if( k == i || pMethodTypes[k] != STANDARD_METHOD )
+ continue;
+
+ // Name holen und auswerten
+ OUString aMethName2 = rxMethod_k->getName();
+ sal_Int32 nNameLen = aMethName2.getLength();
+ sal_Int32 nCopyLen2 = (nNameLen < 6) ? nNameLen : 6;
+ OUString aStartStr2 = aMethName2.copy( 0, nCopyLen2 );
+ OUString aRemoveStr( RTL_CONSTASCII_USTRINGPARAM("remove" ) );
+ // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
+ if( !( aStartStr2 == aRemoveStr ) )
+ continue;
+
+ // Ist es denn der gleiche Listener?
+ if( aMethName2.getLength() - aRemoveStr.getLength() <= aListenerStr.getLength() )
+ continue;
+ OUString aListenerName2 = aMethName2.copy
+ ( 6, aMethName2.getLength() - aRemoveStr.getLength() - aListenerStr.getLength() );
+ // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
+ if( !( aListenerName == aListenerName2 ) )
+ continue;
+
+ // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
+ // - Rueckgabe-Typ
+ // - Anzahl und Art der Parameter
+
+
+ // Methoden sind als Listener-Schnittstelle erkannt
+ rMethodConcept_i |= LISTENER;
+ pLocalMethodConcepts[ k ] |= LISTENER;
+
+ pMethodTypes[i] = ADD_LISTENER_METHOD;
+ pMethodTypes[k] = REMOVE_LISTENER_METHOD;
+ nListenerCount++;
+ }
+ }
+ }
+
+
+ // Jetzt koennen noch SET-Methoden ohne zugehoerige GET-Methode existieren,
+ // diese muessen zu Write-Only-Properties gemachte werden.
+ for( i = 0 ; i < nSourceMethodCount ; i++ )
+ {
+ // Methode ansprechen
+ const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
+
+ // Nur Methoden nehmen, die nicht schon zugeordnet sind
+ if( pMethodTypes[i] != STANDARD_METHOD )
+ continue;
+
+ // Namen besorgen
+ aMethName = rxMethod_i->getName();
+
+ // Wenn der Name zu kurz ist, wird's sowieso nichts
+ if( aMethName.getLength() <= 3 )
+ continue;
+
+ // Ist es eine set-Methode ohne zugehoerige get-Methode?
+ aStartStr = aMethName.copy( 0, 3 );
+ if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("set")) )
+ {
+ // Namen der potentiellen Property
+ aPropName = aMethName.copy( 3 );
+
+ // set-Methode muss void returnen
+ Reference<XIdlClass> xSetRetType = rxMethod_i->getReturnType();
+ if( xSetRetType->getTypeClass() != TypeClass_VOID )
+ {
+ continue;
+ }
+
+ // set-Methode darf nur einen Parameter haben
+ Sequence< Reference<XIdlClass> > setParams = rxMethod_i->getParameterTypes();
+ sal_Int32 nParamCount = setParams.getLength();
+ if( nParamCount != 1 )
+ {
+ continue;
+ }
+
+ // Haben wir den Namen schon?
+ IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
+ if( !( aIt == rPropNameMap.end() ) )
+ {
+ /* TODO:
+ OSL_TRACE(
+ String( "Introspection: Property \"" ) +
+ OOUStringToString( aPropName, CHARSET_SYSTEM ) +
+ String( "\" found more than once" ) );
+ */
+ continue;
+ }
+
+ // Alles klar, es ist eine Write-Only-Property
+ pLocalMethodConcepts[ i ] = PROPERTY;
+
+ pMethodTypes[i] = GETSET_METHOD;
+ Reference<XIdlClass> xGetRetType = setParams.getConstArray()[0];
+
+ // Ist die PropertySequence gross genug?
+ pAccess->checkPropertyArraysSize
+ ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
+
+ // In eigenes Property-Array eintragen
+ Property& rProp = pAllPropArray[ rPropCount ];
+ rProp.Name = aPropName;
+ rProp.Handle = rPropCount;
+ rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
+ rProp.Attributes = 0; // PROPERTY_WRITEONLY ???
+
+ // Neuer Eintrag in die Hashtable
+ rPropNameMap[ aPropName ] = rPropCount;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
+
+ // set-Methode merken
+ pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
+ pInterfaces2, rPropCount );
+ pInterfaces2[ rPropCount ] = rxMethod_i;
+
+ // Art der Property merken
+ pMapTypeArray[ rPropCount ] = MAP_SETONLY;
+ pPropertyConceptArray[ rPropCount ] = METHODS;
+ pAccess->mnMethodPropCount++;
+
+ // Count pflegen
+ rPropCount++;
+ }
+ }
+
+
+ //********************************************************************
+
+ // 4. Methoden in die Gesamt-Sequence uebernehmen
+
+ // Wieviele Methoden muessen in die Method-Sequence?
+ sal_Int32 nExportedMethodCount = 0;
+ sal_Int32 nSupportedListenerCount = 0;
+ for( i = 0 ; i < nSourceMethodCount ; i++ )
+ {
+ if( pMethodTypes[ i ] != INVALID_METHOD )
+ {
+ nExportedMethodCount++;
+ }
+ if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
+ {
+ nSupportedListenerCount++;
+ }
+ }
+
+ // Sequences im Access-Objekt entsprechend aufbohren
+ pAccess->maAllMethodSeq.realloc( nExportedMethodCount + iAllExportedMethod );
+ pAccess->maMethodConceptSeq.realloc( nExportedMethodCount + iAllExportedMethod );
+ pAccess->maSupportedListenerSeq.realloc( nSupportedListenerCount + iAllSupportedListener );
+
+ // Methoden reinschreiben
+ Reference<XIdlMethod>* pDestMethods = pAccess->maAllMethodSeq.getArray();
+ sal_Int32* pMethodConceptArray = pAccess->maMethodConceptSeq.getArray();
+ Type* pListenerClassRefs = pAccess->maSupportedListenerSeq.getArray();
+ for( i = 0 ; i < nSourceMethodCount ; i++ )
+ {
+ if( pMethodTypes[ i ] != INVALID_METHOD )
+ {
+ // Methode ansprechen
+ const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
+
+ // Namen in Hashtable eintragen, wenn nicht schon bekannt
+ OUString aMethName2 = rxMethod->getName();
+ IntrospectionNameMap::iterator aIt = rMethodNameMap.find( aMethName2 );
+ if( aIt == rMethodNameMap.end() )
+ {
+ // Eintragen
+ rMethodNameMap[ aMethName2 ] = iAllExportedMethod;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aMethName2 ) ] = aMethName2;
+ }
+ else
+ {
+ sal_Int32 iHashResult = (*aIt).second;
+
+ Reference<XIdlMethod> xExistingMethod = pDestMethods[ iHashResult ];
+
+ Reference< XIdlClass > xExistingMethClass =
+ xExistingMethod->getDeclaringClass();
+ Reference< XIdlClass > xNewMethClass = rxMethod->getDeclaringClass();
+ if( xExistingMethClass->equals( xNewMethClass ) )
+ continue;
+ }
+
+ pDestMethods[ iAllExportedMethod ] = rxMethod;
+
+ // Wenn kein Concept gesetzt wurde, ist die Methode "normal"
+ sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
+ if( !rMethodConcept_i )
+ rMethodConcept_i = MethodConcept_NORMAL_IMPL;
+ pMethodConceptArray[ iAllExportedMethod ] = rMethodConcept_i;
+ iAllExportedMethod++;
+ }
+ if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
+ {
+ // Klasse des Listeners ermitteln
+ const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
+
+ // void als Default-Klasse eintragen
+ Reference<XIdlClass> xListenerClass = TypeToIdlClass( getCppuVoidType(), m_xSMgr );
+ // ALT: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass();
+
+ // 1. Moeglichkeit: Parameter nach einer Listener-Klasse durchsuchen
+ // Nachteil: Superklassen muessen rekursiv durchsucht werden
+ Sequence< Reference<XIdlClass> > aParams = rxMethod->getParameterTypes();
+ const Reference<XIdlClass>* pParamArray2 = aParams.getConstArray();
+
+ Reference<XIdlClass> xEventListenerClass = TypeToIdlClass( getCppuType( (Reference<XEventListener>*) NULL ), m_xSMgr );
+ // ALT: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass();
+ sal_Int32 nParamCount = aParams.getLength();
+ sal_Int32 k;
+ for( k = 0 ; k < nParamCount ; k++ )
+ {
+ const Reference<XIdlClass>& rxClass = pParamArray2[k];
+
+ // Sind wir von einem Listener abgeleitet?
+ if( rxClass->equals( xEventListenerClass ) ||
+ isDerivedFrom( rxClass, xEventListenerClass ) )
+ {
+ xListenerClass = rxClass;
+ break;
+ }
+ }
+
+ // 2. Moeglichkeit: Namen der Methode auswerden
+ // Nachteil: geht nicht bei Test-Listenern, die es nicht gibt
+ //aMethName = rxMethod->getName();
+ //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 );
+ //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName );
+ Type aListenerType( TypeClass_INTERFACE, xListenerClass->getName() );
+ pListenerClassRefs[ iAllSupportedListener ] = aListenerType;
+ iAllSupportedListener++;
+ }
+ }
+
+ // Wenn in diesem Durchlauf XInterface-Methoden
+ // dabei waren, diese zukuenftig ignorieren
+ if( bFoundXInterface )
+ bXInterfaceIsInvalid = sal_True;
+
+ delete[] pMethodTypes;
+ delete[] pLocalMethodConcepts;
+ }
+
+ // Super-Klasse(n) vorhanden? Dann dort fortsetzen
+ Sequence< Reference<XIdlClass> > aSuperClassSeq = xImplClass2->getSuperclasses();
+
+ // Zur Zeit wird nur von einer Superklasse ausgegangen
+ if( aSuperClassSeq.getLength() >= 1 )
+ {
+ xImplClass2 = aSuperClassSeq.getConstArray()[0];
+ OSL_ENSURE( xImplClass2.is(), "super class null" );
+ }
+ else
+ {
+ xImplClass2 = NULL;
+ }
+ }
+ }
+
+ // Anzahl der exportierten Methoden uebernehmen und Sequences anpassen
+ // (kann abweichen, weil doppelte Methoden erst nach der Ermittlung
+ // von nExportedMethodCount herausgeworfen werden)
+ sal_Int32& rMethCount = pAccess->mnMethCount;
+ rMethCount = iAllExportedMethod;
+ pAccess->maAllMethodSeq.realloc( rMethCount );
+ pAccess->maMethodConceptSeq.realloc( rMethCount );
+
+ // Groesse der Property-Sequences anpassen
+ pAccess->maAllPropertySeq.realloc( rPropCount );
+ pAccess->maPropertyConceptSeq.realloc( rPropCount );
+ pAccess->maMapTypeSeq.realloc( rPropCount );
+
+ // Ende der Schleife ueber alle vom ClassProvider angegebenen Klassen
+ }
+ }
+ // Bei structs Fields als Properties registrieren
+ else //if( eType == TypeClass_STRUCT )
+ {
+ // Ist es ein Interface oder eine struct?
+ //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass();
+ Reference<XIdlClass> xClassRef = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
+ if( !xClassRef.is() )
+ {
+ OSL_ENSURE( sal_False, "Can't get XIdlClass from Reflection" );
+ return pAccess;
+ }
+
+ // Felder holen
+ Sequence< Reference<XIdlField> > fields = xClassRef->getFields();
+ const Reference<XIdlField>* pFields = fields.getConstArray();
+ sal_Int32 nLen = fields.getLength();
+
+ for( i = 0 ; i < nLen ; i++ )
+ {
+ Reference<XIdlField> xField = pFields[i];
+ Reference<XIdlClass> xPropType = xField->getType();
+ OUString aPropName = xField->getName();
+
+ // Ist die PropertySequence gross genug?
+ pAccess->checkPropertyArraysSize
+ ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
+
+ // In eigenes Property-Array eintragen
+ Property& rProp = pAllPropArray[ rPropCount ];
+ rProp.Name = aPropName;
+ rProp.Handle = rPropCount;
+ rProp.Type = Type( xPropType->getTypeClass(), xPropType->getName() );
+ FieldAccessMode eAccessMode = xField->getAccessMode();
+ rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
+ eAccessMode == FieldAccessMode_CONST)
+ ? READONLY : 0;
+
+ //FieldAccessMode eAccessMode = xField->getAccessMode();
+ //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST)
+ //? PropertyAttribute::READONLY : 0;
+
+ // Namen in Hashtable eintragen
+ rPropNameMap[ aPropName ] = rPropCount;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
+
+ // Field merken
+ pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
+ pInterfaces1, rPropCount );
+ pInterfaces1[ rPropCount ] = xField;
+
+ // Art der Property merken
+ pMapTypeArray[ rPropCount ] = MAP_FIELD;
+ pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
+ pAccess->mnAttributePropCount++;
+
+ // Count pflegen
+ rPropCount++;
+ }
+ }
+
+ // Property-Sequence auf die richtige Laenge bringen
+ pAccess->maAllPropertySeq.realloc( pAccess->mnPropCount );
+
+ return pAccess;
+}
+
+//*************************************************************************
+Reference< XInterface > SAL_CALL ImplIntrospection_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr )
+ throw( RuntimeException )
+{
+ Reference< XInterface > xService = (OWeakObject*)(OComponentHelper*)new ImplIntrospection( rSMgr );
+ return xService;
+}
+
+}
+
+extern "C"
+{
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * )
+{
+ void * pRet = 0;
+
+ if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
+ {
+ Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
+ OUString::createFromAscii( pImplName ),
+ stoc_inspect::ImplIntrospection_CreateInstance,
+ stoc_inspect::ImplIntrospection::getSupportedServiceNames_Static() ) );
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+
+ return pRet;
+}
+}
+
+