1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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
;
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
)
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
117 // Properties, that get described with get/set-Methods
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
137 size_t operator()(const OUString Str
) const
139 return (size_t)Str
.hashCode();
145 sal_Bool
operator()(const OUString Str1
, const OUString Str2
) const
147 return ( Str1
== Str2
);
151 typedef boost::unordered_map
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
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
;
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
,
239 void checkInterfaceArraySize( Sequence
< Reference
<XInterface
> >& rSeq
, Reference
<XInterface
>*& rpInterfaceArray
,
240 sal_Int32 iNextIndex
);
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
; }
268 IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference
< XIdlReflection
> xCoreReflection_
)
269 : mxCoreReflection( xCoreReflection_
)
271 aInterfaceSeq1
.realloc( ARRAY_SIZE_STEP
);
272 aInterfaceSeq2
.realloc( ARRAY_SIZE_STEP
);
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
;
283 //mnDangerousPropCount = 0;
284 mnPropertySetPropCount
= 0;
285 mnAttributePropCount
= 0;
286 mnMethodPropCount
= 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
;
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
314 sal_Int32 nSearchFrom
= aMethodName
.getLength();
317 // Strategy: Search back until the first '_' is found
318 sal_Int32 nFound
= aMethodName
.lastIndexOf( '_', nSearchFrom
);
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
);
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
) )
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
) )
369 if( iHashResult
!= -1 )
375 nSearchFrom
= nFound
- 1;
376 if( nSearchFrom
< 0 )
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
);
388 setPropertyValueByIndex( obj
, (sal_Int32
)i
, aValue
);
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();
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
:
422 const Property
& rProp
= maAllPropertySeq
.getConstArray()[ nSequenceIndex
];
424 // Convert Interface-Parameter to the correct type
425 sal_Bool bUseCopy
= sal_False
;
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() )
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
);
463 // throw UnknownPropertyException
466 // else take the normal one
469 // Retrieve PropertySet-Interface
470 Reference
<XPropertySet
> xPropSet
=
471 Reference
<XPropertySet
>::query( xInterface
);
474 xPropSet
->setPropertyValue( rProp
.Name
, bUseCopy
? aRealValue
: aValue
);
478 // throw UnknownPropertyException
486 Reference
<XIdlField
> xField
= (XIdlField
*)(aInterfaceSeq1
.getConstArray()[ nSequenceIndex
].get());
487 Reference
<XIdlField2
> xField2(xField
, UNO_QUERY
);
490 xField2
->set( (Any
&)obj
, aValue
);
491 // IllegalArgumentException
492 // NullPointerException
496 xField
->set( obj
, aValue
);
497 // IllegalArgumentException
498 // NullPointerException
502 // throw IllegalArgumentException();
510 // Retrieve set-Methods
511 Reference
<XIdlMethod
> xMethod
= (XIdlMethod
*)(aInterfaceSeq2
.getConstArray()[ nSequenceIndex
].get());
514 Sequence
<Any
> args( 1 );
515 args
.getArray()[0] = aValue
;
516 xMethod
->invoke( obj
, args
);
520 // throw IllegalArgumentException();
527 Any
IntrospectionAccessStatic_Impl::getPropertyValue( const Any
& obj
, const OUString
& aPropertyName
) const
529 sal_Int32 i
= getPropertyIndex( aPropertyName
);
531 return getPropertyValueByIndex( obj
, i
);
533 throw UnknownPropertyException();
536 Any
IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any
& obj
, sal_Int32 nSequenceIndex
) const
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();
554 const sal_Int16
* pMapTypeArray
= maMapTypeSeq
.getConstArray();
555 switch( pMapTypeArray
[ nSequenceIndex
] )
557 case MAP_PROPERTY_SET
:
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
);
577 // throw UnknownPropertyException
581 // sonst eben das normale nehmen
584 // PropertySet-Interface holen
585 Reference
<XPropertySet
> xPropSet
=
586 Reference
<XPropertySet
>::query( xInterface
);
589 aRet
= xPropSet
->getPropertyValue( rProp
.Name
);
593 // throw UnknownPropertyException
602 Reference
<XIdlField
> xField
= (XIdlField
*)(aInterfaceSeq1
.getConstArray()[ nSequenceIndex
].get());
605 aRet
= xField
->get( obj
);
606 // IllegalArgumentException
607 // NullPointerException
611 // throw IllegalArgumentException();
620 Reference
<XIdlMethod
> xMethod
= (XIdlMethod
*)(aInterfaceSeq1
.getConstArray()[ nSequenceIndex
].get());
624 aRet
= xMethod
->invoke( obj
, args
);
628 // throw IllegalArgumentException();
635 // get-Methode gibt es nicht
636 // throw WriteOnlyPropertyException();
643 // Hilfs-Methoden zur Groessen-Anpassung der Sequences
644 void IntrospectionAccessStatic_Impl::checkPropertyArraysSize
646 Property
*& rpAllPropArray
,
647 sal_Int16
*& rpMapTypeArray
,
648 sal_Int32
*& rpPropertyConceptArray
,
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
;
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
;
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
,
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
;
801 ImplIntrospectionAdapter( ImplIntrospectionAccess
* pAccess_
,
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_
,
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(
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() )
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
)
960 Reference
<XPropertySet
> xPropSet
=
961 Reference
<XPropertySet
>::query( mxIface
);
962 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
964 xPropSet
->addPropertyChangeListener(aPropertyName
, aListener
);
968 void ImplIntrospectionAdapter::removePropertyChangeListener(const OUString
& aPropertyName
, const Reference
<XPropertyChangeListener
>& aListener
)
969 throw( UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
973 Reference
<XPropertySet
> xPropSet
=
974 Reference
<XPropertySet
>::query( mxIface
);
975 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
977 xPropSet
->removePropertyChangeListener(aPropertyName
, aListener
);
981 void ImplIntrospectionAdapter::addVetoableChangeListener(const OUString
& aPropertyName
, const Reference
<XVetoableChangeListener
>& aListener
)
982 throw( UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
986 Reference
<XPropertySet
> xPropSet
=
987 Reference
<XPropertySet
>::query( mxIface
);
988 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
990 xPropSet
->addVetoableChangeListener(aPropertyName
, aListener
);
994 void ImplIntrospectionAdapter::removeVetoableChangeListener(const OUString
& aPropertyName
, const Reference
<XVetoableChangeListener
>& aListener
)
995 throw( UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
999 Reference
<XPropertySet
> xPropSet
=
1000 Reference
<XPropertySet
>::query( mxIface
);
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
)
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
|
1167 sal_Int32
ImplIntrospectionAccess::getSuppliedPropertyConcepts(void)
1168 throw( RuntimeException
)
1170 return PropertyConcept::DANGEROUS
|
1176 Property
ImplIntrospectionAccess::getProperty(const OUString
& Name
, sal_Int32 PropertyConcepts
)
1177 throw( NoSuchElementException
, RuntimeException
)
1180 sal_Int32 i
= mpStaticImpl
->getPropertyIndex( Name
);
1181 sal_Bool bFound
= sal_False
;
1184 sal_Int32 nConcept
= mpStaticImpl
->getPropertyConcepts().getConstArray()[ i
];
1185 if( (PropertyConcepts
& nConcept
) != 0 )
1187 const Property
* pProps
= mpStaticImpl
->getProperties().getConstArray();
1193 throw NoSuchElementException() ;
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
;
1204 sal_Int32 nConcept
= mpStaticImpl
->getPropertyConcepts().getConstArray()[ i
];
1205 if( (PropertyConcepts
& nConcept
) != 0 )
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
|
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
);
1276 sal_Int32 nConcept
= mpStaticImpl
->getMethodConcepts().getConstArray()[ i
];
1277 if( (MethodConcepts
& nConcept
) != 0 )
1279 const Reference
<XIdlMethod
>* pMethods
= mpStaticImpl
->getMethods().getConstArray();
1284 throw NoSuchMethodException();
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
;
1295 sal_Int32 nConcept
= mpStaticImpl
->getMethodConcepts().getConstArray()[ i
];
1296 if( (MethodConcepts
& nConcept
) != 0 )
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
|
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;
1351 // Methode mit Concepts ausgeben
1352 const Reference
< XIdlMethod
>& rxMethod
= pSourceMethods
[ i
];
1353 OString aNameStr
= OUStringToOString( rxMethod
->getName(), osl_getThreadTextEncoding() );
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() );
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
;
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() );
1420 // Methoden von XExactName
1421 OUString
ImplIntrospectionAccess::getExactName( const OUString
& rApproximateName
) throw( RuntimeException
)
1424 LowerToExactNameMap::iterator aIt
=
1425 mpStaticImpl
->maLowerToExactNameMap
.find( toLower( rApproximateName
) );
1426 if( !( aIt
== mpStaticImpl
->maLowerToExactNameMap
.end() ) )
1427 aRetStr
= (*aIt
).second
;
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
)
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
)
1475 sal_Int32 nCount1
= rObj1
.aIdlClasses
.getLength();
1476 sal_Int32 nCount2
= rObj2
.aIdlClasses
.getLength();
1477 if( nCount1
!= nCount2
)
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_
)
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
)
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 );
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;
1552 for( i
= 0 ; i
< nCount32
; i
++ )
1553 nId32
^= *(pBytesAsInt32Array
++);
1555 // XOR with remaining byte values
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
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
;
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(); }
1625 Sequence
< Type
> SAL_CALL
getTypes( ) throw( RuntimeException
);
1626 Sequence
<sal_Int8
> SAL_CALL
getImplementationId( ) throw( RuntimeException
);
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
);
1640 // some XComponent part from OComponentHelper
1641 virtual void SAL_CALL
dispose() throw(::com::sun::star::uno::RuntimeException
);
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
1654 ImplIntrospection::ImplIntrospection( const Reference
<XMultiServiceFactory
> & rXSMgr
)
1655 : OComponentHelper( m_mutex
)
1658 mnCacheEntryCount
= 0;
1659 mnTPCacheEntryCount
= 0;
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() );
1671 Reference
< XComponentContext
> xContext
;
1672 xProps
->getPropertyValue(
1673 OUString("DefaultContext") ) >>= xContext
;
1674 OSL_ASSERT( 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
;
1701 void ImplIntrospection::dispose() throw(::com::sun::star::uno::RuntimeException
)
1703 OComponentHelper::dispose();
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 //-----------------------------------------------------------------------------
1726 Any
ImplIntrospection::queryInterface( const Type
& rType
)
1727 throw(::com::sun::star::uno::RuntimeException
)
1729 Any
aRet( ::cppu::queryInterface(
1731 static_cast< XIntrospection
* >( this ),
1732 static_cast< XServiceInfo
* >( this ) ) );
1734 return (aRet
.hasValue() ? aRet
: OComponentHelper::queryInterface( rType
));
1738 Sequence
< Type
> ImplIntrospection::getTypes()
1739 throw( RuntimeException
)
1741 static OTypeCollection
* s_pTypes
= 0;
1744 MutexGuard
aGuard( Mutex::getGlobalMutex() );
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;
1763 MutexGuard
aGuard( Mutex::getGlobalMutex() );
1766 static OImplementationId s_aId
;
1770 return s_pId
->getImplementationId();
1775 OUString
ImplIntrospection::getImplementationName() throw()
1777 return getImplementationName_Static();
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
)
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
);
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
)
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
);
1839 rtl::Reference
< IntrospectionAccessStatic_Impl
> pStaticImpl( implInspect( aToInspectObj
) );
1840 if( pStaticImpl
.is() )
1841 xAccess
= new ImplIntrospectionAccess( aToInspectObj
, pStaticImpl
);
1847 //-----------------------------------------------------------------------------
1849 // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
1850 struct hashInterface_Impl
1852 size_t operator()(const void* p
) const
1858 struct eqInterface_Impl
1860 bool operator()(const void* p1
, const void* p2
) const
1862 return ( p1
== p2
);
1866 typedef boost::unordered_map
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
);
1888 OUString
sOWName( pTD
->pTypeName
);
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
);
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
1908 // Objekt untersuchen
1909 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1910 if( eType
!= TypeClass_INTERFACE
&& eType
!= TypeClass_STRUCT
&& eType
!= TypeClass_EXCEPTION
)
1913 Reference
<XInterface
> x
;
1914 if( eType
== TypeClass_INTERFACE
)
1916 // Interface aus dem Any besorgen
1917 x
= *(Reference
<XInterface
>*)aToInspectObj
.getValue();
1922 // Haben wir schon eine Cache-Instanz
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();
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
);
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
1972 xPropSetInfo
= xPropSet
->getPropertySetInfo();
1976 xImplClass
= TypeToIdlClass( aToInspectObj
.getValueType(), m_xSMgr
);
1979 if( xTypeProvider
.is() )
1981 Sequence
< sal_Int8
> aImpIdSeq
= xTypeProvider
->getImplementationId();
1982 sal_Int32 nIdLen
= aImpIdSeq
.getLength();
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() )
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
)
2009 aTPCache
.erase( toDelete
);
2012 mnTPCacheEntryCount
++;
2014 // Neuer Eintrage rein in die Table
2015 aKeySeq
.nHitCount
= 1;
2016 aTPCache
[ aKeySeq
] = pAccess
;
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() )
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
)
2052 aCache
.erase( toDelete
);
2055 mnCacheEntryCount
++;
2057 // Neuer Eintrage rein in die Table
2058 aKeySeq
.nHitCount
= 1;
2059 aCache
[ aKeySeq
] = pAccess
;
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
;
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
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
];
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
;
2151 SAL_WARN( "stoc", "Introspection: Property \"" <<
2152 aPropName
<< "\" found more than once in PropertySet" );
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
;
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 )
2206 aCheckedInterfacesMap
[ pIface
] = pIface
;
2209 //********************************************************************
2211 // 2. Fields als Properties registrieren
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
)
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() ) )
2247 // Neuer Eintrag in die Hashtable
2248 rPropNameMap
[ aPropName
] = rPropCount
;
2250 // Tabelle fuer XExactName pflegen
2251 rLowerToExactNameMap
[ toLower( aPropName
) ] = aPropName
;
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
++;
2267 //********************************************************************
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;
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
];
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
;
2319 if( aMethName
!= OUString("queryInterface") )
2321 rMethodConcept_i
|= MethodConcept::DANGEROUS
;
2326 else if( rxMethod_i
->getDeclaringClass()->equals( mxAggregationClass
) )
2328 if( aMethName
== "setDelegator" )
2330 rMethodConcept_i
|= MethodConcept::DANGEROUS
;
2334 else if( rxMethod_i
->getDeclaringClass()->equals( mxElementAccessClass
) )
2336 rMethodConcept_i
|= ( NAMECONTAINER
|
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 )
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 )
2373 // Haben wir den Namen schon?
2374 IntrospectionNameMap::iterator aIt
= rPropNameMap
.find( aPropName
);
2375 if( !( aIt
== rPropNameMap
.end() ) )
2379 String( "Introspection: Property \"" ) +
2380 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2381 String( "\" found more than once" ) );
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
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
)
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" ) )
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
) )
2443 // set-Methode muss void returnen
2444 Reference
<XIdlClass
> xSetRetType
= rxMethod_k
->getReturnType();
2445 if( xSetRetType
->getTypeClass() != TypeClass_VOID
)
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 )
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
;
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
) )
2496 // Welcher Listener?
2497 OUString aListenerName
= aMethName
.copy( 3, nStrLen
- aListenerStr
.getLength() - 3 );
2499 // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2501 // - Anzahl und Art der Parameter
2504 // Passende remove-Methode suchen, sonst gilt's nicht
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
)
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
) )
2525 // Ist es denn der gleiche Listener?
2526 if( aMethName2
.getLength() - aRemoveStr
.getLength() <= aListenerStr
.getLength() )
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
) )
2534 // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
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
;
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
)
2563 aMethName
= rxMethod_i
->getName();
2565 // Wenn der Name zu kurz ist, wird's sowieso nichts
2566 if( aMethName
.getLength() <= 3 )
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
)
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 )
2591 // Haben wir den Namen schon?
2592 IntrospectionNameMap::iterator aIt
= rPropNameMap
.find( aPropName
);
2593 if( !( aIt
== rPropNameMap
.end() ) )
2597 String( "Introspection: Property \"" ) +
2598 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2599 String( "\" found more than once" ) );
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
++;
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() )
2684 rMethodNameMap
[ aMethName2
] = iAllExportedMethod
;
2686 // Tabelle fuer XExactName pflegen
2687 rLowerToExactNameMap
[ toLower( aMethName2
) ] = aMethName2
;
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
) )
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();
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
;
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" );
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" );
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
)
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
;
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
++;
2853 // Property-Sequence auf die richtige Laenge bringen
2854 pAccess
->maAllPropertySeq
.realloc( pAccess
->mnPropCount
);
2859 //*************************************************************************
2860 Reference
< XInterface
> SAL_CALL
ImplIntrospection_CreateInstance( const Reference
< XMultiServiceFactory
> & rSMgr
)
2861 throw( RuntimeException
)
2863 Reference
< XInterface
> xService
= (OWeakObject
*)(OComponentHelper
*)new ImplIntrospection( rSMgr
);
2871 SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
introspection_component_getFactory(
2872 const sal_Char
* pImplName
, void * pServiceManager
,
2873 SAL_UNUSED_PARAMETER
void * )
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() ) );
2887 xFactory
->acquire();
2888 pRet
= xFactory
.get();
2897 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */