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
148 IntrospectionNameMap
;
151 // Hashtable to assign exact names to the Lower-Case
152 // converted names, for the support of XExactName
153 typedef std::unordered_map
161 class ImplIntrospectionAccess
;
162 class IntrospectionAccessStatic_Impl
: public salhelper::SimpleReferenceObject
164 friend class Implementation
;
165 friend class ImplIntrospectionAccess
;
167 // Holding CoreReflection
168 Reference
< XIdlReflection
> mxCoreReflection
;
170 // InterfaceSequences, to save additional information in a property
171 // for example the Field at MAP_FIELD, the get/set-Methods at MAP_GETSET, et cetera
172 std::vector
< Reference
<XInterface
> > aInterfaceSeq1
;
173 std::vector
< Reference
<XInterface
> > aInterfaceSeq2
;
175 // Hashtables for names
176 IntrospectionNameMap maPropertyNameMap
;
177 IntrospectionNameMap maMethodNameMap
;
178 LowerToExactNameMap maLowerToExactNameMap
;
180 // Vector of all Properties, also for delivering from getProperties()
181 std::vector
<Property
> maAllPropertySeq
;
183 // Mapping of properties to Access-Types
184 std::vector
<sal_Int16
> maMapTypeSeq
;
186 // Classification of found methods
187 std::vector
<sal_Int32
> maPropertyConceptSeq
;
189 // Number of Properties
190 sal_Int32 mnPropCount
;
192 // Number of Properties, which are assigned to particular concepts
193 //sal_Int32 mnDangerousPropCount;
194 sal_Int32 mnPropertySetPropCount
;
195 sal_Int32 mnAttributePropCount
;
196 sal_Int32 mnMethodPropCount
;
198 // Flags which indicate if various interfaces are present
200 bool mbElementAccess
;
203 bool mbNameContainer
;
206 bool mbIndexContainer
;
207 bool mbEnumerationAccess
;
211 // Original handles of FastPropertySets
212 std::unique_ptr
<sal_Int32
[]> mpOrgPropertyHandleArray
;
214 // MethodSequence, that accepts all methods
215 std::vector
< Reference
<XIdlMethod
> > maAllMethodSeq
;
217 // Classification of found methods
218 std::vector
<sal_Int32
> maMethodConceptSeq
;
221 sal_Int32 mnMethCount
;
223 // Sequence of Listener, that can be registered
224 std::vector
< Type
> maSupportedListenerSeq
;
226 // Helper-methods for adjusting sizes of Sequences
227 void checkPropertyArraysSize( sal_Int32 iNextIndex
);
228 static void checkInterfaceArraySize( std::vector
< Reference
<XInterface
> >& rSeq
, std::vector
<Reference
<XInterface
>>& rInterfaceVec
,
229 sal_Int32 iNextIndex
);
232 explicit IntrospectionAccessStatic_Impl( Reference
< XIdlReflection
> const & xCoreReflection_
);
233 sal_Int32
getPropertyIndex( const OUString
& aPropertyName
) const;
234 sal_Int32
getMethodIndex( const OUString
& aMethodName
) const;
236 // Methods of XIntrospectionAccess (OLD, now only Impl)
237 void setPropertyValue(const Any
& obj
, const OUString
& aPropertyName
, const Any
& aValue
) const;
238 // void setPropertyValue(Any& obj, const OUString& aPropertyName, const Any& aValue) const;
239 Any
getPropertyValue(const Any
& obj
, const OUString
& aPropertyName
) const;
240 void setPropertyValueByIndex(const Any
& obj
, sal_Int32 nIndex
, const Any
& aValue
) const;
241 // void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const;
242 Any
getPropertyValueByIndex(const Any
& obj
, sal_Int32 nIndex
) const;
244 const std::vector
<Property
>& getProperties() const { return maAllPropertySeq
; }
245 const std::vector
< Reference
<XIdlMethod
> >& getMethods() const { return maAllMethodSeq
; }
246 const std::vector
< Type
>& getSupportedListeners() const { return maSupportedListenerSeq
; }
247 const std::vector
<sal_Int32
>& getPropertyConcepts() const { return maPropertyConceptSeq
; }
248 const std::vector
<sal_Int32
>& getMethodConcepts() const { return maMethodConceptSeq
; }
253 IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference
< XIdlReflection
> const & xCoreReflection_
)
254 : mxCoreReflection( xCoreReflection_
)
256 aInterfaceSeq1
.resize( ARRAY_SIZE_STEP
);
257 aInterfaceSeq2
.resize( ARRAY_SIZE_STEP
);
260 maAllPropertySeq
.resize( ARRAY_SIZE_STEP
);
261 maMapTypeSeq
.resize( ARRAY_SIZE_STEP
);
262 maPropertyConceptSeq
.resize( ARRAY_SIZE_STEP
);
264 mbFastPropSet
= false;
265 mbElementAccess
= false;
266 mbNameAccess
= false;
267 mbNameReplace
= false;
268 mbNameContainer
= false;
269 mbIndexAccess
= false;
270 mbIndexReplace
= false;
271 mbIndexContainer
= false;
272 mbEnumerationAccess
= false;
276 mpOrgPropertyHandleArray
= nullptr;
279 //mnDangerousPropCount = 0;
280 mnPropertySetPropCount
= 0;
281 mnAttributePropCount
= 0;
282 mnMethodPropCount
= 0;
288 sal_Int32
IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString
& aPropertyName
) const
290 IntrospectionAccessStatic_Impl
* pThis
= const_cast<IntrospectionAccessStatic_Impl
*>(this);
291 IntrospectionNameMap::iterator aIt
= pThis
->maPropertyNameMap
.find( aPropertyName
);
292 if (aIt
!= pThis
->maPropertyNameMap
.end())
298 sal_Int32
IntrospectionAccessStatic_Impl::getMethodIndex( const OUString
& aMethodName
) const
300 IntrospectionAccessStatic_Impl
* pThis
= const_cast<IntrospectionAccessStatic_Impl
*>(this);
301 IntrospectionNameMap::iterator aIt
= pThis
->maMethodNameMap
.find( aMethodName
);
302 if (aIt
!= pThis
->maMethodNameMap
.end())
307 // #95159 Check if full qualified name matches
308 sal_Int32 nSearchFrom
= aMethodName
.getLength();
311 // Strategy: Search back until the first '_' is found
312 sal_Int32 nFound
= aMethodName
.lastIndexOf( '_', nSearchFrom
);
316 OUString aPureMethodName
= aMethodName
.copy( nFound
+ 1 );
318 aIt
= pThis
->maMethodNameMap
.find( aPureMethodName
);
319 if (aIt
!= pThis
->maMethodNameMap
.end())
321 // Check if it can be a type?
322 // Problem: Does not work if package names contain _ ?!
323 OUString aStr
= aMethodName
.copy( 0, nFound
);
324 OUString aTypeName
= aStr
.replace( '_', '.' );
325 Reference
< XIdlClass
> xClass
= mxCoreReflection
->forName( aTypeName
);
328 // If this is a valid class it could be the right method
330 // Could be the right method, type has to be checked
331 const sal_Int32 iHashResult
= aIt
->second
;
333 const Reference
<XIdlMethod
> xMethod
= maAllMethodSeq
[iHashResult
];
335 Reference
< XIdlClass
> xMethClass
= xMethod
->getDeclaringClass();
336 if( xClass
->equals( xMethClass
) )
342 // Could also be another method with the same name
343 // Iterate over all methods
344 size_t nLen
= maAllMethodSeq
.size();
345 for (size_t i
= 0; i
< nLen
; ++i
)
347 const Reference
<XIdlMethod
> xMethod2
= maAllMethodSeq
[ i
];
348 if( xMethod2
->getName() == aPureMethodName
)
350 Reference
< XIdlClass
> xMethClass2
= xMethod2
->getDeclaringClass();
352 if( xClass
->equals( xMethClass2
) )
362 nSearchFrom
= nFound
- 1;
363 if( nSearchFrom
< 0 )
369 void IntrospectionAccessStatic_Impl::setPropertyValue( const Any
& obj
, const OUString
& aPropertyName
, const Any
& aValue
) const
370 //void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const OUString& aPropertyName, const Any& aValue ) const
372 sal_Int32 i
= getPropertyIndex( aPropertyName
);
374 throw UnknownPropertyException(aPropertyName
);
375 setPropertyValueByIndex( obj
, i
, aValue
);
378 void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any
& obj
, sal_Int32 nSequenceIndex
, const Any
& aValue
) const
379 //void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
381 // Is the passed object something that fits?
382 Reference
<XInterface
> xInterface
;
383 if( !(obj
>>= xInterface
) )
385 TypeClass eObjType
= obj
.getValueType().getTypeClass();
386 if( nSequenceIndex
>= mnPropCount
)
387 throw IllegalArgumentException(
388 "IntrospectionAccessStatic_Impl::setPropertyValueByIndex(), index > propertyCount, " +
389 OUString::number(nSequenceIndex
) + " > " + OUString::number(mnPropCount
),
390 Reference
<XInterface
>(), 0);
391 if( eObjType
!= TypeClass_STRUCT
&& eObjType
!= TypeClass_EXCEPTION
)
392 throw IllegalArgumentException(
393 "IntrospectionAccessStatic_Impl::setPropertyValueByIndex(), expected struct or exception, got" +
394 obj
.getValueType().getTypeName(), Reference
<XInterface
>(), 0);
398 if( (maAllPropertySeq
[ nSequenceIndex
].Attributes
& READONLY
) != 0 )
400 throw UnknownPropertyException(
401 "IntrospectionAccessStatic_Impl::setPropertyValueByIndex(), property at index " + OUString::number(nSequenceIndex
) + " is readonly");
404 switch( maMapTypeSeq
[ nSequenceIndex
] )
406 case MAP_PROPERTY_SET
:
409 const Property
& rProp
= maAllPropertySeq
[ nSequenceIndex
];
411 // Convert Interface-Parameter to the correct type
412 bool bUseCopy
= false;
415 if( auto valInterface
= o3tl::tryAccess
<
416 css::uno::Reference
<css::uno::XInterface
>>(aValue
) )
418 Type aPropType
= rProp
.Type
;
419 OUString
aTypeName( aPropType
.getTypeName() );
420 Reference
< XIdlClass
> xPropClass
= mxCoreReflection
->forName( aTypeName
);
421 //Reference<XIdlClass> xPropClass = rProp.Type;
422 if( xPropClass
.is() && xPropClass
->getTypeClass() == TypeClass_INTERFACE
)
424 if( valInterface
->is() )
426 //Any queryInterface( const Type& rType );
427 aRealValue
= (*valInterface
)->queryInterface( aPropType
);
428 if( aRealValue
.hasValue() )
434 // Do we have a FastPropertySet and a valid Handle?
435 // CAUTION: At this point we exploit that the PropertySet
436 // gets queried at the beginning of the Introspection-Process.
437 sal_Int32 nOrgHandle
;
438 if( mbFastPropSet
&& ( nOrgHandle
= mpOrgPropertyHandleArray
[ nSequenceIndex
] ) != -1 )
440 // Retrieve PropertySet-Interface
441 Reference
<XFastPropertySet
> xFastPropSet
=
442 Reference
<XFastPropertySet
>::query( xInterface
);
443 if( xFastPropSet
.is() )
445 xFastPropSet
->setFastPropertyValue( nOrgHandle
, bUseCopy
? aRealValue
: aValue
);
449 // throw UnknownPropertyException
452 // else take the normal one
455 // Retrieve PropertySet-Interface
456 Reference
<XPropertySet
> xPropSet
=
457 Reference
<XPropertySet
>::query( xInterface
);
460 xPropSet
->setPropertyValue( rProp
.Name
, bUseCopy
? aRealValue
: aValue
);
464 // throw UnknownPropertyException
472 Reference
<XIdlField
> xField
= static_cast<XIdlField
*>(aInterfaceSeq1
[ nSequenceIndex
].get());
473 Reference
<XIdlField2
> xField2(xField
, UNO_QUERY
);
476 xField2
->set( const_cast<Any
&>(obj
), aValue
);
477 // IllegalArgumentException
478 // NullPointerException
482 xField
->set( obj
, aValue
);
483 // IllegalArgumentException
484 // NullPointerException
488 // throw IllegalArgumentException();
497 Reference
<XIdlMethod
> xMethod
= static_cast<XIdlMethod
*>(aInterfaceSeq2
[ nSequenceIndex
].get());
500 Sequence
<Any
> args( 1 );
501 args
.getArray()[0] = aValue
;
502 xMethod
->invoke( obj
, args
);
506 // throw IllegalArgumentException();
513 Any
IntrospectionAccessStatic_Impl::getPropertyValue( const Any
& obj
, const OUString
& aPropertyName
) const
515 sal_Int32 i
= getPropertyIndex( aPropertyName
);
517 return getPropertyValueByIndex( obj
, i
);
519 throw UnknownPropertyException(aPropertyName
);
522 Any
IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any
& obj
, sal_Int32 nSequenceIndex
) const
526 // Is there anything suitable in the passed object?
527 Reference
<XInterface
> xInterface
;
528 if( !(obj
>>= xInterface
) )
530 TypeClass eObjType
= obj
.getValueType().getTypeClass();
531 if( nSequenceIndex
>= mnPropCount
|| ( eObjType
!= TypeClass_STRUCT
&& eObjType
!= TypeClass_EXCEPTION
) )
533 // throw IllegalArgumentException();
538 switch( maMapTypeSeq
[ nSequenceIndex
] )
540 case MAP_PROPERTY_SET
:
543 const Property
& rProp
= maAllPropertySeq
[ nSequenceIndex
];
545 // Do we have a FastPropertySet and a valid handle?
546 // NOTE: At this point is exploited that the PropertySet
547 // is queried at the beginning of introspection process.
548 sal_Int32 nOrgHandle
;
549 if( mbFastPropSet
&& ( nOrgHandle
= mpOrgPropertyHandleArray
[ nSequenceIndex
] ) != -1 )
551 // Fetch the PropertySet interface
552 Reference
<XFastPropertySet
> xFastPropSet
=
553 Reference
<XFastPropertySet
>::query( xInterface
);
554 if( xFastPropSet
.is() )
556 aRet
= xFastPropSet
->getFastPropertyValue( nOrgHandle
);
560 // throw UnknownPropertyException
564 // Otherwise use the normal one
567 // Fetch the PropertySet interface
568 Reference
<XPropertySet
> xPropSet
=
569 Reference
<XPropertySet
>::query( xInterface
);
572 aRet
= xPropSet
->getPropertyValue( rProp
.Name
);
576 // throw UnknownPropertyException
585 Reference
<XIdlField
> xField
= static_cast<XIdlField
*>(aInterfaceSeq1
[ nSequenceIndex
].get());
588 aRet
= xField
->get( obj
);
589 // IllegalArgumentException
590 // NullPointerException
594 // throw IllegalArgumentException();
603 Reference
<XIdlMethod
> xMethod
= static_cast<XIdlMethod
*>(aInterfaceSeq1
[ nSequenceIndex
].get());
607 aRet
= xMethod
->invoke( obj
, args
);
611 // throw IllegalArgumentException();
618 // Get method does not exist
619 // throw WriteOnlyPropertyException();
626 // Helper method to adjust the size of the vectors
627 void IntrospectionAccessStatic_Impl::checkPropertyArraysSize( sal_Int32 iNextIndex
)
629 sal_Int32 nLen
= static_cast<sal_Int32
>(maAllPropertySeq
.size());
630 if( iNextIndex
>= nLen
)
632 maAllPropertySeq
.resize( nLen
+ ARRAY_SIZE_STEP
);
633 maMapTypeSeq
.resize( nLen
+ ARRAY_SIZE_STEP
);
634 maPropertyConceptSeq
.resize( nLen
+ ARRAY_SIZE_STEP
);
638 void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( std::vector
< Reference
<XInterface
> >& rSeq
,
639 std::vector
<Reference
<XInterface
>>& rInterfaceVec
, sal_Int32 iNextIndex
)
641 sal_Int32 nLen
= rSeq
.size();
642 if( iNextIndex
>= nLen
)
644 // Synchronize new size with ARRAY_SIZE_STEP
645 sal_Int32 nMissingSize
= iNextIndex
- nLen
+ 1;
646 sal_Int32 nSteps
= nMissingSize
/ ARRAY_SIZE_STEP
+ 1;
647 sal_Int32 nNewSize
= nLen
+ nSteps
* ARRAY_SIZE_STEP
;
649 rSeq
.resize( nNewSize
);
650 rInterfaceVec
= rSeq
;
655 //*** ImplIntrospectionAccess ***
658 // New Impl class as part of the introspection conversion to instance-bound
659 // Introspection with property access via XPropertySet. The old class
660 // ImplIntrospectionAccess lives on as IntrospectionAccessStatic_Impl
661 class ImplIntrospectionAccess
: public IntrospectionAccessHelper
663 friend class Implementation
;
665 // Object under examination
666 Any maInspectedObject
;
669 Reference
<XInterface
> mxIface
;
671 // Static introspection data
672 rtl::Reference
< IntrospectionAccessStatic_Impl
> mpStaticImpl
;
674 // Last Sequence that came with getProperties (optimization)
675 Sequence
<Property
> maLastPropertySeq
;
676 sal_Int32 mnLastPropertyConcept
;
678 // Last Sequence that came with getMethods (optimization)
679 Sequence
<Reference
<XIdlMethod
> > maLastMethodSeq
;
680 sal_Int32 mnLastMethodConcept
;
682 // Guards the caching of queried interfaces
685 // Original interfaces of the objects
686 Reference
<XElementAccess
> mxObjElementAccess
;
687 Reference
<XNameContainer
> mxObjNameContainer
;
688 Reference
<XNameReplace
> mxObjNameReplace
;
689 Reference
<XNameAccess
> mxObjNameAccess
;
690 Reference
<XIndexContainer
> mxObjIndexContainer
;
691 Reference
<XIndexReplace
> mxObjIndexReplace
;
692 Reference
<XIndexAccess
> mxObjIndexAccess
;
693 Reference
<XEnumerationAccess
> mxObjEnumerationAccess
;
694 Reference
<XIdlArray
> mxObjIdlArray
;
696 Reference
<XElementAccess
> getXElementAccess();
697 Reference
<XNameContainer
> getXNameContainer();
698 Reference
<XNameReplace
> getXNameReplace();
699 Reference
<XNameAccess
> getXNameAccess();
700 Reference
<XIndexContainer
> getXIndexContainer();
701 Reference
<XIndexReplace
> getXIndexReplace();
702 Reference
<XIndexAccess
> getXIndexAccess();
703 Reference
<XEnumerationAccess
> getXEnumerationAccess();
704 Reference
<XIdlArray
> getXIdlArray();
706 void cacheXNameContainer();
707 void cacheXIndexContainer();
710 ImplIntrospectionAccess( const Any
& obj
, rtl::Reference
< IntrospectionAccessStatic_Impl
> const & pStaticImpl_
);
712 // Methods from XIntrospectionAccess
713 virtual sal_Int32 SAL_CALL
getSuppliedMethodConcepts() override
;
714 virtual sal_Int32 SAL_CALL
getSuppliedPropertyConcepts() override
;
715 virtual Property SAL_CALL
getProperty(const OUString
& Name
, sal_Int32 PropertyConcepts
) override
;
716 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
, sal_Int32 PropertyConcepts
) override
;
717 virtual Sequence
< Property
> SAL_CALL
getProperties(sal_Int32 PropertyConcepts
) override
;
718 virtual Reference
<XIdlMethod
> SAL_CALL
getMethod(const OUString
& Name
, sal_Int32 MethodConcepts
) override
;
719 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
, sal_Int32 MethodConcepts
) override
;
720 virtual Sequence
< Reference
<XIdlMethod
> > SAL_CALL
getMethods(sal_Int32 MethodConcepts
) override
;
721 virtual Sequence
< Type
> SAL_CALL
getSupportedListeners() override
;
722 using OWeakObject::queryAdapter
;
723 virtual Reference
<XInterface
> SAL_CALL
queryAdapter( const Type
& rType
) override
;
725 // Methods from XMaterialHolder
726 virtual Any SAL_CALL
getMaterial() override
;
728 // Methods from XExactName
729 virtual OUString SAL_CALL
getExactName( const OUString
& rApproximateName
) override
;
731 // Methods from XInterface
732 virtual Any SAL_CALL
queryInterface( const Type
& rType
) override
;
733 virtual void SAL_CALL
acquire() throw() override
{ OWeakObject::acquire(); }
734 virtual void SAL_CALL
release() throw() override
{ OWeakObject::release(); }
736 // Methods from XPropertySet
737 virtual Reference
<XPropertySetInfo
> SAL_CALL
getPropertySetInfo() override
;
738 virtual void SAL_CALL
setPropertyValue(const OUString
& aPropertyName
, const Any
& aValue
) override
;
739 virtual Any SAL_CALL
getPropertyValue(const OUString
& aPropertyName
) override
;
740 virtual void SAL_CALL
addPropertyChangeListener(const OUString
& aPropertyName
, const Reference
<XPropertyChangeListener
>& aListener
) override
;
741 virtual void SAL_CALL
removePropertyChangeListener(const OUString
& aPropertyName
, const Reference
<XPropertyChangeListener
>& aListener
) override
;
742 virtual void SAL_CALL
addVetoableChangeListener(const OUString
& aPropertyName
, const Reference
<XVetoableChangeListener
>& aListener
) override
;
743 virtual void SAL_CALL
removeVetoableChangeListener(const OUString
& aPropertyName
, const Reference
<XVetoableChangeListener
>& aListener
) override
;
745 // Methods from XFastPropertySet
746 virtual void SAL_CALL
setFastPropertyValue(sal_Int32 nHandle
, const Any
& aValue
) override
;
747 virtual Any SAL_CALL
getFastPropertyValue(sal_Int32 nHandle
) override
;
749 // Methods from XPropertySetInfo
750 virtual Sequence
< Property
> SAL_CALL
getProperties() override
;
751 virtual Property SAL_CALL
getPropertyByName(const OUString
& Name
) override
;
752 virtual sal_Bool SAL_CALL
hasPropertyByName(const OUString
& Name
) override
;
754 // Methods from XElementAccess
755 virtual Type SAL_CALL
getElementType() override
;
756 virtual sal_Bool SAL_CALL
hasElements() override
;
758 // Methods from XNameAccess
759 virtual Any SAL_CALL
getByName(const OUString
& Name
) override
;
760 virtual Sequence
< OUString
> SAL_CALL
getElementNames() override
;
761 virtual sal_Bool SAL_CALL
hasByName(const OUString
& Name
) override
;
763 // Methods from XNameReplace
764 virtual void SAL_CALL
replaceByName(const OUString
& Name
, const Any
& Element
) override
;
766 // Methods from XNameContainer
767 virtual void SAL_CALL
insertByName(const OUString
& Name
, const Any
& Element
) override
;
768 virtual void SAL_CALL
removeByName(const OUString
& Name
) override
;
770 // Methods from XIndexAccess
771 virtual sal_Int32 SAL_CALL
getCount() override
;
772 virtual Any SAL_CALL
getByIndex(sal_Int32 Index
) override
;
774 // Methods from XIndexReplace
775 virtual void SAL_CALL
replaceByIndex(sal_Int32 Index
, const Any
& Element
) override
;
777 // Methods from XIndexContainer
778 virtual void SAL_CALL
insertByIndex(sal_Int32 Index
, const Any
& Element
) override
;
779 virtual void SAL_CALL
removeByIndex(sal_Int32 Index
) override
;
781 // Methods from XEnumerationAccess
782 virtual Reference
<XEnumeration
> SAL_CALL
createEnumeration() override
;
784 // Methods from XIdlArray
785 virtual void SAL_CALL
realloc(Any
& array
, sal_Int32 length
) override
;
786 virtual sal_Int32 SAL_CALL
getLen(const Any
& array
) override
;
787 virtual Any SAL_CALL
get(const Any
& array
, sal_Int32 index
) override
;
788 virtual void SAL_CALL
set(Any
& array
, sal_Int32 index
, const Any
& value
) override
;
790 // Methods from XUnoTunnel
791 virtual sal_Int64 SAL_CALL
getSomething( const Sequence
< sal_Int8
>& aIdentifier
) override
;
794 ImplIntrospectionAccess::ImplIntrospectionAccess
795 ( const Any
& obj
, rtl::Reference
< IntrospectionAccessStatic_Impl
> const & pStaticImpl_
)
796 : maInspectedObject( obj
), mpStaticImpl( pStaticImpl_
) //, maAdapter()
798 // Save object as an interface if possible
799 maInspectedObject
>>= mxIface
;
801 mnLastPropertyConcept
= -1;
802 mnLastMethodConcept
= -1;
805 Reference
<XElementAccess
> ImplIntrospectionAccess::getXElementAccess()
807 ResettableGuard
< Mutex
> aGuard( m_aMutex
);
809 if( !mxObjElementAccess
.is() )
812 Reference
<XElementAccess
> xElementAccess( mxIface
, UNO_QUERY
);
814 if( !mxObjElementAccess
.is() )
815 mxObjElementAccess
= xElementAccess
;
817 return mxObjElementAccess
;
820 void ImplIntrospectionAccess::cacheXNameContainer()
822 Reference
<XNameContainer
> xNameContainer
;
823 Reference
<XNameReplace
> xNameReplace
;
824 Reference
<XNameAccess
> xNameAccess
;
825 if (mpStaticImpl
->mbNameContainer
)
827 xNameContainer
.set( mxIface
, UNO_QUERY
);
828 xNameReplace
.set( xNameContainer
, UNO_QUERY
);
829 xNameAccess
.set( xNameContainer
, UNO_QUERY
);
831 else if (mpStaticImpl
->mbNameReplace
)
833 xNameReplace
.set( mxIface
, UNO_QUERY
);
834 xNameAccess
.set( xNameReplace
, UNO_QUERY
);
836 else if (mpStaticImpl
->mbNameAccess
)
838 xNameAccess
.set( mxIface
, UNO_QUERY
);
842 MutexGuard
aGuard( m_aMutex
);
843 if( !mxObjNameContainer
.is() )
844 mxObjNameContainer
= xNameContainer
;
845 if( !mxObjNameReplace
.is() )
846 mxObjNameReplace
= xNameReplace
;
847 if( !mxObjNameAccess
.is() )
848 mxObjNameAccess
= xNameAccess
;
852 Reference
<XNameContainer
> ImplIntrospectionAccess::getXNameContainer()
854 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
856 if( !mxObjNameContainer
.is() )
859 cacheXNameContainer();
861 return mxObjNameContainer
;
864 Reference
<XNameReplace
> ImplIntrospectionAccess::getXNameReplace()
866 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
868 if( !mxObjNameReplace
.is() )
871 cacheXNameContainer();
873 return mxObjNameReplace
;
876 Reference
<XNameAccess
> ImplIntrospectionAccess::getXNameAccess()
878 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
880 if( !mxObjNameAccess
.is() )
883 cacheXNameContainer();
885 return mxObjNameAccess
;
888 void ImplIntrospectionAccess::cacheXIndexContainer()
890 Reference
<XIndexContainer
> xIndexContainer
;
891 Reference
<XIndexReplace
> xIndexReplace
;
892 Reference
<XIndexAccess
> xIndexAccess
;
893 if (mpStaticImpl
->mbIndexContainer
)
895 xIndexContainer
.set( mxIface
, UNO_QUERY
);
896 xIndexReplace
.set( xIndexContainer
, UNO_QUERY
);
897 xIndexAccess
.set( xIndexContainer
, UNO_QUERY
);
899 else if (mpStaticImpl
->mbIndexReplace
)
901 xIndexReplace
.set( mxIface
, UNO_QUERY
);
902 xIndexAccess
.set( xIndexReplace
, UNO_QUERY
);
904 else if (mpStaticImpl
->mbIndexAccess
)
906 xIndexAccess
.set( mxIface
, UNO_QUERY
);
910 MutexGuard
aGuard( m_aMutex
);
911 if( !mxObjIndexContainer
.is() )
912 mxObjIndexContainer
= xIndexContainer
;
913 if( !mxObjIndexReplace
.is() )
914 mxObjIndexReplace
= xIndexReplace
;
915 if( !mxObjIndexAccess
.is() )
916 mxObjIndexAccess
= xIndexAccess
;
920 Reference
<XIndexContainer
> ImplIntrospectionAccess::getXIndexContainer()
922 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
924 if( !mxObjIndexContainer
.is() )
927 cacheXIndexContainer();
929 return mxObjIndexContainer
;
932 Reference
<XIndexReplace
> ImplIntrospectionAccess::getXIndexReplace()
934 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
936 if( !mxObjIndexReplace
.is() )
939 cacheXIndexContainer();
941 return mxObjIndexReplace
;
944 Reference
<XIndexAccess
> ImplIntrospectionAccess::getXIndexAccess()
946 ClearableGuard
< Mutex
> aGuard( m_aMutex
);
948 if( !mxObjIndexAccess
.is() )
951 cacheXIndexContainer();
953 return mxObjIndexAccess
;
956 Reference
<XEnumerationAccess
> ImplIntrospectionAccess::getXEnumerationAccess()
958 ResettableGuard
< Mutex
> aGuard( m_aMutex
);
960 if( !mxObjEnumerationAccess
.is() )
963 Reference
<XEnumerationAccess
> xEnumerationAccess( mxIface
, UNO_QUERY
);
965 if( !mxObjEnumerationAccess
.is() )
966 mxObjEnumerationAccess
= xEnumerationAccess
;
968 return mxObjEnumerationAccess
;
971 Reference
<XIdlArray
> ImplIntrospectionAccess::getXIdlArray()
973 ResettableGuard
< Mutex
> aGuard( m_aMutex
);
975 if( !mxObjIdlArray
.is() )
978 Reference
<XIdlArray
> xIdlArray( mxIface
, UNO_QUERY
);
980 if( !mxObjIdlArray
.is() )
981 mxObjIdlArray
= xIdlArray
;
983 return mxObjIdlArray
;
986 // Methods from XInterface
987 Any SAL_CALL
ImplIntrospectionAccess::queryInterface( const Type
& rType
)
989 Any
aRet( ::cppu::queryInterface(
991 static_cast< XIntrospectionAccess
* >( this ),
992 static_cast< XMaterialHolder
* >( this ),
993 static_cast< XExactName
* >( this ),
994 static_cast< XPropertySet
* >( this ),
995 static_cast< XFastPropertySet
* >( this ),
996 static_cast< XPropertySetInfo
* >( this ) ) );
997 if( !aRet
.hasValue() )
998 aRet
= OWeakObject::queryInterface( rType
);
1000 if( !aRet
.hasValue() )
1002 // Wrapper for the object interfaces
1003 ( mpStaticImpl
->mbElementAccess
&& (aRet
= ::cppu::queryInterface
1004 ( rType
, static_cast< XElementAccess
* >( static_cast< XNameAccess
* >( this ) ) ) ).hasValue() )
1005 || ( mpStaticImpl
->mbNameAccess
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XNameAccess
* >( this ) ) ).hasValue() )
1006 || ( mpStaticImpl
->mbNameReplace
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XNameReplace
* >( this ) ) ).hasValue() )
1007 || ( mpStaticImpl
->mbNameContainer
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XNameContainer
* >( this ) ) ).hasValue() )
1008 || ( mpStaticImpl
->mbIndexAccess
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XIndexAccess
* >( this ) ) ).hasValue() )
1009 || ( mpStaticImpl
->mbIndexReplace
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XIndexReplace
* >( this ) ) ).hasValue() )
1010 || ( mpStaticImpl
->mbIndexContainer
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XIndexContainer
* >( this ) ) ).hasValue() )
1011 || ( mpStaticImpl
->mbEnumerationAccess
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XEnumerationAccess
* >( this ) ) ).hasValue() )
1012 || ( mpStaticImpl
->mbIdlArray
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XIdlArray
* >( this ) ) ).hasValue() )
1013 || ( mpStaticImpl
->mbUnoTunnel
&& (aRet
= ::cppu::queryInterface( rType
, static_cast< XUnoTunnel
* >( this ) ) ).hasValue() );
1019 //*** Implementation of ImplIntrospectionAdapter ***
1022 // Methods from XPropertySet
1023 Reference
<XPropertySetInfo
> ImplIntrospectionAccess::getPropertySetInfo()
1025 return static_cast<XPropertySetInfo
*>(this);
1028 void ImplIntrospectionAccess::setPropertyValue(const OUString
& aPropertyName
, const Any
& aValue
)
1030 mpStaticImpl
->setPropertyValue( maInspectedObject
, aPropertyName
, aValue
);
1033 Any
ImplIntrospectionAccess::getPropertyValue(const OUString
& aPropertyName
)
1035 return mpStaticImpl
->getPropertyValue( maInspectedObject
, aPropertyName
);
1038 void ImplIntrospectionAccess::addPropertyChangeListener(const OUString
& aPropertyName
, const Reference
<XPropertyChangeListener
>& aListener
)
1042 Reference
<XPropertySet
> xPropSet
=
1043 Reference
<XPropertySet
>::query( mxIface
);
1044 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
1046 xPropSet
->addPropertyChangeListener(aPropertyName
, aListener
);
1050 void ImplIntrospectionAccess::removePropertyChangeListener(const OUString
& aPropertyName
, const Reference
<XPropertyChangeListener
>& aListener
)
1054 Reference
<XPropertySet
> xPropSet
=
1055 Reference
<XPropertySet
>::query( mxIface
);
1056 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
1058 xPropSet
->removePropertyChangeListener(aPropertyName
, aListener
);
1062 void ImplIntrospectionAccess::addVetoableChangeListener(const OUString
& aPropertyName
, const Reference
<XVetoableChangeListener
>& aListener
)
1066 Reference
<XPropertySet
> xPropSet
=
1067 Reference
<XPropertySet
>::query( mxIface
);
1068 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
1070 xPropSet
->addVetoableChangeListener(aPropertyName
, aListener
);
1074 void ImplIntrospectionAccess::removeVetoableChangeListener(const OUString
& aPropertyName
, const Reference
<XVetoableChangeListener
>& aListener
)
1078 Reference
<XPropertySet
> xPropSet
=
1079 Reference
<XPropertySet
>::query( mxIface
);
1081 xPropSet
->removeVetoableChangeListener(aPropertyName
, aListener
);
1086 // Methods from XFastPropertySet
1087 void ImplIntrospectionAccess::setFastPropertyValue(sal_Int32
, const Any
&)
1091 Any
ImplIntrospectionAccess::getFastPropertyValue(sal_Int32
)
1096 // Methods from XPropertySetInfo
1097 Sequence
< Property
> ImplIntrospectionAccess::getProperties()
1099 return comphelper::containerToSequence(mpStaticImpl
->getProperties());
1102 Property
ImplIntrospectionAccess::getPropertyByName(const OUString
& Name
)
1104 return getProperty( Name
, PropertyConcept::ALL
);
1107 sal_Bool
ImplIntrospectionAccess::hasPropertyByName(const OUString
& Name
)
1109 return hasProperty( Name
, PropertyConcept::ALL
);
1112 // Methods from XElementAccess
1113 Type
ImplIntrospectionAccess::getElementType()
1115 return getXElementAccess()->getElementType();
1118 sal_Bool
ImplIntrospectionAccess::hasElements()
1120 return getXElementAccess()->hasElements();
1123 // Methods from XNameAccess
1124 Any
ImplIntrospectionAccess::getByName(const OUString
& Name
)
1126 return getXNameAccess()->getByName( Name
);
1129 Sequence
< OUString
> ImplIntrospectionAccess::getElementNames()
1131 return getXNameAccess()->getElementNames();
1134 sal_Bool
ImplIntrospectionAccess::hasByName(const OUString
& Name
)
1136 return getXNameAccess()->hasByName( Name
);
1139 // Methods from XNameContainer
1140 void ImplIntrospectionAccess::insertByName(const OUString
& Name
, const Any
& Element
)
1142 getXNameContainer()->insertByName( Name
, Element
);
1145 void ImplIntrospectionAccess::replaceByName(const OUString
& Name
, const Any
& Element
)
1147 getXNameReplace()->replaceByName( Name
, Element
);
1150 void ImplIntrospectionAccess::removeByName(const OUString
& Name
)
1152 getXNameContainer()->removeByName( Name
);
1155 // Methods from XIndexAccess
1156 // Already in XNameAccess: virtual Reference<XIdlClass> getElementType() const
1157 sal_Int32
ImplIntrospectionAccess::getCount()
1159 return getXIndexAccess()->getCount();
1162 Any
ImplIntrospectionAccess::getByIndex(sal_Int32 Index
)
1164 return getXIndexAccess()->getByIndex( Index
);
1167 // Methods from XIndexContainer
1168 void ImplIntrospectionAccess::insertByIndex(sal_Int32 Index
, const Any
& Element
)
1170 getXIndexContainer()->insertByIndex( Index
, Element
);
1173 void ImplIntrospectionAccess::replaceByIndex(sal_Int32 Index
, const Any
& Element
)
1175 getXIndexReplace()->replaceByIndex( Index
, Element
);
1178 void ImplIntrospectionAccess::removeByIndex(sal_Int32 Index
)
1180 getXIndexContainer()->removeByIndex( Index
);
1183 // Methods from XEnumerationAccess
1184 // Already in XNameAccess: virtual Reference<XIdlClass> getElementType() const;
1185 Reference
<XEnumeration
> ImplIntrospectionAccess::createEnumeration()
1187 return getXEnumerationAccess()->createEnumeration();
1190 // Methods from XIdlArray
1191 void ImplIntrospectionAccess::realloc(Any
& array
, sal_Int32 length
)
1193 getXIdlArray()->realloc( array
, length
);
1196 sal_Int32
ImplIntrospectionAccess::getLen(const Any
& array
)
1198 return getXIdlArray()->getLen( array
);
1201 Any
ImplIntrospectionAccess::get(const Any
& array
, sal_Int32 index
)
1203 return getXIdlArray()->get( array
, index
);
1206 void ImplIntrospectionAccess::set(Any
& array
, sal_Int32 index
, const Any
& value
)
1208 getXIdlArray()->set( array
, index
, value
);
1211 // Methods from XUnoTunnel
1212 sal_Int64
ImplIntrospectionAccess::getSomething( const Sequence
< sal_Int8
>& aIdentifier
)
1214 return Reference
<XUnoTunnel
>::query( mxIface
)->getSomething( aIdentifier
);
1218 //*** Implementation of ImplIntrospectionAccess ***
1220 // Methods from XIntrospectionAccess
1221 sal_Int32
ImplIntrospectionAccess::getSuppliedMethodConcepts()
1223 return MethodConcept::DANGEROUS
|
1231 sal_Int32
ImplIntrospectionAccess::getSuppliedPropertyConcepts()
1233 return PropertyConcept::DANGEROUS
|
1239 Property
ImplIntrospectionAccess::getProperty(const OUString
& Name
, sal_Int32 PropertyConcepts
)
1242 sal_Int32 i
= mpStaticImpl
->getPropertyIndex( Name
);
1243 bool bFound
= false;
1246 sal_Int32 nConcept
= mpStaticImpl
->getPropertyConcepts()[ i
];
1247 if( (PropertyConcepts
& nConcept
) != 0 )
1249 aRet
= mpStaticImpl
->getProperties()[ i
];
1254 throw NoSuchElementException(Name
);
1258 sal_Bool
ImplIntrospectionAccess::hasProperty(const OUString
& Name
, sal_Int32 PropertyConcepts
)
1260 sal_Int32 i
= mpStaticImpl
->getPropertyIndex( Name
);
1264 sal_Int32 nConcept
= mpStaticImpl
->getPropertyConcepts()[ i
];
1265 if( (PropertyConcepts
& nConcept
) != 0 )
1271 Sequence
< Property
> ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts
)
1273 // If all supported concepts are required, simply pass through the sequence
1274 sal_Int32 nAllSupportedMask
= PROPERTYSET
|
1277 if( ( PropertyConcepts
& nAllSupportedMask
) == nAllSupportedMask
)
1279 return comphelper::containerToSequence(mpStaticImpl
->getProperties());
1282 // Same sequence as last time?
1283 if( mnLastPropertyConcept
== PropertyConcepts
)
1285 return maLastPropertySeq
;
1288 // Number of properties to be delivered
1289 sal_Int32 nCount
= 0;
1291 // There are currently no DANGEROUS properties
1292 // if( PropertyConcepts & DANGEROUS )
1293 // nCount += mpStaticImpl->mnDangerousPropCount;
1294 if( PropertyConcepts
& PROPERTYSET
)
1295 nCount
+= mpStaticImpl
->mnPropertySetPropCount
;
1296 if( PropertyConcepts
& ATTRIBUTES
)
1297 nCount
+= mpStaticImpl
->mnAttributePropCount
;
1298 if( PropertyConcepts
& METHODS
)
1299 nCount
+= mpStaticImpl
->mnMethodPropCount
;
1301 // Realloc sequence according to the required number
1302 maLastPropertySeq
.realloc( nCount
);
1303 Property
* pDestProps
= maLastPropertySeq
.getArray();
1305 // Go through all the properties and apply according to the concept
1306 const std::vector
<Property
>& rPropSeq
= mpStaticImpl
->getProperties();
1307 const std::vector
<sal_Int32
>& rConcepts
= mpStaticImpl
->getPropertyConcepts();
1308 sal_Int32 nLen
= static_cast<sal_Int32
>(rPropSeq
.size());
1310 sal_Int32 iDest
= 0;
1311 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
1313 sal_Int32 nConcept
= rConcepts
[ i
];
1314 if( nConcept
& PropertyConcepts
)
1315 pDestProps
[ iDest
++ ] = rPropSeq
[ i
];
1318 // Remember PropertyConcept representing maLastPropertySeq
1319 mnLastPropertyConcept
= PropertyConcepts
;
1321 // Supply assembled Sequence
1322 return maLastPropertySeq
;
1325 Reference
<XIdlMethod
> ImplIntrospectionAccess::getMethod(const OUString
& Name
, sal_Int32 MethodConcepts
)
1327 Reference
<XIdlMethod
> xRet
;
1328 sal_Int32 i
= mpStaticImpl
->getMethodIndex( Name
);
1332 sal_Int32 nConcept
= mpStaticImpl
->getMethodConcepts()[ i
];
1333 if( (MethodConcepts
& nConcept
) != 0 )
1335 xRet
= mpStaticImpl
->getMethods()[i
];
1339 throw NoSuchMethodException(Name
);
1343 sal_Bool
ImplIntrospectionAccess::hasMethod(const OUString
& Name
, sal_Int32 MethodConcepts
)
1345 sal_Int32 i
= mpStaticImpl
->getMethodIndex( Name
);
1349 sal_Int32 nConcept
= mpStaticImpl
->getMethodConcepts()[ i
];
1350 if( (MethodConcepts
& nConcept
) != 0 )
1356 Sequence
< Reference
<XIdlMethod
> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts
)
1358 // If all supported concepts are required, simply pass through the sequence
1359 sal_Int32 nAllSupportedMask
= MethodConcept::DANGEROUS
|
1365 MethodConcept_NORMAL_IMPL
;
1366 if( ( MethodConcepts
& nAllSupportedMask
) == nAllSupportedMask
)
1368 return comphelper::containerToSequence(mpStaticImpl
->getMethods());
1371 // Same sequence as last time?
1372 if( mnLastMethodConcept
== MethodConcepts
)
1374 return maLastMethodSeq
;
1377 // Get method sequences
1378 const std::vector
< Reference
<XIdlMethod
> >& aMethodSeq
= mpStaticImpl
->getMethods();
1379 sal_Int32 nLen
= static_cast<sal_Int32
>(aMethodSeq
.size());
1381 // Realloc sequence according to the required number
1382 // Unlike Properties, the number can not be determined by counters in
1383 // inspect() beforehand, since methods can belong to several concepts
1384 maLastMethodSeq
.realloc( nLen
);
1385 Reference
<XIdlMethod
>* pDestMethods
= maLastMethodSeq
.getArray();
1387 // Go through all the methods and apply according to the concept
1388 sal_Int32 iDest
= 0;
1389 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
1391 sal_Int32 nConcept
= mpStaticImpl
->getMethodConcepts()[ i
];
1392 if( nConcept
& MethodConcepts
)
1393 pDestMethods
[ iDest
++ ] = aMethodSeq
[ i
];
1396 // Bring to the correct length
1397 maLastMethodSeq
.realloc( iDest
);
1399 // Remember MethodConcept representing maLastMethodSeq
1400 mnLastMethodConcept
= MethodConcepts
;
1402 // Supply assembled Sequence
1403 return maLastMethodSeq
;
1406 Sequence
< Type
> ImplIntrospectionAccess::getSupportedListeners()
1408 return comphelper::containerToSequence(mpStaticImpl
->getSupportedListeners());
1411 Reference
<XInterface
> SAL_CALL
ImplIntrospectionAccess::queryAdapter( const Type
& rType
)
1413 Reference
<XInterface
> xRet
;
1414 if( rType
== cppu::UnoType
<XInterface
>::get()
1415 || rType
== cppu::UnoType
<XPropertySet
>::get()
1416 || rType
== cppu::UnoType
<XFastPropertySet
>::get()
1417 || rType
== cppu::UnoType
<XPropertySetInfo
>::get()
1418 || rType
== cppu::UnoType
<XElementAccess
>::get()
1419 || rType
== cppu::UnoType
<XNameAccess
>::get()
1420 || rType
== cppu::UnoType
<XNameReplace
>::get()
1421 || rType
== cppu::UnoType
<XNameContainer
>::get()
1422 || rType
== cppu::UnoType
<XIndexAccess
>::get()
1423 || rType
== cppu::UnoType
<XIndexReplace
>::get()
1424 || rType
== cppu::UnoType
<XIndexContainer
>::get()
1425 || rType
== cppu::UnoType
<XEnumerationAccess
>::get()
1426 || rType
== cppu::UnoType
<XIdlArray
>::get()
1427 || rType
== cppu::UnoType
<XUnoTunnel
>::get() )
1429 queryInterface( rType
) >>= xRet
;
1434 // Methods from XMaterialHolder
1435 Any
ImplIntrospectionAccess::getMaterial()
1437 return maInspectedObject
;
1440 // Methods from XExactName
1441 OUString
ImplIntrospectionAccess::getExactName( const OUString
& rApproximateName
)
1444 LowerToExactNameMap::iterator aIt
=
1445 mpStaticImpl
->maLowerToExactNameMap
.find( rApproximateName
.toAsciiLowerCase() );
1446 if (aIt
!= mpStaticImpl
->maLowerToExactNameMap
.end())
1447 aRetStr
= (*aIt
).second
;
1453 css::uno::Reference
<css::beans::XPropertySetInfo
> const & theProperties
,
1454 std::vector
<css::uno::Type
> const & theTypes
):
1455 properties(theProperties
)
1457 //TODO: Could even sort the types lexicographically first, to increase
1458 // the chance of matches between different implementations' getTypes(),
1459 // but the old scheme of using getImplementationId() would have missed
1460 // those matches, too:
1462 for (const css::uno::Type
& rType
: theTypes
) {
1463 b
.append(rType
.getTypeName());
1464 b
.append('*'); // arbitrary delimiter not used by type grammar
1466 types
= b
.makeStringAndClear();
1469 css::uno::Reference
<css::beans::XPropertySetInfo
> properties
;
1473 struct TypeKeyLess
{
1474 bool operator ()(TypeKey
const & key1
, TypeKey
const & key2
) const {
1475 if (key1
.properties
.get() < key2
.properties
.get()) {
1478 if (key1
.properties
.get() > key2
.properties
.get()) {
1481 return key1
.types
< key2
.types
;
1485 template<typename Key
, typename Less
> class Cache
{
1487 rtl::Reference
<IntrospectionAccessStatic_Impl
> find(Key
const & key
) const {
1488 typename
Map::const_iterator
i(map_
.find(key
));
1489 if (i
== map_
.end()) {
1490 return rtl::Reference
<IntrospectionAccessStatic_Impl
>();
1492 if (i
->second
.hits
< std::numeric_limits
<unsigned>::max()) {
1495 assert(i
->second
.access
.is());
1496 return i
->second
.access
;
1502 rtl::Reference
<IntrospectionAccessStatic_Impl
> const & access
)
1504 assert(access
.is());
1505 typename
Map::size_type
const MAX
= 100;
1506 assert(map_
.size() <= MAX
);
1507 if (map_
.size() == MAX
) {
1508 typename
Map::iterator
del(map_
.begin());
1509 for (typename
Map::iterator
i(map_
.begin()); i
!= map_
.end(); ++i
) {
1510 if (i
->second
.hits
< del
->second
.hits
) {
1516 bool ins
= map_
.emplace(key
, Data(access
)).second
;
1517 assert(ins
); (void)ins
;
1520 void clear() { map_
.clear(); }
1525 rtl::Reference
<IntrospectionAccessStatic_Impl
> const & theAccess
):
1526 access(theAccess
), hits(1)
1529 rtl::Reference
<IntrospectionAccessStatic_Impl
> access
;
1530 mutable unsigned hits
;
1533 typedef std::map
<Key
, Data
, Less
> Map
;
1539 cppu::WeakComponentImplHelper
<
1540 css::lang::XServiceInfo
, css::beans::XIntrospection
>
1541 Implementation_Base
;
1543 class Implementation
: private cppu::BaseMutex
, public Implementation_Base
{
1545 explicit Implementation(
1546 css::uno::Reference
<css::uno::XComponentContext
> const & context
):
1547 Implementation_Base(m_aMutex
),
1548 reflection_(css::reflection::theCoreReflection::get(context
))
1552 virtual void SAL_CALL
disposing() override
{
1553 osl::MutexGuard
g(m_aMutex
);
1554 reflection_
.clear();
1558 virtual OUString SAL_CALL
getImplementationName() override
1559 { return OUString("com.sun.star.comp.stoc.Introspection"); }
1561 virtual sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
1562 { return cppu::supportsService(this, ServiceName
); }
1564 virtual css::uno::Sequence
<OUString
> SAL_CALL
1565 getSupportedServiceNames() override
1567 Sequence
<OUString
> s
{ "com.sun.star.beans.Introspection" };
1571 virtual css::uno::Reference
<css::beans::XIntrospectionAccess
> SAL_CALL
1572 inspect(css::uno::Any
const & aObject
) override
;
1574 css::uno::Reference
<css::reflection::XIdlReflection
> reflection_
;
1575 Cache
<TypeKey
, TypeKeyLess
> typeCache_
;
1578 css::uno::Reference
<css::beans::XIntrospectionAccess
> Implementation::inspect(
1579 css::uno::Any
const & aObject
)
1581 css::uno::Reference
<css::reflection::XIdlReflection
> reflection
;
1583 osl::MutexGuard
g(m_aMutex
);
1584 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
) {
1585 throw css::lang::DisposedException(
1586 getImplementationName(), static_cast<OWeakObject
*>(this));
1588 reflection
= reflection_
;
1590 css::uno::Any aToInspectObj
;
1592 if (aObject
>>= t
) {
1593 css::uno::Reference
<css::reflection::XIdlClass
> c(
1594 reflection
->forName(t
.getTypeName()));
1596 SAL_WARN("stoc", "cannot reflect type " << t
.getTypeName());
1597 return css::uno::Reference
<css::beans::XIntrospectionAccess
>();
1599 aToInspectObj
<<= c
;
1601 aToInspectObj
= aObject
;
1605 TypeClass eType
= aToInspectObj
.getValueType().getTypeClass();
1606 if( eType
!= TypeClass_INTERFACE
&& eType
!= TypeClass_STRUCT
&& eType
!= TypeClass_EXCEPTION
)
1607 return css::uno::Reference
<css::beans::XIntrospectionAccess
>();
1609 if( auto x
= o3tl::tryAccess
<Reference
<XInterface
>>(aToInspectObj
) )
1612 return css::uno::Reference
<css::beans::XIntrospectionAccess
>();
1615 // Pointer to possibly needed new IntrospectionAccessStatic_Impl instance
1616 rtl::Reference
< IntrospectionAccessStatic_Impl
> pAccess
;
1618 // Check: Is a matching access object already cached?
1619 std::vector
< Reference
<XIdlClass
> > SupportedClassSeq
;
1620 std::vector
< Type
> SupportedTypesSeq
;
1621 Reference
<XTypeProvider
> xTypeProvider
;
1622 Reference
<XPropertySetInfo
> xPropSetInfo
;
1623 Reference
<XPropertySet
> xPropSet
;
1625 // Look for interfaces XTypeProvider and PropertySet
1626 if( eType
== TypeClass_INTERFACE
)
1628 xTypeProvider
.set( aToInspectObj
, UNO_QUERY
);
1629 if( xTypeProvider
.is() )
1631 SupportedTypesSeq
= comphelper::sequenceToContainer
<std::vector
<Type
>>(xTypeProvider
->getTypes());
1635 "object of type \"" << aToInspectObj
.getValueTypeName()
1636 << "\" lacks XTypeProvider");
1637 SupportedTypesSeq
= { aToInspectObj
.getValueType() };
1639 // Now try to get the PropertySetInfo
1640 xPropSet
.set( aToInspectObj
, UNO_QUERY
);
1642 xPropSetInfo
= xPropSet
->getPropertySetInfo();
1645 SupportedTypesSeq
= { aToInspectObj
.getValueType() };
1649 osl::MutexGuard
g(m_aMutex
);
1650 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
) {
1651 throw css::lang::DisposedException(
1652 getImplementationName(), static_cast<OWeakObject
*>(this));
1654 TypeKey
key(xPropSetInfo
, SupportedTypesSeq
);
1655 pAccess
= typeCache_
.find(key
);
1657 return new ImplIntrospectionAccess(aToInspectObj
, pAccess
);
1659 pAccess
= new IntrospectionAccessStatic_Impl(reflection
);
1660 typeCache_
.insert(key
, pAccess
);
1663 // No access cached -> create new
1664 std::vector
<Property
>& rAllPropArray
= pAccess
->maAllPropertySeq
;
1665 std::vector
<Reference
<XInterface
>>& rInterfaces1
= pAccess
->aInterfaceSeq1
;
1666 std::vector
<Reference
<XInterface
>>& rInterfaces2
= pAccess
->aInterfaceSeq2
;
1667 std::vector
<sal_Int16
>& rMapTypeArray
= pAccess
->maMapTypeSeq
;
1668 std::vector
<sal_Int32
>& rPropertyConceptArray
= pAccess
->maPropertyConceptSeq
;
1671 // References to important data from pAccess
1672 sal_Int32
& rPropCount
= pAccess
->mnPropCount
;
1673 IntrospectionNameMap
& rPropNameMap
= pAccess
->maPropertyNameMap
;
1674 IntrospectionNameMap
& rMethodNameMap
= pAccess
->maMethodNameMap
;
1675 LowerToExactNameMap
& rLowerToExactNameMap
= pAccess
->maLowerToExactNameMap
;
1678 //*** Perform analysis ***
1680 if( eType
== TypeClass_INTERFACE
)
1682 size_t nTypeCount
= SupportedTypesSeq
.size();
1685 SupportedClassSeq
.resize( nTypeCount
);
1687 for( i
= 0 ; i
< static_cast<sal_Int32
>(nTypeCount
) ; i
++ )
1688 SupportedClassSeq
[i
] = reflection
->forName( SupportedTypesSeq
[i
].getTypeName() );
1691 // First look for particular interfaces that are of particular
1692 // importance to the introspection
1694 // Is XPropertySet present?
1695 if( xPropSet
.is() && xPropSetInfo
.is() )
1697 // Is there also a FastPropertySet?
1698 Reference
<XFastPropertySet
> xDummy( aToInspectObj
, UNO_QUERY
);
1699 bool bFast
= pAccess
->mbFastPropSet
= xDummy
.is();
1701 Sequence
<Property
> aPropSeq
= xPropSetInfo
->getProperties();
1702 const Property
* pProps
= aPropSeq
.getConstArray();
1703 sal_Int32 nLen
= aPropSeq
.getLength();
1705 // For a FastPropertySet we must remember the original handles
1707 pAccess
->mpOrgPropertyHandleArray
.reset( new sal_Int32
[ nLen
] );
1709 for( i
= 0 ; i
< nLen
; i
++ )
1711 // Put property in its own list
1712 pAccess
->checkPropertyArraysSize( rPropCount
);
1713 Property
& rProp
= rAllPropArray
[ rPropCount
];
1714 rProp
= pProps
[ i
];
1717 pAccess
->mpOrgPropertyHandleArray
[ i
] = rProp
.Handle
;
1719 // Enter PropCount as a handle for its own FastPropertySet
1720 rProp
.Handle
= rPropCount
;
1722 // Remember type of property
1723 rMapTypeArray
[ rPropCount
] = MAP_PROPERTY_SET
;
1724 rPropertyConceptArray
[ rPropCount
] = PROPERTYSET
;
1725 pAccess
->mnPropertySetPropCount
++;
1727 // Enter name in hash table if not already known
1728 OUString aPropName
= rProp
.Name
;
1730 // Do we already have the name?
1731 IntrospectionNameMap::iterator aIt
= rPropNameMap
.find( aPropName
);
1732 if( aIt
== rPropNameMap
.end() )
1734 // New entry in the hash table
1735 rPropNameMap
[ aPropName
] = rPropCount
;
1737 // Maintain table for XExactName
1738 rLowerToExactNameMap
[ aPropName
.toAsciiLowerCase() ] = aPropName
;
1742 SAL_WARN( "stoc", "Introspection: Property \"" <<
1743 aPropName
<< "\" found more than once in PropertySet" );
1751 // Indices in the export table
1752 sal_Int32 iAllExportedMethod
= 0;
1753 sal_Int32 iAllSupportedListener
= 0;
1755 std::set
<OUString
> seen
;
1757 // Flag, whether XInterface methods should be recorded
1758 // (this must be done only once, allowed initially)
1759 bool bXInterfaceIsInvalid
= false;
1761 // Flag whether the XInterface methods have already been recorded. If
1762 // sal_True, bXInterfaceIsInvalid is activated at the end of the interface
1763 // loop, and XInterface methods are cut off thereafter.
1764 bool bFoundXInterface
= false;
1766 size_t nClassCount
= SupportedClassSeq
.size();
1767 for( sal_Int32 nIdx
= 0 ; nIdx
< static_cast<sal_Int32
>(nClassCount
); nIdx
++ )
1769 Reference
<XIdlClass
> xImplClass2
= SupportedClassSeq
[nIdx
];
1770 while( xImplClass2
.is() )
1772 // Fetch interfaces from the implementation
1773 Sequence
< Reference
<XIdlClass
> > aClassSeq
= xImplClass2
->getInterfaces();
1774 sal_Int32 nIfaceCount
= aClassSeq
.getLength();
1776 aClassSeq
.realloc( nIfaceCount
+ 1 );
1777 aClassSeq
.getArray()[ nIfaceCount
] = xImplClass2
;
1780 const Reference
<XIdlClass
>* pParamArray
= aClassSeq
.getConstArray();
1782 for( sal_Int32 j
= 0 ; j
< nIfaceCount
; j
++ )
1784 const Reference
<XIdlClass
>& rxIfaceClass
= pParamArray
[j
];
1785 if (!seen
.insert(rxIfaceClass
->getName()).second
) {
1789 // 2. Register fields as properties
1792 Sequence
< Reference
<XIdlField
> > fields
= rxIfaceClass
->getFields();
1793 const Reference
<XIdlField
>* pFields
= fields
.getConstArray();
1794 sal_Int32 nLen
= fields
.getLength();
1796 for( i
= 0 ; i
< nLen
; i
++ )
1798 Reference
<XIdlField
> xField
= pFields
[i
];
1799 Reference
<XIdlClass
> xPropType
= xField
->getType();
1801 // Is the property sequence big enough?
1802 pAccess
->checkPropertyArraysSize( rPropCount
);
1804 // Enter in own property array
1805 Property
& rProp
= rAllPropArray
[ rPropCount
];
1806 OUString aFieldName
= xField
->getName();
1807 rProp
.Name
= aFieldName
;
1808 rProp
.Handle
= rPropCount
;
1809 Type
aFieldType( xPropType
->getTypeClass(), xPropType
->getName() );
1810 rProp
.Type
= aFieldType
;
1811 FieldAccessMode eAccessMode
= xField
->getAccessMode();
1812 rProp
.Attributes
= (eAccessMode
== FieldAccessMode_READONLY
||
1813 eAccessMode
== FieldAccessMode_CONST
)
1816 // Enter name in hash table
1817 OUString aPropName
= rProp
.Name
;
1819 // Do we have the name already?
1820 IntrospectionNameMap::iterator aIt
= rPropNameMap
.find( aPropName
);
1821 if (aIt
!= rPropNameMap
.end())
1824 // New entry in the hash table
1825 rPropNameMap
[ aPropName
] = rPropCount
;
1827 // Maintain table for XExactName
1828 rLowerToExactNameMap
[ aPropName
.toAsciiLowerCase() ] = aPropName
;
1831 IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess
->aInterfaceSeq1
,
1832 rInterfaces1
, rPropCount
);
1833 rInterfaces1
[ rPropCount
] = xField
;
1835 // Remember type of property
1836 rMapTypeArray
[ rPropCount
] = MAP_FIELD
;
1837 rPropertyConceptArray
[ rPropCount
] = ATTRIBUTES
;
1838 pAccess
->mnAttributePropCount
++;
1847 // Counter for found listeners
1848 sal_Int32 nListenerCount
= 0;
1850 // Get and remember all methods
1851 Sequence
< Reference
<XIdlMethod
> > methods
= rxIfaceClass
->getMethods();
1852 const Reference
<XIdlMethod
>* pSourceMethods
= methods
.getConstArray();
1853 sal_Int32 nSourceMethodCount
= methods
.getLength();
1855 // 3. a) Search get/set and listener methods
1857 // Create field for information about the methods, so that methods which are not
1858 // related to properties or listeners can easily be found later.
1859 // New: initialise MethodConceptArray
1862 STANDARD_METHOD
, // normal method, not related to properties or listeners
1863 GETSET_METHOD
, // belongs to a get/set property
1864 ADD_LISTENER_METHOD
, // add method of a listener interface
1865 REMOVE_LISTENER_METHOD
, // remove method of a listener interface
1866 INVALID_METHOD
// method whose class is not considered, e.g. XPropertySet
1868 std::unique_ptr
<MethodType
[]> pMethodTypes( new MethodType
[ nSourceMethodCount
] );
1869 std::unique_ptr
<sal_Int32
[]> pLocalMethodConcepts( new sal_Int32
[ nSourceMethodCount
] );
1870 for( i
= 0 ; i
< nSourceMethodCount
; i
++ )
1872 pMethodTypes
[ i
] = STANDARD_METHOD
;
1873 pLocalMethodConcepts
[ i
] = 0;
1876 for( i
= 0 ; i
< nSourceMethodCount
; i
++ )
1879 const Reference
<XIdlMethod
>& rxMethod_i
= pSourceMethods
[i
];
1880 sal_Int32
& rMethodConcept_i
= pLocalMethodConcepts
[ i
];
1883 OUString aMethName
= rxMethod_i
->getName();
1885 // Catalogue methods
1886 // Filter all (?) methods of XInterface so e.g. acquire and release
1887 // can not be called from scripting
1888 rtl::OUString
className(
1889 rxMethod_i
->getDeclaringClass()->getName());
1890 if (className
== "com.sun.star.uno.XInterface") {
1891 bFoundXInterface
= true;
1893 if( bXInterfaceIsInvalid
)
1895 pMethodTypes
[ i
] = INVALID_METHOD
;
1900 if( aMethName
!= "queryInterface" )
1902 rMethodConcept_i
|= MethodConcept::DANGEROUS
;
1906 } else if (className
== "com.sun.star.uno.XAggregation")
1908 if( aMethName
== "setDelegator" )
1910 rMethodConcept_i
|= MethodConcept::DANGEROUS
;
1913 } else if (className
1914 == "com.sun.star.container.XElementAccess")
1916 rMethodConcept_i
|= ( NAMECONTAINER
|
1919 pAccess
->mbElementAccess
= true;
1920 } else if (className
1921 == "com.sun.star.container.XNameContainer")
1923 rMethodConcept_i
|= NAMECONTAINER
;
1924 pAccess
->mbNameContainer
= true;
1925 pAccess
->mbNameReplace
= true;
1926 pAccess
->mbNameAccess
= true;
1927 pAccess
->mbElementAccess
= true;
1928 } else if (className
1929 == "com.sun.star.container.XNameReplace")
1931 rMethodConcept_i
|= NAMECONTAINER
;
1932 pAccess
->mbNameReplace
= true;
1933 pAccess
->mbNameAccess
= true;
1934 pAccess
->mbElementAccess
= true;
1935 } else if (className
1936 == "com.sun.star.container.XNameAccess")
1938 rMethodConcept_i
|= NAMECONTAINER
;
1939 pAccess
->mbNameAccess
= true;
1940 pAccess
->mbElementAccess
= true;
1941 } else if (className
1942 == "com.sun.star.container.XIndexContainer")
1944 rMethodConcept_i
|= INDEXCONTAINER
;
1945 pAccess
->mbIndexContainer
= true;
1946 pAccess
->mbIndexReplace
= true;
1947 pAccess
->mbIndexAccess
= true;
1948 pAccess
->mbElementAccess
= true;
1949 } else if (className
1950 == "com.sun.star.container.XIndexReplace")
1952 rMethodConcept_i
|= INDEXCONTAINER
;
1953 pAccess
->mbIndexReplace
= true;
1954 pAccess
->mbIndexAccess
= true;
1955 pAccess
->mbElementAccess
= true;
1956 } else if (className
1957 == "com.sun.star.container.XIndexAccess")
1959 rMethodConcept_i
|= INDEXCONTAINER
;
1960 pAccess
->mbIndexAccess
= true;
1961 pAccess
->mbElementAccess
= true;
1962 } else if (className
1963 == "com.sun.star.container.XEnumerationAccess")
1965 rMethodConcept_i
|= ENUMERATION
;
1966 pAccess
->mbEnumerationAccess
= true;
1967 pAccess
->mbElementAccess
= true;
1968 } else if (className
1969 == "com.sun.star.reflection.XIdlArray")
1971 pAccess
->mbIdlArray
= true;
1972 } else if (className
1973 == "com.sun.star.lang.XUnoTunnel")
1975 pAccess
->mbUnoTunnel
= true;
1978 // If the name is too short, it isn't anything
1979 if( aMethName
.getLength() <= 3 )
1982 // Is it a get method?
1984 if( aMethName
.startsWith("get", &aPropName
) )
1986 // Get methods must not have any parameters
1987 Sequence
< Reference
<XIdlClass
> > getParams
= rxMethod_i
->getParameterTypes();
1988 if( getParams
.getLength() > 0 )
1993 // Do we have the name already?
1994 IntrospectionNameMap::iterator aIt
= rPropNameMap
.find( aPropName
);
1995 if (aIt
!= rPropNameMap
.end())
1999 String( "Introspection: Property \"" ) +
2000 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2001 String( "\" found more than once" ) );
2006 // It is already at least a read-only property
2007 rMethodConcept_i
|= PROPERTY
;
2009 pMethodTypes
[i
] = GETSET_METHOD
;
2010 Reference
<XIdlClass
> xGetRetType
= rxMethod_i
->getReturnType();
2012 // Is the property sequence big enough?
2013 pAccess
->checkPropertyArraysSize( rPropCount
);
2015 // Write it in its property array
2016 Property
& rProp
= rAllPropArray
[ rPropCount
];
2017 rProp
.Name
= aPropName
;
2018 rProp
.Handle
= rPropCount
;
2019 rProp
.Type
= Type( xGetRetType
->getTypeClass(), xGetRetType
->getName() );
2020 rProp
.Attributes
= READONLY
;
2022 // New entry in the hash table
2023 rPropNameMap
[ aPropName
] = rPropCount
;
2025 // Maintain table for XExactName
2026 rLowerToExactNameMap
[ aPropName
.toAsciiLowerCase() ] = aPropName
;
2028 // Remember get method
2029 IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess
->aInterfaceSeq1
,
2030 rInterfaces1
, rPropCount
);
2031 rInterfaces1
[ rPropCount
] = rxMethod_i
;
2033 // Remember type of property
2034 rMapTypeArray
[ rPropCount
] = MAP_GETSET
;
2035 rPropertyConceptArray
[ rPropCount
] = METHODS
;
2036 pAccess
->mnMethodPropCount
++;
2038 // Search for matching set method
2040 for( k
= 0 ; k
< nSourceMethodCount
; k
++ )
2043 const Reference
<XIdlMethod
>& rxMethod_k
= pSourceMethods
[k
];
2045 // Accept only methods that are not already assigned
2046 if( k
== i
|| pMethodTypes
[k
] != STANDARD_METHOD
)
2049 // Get name and evaluate
2050 OUString aMethName2
= rxMethod_k
->getName();
2051 OUString aPropName2
;
2052 if (!(aMethName2
.startsWith("set", &aPropName2
)
2053 && aPropName2
== aPropName
))
2056 // A set method must return void
2057 Reference
<XIdlClass
> xSetRetType
= rxMethod_k
->getReturnType();
2058 if( xSetRetType
->getTypeClass() != TypeClass_VOID
)
2063 // A set method may only have one parameter
2064 Sequence
< Reference
<XIdlClass
> > setParams
= rxMethod_k
->getParameterTypes();
2065 sal_Int32 nParamCount
= setParams
.getLength();
2066 if( nParamCount
!= 1 )
2071 // Next, the return type must correspond to the parameter type
2072 const Reference
<XIdlClass
>* pParamArray2
= setParams
.getConstArray();
2073 Reference
<XIdlClass
> xParamType
= pParamArray2
[ 0 ];
2074 if( xParamType
->equals( xGetRetType
) )
2076 pLocalMethodConcepts
[ k
] = PROPERTY
;
2078 pMethodTypes
[k
] = GETSET_METHOD
;
2080 // Delete read-only flag again
2081 rProp
.Attributes
&= ~READONLY
;
2083 // Remember set method
2084 IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess
->aInterfaceSeq2
,
2085 rInterfaces2
, rPropCount
);
2086 rInterfaces2
[ rPropCount
] = rxMethod_k
;
2094 // Is it an add listener method?
2095 else if( aMethName
.startsWith("add", &aPropName
) )
2097 // Does it end with "Listener"?
2098 OUString aListenerName
;
2099 if( !aPropName
.endsWith("Listener", &aListenerName
) )
2102 // TODO: More accurate tests could still be carried out here
2104 // - Number and type of parameters
2107 // Search for matching remove method, otherwise not applicable
2109 for( k
= 0 ; k
< nSourceMethodCount
; k
++ )
2112 const Reference
<XIdlMethod
>& rxMethod_k
= pSourceMethods
[k
];
2114 // Accept only methods that are not already assigned
2115 if( k
== i
|| pMethodTypes
[k
] != STANDARD_METHOD
)
2118 // Get name and evaluate
2119 OUString aMethName2
= rxMethod_k
->getName();
2120 OUString aListenerName2
;
2121 if (!(aMethName2
.startsWith(
2122 "remove", &aPropName
)
2123 && aPropName
.endsWith(
2124 "Listener", &aListenerName2
)
2125 && aListenerName2
== aListenerName
))
2128 // TODO: More accurate tests could still be carried out here
2130 // - Number and type of parameters
2133 // Methods are recognised as a listener interface
2134 rMethodConcept_i
|= LISTENER
;
2135 pLocalMethodConcepts
[ k
] |= LISTENER
;
2137 pMethodTypes
[i
] = ADD_LISTENER_METHOD
;
2138 pMethodTypes
[k
] = REMOVE_LISTENER_METHOD
;
2145 // A set method could still exist without a corresponding get method,
2146 // this must be a write-only property
2147 for( i
= 0 ; i
< nSourceMethodCount
; i
++ )
2150 const Reference
<XIdlMethod
>& rxMethod_i
= pSourceMethods
[i
];
2152 // Accept only methods that are not already assigned
2153 if( pMethodTypes
[i
] != STANDARD_METHOD
)
2157 OUString aMethName
= rxMethod_i
->getName();
2159 // If the name is too short, it isn't anything
2160 if( aMethName
.getLength() <= 3 )
2163 // Is it a set method without associated get method?
2165 if( aMethName
.startsWith("set", &aPropName
) )
2167 // A set method must return void
2168 Reference
<XIdlClass
> xSetRetType
= rxMethod_i
->getReturnType();
2169 if( xSetRetType
->getTypeClass() != TypeClass_VOID
)
2174 // A set method may only have one parameter
2175 Sequence
< Reference
<XIdlClass
> > setParams
= rxMethod_i
->getParameterTypes();
2176 sal_Int32 nParamCount
= setParams
.getLength();
2177 if( nParamCount
!= 1 )
2182 // Do we have the name already?
2183 IntrospectionNameMap::iterator aIt
= rPropNameMap
.find( aPropName
);
2184 if (aIt
!= rPropNameMap
.end())
2188 String( "Introspection: Property \"" ) +
2189 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2190 String( "\" found more than once" ) );
2195 // Now we know it's a write only property
2196 pLocalMethodConcepts
[ i
] = PROPERTY
;
2198 pMethodTypes
[i
] = GETSET_METHOD
;
2199 Reference
<XIdlClass
> xGetRetType
= setParams
.getConstArray()[0];
2201 // Is the property sequence big enough?
2202 pAccess
->checkPropertyArraysSize( rPropCount
);
2204 // Write it in its property array
2205 Property
& rProp
= rAllPropArray
[ rPropCount
];
2206 rProp
.Name
= aPropName
;
2207 rProp
.Handle
= rPropCount
;
2208 rProp
.Type
= Type( xGetRetType
->getTypeClass(), xGetRetType
->getName() );
2209 rProp
.Attributes
= 0; // PROPERTY_WRITEONLY ???
2211 // New entry in the hash table
2212 rPropNameMap
[ aPropName
] = rPropCount
;
2214 // Maintain table for XExactName
2215 rLowerToExactNameMap
[ aPropName
.toAsciiLowerCase() ] = aPropName
;
2217 // Remember set method
2218 IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess
->aInterfaceSeq2
,
2219 rInterfaces2
, rPropCount
);
2220 rInterfaces2
[ rPropCount
] = rxMethod_i
;
2222 // Remember type of property
2223 rMapTypeArray
[ rPropCount
] = MAP_SETONLY
;
2224 rPropertyConceptArray
[ rPropCount
] = METHODS
;
2225 pAccess
->mnMethodPropCount
++;
2233 // 4. Place methods in overall sequence
2235 // How many methods in the method sequence
2236 sal_Int32 nExportedMethodCount
= 0;
2237 sal_Int32 nSupportedListenerCount
= 0;
2238 for( i
= 0 ; i
< nSourceMethodCount
; i
++ )
2240 if( pMethodTypes
[ i
] != INVALID_METHOD
)
2242 nExportedMethodCount
++;
2244 if( pMethodTypes
[ i
] == ADD_LISTENER_METHOD
)
2246 nSupportedListenerCount
++;
2250 // Enlarge sequences in the access object accordingly
2251 pAccess
->maAllMethodSeq
.resize( nExportedMethodCount
+ iAllExportedMethod
);
2252 pAccess
->maMethodConceptSeq
.resize( nExportedMethodCount
+ iAllExportedMethod
);
2253 pAccess
->maSupportedListenerSeq
.resize( nSupportedListenerCount
+ iAllSupportedListener
);
2256 for( i
= 0 ; i
< nSourceMethodCount
; i
++ )
2258 if( pMethodTypes
[ i
] != INVALID_METHOD
)
2261 const Reference
<XIdlMethod
>& rxMethod
= pSourceMethods
[i
];
2263 // Enter name in hash table if not already known
2264 OUString aMethName2
= rxMethod
->getName();
2265 IntrospectionNameMap::iterator aIt
= rMethodNameMap
.find( aMethName2
);
2266 if( aIt
== rMethodNameMap
.end() )
2269 rMethodNameMap
[ aMethName2
] = iAllExportedMethod
;
2271 // Maintain table for XExactName
2272 rLowerToExactNameMap
[ aMethName2
.toAsciiLowerCase() ] = aMethName2
;
2276 sal_Int32 iHashResult
= aIt
->second
;
2278 Reference
<XIdlMethod
> xExistingMethod
= pAccess
->maAllMethodSeq
[iHashResult
];
2280 Reference
< XIdlClass
> xExistingMethClass
=
2281 xExistingMethod
->getDeclaringClass();
2282 Reference
< XIdlClass
> xNewMethClass
= rxMethod
->getDeclaringClass();
2283 if( xExistingMethClass
->equals( xNewMethClass
) )
2287 pAccess
->maAllMethodSeq
[iAllExportedMethod
] = rxMethod
;
2289 // If a concept has been set, is the method "normal"?
2290 sal_Int32
& rMethodConcept_i
= pLocalMethodConcepts
[ i
];
2291 if( !rMethodConcept_i
)
2292 rMethodConcept_i
= MethodConcept_NORMAL_IMPL
;
2293 pAccess
->maMethodConceptSeq
[ iAllExportedMethod
] = rMethodConcept_i
;
2294 iAllExportedMethod
++;
2296 if( pMethodTypes
[ i
] == ADD_LISTENER_METHOD
)
2298 // Determine class of listener
2299 const Reference
<XIdlMethod
>& rxMethod
= pSourceMethods
[i
];
2301 // Enter void as default class
2302 css::uno::Reference
<css::reflection::XIdlClass
>
2304 reflection
->forName(
2305 cppu::UnoType
<void>::get()
2307 // Old: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass();
2309 // Option 1: Search for parameters for a listener class
2310 // Disadvantage: Superclasses should be searched recursively
2311 Sequence
< Reference
<XIdlClass
> > aParams
= rxMethod
->getParameterTypes();
2312 const Reference
<XIdlClass
>* pParamArray2
= aParams
.getConstArray();
2314 css::uno::Reference
<css::reflection::XIdlClass
>
2315 xEventListenerClass(
2316 reflection
->forName(
2318 css::lang::XEventListener
>::get()
2320 // Old: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass();
2321 sal_Int32 nParamCount
= aParams
.getLength();
2323 for( k
= 0 ; k
< nParamCount
; k
++ )
2325 const Reference
<XIdlClass
>& rxClass
= pParamArray2
[k
];
2327 // Are we derived from a listener?
2328 if( rxClass
->equals( xEventListenerClass
) ||
2329 isDerivedFrom( rxClass
, xEventListenerClass
) )
2331 xListenerClass
= rxClass
;
2336 // Option 2: Unload the name of the method
2337 // Disadvantage: Does not work with test listeners, where it does not exist
2338 //aMethName = rxMethod->getName();
2339 //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 );
2340 //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName );
2341 Type
aListenerType( TypeClass_INTERFACE
, xListenerClass
->getName() );
2342 pAccess
->maSupportedListenerSeq
[ iAllSupportedListener
] = aListenerType
;
2343 iAllSupportedListener
++;
2347 // When there were XInterface methods in this run,
2348 // ignore them in the future
2349 if( bFoundXInterface
)
2350 bXInterfaceIsInvalid
= true;
2353 // Do superclasses exist? Then continue here
2354 Sequence
< Reference
<XIdlClass
> > aSuperClassSeq
= xImplClass2
->getSuperclasses();
2356 // Currently only one superclass is considered
2357 if( aSuperClassSeq
.getLength() >= 1 )
2359 xImplClass2
= aSuperClassSeq
.getConstArray()[0];
2360 OSL_ENSURE( xImplClass2
.is(), "super class null" );
2364 xImplClass2
= nullptr;
2369 // Apply number of exported methods and adapt Sequences
2370 // (can be different because duplicate methods are thrown
2371 // out only after the determination of nExportedMethodCount)
2372 sal_Int32
& rMethCount
= pAccess
->mnMethCount
;
2373 rMethCount
= iAllExportedMethod
;
2374 pAccess
->maAllMethodSeq
.resize( rMethCount
);
2375 pAccess
->maMethodConceptSeq
.resize( rMethCount
);
2377 // Resize the property sequences
2378 pAccess
->maAllPropertySeq
.resize( rPropCount
);
2379 pAccess
->maPropertyConceptSeq
.resize( rPropCount
);
2380 pAccess
->maMapTypeSeq
.resize( rPropCount
);
2382 // Register struct fields as properties
2383 else //if( eType == TypeClass_STRUCT )
2385 // Is it an interface or a struct?
2386 //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass();
2387 css::uno::Reference
<css::reflection::XIdlClass
> xClassRef(
2388 reflection
->forName(aToInspectObj
.getValueTypeName()));
2389 if( !xClassRef
.is() )
2391 SAL_WARN( "stoc", "Can't get XIdlClass from Reflection" );
2392 return new ImplIntrospectionAccess(aToInspectObj
, pAccess
);
2396 Sequence
< Reference
<XIdlField
> > fields
= xClassRef
->getFields();
2397 const Reference
<XIdlField
>* pFields
= fields
.getConstArray();
2398 sal_Int32 nLen
= fields
.getLength();
2400 for( i
= 0 ; i
< nLen
; i
++ )
2402 Reference
<XIdlField
> xField
= pFields
[i
];
2403 Reference
<XIdlClass
> xPropType
= xField
->getType();
2404 OUString aPropName
= xField
->getName();
2406 // Is the property sequence big enough?
2407 pAccess
->checkPropertyArraysSize( rPropCount
);
2409 // Write it in its property array
2410 Property
& rProp
= rAllPropArray
[ rPropCount
];
2411 rProp
.Name
= aPropName
;
2412 rProp
.Handle
= rPropCount
;
2413 rProp
.Type
= Type( xPropType
->getTypeClass(), xPropType
->getName() );
2414 FieldAccessMode eAccessMode
= xField
->getAccessMode();
2415 rProp
.Attributes
= (eAccessMode
== FieldAccessMode_READONLY
||
2416 eAccessMode
== FieldAccessMode_CONST
)
2419 //FieldAccessMode eAccessMode = xField->getAccessMode();
2420 //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST)
2421 //? PropertyAttribute::READONLY : 0;
2423 // Write name in hash table
2424 rPropNameMap
[ aPropName
] = rPropCount
;
2426 // Maintain table for XExactName
2427 rLowerToExactNameMap
[ aPropName
.toAsciiLowerCase() ] = aPropName
;
2430 IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess
->aInterfaceSeq1
,
2431 rInterfaces1
, rPropCount
);
2432 rInterfaces1
[ rPropCount
] = xField
;
2434 // Remember type of property
2435 rMapTypeArray
[ rPropCount
] = MAP_FIELD
;
2436 rPropertyConceptArray
[ rPropCount
] = ATTRIBUTES
;
2437 pAccess
->mnAttributePropCount
++;
2444 // Set property sequence to the correct length
2445 pAccess
->maAllPropertySeq
.resize( pAccess
->mnPropCount
);
2447 return new ImplIntrospectionAccess(aToInspectObj
, pAccess
);
2452 css::uno::Reference
<css::uno::XComponentContext
> const & context
):
2453 instance(new Implementation(context
))
2456 rtl::Reference
<cppu::OWeakObject
> instance
;
2460 public rtl::StaticWithArg
<
2461 Instance
, css::uno::Reference
<css::uno::XComponentContext
>, Singleton
>
2466 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
2467 com_sun_star_comp_stoc_Introspection_get_implementation(
2468 css::uno::XComponentContext
* context
,
2469 css::uno::Sequence
<css::uno::Any
> const & arguments
)
2472 arguments
.hasElements(), "stoc", "unexpected singleton arguments");
2473 return cppu::acquire(Singleton::get(context
).instance
.get());
2476 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */