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 <osl/mutex.hxx>
21 #include <cppuhelper/queryinterface.hxx>
22 #include <cppuhelper/weak.hxx>
23 #include <cppuhelper/factory.hxx>
24 #include <cppuhelper/implementationentry.hxx>
25 #include <cppuhelper/supportsservice.hxx>
26 #include <cppuhelper/typeprovider.hxx>
27 #include <cppuhelper/implbase.hxx>
29 #include <com/sun/star/script/CannotConvertException.hpp>
30 #include <com/sun/star/script/FailReason.hpp>
31 #include <com/sun/star/script/XTypeConverter.hpp>
32 #include <com/sun/star/script/XInvocation.hpp>
33 #include <com/sun/star/script/XInvocation2.hpp>
34 #include <com/sun/star/reflection/XIdlReflection.hpp>
35 #include <com/sun/star/reflection/theCoreReflection.hpp>
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/container/XIndexContainer.hpp>
38 #include <com/sun/star/container/XEnumerationAccess.hpp>
39 #include <com/sun/star/beans/XExactName.hpp>
40 #include <com/sun/star/beans/XMaterialHolder.hpp>
41 #include <com/sun/star/beans/theIntrospection.hpp>
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/beans/PropertyAttribute.hpp>
44 #include <com/sun/star/beans/MethodConcept.hpp>
45 #include <com/sun/star/beans/PropertyConcept.hpp>
46 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
48 #include <com/sun/star/lang/XServiceInfo.hpp>
49 #include <com/sun/star/lang/XTypeProvider.hpp>
50 #include <com/sun/star/registry/XRegistryKey.hpp>
53 #include <rtl/ustrbuf.hxx>
54 #include <rtl/strbuf.hxx>
56 #define SERVICENAME "com.sun.star.script.Invocation"
57 #define IMPLNAME "com.sun.star.comp.stoc.Invocation"
59 using namespace css::uno
;
60 using namespace css::lang
;
61 using namespace css::script
;
62 using namespace css::reflection
;
63 using namespace css::beans
;
64 using namespace css::registry
;
65 using namespace css::container
;
71 static Sequence
< OUString
> inv_getSupportedServiceNames()
73 Sequence
< OUString
> seqNames
{ SERVICENAME
};
77 static OUString
inv_getImplementationName()
79 return OUString(IMPLNAME
);
82 // TODO: Implement centrally
83 inline Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
, const Reference
< XIdlReflection
> & xRefl
)
85 return xRefl
->forName( rType
.getTypeName() );
92 , public XNameContainer
93 , public XIndexContainer
94 , public XEnumerationAccess
96 , public XMaterialHolder
97 , public XTypeProvider
100 Invocation_Impl( const Any
& rAdapted
, const Reference
<XTypeConverter
> &,
101 const Reference
<XIntrospection
> &,
102 const Reference
<XIdlReflection
> & );
105 virtual Any SAL_CALL
queryInterface( const Type
& aType
) override
;
106 virtual void SAL_CALL
acquire() throw() override
{ OWeakObject::acquire(); }
107 virtual void SAL_CALL
release() throw() override
{ OWeakObject::release(); }
111 virtual Sequence
< css::uno::Type
> SAL_CALL
getTypes( ) override
;
112 virtual Sequence
< sal_Int8
> SAL_CALL
getImplementationId( ) override
;
115 virtual Any SAL_CALL
getMaterial() override
;
118 virtual Reference
<XIntrospectionAccess
> SAL_CALL
getIntrospection() override
;
119 virtual Any SAL_CALL
invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
, Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
) override
;
120 virtual void SAL_CALL
setValue(const OUString
& PropertyName
, const Any
& Value
) override
;
121 virtual Any SAL_CALL
getValue(const OUString
& PropertyName
) override
;
122 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
) override
;
123 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
) override
;
126 virtual Sequence
< OUString
> SAL_CALL
getMemberNames( ) override
;
127 virtual Sequence
< InvocationInfo
> SAL_CALL
getInfo( ) override
;
128 virtual InvocationInfo SAL_CALL
getInfoForName( const OUString
& aName
, sal_Bool bExact
) override
;
130 // All Access and Container methods are not thread safe
132 virtual Type SAL_CALL
getElementType() override
133 { return _xElementAccess
->getElementType(); }
135 virtual sal_Bool SAL_CALL
hasElements() override
136 { return _xElementAccess
->hasElements(); }
139 virtual void SAL_CALL
insertByName( const OUString
& Name
, const Any
& Element
) override
140 { _xNameContainer
->insertByName( Name
, Element
); }
142 virtual void SAL_CALL
removeByName( const OUString
& Name
) override
143 { _xNameContainer
->removeByName( Name
); }
146 virtual void SAL_CALL
replaceByName( const OUString
& Name
, const Any
& Element
) override
147 { _xNameReplace
->replaceByName( Name
, Element
); }
150 virtual Any SAL_CALL
getByName( const OUString
& Name
) override
151 { return _xNameAccess
->getByName( Name
); }
153 virtual Sequence
<OUString
> SAL_CALL
getElementNames() override
154 { return _xNameAccess
->getElementNames(); }
156 virtual sal_Bool SAL_CALL
hasByName( const OUString
& Name
) override
157 { return _xNameAccess
->hasByName( Name
); }
160 virtual void SAL_CALL
insertByIndex( sal_Int32 Index
, const Any
& Element
) override
161 { _xIndexContainer
->insertByIndex( Index
, Element
); }
163 virtual void SAL_CALL
removeByIndex( sal_Int32 Index
) override
164 { _xIndexContainer
->removeByIndex( Index
); }
167 virtual void SAL_CALL
replaceByIndex( sal_Int32 Index
, const Any
& Element
) override
168 { _xIndexReplace
->replaceByIndex( Index
, Element
); }
171 virtual sal_Int32 SAL_CALL
getCount() override
172 { return _xIndexAccess
->getCount(); }
174 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
) override
175 { return _xIndexAccess
->getByIndex( Index
); }
177 // XEnumerationAccess
178 virtual Reference
<XEnumeration
> SAL_CALL
createEnumeration() override
179 { return _xEnumerationAccess
->createEnumeration(); }
182 virtual OUString SAL_CALL
getExactName( const OUString
& rApproximateName
) override
;
186 void setMaterial( const Any
& rMaterial
);
188 void getInfoSequenceImpl( Sequence
< OUString
>* pStringSeq
, Sequence
< InvocationInfo
>* pInfoSeq
);
189 void fillInfoForNameAccess( InvocationInfo
& rInfo
, const OUString
& aName
);
190 static void fillInfoForProperty( InvocationInfo
& rInfo
, const Property
& rProp
);
191 static void fillInfoForMethod( InvocationInfo
& rInfo
, const Reference
< XIdlMethod
>& xMethod
);
193 Reference
<XTypeConverter
> xTypeConverter
;
194 Reference
<XIntrospection
> xIntrospection
;
195 Reference
<XIdlReflection
> xCoreReflection
;
198 // _xDirect and (_xIntrospectionAccess, xPropertySet) are exclusive
199 Reference
<XInvocation
> _xDirect
;
200 Reference
<XInvocation2
> _xDirect2
;
201 Reference
<XPropertySet
> _xPropertySet
;
202 Reference
<XIntrospectionAccess
> _xIntrospectionAccess
;
204 // supplied Interfaces
205 Reference
<XNameContainer
> _xNameContainer
;
206 Reference
<XNameReplace
> _xNameReplace
;
207 Reference
<XNameAccess
> _xNameAccess
;
208 Reference
<XIndexContainer
> _xIndexContainer
;
209 Reference
<XIndexReplace
> _xIndexReplace
;
210 Reference
<XIndexAccess
> _xIndexAccess
;
211 Reference
<XEnumerationAccess
> _xEnumerationAccess
;
212 Reference
<XElementAccess
> _xElementAccess
;
215 Reference
<XExactName
> _xENDirect
, _xENIntrospection
;
219 Invocation_Impl::Invocation_Impl
221 const Any
& rAdapted
,
222 const Reference
<XTypeConverter
> & rTC
,
223 const Reference
<XIntrospection
> & rI
,
224 const Reference
<XIdlReflection
> & rCR
226 : xTypeConverter( rTC
)
227 , xIntrospection( rI
)
228 , xCoreReflection( rCR
)
230 setMaterial( rAdapted
);
233 //### INTERFACE IMPLEMENTATIONS ####################################################################
236 Any SAL_CALL
Invocation_Impl::queryInterface( const Type
& aType
)
238 // PropertySet implementation
239 Any a
= ::cppu::queryInterface( aType
,
240 (static_cast< XInvocation
* >(this)),
241 (static_cast< XMaterialHolder
* >(this)),
242 (static_cast< XTypeProvider
* >(this)) );
248 if( aType
== cppu::UnoType
<XExactName
>::get())
250 // Invocation does not support XExactName, if direct object supports
251 // XInvocation, but not XExactName.
252 if ((_xDirect
.is() && _xENDirect
.is()) ||
253 (!_xDirect
.is() && _xENIntrospection
.is()))
255 return makeAny( Reference
< XExactName
>( (static_cast< XExactName
* >(this)) ) );
258 else if ( aType
== cppu::UnoType
<XNameContainer
>::get())
260 if( _xNameContainer
.is() )
261 return makeAny( Reference
< XNameContainer
>( (static_cast< XNameContainer
* >(this)) ) );
263 else if ( aType
== cppu::UnoType
<XNameReplace
>::get())
265 if( _xNameReplace
.is() )
266 return makeAny( Reference
< XNameReplace
>( (static_cast< XNameReplace
* >(this)) ) );
268 else if ( aType
== cppu::UnoType
<XNameAccess
>::get())
270 if( _xNameAccess
.is() )
271 return makeAny( Reference
< XNameAccess
>( (static_cast< XNameAccess
* >(this)) ) );
273 else if ( aType
== cppu::UnoType
<XIndexContainer
>::get())
275 if (_xIndexContainer
.is())
276 return makeAny( Reference
< XIndexContainer
>( (static_cast< XIndexContainer
* >(this)) ) );
278 else if ( aType
== cppu::UnoType
<XIndexReplace
>::get())
280 if (_xIndexReplace
.is())
281 return makeAny( Reference
< XIndexReplace
>( (static_cast< XIndexReplace
* >(this)) ) );
283 else if ( aType
== cppu::UnoType
<XIndexAccess
>::get())
285 if (_xIndexAccess
.is())
286 return makeAny( Reference
< XIndexAccess
>( (static_cast< XIndexAccess
* >(this)) ) );
288 else if ( aType
== cppu::UnoType
<XEnumerationAccess
>::get())
290 if (_xEnumerationAccess
.is())
291 return makeAny( Reference
< XEnumerationAccess
>( (static_cast< XEnumerationAccess
* >(this)) ) );
293 else if ( aType
== cppu::UnoType
<XElementAccess
>::get())
295 if (_xElementAccess
.is())
297 return makeAny( Reference
< XElementAccess
>(
298 (static_cast< XElementAccess
* >((static_cast< XNameContainer
* >(this))) ) ) );
301 else if ( aType
== cppu::UnoType
<XInvocation2
>::get())
303 // Invocation does not support XInvocation2, if direct object supports
304 // XInvocation, but not XInvocation2.
305 if ( ( _xDirect
.is() && _xDirect2
.is()) ||
306 (!_xDirect
.is() && _xIntrospectionAccess
.is() ) )
308 return makeAny( Reference
< XInvocation2
>( (static_cast< XInvocation2
* >(this)) ) );
312 return OWeakObject::queryInterface( aType
);
316 Any
Invocation_Impl::getMaterial()
318 // AB, 12.2.1999 Make sure that the material is taken when possible
319 // from the direct Invocation of the Introspection, otherwise structs
320 // are not handled correctly
321 Reference
<XMaterialHolder
> xMaterialHolder
;
324 xMaterialHolder
.set( _xDirect
, UNO_QUERY
);
325 //_xDirect->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
327 else if( _xIntrospectionAccess
.is() )
329 xMaterialHolder
.set( _xIntrospectionAccess
, UNO_QUERY
);
330 //_xIntrospectionAccess->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
332 if( xMaterialHolder
.is() )
334 return xMaterialHolder
->getMaterial();
340 void Invocation_Impl::setMaterial( const Any
& rMaterial
)
342 // set the material first and only once
343 _aMaterial
= rMaterial
;
345 // First do this outside the guard
346 _xDirect
.set( rMaterial
, UNO_QUERY
);
350 // Consult object directly
351 _xElementAccess
.set( _xDirect
, UNO_QUERY
);
352 _xEnumerationAccess
.set( _xDirect
, UNO_QUERY
);
353 _xIndexAccess
.set( _xDirect
, UNO_QUERY
);
354 _xIndexReplace
.set( _xDirect
, UNO_QUERY
);
355 _xIndexContainer
.set( _xDirect
, UNO_QUERY
);
356 _xNameAccess
.set( _xDirect
, UNO_QUERY
);
357 _xNameReplace
.set( _xDirect
, UNO_QUERY
);
358 _xNameContainer
.set( _xDirect
, UNO_QUERY
);
359 _xENDirect
.set( _xDirect
, UNO_QUERY
);
360 _xDirect2
.set( _xDirect
, UNO_QUERY
);
363 //_xIntrospectionAccess = XIntrospectionAccessRef();
364 //_xPropertySet = XPropertySetRef();
368 // Make Invocation on the Introspection
369 if (xIntrospection
.is())
371 _xIntrospectionAccess
= xIntrospection
->inspect( _aMaterial
);
372 if( _xIntrospectionAccess
.is() )
375 _xIntrospectionAccess
->queryAdapter(
376 cppu::UnoType
<XElementAccess
>::get()), UNO_QUERY
);
378 if( _xElementAccess
.is() )
380 _xEnumerationAccess
.set(
381 _xIntrospectionAccess
->queryAdapter(
382 cppu::UnoType
<XEnumerationAccess
>::get()), UNO_QUERY
);
385 _xIntrospectionAccess
->queryAdapter(
386 cppu::UnoType
<XIndexAccess
>::get()), UNO_QUERY
);
388 if( _xIndexAccess
.is() )
391 _xIntrospectionAccess
->queryAdapter(
392 cppu::UnoType
<XIndexReplace
>::get()), UNO_QUERY
);
394 _xIndexContainer
.set(
395 _xIntrospectionAccess
->queryAdapter(
396 cppu::UnoType
<XIndexContainer
>::get()), UNO_QUERY
);
400 _xIntrospectionAccess
->queryAdapter(
401 cppu::UnoType
<XNameAccess
>::get()), UNO_QUERY
);
403 if( _xNameAccess
.is() )
406 _xIntrospectionAccess
->queryAdapter(
407 cppu::UnoType
<XNameReplace
>::get()), UNO_QUERY
);
410 _xIntrospectionAccess
->queryAdapter(
411 cppu::UnoType
<XNameContainer
>::get()), UNO_QUERY
);
415 _xPropertySet
.set( _xIntrospectionAccess
->queryAdapter( cppu::UnoType
<XPropertySet
>::get()),
418 _xENIntrospection
.set( _xIntrospectionAccess
, UNO_QUERY
);
422 _xDirect = XInvocationRef();
423 if( !_xIntrospectionAccess.is() )
426 _xElementAccess = XElementAccessRef();
427 _xEnumerationAccess = XEnumerationAccessRef();
428 _xIndexAccess = XIndexAccessRef();
429 _xIndexContainer = XIndexContainerRef();
430 _xNameAccess = XNameAccessRef();
431 _xNameContainer = XNameContainerRef();
432 _xPropertySet = XPropertySetRef();
439 OUString
Invocation_Impl::getExactName( const OUString
& rApproximateName
)
442 return _xENDirect
->getExactName( rApproximateName
);
445 if (_xENIntrospection
.is())
446 aRet
= _xENIntrospection
->getExactName( rApproximateName
);
451 Reference
<XIntrospectionAccess
> Invocation_Impl::getIntrospection()
454 return _xDirect
->getIntrospection();
456 return _xIntrospectionAccess
;
460 sal_Bool
Invocation_Impl::hasMethod( const OUString
& Name
)
463 return _xDirect
->hasMethod( Name
);
464 if( _xIntrospectionAccess
.is() )
465 return _xIntrospectionAccess
->hasMethod( Name
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
470 sal_Bool
Invocation_Impl::hasProperty( const OUString
& Name
)
473 return _xDirect
->hasProperty( Name
);
475 if( _xIntrospectionAccess
.is()
476 && _xIntrospectionAccess
->hasProperty( Name
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
479 if( _xNameAccess
.is() )
480 return _xNameAccess
->hasByName( Name
);
485 Any
Invocation_Impl::getValue( const OUString
& PropertyName
)
488 return _xDirect
->getValue( PropertyName
);
492 if( _xIntrospectionAccess
.is() && _xPropertySet
.is()
493 && _xIntrospectionAccess
->hasProperty
494 ( PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
496 return _xPropertySet
->getPropertyValue( PropertyName
);
499 if( _xNameAccess
.is() && _xNameAccess
->hasByName( PropertyName
) )
500 return _xNameAccess
->getByName( PropertyName
);
502 catch (UnknownPropertyException
&)
506 catch (RuntimeException
&)
514 throw UnknownPropertyException( "cannot get value " + PropertyName
);
518 void Invocation_Impl::setValue( const OUString
& PropertyName
, const Any
& Value
)
521 _xDirect
->setValue( PropertyName
, Value
);
527 if( _xIntrospectionAccess
.is() && _xPropertySet
.is()
528 && _xIntrospectionAccess
->hasProperty(
529 PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
531 Property aProp
= _xIntrospectionAccess
->getProperty(
532 PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
);
533 Reference
< XIdlClass
> r
= TypeToIdlClass( aProp
.Type
, xCoreReflection
);
534 if( r
->isAssignableFrom( TypeToIdlClass( Value
.getValueType(), xCoreReflection
) ) )
535 _xPropertySet
->setPropertyValue( PropertyName
, Value
);
536 else if( xTypeConverter
.is() )
537 _xPropertySet
->setPropertyValue(
538 PropertyName
, xTypeConverter
->convertTo( Value
, aProp
.Type
) );
540 throw RuntimeException( "no type converter service!" );
543 else if( _xNameContainer
.is() )
545 // Note: This misfeature deliberately not adapted to apply to objects which
546 // have XNameReplace but not XNameContainer
548 Reference
< XIdlClass
> r
=
549 TypeToIdlClass( _xNameContainer
->getElementType(), xCoreReflection
);
550 if( r
->isAssignableFrom(TypeToIdlClass( Value
.getValueType(), xCoreReflection
) ) )
552 else if( xTypeConverter
.is() )
553 aConv
= xTypeConverter
->convertTo( Value
, _xNameContainer
->getElementType() );
555 throw RuntimeException( "no type converter service!" );
557 // Replace if present, otherwise insert
558 if (_xNameContainer
->hasByName( PropertyName
))
559 _xNameContainer
->replaceByName( PropertyName
, aConv
);
561 _xNameContainer
->insertByName( PropertyName
, aConv
);
564 throw UnknownPropertyException( "no introspection nor name container!" );
566 catch (UnknownPropertyException
&)
570 catch (CannotConvertException
&)
574 catch (InvocationTargetException
&)
578 catch (RuntimeException
&)
582 catch (const Exception
& exc
)
584 throw InvocationTargetException(
585 "exception occurred in setValue(): " + exc
.Message
,
586 Reference
< XInterface
>(), makeAny( exc
/* though sliced */ ) );
592 Any
Invocation_Impl::invoke( const OUString
& FunctionName
, const Sequence
<Any
>& InParams
,
593 Sequence
<sal_Int16
>& OutIndices
, Sequence
<Any
>& OutParams
)
596 return _xDirect
->invoke( FunctionName
, InParams
, OutIndices
, OutParams
);
598 if (_xIntrospectionAccess
.is())
600 // throw NoSuchMethodException if not exist
601 Reference
<XIdlMethod
> xMethod
= _xIntrospectionAccess
->getMethod(
602 FunctionName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
605 Sequence
<ParamInfo
> aFParams
= xMethod
->getParameterInfos();
606 const ParamInfo
* pFParams
= aFParams
.getConstArray();
607 sal_Int32 nFParamsLen
= aFParams
.getLength();
608 if (nFParamsLen
!= InParams
.getLength())
610 throw IllegalArgumentException(
611 "incorrect number of parameters passed invoking function " + FunctionName
+
612 "expected " + OUString::number(nFParamsLen
) + ", got " + OUString::number(InParams
.getLength()),
613 static_cast<OWeakObject
*>(this), (sal_Int16
) 1 );
617 const Any
* pInParams
= InParams
.getConstArray();
619 // Introspection Invoke Parameter
620 Sequence
<Any
> aInvokeParams( nFParamsLen
);
621 Any
* pInvokeParams
= aInvokeParams
.getArray();
624 OutIndices
.realloc( nFParamsLen
);
625 sal_Int16
* pOutIndices
= OutIndices
.getArray();
626 sal_uInt32 nOutIndex
= 0;
628 for ( sal_Int32 nPos
= 0; nPos
< nFParamsLen
; ++nPos
)
632 const ParamInfo
& rFParam
= pFParams
[nPos
];
633 const Reference
<XIdlClass
>& rDestType
= rFParam
.aType
;
635 // is IN/INOUT parameter?
636 if (rFParam
.aMode
!= ParamMode_OUT
)
638 if (rDestType
->isAssignableFrom( TypeToIdlClass( pInParams
[nPos
].getValueType(), xCoreReflection
) ))
640 pInvokeParams
[nPos
] = pInParams
[nPos
];
642 else if (xTypeConverter
.is())
644 Type
aDestType( rDestType
->getTypeClass(), rDestType
->getName() );
645 pInvokeParams
[nPos
] = xTypeConverter
->convertTo( pInParams
[nPos
], aDestType
);
649 CannotConvertException aExc
;
650 aExc
.Context
= *this;
651 aExc
.Message
= "invocation type mismatch!";
656 // is OUT/INOUT parameter?
657 if (rFParam
.aMode
!= ParamMode_IN
)
659 pOutIndices
[nOutIndex
] = (sal_Int16
)nPos
;
660 if (rFParam
.aMode
== ParamMode_OUT
)
661 rDestType
->createObject( pInvokeParams
[nPos
] ); // default init
665 catch( CannotConvertException
& rExc
)
667 rExc
.ArgumentIndex
= nPos
; // Add optional parameter index
673 Any aRet
= xMethod
->invoke( _aMaterial
, aInvokeParams
);
676 OutIndices
.realloc( nOutIndex
);
677 pOutIndices
= OutIndices
.getArray();
678 OutParams
.realloc( nOutIndex
);
679 Any
* pOutParams
= OutParams
.getArray();
683 pOutParams
[nOutIndex
] = pInvokeParams
[ pOutIndices
[nOutIndex
] ];
689 RuntimeException aExc
;
690 aExc
.Context
= *this;
691 aExc
.Message
= "invocation lacking of introspection access!";
696 // Struct to optimize sorting
701 // Defines where the member comes from
702 enum Mode
{ NAMEACCESS
, PROPERTYSET
, METHOD
} eMode
;
704 // Index to respective sequence
705 // (Index to NameAccess sequence for eMode==NAMEACCESS etc.)
709 // Implementation of getting name or info
710 // String sequence will be filled when pStringSeq != NULL
711 // Info sequence will be filled when pInfoSeq != NULL
712 void Invocation_Impl::getInfoSequenceImpl
714 Sequence
< OUString
>* pStringSeq
,
715 Sequence
< InvocationInfo
>* pInfoSeq
718 //Sequence< OUString > aStrSeq;
720 //pStringSeq = &aStrSeq;
723 // Get all needed sequences
724 Sequence
<OUString
> aNameAccessNames
;
725 Sequence
<Property
> aPropertySeq
;
726 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
;
728 if( _xNameAccess
.is() )
730 aNameAccessNames
= _xNameAccess
->getElementNames();
733 if( _xIntrospectionAccess
.is() )
735 aPropertySeq
= _xIntrospectionAccess
->getProperties
736 ( PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
738 aMethodSeq
= _xIntrospectionAccess
->getMethods
739 ( MethodConcept::ALL
- MethodConcept::DANGEROUS
);
742 sal_Int32 nNameAccessCount
= aNameAccessNames
.getLength();
743 sal_Int32 nPropertyCount
= aPropertySeq
.getLength();
744 sal_Int32 nMethodCount
= aMethodSeq
.getLength();
745 sal_Int32 nTotalCount
= nNameAccessCount
+ nPropertyCount
+ nMethodCount
;
747 // Create and fill array of MemberItems
748 std::unique_ptr
< MemberItem
[]> pItems( new MemberItem
[ nTotalCount
] );
749 const OUString
* pStrings
= aNameAccessNames
.getConstArray();
750 const Property
* pProps
= aPropertySeq
.getConstArray();
751 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
753 // Fill array of MemberItems
754 sal_Int32 i
, iTotal
= 0;
757 for( i
= 0 ; i
< nNameAccessCount
; i
++, iTotal
++ )
759 MemberItem
& rItem
= pItems
[ iTotal
];
760 rItem
.aName
= pStrings
[ i
];
761 rItem
.eMode
= MemberItem::NAMEACCESS
;
766 for( i
= 0 ; i
< nPropertyCount
; i
++, iTotal
++ )
768 MemberItem
& rItem
= pItems
[ iTotal
];
769 rItem
.aName
= pProps
[ i
].Name
;
770 rItem
.eMode
= MemberItem::PROPERTYSET
;
775 for( i
= 0 ; i
< nMethodCount
; i
++, iTotal
++ )
777 MemberItem
& rItem
= pItems
[ iTotal
];
778 Reference
< XIdlMethod
> xMethod
= pMethods
[ i
];
779 rItem
.aName
= xMethod
->getName();
780 rItem
.eMode
= MemberItem::METHOD
;
784 // Setting up result sequences
785 OUString
* pRetStrings
= nullptr;
788 pStringSeq
->realloc( nTotalCount
);
789 pRetStrings
= pStringSeq
->getArray();
792 InvocationInfo
* pRetInfos
= nullptr;
795 pInfoSeq
->realloc( nTotalCount
);
796 pRetInfos
= pInfoSeq
->getArray();
799 // Fill result sequences in the correct order of members
800 for( iTotal
= 0 ; iTotal
< nTotalCount
; iTotal
++ )
802 MemberItem
& rItem
= pItems
[ iTotal
];
805 pRetStrings
[ iTotal
] = rItem
.aName
;
810 if( rItem
.eMode
== MemberItem::NAMEACCESS
)
812 fillInfoForNameAccess( pRetInfos
[ iTotal
], rItem
.aName
);
814 else if( rItem
.eMode
== MemberItem::PROPERTYSET
)
816 fillInfoForProperty( pRetInfos
[ iTotal
], pProps
[ rItem
.nIndex
] );
818 else if( rItem
.eMode
== MemberItem::METHOD
)
820 fillInfoForMethod( pRetInfos
[ iTotal
], pMethods
[ rItem
.nIndex
] );
827 Sequence
< OUString
> SAL_CALL
Invocation_Impl::getMemberNames( )
831 return _xDirect2
->getMemberNames();
833 Sequence
< OUString
> aRetSeq
;
834 getInfoSequenceImpl( &aRetSeq
, nullptr );
838 Sequence
< InvocationInfo
> SAL_CALL
Invocation_Impl::getInfo( )
842 return _xDirect2
->getInfo();
844 Sequence
< InvocationInfo
> aRetSeq
;
845 getInfoSequenceImpl( nullptr, &aRetSeq
);
849 InvocationInfo SAL_CALL
Invocation_Impl::getInfoForName( const OUString
& aName
, sal_Bool bExact
)
853 return _xDirect2
->getInfoForName( aName
, bExact
);
857 OUString aExactName
= aName
;
858 InvocationInfo aRetInfo
;
861 aExactName
= getExactName( aName
);
862 if( !aExactName
.isEmpty() )
864 if( _xIntrospectionAccess
->hasMethod( aExactName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
) )
866 Reference
<XIdlMethod
> xMethod
= _xIntrospectionAccess
->getMethod
867 ( aExactName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
868 fillInfoForMethod( aRetInfo
, xMethod
);
873 if( _xIntrospectionAccess
.is() && _xIntrospectionAccess
->hasProperty
874 ( aExactName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
876 Property aProp
= _xIntrospectionAccess
->getProperty
877 ( aExactName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
);
878 fillInfoForProperty( aRetInfo
, aProp
);
882 else if( _xNameAccess
.is() && _xNameAccess
->hasByName( aExactName
) )
884 fillInfoForNameAccess( aRetInfo
, aExactName
);
891 throw IllegalArgumentException(
892 "getExactName(), Unknown name " + aName
,
893 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
898 // Helper functions to fill InvocationInfo for XNameAccess
899 void Invocation_Impl::fillInfoForNameAccess
901 InvocationInfo
& rInfo
,
902 const OUString
& aName
906 rInfo
.eMemberType
= MemberType_PROPERTY
;
907 rInfo
.PropertyAttribute
= 0;
908 if( !_xNameContainer
.is() )
910 rInfo
.PropertyAttribute
= PropertyAttribute::READONLY
;
912 rInfo
.aType
= _xNameAccess
->getElementType();
915 void Invocation_Impl::fillInfoForProperty
917 InvocationInfo
& rInfo
,
918 const Property
& rProp
921 rInfo
.aName
= rProp
.Name
;
922 rInfo
.eMemberType
= MemberType_PROPERTY
;
923 rInfo
.PropertyAttribute
= rProp
.Attributes
;
924 rInfo
.aType
= rProp
.Type
;
927 void Invocation_Impl::fillInfoForMethod
929 InvocationInfo
& rInfo
,
930 const Reference
< XIdlMethod
>& xMethod
933 rInfo
.aName
= xMethod
->getName();
934 rInfo
.eMemberType
= MemberType_METHOD
;
935 Reference
< XIdlClass
> xReturnClass
= xMethod
->getReturnType();
936 Type
aReturnType( xReturnClass
->getTypeClass(), xReturnClass
->getName() );
937 rInfo
.aType
= aReturnType
;
938 Sequence
<ParamInfo
> aParamInfos
= xMethod
->getParameterInfos();
939 sal_Int32 nParamCount
= aParamInfos
.getLength();
940 if( nParamCount
> 0 )
942 const ParamInfo
* pInfo
= aParamInfos
.getConstArray();
944 rInfo
.aParamTypes
.realloc( nParamCount
);
945 Type
* pParamTypes
= rInfo
.aParamTypes
.getArray();
946 rInfo
.aParamModes
.realloc( nParamCount
);
947 ParamMode
* pParamModes
= rInfo
.aParamModes
.getArray();
949 for( sal_Int32 i
= 0 ; i
< nParamCount
; i
++ )
951 Reference
< XIdlClass
> xParamClass
= pInfo
[i
].aType
;
952 Type
aParamType( xParamClass
->getTypeClass(), xParamClass
->getName() );
953 pParamTypes
[ i
] = aParamType
;
954 pParamModes
[ i
] = pInfo
[i
].aMode
;
961 Sequence
< Type
> SAL_CALL
Invocation_Impl::getTypes()
963 static Sequence
< Type
> const * s_pTypes
= nullptr;
966 Sequence
< Type
> types( 4 + 10 );
967 Type
* pTypes
= types
.getArray();
970 pTypes
[ n
++ ] = cppu::UnoType
<XTypeProvider
>::get();
971 pTypes
[ n
++ ] = cppu::UnoType
<XWeak
>::get();
972 pTypes
[ n
++ ] = cppu::UnoType
<XInvocation
>::get();
973 pTypes
[ n
++ ] = cppu::UnoType
<XMaterialHolder
>::get();
975 // Invocation does not support XExactName if direct object supports
976 // XInvocation, but not XExactName.
977 if ((_xDirect
.is() && _xENDirect
.is()) ||
978 (!_xDirect
.is() && _xENIntrospection
.is()))
980 pTypes
[ n
++ ] = cppu::UnoType
<XExactName
>::get();
982 if( _xNameContainer
.is() )
984 pTypes
[ n
++ ] = cppu::UnoType
<XNameContainer
>::get();
986 if( _xNameReplace
.is() )
988 pTypes
[ n
++ ] = cppu::UnoType
<XNameReplace
>::get();
990 if( _xNameAccess
.is() )
992 pTypes
[ n
++ ] = cppu::UnoType
<XNameAccess
>::get();
994 if (_xIndexContainer
.is())
996 pTypes
[ n
++ ] = cppu::UnoType
<XIndexContainer
>::get();
998 if (_xIndexReplace
.is())
1000 pTypes
[ n
++ ] = cppu::UnoType
<XIndexReplace
>::get();
1002 if (_xIndexAccess
.is())
1004 pTypes
[ n
++ ] = cppu::UnoType
<XIndexAccess
>::get();
1006 if (_xEnumerationAccess
.is())
1008 pTypes
[ n
++ ] = cppu::UnoType
<XEnumerationAccess
>::get();
1010 if (_xElementAccess
.is())
1012 pTypes
[ n
++ ] = cppu::UnoType
<XElementAccess
>::get();
1014 // Invocation does not support XInvocation2, if direct object supports
1015 // XInvocation, but not XInvocation2.
1016 if ( ( _xDirect
.is() && _xDirect2
.is()) ||
1017 (!_xDirect
.is() && _xIntrospectionAccess
.is() ) )
1019 pTypes
[ n
++ ] = cppu::UnoType
<XInvocation2
>::get();
1025 MutexGuard
guard( Mutex::getGlobalMutex() );
1028 static Sequence
< Type
> s_types( types
);
1029 s_pTypes
= &s_types
;
1035 Sequence
< sal_Int8
> SAL_CALL
Invocation_Impl::getImplementationId( )
1037 return css::uno::Sequence
<sal_Int8
>();
1041 class InvocationService
1042 : public WeakImplHelper
< XSingleServiceFactory
, XServiceInfo
>
1045 explicit InvocationService( const Reference
<XComponentContext
> & xCtx
);
1048 OUString SAL_CALL
getImplementationName() override
;
1049 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) override
;
1050 Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
1052 // XSingleServiceFactory
1053 Reference
<XInterface
> SAL_CALL
createInstance() override
;
1054 Reference
<XInterface
> SAL_CALL
createInstanceWithArguments(
1055 const Sequence
<Any
>& rArguments
) override
;
1057 Reference
<XComponentContext
> mxCtx
;
1058 Reference
<XMultiComponentFactory
> mxSMgr
;
1059 Reference
<XTypeConverter
> xTypeConverter
;
1060 Reference
<XIntrospection
> xIntrospection
;
1061 Reference
<XIdlReflection
> xCoreReflection
;
1064 InvocationService::InvocationService( const Reference
<XComponentContext
> & xCtx
)
1066 , mxSMgr( xCtx
->getServiceManager() )
1067 , xCoreReflection( css::reflection::theCoreReflection::get(mxCtx
) )
1070 mxSMgr
->createInstanceWithContext( "com.sun.star.script.Converter", xCtx
),
1072 xIntrospection
= theIntrospection::get(xCtx
);
1076 OUString
InvocationService::getImplementationName()
1078 return inv_getImplementationName();
1082 sal_Bool
InvocationService::supportsService(const OUString
& ServiceName
)
1084 return cppu::supportsService(this, ServiceName
);
1088 Sequence
< OUString
> InvocationService::getSupportedServiceNames()
1090 return inv_getSupportedServiceNames();
1094 Reference
<XInterface
> InvocationService::createInstance()
1096 //TODO:throw( Exception("no default construction of invocation adapter possible!", *this) );
1097 return Reference
<XInterface
>(); // dummy
1101 Reference
<XInterface
> InvocationService::createInstanceWithArguments(
1102 const Sequence
<Any
>& rArguments
)
1104 if (rArguments
.getLength() == 1)
1106 return Reference
< XInterface
>
1107 ( *new Invocation_Impl( *rArguments
.getConstArray(),
1108 xTypeConverter
, xIntrospection
, xCoreReflection
) );
1112 //TODO:throw( Exception("no default construction of invocation adapter possible!", *this) );
1113 return Reference
<XInterface
>();
1117 /// @throws RuntimeException
1118 Reference
<XInterface
> SAL_CALL
InvocationService_CreateInstance( const Reference
<XComponentContext
> & xCtx
)
1120 Reference
<XInterface
> xService( *new InvocationService( xCtx
) );
1126 using namespace stoc_inv
;
1127 static const struct ImplementationEntry g_entries
[] =
1130 InvocationService_CreateInstance
, inv_getImplementationName
,
1131 inv_getSupportedServiceNames
, createSingleComponentFactory
,
1134 { nullptr, nullptr, nullptr, nullptr, nullptr, 0 }
1137 extern "C" SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
invocation_component_getFactory(
1138 const sal_Char
* pImplName
, void * pServiceManager
, void * pRegistryKey
)
1140 return component_getFactoryHelper( pImplName
, pServiceManager
, pRegistryKey
, g_entries
);
1143 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */