fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / stoc / source / inspect / introspection.cxx
blob4c36dc546037fae4d4eba838685fa257137b4581
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
22 #define INTROSPECTION_CACHE_MAX_SIZE 100
24 #include <osl/diagnose.h>
25 #include <osl/mutex.hxx>
26 #include <osl/thread.h>
27 #include <cppuhelper/queryinterface.hxx>
28 #include <cppuhelper/weak.hxx>
29 #include <cppuhelper/component.hxx>
30 #include <cppuhelper/factory.hxx>
31 #include <cppuhelper/implbase3.hxx>
32 #include <cppuhelper/typeprovider.hxx>
33 #include <salhelper/simplereferenceobject.hxx>
35 #include <com/sun/star/uno/DeploymentException.hpp>
36 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/lang/XServiceInfo.hpp>
39 #include <com/sun/star/lang/XEventListener.hpp>
40 #include <com/sun/star/reflection/XIdlReflection.hpp>
41 #include <com/sun/star/reflection/XIdlClass.hpp>
42 #include <com/sun/star/reflection/XIdlField2.hpp>
43 #include <com/sun/star/beans/UnknownPropertyException.hpp>
44 #include <com/sun/star/beans/Property.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/beans/XFastPropertySet.hpp>
47 #include <com/sun/star/beans/XIntrospection.hpp>
48 #include <com/sun/star/beans/XIntrospectionAccess.hpp>
49 #include <com/sun/star/beans/XMaterialHolder.hpp>
50 #include <com/sun/star/beans/XExactName.hpp>
51 #include <com/sun/star/beans/PropertyAttribute.hpp>
52 #include <com/sun/star/beans/PropertyConcept.hpp>
53 #include <com/sun/star/beans/MethodConcept.hpp>
54 #include <com/sun/star/container/XNameContainer.hpp>
55 #include <com/sun/star/container/XIndexContainer.hpp>
56 #include <com/sun/star/container/XEnumerationAccess.hpp>
58 #include <rtl/ref.hxx>
59 #include <rtl/ustrbuf.hxx>
60 #include <rtl/strbuf.hxx>
61 #include <boost/unordered_map.hpp>
63 using namespace com::sun::star::uno;
64 using namespace com::sun::star::lang;
65 using namespace com::sun::star::reflection;
66 using namespace com::sun::star::container;
67 using namespace com::sun::star::registry;
68 using namespace com::sun::star::beans;
69 using namespace com::sun::star::beans::PropertyAttribute;
70 using namespace com::sun::star::beans::PropertyConcept;
71 using namespace com::sun::star::beans::MethodConcept;
72 using namespace cppu;
73 using namespace osl;
75 #define IMPLEMENTATION_NAME "com.sun.star.comp.stoc.Introspection"
76 #define SERVICE_NAME "com.sun.star.beans.Introspection"
78 namespace stoc_inspect
81 typedef WeakImplHelper3< XIntrospectionAccess, XMaterialHolder, XExactName > IntrospectionAccessHelper;
84 //==================================================================================================
86 // Special value for Method-Concept, to be able to mark "normal" functions
87 #define MethodConcept_NORMAL_IMPL 0x80000000
90 // Method to assert, if a class is derived from another class
91 sal_Bool isDerivedFrom( Reference<XIdlClass> xToTestClass, Reference<XIdlClass> xDerivedFromClass )
93 Sequence< Reference<XIdlClass> > aClassesSeq = xToTestClass->getSuperclasses();
94 const Reference<XIdlClass>* pClassesArray = aClassesSeq.getConstArray();
96 sal_Int32 nSuperClassCount = aClassesSeq.getLength();
97 for ( sal_Int32 i = 0; i < nSuperClassCount; ++i )
99 const Reference<XIdlClass>& rxClass = pClassesArray[i];
101 if ( xDerivedFromClass->equals( rxClass ) ||
102 isDerivedFrom( rxClass, xDerivedFromClass )
104 return sal_True;
107 return sal_False;
110 //========================================================================
112 // *** Classification of Properties (no enum, to be able to use Sequence) ***
113 // Properties from a PropertySet-Interface
114 #define MAP_PROPERTY_SET 0
115 // Properties from Fields
116 #define MAP_FIELD 1
117 // Properties, that get described with get/set-Methods
118 #define MAP_GETSET 2
119 // Properties, with only a set-Method
120 #define MAP_SETONLY 3
123 // Increments, in which the size of Sequences get adjusted
124 #define ARRAY_SIZE_STEP 20
128 //**************************************
129 //*** IntrospectionAccessStatic_Impl ***
130 //**************************************
131 // Equals to the old IntrospectionAccessImpl, forms now a static
132 // part of the new Instance-related ImplIntrospectionAccess
134 // Hashtable for the search of names
135 struct hashName_Impl
137 size_t operator()(const OUString Str) const
139 return (size_t)Str.hashCode();
143 struct eqName_Impl
145 sal_Bool operator()(const OUString Str1, const OUString Str2) const
147 return ( Str1 == Str2 );
151 typedef boost::unordered_map
153 OUString,
154 sal_Int32,
155 hashName_Impl,
156 eqName_Impl
158 IntrospectionNameMap;
161 // Hashtable to assign exact names to the Lower-Case
162 // converted names, for the support of XExactName
163 typedef boost::unordered_map
165 OUString,
166 OUString,
167 hashName_Impl,
168 eqName_Impl
170 LowerToExactNameMap;
173 class ImplIntrospectionAccess;
174 class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject
176 friend class ImplIntrospection;
177 friend class ImplIntrospectionAccess;
179 // Holding CoreReflection
180 Reference< XIdlReflection > mxCoreReflection;
182 // InterfaceSequences, to save additional information in a property
183 // for example the Field at MAP_FIELD, the get/set-Methods at MAP_GETSET, et cetera
184 Sequence< Reference<XInterface> > aInterfaceSeq1;
185 Sequence< Reference<XInterface> > aInterfaceSeq2;
187 // Hashtables for names
188 IntrospectionNameMap maPropertyNameMap;
189 IntrospectionNameMap maMethodNameMap;
190 LowerToExactNameMap maLowerToExactNameMap;
192 // Sequence of all Properties, also for delivering from getProperties()
193 Sequence<Property> maAllPropertySeq;
195 // Mapping of properties to Access-Types
196 Sequence<sal_Int16> maMapTypeSeq;
198 // Classification of found methods
199 Sequence<sal_Int32> maPropertyConceptSeq;
201 // Number of Properties
202 sal_Int32 mnPropCount;
204 // Number of Properties, which are assigned to particular concepts
205 //sal_Int32 mnDangerousPropCount;
206 sal_Int32 mnPropertySetPropCount;
207 sal_Int32 mnAttributePropCount;
208 sal_Int32 mnMethodPropCount;
210 // Flag, if a FastPropertySet is supported
211 sal_Bool mbFastPropSet;
213 // Original-Handles of FastPropertySets
214 sal_Int32* mpOrgPropertyHandleArray;
216 // MethodSequence, that accepts all methods
217 Sequence< Reference<XIdlMethod> > maAllMethodSeq;
219 // Classification of found methods
220 Sequence<sal_Int32> maMethodConceptSeq;
222 // Number of methods
223 sal_Int32 mnMethCount;
225 // Sequence of Listener, that can be registered
226 Sequence< Type > maSupportedListenerSeq;
228 // BaseInit (should be done later in the application!)
229 void BaseInit( void );
231 // Helper-methods for adjusting sizes of Sequences
232 void checkPropertyArraysSize
234 Property*& rpAllPropArray,
235 sal_Int16*& rpMapTypeArray,
236 sal_Int32*& rpPropertyConceptArray,
237 sal_Int32 iNextIndex
239 void checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, Reference<XInterface>*& rpInterfaceArray,
240 sal_Int32 iNextIndex );
242 public:
243 IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ );
244 ~IntrospectionAccessStatic_Impl()
246 delete[] mpOrgPropertyHandleArray;
248 sal_Int32 getPropertyIndex( const OUString& aPropertyName ) const;
249 sal_Int32 getMethodIndex( const OUString& aMethodName ) const;
251 // Methods of XIntrospectionAccess (OLD, now only Impl)
252 void setPropertyValue(const Any& obj, const OUString& aPropertyName, const Any& aValue) const;
253 // void setPropertyValue(Any& obj, const OUString& aPropertyName, const Any& aValue) const;
254 Any getPropertyValue(const Any& obj, const OUString& aPropertyName) const;
255 void setPropertyValueByIndex(const Any& obj, sal_Int32 nIndex, const Any& aValue) const;
256 // void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const;
257 Any getPropertyValueByIndex(const Any& obj, sal_Int32 nIndex) const;
259 Sequence<Property> getProperties(void) const { return maAllPropertySeq; }
260 Sequence< Reference<XIdlMethod> > getMethods(void) const { return maAllMethodSeq; }
261 Sequence< Type > getSupportedListeners(void) const { return maSupportedListenerSeq; }
262 Sequence<sal_Int32> getPropertyConcepts(void) const { return maPropertyConceptSeq; }
263 Sequence<sal_Int32> getMethodConcepts(void) const { return maMethodConceptSeq; }
267 // Ctor
268 IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ )
269 : mxCoreReflection( xCoreReflection_ )
271 aInterfaceSeq1.realloc( ARRAY_SIZE_STEP );
272 aInterfaceSeq2.realloc( ARRAY_SIZE_STEP );
274 // Property-Data
275 maAllPropertySeq.realloc( ARRAY_SIZE_STEP );
276 maMapTypeSeq.realloc( ARRAY_SIZE_STEP );
277 maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
279 mbFastPropSet = sal_False;
280 mpOrgPropertyHandleArray = NULL;
282 mnPropCount = 0;
283 //mnDangerousPropCount = 0;
284 mnPropertySetPropCount = 0;
285 mnAttributePropCount = 0;
286 mnMethodPropCount = 0;
288 // Method-Data
289 mnMethCount = 0;
292 sal_Int32 IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString& aPropertyName ) const
294 sal_Int32 iHashResult = -1;
295 IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
296 IntrospectionNameMap::iterator aIt = pThis->maPropertyNameMap.find( aPropertyName );
297 if( !( aIt == pThis->maPropertyNameMap.end() ) )
298 iHashResult = (*aIt).second;
299 return iHashResult;
302 sal_Int32 IntrospectionAccessStatic_Impl::getMethodIndex( const OUString& aMethodName ) const
304 sal_Int32 iHashResult = -1;
305 IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
306 IntrospectionNameMap::iterator aIt = pThis->maMethodNameMap.find( aMethodName );
307 if( !( aIt == pThis->maMethodNameMap.end() ) )
309 iHashResult = (*aIt).second;
311 // #95159 Check if full qualified name matches
312 else
314 sal_Int32 nSearchFrom = aMethodName.getLength();
315 while( true )
317 // Strategy: Search back until the first '_' is found
318 sal_Int32 nFound = aMethodName.lastIndexOf( '_', nSearchFrom );
319 if( nFound == -1 )
320 break;
322 OUString aPureMethodName = aMethodName.copy( nFound + 1 );
324 aIt = pThis->maMethodNameMap.find( aPureMethodName );
325 if( !( aIt == pThis->maMethodNameMap.end() ) )
327 // Check if it can be a type?
328 // Problem: Does not work if package names contain _ ?!
329 OUString aStr = aMethodName.copy( 0, nFound );
330 OUString aTypeName = aStr.replace( '_', '.' );
331 Reference< XIdlClass > xClass = mxCoreReflection->forName( aTypeName );
332 if( xClass.is() )
334 // If this is a valid class it could be the right method
336 // Could be the right method, type has to be checked
337 iHashResult = (*aIt).second;
339 const Reference<XIdlMethod>* pMethods = maAllMethodSeq.getConstArray();
340 const Reference<XIdlMethod> xMethod = pMethods[ iHashResult ];
342 Reference< XIdlClass > xMethClass = xMethod->getDeclaringClass();
343 if( xClass->equals( xMethClass ) )
345 break;
347 else
349 iHashResult = -1;
351 // Could also be another method with the same name
352 // Iterate over all methods
353 sal_Int32 nLen = maAllMethodSeq.getLength();
354 for( int i = 0 ; i < nLen ; ++i )
356 const Reference<XIdlMethod> xMethod2 = pMethods[ i ];
357 if( xMethod2->getName() == aPureMethodName )
359 Reference< XIdlClass > xMethClass2 = xMethod2->getDeclaringClass();
361 if( xClass->equals( xMethClass2 ) )
363 iHashResult = i;
364 break;
369 if( iHashResult != -1 )
370 break;
375 nSearchFrom = nFound - 1;
376 if( nSearchFrom < 0 )
377 break;
380 return iHashResult;
383 void IntrospectionAccessStatic_Impl::setPropertyValue( const Any& obj, const OUString& aPropertyName, const Any& aValue ) const
384 //void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const OUString& aPropertyName, const Any& aValue ) const
386 sal_Int32 i = getPropertyIndex( aPropertyName );
387 if( i != -1 )
388 setPropertyValueByIndex( obj, (sal_Int32)i, aValue );
389 else
390 throw UnknownPropertyException();
393 void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
394 //void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
396 // Is the passed object something that fits?
397 TypeClass eObjType = obj.getValueType().getTypeClass();
399 Reference<XInterface> xInterface;
400 if( eObjType == TypeClass_INTERFACE )
402 xInterface = *( Reference<XInterface>*)obj.getValue();
404 else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
406 throw IllegalArgumentException();
409 // Test flags
410 const Property* pProps = maAllPropertySeq.getConstArray();
411 if( (pProps[ nSequenceIndex ].Attributes & READONLY) != 0 )
413 throw UnknownPropertyException();
416 const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
417 switch( pMapTypeArray[ nSequenceIndex ] )
419 case MAP_PROPERTY_SET:
421 // Get Property
422 const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
424 // Convert Interface-Parameter to the correct type
425 sal_Bool bUseCopy = sal_False;
426 Any aRealValue;
428 TypeClass eValType = aValue.getValueType().getTypeClass();
429 if( eValType == TypeClass_INTERFACE )
431 Type aPropType = rProp.Type;
432 OUString aTypeName( aPropType.getTypeName() );
433 Reference< XIdlClass > xPropClass = mxCoreReflection->forName( aTypeName );
434 //Reference<XIdlClass> xPropClass = rProp.Type;
435 if( xPropClass.is() && xPropClass->getTypeClass() == TypeClass_INTERFACE )
437 Reference<XInterface> valInterface = *(Reference<XInterface>*)aValue.getValue();
438 if( valInterface.is() )
440 //Any queryInterface( const Type& rType );
441 aRealValue = valInterface->queryInterface( aPropType );
442 if( aRealValue.hasValue() )
443 bUseCopy = sal_True;
448 // Do we have a FastPropertySet and a valid Handle?
449 // CAUTION: At this point we exploit, that the PropertySet
450 // gets queried at the beginning of the Introspection-Process.
451 sal_Int32 nOrgHandle;
452 if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
454 // Retrieve PropertySet-Interface
455 Reference<XFastPropertySet> xFastPropSet =
456 Reference<XFastPropertySet>::query( xInterface );
457 if( xFastPropSet.is() )
459 xFastPropSet->setFastPropertyValue( nOrgHandle, bUseCopy ? aRealValue : aValue );
461 else
463 // throw UnknownPropertyException
466 // else take the normal one
467 else
469 // Retrieve PropertySet-Interface
470 Reference<XPropertySet> xPropSet =
471 Reference<XPropertySet>::query( xInterface );
472 if( xPropSet.is() )
474 xPropSet->setPropertyValue( rProp.Name, bUseCopy ? aRealValue : aValue );
476 else
478 // throw UnknownPropertyException
482 break;
484 case MAP_FIELD:
486 Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
487 Reference<XIdlField2> xField2(xField, UNO_QUERY);
488 if( xField2.is() )
490 xField2->set( (Any&)obj, aValue );
491 // IllegalArgumentException
492 // NullPointerException
493 } else
494 if( xField.is() )
496 xField->set( obj, aValue );
497 // IllegalArgumentException
498 // NullPointerException
500 else
502 // throw IllegalArgumentException();
505 break;
507 case MAP_GETSET:
508 case MAP_SETONLY:
510 // Retrieve set-Methods
511 Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq2.getConstArray()[ nSequenceIndex ].get());
512 if( xMethod.is() )
514 Sequence<Any> args( 1 );
515 args.getArray()[0] = aValue;
516 xMethod->invoke( obj, args );
518 else
520 // throw IllegalArgumentException();
523 break;
527 Any IntrospectionAccessStatic_Impl::getPropertyValue( const Any& obj, const OUString& aPropertyName ) const
529 sal_Int32 i = getPropertyIndex( aPropertyName );
530 if( i != -1 )
531 return getPropertyValueByIndex( obj, i );
533 throw UnknownPropertyException();
536 Any IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex) const
538 Any aRet;
540 // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
541 TypeClass eObjType = obj.getValueType().getTypeClass();
543 Reference<XInterface> xInterface;
544 if( eObjType == TypeClass_INTERFACE )
546 xInterface = *(Reference<XInterface>*)obj.getValue();
548 else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
550 // throw IllegalArgumentException();
551 return aRet;
554 const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
555 switch( pMapTypeArray[ nSequenceIndex ] )
557 case MAP_PROPERTY_SET:
559 // Property besorgen
560 const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
562 // Haben wir ein FastPropertySet und ein gueltiges Handle?
563 // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
564 // zu Beginn des Introspection-Vorgangs abgefragt wird.
565 sal_Int32 nOrgHandle;
566 if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
568 // PropertySet-Interface holen
569 Reference<XFastPropertySet> xFastPropSet =
570 Reference<XFastPropertySet>::query( xInterface );
571 if( xFastPropSet.is() )
573 aRet = xFastPropSet->getFastPropertyValue( nOrgHandle);
575 else
577 // throw UnknownPropertyException
578 return aRet;
581 // sonst eben das normale nehmen
582 else
584 // PropertySet-Interface holen
585 Reference<XPropertySet> xPropSet =
586 Reference<XPropertySet>::query( xInterface );
587 if( xPropSet.is() )
589 aRet = xPropSet->getPropertyValue( rProp.Name );
591 else
593 // throw UnknownPropertyException
594 return aRet;
598 break;
600 case MAP_FIELD:
602 Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
603 if( xField.is() )
605 aRet = xField->get( obj );
606 // IllegalArgumentException
607 // NullPointerException
609 else
611 // throw IllegalArgumentException();
612 return aRet;
615 break;
617 case MAP_GETSET:
619 // get-Methode holen
620 Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
621 if( xMethod.is() )
623 Sequence<Any> args;
624 aRet = xMethod->invoke( obj, args );
626 else
628 // throw IllegalArgumentException();
629 return aRet;
632 break;
634 case MAP_SETONLY:
635 // get-Methode gibt es nicht
636 // throw WriteOnlyPropertyException();
637 return aRet;
639 return aRet;
643 // Hilfs-Methoden zur Groessen-Anpassung der Sequences
644 void IntrospectionAccessStatic_Impl::checkPropertyArraysSize
646 Property*& rpAllPropArray,
647 sal_Int16*& rpMapTypeArray,
648 sal_Int32*& rpPropertyConceptArray,
649 sal_Int32 iNextIndex
652 sal_Int32 nLen = maAllPropertySeq.getLength();
653 if( iNextIndex >= nLen )
655 maAllPropertySeq.realloc( nLen + ARRAY_SIZE_STEP );
656 rpAllPropArray = maAllPropertySeq.getArray();
658 maMapTypeSeq.realloc( nLen + ARRAY_SIZE_STEP );
659 rpMapTypeArray = maMapTypeSeq.getArray();
661 maPropertyConceptSeq.realloc( nLen + ARRAY_SIZE_STEP );
662 rpPropertyConceptArray = maPropertyConceptSeq.getArray();
666 void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq,
667 Reference<XInterface>*& rpInterfaceArray, sal_Int32 iNextIndex )
669 sal_Int32 nLen = rSeq.getLength();
670 if( iNextIndex >= nLen )
672 // Neue Groesse mit ARRAY_SIZE_STEP abgleichen
673 sal_Int32 nMissingSize = iNextIndex - nLen + 1;
674 sal_Int32 nSteps = nMissingSize / ARRAY_SIZE_STEP + 1;
675 sal_Int32 nNewSize = nLen + nSteps * ARRAY_SIZE_STEP;
677 rSeq.realloc( nNewSize );
678 rpInterfaceArray = rSeq.getArray();
683 //*******************************
684 //*** ImplIntrospectionAccess ***
685 //*******************************
687 // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
688 // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
689 // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
690 class ImplIntrospectionAccess : public IntrospectionAccessHelper
692 friend class ImplIntrospection;
694 // Untersuchtes Objekt
695 Any maInspectedObject;
697 // Als Interface
698 Reference<XInterface> mxIface;
700 // Statische Daten der Introspection
701 rtl::Reference< IntrospectionAccessStatic_Impl > mpStaticImpl;
703 // Adapter-Implementation
704 WeakReference< XInterface > maAdapter;
706 // Letzte Sequence, die bei getProperties geliefert wurde (Optimierung)
707 Sequence<Property> maLastPropertySeq;
708 sal_Int32 mnLastPropertyConcept;
710 // Letzte Sequence, die bei getMethods geliefert wurde (Optimierung)
711 Sequence<Reference<XIdlMethod> > maLastMethodSeq;
712 sal_Int32 mnLastMethodConcept;
714 public:
715 ImplIntrospectionAccess( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ );
716 ~ImplIntrospectionAccess();
718 // Methoden von XIntrospectionAccess
719 virtual sal_Int32 SAL_CALL getSuppliedMethodConcepts(void)
720 throw( RuntimeException );
721 virtual sal_Int32 SAL_CALL getSuppliedPropertyConcepts(void)
722 throw( RuntimeException );
723 virtual Property SAL_CALL getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
724 throw( NoSuchElementException, RuntimeException );
725 virtual sal_Bool SAL_CALL hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
726 throw( RuntimeException );
727 virtual Sequence< Property > SAL_CALL getProperties(sal_Int32 PropertyConcepts)
728 throw( RuntimeException );
729 virtual Reference<XIdlMethod> SAL_CALL getMethod(const OUString& Name, sal_Int32 MethodConcepts)
730 throw( NoSuchMethodException, RuntimeException );
731 virtual sal_Bool SAL_CALL hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
732 throw( RuntimeException );
733 virtual Sequence< Reference<XIdlMethod> > SAL_CALL getMethods(sal_Int32 MethodConcepts)
734 throw( RuntimeException );
735 virtual Sequence< Type > SAL_CALL getSupportedListeners(void)
736 throw( RuntimeException );
737 using OWeakObject::queryAdapter;
738 virtual Reference<XInterface> SAL_CALL queryAdapter( const Type& rType )
739 throw( IllegalTypeException, RuntimeException );
741 // Methoden von XMaterialHolder
742 virtual Any SAL_CALL getMaterial(void) throw(RuntimeException);
744 // Methoden von XExactName
745 virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException );
748 ImplIntrospectionAccess::ImplIntrospectionAccess
749 ( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
750 : maInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ), maAdapter()
752 // Objekt als Interface merken, wenn moeglich
753 TypeClass eType = maInspectedObject.getValueType().getTypeClass();
754 if( eType == TypeClass_INTERFACE )
755 mxIface = *(Reference<XInterface>*)maInspectedObject.getValue();
757 mnLastPropertyConcept = -1;
758 mnLastMethodConcept = -1;
761 ImplIntrospectionAccess::~ImplIntrospectionAccess()
766 //*******************************
767 //*** ImplIntrospectionAdapter ***
768 //*******************************
770 // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
771 // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
772 // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
773 class ImplIntrospectionAdapter :
774 public XPropertySet, public XFastPropertySet, public XPropertySetInfo,
775 public XNameContainer, public XIndexContainer,
776 public XEnumerationAccess, public XIdlArray,
777 public OWeakObject
779 // Parent-Objekt
780 ::rtl::Reference< ImplIntrospectionAccess > mpAccess;
782 // Untersuchtes Objekt
783 const Any& mrInspectedObject;
785 // Statische Daten der Introspection
786 rtl::Reference< IntrospectionAccessStatic_Impl > mpStaticImpl;
788 // Objekt als Interface
789 Reference<XInterface> mxIface;
791 // Original-Interfaces des Objekts
792 Reference<XElementAccess> mxObjElementAccess;
793 Reference<XNameContainer> mxObjNameContainer;
794 Reference<XNameAccess> mxObjNameAccess;
795 Reference<XIndexAccess> mxObjIndexAccess;
796 Reference<XIndexContainer> mxObjIndexContainer;
797 Reference<XEnumerationAccess> mxObjEnumerationAccess;
798 Reference<XIdlArray> mxObjIdlArray;
800 public:
801 ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
802 const Any& obj,
803 rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ );
805 // Methoden von XInterface
806 virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
807 virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
808 virtual void SAL_CALL release() throw() { OWeakObject::release(); }
810 // Methoden von XPropertySet
811 virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( RuntimeException );
812 virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, const Any& aValue)
813 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException );
814 virtual Any SAL_CALL getPropertyValue(const OUString& aPropertyName)
815 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
816 virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
817 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
818 virtual void SAL_CALL removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
819 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
820 virtual void SAL_CALL addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
821 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
822 virtual void SAL_CALL removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
823 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
825 // Methoden von XFastPropertySet
826 virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const Any& aValue)
827 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException );
828 virtual Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle)
829 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
831 // Methoden von XPropertySetInfo
832 virtual Sequence< Property > SAL_CALL getProperties(void) throw( RuntimeException );
833 virtual Property SAL_CALL getPropertyByName(const OUString& Name) throw( RuntimeException );
834 virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& Name) throw( RuntimeException );
836 // Methoden von XElementAccess
837 virtual Type SAL_CALL getElementType(void) throw( RuntimeException );
838 virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException );
840 // Methoden von XNameAccess
841 virtual Any SAL_CALL getByName(const OUString& Name)
842 throw( NoSuchElementException, WrappedTargetException, RuntimeException );
843 virtual Sequence< OUString > SAL_CALL getElementNames(void) throw( RuntimeException );
844 virtual sal_Bool SAL_CALL hasByName(const OUString& Name) throw( RuntimeException );
846 // Methoden von XNameContainer
847 virtual void SAL_CALL insertByName(const OUString& Name, const Any& Element)
848 throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException );
849 virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element)
850 throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException );
851 virtual void SAL_CALL removeByName(const OUString& Name)
852 throw( NoSuchElementException, WrappedTargetException, RuntimeException );
854 // Methoden von XIndexAccess
855 virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException );
856 virtual Any SAL_CALL getByIndex(sal_Int32 Index)
857 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
859 // Methoden von XIndexContainer
860 virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element)
861 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
862 virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element)
863 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
864 virtual void SAL_CALL removeByIndex(sal_Int32 Index)
865 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
867 // Methoden von XEnumerationAccess
868 virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException );
870 // Methoden von XIdlArray
871 virtual void SAL_CALL realloc(Any& array, sal_Int32 length)
872 throw( IllegalArgumentException, RuntimeException );
873 virtual sal_Int32 SAL_CALL getLen(const Any& array) throw( IllegalArgumentException, RuntimeException );
874 virtual Any SAL_CALL get(const Any& array, sal_Int32 index)
875 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException );
876 virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value)
877 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException );
880 ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
881 const Any& obj,
882 rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
883 : mpAccess( pAccess_), mrInspectedObject( obj ), mpStaticImpl( pStaticImpl_ )
885 // Objekt als Interfaceholen
886 TypeClass eType = mrInspectedObject.getValueType().getTypeClass();
887 if( eType == TypeClass_INTERFACE )
889 mxIface = *( Reference< XInterface >*)mrInspectedObject.getValue();
891 mxObjElementAccess = Reference<XElementAccess>::query( mxIface );
892 mxObjNameAccess = Reference<XNameAccess>::query( mxIface );
893 mxObjNameContainer = Reference<XNameContainer>::query( mxIface );
894 mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface );
895 mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface );
896 mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
897 mxObjIdlArray = Reference<XIdlArray>::query( mxIface );
901 // Methoden von XInterface
902 Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType )
903 throw( RuntimeException )
905 Any aRet( ::cppu::queryInterface(
906 rType,
907 static_cast< XPropertySet * >( this ),
908 static_cast< XFastPropertySet * >( this ),
909 static_cast< XPropertySetInfo * >( this ) ) );
910 if( !aRet.hasValue() )
911 aRet = OWeakObject::queryInterface( rType );
913 if( !aRet.hasValue() )
915 // Wrapper fuer die Objekt-Interfaces
916 if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface
917 ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() )
918 || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
919 || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
920 || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
921 || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
922 || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
923 || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
928 return aRet;
932 //***************************************************
933 //*** Implementation von ImplIntrospectionAdapter ***
934 //***************************************************
936 // Methoden von XPropertySet
937 Reference<XPropertySetInfo> ImplIntrospectionAdapter::getPropertySetInfo(void)
938 throw( RuntimeException )
940 return (XPropertySetInfo *)this;
943 void ImplIntrospectionAdapter::setPropertyValue(const OUString& aPropertyName, const Any& aValue)
944 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
946 mpStaticImpl->setPropertyValue( mrInspectedObject, aPropertyName, aValue );
949 Any ImplIntrospectionAdapter::getPropertyValue(const OUString& aPropertyName)
950 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
952 return mpStaticImpl->getPropertyValue( mrInspectedObject, aPropertyName );
955 void ImplIntrospectionAdapter::addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
956 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
958 if( mxIface.is() )
960 Reference<XPropertySet> xPropSet =
961 Reference<XPropertySet>::query( mxIface );
962 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
963 if( xPropSet.is() )
964 xPropSet->addPropertyChangeListener(aPropertyName, aListener);
968 void ImplIntrospectionAdapter::removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
969 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
971 if( mxIface.is() )
973 Reference<XPropertySet> xPropSet =
974 Reference<XPropertySet>::query( mxIface );
975 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
976 if( xPropSet.is() )
977 xPropSet->removePropertyChangeListener(aPropertyName, aListener);
981 void ImplIntrospectionAdapter::addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
982 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
984 if( mxIface.is() )
986 Reference<XPropertySet> xPropSet =
987 Reference<XPropertySet>::query( mxIface );
988 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
989 if( xPropSet.is() )
990 xPropSet->addVetoableChangeListener(aPropertyName, aListener);
994 void ImplIntrospectionAdapter::removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
995 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
997 if( mxIface.is() )
999 Reference<XPropertySet> xPropSet =
1000 Reference<XPropertySet>::query( mxIface );
1001 if( xPropSet.is() )
1002 xPropSet->removeVetoableChangeListener(aPropertyName, aListener);
1007 // Methoden von XFastPropertySet
1008 void ImplIntrospectionAdapter::setFastPropertyValue(sal_Int32, const Any&)
1009 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
1013 Any ImplIntrospectionAdapter::getFastPropertyValue(sal_Int32)
1014 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
1016 return Any();
1019 // Methoden von XPropertySetInfo
1020 Sequence< Property > ImplIntrospectionAdapter::getProperties(void) throw( RuntimeException )
1022 return mpStaticImpl->getProperties();
1025 Property ImplIntrospectionAdapter::getPropertyByName(const OUString& Name)
1026 throw( RuntimeException )
1028 return mpAccess->getProperty( Name, PropertyConcept::ALL );
1031 sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name)
1032 throw( RuntimeException )
1034 return mpAccess->hasProperty( Name, PropertyConcept::ALL );
1037 // Methoden von XElementAccess
1038 Type ImplIntrospectionAdapter::getElementType(void) throw( RuntimeException )
1040 return mxObjElementAccess->getElementType();
1043 sal_Bool ImplIntrospectionAdapter::hasElements(void) throw( RuntimeException )
1045 return mxObjElementAccess->hasElements();
1048 // Methoden von XNameAccess
1049 Any ImplIntrospectionAdapter::getByName(const OUString& Name)
1050 throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1052 return mxObjNameAccess->getByName( Name );
1055 Sequence< OUString > ImplIntrospectionAdapter::getElementNames(void)
1056 throw( RuntimeException )
1058 return mxObjNameAccess->getElementNames();
1061 sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name)
1062 throw( RuntimeException )
1064 return mxObjNameAccess->hasByName( Name );
1067 // Methoden von XNameContainer
1068 void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element)
1069 throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
1071 mxObjNameContainer->insertByName( Name, Element );
1074 void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element)
1075 throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
1077 mxObjNameContainer->replaceByName( Name, Element );
1080 void ImplIntrospectionAdapter::removeByName(const OUString& Name)
1081 throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1083 mxObjNameContainer->removeByName( Name );
1086 // Methoden von XIndexAccess
1087 // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const
1088 sal_Int32 ImplIntrospectionAdapter::getCount(void) throw( RuntimeException )
1090 return mxObjIndexAccess->getCount();
1093 Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index)
1094 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1096 return mxObjIndexAccess->getByIndex( Index );
1099 // Methoden von XIndexContainer
1100 void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element)
1101 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1103 mxObjIndexContainer->insertByIndex( Index, Element );
1106 void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element)
1107 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1109 mxObjIndexContainer->replaceByIndex( Index, Element );
1112 void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index)
1113 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1115 mxObjIndexContainer->removeByIndex( Index );
1118 // Methoden von XEnumerationAccess
1119 // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const;
1120 Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration(void) throw( RuntimeException )
1122 return mxObjEnumerationAccess->createEnumeration();
1125 // Methoden von XIdlArray
1126 void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length)
1127 throw( IllegalArgumentException, RuntimeException )
1129 mxObjIdlArray->realloc( array, length );
1132 sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array)
1133 throw( IllegalArgumentException, RuntimeException )
1135 return mxObjIdlArray->getLen( array );
1138 Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index)
1139 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException )
1141 return mxObjIdlArray->get( array, index );
1144 void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value)
1145 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException )
1147 mxObjIdlArray->set( array, index, value );
1151 //**************************************************
1152 //*** Implementation von ImplIntrospectionAccess ***
1153 //**************************************************
1155 // Methoden von XIntrospectionAccess
1156 sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts(void)
1157 throw( RuntimeException )
1159 return MethodConcept::DANGEROUS |
1160 PROPERTY |
1161 LISTENER |
1162 ENUMERATION |
1163 NAMECONTAINER |
1164 INDEXCONTAINER;
1167 sal_Int32 ImplIntrospectionAccess::getSuppliedPropertyConcepts(void)
1168 throw( RuntimeException )
1170 return PropertyConcept::DANGEROUS |
1171 PROPERTYSET |
1172 ATTRIBUTES |
1173 METHODS;
1176 Property ImplIntrospectionAccess::getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
1177 throw( NoSuchElementException, RuntimeException )
1179 Property aRet;
1180 sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
1181 sal_Bool bFound = sal_False;
1182 if( i != -1 )
1184 sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
1185 if( (PropertyConcepts & nConcept) != 0 )
1187 const Property* pProps = mpStaticImpl->getProperties().getConstArray();
1188 aRet = pProps[ i ];
1189 bFound = sal_True;
1192 if( !bFound )
1193 throw NoSuchElementException() ;
1194 return aRet;
1197 sal_Bool ImplIntrospectionAccess::hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
1198 throw( RuntimeException )
1200 sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
1201 sal_Bool bRet = sal_False;
1202 if( i != -1 )
1204 sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
1205 if( (PropertyConcepts & nConcept) != 0 )
1206 bRet = sal_True;
1208 return bRet;
1211 Sequence< Property > ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts)
1212 throw( RuntimeException )
1214 // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
1215 sal_Int32 nAllSupportedMask = PROPERTYSET |
1216 ATTRIBUTES |
1217 METHODS;
1218 if( ( PropertyConcepts & nAllSupportedMask ) == nAllSupportedMask )
1220 return mpStaticImpl->getProperties();
1223 // Gleiche Sequence wie beim vorigen mal?
1224 if( mnLastPropertyConcept == PropertyConcepts )
1226 return maLastPropertySeq;
1229 // Anzahl der zu liefernden Properties
1230 sal_Int32 nCount = 0;
1232 // Es gibt zur Zeit keine DANGEROUS-Properties
1233 // if( PropertyConcepts & DANGEROUS )
1234 // nCount += mpStaticImpl->mnDangerousPropCount;
1235 if( PropertyConcepts & PROPERTYSET )
1236 nCount += mpStaticImpl->mnPropertySetPropCount;
1237 if( PropertyConcepts & ATTRIBUTES )
1238 nCount += mpStaticImpl->mnAttributePropCount;
1239 if( PropertyConcepts & METHODS )
1240 nCount += mpStaticImpl->mnMethodPropCount;
1242 // Sequence entsprechend der geforderten Anzahl reallocieren
1243 ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
1244 pThis->maLastPropertySeq.realloc( nCount );
1245 Property* pDestProps = pThis->maLastPropertySeq.getArray();
1247 // Alle Properties durchgehen und entsprechend der Concepte uebernehmen
1248 Sequence<Property> aPropSeq = mpStaticImpl->getProperties();
1249 const Property* pSourceProps = aPropSeq.getConstArray();
1250 const sal_Int32* pConcepts = mpStaticImpl->getPropertyConcepts().getConstArray();
1251 sal_Int32 nLen = aPropSeq.getLength();
1253 sal_Int32 iDest = 0;
1254 for( sal_Int32 i = 0 ; i < nLen ; i++ )
1256 sal_Int32 nConcept = pConcepts[ i ];
1257 if( nConcept & PropertyConcepts )
1258 pDestProps[ iDest++ ] = pSourceProps[ i ];
1261 // PropertyConcept merken, dies entspricht maLastPropertySeq
1262 pThis->mnLastPropertyConcept = PropertyConcepts;
1264 // Zusammengebastelte Sequence liefern
1265 return maLastPropertySeq;
1268 Reference<XIdlMethod> ImplIntrospectionAccess::getMethod(const OUString& Name, sal_Int32 MethodConcepts)
1269 throw( NoSuchMethodException, RuntimeException )
1271 Reference<XIdlMethod> xRet;
1272 sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
1273 if( i != -1 )
1276 sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
1277 if( (MethodConcepts & nConcept) != 0 )
1279 const Reference<XIdlMethod>* pMethods = mpStaticImpl->getMethods().getConstArray();
1280 xRet = pMethods[i];
1283 if( !xRet.is() )
1284 throw NoSuchMethodException();
1285 return xRet;
1288 sal_Bool ImplIntrospectionAccess::hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
1289 throw( RuntimeException )
1291 sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
1292 sal_Bool bRet = sal_False;
1293 if( i != -1 )
1295 sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
1296 if( (MethodConcepts & nConcept) != 0 )
1297 bRet = sal_True;
1299 return bRet;
1302 Sequence< Reference<XIdlMethod> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts)
1303 throw( RuntimeException )
1305 ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
1307 // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
1308 sal_Int32 nAllSupportedMask = MethodConcept::DANGEROUS |
1309 PROPERTY |
1310 LISTENER |
1311 ENUMERATION |
1312 NAMECONTAINER |
1313 INDEXCONTAINER |
1314 MethodConcept_NORMAL_IMPL;
1315 if( ( MethodConcepts & nAllSupportedMask ) == nAllSupportedMask )
1317 return mpStaticImpl->getMethods();
1320 // Gleiche Sequence wie beim vorigen mal?
1321 if( mnLastMethodConcept == MethodConcepts )
1323 return maLastMethodSeq;
1326 // Methoden-Sequences besorgen
1327 Sequence< Reference<XIdlMethod> > aMethodSeq = mpStaticImpl->getMethods();
1328 const Reference<XIdlMethod>* pSourceMethods = aMethodSeq.getConstArray();
1329 const sal_Int32* pConcepts = mpStaticImpl->getMethodConcepts().getConstArray();
1330 sal_Int32 nLen = aMethodSeq.getLength();
1332 // Sequence entsprechend der geforderten Anzahl reallocieren
1333 // Anders als bei den Properties kann die Anzahl nicht durch
1334 // Zaehler in inspect() vorher ermittelt werden, da Methoden
1335 // mehreren Konzepten angehoeren koennen
1336 pThis->maLastMethodSeq.realloc( nLen );
1337 Reference<XIdlMethod>* pDestMethods = pThis->maLastMethodSeq.getArray();
1339 // Alle Methods durchgehen und entsprechend der Concepte uebernehmen
1340 sal_Int32 iDest = 0;
1341 for( sal_Int32 i = 0 ; i < nLen ; i++ )
1343 sal_Int32 nConcept = pConcepts[ i ];
1344 if( nConcept & MethodConcepts )
1345 pDestMethods[ iDest++ ] = pSourceMethods[ i ];
1347 #if OSL_DEBUG_LEVEL > 0
1348 static bool debug = false;
1349 if ( debug )
1351 // Methode mit Concepts ausgeben
1352 const Reference< XIdlMethod >& rxMethod = pSourceMethods[ i ];
1353 OString aNameStr = OUStringToOString( rxMethod->getName(), osl_getThreadTextEncoding() );
1354 OString ConceptStr;
1355 if( nConcept & MethodConcept::DANGEROUS )
1356 ConceptStr += "DANGEROUS |";
1357 if( nConcept & MethodConcept::PROPERTY )
1358 ConceptStr += "PROPERTY |";
1359 if( nConcept & MethodConcept::LISTENER )
1360 ConceptStr += "LISTENER |";
1361 if( nConcept & MethodConcept::ENUMERATION )
1362 ConceptStr += "ENUMERATION |";
1363 if( nConcept & MethodConcept::NAMECONTAINER )
1364 ConceptStr += "NAMECONTAINER |";
1365 if( nConcept & MethodConcept::INDEXCONTAINER )
1366 ConceptStr += "INDEXCONTAINER |";
1367 OSL_TRACE( "Method %ld: %s, Concepts = %s", i, aNameStr.getStr(), ConceptStr.getStr() );
1369 #endif
1372 // Auf die richtige Laenge bringen
1373 pThis->maLastMethodSeq.realloc( iDest );
1375 // MethodConcept merken, dies entspricht maLastMethodSeq
1376 pThis->mnLastMethodConcept = MethodConcepts;
1378 // Zusammengebastelte Sequence liefern
1379 return maLastMethodSeq;
1382 Sequence< Type > ImplIntrospectionAccess::getSupportedListeners(void)
1383 throw( RuntimeException )
1385 return mpStaticImpl->getSupportedListeners();
1388 Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type& rType )
1389 throw( IllegalTypeException, RuntimeException )
1391 // Gibt es schon einen Adapter?
1392 Reference< XInterface > xAdapter( maAdapter );
1393 if( !xAdapter.is() )
1395 xAdapter = *( new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl ) );
1396 maAdapter = xAdapter;
1399 Reference<XInterface> xRet;
1400 xAdapter->queryInterface( rType ) >>= xRet;
1401 return xRet;
1404 // Methoden von XMaterialHolder
1405 Any ImplIntrospectionAccess::getMaterial(void) throw(RuntimeException)
1407 return maInspectedObject;
1410 // Hilfs-Funktion zur LowerCase-Wandlung eines OUString
1411 OUString toLower( OUString aUStr )
1413 // Tabelle fuer XExactName pflegen
1414 OUString aOWStr( aUStr.getStr() );
1415 OUString aOWLowerStr = aOWStr.toAsciiLowerCase();
1416 OUString aLowerUStr( aOWLowerStr.getStr() );
1417 return aLowerUStr;
1420 // Methoden von XExactName
1421 OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName ) throw( RuntimeException )
1423 OUString aRetStr;
1424 LowerToExactNameMap::iterator aIt =
1425 mpStaticImpl->maLowerToExactNameMap.find( toLower( rApproximateName ) );
1426 if( !( aIt == mpStaticImpl->maLowerToExactNameMap.end() ) )
1427 aRetStr = (*aIt).second;
1428 return aRetStr;
1432 //-----------------------------------------------------------------------------
1434 struct hashIntrospectionKey_Impl
1436 Sequence< Reference<XIdlClass> > aIdlClasses;
1437 Reference<XPropertySetInfo> xPropInfo;
1438 Reference<XIdlClass> xImplClass;
1439 sal_Int32 nHitCount;
1441 void IncHitCount() const { ((hashIntrospectionKey_Impl*)this)->nHitCount++; }
1442 hashIntrospectionKey_Impl() : nHitCount( 0 ) {}
1443 hashIntrospectionKey_Impl( const Sequence< Reference<XIdlClass> > & rIdlClasses,
1444 const Reference<XPropertySetInfo> & rxPropInfo,
1445 const Reference<XIdlClass> & rxImplClass );
1448 hashIntrospectionKey_Impl::hashIntrospectionKey_Impl
1450 const Sequence< Reference<XIdlClass> > & rIdlClasses,
1451 const Reference<XPropertySetInfo> & rxPropInfo,
1452 const Reference<XIdlClass> & rxImplClass
1454 : aIdlClasses( rIdlClasses )
1455 , xPropInfo( rxPropInfo )
1456 , xImplClass( rxImplClass )
1457 , nHitCount( 0 )
1461 struct hashIntrospectionAccessCache_Impl
1463 size_t operator()(const hashIntrospectionKey_Impl & rObj ) const
1465 return (size_t)rObj.xImplClass.get() ^ (size_t)rObj.xPropInfo.get();
1468 bool operator()( const hashIntrospectionKey_Impl & rObj1,
1469 const hashIntrospectionKey_Impl & rObj2 ) const
1471 if( rObj1.xPropInfo != rObj2.xPropInfo
1472 || rObj1.xImplClass != rObj2.xImplClass )
1473 return sal_False;
1475 sal_Int32 nCount1 = rObj1.aIdlClasses.getLength();
1476 sal_Int32 nCount2 = rObj2.aIdlClasses.getLength();
1477 if( nCount1 != nCount2 )
1478 return sal_False;
1480 const Reference<XIdlClass>* pRefs1 = rObj1.aIdlClasses.getConstArray();
1481 const Reference<XIdlClass>* pRefs2 = rObj2.aIdlClasses.getConstArray();
1482 return memcmp( pRefs1, pRefs2, nCount1 * sizeof( Reference<XIdlClass> ) ) == 0;
1487 typedef boost::unordered_map
1489 hashIntrospectionKey_Impl,
1490 rtl::Reference< IntrospectionAccessStatic_Impl >,
1491 hashIntrospectionAccessCache_Impl,
1492 hashIntrospectionAccessCache_Impl
1494 IntrospectionAccessCacheMap;
1496 // For XTypeProvider
1497 struct hashTypeProviderKey_Impl
1499 Reference<XPropertySetInfo> xPropInfo;
1500 Sequence< sal_Int8 > maImpIdSeq;
1501 sal_Int32 nHitCount;
1503 void IncHitCount() const { ((hashTypeProviderKey_Impl*)this)->nHitCount++; }
1504 hashTypeProviderKey_Impl() : nHitCount( 0 ) {}
1505 hashTypeProviderKey_Impl( const Reference<XPropertySetInfo> & rxPropInfo, const Sequence< sal_Int8 > & aImpIdSeq_ );
1508 hashTypeProviderKey_Impl::hashTypeProviderKey_Impl
1510 const Reference<XPropertySetInfo> & rxPropInfo,
1511 const Sequence< sal_Int8 > & aImpIdSeq_
1513 : xPropInfo( rxPropInfo )
1514 , maImpIdSeq( aImpIdSeq_ )
1515 , nHitCount( 0 )
1519 struct TypeProviderAccessCache_Impl
1521 size_t operator()(const hashTypeProviderKey_Impl & rObj ) const;
1523 bool operator()( const hashTypeProviderKey_Impl & rObj1,
1524 const hashTypeProviderKey_Impl & rObj2 ) const
1526 if( rObj1.xPropInfo != rObj2.xPropInfo )
1527 return sal_False;
1529 bool bEqual = false;
1530 sal_Int32 nLen1 = rObj1.maImpIdSeq.getLength();
1531 sal_Int32 nLen2 = rObj2.maImpIdSeq.getLength();
1532 if( nLen1 == nLen2 && nLen1 > 0 )
1534 const sal_Int8* pId1 = rObj1.maImpIdSeq.getConstArray();
1535 const sal_Int8* pId2 = rObj2.maImpIdSeq.getConstArray();
1536 bEqual = (memcmp( pId1, pId2, nLen1 * sizeof( sal_Int8 ) ) == 0 );
1538 return bEqual;
1542 size_t TypeProviderAccessCache_Impl::operator()(const hashTypeProviderKey_Impl & rObj ) const
1544 const sal_Int32* pBytesAsInt32Array = (const sal_Int32*)rObj.maImpIdSeq.getConstArray();
1545 sal_Int32 nLen = rObj.maImpIdSeq.getLength();
1546 sal_Int32 nCount32 = nLen / 4;
1547 sal_Int32 nMod32 = nLen % 4;
1549 // XOR with full 32 bit values
1550 sal_Int32 nId32 = 0;
1551 sal_Int32 i;
1552 for( i = 0 ; i < nCount32 ; i++ )
1553 nId32 ^= *(pBytesAsInt32Array++);
1555 // XOR with remaining byte values
1556 if( nMod32 )
1558 const sal_Int8* pBytes = (const sal_Int8*)pBytesAsInt32Array;
1559 sal_Int8* pInt8_Id32 = (sal_Int8*)&nId32;
1560 for( i = 0 ; i < nMod32 ; i++ )
1561 *(pInt8_Id32++) ^= *(pBytes++);
1564 return (size_t)nId32;
1568 typedef boost::unordered_map
1570 hashTypeProviderKey_Impl,
1571 rtl::Reference< IntrospectionAccessStatic_Impl >,
1572 TypeProviderAccessCache_Impl,
1573 TypeProviderAccessCache_Impl
1575 TypeProviderAccessCacheMap;
1577 //*************************
1578 //*** ImplIntrospection ***
1579 //*************************
1581 struct OIntrospectionMutex
1583 Mutex m_mutex;
1586 class ImplIntrospection : public XIntrospection
1587 , public XServiceInfo
1588 , public OIntrospectionMutex
1589 , public OComponentHelper
1591 // Implementation der Introspection.
1592 rtl::Reference< IntrospectionAccessStatic_Impl > implInspect(const Any& aToInspectObj);
1594 // Save XMultiServiceFactory from createComponent
1595 Reference<XMultiServiceFactory> m_xSMgr;
1597 // CoreReflection halten
1598 Reference< XIdlReflection > mxCoreReflection;
1600 // Klassen, deren Methoden eine spezielle Rolle spielen
1601 Reference<XIdlClass> mxElementAccessClass;
1602 Reference<XIdlClass> mxNameContainerClass;
1603 Reference<XIdlClass> mxNameAccessClass;
1604 Reference<XIdlClass> mxIndexContainerClass;
1605 Reference<XIdlClass> mxIndexAccessClass;
1606 Reference<XIdlClass> mxEnumerationAccessClass;
1607 Reference<XIdlClass> mxInterfaceClass;
1608 Reference<XIdlClass> mxAggregationClass;
1609 sal_Bool mbDisposed;
1611 sal_uInt16 mnCacheEntryCount;
1612 sal_uInt16 mnTPCacheEntryCount;
1613 IntrospectionAccessCacheMap* mpCache;
1614 TypeProviderAccessCacheMap* mpTypeProviderCache;
1616 public:
1617 ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr );
1619 // Methoden von XInterface
1620 virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
1621 virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); }
1622 virtual void SAL_CALL release() throw() { OComponentHelper::release(); }
1624 // XTypeProvider
1625 Sequence< Type > SAL_CALL getTypes( ) throw( RuntimeException );
1626 Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw( RuntimeException );
1628 // XServiceInfo
1629 OUString SAL_CALL getImplementationName() throw();
1630 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
1631 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
1632 static OUString SAL_CALL getImplementationName_Static( );
1633 static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(void) throw();
1635 // Methoden von XIntrospection
1636 virtual Reference<XIntrospectionAccess> SAL_CALL inspect(const Any& aToInspectObj)
1637 throw( RuntimeException );
1639 protected:
1640 // some XComponent part from OComponentHelper
1641 virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
1644 enum MethodType
1646 STANDARD_METHOD, // normale Methode, kein Bezug zu Properties oder Listenern
1647 GETSET_METHOD, // gehoert zu einer get/set-Property
1648 ADD_LISTENER_METHOD, // add-Methode einer Listener-Schnittstelle
1649 REMOVE_LISTENER_METHOD, // remove-Methode einer Listener-Schnittstelle
1650 INVALID_METHOD // Methode, deren Klasse nicht beruecksichtigt wird, z.B. XPropertySet
1653 // Ctor
1654 ImplIntrospection::ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr )
1655 : OComponentHelper( m_mutex )
1656 , m_xSMgr( rXSMgr )
1658 mnCacheEntryCount = 0;
1659 mnTPCacheEntryCount = 0;
1660 mpCache = NULL;
1661 mpTypeProviderCache = NULL;
1663 // Spezielle Klassen holen
1664 // Reference< XInterface > xServiceIface = m_xSMgr->createInstance( OUString("com.sun.star.reflection.CoreReflection") );
1665 // if( xServiceIface.is() )
1666 // mxCoreReflection = Reference< XIdlReflection >::query( xServiceIface );
1667 Reference< XPropertySet > xProps( rXSMgr, UNO_QUERY );
1668 OSL_ASSERT( xProps.is() );
1669 if (xProps.is())
1671 Reference< XComponentContext > xContext;
1672 xProps->getPropertyValue(
1673 OUString("DefaultContext") ) >>= xContext;
1674 OSL_ASSERT( xContext.is() );
1675 if (xContext.is())
1677 xContext->getValueByName(
1678 OUString("/singletons/com.sun.star.reflection.theCoreReflection") ) >>= mxCoreReflection;
1679 OSL_ENSURE( mxCoreReflection.is(), "### CoreReflection singleton not accessible!?" );
1682 if (! mxCoreReflection.is())
1684 throw DeploymentException(
1685 OUString("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible"),
1686 Reference< XInterface >() );
1689 mxElementAccessClass = mxCoreReflection->forName( OUString("com.sun.star.container.XElementAccess") );
1690 mxNameContainerClass = mxCoreReflection->forName( OUString("com.sun.star.container.XNameContainer") );
1691 mxNameAccessClass = mxCoreReflection->forName( OUString("com.sun.star.container.XNameAccess") );
1692 mxIndexContainerClass = mxCoreReflection->forName( OUString("com.sun.star.container.XIndexContainer") );
1693 mxIndexAccessClass = mxCoreReflection->forName( OUString("com.sun.star.container.XIndexAccess") );
1694 mxEnumerationAccessClass = mxCoreReflection->forName( OUString("com.sun.star.container.XEnumerationAccess") );
1695 mxInterfaceClass = mxCoreReflection->forName( OUString("com.sun.star.uno.XInterface") );
1696 mxAggregationClass = mxCoreReflection->forName( OUString("com.sun.star.uno.XAggregation") );
1697 mbDisposed = sal_False;
1700 // XComponent
1701 void ImplIntrospection::dispose() throw(::com::sun::star::uno::RuntimeException)
1703 OComponentHelper::dispose();
1705 // Cache loeschen
1706 delete mpCache;
1707 mpCache = NULL;
1708 delete mpTypeProviderCache;
1709 mpTypeProviderCache = NULL;
1711 mxElementAccessClass = NULL;
1712 mxNameContainerClass = NULL;
1713 mxNameAccessClass = NULL;
1714 mxIndexContainerClass = NULL;
1715 mxIndexAccessClass = NULL;
1716 mxEnumerationAccessClass = NULL;
1717 mxInterfaceClass = NULL;
1718 mxAggregationClass = NULL;
1719 mbDisposed = sal_True;
1723 //-----------------------------------------------------------------------------
1725 // XInterface
1726 Any ImplIntrospection::queryInterface( const Type & rType )
1727 throw(::com::sun::star::uno::RuntimeException)
1729 Any aRet( ::cppu::queryInterface(
1730 rType,
1731 static_cast< XIntrospection * >( this ),
1732 static_cast< XServiceInfo * >( this ) ) );
1734 return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType ));
1737 // XTypeProvider
1738 Sequence< Type > ImplIntrospection::getTypes()
1739 throw( RuntimeException )
1741 static OTypeCollection * s_pTypes = 0;
1742 if (! s_pTypes)
1744 MutexGuard aGuard( Mutex::getGlobalMutex() );
1745 if (! s_pTypes)
1747 static OTypeCollection s_aTypes(
1748 ::getCppuType( (const Reference< XIntrospection > *)0 ),
1749 ::getCppuType( (const Reference< XServiceInfo > *)0 ),
1750 OComponentHelper::getTypes() );
1751 s_pTypes = &s_aTypes;
1754 return s_pTypes->getTypes();
1757 Sequence< sal_Int8 > ImplIntrospection::getImplementationId()
1758 throw( RuntimeException )
1760 static OImplementationId * s_pId = 0;
1761 if (! s_pId)
1763 MutexGuard aGuard( Mutex::getGlobalMutex() );
1764 if (! s_pId)
1766 static OImplementationId s_aId;
1767 s_pId = &s_aId;
1770 return s_pId->getImplementationId();
1774 // XServiceInfo
1775 OUString ImplIntrospection::getImplementationName() throw()
1777 return getImplementationName_Static();
1780 // XServiceInfo
1781 sal_Bool ImplIntrospection::supportsService(const OUString& ServiceName) throw()
1783 Sequence< OUString > aSNL = getSupportedServiceNames();
1784 const OUString * pArray = aSNL.getConstArray();
1785 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1786 if( pArray[i] == ServiceName )
1787 return sal_True;
1788 return sal_False;
1791 // XServiceInfo
1792 Sequence< OUString > ImplIntrospection::getSupportedServiceNames(void) throw()
1794 return getSupportedServiceNames_Static();
1797 //*************************************************************************
1798 // Helper XServiceInfo
1799 OUString ImplIntrospection::getImplementationName_Static( )
1801 return OUString::createFromAscii( IMPLEMENTATION_NAME );
1804 // ORegistryServiceManager_Static
1805 Sequence< OUString > ImplIntrospection::getSupportedServiceNames_Static(void) throw()
1807 Sequence< OUString > aSNS( 1 );
1808 aSNS.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
1809 return aSNS;
1812 //*************************************************************************
1814 // Methoden von XIntrospection
1815 Reference<XIntrospectionAccess> ImplIntrospection::inspect(const Any& aToInspectObj)
1816 throw( RuntimeException )
1818 Reference<XIntrospectionAccess> xAccess;
1820 if ( aToInspectObj.getValueType().getTypeClass() == TypeClass_TYPE )
1822 Type aType;
1823 aToInspectObj >>= aType;
1825 Reference< XIdlClass > xIdlClass = mxCoreReflection->forName(((Type*)(aToInspectObj.getValue()))->getTypeName());
1827 if ( xIdlClass.is() )
1829 Any aRealInspectObj;
1830 aRealInspectObj <<= xIdlClass;
1832 rtl::Reference< IntrospectionAccessStatic_Impl > pStaticImpl( implInspect( aRealInspectObj ) );
1833 if( pStaticImpl.is() )
1834 xAccess = new ImplIntrospectionAccess( aRealInspectObj, pStaticImpl );
1837 else
1839 rtl::Reference< IntrospectionAccessStatic_Impl > pStaticImpl( implInspect( aToInspectObj ) );
1840 if( pStaticImpl.is() )
1841 xAccess = new ImplIntrospectionAccess( aToInspectObj, pStaticImpl );
1844 return xAccess;
1847 //-----------------------------------------------------------------------------
1849 // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
1850 struct hashInterface_Impl
1852 size_t operator()(const void* p) const
1854 return (size_t)p;
1858 struct eqInterface_Impl
1860 bool operator()(const void* p1, const void* p2) const
1862 return ( p1 == p2 );
1866 typedef boost::unordered_map
1868 void*,
1869 void*,
1870 hashInterface_Impl,
1871 eqInterface_Impl
1873 CheckedInterfacesMap;
1877 // TODO: Spaeter auslagern
1878 Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr )
1880 static Reference< XIdlReflection > xRefl;
1882 // void als Default-Klasse eintragen
1883 Reference<XIdlClass> xRetClass;
1884 typelib_TypeDescription * pTD = 0;
1885 rType.getDescription( &pTD );
1886 if( pTD )
1888 OUString sOWName( pTD->pTypeName );
1889 if( !xRefl.is() )
1891 xRefl = Reference< XIdlReflection >( xMgr->createInstance( OUString("com.sun.star.reflection.CoreReflection") ), UNO_QUERY );
1892 OSL_ENSURE( xRefl.is(), "### no corereflection!" );
1894 xRetClass = xRefl->forName( sOWName );
1896 return xRetClass;
1899 // Implementation der Introspection.
1900 rtl::Reference< IntrospectionAccessStatic_Impl > ImplIntrospection::implInspect(const Any& aToInspectObj)
1902 MutexGuard aGuard( m_mutex );
1904 // Wenn die Introspection schon disposed ist, wird nur ein leeres Ergebnis geliefert
1905 if( mbDisposed )
1906 return NULL;
1908 // Objekt untersuchen
1909 TypeClass eType = aToInspectObj.getValueType().getTypeClass();
1910 if( eType != TypeClass_INTERFACE && eType != TypeClass_STRUCT && eType != TypeClass_EXCEPTION )
1911 return NULL;
1913 Reference<XInterface> x;
1914 if( eType == TypeClass_INTERFACE )
1916 // Interface aus dem Any besorgen
1917 x = *(Reference<XInterface>*)aToInspectObj.getValue();
1918 if( !x.is() )
1919 return NULL;
1922 // Haben wir schon eine Cache-Instanz
1923 if( !mpCache )
1924 mpCache = new IntrospectionAccessCacheMap;
1925 if( !mpTypeProviderCache )
1926 mpTypeProviderCache = new TypeProviderAccessCacheMap;
1927 IntrospectionAccessCacheMap& aCache = *mpCache;
1928 TypeProviderAccessCacheMap& aTPCache = *mpTypeProviderCache;
1930 // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
1931 rtl::Reference< IntrospectionAccessStatic_Impl > pAccess;
1933 // Pruefen: Ist schon ein passendes Access-Objekt gecached?
1934 Sequence< Reference<XIdlClass> > SupportedClassSeq;
1935 Sequence< Type > SupportedTypesSeq;
1936 Reference<XTypeProvider> xTypeProvider;
1937 Reference<XIdlClass> xImplClass;
1938 Reference<XPropertySetInfo> xPropSetInfo;
1939 Reference<XPropertySet> xPropSet;
1941 // Look for interfaces XTypeProvider and PropertySet
1942 if( eType == TypeClass_INTERFACE )
1944 xTypeProvider = Reference<XTypeProvider>::query( x );
1945 if( xTypeProvider.is() )
1947 SupportedTypesSeq = xTypeProvider->getTypes();
1948 sal_Int32 nTypeCount = SupportedTypesSeq.getLength();
1949 if( nTypeCount )
1951 SupportedClassSeq.realloc( nTypeCount );
1952 Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray();
1954 const Type* pTypes = SupportedTypesSeq.getConstArray();
1955 for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
1957 pClasses[ i ] = TypeToIdlClass( pTypes[ i ], m_xSMgr );
1959 // TODO: Caching!
1962 else
1964 xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
1965 SupportedClassSeq.realloc( 1 );
1966 SupportedClassSeq.getArray()[ 0 ] = xImplClass;
1969 xPropSet = Reference<XPropertySet>::query( x );
1970 // Jetzt versuchen, das PropertySetInfo zu bekommen
1971 if( xPropSet.is() )
1972 xPropSetInfo = xPropSet->getPropertySetInfo();
1974 else
1976 xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
1979 if( xTypeProvider.is() )
1981 Sequence< sal_Int8 > aImpIdSeq = xTypeProvider->getImplementationId();
1982 sal_Int32 nIdLen = aImpIdSeq.getLength();
1984 if( nIdLen )
1986 // cache only, if the descriptor class is set
1987 hashTypeProviderKey_Impl aKeySeq( xPropSetInfo, aImpIdSeq );
1989 TypeProviderAccessCacheMap::iterator aIt = aTPCache.find( aKeySeq );
1990 if( aIt == aTPCache.end() )
1992 // not found
1993 // Neue Instanz anlegen und unter dem gegebenen Key einfuegen
1994 pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
1996 // Groesse begrenzen, alten Eintrag wieder rausschmeissen
1997 if( mnTPCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE )
1999 // Access mit dem kleinsten HitCount suchen
2000 TypeProviderAccessCacheMap::iterator iter = aTPCache.begin();
2001 TypeProviderAccessCacheMap::iterator end = aTPCache.end();
2002 TypeProviderAccessCacheMap::iterator toDelete = iter;
2003 while( iter != end )
2005 if( (*iter).first.nHitCount < (*toDelete).first.nHitCount )
2006 toDelete = iter;
2007 ++iter;
2009 aTPCache.erase( toDelete );
2011 else
2012 mnTPCacheEntryCount++;
2014 // Neuer Eintrage rein in die Table
2015 aKeySeq.nHitCount = 1;
2016 aTPCache[ aKeySeq ] = pAccess;
2019 else
2021 // Hit-Count erhoehen
2022 (*aIt).first.IncHitCount();
2023 return (*aIt).second;
2027 else if( xImplClass.is() )
2029 // cache only, if the descriptor class is set
2030 hashIntrospectionKey_Impl aKeySeq( SupportedClassSeq, xPropSetInfo, xImplClass );
2032 IntrospectionAccessCacheMap::iterator aIt = aCache.find( aKeySeq );
2033 if( aIt == aCache.end() )
2035 // not found
2036 // Neue Instanz anlegen und unter dem gegebenen Key einfuegen
2037 pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
2039 // Groesse begrenzen, alten Eintrag wieder rausschmeissen
2040 if( mnCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE )
2042 // Access mit dem kleinsten HitCount suchen
2043 IntrospectionAccessCacheMap::iterator iter = aCache.begin();
2044 IntrospectionAccessCacheMap::iterator end = aCache.end();
2045 IntrospectionAccessCacheMap::iterator toDelete = iter;
2046 while( iter != end )
2048 if( (*iter).first.nHitCount < (*toDelete).first.nHitCount )
2049 toDelete = iter;
2050 ++iter;
2052 aCache.erase( toDelete );
2054 else
2055 mnCacheEntryCount++;
2057 // Neuer Eintrage rein in die Table
2058 aKeySeq.nHitCount = 1;
2059 aCache[ aKeySeq ] = pAccess;
2062 else
2064 // Hit-Count erhoehen
2065 (*aIt).first.IncHitCount();
2066 return (*aIt).second;
2070 // Kein Access gecached -> neu anlegen
2071 Property* pAllPropArray;
2072 Reference<XInterface>* pInterfaces1;
2073 Reference<XInterface>* pInterfaces2;
2074 sal_Int16* pMapTypeArray;
2075 sal_Int32* pPropertyConceptArray;
2076 sal_Int32 i;
2078 if( !pAccess.is() )
2079 pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
2081 // Referenzen auf wichtige Daten von pAccess
2082 sal_Int32& rPropCount = pAccess->mnPropCount;
2083 IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
2084 IntrospectionNameMap& rMethodNameMap = pAccess->maMethodNameMap;
2085 LowerToExactNameMap& rLowerToExactNameMap = pAccess->maLowerToExactNameMap;
2087 // Schon mal Pointer auf das eigene Property-Feld holen
2088 pAllPropArray = pAccess->maAllPropertySeq.getArray();
2089 pInterfaces1 = pAccess->aInterfaceSeq1.getArray();
2090 pInterfaces2 = pAccess->aInterfaceSeq2.getArray();
2091 pMapTypeArray = pAccess->maMapTypeSeq.getArray();
2092 pPropertyConceptArray = pAccess->maPropertyConceptSeq.getArray();
2094 //*************************
2095 //*** Analyse vornehmen ***
2096 //*************************
2097 if( eType == TypeClass_INTERFACE )
2099 // Zunaechst nach speziellen Interfaces suchen, die fuer
2100 // die Introspection von besonderer Bedeutung sind.
2102 // XPropertySet vorhanden?
2103 if( xPropSet.is() && xPropSetInfo.is() )
2105 // Gibt es auch ein FastPropertySet?
2106 Reference<XFastPropertySet> xDummy = Reference<XFastPropertySet>::query( x );
2107 sal_Bool bFast = pAccess->mbFastPropSet = xDummy.is();
2109 Sequence<Property> aPropSeq = xPropSetInfo->getProperties();
2110 const Property* pProps = aPropSeq.getConstArray();
2111 sal_Int32 nLen = aPropSeq.getLength();
2113 // Bei FastPropertySet muessen wir uns die Original-Handles merken
2114 if( bFast )
2115 pAccess->mpOrgPropertyHandleArray = new sal_Int32[ nLen ];
2117 for( i = 0 ; i < nLen ; i++ )
2119 // Property in eigene Liste uebernehmen
2120 pAccess->checkPropertyArraysSize
2121 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2122 Property& rProp = pAllPropArray[ rPropCount ];
2123 rProp = pProps[ i ];
2125 if( bFast )
2126 pAccess->mpOrgPropertyHandleArray[ i ] = rProp.Handle;
2128 // PropCount als Handle fuer das eigene FastPropertySet eintragen
2129 rProp.Handle = rPropCount;
2131 // Art der Property merken
2132 pMapTypeArray[ rPropCount ] = MAP_PROPERTY_SET;
2133 pPropertyConceptArray[ rPropCount ] = PROPERTYSET;
2134 pAccess->mnPropertySetPropCount++;
2136 // Namen in Hashtable eintragen, wenn nicht schon bekannt
2137 OUString aPropName = rProp.Name;
2139 // Haben wir den Namen schon?
2140 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2141 if( aIt == rPropNameMap.end() )
2143 // Neuer Eintrag in die Hashtable
2144 rPropNameMap[ aPropName ] = rPropCount;
2146 // Tabelle fuer XExactName pflegen
2147 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2149 else
2151 SAL_WARN( "stoc", "Introspection: Property \"" <<
2152 aPropName << "\" found more than once in PropertySet" );
2155 // Count pflegen
2156 rPropCount++;
2160 // Indizes in die Export-Tabellen
2161 sal_Int32 iAllExportedMethod = 0;
2162 sal_Int32 iAllSupportedListener = 0;
2164 // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
2165 CheckedInterfacesMap aCheckedInterfacesMap;
2167 // Flag, ob XInterface-Methoden erfasst werden sollen
2168 // (das darf nur einmal erfolgen, initial zulassen)
2169 sal_Bool bXInterfaceIsInvalid = sal_False;
2171 // Flag, ob die XInterface-Methoden schon erfasst wurden. Wenn sal_True,
2172 // wird bXInterfaceIsInvalid am Ende der Iface-Schleife aktiviert und
2173 // XInterface-Methoden werden danach abgeklemmt.
2174 sal_Bool bFoundXInterface = sal_False;
2176 sal_Int32 nClassCount = SupportedClassSeq.getLength();
2177 for( sal_Int32 nIdx = 0 ; nIdx < nClassCount; nIdx++ )
2179 Reference<XIdlClass> xImplClass2 = SupportedClassSeq.getConstArray()[nIdx];
2180 while( xImplClass2.is() )
2182 // Interfaces der Implementation holen
2183 Sequence< Reference<XIdlClass> > aClassSeq = xImplClass2->getInterfaces();
2184 sal_Int32 nIfaceCount = aClassSeq.getLength();
2186 aClassSeq.realloc( nIfaceCount + 1 );
2187 aClassSeq.getArray()[ nIfaceCount ] = xImplClass2;
2188 nIfaceCount++;
2190 const Reference<XIdlClass>* pParamArray = aClassSeq.getConstArray();
2192 for( sal_Int32 j = 0 ; j < nIfaceCount ; j++ )
2194 const Reference<XIdlClass>& rxIfaceClass = pParamArray[j];
2196 // Pruefen, ob das Interface schon beruecksichtigt wurde.
2197 XInterface* pIface = ( static_cast< XInterface* >( rxIfaceClass.get() ) );
2198 if( aCheckedInterfacesMap.count( pIface ) > 0 )
2200 // Kennen wir schon
2201 continue;
2203 else
2205 // Sonst eintragen
2206 aCheckedInterfacesMap[ pIface ] = pIface;
2209 //********************************************************************
2211 // 2. Fields als Properties registrieren
2213 // Felder holen
2214 Sequence< Reference<XIdlField> > fields = rxIfaceClass->getFields();
2215 const Reference<XIdlField>* pFields = fields.getConstArray();
2216 sal_Int32 nLen = fields.getLength();
2218 for( i = 0 ; i < nLen ; i++ )
2220 Reference<XIdlField> xField = pFields[i];
2221 Reference<XIdlClass> xPropType = xField->getType();
2223 // Ist die PropertySequence gross genug?
2224 pAccess->checkPropertyArraysSize
2225 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2227 // In eigenes Property-Array eintragen
2228 Property& rProp = pAllPropArray[ rPropCount ];
2229 OUString aFieldName = xField->getName();
2230 rProp.Name = aFieldName;
2231 rProp.Handle = rPropCount;
2232 Type aFieldType( xPropType->getTypeClass(), xPropType->getName() );
2233 rProp.Type = aFieldType;
2234 FieldAccessMode eAccessMode = xField->getAccessMode();
2235 rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
2236 eAccessMode == FieldAccessMode_CONST)
2237 ? READONLY : 0;
2239 // Namen in Hashtable eintragen
2240 OUString aPropName = rProp.Name;
2242 // Haben wir den Namen schon?
2243 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2244 if( !( aIt == rPropNameMap.end() ) )
2245 continue;
2247 // Neuer Eintrag in die Hashtable
2248 rPropNameMap[ aPropName ] = rPropCount;
2250 // Tabelle fuer XExactName pflegen
2251 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2253 // Field merken
2254 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2255 pInterfaces1, rPropCount );
2256 pInterfaces1[ rPropCount ] = xField;
2258 // Art der Property merken
2259 pMapTypeArray[ rPropCount ] = MAP_FIELD;
2260 pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
2261 pAccess->mnAttributePropCount++;
2263 // Count pflegen
2264 rPropCount++;
2267 //********************************************************************
2269 // 3. Methoden
2271 // Zaehler fuer die gefundenen Listener
2272 sal_Int32 nListenerCount = 0;
2274 // Alle Methoden holen und merken
2275 Sequence< Reference<XIdlMethod> > methods = rxIfaceClass->getMethods();
2276 const Reference<XIdlMethod>* pSourceMethods = methods.getConstArray();
2277 sal_Int32 nSourceMethodCount = methods.getLength();
2279 // 3. a) get/set- und Listener-Methoden suchen
2281 // Feld fuer Infos ueber die Methoden anlegen, damit spaeter leicht die Methoden
2282 // gefunden werden koennen, die nicht im Zusammenhang mit Properties oder Listenern
2283 // stehen. NEU: auch MethodConceptArray initialisieren
2284 MethodType* pMethodTypes = new MethodType[ nSourceMethodCount ];
2285 sal_Int32* pLocalMethodConcepts = new sal_Int32[ nSourceMethodCount ];
2286 for( i = 0 ; i < nSourceMethodCount ; i++ )
2288 pMethodTypes[ i ] = STANDARD_METHOD;
2289 pLocalMethodConcepts[ i ] = 0;
2292 OUString aMethName;
2293 OUString aPropName;
2294 OUString aStartStr;
2295 for( i = 0 ; i < nSourceMethodCount ; i++ )
2297 // Methode ansprechen
2298 const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
2299 sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
2301 // Namen besorgen
2302 aMethName = rxMethod_i->getName();
2304 // Methoden katalogisieren
2305 // Alle (?) Methoden von XInterface filtern, damit z.B. nicht
2306 // vom Scripting aus acquire oder release gerufen werden kann
2307 if( rxMethod_i->getDeclaringClass()->equals( mxInterfaceClass ) )
2309 // XInterface-Methoden sind hiermit einmal beruecksichtigt
2310 bFoundXInterface = sal_True;
2312 if( bXInterfaceIsInvalid )
2314 pMethodTypes[ i ] = INVALID_METHOD;
2315 continue;
2317 else
2319 if( aMethName != OUString("queryInterface") )
2321 rMethodConcept_i |= MethodConcept::DANGEROUS;
2322 continue;
2326 else if( rxMethod_i->getDeclaringClass()->equals( mxAggregationClass ) )
2328 if( aMethName == "setDelegator" )
2330 rMethodConcept_i |= MethodConcept::DANGEROUS;
2331 continue;
2334 else if( rxMethod_i->getDeclaringClass()->equals( mxElementAccessClass ) )
2336 rMethodConcept_i |= ( NAMECONTAINER |
2337 INDEXCONTAINER |
2338 ENUMERATION );
2340 else if( rxMethod_i->getDeclaringClass()->equals( mxNameContainerClass ) ||
2341 rxMethod_i->getDeclaringClass()->equals( mxNameAccessClass ) )
2343 rMethodConcept_i |= NAMECONTAINER;
2345 else if( rxMethod_i->getDeclaringClass()->equals( mxIndexContainerClass ) ||
2346 rxMethod_i->getDeclaringClass()->equals( mxIndexAccessClass ) )
2348 rMethodConcept_i |= INDEXCONTAINER;
2350 else if( rxMethod_i->getDeclaringClass()->equals( mxEnumerationAccessClass ) )
2352 rMethodConcept_i |= ENUMERATION;
2355 // Wenn der Name zu kurz ist, wird's sowieso nichts
2356 if( aMethName.getLength() <= 3 )
2357 continue;
2359 // Ist es eine get-Methode?
2360 aStartStr = aMethName.copy( 0, 3 );
2361 if( aStartStr == "get" )
2363 // Namen der potentiellen Property
2364 aPropName = aMethName.copy( 3 );
2366 // get-Methode darf keinen Parameter haben
2367 Sequence< Reference<XIdlClass> > getParams = rxMethod_i->getParameterTypes();
2368 if( getParams.getLength() > 0 )
2370 continue;
2373 // Haben wir den Namen schon?
2374 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2375 if( !( aIt == rPropNameMap.end() ) )
2377 /* TODO
2378 OSL_TRACE(
2379 String( "Introspection: Property \"" ) +
2380 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2381 String( "\" found more than once" ) );
2383 continue;
2386 // Eine readonly-Property ist es jetzt mindestens schon
2387 rMethodConcept_i |= PROPERTY;
2389 pMethodTypes[i] = GETSET_METHOD;
2390 Reference<XIdlClass> xGetRetType = rxMethod_i->getReturnType();
2392 // Ist die PropertySequence gross genug?
2393 pAccess->checkPropertyArraysSize
2394 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2396 // In eigenes Property-Array eintragen
2397 Property& rProp = pAllPropArray[ rPropCount ];
2398 rProp.Name = aPropName;
2399 rProp.Handle = rPropCount;
2400 rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
2401 rProp.Attributes = READONLY;
2403 // Neuer Eintrag in die Hashtable
2404 rPropNameMap[ aPropName ] = rPropCount;
2406 // Tabelle fuer XExactName pflegen
2407 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2409 // get-Methode merken
2410 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2411 pInterfaces1, rPropCount );
2412 pInterfaces1[ rPropCount ] = rxMethod_i;
2414 // Art der Property merken
2415 pMapTypeArray[ rPropCount ] = MAP_GETSET;
2416 pPropertyConceptArray[ rPropCount ] = METHODS;
2417 pAccess->mnMethodPropCount++;
2419 // Passende set-Methode suchen
2420 sal_Int32 k;
2421 for( k = 0 ; k < nSourceMethodCount ; k++ )
2423 // Methode ansprechen
2424 const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
2426 // Nur Methoden nehmen, die nicht schon zugeordnet sind
2427 if( k == i || pMethodTypes[k] != STANDARD_METHOD )
2428 continue;
2430 // Name holen und auswerten
2431 OUString aMethName2 = rxMethod_k->getName();
2432 OUString aStartStr2 = aMethName2.copy( 0, 3 );
2433 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2434 if( !( aStartStr2 == "set" ) )
2435 continue;
2437 // Ist es denn der gleiche Name?
2438 OUString aPropName2 = aMethName2.copy( 3 );
2439 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2440 if( !( aPropName == aPropName2 ) )
2441 continue;
2443 // set-Methode muss void returnen
2444 Reference<XIdlClass> xSetRetType = rxMethod_k->getReturnType();
2445 if( xSetRetType->getTypeClass() != TypeClass_VOID )
2447 continue;
2450 // set-Methode darf nur einen Parameter haben
2451 Sequence< Reference<XIdlClass> > setParams = rxMethod_k->getParameterTypes();
2452 sal_Int32 nParamCount = setParams.getLength();
2453 if( nParamCount != 1 )
2455 continue;
2458 // Jetzt muss nur noch der return-Typ dem Parameter-Typ entsprechen
2459 const Reference<XIdlClass>* pParamArray2 = setParams.getConstArray();
2460 Reference<XIdlClass> xParamType = pParamArray2[ 0 ];
2461 if( xParamType->equals( xGetRetType ) )
2463 pLocalMethodConcepts[ k ] = PROPERTY;
2465 pMethodTypes[k] = GETSET_METHOD;
2467 // ReadOnly-Flag wieder loschen
2468 rProp.Attributes &= ~READONLY;
2470 // set-Methode merken
2471 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
2472 pInterfaces2, rPropCount );
2473 pInterfaces2[ rPropCount ] = rxMethod_k;
2477 // Count pflegen
2478 rPropCount++;
2481 // Ist es eine addListener-Methode?
2482 else if( aStartStr == "add" )
2484 OUString aListenerStr( "Listener" );
2486 // Namen der potentiellen Property
2487 sal_Int32 nStrLen = aMethName.getLength();
2488 sal_Int32 nCopyLen = nStrLen - aListenerStr.getLength();
2489 OUString aEndStr = aMethName.copy( nCopyLen > 0 ? nCopyLen : 0 );
2491 // Endet das Teil auf Listener?
2492 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2493 if( !( aEndStr == aListenerStr ) )
2494 continue;
2496 // Welcher Listener?
2497 OUString aListenerName = aMethName.copy( 3, nStrLen - aListenerStr.getLength() - 3 );
2499 // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2500 // - Rueckgabe-Typ
2501 // - Anzahl und Art der Parameter
2504 // Passende remove-Methode suchen, sonst gilt's nicht
2505 sal_Int32 k;
2506 for( k = 0 ; k < nSourceMethodCount ; k++ )
2508 // Methode ansprechen
2509 const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
2511 // Nur Methoden nehmen, die nicht schon zugeordnet sind
2512 if( k == i || pMethodTypes[k] != STANDARD_METHOD )
2513 continue;
2515 // Name holen und auswerten
2516 OUString aMethName2 = rxMethod_k->getName();
2517 sal_Int32 nNameLen = aMethName2.getLength();
2518 sal_Int32 nCopyLen2 = (nNameLen < 6) ? nNameLen : 6;
2519 OUString aStartStr2 = aMethName2.copy( 0, nCopyLen2 );
2520 OUString aRemoveStr("remove" );
2521 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2522 if( !( aStartStr2 == aRemoveStr ) )
2523 continue;
2525 // Ist es denn der gleiche Listener?
2526 if( aMethName2.getLength() - aRemoveStr.getLength() <= aListenerStr.getLength() )
2527 continue;
2528 OUString aListenerName2 = aMethName2.copy
2529 ( 6, aMethName2.getLength() - aRemoveStr.getLength() - aListenerStr.getLength() );
2530 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2531 if( !( aListenerName == aListenerName2 ) )
2532 continue;
2534 // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2535 // - Rueckgabe-Typ
2536 // - Anzahl und Art der Parameter
2539 // Methoden sind als Listener-Schnittstelle erkannt
2540 rMethodConcept_i |= LISTENER;
2541 pLocalMethodConcepts[ k ] |= LISTENER;
2543 pMethodTypes[i] = ADD_LISTENER_METHOD;
2544 pMethodTypes[k] = REMOVE_LISTENER_METHOD;
2545 nListenerCount++;
2551 // Jetzt koennen noch SET-Methoden ohne zugehoerige GET-Methode existieren,
2552 // diese muessen zu Write-Only-Properties gemachte werden.
2553 for( i = 0 ; i < nSourceMethodCount ; i++ )
2555 // Methode ansprechen
2556 const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
2558 // Nur Methoden nehmen, die nicht schon zugeordnet sind
2559 if( pMethodTypes[i] != STANDARD_METHOD )
2560 continue;
2562 // Namen besorgen
2563 aMethName = rxMethod_i->getName();
2565 // Wenn der Name zu kurz ist, wird's sowieso nichts
2566 if( aMethName.getLength() <= 3 )
2567 continue;
2569 // Ist es eine set-Methode ohne zugehoerige get-Methode?
2570 aStartStr = aMethName.copy( 0, 3 );
2571 if( aStartStr == "set" )
2573 // Namen der potentiellen Property
2574 aPropName = aMethName.copy( 3 );
2576 // set-Methode muss void returnen
2577 Reference<XIdlClass> xSetRetType = rxMethod_i->getReturnType();
2578 if( xSetRetType->getTypeClass() != TypeClass_VOID )
2580 continue;
2583 // set-Methode darf nur einen Parameter haben
2584 Sequence< Reference<XIdlClass> > setParams = rxMethod_i->getParameterTypes();
2585 sal_Int32 nParamCount = setParams.getLength();
2586 if( nParamCount != 1 )
2588 continue;
2591 // Haben wir den Namen schon?
2592 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2593 if( !( aIt == rPropNameMap.end() ) )
2595 /* TODO:
2596 OSL_TRACE(
2597 String( "Introspection: Property \"" ) +
2598 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2599 String( "\" found more than once" ) );
2601 continue;
2604 // Alles klar, es ist eine Write-Only-Property
2605 pLocalMethodConcepts[ i ] = PROPERTY;
2607 pMethodTypes[i] = GETSET_METHOD;
2608 Reference<XIdlClass> xGetRetType = setParams.getConstArray()[0];
2610 // Ist die PropertySequence gross genug?
2611 pAccess->checkPropertyArraysSize
2612 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2614 // In eigenes Property-Array eintragen
2615 Property& rProp = pAllPropArray[ rPropCount ];
2616 rProp.Name = aPropName;
2617 rProp.Handle = rPropCount;
2618 rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
2619 rProp.Attributes = 0; // PROPERTY_WRITEONLY ???
2621 // Neuer Eintrag in die Hashtable
2622 rPropNameMap[ aPropName ] = rPropCount;
2624 // Tabelle fuer XExactName pflegen
2625 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2627 // set-Methode merken
2628 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
2629 pInterfaces2, rPropCount );
2630 pInterfaces2[ rPropCount ] = rxMethod_i;
2632 // Art der Property merken
2633 pMapTypeArray[ rPropCount ] = MAP_SETONLY;
2634 pPropertyConceptArray[ rPropCount ] = METHODS;
2635 pAccess->mnMethodPropCount++;
2637 // Count pflegen
2638 rPropCount++;
2643 //********************************************************************
2645 // 4. Methoden in die Gesamt-Sequence uebernehmen
2647 // Wieviele Methoden muessen in die Method-Sequence?
2648 sal_Int32 nExportedMethodCount = 0;
2649 sal_Int32 nSupportedListenerCount = 0;
2650 for( i = 0 ; i < nSourceMethodCount ; i++ )
2652 if( pMethodTypes[ i ] != INVALID_METHOD )
2654 nExportedMethodCount++;
2656 if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
2658 nSupportedListenerCount++;
2662 // Sequences im Access-Objekt entsprechend aufbohren
2663 pAccess->maAllMethodSeq.realloc( nExportedMethodCount + iAllExportedMethod );
2664 pAccess->maMethodConceptSeq.realloc( nExportedMethodCount + iAllExportedMethod );
2665 pAccess->maSupportedListenerSeq.realloc( nSupportedListenerCount + iAllSupportedListener );
2667 // Methoden reinschreiben
2668 Reference<XIdlMethod>* pDestMethods = pAccess->maAllMethodSeq.getArray();
2669 sal_Int32* pMethodConceptArray = pAccess->maMethodConceptSeq.getArray();
2670 Type* pListenerClassRefs = pAccess->maSupportedListenerSeq.getArray();
2671 for( i = 0 ; i < nSourceMethodCount ; i++ )
2673 if( pMethodTypes[ i ] != INVALID_METHOD )
2675 // Methode ansprechen
2676 const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
2678 // Namen in Hashtable eintragen, wenn nicht schon bekannt
2679 OUString aMethName2 = rxMethod->getName();
2680 IntrospectionNameMap::iterator aIt = rMethodNameMap.find( aMethName2 );
2681 if( aIt == rMethodNameMap.end() )
2683 // Eintragen
2684 rMethodNameMap[ aMethName2 ] = iAllExportedMethod;
2686 // Tabelle fuer XExactName pflegen
2687 rLowerToExactNameMap[ toLower( aMethName2 ) ] = aMethName2;
2689 else
2691 sal_Int32 iHashResult = (*aIt).second;
2693 Reference<XIdlMethod> xExistingMethod = pDestMethods[ iHashResult ];
2695 Reference< XIdlClass > xExistingMethClass =
2696 xExistingMethod->getDeclaringClass();
2697 Reference< XIdlClass > xNewMethClass = rxMethod->getDeclaringClass();
2698 if( xExistingMethClass->equals( xNewMethClass ) )
2699 continue;
2702 pDestMethods[ iAllExportedMethod ] = rxMethod;
2704 // Wenn kein Concept gesetzt wurde, ist die Methode "normal"
2705 sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
2706 if( !rMethodConcept_i )
2707 rMethodConcept_i = MethodConcept_NORMAL_IMPL;
2708 pMethodConceptArray[ iAllExportedMethod ] = rMethodConcept_i;
2709 iAllExportedMethod++;
2711 if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
2713 // Klasse des Listeners ermitteln
2714 const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
2716 // void als Default-Klasse eintragen
2717 Reference<XIdlClass> xListenerClass = TypeToIdlClass( getCppuVoidType(), m_xSMgr );
2718 // ALT: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass();
2720 // 1. Moeglichkeit: Parameter nach einer Listener-Klasse durchsuchen
2721 // Nachteil: Superklassen muessen rekursiv durchsucht werden
2722 Sequence< Reference<XIdlClass> > aParams = rxMethod->getParameterTypes();
2723 const Reference<XIdlClass>* pParamArray2 = aParams.getConstArray();
2725 Reference<XIdlClass> xEventListenerClass = TypeToIdlClass( getCppuType( (Reference<XEventListener>*) NULL ), m_xSMgr );
2726 // ALT: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass();
2727 sal_Int32 nParamCount = aParams.getLength();
2728 sal_Int32 k;
2729 for( k = 0 ; k < nParamCount ; k++ )
2731 const Reference<XIdlClass>& rxClass = pParamArray2[k];
2733 // Sind wir von einem Listener abgeleitet?
2734 if( rxClass->equals( xEventListenerClass ) ||
2735 isDerivedFrom( rxClass, xEventListenerClass ) )
2737 xListenerClass = rxClass;
2738 break;
2742 // 2. Moeglichkeit: Namen der Methode auswerden
2743 // Nachteil: geht nicht bei Test-Listenern, die es nicht gibt
2744 //aMethName = rxMethod->getName();
2745 //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 );
2746 //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName );
2747 Type aListenerType( TypeClass_INTERFACE, xListenerClass->getName() );
2748 pListenerClassRefs[ iAllSupportedListener ] = aListenerType;
2749 iAllSupportedListener++;
2753 // Wenn in diesem Durchlauf XInterface-Methoden
2754 // dabei waren, diese zukuenftig ignorieren
2755 if( bFoundXInterface )
2756 bXInterfaceIsInvalid = sal_True;
2758 delete[] pMethodTypes;
2759 delete[] pLocalMethodConcepts;
2762 // Super-Klasse(n) vorhanden? Dann dort fortsetzen
2763 Sequence< Reference<XIdlClass> > aSuperClassSeq = xImplClass2->getSuperclasses();
2765 // Zur Zeit wird nur von einer Superklasse ausgegangen
2766 if( aSuperClassSeq.getLength() >= 1 )
2768 xImplClass2 = aSuperClassSeq.getConstArray()[0];
2769 OSL_ENSURE( xImplClass2.is(), "super class null" );
2771 else
2773 xImplClass2 = NULL;
2778 // Anzahl der exportierten Methoden uebernehmen und Sequences anpassen
2779 // (kann abweichen, weil doppelte Methoden erst nach der Ermittlung
2780 // von nExportedMethodCount herausgeworfen werden)
2781 sal_Int32& rMethCount = pAccess->mnMethCount;
2782 rMethCount = iAllExportedMethod;
2783 pAccess->maAllMethodSeq.realloc( rMethCount );
2784 pAccess->maMethodConceptSeq.realloc( rMethCount );
2786 // Groesse der Property-Sequences anpassen
2787 pAccess->maAllPropertySeq.realloc( rPropCount );
2788 pAccess->maPropertyConceptSeq.realloc( rPropCount );
2789 pAccess->maMapTypeSeq.realloc( rPropCount );
2791 // Bei structs Fields als Properties registrieren
2792 else //if( eType == TypeClass_STRUCT )
2794 // Ist es ein Interface oder eine struct?
2795 //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass();
2796 Reference<XIdlClass> xClassRef = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
2797 if( !xClassRef.is() )
2799 SAL_WARN( "stoc", "Can't get XIdlClass from Reflection" );
2800 return pAccess;
2803 // Felder holen
2804 Sequence< Reference<XIdlField> > fields = xClassRef->getFields();
2805 const Reference<XIdlField>* pFields = fields.getConstArray();
2806 sal_Int32 nLen = fields.getLength();
2808 for( i = 0 ; i < nLen ; i++ )
2810 Reference<XIdlField> xField = pFields[i];
2811 Reference<XIdlClass> xPropType = xField->getType();
2812 OUString aPropName = xField->getName();
2814 // Ist die PropertySequence gross genug?
2815 pAccess->checkPropertyArraysSize
2816 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2818 // In eigenes Property-Array eintragen
2819 Property& rProp = pAllPropArray[ rPropCount ];
2820 rProp.Name = aPropName;
2821 rProp.Handle = rPropCount;
2822 rProp.Type = Type( xPropType->getTypeClass(), xPropType->getName() );
2823 FieldAccessMode eAccessMode = xField->getAccessMode();
2824 rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
2825 eAccessMode == FieldAccessMode_CONST)
2826 ? READONLY : 0;
2828 //FieldAccessMode eAccessMode = xField->getAccessMode();
2829 //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST)
2830 //? PropertyAttribute::READONLY : 0;
2832 // Namen in Hashtable eintragen
2833 rPropNameMap[ aPropName ] = rPropCount;
2835 // Tabelle fuer XExactName pflegen
2836 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2838 // Field merken
2839 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2840 pInterfaces1, rPropCount );
2841 pInterfaces1[ rPropCount ] = xField;
2843 // Art der Property merken
2844 pMapTypeArray[ rPropCount ] = MAP_FIELD;
2845 pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
2846 pAccess->mnAttributePropCount++;
2848 // Count pflegen
2849 rPropCount++;
2853 // Property-Sequence auf die richtige Laenge bringen
2854 pAccess->maAllPropertySeq.realloc( pAccess->mnPropCount );
2856 return pAccess;
2859 //*************************************************************************
2860 Reference< XInterface > SAL_CALL ImplIntrospection_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr )
2861 throw( RuntimeException )
2863 Reference< XInterface > xService = (OWeakObject*)(OComponentHelper*)new ImplIntrospection( rSMgr );
2864 return xService;
2869 extern "C"
2871 SAL_DLLPUBLIC_EXPORT void * SAL_CALL introspection_component_getFactory(
2872 const sal_Char * pImplName, void * pServiceManager,
2873 SAL_UNUSED_PARAMETER void * )
2875 void * pRet = 0;
2877 if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
2879 Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory(
2880 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
2881 OUString::createFromAscii( pImplName ),
2882 stoc_inspect::ImplIntrospection_CreateInstance,
2883 stoc_inspect::ImplIntrospection::getSupportedServiceNames_Static() ) );
2885 if (xFactory.is())
2887 xFactory->acquire();
2888 pRet = xFactory.get();
2892 return pRet;
2897 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */