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 .
20 #include <sal/config.h>
29 #include <o3tl/any.hxx>
30 #include <osl/diagnose.h>
31 #include <osl/mutex.hxx>
32 #include <osl/thread.h>
33 #include <sal/log.hxx>
34 #include <cppuhelper/basemutex.hxx>
35 #include <cppuhelper/compbase.hxx>
36 #include <cppuhelper/queryinterface.hxx>
37 #include <cppuhelper/weak.hxx>
38 #include <cppuhelper/component.hxx>
39 #include <cppuhelper/factory.hxx>
40 #include <cppuhelper/implbase.hxx>
41 #include <cppuhelper/supportsservice.hxx>
42 #include <cppuhelper/typeprovider.hxx>
43 #include <comphelper/sequence.hxx>
44 #include <salhelper/simplereferenceobject.hxx>
46 #include <com/sun/star/uno/DeploymentException.hpp>
47 #include <com/sun/star/lang/NoSuchMethodException.hpp>
48 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
49 #include <com/sun/star/lang/XServiceInfo.hpp>
50 #include <com/sun/star/lang/XEventListener.hpp>
51 #include <com/sun/star/lang/XUnoTunnel.hpp>
52 #include <com/sun/star/reflection/XIdlReflection.hpp>
53 #include <com/sun/star/reflection/XIdlClass.hpp>
54 #include <com/sun/star/reflection/XIdlField2.hpp>
55 #include <com/sun/star/reflection/theCoreReflection.hpp>
56 #include <com/sun/star/beans/UnknownPropertyException.hpp>
57 #include <com/sun/star/beans/Property.hpp>
58 #include <com/sun/star/beans/XPropertySet.hpp>
59 #include <com/sun/star/beans/XFastPropertySet.hpp>
60 #include <com/sun/star/beans/XIntrospection.hpp>
61 #include <com/sun/star/beans/XIntrospectionAccess.hpp>
62 #include <com/sun/star/beans/XMaterialHolder.hpp>
63 #include <com/sun/star/beans/XExactName.hpp>
64 #include <com/sun/star/beans/PropertyAttribute.hpp>
65 #include <com/sun/star/beans/PropertyConcept.hpp>
66 #include <com/sun/star/beans/MethodConcept.hpp>
67 #include <com/sun/star/container/XNameContainer.hpp>
68 #include <com/sun/star/container/XIndexContainer.hpp>
69 #include <com/sun/star/container/XEnumerationAccess.hpp>
71 #include <rtl/ref.hxx>
72 #include <rtl/ustrbuf.hxx>
73 #include <rtl/strbuf.hxx>
74 #include <unordered_map>
76 using namespace css::uno
;
77 using namespace css::lang
;
78 using namespace css::reflection
;
79 using namespace css::container
;
80 using namespace css::registry
;
81 using namespace css::beans
;
82 using namespace css::beans::PropertyAttribute
;
83 using namespace css::beans::PropertyConcept
;
84 using namespace css::beans::MethodConcept
;
91 typedef WeakImplHelper
< XIntrospectionAccess
, XMaterialHolder
, XExactName
,
92 XPropertySet
, XFastPropertySet
, XPropertySetInfo
,
93 XNameContainer
, XIndexContainer
, XEnumerationAccess
,
94 XIdlArray
, XUnoTunnel
> IntrospectionAccessHelper
;
97 // Special value for Method-Concept, to be able to mark "normal" functions
98 #define MethodConcept_NORMAL_IMPL 0x80000000
101 // Method to assert, if a class is derived from another class
102 bool isDerivedFrom( const Reference
<XIdlClass
>& xToTestClass
, const Reference
<XIdlClass
>& xDerivedFromClass
)
104 Sequence
< Reference
<XIdlClass
> > aClassesSeq
= xToTestClass
->getSuperclasses();
105 const Reference
<XIdlClass
>* pClassesArray
= aClassesSeq
.getConstArray();
107 sal_Int32 nSuperClassCount
= aClassesSeq
.getLength();
108 for ( sal_Int32 i
= 0; i
< nSuperClassCount
; ++i
)
110 const Reference
<XIdlClass
>& rxClass
= pClassesArray
[i
];
112 if ( xDerivedFromClass
->equals( rxClass
) ||
113 isDerivedFrom( rxClass
, xDerivedFromClass
)
122 // *** Classification of Properties (no enum, to be able to use Sequence) ***
123 // Properties from a PropertySet-Interface
124 #define MAP_PROPERTY_SET 0
125 // Properties from Fields
127 // Properties that get described with get/set methods
129 // Properties with only a set method
130 #define MAP_SETONLY 3
133 // Increments by which the size of sequences get adjusted
134 #define ARRAY_SIZE_STEP 20
137 //*** IntrospectionAccessStatic_Impl ***
139 // Equals to the old IntrospectionAccessImpl, forms now a static
140 // part of the new Instance-related ImplIntrospectionAccess
142 // Hashtable for the search of names
143 typedef std::unordered_map
149 IntrospectionNameMap
;
152 // Hashtable to assign exact names to the Lower-Case
153 // converted names, for the support of XExactName
154 typedef std::unordered_map
163 class ImplIntrospectionAccess
;
164 class IntrospectionAccessStatic_Impl
: public salhelper::SimpleReferenceObject
166 friend class Implementation
;
167 friend class ImplIntrospectionAccess
;
169 // Holding CoreReflection
170 Reference
< XIdlReflection
> mxCoreReflection
;
172 // InterfaceSequences, to save additional information in a property
173 // for example the Field at MAP_FIELD, the get/set-Methods at MAP_GETSET, et cetera
174 std::vector
< Reference
<XInterface
> > aInterfaceSeq1
;
175 std::vector
< Reference
<XInterface
> > aInterfaceSeq2
;
177 // Hashtables for names
178 IntrospectionNameMap maPropertyNameMap
;
179 IntrospectionNameMap maMethodNameMap
;
180 LowerToExactNameMap maLowerToExactNameMap
;
182 // Vector of all Properties, also for delivering from getProperties()
183 std::vector
<Property
> maAllPropertySeq
;
185 // Mapping of properties to Access-Types
186 std::vector
<sal_Int16
> maMapTypeSeq
;
188 // Classification of found methods
189 std::vector
<sal_Int32
> maPropertyConceptSeq
;
191 // Number of Properties
192 sal_Int32 mnPropCount
;
194 // Number of Properties, which are assigned to particular concepts
195 //sal_Int32 mnDangerousPropCount;
196 sal_Int32 mnPropertySetPropCount
;
197 sal_Int32 mnAttributePropCount
;
198 sal_Int32 mnMethodPropCount
;
200 // Flags which indicate if various interfaces are present
202 bool mbElementAccess
;
205 bool mbNameContainer
;
208 bool mbIndexContainer
;
209 bool mbEnumerationAccess
;
213 // Original handles of FastPropertySets
214 std::unique_ptr
<sal_Int32
[]> mpOrgPropertyHandleArray
;
216 // MethodSequence, that accepts all methods
217 std::vector
< Reference
<XIdlMethod
> > maAllMethodSeq
;
219 // Classification of found methods
220 std::vector
<sal_Int32
> maMethodConceptSeq
;
223 sal_Int32 mnMethCount
;
225 // Sequence of Listener, that can be registered
226 std::vector
< Type
> maSupportedListenerSeq
;
228 // Helper-methods for adjusting sizes of Sequences
229 void checkPropertyArraysSize( sal_Int32 iNextIndex
);
230 static void checkInterfaceArraySize( std::vector
< Reference
<XInterface
> >& rSeq
, std::vector
<Reference
<XInterface
>>& rInterfaceVec
,
231 sal_Int32 iNextIndex
);
234 explicit IntrospectionAccessStatic_Impl( Reference
< XIdlReflection
> const & xCoreReflection_
);
235 sal_Int32
getPropertyIndex( const OUString
& aPropertyName
) const;
236 sal_Int32
getMethodIndex( const OUString
& aMethodName
) const;
238 // Methods of XIntrospectionAccess (OLD, now only Impl)
239 void setPropertyValue(const Any
& obj
, const OUString
& aPropertyName
, const Any
& aValue
) const;
240 // void setPropertyValue(Any& obj, const OUString& aPropertyName, const Any& aValue) const;
241 Any
getPropertyValue(const Any
& obj
, const OUString
& aPropertyName
) const;
242 void setPropertyValueByIndex(const Any
& obj
, sal_Int32 nIndex
, const Any
& aValue
) const;
243 // void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const;
244 Any
getPropertyValueByIndex(const Any
& obj
, sal_Int32 nIndex
) const;
246 const std::vector
<Property
>& getProperties() const { return maAllPropertySeq
; }
247 const std::vector
< Reference
<XIdlMethod
> >& getMethods() const { return maAllMethodSeq
; }
248 const std::vector
< Type
>& getSupportedListeners() const { return maSupportedListenerSeq
; }
249 const std::vector
<sal_Int32
>& getPropertyConcepts() const { return maPropertyConceptSeq
; }
250 const std::vector
<sal_Int32
>& getMethodConcepts() const { return maMethodConceptSeq
; }
255 IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference
< XIdlReflection
> const & xCoreReflection_
)
256 : mxCoreReflection( xCoreReflection_
)
258 aInterfaceSeq1
.resize( ARRAY_SIZE_STEP
);
259 aInterfaceSeq2
.resize( ARRAY_SIZE_STEP
);
262 maAllPropertySeq
.resize( ARRAY_SIZE_STEP
);
263 maMapTypeSeq
.resize( ARRAY_SIZE_STEP
);
264 maPropertyConceptSeq
.resize( ARRAY_SIZE_STEP
);
266 mbFastPropSet
= false;
267 mbElementAccess
= false;
268 mbNameAccess
= false;
269 mbNameReplace
= false;
270 mbNameContainer
= false;
271 mbIndexAccess
= false;
272 mbIndexReplace
= false;
273 mbIndexContainer
= false;
274 mbEnumerationAccess
= false;
278 mpOrgPropertyHandleArray
= nullptr;
281 //mnDangerousPropCount = 0;
282 mnPropertySetPropCount
= 0;
283 mnAttributePropCount
= 0;
284 mnMethodPropCount
= 0;
290 sal_Int32
IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString
& aPropertyName
) const
292 IntrospectionAccessStatic_Impl
* pThis
= const_cast<IntrospectionAccessStatic_Impl
*>(this);
293 IntrospectionNameMap::iterator aIt
= pThis
->maPropertyNameMap
.find( aPropertyName
);
294 if (aIt
!= pThis
->maPropertyNameMap
.end())
300 sal_Int32
IntrospectionAccessStatic_Impl::getMethodIndex( const OUString
& aMethodName
) const
302 IntrospectionAccessStatic_Impl
* pThis
= const_cast<IntrospectionAccessStatic_Impl
*>(this);
303 IntrospectionNameMap::iterator aIt
= pThis
->maMethodNameMap
.find( aMethodName
);
304 if (aIt
!= pThis
->maMethodNameMap
.end())
309 // #95159 Check if full qualified name matches
310 sal_Int32 nSearchFrom
= aMethodName
.getLength();
313 // Strategy: Search back until the first '_' is found
314 sal_Int32 nFound
= aMethodName
.lastIndexOf( '_', nSearchFrom
);
318 OUString aPureMethodName
= aMethodName
.copy( nFound
+ 1 );
320 aIt
= pThis
->maMethodNameMap
.find( aPureMethodName
);
321 if (aIt
!= pThis
->maMethodNameMap
.end())
323 // Check if it can be a type?
324 // Problem: Does not work if package names contain _ ?!
325 OUString aStr
= aMethodName
.copy( 0, nFound
);
326 OUString aTypeName
= aStr
.replace( '_', '.' );
327 Reference
< XIdlClass
> xClass
= mxCoreReflection
->forName( aTypeName
);
330 // If this is a valid class it could be the right method
332 // Could be the right method, type has to be checked
333 const sal_Int32 iHashResult
= aIt
->second
;
335 const Reference
<XIdlMethod
> xMethod
= maAllMethodSeq
[iHashResult
];
337 Reference
< XIdlClass
> xMethClass
= xMethod
->getDeclaringClass();
338 if( xClass
->equals( xMethClass
) )
344 // Could also be another method with the same name
345 // Iterate over all methods
346 size_t nLen
= maAllMethodSeq
.size();
347 for (size_t i
= 0; i
< nLen
; ++i
)
349 const Reference
<XIdlMethod
> xMethod2
= maAllMethodSeq
[ i
];
350 if( xMethod2
->getName() == aPureMethodName
)
352 Reference
< XIdlClass
> xMethClass2
= xMethod2
->getDeclaringClass();
354 if( xClass
->equals( xMethClass2
) )
364 nSearchFrom
= nFound
- 1;
365 if( nSearchFrom
< 0 )
371 void IntrospectionAccessStatic_Impl::setPropertyValue( const Any
& obj
, const OUString
& aPropertyName
, const Any
& aValue
) const
372 //void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const OUString& aPropertyName, const Any& aValue ) const
374 sal_Int32 i
= getPropertyIndex( aPropertyName
);
376 setPropertyValueByIndex( obj
, i
, aValue
);
378 throw UnknownPropertyException(aPropertyName
);
381 void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any
& obj
, sal_Int32 nSequenceIndex
, const Any
& aValue
) const
382 //void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
384 // Is the passed object something that fits?
385 Reference
<XInterface
> xInterface
;
386 if( !(obj
>>= xInterface
) )
388 TypeClass eObjType
= obj
.getValueType().getTypeClass();
389 if( nSequenceIndex
>= mnPropCount
)
390 throw IllegalArgumentException(
391 "IntrospectionAccessStatic_Impl::setPropertyValueByIndex(), index > propertyCount, " +
392 OUString::number(nSequenceIndex
) + " > " + OUString::number(mnPropCount
),
393 Reference
<XInterface
>(), 0);
394 if( eObjType
!= TypeClass_STRUCT
&& eObjType
!= TypeClass_EXCEPTION
)
395 throw IllegalArgumentException(
396 "IntrospectionAccessStatic_Impl::setPropertyValueByIndex(), expected struct or exception, got" +
397 obj
.getValueType().getTypeName(), Reference
<XInterface
>(), 0);
401 if( (maAllPropertySeq
[ nSequenceIndex
].Attributes
& READONLY
) != 0 )
403 throw UnknownPropertyException(
404 "IntrospectionAccessStatic_Impl::setPropertyValueByIndex(), property at index " + OUString::number(nSequenceIndex
) + " is readonly");
407 switch( maMapTypeSeq
[ nSequenceIndex
] )
409 case MAP_PROPERTY_SET
:
412 const Property
& rProp
= maAllPropertySeq
[ nSequenceIndex
];
414 // Convert Interface-Parameter to the correct type
415 bool bUseCopy
= false;
418 if( auto valInterface
= o3tl::tryAccess
<
419 css::uno::Reference
<css::uno::XInterface
>>(aValue
) )
421 Type aPropType
= rProp
.Type
;
422 OUString
aTypeName( aPropType
.getTypeName() );
423 Reference
< XIdlClass
> xPropClass
= mxCoreReflection
->forName( aTypeName
);
424 //Reference<XIdlClass> xPropClass = rProp.Type;
425 if( xPropClass
.is() && xPropClass
->getTypeClass() == TypeClass_INTERFACE
)
427 if( valInterface
->is() )
429 //Any queryInterface( const Type& rType );
430 aRealValue
= (*valInterface
)->queryInterface( aPropType
);
431 if( aRealValue
.hasValue() )
437 // Do we have a FastPropertySet and a valid Handle?
438 // CAUTION: At this point we exploit that the PropertySet
439 // gets queried at the beginning of the Introspection-Process.
440 sal_Int32 nOrgHandle
;
441 if( mbFastPropSet
&& ( nOrgHandle
= mpOrgPropertyHandleArray
[ nSequenceIndex
] ) != -1 )
443 // Retrieve PropertySet-Interface
444 Reference
<XFastPropertySet
> xFastPropSet
=
445 Reference
<XFastPropertySet
>::query( xInterface
);
446 if( xFastPropSet
.is() )
448 xFastPropSet
->setFastPropertyValue( nOrgHandle
, bUseCopy
? aRealValue
: aValue
);
452 // throw UnknownPropertyException
455 // else take the normal one
458 // Retrieve PropertySet-Interface
459 Reference
<XPropertySet
> xPropSet
=
460 Reference
<XPropertySet
>::query( xInterface
);
463 xPropSet
->setPropertyValue( rProp
.Name
, bUseCopy
? aRealValue
: aValue
);
467 // throw UnknownPropertyException
475 Reference
<XIdlField
> xField
= static_cast<XIdlField
*>(aInterfaceSeq1
[ nSequenceIndex
].get());
476 Reference
<XIdlField2
> xField2(xField
, UNO_QUERY
);
479 xField2
->set( (Any
&)obj
, aValue
);
480 // IllegalArgumentException
481 // NullPointerException
485 xField
->set( obj
, aValue
);
486 // IllegalArgumentException
487 // NullPointerException
491 // throw IllegalArgumentException();
500 Reference
<XIdlMethod
> xMethod
= static_cast<XIdlMethod
*>(aInterfaceSeq2
[ nSequenceIndex
].get());
503 Sequence
<Any
> args( 1 );
504 args
.getArray()[0] = aValue
;
505 xMethod
->invoke( obj
, args
);
509 // throw IllegalArgumentException();
516 Any
IntrospectionAccessStatic_Impl::getPropertyValue( const Any
& obj
, const OUString
& aPropertyName
) const
518 sal_Int32 i
= getPropertyIndex( aPropertyName
);
520 return getPropertyValueByIndex( obj
, i
);
522 throw UnknownPropertyException(aPropertyName
);
525 Any
IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any
& obj
, sal_Int32 nSequenceIndex
) const
529 // Is there anything suitable in the passed object?
530 Reference
<XInterface
> xInterface
;
531 if( !(obj
>>= xInterface
) )
533 TypeClass eObjType
= obj
.getValueType().getTypeClass();
534 if( nSequenceIndex
>= mnPropCount
|| ( eObjType
!= TypeClass_STRUCT
&& eObjType
!= TypeClass_EXCEPTION
) )
536 // throw IllegalArgumentException();
541 switch( maMapTypeSeq
[ nSequenceIndex
] )
543 case MAP_PROPERTY_SET
:
546 const Property
& rProp
= maAllPropertySeq
[ nSequenceIndex
];
548 // Do we have a FastPropertySet and a valid handle?
549 // NOTE: At this point is exploited that the PropertySet
550 // is queried at the beginning of introspection process.
551 sal_Int32 nOrgHandle
;
552 if( mbFastPropSet
&& ( nOrgHandle
= mpOrgPropertyHandleArray
[ nSequenceIndex
] ) != -1 )
554 // Fetch the PropertySet interface
555 Reference
<XFastPropertySet
> xFastPropSet
=
556 Reference
<XFastPropertySet
>::query( xInterface
);
557 if( xFastPropSet
.is() )
559 aRet
= xFastPropSet
->getFastPropertyValue( nOrgHandle
);
563 // throw UnknownPropertyException
567 // Otherwise use the normal one
570 // Fetch the PropertySet interface
571 Reference
<XPropertySet
> xPropSet
=
572 Reference
<XPropertySet
>::query( xInterface
);
575 aRet
= xPropSet
->getPropertyValue( rProp
.Name
);
579 // throw UnknownPropertyException
588 Reference
<XIdlField
> xField
= static_cast<XIdlField
*>(aInterfaceSeq1
[ nSequenceIndex
].get());
591 aRet
= xField
->get( obj
);
592 // IllegalArgumentException
593 // NullPointerException
597 // throw IllegalArgumentException();
606 Reference
<XIdlMethod
> xMethod
= static_cast<XIdlMethod
*>(aInterfaceSeq1
[ nSequenceIndex
].get());
610 aRet
= xMethod
->invoke( obj
, args
);
614 // throw IllegalArgumentException();
621 // Get method does not exist
622 // throw WriteOnlyPropertyException();
629 // Helper method to adjust the size of the vectors
630 void IntrospectionAccessStatic_Impl::checkPropertyArraysSize( sal_Int32 iNextIndex
)
632 sal_Int32 nLen
= (sal_Int32
)maAllPropertySeq
.size();
633 if( iNextIndex
>= nLen
)
635 maAllPropertySeq
.resize( nLen
+ ARRAY_SIZE_STEP
);
636 maMapTypeSeq
.resize( nLen
+ ARRAY_SIZE_STEP
);
637 maPropertyConceptSeq
.resize( nLen
+ ARRAY_SIZE_STEP
);
641 void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( std::vector
< Reference
<XInterface
> >& rSeq
,
642 std::vector
<Reference
<XInterface
>>& rInterfaceVec
, sal_Int32 iNextIndex
)
644 sal_Int32 nLen
= rSeq
.size();
645 if( iNextIndex
>= nLen
)
647 // Synchronize new size with ARRAY_SIZE_STEP
648 sal_Int32 nMissingSize
= iNextIndex
- nLen
+ 1;
649 sal_Int32 nSteps
= nMissingSize
/ ARRAY_SIZE_STEP
+ 1;
650 sal_Int32 nNewSize
= nLen
+ nSteps
* ARRAY_SIZE_STEP
;
652 rSeq
.resize( nNewSize
);
653 rInterfaceVec
= rSeq
;
658 //*** ImplIntrospectionAccess ***
661 // New Impl class as part of the introspection conversion to instance-bound
662 // Introspection with property access via XPropertySet. The old class
663 // ImplIntrospectionAccess lives on as IntrospectionAccessStatic_Impl
664 class ImplIntrospectionAccess
: public IntrospectionAccessHelper
666 friend class Implementation
;
668 // Object under examination
669 Any maInspectedObject
;
672 Reference
<XInterface
> mxIface
;
674 // Static introspection data
675 rtl::Reference
< IntrospectionAccessStatic_Impl
> mpStaticImpl
;
677 // Last Sequence that came with getProperties (optimization)
678 Sequence
<Property
> maLastPropertySeq
;
679 sal_Int32 mnLastPropertyConcept
;
681 // Last Sequence that came with getMethods (optimization)
682 Sequence
<Reference
<XIdlMethod
> > maLastMethodSeq
;
683 sal_Int32 mnLastMethodConcept
;
685 // Guards the caching of queried interfaces
688 // Original interfaces of the objects
689 Reference
<XElementAccess
> mxObjElementAccess
;
690 Reference
<XNameContainer
> mxObjNameContainer
;
691 Reference
<XNameReplace
> mxObjNameReplace
;
692 Reference
<XNameAccess
> mxObjNameAccess
;
693 Reference
<XIndexContainer
> mxObjIndexContainer
;
694 Reference
<XIndexReplace
> mxObjIndexReplace
;
695 Reference
<XIndexAccess
> mxObjIndexAccess
;
696 Reference
<XEnumerationAccess
> mxObjEnumerationAccess
;
697 Reference
<XIdlArray
> mxObjIdlArray
;
699 Reference
<XElementAccess
> getXElementAccess();
700 Reference
<XNameContainer
> getXNameContainer();
701 Reference
<XNameReplace
> getXNameReplace();
702 Reference
<XNameAccess
> getXNameAccess();
703 Reference
<XIndexContainer
> getXIndexContainer();
704 Reference
<XIndexReplace
> getXIndexReplace();
705 Reference
<XIndexAccess
> getXIndexAccess();
706 Reference
<XEnumerationAccess
> getXEnumerationAccess();
707 Reference
<XIdlArray
> getXIdlArray();
709 void cacheXNameContainer();
710 void cacheXIndexContainer();
713 ImplIntrospectionAccess( const Any
& obj
, rtl::Reference
< IntrospectionAccessStatic_Impl
> const & pStaticImpl_
);
715 // Methods from XIntrospectionAccess
716 virtual sal_Int32 SAL_CALL
getSuppliedMethodConcepts() override
;
717 virtual sal_Int32 SAL_CALL
getSuppliedPropertyConcepts() override
;
718 virtual Property SAL_CALL
getProperty(const OUString
& Name
, sal_Int32 PropertyConcepts
) override
;
719 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
, sal_Int32 PropertyConcepts
) override
;
720 virtual Sequence
< Property
> SAL_CALL
getProperties(sal_Int32 PropertyConcepts
) override
;
721 virtual Reference
<XIdlMethod
> SAL_CALL
getMethod(const OUString
& Name
, sal_Int32 MethodConcepts
) override
;
722 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
, sal_Int32 MethodConcepts
) override
;
723 virtual Sequence
< Reference
<XIdlMethod
> > SAL_CALL
getMethods(sal_Int32 MethodConcepts
) override
;
724 virtual Sequence
< Type
> SAL_CALL
getSupportedListeners() override
;
725 using OWeakObject::queryAdapter
;
726 virtual Reference
<XInterface
> SAL_CALL
queryAdapter( const Type
& rType
) override
;
728 // Methods from XMaterialHolder
729 virtual Any SAL_CALL
getMaterial() override
;
731 // Methods from XExactName
732 virtual OUString SAL_CALL
getExactName( const OUString
& rApproximateName
) override
;
734 // Methods from XInterface
735 virtual Any SAL_CALL
queryInterface( const Type
& rType
) override
;
736 virtual void SAL_CALL
acquire() throw() override
{ OWeakObject::acquire(); }
737 virtual void SAL_CALL
release() throw() override
{ OWeakObject::release(); }
739 // Methods from XPropertySet
740 virtual Reference
<XPropertySetInfo
> SAL_CALL
getPropertySetInfo() override
;
741 virtual void SAL_CALL
setPropertyValue(const OUString
& aPropertyName
, const Any
& aValue
) override
;
742 virtual Any SAL_CALL
getPropertyValue(const OUString
& aPropertyName
) override
;
743 virtual void SAL_CALL
addPropertyChangeListener(const OUString
& aPropertyName
, const Reference
<XPropertyChangeListener
>& aListener
) override
;
744 virtual void SAL_CALL
removePropertyChangeListener(const OUString
& aPropertyName
, const Reference
<XPropertyChangeListener
>& aListener
) override
;
745 virtual void SAL_CALL
addVetoableChangeListener(const OUString
& aPropertyName
, const Reference
<XVetoableChangeListener
>& aListener
) override
;
746 virtual void SAL_CALL
removeVetoableChangeListener(const OUString
& aPropertyName
, const Reference
<XVetoableChangeListener
>& aListener
) override
;
748 // Methods from XFastPropertySet
749 virtual void SAL_CALL
setFastPropertyValue(sal_Int32 nHandle
, const Any
& aValue
) override
;
750 virtual Any SAL_CALL
getFastPropertyValue(sal_Int32 nHandle
) override
;
752 // Methods from XPropertySetInfo
753 virtual Sequence
< Property
> SAL_CALL
getProperties() override
;
754 virtual Property SAL_CALL
getPropertyByName(const OUString
& Name
) override
;
755 virtual sal_Bool SAL_CALL
hasPropertyByName(const OUString
& Name
) override
;
757 // Methods from XElementAccess
758 virtual Type SAL_CALL
getElementType() override
;
759 virtual sal_Bool SAL_CALL
hasElements() override
;
761 // Methods from XNameAccess
762 virtual Any SAL_CALL
getByName(const OUString
& Name
) override
;
763 virtual Sequence
< OUString
> SAL_CALL
getElementNames() override
;
764 virtual sal_Bool SAL_CALL
hasByName(const OUString
& Name
) override
;
766 // Methods from XNameReplace
767 virtual void SAL_CALL
replaceByName(const OUString
& Name
, const Any
& Element
) override
;
769 // Methods from XNameContainer
770 virtual void SAL_CALL
insertByName(const OUString
& Name
, const Any
& Element
) override
;
771 virtual void SAL_CALL
removeByName(const OUString
& Name
) override
;
773 // Methods from XIndexAccess
774 virtual sal_Int32 SAL_CALL
getCount() override
;
775 virtual Any SAL_CALL
getByIndex(sal_Int32 Index
) override
;
777 // Methods from XIndexReplace
778 virtual void SAL_CALL
replaceByIndex(sal_Int32 Index
, const Any
& Element
) override
;
780 // Methods from XIndexContainer
781 virtual void SAL_CALL
insertByIndex(sal_Int32 Index
, const Any
& Element
) override
;
782 virtual void SAL_CALL
removeByIndex(sal_Int32 Index
) override
;
784 // Methods from XEnumerationAccess
785 virtual Reference
<XEnumeration
> SAL_CALL
createEnumeration() override
;
787 // Methods from XIdlArray
788 virtual void SAL_CALL
realloc(Any
& array
, sal_Int32 length
) override
;
789 virtual sal_Int32 SAL_CALL
getLen(const Any
& array
) override
;
790 virtual Any SAL_CALL
get(const Any
& array
, sal_Int32 index
) override
;
791 virtual void SAL_CALL
set(Any
& array
, sal_Int32 index
, const Any
& value
) override
;
793 // Methods from XUnoTunnel
794 virtual sal_Int64 SAL_CALL
getSomething( const Sequence
< sal_Int8
>& aIdentifier
) override
;
797 ImplIntrospectionAccess::ImplIntrospectionAccess
798 ( const Any
& obj
, rtl::Reference
< IntrospectionAccessStatic_Impl
> const & pStaticImpl_
)
799 : maInspectedObject( obj
), mpStaticImpl( pStaticImpl_
) //, maAdapter()
801 // Save object as an interface if possible
802 maInspectedObject
>>= mxIface
;
804 mnLastPropertyConcept
= -1;
805 mnLastMethodConcept
= -1;
808 Reference
<XElementAccess
> ImplIntrospectionAccess::getXElementAccess()
810 ResettableGuard
< Mutex
> aGuard( m_aMutex
);
812 if( !mxObjElementAccess
.is() )
815 Reference
<XElementAccess
> xElementAccess( mxIface
, UNO_QUERY
);
817 if( !mxObjElementAccess
.is() )
818 mxObjElementAccess
= xElementAccess
;
820 return mxObjElementAccess
;
823 void ImplIntrospectionAccess::cacheXNameContainer()
825 Reference
<XNameContainer
> xNameContainer
;
826 Reference
<XNameReplace
> xNameReplace
;
827 Reference
<XNameAccess
> xNameAccess
;
828 if (mpStaticImpl
->mbNameContainer
)
830 xNameContainer
.set( mxIface
, UNO_QUERY
);
831 xNameReplace
.set( xNameContainer
, UNO_QUERY
);
832 xNameAccess
.set( xNameContainer
, UNO_QUERY
);
834 else if (mpStaticImpl
->mbNameReplace
)
836 xNameReplace
.set( mxIface
, UNO_QUERY
);
837 xNameAccess
.set( xNameReplace
, UNO_QUERY
);
839 else if (mpStaticImpl
->mbNameAccess
)
841 xNameAccess
.set( mxIface
, UNO_QUERY
);
845 MutexGuard
aGuard( m_aMutex
);
846 if( !mxObjNameContainer
.is() )
847 mxObjNameContainer
= xNameContainer
;
848 if( !mxObjNameReplace
.is() )
849 mxObjNameReplace
= xNameReplace
;
850 if( !mxObjNameAccess
.is() )
851 mxObjNameAccess
= xNameAccess
;
855 Reference
<XNameContainer
> ImplIntrospectionAccess::getXNameContainer()
857 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
859 if( !mxObjNameContainer
.is() )
862 cacheXNameContainer();
864 return mxObjNameContainer
;
867 Reference
<XNameReplace
> ImplIntrospectionAccess::getXNameReplace()
869 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
871 if( !mxObjNameReplace
.is() )
874 cacheXNameContainer();
876 return mxObjNameReplace
;
879 Reference
<XNameAccess
> ImplIntrospectionAccess::getXNameAccess()
881 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
883 if( !mxObjNameAccess
.is() )
886 cacheXNameContainer();
888 return mxObjNameAccess
;
891 void ImplIntrospectionAccess::cacheXIndexContainer()
893 Reference
<XIndexContainer
> xIndexContainer
;
894 Reference
<XIndexReplace
> xIndexReplace
;
895 Reference
<XIndexAccess
> xIndexAccess
;
896 if (mpStaticImpl
->mbIndexContainer
)
898 xIndexContainer
.set( mxIface
, UNO_QUERY
);
899 xIndexReplace
.set( xIndexContainer
, UNO_QUERY
);
900 xIndexAccess
.set( xIndexContainer
, UNO_QUERY
);
902 else if (mpStaticImpl
->mbIndexReplace
)
904 xIndexReplace
.set( mxIface
, UNO_QUERY
);
905 xIndexAccess
.set( xIndexReplace
, UNO_QUERY
);
907 else if (mpStaticImpl
->mbIndexAccess
)
909 xIndexAccess
.set( mxIface
, UNO_QUERY
);
913 MutexGuard
aGuard( m_aMutex
);
914 if( !mxObjIndexContainer
.is() )
915 mxObjIndexContainer
= xIndexContainer
;
916 if( !mxObjIndexReplace
.is() )
917 mxObjIndexReplace
= xIndexReplace
;
918 if( !mxObjIndexAccess
.is() )
919 mxObjIndexAccess
= xIndexAccess
;
923 Reference
<XIndexContainer
> ImplIntrospectionAccess::getXIndexContainer()
925 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
927 if( !mxObjIndexContainer
.is() )
930 cacheXIndexContainer();
932 return mxObjIndexContainer
;
935 Reference
<XIndexReplace
> ImplIntrospectionAccess::getXIndexReplace()
937 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
939 if( !mxObjIndexReplace
.is() )
942 cacheXIndexContainer();
944 return mxObjIndexReplace
;
947 Reference
<XIndexAccess
> ImplIntrospectionAccess::getXIndexAccess()
949 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
951 if( !mxObjIndexAccess
.is() )
954 cacheXIndexContainer();
956 return mxObjIndexAccess
;
959 Reference
<XEnumerationAccess
> ImplIntrospectionAccess::getXEnumerationAccess()
961 ResettableGuard
< Mutex
> aGuard( m_aMutex
);
963 if( !mxObjEnumerationAccess
.is() )
966 Reference
<XEnumerationAccess
> xEnumerationAccess( mxIface
, UNO_QUERY
);
968 if( !mxObjEnumerationAccess
.is() )
969 mxObjEnumerationAccess
= xEnumerationAccess
;
971 return mxObjEnumerationAccess
;
974 Reference
<XIdlArray
> ImplIntrospectionAccess::getXIdlArray()
976 ResettableGuard
< Mutex
> aGuard( m_aMutex
);
978 if( !mxObjIdlArray
.is() )
981 Reference
<XIdlArray
> xIdlArray( mxIface
, UNO_QUERY
);
983 if( !mxObjIdlArray
.is() )
984 mxObjIdlArray
= xIdlArray
;
986 return mxObjIdlArray
;
989 // Methods from XInterface
990 Any SAL_CALL
ImplIntrospectionAccess::queryInterface( const Type
& rType
)
992 Any
aRet( ::cppu::queryInterface(
994 static_cast< XIntrospectionAccess
* >( this ),
995 static_cast< XMaterialHolder
* >( this ),
996 static_cast< XExactName
* >( this ),
997 static_cast< XPropertySet
* >( this ),
998 static_cast< XFastPropertySet
* >( this ),
999 static_cast< XPropertySetInfo
* >( this ) ) );
1000 if( !aRet
.hasValue() )
1001 aRet
= OWeakObject::queryInterface( rType
);
1003 if( !aRet
.hasValue() )
1005 // Wrapper for the object interfaces
1006 if( ( mpStaticImpl
->mbElementAccess
&& (aRet
= ::cppu::queryInterface
1007 ( rType
, static_cast< XElementAccess
* >( static_cast< XNameAccess
* >( this ) ) ) ).hasValue() )
1008 || ( mpStaticImpl
->mbNameAccess
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XNameAccess
* >( this ) ) ).hasValue() )
1009 || ( mpStaticImpl
->mbNameReplace
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XNameReplace
* >( this ) ) ).hasValue() )
1010 || ( mpStaticImpl
->mbNameContainer
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XNameContainer
* >( this ) ) ).hasValue() )
1011 || ( mpStaticImpl
->mbIndexAccess
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XIndexAccess
* >( this ) ) ).hasValue() )
1012 || ( mpStaticImpl
->mbIndexReplace
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XIndexReplace
* >( this ) ) ).hasValue() )
1013 || ( mpStaticImpl
->mbIndexContainer
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XIndexContainer
* >( this ) ) ).hasValue() )
1014 || ( mpStaticImpl
->mbEnumerationAccess
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XEnumerationAccess
* >( this ) ) ).hasValue() )
1015 || ( mpStaticImpl
->mbIdlArray
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XIdlArray
* >( this ) ) ).hasValue() )
1016 || ( mpStaticImpl
->mbUnoTunnel
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XUnoTunnel
* >( this ) ) ).hasValue() )
1025 //*** Implementation of ImplIntrospectionAdapter ***
1028 // Methods from XPropertySet
1029 Reference
<XPropertySetInfo
> ImplIntrospectionAccess::getPropertySetInfo()
1031 return static_cast<XPropertySetInfo
*>(this);
1034 void ImplIntrospectionAccess::setPropertyValue(const OUString
& aPropertyName
, const Any
& aValue
)
1036 mpStaticImpl
->setPropertyValue( maInspectedObject
, aPropertyName
, aValue
);
1039 Any
ImplIntrospectionAccess::getPropertyValue(const OUString
& aPropertyName
)
1041 return mpStaticImpl
->getPropertyValue( maInspectedObject
, aPropertyName
);
1044 void ImplIntrospectionAccess::addPropertyChangeListener(const OUString
& aPropertyName
, const Reference
<XPropertyChangeListener
>& aListener
)
1048 Reference
<XPropertySet
> xPropSet
=
1049 Reference
<XPropertySet
>::query( mxIface
);
1050 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
1052 xPropSet
->addPropertyChangeListener(aPropertyName
, aListener
);
1056 void ImplIntrospectionAccess::removePropertyChangeListener(const OUString
& aPropertyName
, const Reference
<XPropertyChangeListener
>& aListener
)
1060 Reference
<XPropertySet
> xPropSet
=
1061 Reference
<XPropertySet
>::query( mxIface
);
1062 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
1064 xPropSet
->removePropertyChangeListener(aPropertyName
, aListener
);
1068 void ImplIntrospectionAccess::addVetoableChangeListener(const OUString
& aPropertyName
, const Reference
<XVetoableChangeListener
>& aListener
)
1072 Reference
<XPropertySet
> xPropSet
=
1073 Reference
<XPropertySet
>::query( mxIface
);
1074 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
1076 xPropSet
->addVetoableChangeListener(aPropertyName
, aListener
);
1080 void ImplIntrospectionAccess::removeVetoableChangeListener(const OUString
& aPropertyName
, const Reference
<XVetoableChangeListener
>& aListener
)
1084 Reference
<XPropertySet
> xPropSet
=
1085 Reference
<XPropertySet
>::query( mxIface
);
1087 xPropSet
->removeVetoableChangeListener(aPropertyName
, aListener
);
1092 // Methods from XFastPropertySet
1093 void ImplIntrospectionAccess::setFastPropertyValue(sal_Int32
, const Any
&)
1097 Any
ImplIntrospectionAccess::getFastPropertyValue(sal_Int32
)
1102 // Methods from XPropertySetInfo
1103 Sequence
< Property
> ImplIntrospectionAccess::getProperties()
1105 return comphelper::containerToSequence(mpStaticImpl
->getProperties());
1108 Property
ImplIntrospectionAccess::getPropertyByName(const OUString
& Name
)
1110 return getProperty( Name
, PropertyConcept::ALL
);
1113 sal_Bool
ImplIntrospectionAccess::hasPropertyByName(const OUString
& Name
)
1115 return hasProperty( Name
, PropertyConcept::ALL
);
1118 // Methods from XElementAccess
1119 Type
ImplIntrospectionAccess::getElementType()
1121 return getXElementAccess()->getElementType();
1124 sal_Bool
ImplIntrospectionAccess::hasElements()
1126 return getXElementAccess()->hasElements();
1129 // Methods from XNameAccess
1130 Any
ImplIntrospectionAccess::getByName(const OUString
& Name
)
1132 return getXNameAccess()->getByName( Name
);
1135 Sequence
< OUString
> ImplIntrospectionAccess::getElementNames()
1137 return getXNameAccess()->getElementNames();
1140 sal_Bool
ImplIntrospectionAccess::hasByName(const OUString
& Name
)
1142 return getXNameAccess()->hasByName( Name
);
1145 // Methods from XNameContainer
1146 void ImplIntrospectionAccess::insertByName(const OUString
& Name
, const Any
& Element
)
1148 getXNameContainer()->insertByName( Name
, Element
);
1151 void ImplIntrospectionAccess::replaceByName(const OUString
& Name
, const Any
& Element
)
1153 getXNameReplace()->replaceByName( Name
, Element
);
1156 void ImplIntrospectionAccess::removeByName(const OUString
& Name
)
1158 getXNameContainer()->removeByName( Name
);
1161 // Methods from XIndexAccess
1162 // Already in XNameAccess: virtual Reference<XIdlClass> getElementType() const
1163 sal_Int32
ImplIntrospectionAccess::getCount()
1165 return getXIndexAccess()->getCount();
1168 Any
ImplIntrospectionAccess::getByIndex(sal_Int32 Index
)
1170 return getXIndexAccess()->getByIndex( Index
);
1173 // Methods from XIndexContainer
1174 void ImplIntrospectionAccess::insertByIndex(sal_Int32 Index
, const Any
& Element
)
1176 getXIndexContainer()->insertByIndex( Index
, Element
);
1179 void ImplIntrospectionAccess::replaceByIndex(sal_Int32 Index
, const Any
& Element
)
1181 getXIndexReplace()->replaceByIndex( Index
, Element
);
1184 void ImplIntrospectionAccess::removeByIndex(sal_Int32 Index
)
1186 getXIndexContainer()->removeByIndex( Index
);
1189 // Methods from XEnumerationAccess
1190 // Already in XNameAccess: virtual Reference<XIdlClass> getElementType() const;
1191 Reference
<XEnumeration
> ImplIntrospectionAccess::createEnumeration()
1193 return getXEnumerationAccess()->createEnumeration();
1196 // Methods from XIdlArray
1197 void ImplIntrospectionAccess::realloc(Any
& array
, sal_Int32 length
)
1199 getXIdlArray()->realloc( array
, length
);
1202 sal_Int32
ImplIntrospectionAccess::getLen(const Any
& array
)
1204 return getXIdlArray()->getLen( array
);
1207 Any
ImplIntrospectionAccess::get(const Any
& array
, sal_Int32 index
)
1209 return getXIdlArray()->get( array
, index
);
1212 void ImplIntrospectionAccess::set(Any
& array
, sal_Int32 index
, const Any
& value
)
1214 getXIdlArray()->set( array
, index
, value
);
1217 // Methods from XUnoTunnel
1218 sal_Int64
ImplIntrospectionAccess::getSomething( const Sequence
< sal_Int8
>& aIdentifier
)
1220 return Reference
<XUnoTunnel
>::query( mxIface
)->getSomething( aIdentifier
);
1224 //*** Implementation of ImplIntrospectionAccess ***
1226 // Methods from XIntrospectionAccess
1227 sal_Int32
ImplIntrospectionAccess::getSuppliedMethodConcepts()
1229 return MethodConcept::DANGEROUS
|
1237 sal_Int32
ImplIntrospectionAccess::getSuppliedPropertyConcepts()
1239 return PropertyConcept::DANGEROUS
|
1245 Property
ImplIntrospectionAccess::getProperty(const OUString
& Name
, sal_Int32 PropertyConcepts
)
1248 sal_Int32 i
= mpStaticImpl
->getPropertyIndex( Name
);
1249 bool bFound
= false;
1252 sal_Int32 nConcept
= mpStaticImpl
->getPropertyConcepts()[ i
];
1253 if( (PropertyConcepts
& nConcept
) != 0 )
1255 aRet
= mpStaticImpl
->getProperties()[ i
];
1260 throw NoSuchElementException(Name
);
1264 sal_Bool
ImplIntrospectionAccess::hasProperty(const OUString
& Name
, sal_Int32 PropertyConcepts
)
1266 sal_Int32 i
= mpStaticImpl
->getPropertyIndex( Name
);
1270 sal_Int32 nConcept
= mpStaticImpl
->getPropertyConcepts()[ i
];
1271 if( (PropertyConcepts
& nConcept
) != 0 )
1277 Sequence
< Property
> ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts
)
1279 // If all supported concepts are required, simply pass through the sequence
1280 sal_Int32 nAllSupportedMask
= PROPERTYSET
|
1283 if( ( PropertyConcepts
& nAllSupportedMask
) == nAllSupportedMask
)
1285 return comphelper::containerToSequence(mpStaticImpl
->getProperties());
1288 // Same sequence as last time?
1289 if( mnLastPropertyConcept
== PropertyConcepts
)
1291 return maLastPropertySeq
;
1294 // Number of properties to be delivered
1295 sal_Int32 nCount
= 0;
1297 // There are currently no DANGEROUS properties
1298 // if( PropertyConcepts & DANGEROUS )
1299 // nCount += mpStaticImpl->mnDangerousPropCount;
1300 if( PropertyConcepts
& PROPERTYSET
)
1301 nCount
+= mpStaticImpl
->mnPropertySetPropCount
;
1302 if( PropertyConcepts
& ATTRIBUTES
)
1303 nCount
+= mpStaticImpl
->mnAttributePropCount
;
1304 if( PropertyConcepts
& METHODS
)
1305 nCount
+= mpStaticImpl
->mnMethodPropCount
;
1307 // Realloc sequence according to the required number
1308 maLastPropertySeq
.realloc( nCount
);
1309 Property
* pDestProps
= maLastPropertySeq
.getArray();
1311 // Go through all the properties and apply according to the concept
1312 const std::vector
<Property
>& rPropSeq
= mpStaticImpl
->getProperties();
1313 const std::vector
<sal_Int32
>& rConcepts
= mpStaticImpl
->getPropertyConcepts();
1314 sal_Int32 nLen
= (sal_Int32
)rPropSeq
.size();
1316 sal_Int32 iDest
= 0;
1317 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
1319 sal_Int32 nConcept
= rConcepts
[ i
];
1320 if( nConcept
& PropertyConcepts
)
1321 pDestProps
[ iDest
++ ] = rPropSeq
[ i
];
1324 // Remember PropertyConcept representing maLastPropertySeq
1325 mnLastPropertyConcept
= PropertyConcepts
;
1327 // Supply assembled Sequence
1328 return maLastPropertySeq
;
1331 Reference
<XIdlMethod
> ImplIntrospectionAccess::getMethod(const OUString
& Name
, sal_Int32 MethodConcepts
)
1333 Reference
<XIdlMethod
> xRet
;
1334 sal_Int32 i
= mpStaticImpl
->getMethodIndex( Name
);
1338 sal_Int32 nConcept
= mpStaticImpl
->getMethodConcepts()[ i
];
1339 if( (MethodConcepts
& nConcept
) != 0 )
1341 xRet
= mpStaticImpl
->getMethods()[i
];
1345 throw NoSuchMethodException(Name
);
1349 sal_Bool
ImplIntrospectionAccess::hasMethod(const OUString
& Name
, sal_Int32 MethodConcepts
)
1351 sal_Int32 i
= mpStaticImpl
->getMethodIndex( Name
);
1355 sal_Int32 nConcept
= mpStaticImpl
->getMethodConcepts()[ i
];
1356 if( (MethodConcepts
& nConcept
) != 0 )
1362 Sequence
< Reference
<XIdlMethod
> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts
)
1364 // If all supported concepts are required, simply pass through the sequence
1365 sal_Int32 nAllSupportedMask
= MethodConcept::DANGEROUS
|
1371 MethodConcept_NORMAL_IMPL
;
1372 if( ( MethodConcepts
& nAllSupportedMask
) == nAllSupportedMask
)
1374 return comphelper::containerToSequence(mpStaticImpl
->getMethods());
1377 // Same sequence as last time?
1378 if( mnLastMethodConcept
== MethodConcepts
)
1380 return maLastMethodSeq
;
1383 // Get method sequences
1384 const std::vector
< Reference
<XIdlMethod
> >& aMethodSeq
= mpStaticImpl
->getMethods();
1385 sal_Int32 nLen
= (sal_Int32
)aMethodSeq
.size();
1387 // Realloc sequence according to the required number
1388 // Unlike Properties, the number can not be determined by counters in
1389 // inspect() beforehand, since methods can belong to several concepts
1390 maLastMethodSeq
.realloc( nLen
);
1391 Reference
<XIdlMethod
>* pDestMethods
= maLastMethodSeq
.getArray();
1393 // Go through all the methods and apply according to the concept
1394 sal_Int32 iDest
= 0;
1395 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
1397 sal_Int32 nConcept
= mpStaticImpl
->getMethodConcepts()[ i
];
1398 if( nConcept
& MethodConcepts
)
1399 pDestMethods
[ iDest
++ ] = aMethodSeq
[ i
];
1402 // Bring to the correct length
1403 maLastMethodSeq
.realloc( iDest
);
1405 // Remember MethodConcept representing maLastMethodSeq
1406 mnLastMethodConcept
= MethodConcepts
;
1408 // Supply assembled Sequence
1409 return maLastMethodSeq
;
1412 Sequence
< Type
> ImplIntrospectionAccess::getSupportedListeners()
1414 return comphelper::containerToSequence(mpStaticImpl
->getSupportedListeners());
1417 Reference
<XInterface
> SAL_CALL
ImplIntrospectionAccess::queryAdapter( const Type
& rType
)
1419 Reference
<XInterface
> xRet
;
1420 if( rType
== cppu::UnoType
<XInterface
>::get()
1421 || rType
== cppu::UnoType
<XPropertySet
>::get()
1422 || rType
== cppu::UnoType
<XFastPropertySet
>::get()
1423 || rType
== cppu::UnoType
<XPropertySetInfo
>::get()
1424 || rType
== cppu::UnoType
<XElementAccess
>::get()
1425 || rType
== cppu::UnoType
<XNameAccess
>::get()
1426 || rType
== cppu::UnoType
<XNameReplace
>::get()
1427 || rType
== cppu::UnoType
<XNameContainer
>::get()
1428 || rType
== cppu::UnoType
<XIndexAccess
>::get()
1429 || rType
== cppu::UnoType
<XIndexReplace
>::get()
1430 || rType
== cppu::UnoType
<XIndexContainer
>::get()
1431 || rType
== cppu::UnoType
<XEnumerationAccess
>::get()
1432 || rType
== cppu::UnoType
<XIdlArray
>::get()
1433 || rType
== cppu::UnoType
<XUnoTunnel
>::get() )
1435 queryInterface( rType
) >>= xRet
;
1440 // Methods from XMaterialHolder
1441 Any
ImplIntrospectionAccess::getMaterial()
1443 return maInspectedObject
;
1446 // Methods from XExactName
1447 OUString
ImplIntrospectionAccess::getExactName( const OUString
& rApproximateName
)
1450 LowerToExactNameMap::iterator aIt
=
1451 mpStaticImpl
->maLowerToExactNameMap
.find( rApproximateName
.toAsciiLowerCase() );
1452 if (aIt
!= mpStaticImpl
->maLowerToExactNameMap
.end())
1453 aRetStr
= (*aIt
).second
;
1459 css::uno::Reference
<css::beans::XPropertySetInfo
> const & theProperties
,
1460 std::vector
<css::uno::Type
> const & theTypes
):
1461 properties(theProperties
)
1463 //TODO: Could even sort the types lexicographically first, to increase
1464 // the chance of matches between different implementations' getTypes(),
1465 // but the old scheme of using getImplementationId() would have missed
1466 // those matches, too:
1468 for (const css::uno::Type
& rType
: theTypes
) {
1469 b
.append(rType
.getTypeName());
1470 b
.append('*'); // arbitrary delimiter not used by type grammar
1472 types
= b
.makeStringAndClear();
1475 css::uno::Reference
<css::beans::XPropertySetInfo
> properties
;
1479 struct TypeKeyLess
{
1480 bool operator ()(TypeKey
const & key1
, TypeKey
const & key2
) const {
1481 if (key1
.properties
.get() < key2
.properties
.get()) {
1484 if (key1
.properties
.get() > key2
.properties
.get()) {
1487 return key1
.types
< key2
.types
;
1491 template<typename Key
, typename Less
> class Cache
{
1493 rtl::Reference
<IntrospectionAccessStatic_Impl
> find(Key
const & key
) const {
1494 typename
Map::const_iterator
i(map_
.find(key
));
1495 if (i
== map_
.end()) {
1496 return rtl::Reference
<IntrospectionAccessStatic_Impl
>();
1498 if (i
->second
.hits
< std::numeric_limits
<unsigned>::max()) {
1501 assert(i
->second
.access
.is());
1502 return i
->second
.access
;
1508 rtl::Reference
<IntrospectionAccessStatic_Impl
> const & access
)
1510 assert(access
.is());
1511 typename
Map::size_type
const MAX
= 100;
1512 assert(map_
.size() <= MAX
);
1513 if (map_
.size() == MAX
) {
1514 typename
Map::iterator
del(map_
.begin());
1515 for (typename
Map::iterator
i(map_
.begin()); i
!= map_
.end(); ++i
) {
1516 if (i
->second
.hits
< del
->second
.hits
) {
1522 bool ins
= map_
.insert(typename
Map::value_type(key
, Data(access
)))
1524 assert(ins
); (void)ins
;
1527 void clear() { map_
.clear(); }
1532 rtl::Reference
<IntrospectionAccessStatic_Impl
> const & theAccess
):
1533 access(theAccess
), hits(1)
1536 rtl::Reference
<IntrospectionAccessStatic_Impl
> access
;
1537 mutable unsigned hits
;
1540 typedef std::map
<Key
, Data
, Less
> Map
;
1546 cppu::WeakComponentImplHelper
<
1547 css::lang::XServiceInfo
, css::beans::XIntrospection
>
1548 Implementation_Base
;
1550 class Implementation
: private cppu::BaseMutex
, public Implementation_Base
{
1552 explicit Implementation(
1553 css::uno::Reference
<css::uno::XComponentContext
> const & context
):
1554 Implementation_Base(m_aMutex
),
1555 reflection_(css::reflection::theCoreReflection::get(context
))
1559 virtual void SAL_CALL
disposing() override
{
1560 osl::MutexGuard
g(m_aMutex
);
1561 reflection_
.clear();
1565 virtual OUString SAL_CALL
getImplementationName() override
1566 { return OUString("com.sun.star.comp.stoc.Introspection"); }
1568 virtual sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
1569 { return cppu::supportsService(this, ServiceName
); }
1571 virtual css::uno::Sequence
<OUString
> SAL_CALL
1572 getSupportedServiceNames() override
1574 Sequence
<OUString
> s
{ "com.sun.star.beans.Introspection" };
1578 virtual css::uno::Reference
<css::beans::XIntrospectionAccess
> SAL_CALL
1579 inspect(css::uno::Any
const & aObject
) override
;
1581 css::uno::Reference
<css::reflection::XIdlReflection
> reflection_
;
1582 Cache
<TypeKey
, TypeKeyLess
> typeCache_
;
1585 css::uno::Reference
<css::beans::XIntrospectionAccess
> Implementation::inspect(
1586 css::uno::Any
const & aObject
)
1588 css::uno::Reference
<css::reflection::XIdlReflection
> reflection
;
1590 osl::MutexGuard
g(m_aMutex
);
1591 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
) {
1592 throw css::lang::DisposedException(
1593 getImplementationName(), static_cast<OWeakObject
*>(this));
1595 reflection
= reflection_
;
1597 css::uno::Any aToInspectObj
;
1599 if (aObject
>>= t
) {
1600 css::uno::Reference
<css::reflection::XIdlClass
> c(
1601 reflection
->forName(t
.getTypeName()));
1603 SAL_WARN("stoc", "cannot reflect type " << t
.getTypeName());
1604 return css::uno::Reference
<css::beans::XIntrospectionAccess
>();
1606 aToInspectObj
<<= c
;
1608 aToInspectObj
= aObject
;
1612 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1613 if( eType
!= TypeClass_INTERFACE
&& eType
!= TypeClass_STRUCT
&& eType
!= TypeClass_EXCEPTION
)
1614 return css::uno::Reference
<css::beans::XIntrospectionAccess
>();
1616 if( auto x
= o3tl::tryAccess
<Reference
<XInterface
>>(aToInspectObj
) )
1619 return css::uno::Reference
<css::beans::XIntrospectionAccess
>();
1622 // Pointer to possibly needed new IntrospectionAccessStatic_Impl instance
1623 rtl::Reference
< IntrospectionAccessStatic_Impl
> pAccess
;
1625 // Check: Is a matching access object already cached?
1626 std::vector
< Reference
<XIdlClass
> > SupportedClassSeq
;
1627 std::vector
< Type
> SupportedTypesSeq
;
1628 Reference
<XTypeProvider
> xTypeProvider
;
1629 Reference
<XPropertySetInfo
> xPropSetInfo
;
1630 Reference
<XPropertySet
> xPropSet
;
1632 // Look for interfaces XTypeProvider and PropertySet
1633 if( eType
== TypeClass_INTERFACE
)
1635 xTypeProvider
.set( aToInspectObj
, UNO_QUERY
);
1636 if( xTypeProvider
.is() )
1638 SupportedTypesSeq
= comphelper::sequenceToContainer
<std::vector
<Type
>>(xTypeProvider
->getTypes());
1642 "object of type \"" << aToInspectObj
.getValueTypeName()
1643 << "\" lacks XTypeProvider");
1644 SupportedTypesSeq
= { aToInspectObj
.getValueType() };
1646 // Now try to get the PropertySetInfo
1647 xPropSet
.set( aToInspectObj
, UNO_QUERY
);
1649 xPropSetInfo
= xPropSet
->getPropertySetInfo();
1652 SupportedTypesSeq
= { aToInspectObj
.getValueType() };
1656 osl::MutexGuard
g(m_aMutex
);
1657 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
) {
1658 throw css::lang::DisposedException(
1659 getImplementationName(), static_cast<OWeakObject
*>(this));
1661 TypeKey
key(xPropSetInfo
, SupportedTypesSeq
);
1662 pAccess
= typeCache_
.find(key
);
1664 return new ImplIntrospectionAccess(aToInspectObj
, pAccess
);
1666 pAccess
= new IntrospectionAccessStatic_Impl(reflection
);
1667 typeCache_
.insert(key
, pAccess
);
1670 // No access cached -> create new
1671 std::vector
<Property
>& rAllPropArray
= pAccess
->maAllPropertySeq
;
1672 std::vector
<Reference
<XInterface
>>& rInterfaces1
= pAccess
->aInterfaceSeq1
;
1673 std::vector
<Reference
<XInterface
>>& rInterfaces2
= pAccess
->aInterfaceSeq2
;
1674 std::vector
<sal_Int16
>& rMapTypeArray
= pAccess
->maMapTypeSeq
;
1675 std::vector
<sal_Int32
>& rPropertyConceptArray
= pAccess
->maPropertyConceptSeq
;
1678 // References to important data from pAccess
1679 sal_Int32
& rPropCount
= pAccess
->mnPropCount
;
1680 IntrospectionNameMap
& rPropNameMap
= pAccess
->maPropertyNameMap
;
1681 IntrospectionNameMap
& rMethodNameMap
= pAccess
->maMethodNameMap
;
1682 LowerToExactNameMap
& rLowerToExactNameMap
= pAccess
->maLowerToExactNameMap
;
1685 //*** Perform analysis ***
1687 if( eType
== TypeClass_INTERFACE
)
1689 size_t nTypeCount
= SupportedTypesSeq
.size();
1692 SupportedClassSeq
.resize( nTypeCount
);
1694 for( i
= 0 ; i
< (sal_Int32
)nTypeCount
; i
++ )
1695 SupportedClassSeq
[i
] = reflection
->forName( SupportedTypesSeq
[i
].getTypeName() );
1698 // First look for particular interfaces that are of particular
1699 // importance to the introspection
1701 // Is XPropertySet present?
1702 if( xPropSet
.is() && xPropSetInfo
.is() )
1704 // Is there also a FastPropertySet?
1705 Reference
<XFastPropertySet
> xDummy( aToInspectObj
, UNO_QUERY
);
1706 bool bFast
= pAccess
->mbFastPropSet
= xDummy
.is();
1708 Sequence
<Property
> aPropSeq
= xPropSetInfo
->getProperties();
1709 const Property
* pProps
= aPropSeq
.getConstArray();
1710 sal_Int32 nLen
= aPropSeq
.getLength();
1712 // For a FastPropertySet we must remember the original handles
1714 pAccess
->mpOrgPropertyHandleArray
.reset( new sal_Int32
[ nLen
] );
1716 for( i
= 0 ; i
< nLen
; i
++ )
1718 // Put property in its own list
1719 pAccess
->checkPropertyArraysSize( rPropCount
);
1720 Property
& rProp
= rAllPropArray
[ rPropCount
];
1721 rProp
= pProps
[ i
];
1724 pAccess
->mpOrgPropertyHandleArray
[ i
] = rProp
.Handle
;
1726 // Enter PropCount as a handle for its own FastPropertySet
1727 rProp
.Handle
= rPropCount
;
1729 // Remember type of property
1730 rMapTypeArray
[ rPropCount
] = MAP_PROPERTY_SET
;
1731 rPropertyConceptArray
[ rPropCount
] = PROPERTYSET
;
1732 pAccess
->mnPropertySetPropCount
++;
1734 // Enter name in hash table if not already known
1735 OUString aPropName
= rProp
.Name
;
1737 // Do we already have the name?
1738 IntrospectionNameMap::iterator aIt
= rPropNameMap
.find( aPropName
);
1739 if( aIt
== rPropNameMap
.end() )
1741 // New entry in the hash table
1742 rPropNameMap
[ aPropName
] = rPropCount
;
1744 // Maintain table for XExactName
1745 rLowerToExactNameMap
[ aPropName
.toAsciiLowerCase() ] = aPropName
;
1749 SAL_WARN( "stoc", "Introspection: Property \"" <<
1750 aPropName
<< "\" found more than once in PropertySet" );
1758 // Indices in the export table
1759 sal_Int32 iAllExportedMethod
= 0;
1760 sal_Int32 iAllSupportedListener
= 0;
1762 std::set
<OUString
> seen
;
1764 // Flag, whether XInterface methods should be recorded
1765 // (this must be done only once, allowed initially)
1766 bool bXInterfaceIsInvalid
= false;
1768 // Flag whether the XInterface methods have already been recorded. If
1769 // sal_True, bXInterfaceIsInvalid is activated at the end of the interface
1770 // loop, and XInterface methods are cut off thereafter.
1771 bool bFoundXInterface
= false;
1773 size_t nClassCount
= SupportedClassSeq
.size();
1774 for( sal_Int32 nIdx
= 0 ; nIdx
< (sal_Int32
)nClassCount
; nIdx
++ )
1776 Reference
<XIdlClass
> xImplClass2
= SupportedClassSeq
[nIdx
];
1777 while( xImplClass2
.is() )
1779 // Fetch interfaces from the implementation
1780 Sequence
< Reference
<XIdlClass
> > aClassSeq
= xImplClass2
->getInterfaces();
1781 sal_Int32 nIfaceCount
= aClassSeq
.getLength();
1783 aClassSeq
.realloc( nIfaceCount
+ 1 );
1784 aClassSeq
.getArray()[ nIfaceCount
] = xImplClass2
;
1787 const Reference
<XIdlClass
>* pParamArray
= aClassSeq
.getConstArray();
1789 for( sal_Int32 j
= 0 ; j
< nIfaceCount
; j
++ )
1791 const Reference
<XIdlClass
>& rxIfaceClass
= pParamArray
[j
];
1792 if (!seen
.insert(rxIfaceClass
->getName()).second
) {
1796 // 2. Register fields as properties
1799 Sequence
< Reference
<XIdlField
> > fields
= rxIfaceClass
->getFields();
1800 const Reference
<XIdlField
>* pFields
= fields
.getConstArray();
1801 sal_Int32 nLen
= fields
.getLength();
1803 for( i
= 0 ; i
< nLen
; i
++ )
1805 Reference
<XIdlField
> xField
= pFields
[i
];
1806 Reference
<XIdlClass
> xPropType
= xField
->getType();
1808 // Is the property sequence big enough?
1809 pAccess
->checkPropertyArraysSize( rPropCount
);
1811 // Enter in own property array
1812 Property
& rProp
= rAllPropArray
[ rPropCount
];
1813 OUString aFieldName
= xField
->getName();
1814 rProp
.Name
= aFieldName
;
1815 rProp
.Handle
= rPropCount
;
1816 Type
aFieldType( xPropType
->getTypeClass(), xPropType
->getName() );
1817 rProp
.Type
= aFieldType
;
1818 FieldAccessMode eAccessMode
= xField
->getAccessMode();
1819 rProp
.Attributes
= (eAccessMode
== FieldAccessMode_READONLY
||
1820 eAccessMode
== FieldAccessMode_CONST
)
1823 // Enter name in hash table
1824 OUString aPropName
= rProp
.Name
;
1826 // Do we have the name already?
1827 IntrospectionNameMap::iterator aIt
= rPropNameMap
.find( aPropName
);
1828 if (aIt
!= rPropNameMap
.end())
1831 // New entry in the hash table
1832 rPropNameMap
[ aPropName
] = rPropCount
;
1834 // Maintain table for XExactName
1835 rLowerToExactNameMap
[ aPropName
.toAsciiLowerCase() ] = aPropName
;
1838 IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess
->aInterfaceSeq1
,
1839 rInterfaces1
, rPropCount
);
1840 rInterfaces1
[ rPropCount
] = xField
;
1842 // Remember type of property
1843 rMapTypeArray
[ rPropCount
] = MAP_FIELD
;
1844 rPropertyConceptArray
[ rPropCount
] = ATTRIBUTES
;
1845 pAccess
->mnAttributePropCount
++;
1854 // Counter for found listeners
1855 sal_Int32 nListenerCount
= 0;
1857 // Get and remember all methods
1858 Sequence
< Reference
<XIdlMethod
> > methods
= rxIfaceClass
->getMethods();
1859 const Reference
<XIdlMethod
>* pSourceMethods
= methods
.getConstArray();
1860 sal_Int32 nSourceMethodCount
= methods
.getLength();
1862 // 3. a) Search get/set and listener methods
1864 // Create field for information about the methods, so that methods which are not
1865 // related to properties or listeners can easily be found later.
1866 // New: initialise MethodConceptArray
1869 STANDARD_METHOD
, // normal method, not related to properties or listeners
1870 GETSET_METHOD
, // belongs to a get/set property
1871 ADD_LISTENER_METHOD
, // add method of a listener interface
1872 REMOVE_LISTENER_METHOD
, // remove method of a listener interface
1873 INVALID_METHOD
// method whose class is not considered, e.g. XPropertySet
1875 std::unique_ptr
<MethodType
[]> pMethodTypes( new MethodType
[ nSourceMethodCount
] );
1876 std::unique_ptr
<sal_Int32
[]> pLocalMethodConcepts( new sal_Int32
[ nSourceMethodCount
] );
1877 for( i
= 0 ; i
< nSourceMethodCount
; i
++ )
1879 pMethodTypes
[ i
] = STANDARD_METHOD
;
1880 pLocalMethodConcepts
[ i
] = 0;
1883 for( i
= 0 ; i
< nSourceMethodCount
; i
++ )
1886 const Reference
<XIdlMethod
>& rxMethod_i
= pSourceMethods
[i
];
1887 sal_Int32
& rMethodConcept_i
= pLocalMethodConcepts
[ i
];
1890 OUString aMethName
= rxMethod_i
->getName();
1892 // Catalogue methods
1893 // Filter all (?) methods of XInterface so e.g. acquire and release
1894 // can not be called from scripting
1895 rtl::OUString
className(
1896 rxMethod_i
->getDeclaringClass()->getName());
1897 if (className
== "com.sun.star.uno.XInterface") {
1898 bFoundXInterface
= true;
1900 if( bXInterfaceIsInvalid
)
1902 pMethodTypes
[ i
] = INVALID_METHOD
;
1907 if( aMethName
!= "queryInterface" )
1909 rMethodConcept_i
|= MethodConcept::DANGEROUS
;
1913 } else if (className
== "com.sun.star.uno.XAggregation")
1915 if( aMethName
== "setDelegator" )
1917 rMethodConcept_i
|= MethodConcept::DANGEROUS
;
1920 } else if (className
1921 == "com.sun.star.container.XElementAccess")
1923 rMethodConcept_i
|= ( NAMECONTAINER
|
1926 pAccess
->mbElementAccess
= true;
1927 } else if ((className
1928 == "com.sun.star.container.XNameContainer"))
1930 rMethodConcept_i
|= NAMECONTAINER
;
1931 pAccess
->mbNameContainer
= true;
1932 pAccess
->mbNameReplace
= true;
1933 pAccess
->mbNameAccess
= true;
1934 pAccess
->mbElementAccess
= true;
1935 } else if ((className
1936 == "com.sun.star.container.XNameReplace"))
1938 rMethodConcept_i
|= NAMECONTAINER
;
1939 pAccess
->mbNameReplace
= true;
1940 pAccess
->mbNameAccess
= true;
1941 pAccess
->mbElementAccess
= true;
1942 } else if ((className
1943 == "com.sun.star.container.XNameAccess"))
1945 rMethodConcept_i
|= NAMECONTAINER
;
1946 pAccess
->mbNameAccess
= true;
1947 pAccess
->mbElementAccess
= true;
1948 } else if ((className
1949 == "com.sun.star.container.XIndexContainer"))
1951 rMethodConcept_i
|= INDEXCONTAINER
;
1952 pAccess
->mbIndexContainer
= true;
1953 pAccess
->mbIndexReplace
= true;
1954 pAccess
->mbIndexAccess
= true;
1955 pAccess
->mbElementAccess
= true;
1956 } else if ((className
1957 == "com.sun.star.container.XIndexReplace"))
1959 rMethodConcept_i
|= INDEXCONTAINER
;
1960 pAccess
->mbIndexReplace
= true;
1961 pAccess
->mbIndexAccess
= true;
1962 pAccess
->mbElementAccess
= true;
1963 } else if ((className
1964 == "com.sun.star.container.XIndexAccess"))
1966 rMethodConcept_i
|= INDEXCONTAINER
;
1967 pAccess
->mbIndexAccess
= true;
1968 pAccess
->mbElementAccess
= true;
1969 } else if (className
1970 == "com.sun.star.container.XEnumerationAccess")
1972 rMethodConcept_i
|= ENUMERATION
;
1973 pAccess
->mbEnumerationAccess
= true;
1974 pAccess
->mbElementAccess
= true;
1975 } else if (className
1976 == "com.sun.star.reflection.XIdlArray")
1978 pAccess
->mbIdlArray
= true;
1979 } else if (className
1980 == "com.sun.star.lang.XUnoTunnel")
1982 pAccess
->mbUnoTunnel
= true;
1985 // If the name is too short, it isn't anything
1986 if( aMethName
.getLength() <= 3 )
1989 // Is it a get method?
1991 if( aMethName
.startsWith("get", &aPropName
) )
1993 // Get methods must not have any parameters
1994 Sequence
< Reference
<XIdlClass
> > getParams
= rxMethod_i
->getParameterTypes();
1995 if( getParams
.getLength() > 0 )
2000 // Do we have the name already?
2001 IntrospectionNameMap::iterator aIt
= rPropNameMap
.find( aPropName
);
2002 if (aIt
!= rPropNameMap
.end())
2006 String( "Introspection: Property \"" ) +
2007 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2008 String( "\" found more than once" ) );
2013 // It is already at least a read-only property
2014 rMethodConcept_i
|= PROPERTY
;
2016 pMethodTypes
[i
] = GETSET_METHOD
;
2017 Reference
<XIdlClass
> xGetRetType
= rxMethod_i
->getReturnType();
2019 // Is the property sequence big enough?
2020 pAccess
->checkPropertyArraysSize( rPropCount
);
2022 // Write it in its property array
2023 Property
& rProp
= rAllPropArray
[ rPropCount
];
2024 rProp
.Name
= aPropName
;
2025 rProp
.Handle
= rPropCount
;
2026 rProp
.Type
= Type( xGetRetType
->getTypeClass(), xGetRetType
->getName() );
2027 rProp
.Attributes
= READONLY
;
2029 // New entry in the hash table
2030 rPropNameMap
[ aPropName
] = rPropCount
;
2032 // Maintain table for XExactName
2033 rLowerToExactNameMap
[ aPropName
.toAsciiLowerCase() ] = aPropName
;
2035 // Remember get method
2036 IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess
->aInterfaceSeq1
,
2037 rInterfaces1
, rPropCount
);
2038 rInterfaces1
[ rPropCount
] = rxMethod_i
;
2040 // Remember type of property
2041 rMapTypeArray
[ rPropCount
] = MAP_GETSET
;
2042 rPropertyConceptArray
[ rPropCount
] = METHODS
;
2043 pAccess
->mnMethodPropCount
++;
2045 // Search for matching set method
2047 for( k
= 0 ; k
< nSourceMethodCount
; k
++ )
2050 const Reference
<XIdlMethod
>& rxMethod_k
= pSourceMethods
[k
];
2052 // Accept only methods that are not already assigned
2053 if( k
== i
|| pMethodTypes
[k
] != STANDARD_METHOD
)
2056 // Get name and evaluate
2057 OUString aMethName2
= rxMethod_k
->getName();
2058 OUString aPropName2
;
2059 if (!(aMethName2
.startsWith("set", &aPropName2
)
2060 && aPropName2
== aPropName
))
2063 // A set method must return void
2064 Reference
<XIdlClass
> xSetRetType
= rxMethod_k
->getReturnType();
2065 if( xSetRetType
->getTypeClass() != TypeClass_VOID
)
2070 // A set method may only have one parameter
2071 Sequence
< Reference
<XIdlClass
> > setParams
= rxMethod_k
->getParameterTypes();
2072 sal_Int32 nParamCount
= setParams
.getLength();
2073 if( nParamCount
!= 1 )
2078 // Next, the return type must correspond to the parameter type
2079 const Reference
<XIdlClass
>* pParamArray2
= setParams
.getConstArray();
2080 Reference
<XIdlClass
> xParamType
= pParamArray2
[ 0 ];
2081 if( xParamType
->equals( xGetRetType
) )
2083 pLocalMethodConcepts
[ k
] = PROPERTY
;
2085 pMethodTypes
[k
] = GETSET_METHOD
;
2087 // Delete read-only flag again
2088 rProp
.Attributes
&= ~READONLY
;
2090 // Remember set method
2091 IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess
->aInterfaceSeq2
,
2092 rInterfaces2
, rPropCount
);
2093 rInterfaces2
[ rPropCount
] = rxMethod_k
;
2101 // Is it an add listener method?
2102 else if( aMethName
.startsWith("add", &aPropName
) )
2104 // Does it end with "Listener"?
2105 OUString aListenerName
;
2106 if( !aPropName
.endsWith("Listener", &aListenerName
) )
2109 // TODO: More accurate tests could still be carried out here
2111 // - Number and type of parameters
2114 // Search for matching remove method, otherwise not applicable
2116 for( k
= 0 ; k
< nSourceMethodCount
; k
++ )
2119 const Reference
<XIdlMethod
>& rxMethod_k
= pSourceMethods
[k
];
2121 // Accept only methods that are not already assigned
2122 if( k
== i
|| pMethodTypes
[k
] != STANDARD_METHOD
)
2125 // Get name and evaluate
2126 OUString aMethName2
= rxMethod_k
->getName();
2127 OUString aListenerName2
;
2128 if (!(aMethName2
.startsWith(
2129 "remove", &aPropName
)
2130 && aPropName
.endsWith(
2131 "Listener", &aListenerName2
)
2132 && aListenerName2
== aListenerName
))
2135 // TODO: More accurate tests could still be carried out here
2137 // - Number and type of parameters
2140 // Methods are recognised as a listener interface
2141 rMethodConcept_i
|= LISTENER
;
2142 pLocalMethodConcepts
[ k
] |= LISTENER
;
2144 pMethodTypes
[i
] = ADD_LISTENER_METHOD
;
2145 pMethodTypes
[k
] = REMOVE_LISTENER_METHOD
;
2152 // A set method could still exist without a corresponding get method,
2153 // this must be a write-only property
2154 for( i
= 0 ; i
< nSourceMethodCount
; i
++ )
2157 const Reference
<XIdlMethod
>& rxMethod_i
= pSourceMethods
[i
];
2159 // Accept only methods that are not already assigned
2160 if( pMethodTypes
[i
] != STANDARD_METHOD
)
2164 OUString aMethName
= rxMethod_i
->getName();
2166 // If the name is too short, it isn't anything
2167 if( aMethName
.getLength() <= 3 )
2170 // Is it a set method without associated get method?
2172 if( aMethName
.startsWith("set", &aPropName
) )
2174 // A set method must return void
2175 Reference
<XIdlClass
> xSetRetType
= rxMethod_i
->getReturnType();
2176 if( xSetRetType
->getTypeClass() != TypeClass_VOID
)
2181 // A set method may only have one parameter
2182 Sequence
< Reference
<XIdlClass
> > setParams
= rxMethod_i
->getParameterTypes();
2183 sal_Int32 nParamCount
= setParams
.getLength();
2184 if( nParamCount
!= 1 )
2189 // Do we have the name already?
2190 IntrospectionNameMap::iterator aIt
= rPropNameMap
.find( aPropName
);
2191 if (aIt
!= rPropNameMap
.end())
2195 String( "Introspection: Property \"" ) +
2196 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2197 String( "\" found more than once" ) );
2202 // Now we know it's a write only property
2203 pLocalMethodConcepts
[ i
] = PROPERTY
;
2205 pMethodTypes
[i
] = GETSET_METHOD
;
2206 Reference
<XIdlClass
> xGetRetType
= setParams
.getConstArray()[0];
2208 // Is the property sequence big enough?
2209 pAccess
->checkPropertyArraysSize( rPropCount
);
2211 // Write it in its property array
2212 Property
& rProp
= rAllPropArray
[ rPropCount
];
2213 rProp
.Name
= aPropName
;
2214 rProp
.Handle
= rPropCount
;
2215 rProp
.Type
= Type( xGetRetType
->getTypeClass(), xGetRetType
->getName() );
2216 rProp
.Attributes
= 0; // PROPERTY_WRITEONLY ???
2218 // New entry in the hash table
2219 rPropNameMap
[ aPropName
] = rPropCount
;
2221 // Maintain table for XExactName
2222 rLowerToExactNameMap
[ aPropName
.toAsciiLowerCase() ] = aPropName
;
2224 // Remember set method
2225 IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess
->aInterfaceSeq2
,
2226 rInterfaces2
, rPropCount
);
2227 rInterfaces2
[ rPropCount
] = rxMethod_i
;
2229 // Remember type of property
2230 rMapTypeArray
[ rPropCount
] = MAP_SETONLY
;
2231 rPropertyConceptArray
[ rPropCount
] = METHODS
;
2232 pAccess
->mnMethodPropCount
++;
2240 // 4. Place methods in overall sequence
2242 // How many methods in the method sequence
2243 sal_Int32 nExportedMethodCount
= 0;
2244 sal_Int32 nSupportedListenerCount
= 0;
2245 for( i
= 0 ; i
< nSourceMethodCount
; i
++ )
2247 if( pMethodTypes
[ i
] != INVALID_METHOD
)
2249 nExportedMethodCount
++;
2251 if( pMethodTypes
[ i
] == ADD_LISTENER_METHOD
)
2253 nSupportedListenerCount
++;
2257 // Enlarge sequences in the access object accordingly
2258 pAccess
->maAllMethodSeq
.resize( nExportedMethodCount
+ iAllExportedMethod
);
2259 pAccess
->maMethodConceptSeq
.resize( nExportedMethodCount
+ iAllExportedMethod
);
2260 pAccess
->maSupportedListenerSeq
.resize( nSupportedListenerCount
+ iAllSupportedListener
);
2263 for( i
= 0 ; i
< nSourceMethodCount
; i
++ )
2265 if( pMethodTypes
[ i
] != INVALID_METHOD
)
2268 const Reference
<XIdlMethod
>& rxMethod
= pSourceMethods
[i
];
2270 // Enter name in hash table if not already known
2271 OUString aMethName2
= rxMethod
->getName();
2272 IntrospectionNameMap::iterator aIt
= rMethodNameMap
.find( aMethName2
);
2273 if( aIt
== rMethodNameMap
.end() )
2276 rMethodNameMap
[ aMethName2
] = iAllExportedMethod
;
2278 // Maintain table for XExactName
2279 rLowerToExactNameMap
[ aMethName2
.toAsciiLowerCase() ] = aMethName2
;
2283 sal_Int32 iHashResult
= aIt
->second
;
2285 Reference
<XIdlMethod
> xExistingMethod
= pAccess
->maAllMethodSeq
[iHashResult
];
2287 Reference
< XIdlClass
> xExistingMethClass
=
2288 xExistingMethod
->getDeclaringClass();
2289 Reference
< XIdlClass
> xNewMethClass
= rxMethod
->getDeclaringClass();
2290 if( xExistingMethClass
->equals( xNewMethClass
) )
2294 pAccess
->maAllMethodSeq
[iAllExportedMethod
] = rxMethod
;
2296 // If a concept has been set, is the method "normal"?
2297 sal_Int32
& rMethodConcept_i
= pLocalMethodConcepts
[ i
];
2298 if( !rMethodConcept_i
)
2299 rMethodConcept_i
= MethodConcept_NORMAL_IMPL
;
2300 pAccess
->maMethodConceptSeq
[ iAllExportedMethod
] = rMethodConcept_i
;
2301 iAllExportedMethod
++;
2303 if( pMethodTypes
[ i
] == ADD_LISTENER_METHOD
)
2305 // Determine class of listener
2306 const Reference
<XIdlMethod
>& rxMethod
= pSourceMethods
[i
];
2308 // Enter void as default class
2309 css::uno::Reference
<css::reflection::XIdlClass
>
2311 reflection
->forName(
2312 cppu::UnoType
<void>::get()
2314 // Old: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass();
2316 // Option 1: Search for parameters for a listener class
2317 // Disadvantage: Superclasses should be searched recursively
2318 Sequence
< Reference
<XIdlClass
> > aParams
= rxMethod
->getParameterTypes();
2319 const Reference
<XIdlClass
>* pParamArray2
= aParams
.getConstArray();
2321 css::uno::Reference
<css::reflection::XIdlClass
>
2322 xEventListenerClass(
2323 reflection
->forName(
2325 css::lang::XEventListener
>::get()
2327 // Old: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass();
2328 sal_Int32 nParamCount
= aParams
.getLength();
2330 for( k
= 0 ; k
< nParamCount
; k
++ )
2332 const Reference
<XIdlClass
>& rxClass
= pParamArray2
[k
];
2334 // Are we derived from a listener?
2335 if( rxClass
->equals( xEventListenerClass
) ||
2336 isDerivedFrom( rxClass
, xEventListenerClass
) )
2338 xListenerClass
= rxClass
;
2343 // Option 2: Unload the name of the method
2344 // Disadvantage: Does not work with test listeners, where it does not exist
2345 //aMethName = rxMethod->getName();
2346 //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 );
2347 //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName );
2348 Type
aListenerType( TypeClass_INTERFACE
, xListenerClass
->getName() );
2349 pAccess
->maSupportedListenerSeq
[ iAllSupportedListener
] = aListenerType
;
2350 iAllSupportedListener
++;
2354 // When there were XInterface methods in this run,
2355 // ignore them in the future
2356 if( bFoundXInterface
)
2357 bXInterfaceIsInvalid
= true;
2360 // Do superclasses exist? Then continue here
2361 Sequence
< Reference
<XIdlClass
> > aSuperClassSeq
= xImplClass2
->getSuperclasses();
2363 // Currently only one superclass is considered
2364 if( aSuperClassSeq
.getLength() >= 1 )
2366 xImplClass2
= aSuperClassSeq
.getConstArray()[0];
2367 OSL_ENSURE( xImplClass2
.is(), "super class null" );
2371 xImplClass2
= nullptr;
2376 // Apply number of exported methods and adapt Sequences
2377 // (can be different because duplicate methods are thrown
2378 // out only after the determination of nExportedMethodCount)
2379 sal_Int32
& rMethCount
= pAccess
->mnMethCount
;
2380 rMethCount
= iAllExportedMethod
;
2381 pAccess
->maAllMethodSeq
.resize( rMethCount
);
2382 pAccess
->maMethodConceptSeq
.resize( rMethCount
);
2384 // Resize the property sequences
2385 pAccess
->maAllPropertySeq
.resize( rPropCount
);
2386 pAccess
->maPropertyConceptSeq
.resize( rPropCount
);
2387 pAccess
->maMapTypeSeq
.resize( rPropCount
);
2389 // Register struct fields as properties
2390 else //if( eType == TypeClass_STRUCT )
2392 // Is it an interface or a struct?
2393 //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass();
2394 css::uno::Reference
<css::reflection::XIdlClass
> xClassRef(
2395 reflection
->forName(aToInspectObj
.getValueTypeName()));
2396 if( !xClassRef
.is() )
2398 SAL_WARN( "stoc", "Can't get XIdlClass from Reflection" );
2399 return new ImplIntrospectionAccess(aToInspectObj
, pAccess
);
2403 Sequence
< Reference
<XIdlField
> > fields
= xClassRef
->getFields();
2404 const Reference
<XIdlField
>* pFields
= fields
.getConstArray();
2405 sal_Int32 nLen
= fields
.getLength();
2407 for( i
= 0 ; i
< nLen
; i
++ )
2409 Reference
<XIdlField
> xField
= pFields
[i
];
2410 Reference
<XIdlClass
> xPropType
= xField
->getType();
2411 OUString aPropName
= xField
->getName();
2413 // Is the property sequence big enough?
2414 pAccess
->checkPropertyArraysSize( rPropCount
);
2416 // Write it in its property array
2417 Property
& rProp
= rAllPropArray
[ rPropCount
];
2418 rProp
.Name
= aPropName
;
2419 rProp
.Handle
= rPropCount
;
2420 rProp
.Type
= Type( xPropType
->getTypeClass(), xPropType
->getName() );
2421 FieldAccessMode eAccessMode
= xField
->getAccessMode();
2422 rProp
.Attributes
= (eAccessMode
== FieldAccessMode_READONLY
||
2423 eAccessMode
== FieldAccessMode_CONST
)
2426 //FieldAccessMode eAccessMode = xField->getAccessMode();
2427 //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST)
2428 //? PropertyAttribute::READONLY : 0;
2430 // Write name in hash table
2431 rPropNameMap
[ aPropName
] = rPropCount
;
2433 // Maintain table for XExactName
2434 rLowerToExactNameMap
[ aPropName
.toAsciiLowerCase() ] = aPropName
;
2437 IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess
->aInterfaceSeq1
,
2438 rInterfaces1
, rPropCount
);
2439 rInterfaces1
[ rPropCount
] = xField
;
2441 // Remember type of property
2442 rMapTypeArray
[ rPropCount
] = MAP_FIELD
;
2443 rPropertyConceptArray
[ rPropCount
] = ATTRIBUTES
;
2444 pAccess
->mnAttributePropCount
++;
2451 // Set property sequence to the correct length
2452 pAccess
->maAllPropertySeq
.resize( pAccess
->mnPropCount
);
2454 return new ImplIntrospectionAccess(aToInspectObj
, pAccess
);
2459 css::uno::Reference
<css::uno::XComponentContext
> const & context
):
2460 instance(new Implementation(context
))
2463 rtl::Reference
<cppu::OWeakObject
> instance
;
2467 public rtl::StaticWithArg
<
2468 Instance
, css::uno::Reference
<css::uno::XComponentContext
>, Singleton
>
2473 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
* SAL_CALL
2474 com_sun_star_comp_stoc_Introspection_get_implementation(
2475 css::uno::XComponentContext
* context
,
2476 css::uno::Sequence
<css::uno::Any
> const & arguments
)
2479 arguments
.hasElements(), "stoc", "unexpected singleton arguments");
2480 return cppu::acquire(Singleton::get(context
).instance
.get());
2483 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */