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 <comphelper/sequence.hxx>
21 #include <cppuhelper/queryinterface.hxx>
22 #include <cppuhelper/exc_hlp.hxx>
23 #include <cppuhelper/weak.hxx>
24 #include <cppuhelper/supportsservice.hxx>
25 #include <cppuhelper/implbase.hxx>
27 #include <com/sun/star/script/CannotConvertException.hpp>
28 #include <com/sun/star/script/XTypeConverter.hpp>
29 #include <com/sun/star/script/XInvocation.hpp>
30 #include <com/sun/star/script/XInvocation2.hpp>
31 #include <com/sun/star/reflection/XIdlReflection.hpp>
32 #include <com/sun/star/reflection/theCoreReflection.hpp>
33 #include <com/sun/star/container/XNameContainer.hpp>
34 #include <com/sun/star/container/XIndexContainer.hpp>
35 #include <com/sun/star/container/XEnumerationAccess.hpp>
36 #include <com/sun/star/beans/XExactName.hpp>
37 #include <com/sun/star/beans/XMaterialHolder.hpp>
38 #include <com/sun/star/beans/theIntrospection.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include <com/sun/star/beans/MethodConcept.hpp>
42 #include <com/sun/star/beans/PropertyConcept.hpp>
43 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
44 #include <com/sun/star/lang/XServiceInfo.hpp>
45 #include <com/sun/star/lang/XTypeProvider.hpp>
50 using namespace css::uno
;
51 using namespace css::lang
;
52 using namespace css::script
;
53 using namespace css::reflection
;
54 using namespace css::beans
;
55 using namespace css::container
;
63 // TODO: Implement centrally
64 static Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
, const Reference
< XIdlReflection
> & xRefl
)
66 return xRefl
->forName( rType
.getTypeName() );
74 , public XNameContainer
75 , public XIndexContainer
76 , public XEnumerationAccess
78 , public XMaterialHolder
79 , public XTypeProvider
82 Invocation_Impl( const Any
& rAdapted
, const Reference
<XTypeConverter
> &,
83 const Reference
<XIntrospection
> &,
84 const Reference
<XIdlReflection
> &,
88 virtual Any SAL_CALL
queryInterface( const Type
& aType
) override
;
89 virtual void SAL_CALL
acquire() noexcept override
{ OWeakObject::acquire(); }
90 virtual void SAL_CALL
release() noexcept override
{ OWeakObject::release(); }
94 virtual Sequence
< css::uno::Type
> SAL_CALL
getTypes( ) override
;
95 virtual Sequence
< sal_Int8
> SAL_CALL
getImplementationId( ) override
;
98 virtual Any SAL_CALL
getMaterial() override
;
101 virtual Reference
<XIntrospectionAccess
> SAL_CALL
getIntrospection() override
;
102 virtual Any SAL_CALL
invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
, Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
) override
;
103 virtual void SAL_CALL
setValue(const OUString
& PropertyName
, const Any
& Value
) override
;
104 virtual Any SAL_CALL
getValue(const OUString
& PropertyName
) override
;
105 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
) override
;
106 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
) override
;
109 virtual Sequence
< OUString
> SAL_CALL
getMemberNames( ) override
;
110 virtual Sequence
< InvocationInfo
> SAL_CALL
getInfo( ) override
;
111 virtual InvocationInfo SAL_CALL
getInfoForName( const OUString
& aName
, sal_Bool bExact
) override
;
113 // All Access and Container methods are not thread safe
115 virtual Type SAL_CALL
getElementType() override
116 { return _xElementAccess
->getElementType(); }
118 virtual sal_Bool SAL_CALL
hasElements() override
119 { return _xElementAccess
->hasElements(); }
122 virtual void SAL_CALL
insertByName( const OUString
& Name
, const Any
& Element
) override
123 { _xNameContainer
->insertByName( Name
, Element
); }
125 virtual void SAL_CALL
removeByName( const OUString
& Name
) override
126 { _xNameContainer
->removeByName( Name
); }
129 virtual void SAL_CALL
replaceByName( const OUString
& Name
, const Any
& Element
) override
130 { _xNameReplace
->replaceByName( Name
, Element
); }
133 virtual Any SAL_CALL
getByName( const OUString
& Name
) override
134 { return _xNameAccess
->getByName( Name
); }
136 virtual Sequence
<OUString
> SAL_CALL
getElementNames() override
137 { return _xNameAccess
->getElementNames(); }
139 virtual sal_Bool SAL_CALL
hasByName( const OUString
& Name
) override
140 { return _xNameAccess
->hasByName( Name
); }
143 virtual void SAL_CALL
insertByIndex( sal_Int32 Index
, const Any
& Element
) override
144 { _xIndexContainer
->insertByIndex( Index
, Element
); }
146 virtual void SAL_CALL
removeByIndex( sal_Int32 Index
) override
147 { _xIndexContainer
->removeByIndex( Index
); }
150 virtual void SAL_CALL
replaceByIndex( sal_Int32 Index
, const Any
& Element
) override
151 { _xIndexReplace
->replaceByIndex( Index
, Element
); }
154 virtual sal_Int32 SAL_CALL
getCount() override
155 { return _xIndexAccess
->getCount(); }
157 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
) override
158 { return _xIndexAccess
->getByIndex( Index
); }
160 // XEnumerationAccess
161 virtual Reference
<XEnumeration
> SAL_CALL
createEnumeration() override
162 { return _xEnumerationAccess
->createEnumeration(); }
165 virtual OUString SAL_CALL
getExactName( const OUString
& rApproximateName
) override
;
169 void setMaterial( const Any
& rMaterial
);
171 void getInfoSequenceImpl( Sequence
< OUString
>* pStringSeq
, Sequence
< InvocationInfo
>* pInfoSeq
);
172 void fillInfoForNameAccess( InvocationInfo
& rInfo
, const OUString
& aName
);
173 static void fillInfoForProperty( InvocationInfo
& rInfo
, const Property
& rProp
);
174 static void fillInfoForMethod( InvocationInfo
& rInfo
, const Reference
< XIdlMethod
>& xMethod
);
176 Reference
<XTypeConverter
> xTypeConverter
;
177 Reference
<XIntrospection
> xIntrospection
;
178 Reference
<XIdlReflection
> xCoreReflection
;
181 // _xDirect and (_xIntrospectionAccess, xPropertySet) are exclusive
182 Reference
<XInvocation
> _xDirect
;
183 Reference
<XInvocation2
> _xDirect2
;
184 Reference
<XPropertySet
> _xPropertySet
;
185 Reference
<XIntrospectionAccess
> _xIntrospectionAccess
;
187 // supplied Interfaces
188 Reference
<XNameContainer
> _xNameContainer
;
189 Reference
<XNameReplace
> _xNameReplace
;
190 Reference
<XNameAccess
> _xNameAccess
;
191 Reference
<XIndexContainer
> _xIndexContainer
;
192 Reference
<XIndexReplace
> _xIndexReplace
;
193 Reference
<XIndexAccess
> _xIndexAccess
;
194 Reference
<XEnumerationAccess
> _xEnumerationAccess
;
195 Reference
<XElementAccess
> _xElementAccess
;
198 Reference
<XExactName
> _xENDirect
, _xENIntrospection
;
205 Invocation_Impl::Invocation_Impl
207 const Any
& rAdapted
,
208 const Reference
<XTypeConverter
> & rTC
,
209 const Reference
<XIntrospection
> & rI
,
210 const Reference
<XIdlReflection
> & rCR
,
213 : xTypeConverter( rTC
)
214 , xIntrospection( rI
)
215 , xCoreReflection( rCR
)
216 , mbFromOLE( bFromOLE
)
218 setMaterial( rAdapted
);
221 //### INTERFACE IMPLEMENTATIONS ####################################################################
224 Any SAL_CALL
Invocation_Impl::queryInterface( const Type
& aType
)
226 // PropertySet implementation
227 Any a
= ::cppu::queryInterface( aType
,
228 static_cast< XInvocation
* >(this),
229 static_cast< XMaterialHolder
* >(this),
230 static_cast< XTypeProvider
* >(this) );
236 if( aType
== cppu::UnoType
<XExactName
>::get())
238 // Invocation does not support XExactName, if direct object supports
239 // XInvocation, but not XExactName. Except when called from OLE Automation.
241 (_xDirect
.is() && _xENDirect
.is()) ||
242 (!_xDirect
.is() && _xENIntrospection
.is()))
244 return Any( Reference
< XExactName
>( static_cast< XExactName
* >(this) ) );
247 else if ( aType
== cppu::UnoType
<XNameContainer
>::get())
249 if( _xNameContainer
.is() )
250 return Any( Reference
< XNameContainer
>( static_cast< XNameContainer
* >(this) ) );
252 else if ( aType
== cppu::UnoType
<XNameReplace
>::get())
254 if( _xNameReplace
.is() )
255 return Any( Reference
< XNameReplace
>( static_cast< XNameReplace
* >(this) ) );
257 else if ( aType
== cppu::UnoType
<XNameAccess
>::get())
259 if( _xNameAccess
.is() )
260 return Any( Reference
< XNameAccess
>( static_cast< XNameAccess
* >(this) ) );
262 else if ( aType
== cppu::UnoType
<XIndexContainer
>::get())
264 if (_xIndexContainer
.is())
265 return Any( Reference
< XIndexContainer
>( static_cast< XIndexContainer
* >(this) ) );
267 else if ( aType
== cppu::UnoType
<XIndexReplace
>::get())
269 if (_xIndexReplace
.is())
270 return Any( Reference
< XIndexReplace
>( static_cast< XIndexReplace
* >(this) ) );
272 else if ( aType
== cppu::UnoType
<XIndexAccess
>::get())
274 if (_xIndexAccess
.is())
275 return Any( Reference
< XIndexAccess
>( static_cast< XIndexAccess
* >(this) ) );
277 else if ( aType
== cppu::UnoType
<XEnumerationAccess
>::get())
279 if (_xEnumerationAccess
.is())
280 return Any( Reference
< XEnumerationAccess
>( static_cast< XEnumerationAccess
* >(this) ) );
282 else if ( aType
== cppu::UnoType
<XElementAccess
>::get())
284 if (_xElementAccess
.is())
286 return Any( Reference
< XElementAccess
>(
287 static_cast< XElementAccess
* >(static_cast< XNameContainer
* >(this)) ) );
290 else if ( aType
== cppu::UnoType
<XInvocation2
>::get())
292 // Invocation does not support XInvocation2, if direct object supports
293 // XInvocation, but not XInvocation2.
295 ( _xDirect
.is() && _xDirect2
.is()) ||
296 (!_xDirect
.is() && _xIntrospectionAccess
.is() ) )
298 return Any( Reference
< XInvocation2
>( static_cast< XInvocation2
* >(this) ) );
302 return OWeakObject::queryInterface( aType
);
306 Any
Invocation_Impl::getMaterial()
308 // AB, 12.2.1999 Make sure that the material is taken when possible
309 // from the direct Invocation of the Introspection, otherwise structs
310 // are not handled correctly
311 Reference
<XMaterialHolder
> xMaterialHolder
;
314 xMaterialHolder
.set( _xDirect
, UNO_QUERY
);
315 //_xDirect->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
317 else if( _xIntrospectionAccess
.is() )
319 xMaterialHolder
.set( _xIntrospectionAccess
, UNO_QUERY
);
320 //_xIntrospectionAccess->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
322 if( xMaterialHolder
.is() )
324 return xMaterialHolder
->getMaterial();
330 void Invocation_Impl::setMaterial( const Any
& rMaterial
)
332 // set the material first and only once
333 _aMaterial
= rMaterial
;
335 // First do this outside the guard
336 _xDirect
.set( rMaterial
, UNO_QUERY
);
338 if( !mbFromOLE
&& _xDirect
.is() )
340 // Consult object directly
341 _xElementAccess
.set( _xDirect
, UNO_QUERY
);
342 _xEnumerationAccess
.set( _xDirect
, UNO_QUERY
);
343 _xIndexAccess
.set( _xDirect
, UNO_QUERY
);
344 _xIndexReplace
.set( _xDirect
, UNO_QUERY
);
345 _xIndexContainer
.set( _xDirect
, UNO_QUERY
);
346 _xNameAccess
.set( _xDirect
, UNO_QUERY
);
347 _xNameReplace
.set( _xDirect
, UNO_QUERY
);
348 _xNameContainer
.set( _xDirect
, UNO_QUERY
);
349 _xENDirect
.set( _xDirect
, UNO_QUERY
);
350 _xDirect2
.set( _xDirect
, UNO_QUERY
);
354 // Make Invocation on the Introspection
355 if (xIntrospection
.is())
357 _xIntrospectionAccess
= xIntrospection
->inspect( _aMaterial
);
358 if( _xIntrospectionAccess
.is() )
361 _xIntrospectionAccess
->queryAdapter(
362 cppu::UnoType
<XElementAccess
>::get()), UNO_QUERY
);
364 if( _xElementAccess
.is() )
366 _xEnumerationAccess
.set(
367 _xIntrospectionAccess
->queryAdapter(
368 cppu::UnoType
<XEnumerationAccess
>::get()), UNO_QUERY
);
371 _xIntrospectionAccess
->queryAdapter(
372 cppu::UnoType
<XIndexAccess
>::get()), UNO_QUERY
);
374 if( _xIndexAccess
.is() )
377 _xIntrospectionAccess
->queryAdapter(
378 cppu::UnoType
<XIndexReplace
>::get()), UNO_QUERY
);
380 _xIndexContainer
.set(
381 _xIntrospectionAccess
->queryAdapter(
382 cppu::UnoType
<XIndexContainer
>::get()), UNO_QUERY
);
386 _xIntrospectionAccess
->queryAdapter(
387 cppu::UnoType
<XNameAccess
>::get()), UNO_QUERY
);
389 if( _xNameAccess
.is() )
392 _xIntrospectionAccess
->queryAdapter(
393 cppu::UnoType
<XNameReplace
>::get()), UNO_QUERY
);
396 _xIntrospectionAccess
->queryAdapter(
397 cppu::UnoType
<XNameContainer
>::get()), UNO_QUERY
);
401 _xPropertySet
.set( _xIntrospectionAccess
->queryAdapter( cppu::UnoType
<XPropertySet
>::get()),
404 _xENIntrospection
.set( _xIntrospectionAccess
, UNO_QUERY
);
411 OUString
Invocation_Impl::getExactName( const OUString
& rApproximateName
)
414 return _xENDirect
->getExactName( rApproximateName
);
417 if (_xENIntrospection
.is())
418 aRet
= _xENIntrospection
->getExactName( rApproximateName
);
423 Reference
<XIntrospectionAccess
> Invocation_Impl::getIntrospection()
426 return _xDirect
->getIntrospection();
428 return _xIntrospectionAccess
;
432 sal_Bool
Invocation_Impl::hasMethod( const OUString
& Name
)
434 if (!mbFromOLE
&& _xDirect
.is())
435 return _xDirect
->hasMethod( Name
);
436 if( _xIntrospectionAccess
.is() )
437 return _xIntrospectionAccess
->hasMethod( Name
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
442 sal_Bool
Invocation_Impl::hasProperty( const OUString
& Name
)
446 bool bRet
= _xDirect
->hasProperty( Name
);
447 if (bRet
|| !mbFromOLE
)
451 if( _xIntrospectionAccess
.is()
452 && _xIntrospectionAccess
->hasProperty( Name
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
455 if( _xNameAccess
.is() )
456 return _xNameAccess
->hasByName( Name
);
461 Any
Invocation_Impl::getValue( const OUString
& PropertyName
)
466 return _xDirect
->getValue( PropertyName
);
476 if( _xIntrospectionAccess
.is() && _xPropertySet
.is()
477 && _xIntrospectionAccess
->hasProperty
478 ( PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
480 return _xPropertySet
->getPropertyValue( PropertyName
);
483 if( _xNameAccess
.is() && _xNameAccess
->hasByName( PropertyName
) )
484 return _xNameAccess
->getByName( PropertyName
);
486 catch (UnknownPropertyException
&)
490 catch (RuntimeException
&)
498 throw UnknownPropertyException( "cannot get value " + PropertyName
);
502 void Invocation_Impl::setValue( const OUString
& PropertyName
, const Any
& Value
)
508 _xDirect
->setValue( PropertyName
, Value
);
520 if( _xIntrospectionAccess
.is() && _xPropertySet
.is()
521 && _xIntrospectionAccess
->hasProperty(
522 PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
524 Property aProp
= _xIntrospectionAccess
->getProperty(
525 PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
);
526 Reference
< XIdlClass
> r
= TypeToIdlClass( aProp
.Type
, xCoreReflection
);
527 if( r
->isAssignableFrom( TypeToIdlClass( Value
.getValueType(), xCoreReflection
) ) )
528 _xPropertySet
->setPropertyValue( PropertyName
, Value
);
529 else if( xTypeConverter
.is() )
530 _xPropertySet
->setPropertyValue(
531 PropertyName
, xTypeConverter
->convertTo( Value
, aProp
.Type
) );
533 throw RuntimeException( "no type converter service!" );
536 else if( _xNameContainer
.is() )
538 // Note: This misfeature deliberately not adapted to apply to objects which
539 // have XNameReplace but not XNameContainer
541 Reference
< XIdlClass
> r
=
542 TypeToIdlClass( _xNameContainer
->getElementType(), xCoreReflection
);
543 if( r
->isAssignableFrom(TypeToIdlClass( Value
.getValueType(), xCoreReflection
) ) )
545 else if( xTypeConverter
.is() )
546 aConv
= xTypeConverter
->convertTo( Value
, _xNameContainer
->getElementType() );
548 throw RuntimeException( "no type converter service!" );
550 // Replace if present, otherwise insert
551 if (_xNameContainer
->hasByName( PropertyName
))
552 _xNameContainer
->replaceByName( PropertyName
, aConv
);
554 _xNameContainer
->insertByName( PropertyName
, aConv
);
557 throw UnknownPropertyException( "no introspection nor name container!" );
559 catch (UnknownPropertyException
&)
563 catch (CannotConvertException
&)
567 catch (InvocationTargetException
&)
571 catch (RuntimeException
&)
575 catch (const Exception
& exc
)
577 css::uno::Any anyEx
= cppu::getCaughtException();
578 throw InvocationTargetException(
579 "exception occurred in setValue(): " + exc
.Message
,
580 Reference
< XInterface
>(), anyEx
);
585 Any
Invocation_Impl::invoke( const OUString
& FunctionName
, const Sequence
<Any
>& InParams
,
586 Sequence
<sal_Int16
>& OutIndices
, Sequence
<Any
>& OutParams
)
588 if (!mbFromOLE
&& _xDirect
.is())
589 return _xDirect
->invoke( FunctionName
, InParams
, OutIndices
, OutParams
);
591 if (_xIntrospectionAccess
.is())
593 // throw NoSuchMethodException if not exist
594 Reference
<XIdlMethod
> xMethod
= _xIntrospectionAccess
->getMethod(
595 FunctionName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
598 Sequence
<ParamInfo
> aFParams
= xMethod
->getParameterInfos();
599 const ParamInfo
* pFParams
= aFParams
.getConstArray();
600 sal_Int32 nFParamsLen
= aFParams
.getLength();
601 if (nFParamsLen
!= InParams
.getLength())
603 throw IllegalArgumentException(
604 "incorrect number of parameters passed invoking function " + FunctionName
+
605 ": expected " + OUString::number(nFParamsLen
) + ", got " + OUString::number(InParams
.getLength()),
606 static_cast<OWeakObject
*>(this), sal_Int16(1) );
610 const Any
* pInParams
= InParams
.getConstArray();
612 // Introspection Invoke Parameter
613 Sequence
<Any
> aInvokeParams( nFParamsLen
);
614 Any
* pInvokeParams
= aInvokeParams
.getArray();
617 OutIndices
.realloc( nFParamsLen
);
618 sal_Int16
* pOutIndices
= OutIndices
.getArray();
619 sal_uInt32 nOutIndex
= 0;
621 for ( sal_Int32 nPos
= 0; nPos
< nFParamsLen
; ++nPos
)
625 const ParamInfo
& rFParam
= pFParams
[nPos
];
626 const Reference
<XIdlClass
>& rDestType
= rFParam
.aType
;
628 // is IN/INOUT parameter?
629 if (rFParam
.aMode
!= ParamMode_OUT
)
631 if (rDestType
->isAssignableFrom( TypeToIdlClass( pInParams
[nPos
].getValueType(), xCoreReflection
) ))
633 pInvokeParams
[nPos
] = pInParams
[nPos
];
635 else if (xTypeConverter
.is())
637 Type
aDestType( rDestType
->getTypeClass(), rDestType
->getName() );
638 pInvokeParams
[nPos
] = xTypeConverter
->convertTo( pInParams
[nPos
], aDestType
);
642 CannotConvertException aExc
;
643 aExc
.Context
= *this;
644 aExc
.Message
= "invocation type mismatch!";
649 // is OUT/INOUT parameter?
650 if (rFParam
.aMode
!= ParamMode_IN
)
652 pOutIndices
[nOutIndex
] = static_cast<sal_Int16
>(nPos
);
653 if (rFParam
.aMode
== ParamMode_OUT
)
654 rDestType
->createObject( pInvokeParams
[nPos
] ); // default init
658 catch( CannotConvertException
& rExc
)
660 rExc
.ArgumentIndex
= nPos
; // Add optional parameter index
666 Any aRet
= xMethod
->invoke( _aMaterial
, aInvokeParams
);
669 OutIndices
.realloc( nOutIndex
);
670 OutParams
.realloc( nOutIndex
);
672 std::transform(std::cbegin(OutIndices
), std::cend(OutIndices
), OutParams
.getArray(),
673 [&pInvokeParams
](const sal_Int16 nIndex
) -> Any
{ return pInvokeParams
[nIndex
]; });
678 RuntimeException aExc
;
679 aExc
.Context
= *this;
680 aExc
.Message
= "invocation lacking of introspection access!";
686 // Struct to optimize sorting
691 // Defines where the member comes from
692 enum class Mode
{ NameAccess
, PropertySet
, Method
};
695 // Index to respective sequence
696 // (Index to NameAccess sequence for eMode==Mode::NameAccess etc.)
702 // Implementation of getting name or info
703 // String sequence will be filled when pStringSeq != NULL
704 // Info sequence will be filled when pInfoSeq != NULL
705 void Invocation_Impl::getInfoSequenceImpl
707 Sequence
< OUString
>* pStringSeq
,
708 Sequence
< InvocationInfo
>* pInfoSeq
711 //Sequence< OUString > aStrSeq;
713 //pStringSeq = &aStrSeq;
716 // Get all needed sequences
717 Sequence
<OUString
> aNameAccessNames
;
718 Sequence
<Property
> aPropertySeq
;
719 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
;
721 if( _xNameAccess
.is() )
723 aNameAccessNames
= _xNameAccess
->getElementNames();
726 if( _xIntrospectionAccess
.is() )
728 aPropertySeq
= _xIntrospectionAccess
->getProperties
729 ( PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
731 aMethodSeq
= _xIntrospectionAccess
->getMethods
732 ( MethodConcept::ALL
- MethodConcept::DANGEROUS
);
735 sal_Int32 nNameAccessCount
= aNameAccessNames
.getLength();
736 sal_Int32 nPropertyCount
= aPropertySeq
.getLength();
737 sal_Int32 nMethodCount
= aMethodSeq
.getLength();
738 sal_Int32 nTotalCount
= nNameAccessCount
+ nPropertyCount
+ nMethodCount
;
740 // Create and fill array of MemberItems
741 std::unique_ptr
< MemberItem
[]> pItems( new MemberItem
[ nTotalCount
] );
742 const OUString
* pStrings
= aNameAccessNames
.getConstArray();
743 const Property
* pProps
= aPropertySeq
.getConstArray();
744 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
746 // Fill array of MemberItems
747 sal_Int32 i
, iTotal
= 0;
750 for( i
= 0 ; i
< nNameAccessCount
; i
++, iTotal
++ )
752 MemberItem
& rItem
= pItems
[ iTotal
];
753 rItem
.aName
= pStrings
[ i
];
754 rItem
.eMode
= MemberItem::Mode::NameAccess
;
759 for( i
= 0 ; i
< nPropertyCount
; i
++, iTotal
++ )
761 MemberItem
& rItem
= pItems
[ iTotal
];
762 rItem
.aName
= pProps
[ i
].Name
;
763 rItem
.eMode
= MemberItem::Mode::PropertySet
;
768 for( i
= 0 ; i
< nMethodCount
; i
++, iTotal
++ )
770 MemberItem
& rItem
= pItems
[ iTotal
];
771 Reference
< XIdlMethod
> xMethod
= pMethods
[ i
];
772 rItem
.aName
= xMethod
->getName();
773 rItem
.eMode
= MemberItem::Mode::Method
;
777 // Setting up result sequences
778 OUString
* pRetStrings
= nullptr;
781 pStringSeq
->realloc( nTotalCount
);
782 pRetStrings
= pStringSeq
->getArray();
785 InvocationInfo
* pRetInfos
= nullptr;
788 pInfoSeq
->realloc( nTotalCount
);
789 pRetInfos
= pInfoSeq
->getArray();
792 // Fill result sequences in the correct order of members
793 for( iTotal
= 0 ; iTotal
< nTotalCount
; iTotal
++ )
795 MemberItem
& rItem
= pItems
[ iTotal
];
798 pRetStrings
[ iTotal
] = rItem
.aName
;
803 if( rItem
.eMode
== MemberItem::Mode::NameAccess
)
805 fillInfoForNameAccess( pRetInfos
[ iTotal
], rItem
.aName
);
807 else if( rItem
.eMode
== MemberItem::Mode::PropertySet
)
809 fillInfoForProperty( pRetInfos
[ iTotal
], pProps
[ rItem
.nIndex
] );
811 else if( rItem
.eMode
== MemberItem::Mode::Method
)
813 fillInfoForMethod( pRetInfos
[ iTotal
], pMethods
[ rItem
.nIndex
] );
820 Sequence
< OUString
> SAL_CALL
Invocation_Impl::getMemberNames( )
824 return _xDirect2
->getMemberNames();
826 Sequence
< OUString
> aRetSeq
;
827 getInfoSequenceImpl( &aRetSeq
, nullptr );
831 Sequence
< InvocationInfo
> SAL_CALL
Invocation_Impl::getInfo( )
835 return _xDirect2
->getInfo();
837 Sequence
< InvocationInfo
> aRetSeq
;
838 getInfoSequenceImpl( nullptr, &aRetSeq
);
842 InvocationInfo SAL_CALL
Invocation_Impl::getInfoForName( const OUString
& aName
, sal_Bool bExact
)
846 return _xDirect2
->getInfoForName( aName
, bExact
);
850 OUString aExactName
= aName
;
851 InvocationInfo aRetInfo
;
854 aExactName
= getExactName( aName
);
855 if( !aExactName
.isEmpty() )
857 if( _xIntrospectionAccess
->hasMethod( aExactName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
) )
859 Reference
<XIdlMethod
> xMethod
= _xIntrospectionAccess
->getMethod
860 ( aExactName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
861 fillInfoForMethod( aRetInfo
, xMethod
);
866 if( _xIntrospectionAccess
.is() && _xIntrospectionAccess
->hasProperty
867 ( aExactName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
869 Property aProp
= _xIntrospectionAccess
->getProperty
870 ( aExactName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
);
871 fillInfoForProperty( aRetInfo
, aProp
);
875 else if( _xNameAccess
.is() && _xNameAccess
->hasByName( aExactName
) )
877 fillInfoForNameAccess( aRetInfo
, aExactName
);
884 throw IllegalArgumentException(
885 "getExactName(), Unknown name " + aName
,
886 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
891 // Helper functions to fill InvocationInfo for XNameAccess
892 void Invocation_Impl::fillInfoForNameAccess
894 InvocationInfo
& rInfo
,
895 const OUString
& aName
899 rInfo
.eMemberType
= MemberType_PROPERTY
;
900 rInfo
.PropertyAttribute
= 0;
901 if( !_xNameContainer
.is() )
903 rInfo
.PropertyAttribute
= PropertyAttribute::READONLY
;
905 rInfo
.aType
= _xNameAccess
->getElementType();
908 void Invocation_Impl::fillInfoForProperty
910 InvocationInfo
& rInfo
,
911 const Property
& rProp
914 rInfo
.aName
= rProp
.Name
;
915 rInfo
.eMemberType
= MemberType_PROPERTY
;
916 rInfo
.PropertyAttribute
= rProp
.Attributes
;
917 rInfo
.aType
= rProp
.Type
;
920 void Invocation_Impl::fillInfoForMethod
922 InvocationInfo
& rInfo
,
923 const Reference
< XIdlMethod
>& xMethod
926 rInfo
.aName
= xMethod
->getName();
927 rInfo
.eMemberType
= MemberType_METHOD
;
928 Reference
< XIdlClass
> xReturnClass
= xMethod
->getReturnType();
929 Type
aReturnType( xReturnClass
->getTypeClass(), xReturnClass
->getName() );
930 rInfo
.aType
= aReturnType
;
931 Sequence
<ParamInfo
> aParamInfos
= xMethod
->getParameterInfos();
932 sal_Int32 nParamCount
= aParamInfos
.getLength();
933 if( nParamCount
<= 0 )
936 const ParamInfo
* pInfo
= aParamInfos
.getConstArray();
938 rInfo
.aParamTypes
.realloc( nParamCount
);
939 Type
* pParamTypes
= rInfo
.aParamTypes
.getArray();
940 rInfo
.aParamModes
.realloc( nParamCount
);
941 ParamMode
* pParamModes
= rInfo
.aParamModes
.getArray();
943 for( sal_Int32 i
= 0 ; i
< nParamCount
; i
++ )
945 Reference
< XIdlClass
> xParamClass
= pInfo
[i
].aType
;
946 Type
aParamType( xParamClass
->getTypeClass(), xParamClass
->getName() );
947 pParamTypes
[ i
] = aParamType
;
948 pParamModes
[ i
] = pInfo
[i
].aMode
;
954 Sequence
< Type
> SAL_CALL
Invocation_Impl::getTypes()
956 static Sequence
<Type
> s_types
= [this]() {
957 std::vector
<Type
> tmp
{
958 cppu::UnoType
<XTypeProvider
>::get(),
959 cppu::UnoType
<XWeak
>::get(),
960 cppu::UnoType
<XInvocation
>::get(),
961 cppu::UnoType
<XMaterialHolder
>::get() };
963 // Invocation does not support XExactName if direct object supports
964 // XInvocation, but not XExactName.
965 if ((_xDirect
.is() && _xENDirect
.is()) || (!_xDirect
.is() && _xENIntrospection
.is()))
966 tmp
.push_back(cppu::UnoType
<XExactName
>::get());
967 if (_xNameContainer
.is())
968 tmp
.push_back(cppu::UnoType
<XNameContainer
>::get());
969 if (_xNameReplace
.is())
970 tmp
.push_back(cppu::UnoType
<XNameReplace
>::get());
971 if (_xNameAccess
.is())
972 tmp
.push_back(cppu::UnoType
<XNameAccess
>::get());
973 if (_xIndexContainer
.is())
974 tmp
.push_back(cppu::UnoType
<XIndexContainer
>::get());
975 if (_xIndexReplace
.is())
976 tmp
.push_back(cppu::UnoType
<XIndexReplace
>::get());
977 if (_xIndexAccess
.is())
978 tmp
.push_back(cppu::UnoType
<XIndexAccess
>::get());
979 if (_xEnumerationAccess
.is())
980 tmp
.push_back(cppu::UnoType
<XEnumerationAccess
>::get());
981 if (_xElementAccess
.is())
982 tmp
.push_back(cppu::UnoType
<XElementAccess
>::get());
983 // Invocation does not support XInvocation2, if direct object supports
984 // XInvocation, but not XInvocation2.
985 if ((_xDirect
.is() && _xDirect2
.is()) || (!_xDirect
.is() && _xIntrospectionAccess
.is()))
986 tmp
.push_back(cppu::UnoType
<XInvocation2
>::get());
988 return comphelper::containerToSequence(tmp
);
993 Sequence
< sal_Int8
> SAL_CALL
Invocation_Impl::getImplementationId( )
995 return css::uno::Sequence
<sal_Int8
>();
1000 class InvocationService
1001 : public WeakImplHelper
< XSingleServiceFactory
, XServiceInfo
>
1004 explicit InvocationService( const Reference
<XComponentContext
> & xCtx
);
1007 OUString SAL_CALL
getImplementationName() override
;
1008 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) override
;
1009 Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
1011 // XSingleServiceFactory
1012 Reference
<XInterface
> SAL_CALL
createInstance() override
;
1013 Reference
<XInterface
> SAL_CALL
createInstanceWithArguments(
1014 const Sequence
<Any
>& rArguments
) override
;
1016 Reference
<XComponentContext
> mxCtx
;
1017 Reference
<XMultiComponentFactory
> mxSMgr
;
1018 Reference
<XTypeConverter
> xTypeConverter
;
1019 Reference
<XIntrospection
> xIntrospection
;
1020 Reference
<XIdlReflection
> xCoreReflection
;
1025 InvocationService::InvocationService( const Reference
<XComponentContext
> & xCtx
)
1027 , mxSMgr( xCtx
->getServiceManager() )
1028 , xCoreReflection( css::reflection::theCoreReflection::get(mxCtx
) )
1031 mxSMgr
->createInstanceWithContext( "com.sun.star.script.Converter", xCtx
),
1033 xIntrospection
= theIntrospection::get(xCtx
);
1037 OUString
InvocationService::getImplementationName()
1039 return "com.sun.star.comp.stoc.Invocation";
1043 sal_Bool
InvocationService::supportsService(const OUString
& ServiceName
)
1045 return cppu::supportsService(this, ServiceName
);
1049 Sequence
< OUString
> InvocationService::getSupportedServiceNames()
1051 return { "com.sun.star.script.Invocation" };
1055 Reference
<XInterface
> InvocationService::createInstance()
1057 //TODO:throw( Exception("no default construction of invocation adapter possible!", *this) );
1058 return Reference
<XInterface
>(); // dummy
1062 Reference
<XInterface
> InvocationService::createInstanceWithArguments(
1063 const Sequence
<Any
>& rArguments
)
1065 if (rArguments
.getLength() == 2)
1068 if ((rArguments
[1] >>= aArg1
) &&
1071 return Reference
< XInterface
>
1072 ( *new Invocation_Impl( *rArguments
.getConstArray(),
1073 xTypeConverter
, xIntrospection
, xCoreReflection
, true ) );
1076 if (rArguments
.getLength() == 1)
1078 return Reference
< XInterface
>
1079 ( *new Invocation_Impl( *rArguments
.getConstArray(),
1080 xTypeConverter
, xIntrospection
, xCoreReflection
, false ) );
1083 //TODO:throw( Exception("no default construction of invocation adapter possible!", *this) );
1084 return Reference
<XInterface
>();
1087 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
1088 stoc_InvocationService_get_implementation(
1089 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
1091 return cppu::acquire(new InvocationService(context
));
1097 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */