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
;
62 // TODO: Implement centrally
63 static Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
, const Reference
< XIdlReflection
> & xRefl
)
65 return xRefl
->forName( rType
.getTypeName() );
73 , public XNameContainer
74 , public XIndexContainer
75 , public XEnumerationAccess
77 , public XMaterialHolder
78 , public XTypeProvider
81 Invocation_Impl( const Any
& rAdapted
, const Reference
<XTypeConverter
> &,
82 const Reference
<XIntrospection
> &,
83 const Reference
<XIdlReflection
> &,
87 virtual Any SAL_CALL
queryInterface( const Type
& aType
) override
;
88 virtual void SAL_CALL
acquire() noexcept override
{ OWeakObject::acquire(); }
89 virtual void SAL_CALL
release() noexcept override
{ OWeakObject::release(); }
93 virtual Sequence
< css::uno::Type
> SAL_CALL
getTypes( ) override
;
94 virtual Sequence
< sal_Int8
> SAL_CALL
getImplementationId( ) override
;
97 virtual Any SAL_CALL
getMaterial() override
;
100 virtual Reference
<XIntrospectionAccess
> SAL_CALL
getIntrospection() override
;
101 virtual Any SAL_CALL
invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
, Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
) override
;
102 virtual void SAL_CALL
setValue(const OUString
& PropertyName
, const Any
& Value
) override
;
103 virtual Any SAL_CALL
getValue(const OUString
& PropertyName
) override
;
104 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
) override
;
105 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
) override
;
108 virtual Sequence
< OUString
> SAL_CALL
getMemberNames( ) override
;
109 virtual Sequence
< InvocationInfo
> SAL_CALL
getInfo( ) override
;
110 virtual InvocationInfo SAL_CALL
getInfoForName( const OUString
& aName
, sal_Bool bExact
) override
;
112 // All Access and Container methods are not thread safe
114 virtual Type SAL_CALL
getElementType() override
115 { return _xElementAccess
->getElementType(); }
117 virtual sal_Bool SAL_CALL
hasElements() override
118 { return _xElementAccess
->hasElements(); }
121 virtual void SAL_CALL
insertByName( const OUString
& Name
, const Any
& Element
) override
122 { _xNameContainer
->insertByName( Name
, Element
); }
124 virtual void SAL_CALL
removeByName( const OUString
& Name
) override
125 { _xNameContainer
->removeByName( Name
); }
128 virtual void SAL_CALL
replaceByName( const OUString
& Name
, const Any
& Element
) override
129 { _xNameReplace
->replaceByName( Name
, Element
); }
132 virtual Any SAL_CALL
getByName( const OUString
& Name
) override
133 { return _xNameAccess
->getByName( Name
); }
135 virtual Sequence
<OUString
> SAL_CALL
getElementNames() override
136 { return _xNameAccess
->getElementNames(); }
138 virtual sal_Bool SAL_CALL
hasByName( const OUString
& Name
) override
139 { return _xNameAccess
->hasByName( Name
); }
142 virtual void SAL_CALL
insertByIndex( sal_Int32 Index
, const Any
& Element
) override
143 { _xIndexContainer
->insertByIndex( Index
, Element
); }
145 virtual void SAL_CALL
removeByIndex( sal_Int32 Index
) override
146 { _xIndexContainer
->removeByIndex( Index
); }
149 virtual void SAL_CALL
replaceByIndex( sal_Int32 Index
, const Any
& Element
) override
150 { _xIndexReplace
->replaceByIndex( Index
, Element
); }
153 virtual sal_Int32 SAL_CALL
getCount() override
154 { return _xIndexAccess
->getCount(); }
156 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
) override
157 { return _xIndexAccess
->getByIndex( Index
); }
159 // XEnumerationAccess
160 virtual Reference
<XEnumeration
> SAL_CALL
createEnumeration() override
161 { return _xEnumerationAccess
->createEnumeration(); }
164 virtual OUString SAL_CALL
getExactName( const OUString
& rApproximateName
) override
;
168 void setMaterial( const Any
& rMaterial
);
170 void getInfoSequenceImpl( Sequence
< OUString
>* pStringSeq
, Sequence
< InvocationInfo
>* pInfoSeq
);
171 void fillInfoForNameAccess( InvocationInfo
& rInfo
, const OUString
& aName
);
172 static void fillInfoForProperty( InvocationInfo
& rInfo
, const Property
& rProp
);
173 static void fillInfoForMethod( InvocationInfo
& rInfo
, const Reference
< XIdlMethod
>& xMethod
);
175 Reference
<XTypeConverter
> xTypeConverter
;
176 Reference
<XIntrospection
> xIntrospection
;
177 Reference
<XIdlReflection
> xCoreReflection
;
180 // _xDirect and (_xIntrospectionAccess, xPropertySet) are exclusive
181 Reference
<XInvocation
> _xDirect
;
182 Reference
<XInvocation2
> _xDirect2
;
183 Reference
<XPropertySet
> _xPropertySet
;
184 Reference
<XIntrospectionAccess
> _xIntrospectionAccess
;
186 // supplied Interfaces
187 Reference
<XNameContainer
> _xNameContainer
;
188 Reference
<XNameReplace
> _xNameReplace
;
189 Reference
<XNameAccess
> _xNameAccess
;
190 Reference
<XIndexContainer
> _xIndexContainer
;
191 Reference
<XIndexReplace
> _xIndexReplace
;
192 Reference
<XIndexAccess
> _xIndexAccess
;
193 Reference
<XEnumerationAccess
> _xEnumerationAccess
;
194 Reference
<XElementAccess
> _xElementAccess
;
197 Reference
<XExactName
> _xENDirect
, _xENIntrospection
;
204 Invocation_Impl::Invocation_Impl
206 const Any
& rAdapted
,
207 const Reference
<XTypeConverter
> & rTC
,
208 const Reference
<XIntrospection
> & rI
,
209 const Reference
<XIdlReflection
> & rCR
,
212 : xTypeConverter( rTC
)
213 , xIntrospection( rI
)
214 , xCoreReflection( rCR
)
215 , mbFromOLE( bFromOLE
)
217 setMaterial( rAdapted
);
220 //### INTERFACE IMPLEMENTATIONS ####################################################################
223 Any SAL_CALL
Invocation_Impl::queryInterface( const Type
& aType
)
225 // PropertySet implementation
226 Any a
= ::cppu::queryInterface( aType
,
227 static_cast< XInvocation
* >(this),
228 static_cast< XMaterialHolder
* >(this),
229 static_cast< XTypeProvider
* >(this) );
235 if( aType
== cppu::UnoType
<XExactName
>::get())
237 // Invocation does not support XExactName, if direct object supports
238 // XInvocation, but not XExactName. Except when called from OLE Automation.
240 (_xDirect
.is() && _xENDirect
.is()) ||
241 (!_xDirect
.is() && _xENIntrospection
.is()))
243 return Any( Reference
< XExactName
>( static_cast< XExactName
* >(this) ) );
246 else if ( aType
== cppu::UnoType
<XNameContainer
>::get())
248 if( _xNameContainer
.is() )
249 return Any( Reference
< XNameContainer
>( static_cast< XNameContainer
* >(this) ) );
251 else if ( aType
== cppu::UnoType
<XNameReplace
>::get())
253 if( _xNameReplace
.is() )
254 return Any( Reference
< XNameReplace
>( static_cast< XNameReplace
* >(this) ) );
256 else if ( aType
== cppu::UnoType
<XNameAccess
>::get())
258 if( _xNameAccess
.is() )
259 return Any( Reference
< XNameAccess
>( static_cast< XNameAccess
* >(this) ) );
261 else if ( aType
== cppu::UnoType
<XIndexContainer
>::get())
263 if (_xIndexContainer
.is())
264 return Any( Reference
< XIndexContainer
>( static_cast< XIndexContainer
* >(this) ) );
266 else if ( aType
== cppu::UnoType
<XIndexReplace
>::get())
268 if (_xIndexReplace
.is())
269 return Any( Reference
< XIndexReplace
>( static_cast< XIndexReplace
* >(this) ) );
271 else if ( aType
== cppu::UnoType
<XIndexAccess
>::get())
273 if (_xIndexAccess
.is())
274 return Any( Reference
< XIndexAccess
>( static_cast< XIndexAccess
* >(this) ) );
276 else if ( aType
== cppu::UnoType
<XEnumerationAccess
>::get())
278 if (_xEnumerationAccess
.is())
279 return Any( Reference
< XEnumerationAccess
>( static_cast< XEnumerationAccess
* >(this) ) );
281 else if ( aType
== cppu::UnoType
<XElementAccess
>::get())
283 if (_xElementAccess
.is())
285 return Any( Reference
< XElementAccess
>(
286 static_cast< XElementAccess
* >(static_cast< XNameContainer
* >(this)) ) );
289 else if ( aType
== cppu::UnoType
<XInvocation2
>::get())
291 // Invocation does not support XInvocation2, if direct object supports
292 // XInvocation, but not XInvocation2.
294 ( _xDirect
.is() && _xDirect2
.is()) ||
295 (!_xDirect
.is() && _xIntrospectionAccess
.is() ) )
297 return Any( Reference
< XInvocation2
>( static_cast< XInvocation2
* >(this) ) );
301 return OWeakObject::queryInterface( aType
);
305 Any
Invocation_Impl::getMaterial()
307 // AB, 12.2.1999 Make sure that the material is taken when possible
308 // from the direct Invocation of the Introspection, otherwise structs
309 // are not handled correctly
310 Reference
<XMaterialHolder
> xMaterialHolder
;
313 xMaterialHolder
.set( _xDirect
, UNO_QUERY
);
314 //_xDirect->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
316 else if( _xIntrospectionAccess
.is() )
318 xMaterialHolder
.set( _xIntrospectionAccess
, UNO_QUERY
);
319 //_xIntrospectionAccess->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
321 if( xMaterialHolder
.is() )
323 return xMaterialHolder
->getMaterial();
329 void Invocation_Impl::setMaterial( const Any
& rMaterial
)
331 // set the material first and only once
332 _aMaterial
= rMaterial
;
334 // First do this outside the guard
335 _xDirect
.set( rMaterial
, UNO_QUERY
);
337 if( !mbFromOLE
&& _xDirect
.is() )
339 // Consult object directly
340 _xElementAccess
.set( _xDirect
, UNO_QUERY
);
341 _xEnumerationAccess
.set( _xDirect
, UNO_QUERY
);
342 _xIndexAccess
.set( _xDirect
, UNO_QUERY
);
343 _xIndexReplace
.set( _xDirect
, UNO_QUERY
);
344 _xIndexContainer
.set( _xDirect
, UNO_QUERY
);
345 _xNameAccess
.set( _xDirect
, UNO_QUERY
);
346 _xNameReplace
.set( _xDirect
, UNO_QUERY
);
347 _xNameContainer
.set( _xDirect
, UNO_QUERY
);
348 _xENDirect
.set( _xDirect
, UNO_QUERY
);
349 _xDirect2
.set( _xDirect
, UNO_QUERY
);
353 // Make Invocation on the Introspection
354 if (xIntrospection
.is())
356 _xIntrospectionAccess
= xIntrospection
->inspect( _aMaterial
);
357 if( _xIntrospectionAccess
.is() )
360 _xIntrospectionAccess
->queryAdapter(
361 cppu::UnoType
<XElementAccess
>::get()), UNO_QUERY
);
363 if( _xElementAccess
.is() )
365 _xEnumerationAccess
.set(
366 _xIntrospectionAccess
->queryAdapter(
367 cppu::UnoType
<XEnumerationAccess
>::get()), UNO_QUERY
);
370 _xIntrospectionAccess
->queryAdapter(
371 cppu::UnoType
<XIndexAccess
>::get()), UNO_QUERY
);
373 if( _xIndexAccess
.is() )
376 _xIntrospectionAccess
->queryAdapter(
377 cppu::UnoType
<XIndexReplace
>::get()), UNO_QUERY
);
379 _xIndexContainer
.set(
380 _xIntrospectionAccess
->queryAdapter(
381 cppu::UnoType
<XIndexContainer
>::get()), UNO_QUERY
);
385 _xIntrospectionAccess
->queryAdapter(
386 cppu::UnoType
<XNameAccess
>::get()), UNO_QUERY
);
388 if( _xNameAccess
.is() )
391 _xIntrospectionAccess
->queryAdapter(
392 cppu::UnoType
<XNameReplace
>::get()), UNO_QUERY
);
395 _xIntrospectionAccess
->queryAdapter(
396 cppu::UnoType
<XNameContainer
>::get()), UNO_QUERY
);
400 _xPropertySet
.set( _xIntrospectionAccess
->queryAdapter( cppu::UnoType
<XPropertySet
>::get()),
403 _xENIntrospection
.set( _xIntrospectionAccess
, UNO_QUERY
);
410 OUString
Invocation_Impl::getExactName( const OUString
& rApproximateName
)
413 return _xENDirect
->getExactName( rApproximateName
);
416 if (_xENIntrospection
.is())
417 aRet
= _xENIntrospection
->getExactName( rApproximateName
);
422 Reference
<XIntrospectionAccess
> Invocation_Impl::getIntrospection()
425 return _xDirect
->getIntrospection();
427 return _xIntrospectionAccess
;
431 sal_Bool
Invocation_Impl::hasMethod( const OUString
& Name
)
433 if (!mbFromOLE
&& _xDirect
.is())
434 return _xDirect
->hasMethod( Name
);
435 if( _xIntrospectionAccess
.is() )
436 return _xIntrospectionAccess
->hasMethod( Name
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
441 sal_Bool
Invocation_Impl::hasProperty( const OUString
& Name
)
445 bool bRet
= _xDirect
->hasProperty( Name
);
446 if (bRet
|| !mbFromOLE
)
450 if( _xIntrospectionAccess
.is()
451 && _xIntrospectionAccess
->hasProperty( Name
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
454 if( _xNameAccess
.is() )
455 return _xNameAccess
->hasByName( Name
);
460 Any
Invocation_Impl::getValue( const OUString
& PropertyName
)
465 return _xDirect
->getValue( PropertyName
);
475 if( _xIntrospectionAccess
.is() && _xPropertySet
.is()
476 && _xIntrospectionAccess
->hasProperty
477 ( PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
479 return _xPropertySet
->getPropertyValue( PropertyName
);
482 if( _xNameAccess
.is() && _xNameAccess
->hasByName( PropertyName
) )
483 return _xNameAccess
->getByName( PropertyName
);
485 catch (UnknownPropertyException
&)
489 catch (RuntimeException
&)
497 throw UnknownPropertyException( "cannot get value " + PropertyName
);
501 void Invocation_Impl::setValue( const OUString
& PropertyName
, const Any
& Value
)
507 _xDirect
->setValue( PropertyName
, Value
);
519 if( _xIntrospectionAccess
.is() && _xPropertySet
.is()
520 && _xIntrospectionAccess
->hasProperty(
521 PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
523 Property aProp
= _xIntrospectionAccess
->getProperty(
524 PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
);
525 Reference
< XIdlClass
> r
= TypeToIdlClass( aProp
.Type
, xCoreReflection
);
526 if( r
->isAssignableFrom( TypeToIdlClass( Value
.getValueType(), xCoreReflection
) ) )
527 _xPropertySet
->setPropertyValue( PropertyName
, Value
);
528 else if( xTypeConverter
.is() )
529 _xPropertySet
->setPropertyValue(
530 PropertyName
, xTypeConverter
->convertTo( Value
, aProp
.Type
) );
532 throw RuntimeException( u
"no type converter service!"_ustr
);
535 else if( _xNameContainer
.is() )
537 // Note: This misfeature deliberately not adapted to apply to objects which
538 // have XNameReplace but not XNameContainer
540 Reference
< XIdlClass
> r
=
541 TypeToIdlClass( _xNameContainer
->getElementType(), xCoreReflection
);
542 if( r
->isAssignableFrom(TypeToIdlClass( Value
.getValueType(), xCoreReflection
) ) )
544 else if( xTypeConverter
.is() )
545 aConv
= xTypeConverter
->convertTo( Value
, _xNameContainer
->getElementType() );
547 throw RuntimeException( u
"no type converter service!"_ustr
);
549 // Replace if present, otherwise insert
550 if (_xNameContainer
->hasByName( PropertyName
))
551 _xNameContainer
->replaceByName( PropertyName
, aConv
);
553 _xNameContainer
->insertByName( PropertyName
, aConv
);
556 throw UnknownPropertyException( u
"no introspection nor name container!"_ustr
);
558 catch (UnknownPropertyException
&)
562 catch (CannotConvertException
&)
566 catch (InvocationTargetException
&)
570 catch (RuntimeException
&)
574 catch (const Exception
& exc
)
576 css::uno::Any anyEx
= cppu::getCaughtException();
577 throw InvocationTargetException(
578 "exception occurred in setValue(): " + exc
.Message
,
579 Reference
< XInterface
>(), anyEx
);
584 Any
Invocation_Impl::invoke( const OUString
& FunctionName
, const Sequence
<Any
>& InParams
,
585 Sequence
<sal_Int16
>& OutIndices
, Sequence
<Any
>& OutParams
)
587 if (!mbFromOLE
&& _xDirect
.is())
588 return _xDirect
->invoke( FunctionName
, InParams
, OutIndices
, OutParams
);
590 if (_xIntrospectionAccess
.is())
592 // throw NoSuchMethodException if not exist
593 Reference
<XIdlMethod
> xMethod
= _xIntrospectionAccess
->getMethod(
594 FunctionName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
597 Sequence
<ParamInfo
> aFParams
= xMethod
->getParameterInfos();
598 const ParamInfo
* pFParams
= aFParams
.getConstArray();
599 sal_Int32 nFParamsLen
= aFParams
.getLength();
600 if (nFParamsLen
!= InParams
.getLength())
602 throw IllegalArgumentException(
603 "incorrect number of parameters passed invoking function " + FunctionName
+
604 ": expected " + OUString::number(nFParamsLen
) + ", got " + OUString::number(InParams
.getLength()),
605 getXWeak(), sal_Int16(1) );
609 const Any
* pInParams
= InParams
.getConstArray();
611 // Introspection Invoke Parameter
612 Sequence
<Any
> aInvokeParams( nFParamsLen
);
613 Any
* pInvokeParams
= aInvokeParams
.getArray();
616 OutIndices
.realloc( nFParamsLen
);
617 sal_Int16
* pOutIndices
= OutIndices
.getArray();
618 sal_uInt32 nOutIndex
= 0;
620 for ( sal_Int32 nPos
= 0; nPos
< nFParamsLen
; ++nPos
)
624 const ParamInfo
& rFParam
= pFParams
[nPos
];
625 const Reference
<XIdlClass
>& rDestType
= rFParam
.aType
;
627 // is IN/INOUT parameter?
628 if (rFParam
.aMode
!= ParamMode_OUT
)
630 if (rDestType
->isAssignableFrom( TypeToIdlClass( pInParams
[nPos
].getValueType(), xCoreReflection
) ))
632 pInvokeParams
[nPos
] = pInParams
[nPos
];
634 else if (xTypeConverter
.is())
636 Type
aDestType( rDestType
->getTypeClass(), rDestType
->getName() );
637 pInvokeParams
[nPos
] = xTypeConverter
->convertTo( pInParams
[nPos
], aDestType
);
641 throw CannotConvertException(u
"invocation type mismatch!"_ustr
, *this, {}, 0, 0);
645 // is OUT/INOUT parameter?
646 if (rFParam
.aMode
!= ParamMode_IN
)
648 pOutIndices
[nOutIndex
] = static_cast<sal_Int16
>(nPos
);
649 if (rFParam
.aMode
== ParamMode_OUT
)
650 rDestType
->createObject( pInvokeParams
[nPos
] ); // default init
654 catch( CannotConvertException
& rExc
)
656 rExc
.ArgumentIndex
= nPos
; // Add optional parameter index
662 Any aRet
= xMethod
->invoke( _aMaterial
, aInvokeParams
);
665 OutIndices
.realloc( nOutIndex
);
666 OutParams
.realloc( nOutIndex
);
668 std::transform(std::cbegin(OutIndices
), std::cend(OutIndices
), OutParams
.getArray(),
669 [&pInvokeParams
](const sal_Int16 nIndex
) -> Any
{ return pInvokeParams
[nIndex
]; });
674 throw RuntimeException(u
"invocation lacking of introspection access!"_ustr
, *this);
679 // Struct to optimize sorting
684 // Defines where the member comes from
685 enum class Mode
{ NameAccess
, PropertySet
, Method
};
688 // Index to respective sequence
689 // (Index to NameAccess sequence for eMode==Mode::NameAccess etc.)
695 // Implementation of getting name or info
696 // String sequence will be filled when pStringSeq != NULL
697 // Info sequence will be filled when pInfoSeq != NULL
698 void Invocation_Impl::getInfoSequenceImpl
700 Sequence
< OUString
>* pStringSeq
,
701 Sequence
< InvocationInfo
>* pInfoSeq
704 //Sequence< OUString > aStrSeq;
706 //pStringSeq = &aStrSeq;
709 // Get all needed sequences
710 Sequence
<OUString
> aNameAccessNames
;
711 Sequence
<Property
> aPropertySeq
;
712 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
;
714 if( _xNameAccess
.is() )
716 aNameAccessNames
= _xNameAccess
->getElementNames();
719 if( _xIntrospectionAccess
.is() )
721 aPropertySeq
= _xIntrospectionAccess
->getProperties
722 ( PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
724 aMethodSeq
= _xIntrospectionAccess
->getMethods
725 ( MethodConcept::ALL
- MethodConcept::DANGEROUS
);
728 sal_Int32 nNameAccessCount
= aNameAccessNames
.getLength();
729 sal_Int32 nPropertyCount
= aPropertySeq
.getLength();
730 sal_Int32 nMethodCount
= aMethodSeq
.getLength();
731 sal_Int32 nTotalCount
= nNameAccessCount
+ nPropertyCount
+ nMethodCount
;
733 // Create and fill array of MemberItems
734 std::unique_ptr
< MemberItem
[]> pItems( new MemberItem
[ nTotalCount
] );
735 const OUString
* pStrings
= aNameAccessNames
.getConstArray();
736 const Property
* pProps
= aPropertySeq
.getConstArray();
737 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
739 // Fill array of MemberItems
740 sal_Int32 i
, iTotal
= 0;
743 for( i
= 0 ; i
< nNameAccessCount
; i
++, iTotal
++ )
745 MemberItem
& rItem
= pItems
[ iTotal
];
746 rItem
.aName
= pStrings
[ i
];
747 rItem
.eMode
= MemberItem::Mode::NameAccess
;
752 for( i
= 0 ; i
< nPropertyCount
; i
++, iTotal
++ )
754 MemberItem
& rItem
= pItems
[ iTotal
];
755 rItem
.aName
= pProps
[ i
].Name
;
756 rItem
.eMode
= MemberItem::Mode::PropertySet
;
761 for( i
= 0 ; i
< nMethodCount
; i
++, iTotal
++ )
763 MemberItem
& rItem
= pItems
[ iTotal
];
764 Reference
< XIdlMethod
> xMethod
= pMethods
[ i
];
765 rItem
.aName
= xMethod
->getName();
766 rItem
.eMode
= MemberItem::Mode::Method
;
770 // Setting up result sequences
771 OUString
* pRetStrings
= nullptr;
774 pStringSeq
->realloc( nTotalCount
);
775 pRetStrings
= pStringSeq
->getArray();
778 InvocationInfo
* pRetInfos
= nullptr;
781 pInfoSeq
->realloc( nTotalCount
);
782 pRetInfos
= pInfoSeq
->getArray();
785 // Fill result sequences in the correct order of members
786 for( iTotal
= 0 ; iTotal
< nTotalCount
; iTotal
++ )
788 MemberItem
& rItem
= pItems
[ iTotal
];
791 pRetStrings
[ iTotal
] = rItem
.aName
;
796 if( rItem
.eMode
== MemberItem::Mode::NameAccess
)
798 fillInfoForNameAccess( pRetInfos
[ iTotal
], rItem
.aName
);
800 else if( rItem
.eMode
== MemberItem::Mode::PropertySet
)
802 fillInfoForProperty( pRetInfos
[ iTotal
], pProps
[ rItem
.nIndex
] );
804 else if( rItem
.eMode
== MemberItem::Mode::Method
)
806 fillInfoForMethod( pRetInfos
[ iTotal
], pMethods
[ rItem
.nIndex
] );
813 Sequence
< OUString
> SAL_CALL
Invocation_Impl::getMemberNames( )
817 return _xDirect2
->getMemberNames();
819 Sequence
< OUString
> aRetSeq
;
820 getInfoSequenceImpl( &aRetSeq
, nullptr );
824 Sequence
< InvocationInfo
> SAL_CALL
Invocation_Impl::getInfo( )
828 return _xDirect2
->getInfo();
830 Sequence
< InvocationInfo
> aRetSeq
;
831 getInfoSequenceImpl( nullptr, &aRetSeq
);
835 InvocationInfo SAL_CALL
Invocation_Impl::getInfoForName( const OUString
& aName
, sal_Bool bExact
)
839 return _xDirect2
->getInfoForName( aName
, bExact
);
843 OUString aExactName
= aName
;
844 InvocationInfo aRetInfo
;
847 aExactName
= getExactName( aName
);
848 if( !aExactName
.isEmpty() )
850 if( _xIntrospectionAccess
->hasMethod( aExactName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
) )
852 Reference
<XIdlMethod
> xMethod
= _xIntrospectionAccess
->getMethod
853 ( aExactName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
854 fillInfoForMethod( aRetInfo
, xMethod
);
859 if( _xIntrospectionAccess
.is() && _xIntrospectionAccess
->hasProperty
860 ( aExactName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
862 Property aProp
= _xIntrospectionAccess
->getProperty
863 ( aExactName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
);
864 fillInfoForProperty( aRetInfo
, aProp
);
868 else if( _xNameAccess
.is() && _xNameAccess
->hasByName( aExactName
) )
870 fillInfoForNameAccess( aRetInfo
, aExactName
);
877 throw IllegalArgumentException(
878 "getExactName(), Unknown name " + aName
,
884 // Helper functions to fill InvocationInfo for XNameAccess
885 void Invocation_Impl::fillInfoForNameAccess
887 InvocationInfo
& rInfo
,
888 const OUString
& aName
892 rInfo
.eMemberType
= MemberType_PROPERTY
;
893 rInfo
.PropertyAttribute
= 0;
894 if( !_xNameContainer
.is() )
896 rInfo
.PropertyAttribute
= PropertyAttribute::READONLY
;
898 rInfo
.aType
= _xNameAccess
->getElementType();
901 void Invocation_Impl::fillInfoForProperty
903 InvocationInfo
& rInfo
,
904 const Property
& rProp
907 rInfo
.aName
= rProp
.Name
;
908 rInfo
.eMemberType
= MemberType_PROPERTY
;
909 rInfo
.PropertyAttribute
= rProp
.Attributes
;
910 rInfo
.aType
= rProp
.Type
;
913 void Invocation_Impl::fillInfoForMethod
915 InvocationInfo
& rInfo
,
916 const Reference
< XIdlMethod
>& xMethod
919 rInfo
.aName
= xMethod
->getName();
920 rInfo
.eMemberType
= MemberType_METHOD
;
921 Reference
< XIdlClass
> xReturnClass
= xMethod
->getReturnType();
922 rInfo
.aType
= Type(xReturnClass
->getTypeClass(), xReturnClass
->getName());
923 Sequence
<ParamInfo
> aParamInfos
= xMethod
->getParameterInfos();
924 sal_Int32 nParamCount
= aParamInfos
.getLength();
925 if( nParamCount
<= 0 )
928 const ParamInfo
* pInfo
= aParamInfos
.getConstArray();
930 rInfo
.aParamTypes
.realloc( nParamCount
);
931 Type
* pParamTypes
= rInfo
.aParamTypes
.getArray();
932 rInfo
.aParamModes
.realloc( nParamCount
);
933 ParamMode
* pParamModes
= rInfo
.aParamModes
.getArray();
935 for( sal_Int32 i
= 0 ; i
< nParamCount
; i
++ )
937 Reference
< XIdlClass
> xParamClass
= pInfo
[i
].aType
;
938 pParamTypes
[ i
] = Type(xParamClass
->getTypeClass(), xParamClass
->getName());
939 pParamModes
[ i
] = pInfo
[i
].aMode
;
945 Sequence
< Type
> SAL_CALL
Invocation_Impl::getTypes()
947 static Sequence
<Type
> s_types
= [this]() {
948 std::vector
<Type
> tmp
{
949 cppu::UnoType
<XTypeProvider
>::get(),
950 cppu::UnoType
<XWeak
>::get(),
951 cppu::UnoType
<XInvocation
>::get(),
952 cppu::UnoType
<XMaterialHolder
>::get() };
954 // Invocation does not support XExactName if direct object supports
955 // XInvocation, but not XExactName.
956 if ((_xDirect
.is() && _xENDirect
.is()) || (!_xDirect
.is() && _xENIntrospection
.is()))
957 tmp
.push_back(cppu::UnoType
<XExactName
>::get());
958 if (_xNameContainer
.is())
959 tmp
.push_back(cppu::UnoType
<XNameContainer
>::get());
960 if (_xNameReplace
.is())
961 tmp
.push_back(cppu::UnoType
<XNameReplace
>::get());
962 if (_xNameAccess
.is())
963 tmp
.push_back(cppu::UnoType
<XNameAccess
>::get());
964 if (_xIndexContainer
.is())
965 tmp
.push_back(cppu::UnoType
<XIndexContainer
>::get());
966 if (_xIndexReplace
.is())
967 tmp
.push_back(cppu::UnoType
<XIndexReplace
>::get());
968 if (_xIndexAccess
.is())
969 tmp
.push_back(cppu::UnoType
<XIndexAccess
>::get());
970 if (_xEnumerationAccess
.is())
971 tmp
.push_back(cppu::UnoType
<XEnumerationAccess
>::get());
972 if (_xElementAccess
.is())
973 tmp
.push_back(cppu::UnoType
<XElementAccess
>::get());
974 // Invocation does not support XInvocation2, if direct object supports
975 // XInvocation, but not XInvocation2.
976 if ((_xDirect
.is() && _xDirect2
.is()) || (!_xDirect
.is() && _xIntrospectionAccess
.is()))
977 tmp
.push_back(cppu::UnoType
<XInvocation2
>::get());
979 return comphelper::containerToSequence(tmp
);
984 Sequence
< sal_Int8
> SAL_CALL
Invocation_Impl::getImplementationId( )
986 return css::uno::Sequence
<sal_Int8
>();
991 class InvocationService
992 : public WeakImplHelper
< XSingleServiceFactory
, XServiceInfo
>
995 explicit InvocationService( const Reference
<XComponentContext
> & xCtx
);
998 OUString SAL_CALL
getImplementationName() override
;
999 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) override
;
1000 Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
1002 // XSingleServiceFactory
1003 Reference
<XInterface
> SAL_CALL
createInstance() override
;
1004 Reference
<XInterface
> SAL_CALL
createInstanceWithArguments(
1005 const Sequence
<Any
>& rArguments
) override
;
1007 Reference
<XComponentContext
> mxCtx
;
1008 Reference
<XMultiComponentFactory
> mxSMgr
;
1009 Reference
<XTypeConverter
> xTypeConverter
;
1010 Reference
<XIntrospection
> xIntrospection
;
1011 Reference
<XIdlReflection
> xCoreReflection
;
1016 InvocationService::InvocationService( const Reference
<XComponentContext
> & xCtx
)
1018 , mxSMgr( xCtx
->getServiceManager() )
1019 , xCoreReflection( css::reflection::theCoreReflection::get(mxCtx
) )
1022 mxSMgr
->createInstanceWithContext( u
"com.sun.star.script.Converter"_ustr
, xCtx
),
1024 xIntrospection
= theIntrospection::get(xCtx
);
1028 OUString
InvocationService::getImplementationName()
1030 return u
"com.sun.star.comp.stoc.Invocation"_ustr
;
1034 sal_Bool
InvocationService::supportsService(const OUString
& ServiceName
)
1036 return cppu::supportsService(this, ServiceName
);
1040 Sequence
< OUString
> InvocationService::getSupportedServiceNames()
1042 return { u
"com.sun.star.script.Invocation"_ustr
};
1046 Reference
<XInterface
> InvocationService::createInstance()
1048 //TODO:throw( Exception("no default construction of invocation adapter possible!", *this) );
1049 return Reference
<XInterface
>(); // dummy
1053 Reference
<XInterface
> InvocationService::createInstanceWithArguments(
1054 const Sequence
<Any
>& rArguments
)
1056 if (rArguments
.getLength() == 2)
1059 if ((rArguments
[1] >>= aArg1
) &&
1062 return Reference
< XInterface
>
1063 ( *new Invocation_Impl( *rArguments
.getConstArray(),
1064 xTypeConverter
, xIntrospection
, xCoreReflection
, true ) );
1067 if (rArguments
.getLength() == 1)
1069 return Reference
< XInterface
>
1070 ( *new Invocation_Impl( *rArguments
.getConstArray(),
1071 xTypeConverter
, xIntrospection
, xCoreReflection
, false ) );
1074 //TODO:throw( Exception("no default construction of invocation adapter possible!", *this) );
1075 return Reference
<XInterface
>();
1078 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
1079 stoc_InvocationService_get_implementation(
1080 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
1082 return cppu::acquire(new InvocationService(context
));
1088 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */