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/XTypeConverter.hpp>
31 #include <com/sun/star/script/XInvocation.hpp>
32 #include <com/sun/star/script/XInvocation2.hpp>
33 #include <com/sun/star/reflection/XIdlReflection.hpp>
34 #include <com/sun/star/reflection/theCoreReflection.hpp>
35 #include <com/sun/star/container/XNameContainer.hpp>
36 #include <com/sun/star/container/XIndexContainer.hpp>
37 #include <com/sun/star/container/XEnumerationAccess.hpp>
38 #include <com/sun/star/beans/XExactName.hpp>
39 #include <com/sun/star/beans/XMaterialHolder.hpp>
40 #include <com/sun/star/beans/theIntrospection.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/beans/PropertyAttribute.hpp>
43 #include <com/sun/star/beans/MethodConcept.hpp>
44 #include <com/sun/star/beans/PropertyConcept.hpp>
45 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/lang/XServiceInfo.hpp>
48 #include <com/sun/star/lang/XTypeProvider.hpp>
49 #include <com/sun/star/registry/XRegistryKey.hpp>
52 #include <rtl/ustrbuf.hxx>
53 #include <rtl/strbuf.hxx>
55 #define SERVICENAME "com.sun.star.script.Invocation"
56 #define IMPLNAME "com.sun.star.comp.stoc.Invocation"
58 using namespace css::uno
;
59 using namespace css::lang
;
60 using namespace css::script
;
61 using namespace css::reflection
;
62 using namespace css::beans
;
63 using namespace css::registry
;
64 using namespace css::container
;
70 static Sequence
< OUString
> inv_getSupportedServiceNames()
72 Sequence
< OUString
> seqNames
{ SERVICENAME
};
76 static OUString
inv_getImplementationName()
78 return OUString(IMPLNAME
);
81 // TODO: Implement centrally
82 inline Reference
<XIdlClass
> TypeToIdlClass( const Type
& rType
, const Reference
< XIdlReflection
> & xRefl
)
84 return xRefl
->forName( rType
.getTypeName() );
91 , public XNameContainer
92 , public XIndexContainer
93 , public XEnumerationAccess
95 , public XMaterialHolder
96 , public XTypeProvider
99 Invocation_Impl( const Any
& rAdapted
, const Reference
<XTypeConverter
> &,
100 const Reference
<XIntrospection
> &,
101 const Reference
<XIdlReflection
> & );
104 virtual Any SAL_CALL
queryInterface( const Type
& aType
) override
;
105 virtual void SAL_CALL
acquire() throw() override
{ OWeakObject::acquire(); }
106 virtual void SAL_CALL
release() throw() override
{ OWeakObject::release(); }
110 virtual Sequence
< css::uno::Type
> SAL_CALL
getTypes( ) override
;
111 virtual Sequence
< sal_Int8
> SAL_CALL
getImplementationId( ) override
;
114 virtual Any SAL_CALL
getMaterial() override
;
117 virtual Reference
<XIntrospectionAccess
> SAL_CALL
getIntrospection() override
;
118 virtual Any SAL_CALL
invoke(const OUString
& FunctionName
, const Sequence
< Any
>& Params
, Sequence
< sal_Int16
>& OutParamIndex
, Sequence
< Any
>& OutParam
) override
;
119 virtual void SAL_CALL
setValue(const OUString
& PropertyName
, const Any
& Value
) override
;
120 virtual Any SAL_CALL
getValue(const OUString
& PropertyName
) override
;
121 virtual sal_Bool SAL_CALL
hasMethod(const OUString
& Name
) override
;
122 virtual sal_Bool SAL_CALL
hasProperty(const OUString
& Name
) override
;
125 virtual Sequence
< OUString
> SAL_CALL
getMemberNames( ) override
;
126 virtual Sequence
< InvocationInfo
> SAL_CALL
getInfo( ) override
;
127 virtual InvocationInfo SAL_CALL
getInfoForName( const OUString
& aName
, sal_Bool bExact
) override
;
129 // All Access and Container methods are not thread safe
131 virtual Type SAL_CALL
getElementType() override
132 { return _xElementAccess
->getElementType(); }
134 virtual sal_Bool SAL_CALL
hasElements() override
135 { return _xElementAccess
->hasElements(); }
138 virtual void SAL_CALL
insertByName( const OUString
& Name
, const Any
& Element
) override
139 { _xNameContainer
->insertByName( Name
, Element
); }
141 virtual void SAL_CALL
removeByName( const OUString
& Name
) override
142 { _xNameContainer
->removeByName( Name
); }
145 virtual void SAL_CALL
replaceByName( const OUString
& Name
, const Any
& Element
) override
146 { _xNameReplace
->replaceByName( Name
, Element
); }
149 virtual Any SAL_CALL
getByName( const OUString
& Name
) override
150 { return _xNameAccess
->getByName( Name
); }
152 virtual Sequence
<OUString
> SAL_CALL
getElementNames() override
153 { return _xNameAccess
->getElementNames(); }
155 virtual sal_Bool SAL_CALL
hasByName( const OUString
& Name
) override
156 { return _xNameAccess
->hasByName( Name
); }
159 virtual void SAL_CALL
insertByIndex( sal_Int32 Index
, const Any
& Element
) override
160 { _xIndexContainer
->insertByIndex( Index
, Element
); }
162 virtual void SAL_CALL
removeByIndex( sal_Int32 Index
) override
163 { _xIndexContainer
->removeByIndex( Index
); }
166 virtual void SAL_CALL
replaceByIndex( sal_Int32 Index
, const Any
& Element
) override
167 { _xIndexReplace
->replaceByIndex( Index
, Element
); }
170 virtual sal_Int32 SAL_CALL
getCount() override
171 { return _xIndexAccess
->getCount(); }
173 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
) override
174 { return _xIndexAccess
->getByIndex( Index
); }
176 // XEnumerationAccess
177 virtual Reference
<XEnumeration
> SAL_CALL
createEnumeration() override
178 { return _xEnumerationAccess
->createEnumeration(); }
181 virtual OUString SAL_CALL
getExactName( const OUString
& rApproximateName
) override
;
185 void setMaterial( const Any
& rMaterial
);
187 void getInfoSequenceImpl( Sequence
< OUString
>* pStringSeq
, Sequence
< InvocationInfo
>* pInfoSeq
);
188 void fillInfoForNameAccess( InvocationInfo
& rInfo
, const OUString
& aName
);
189 static void fillInfoForProperty( InvocationInfo
& rInfo
, const Property
& rProp
);
190 static void fillInfoForMethod( InvocationInfo
& rInfo
, const Reference
< XIdlMethod
>& xMethod
);
192 Reference
<XTypeConverter
> xTypeConverter
;
193 Reference
<XIntrospection
> xIntrospection
;
194 Reference
<XIdlReflection
> xCoreReflection
;
197 // _xDirect and (_xIntrospectionAccess, xPropertySet) are exclusive
198 Reference
<XInvocation
> _xDirect
;
199 Reference
<XInvocation2
> _xDirect2
;
200 Reference
<XPropertySet
> _xPropertySet
;
201 Reference
<XIntrospectionAccess
> _xIntrospectionAccess
;
203 // supplied Interfaces
204 Reference
<XNameContainer
> _xNameContainer
;
205 Reference
<XNameReplace
> _xNameReplace
;
206 Reference
<XNameAccess
> _xNameAccess
;
207 Reference
<XIndexContainer
> _xIndexContainer
;
208 Reference
<XIndexReplace
> _xIndexReplace
;
209 Reference
<XIndexAccess
> _xIndexAccess
;
210 Reference
<XEnumerationAccess
> _xEnumerationAccess
;
211 Reference
<XElementAccess
> _xElementAccess
;
214 Reference
<XExactName
> _xENDirect
, _xENIntrospection
;
218 Invocation_Impl::Invocation_Impl
220 const Any
& rAdapted
,
221 const Reference
<XTypeConverter
> & rTC
,
222 const Reference
<XIntrospection
> & rI
,
223 const Reference
<XIdlReflection
> & rCR
225 : xTypeConverter( rTC
)
226 , xIntrospection( rI
)
227 , xCoreReflection( rCR
)
229 setMaterial( rAdapted
);
232 //### INTERFACE IMPLEMENTATIONS ####################################################################
235 Any SAL_CALL
Invocation_Impl::queryInterface( const Type
& aType
)
237 // PropertySet implementation
238 Any a
= ::cppu::queryInterface( aType
,
239 static_cast< XInvocation
* >(this),
240 static_cast< XMaterialHolder
* >(this),
241 static_cast< XTypeProvider
* >(this) );
247 if( aType
== cppu::UnoType
<XExactName
>::get())
249 // Invocation does not support XExactName, if direct object supports
250 // XInvocation, but not XExactName.
251 if ((_xDirect
.is() && _xENDirect
.is()) ||
252 (!_xDirect
.is() && _xENIntrospection
.is()))
254 return makeAny( Reference
< XExactName
>( static_cast< XExactName
* >(this) ) );
257 else if ( aType
== cppu::UnoType
<XNameContainer
>::get())
259 if( _xNameContainer
.is() )
260 return makeAny( Reference
< XNameContainer
>( static_cast< XNameContainer
* >(this) ) );
262 else if ( aType
== cppu::UnoType
<XNameReplace
>::get())
264 if( _xNameReplace
.is() )
265 return makeAny( Reference
< XNameReplace
>( static_cast< XNameReplace
* >(this) ) );
267 else if ( aType
== cppu::UnoType
<XNameAccess
>::get())
269 if( _xNameAccess
.is() )
270 return makeAny( Reference
< XNameAccess
>( static_cast< XNameAccess
* >(this) ) );
272 else if ( aType
== cppu::UnoType
<XIndexContainer
>::get())
274 if (_xIndexContainer
.is())
275 return makeAny( Reference
< XIndexContainer
>( static_cast< XIndexContainer
* >(this) ) );
277 else if ( aType
== cppu::UnoType
<XIndexReplace
>::get())
279 if (_xIndexReplace
.is())
280 return makeAny( Reference
< XIndexReplace
>( static_cast< XIndexReplace
* >(this) ) );
282 else if ( aType
== cppu::UnoType
<XIndexAccess
>::get())
284 if (_xIndexAccess
.is())
285 return makeAny( Reference
< XIndexAccess
>( static_cast< XIndexAccess
* >(this) ) );
287 else if ( aType
== cppu::UnoType
<XEnumerationAccess
>::get())
289 if (_xEnumerationAccess
.is())
290 return makeAny( Reference
< XEnumerationAccess
>( static_cast< XEnumerationAccess
* >(this) ) );
292 else if ( aType
== cppu::UnoType
<XElementAccess
>::get())
294 if (_xElementAccess
.is())
296 return makeAny( Reference
< XElementAccess
>(
297 static_cast< XElementAccess
* >(static_cast< XNameContainer
* >(this)) ) );
300 else if ( aType
== cppu::UnoType
<XInvocation2
>::get())
302 // Invocation does not support XInvocation2, if direct object supports
303 // XInvocation, but not XInvocation2.
304 if ( ( _xDirect
.is() && _xDirect2
.is()) ||
305 (!_xDirect
.is() && _xIntrospectionAccess
.is() ) )
307 return makeAny( Reference
< XInvocation2
>( static_cast< XInvocation2
* >(this) ) );
311 return OWeakObject::queryInterface( aType
);
315 Any
Invocation_Impl::getMaterial()
317 // AB, 12.2.1999 Make sure that the material is taken when possible
318 // from the direct Invocation of the Introspection, otherwise structs
319 // are not handled correctly
320 Reference
<XMaterialHolder
> xMaterialHolder
;
323 xMaterialHolder
.set( _xDirect
, UNO_QUERY
);
324 //_xDirect->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
326 else if( _xIntrospectionAccess
.is() )
328 xMaterialHolder
.set( _xIntrospectionAccess
, UNO_QUERY
);
329 //_xIntrospectionAccess->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
331 if( xMaterialHolder
.is() )
333 return xMaterialHolder
->getMaterial();
339 void Invocation_Impl::setMaterial( const Any
& rMaterial
)
341 // set the material first and only once
342 _aMaterial
= rMaterial
;
344 // First do this outside the guard
345 _xDirect
.set( rMaterial
, UNO_QUERY
);
349 // Consult object directly
350 _xElementAccess
.set( _xDirect
, UNO_QUERY
);
351 _xEnumerationAccess
.set( _xDirect
, UNO_QUERY
);
352 _xIndexAccess
.set( _xDirect
, UNO_QUERY
);
353 _xIndexReplace
.set( _xDirect
, UNO_QUERY
);
354 _xIndexContainer
.set( _xDirect
, UNO_QUERY
);
355 _xNameAccess
.set( _xDirect
, UNO_QUERY
);
356 _xNameReplace
.set( _xDirect
, UNO_QUERY
);
357 _xNameContainer
.set( _xDirect
, UNO_QUERY
);
358 _xENDirect
.set( _xDirect
, UNO_QUERY
);
359 _xDirect2
.set( _xDirect
, UNO_QUERY
);
363 // Make Invocation on the Introspection
364 if (xIntrospection
.is())
366 _xIntrospectionAccess
= xIntrospection
->inspect( _aMaterial
);
367 if( _xIntrospectionAccess
.is() )
370 _xIntrospectionAccess
->queryAdapter(
371 cppu::UnoType
<XElementAccess
>::get()), UNO_QUERY
);
373 if( _xElementAccess
.is() )
375 _xEnumerationAccess
.set(
376 _xIntrospectionAccess
->queryAdapter(
377 cppu::UnoType
<XEnumerationAccess
>::get()), UNO_QUERY
);
380 _xIntrospectionAccess
->queryAdapter(
381 cppu::UnoType
<XIndexAccess
>::get()), UNO_QUERY
);
383 if( _xIndexAccess
.is() )
386 _xIntrospectionAccess
->queryAdapter(
387 cppu::UnoType
<XIndexReplace
>::get()), UNO_QUERY
);
389 _xIndexContainer
.set(
390 _xIntrospectionAccess
->queryAdapter(
391 cppu::UnoType
<XIndexContainer
>::get()), UNO_QUERY
);
395 _xIntrospectionAccess
->queryAdapter(
396 cppu::UnoType
<XNameAccess
>::get()), UNO_QUERY
);
398 if( _xNameAccess
.is() )
401 _xIntrospectionAccess
->queryAdapter(
402 cppu::UnoType
<XNameReplace
>::get()), UNO_QUERY
);
405 _xIntrospectionAccess
->queryAdapter(
406 cppu::UnoType
<XNameContainer
>::get()), UNO_QUERY
);
410 _xPropertySet
.set( _xIntrospectionAccess
->queryAdapter( cppu::UnoType
<XPropertySet
>::get()),
413 _xENIntrospection
.set( _xIntrospectionAccess
, UNO_QUERY
);
420 OUString
Invocation_Impl::getExactName( const OUString
& rApproximateName
)
423 return _xENDirect
->getExactName( rApproximateName
);
426 if (_xENIntrospection
.is())
427 aRet
= _xENIntrospection
->getExactName( rApproximateName
);
432 Reference
<XIntrospectionAccess
> Invocation_Impl::getIntrospection()
435 return _xDirect
->getIntrospection();
437 return _xIntrospectionAccess
;
441 sal_Bool
Invocation_Impl::hasMethod( const OUString
& Name
)
444 return _xDirect
->hasMethod( Name
);
445 if( _xIntrospectionAccess
.is() )
446 return _xIntrospectionAccess
->hasMethod( Name
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
451 sal_Bool
Invocation_Impl::hasProperty( const OUString
& Name
)
454 return _xDirect
->hasProperty( Name
);
456 if( _xIntrospectionAccess
.is()
457 && _xIntrospectionAccess
->hasProperty( Name
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
460 if( _xNameAccess
.is() )
461 return _xNameAccess
->hasByName( Name
);
466 Any
Invocation_Impl::getValue( const OUString
& PropertyName
)
469 return _xDirect
->getValue( PropertyName
);
473 if( _xIntrospectionAccess
.is() && _xPropertySet
.is()
474 && _xIntrospectionAccess
->hasProperty
475 ( PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
477 return _xPropertySet
->getPropertyValue( PropertyName
);
480 if( _xNameAccess
.is() && _xNameAccess
->hasByName( PropertyName
) )
481 return _xNameAccess
->getByName( PropertyName
);
483 catch (UnknownPropertyException
&)
487 catch (RuntimeException
&)
495 throw UnknownPropertyException( "cannot get value " + PropertyName
);
499 void Invocation_Impl::setValue( const OUString
& PropertyName
, const Any
& Value
)
502 _xDirect
->setValue( PropertyName
, Value
);
508 if( _xIntrospectionAccess
.is() && _xPropertySet
.is()
509 && _xIntrospectionAccess
->hasProperty(
510 PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
512 Property aProp
= _xIntrospectionAccess
->getProperty(
513 PropertyName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
);
514 Reference
< XIdlClass
> r
= TypeToIdlClass( aProp
.Type
, xCoreReflection
);
515 if( r
->isAssignableFrom( TypeToIdlClass( Value
.getValueType(), xCoreReflection
) ) )
516 _xPropertySet
->setPropertyValue( PropertyName
, Value
);
517 else if( xTypeConverter
.is() )
518 _xPropertySet
->setPropertyValue(
519 PropertyName
, xTypeConverter
->convertTo( Value
, aProp
.Type
) );
521 throw RuntimeException( "no type converter service!" );
524 else if( _xNameContainer
.is() )
526 // Note: This misfeature deliberately not adapted to apply to objects which
527 // have XNameReplace but not XNameContainer
529 Reference
< XIdlClass
> r
=
530 TypeToIdlClass( _xNameContainer
->getElementType(), xCoreReflection
);
531 if( r
->isAssignableFrom(TypeToIdlClass( Value
.getValueType(), xCoreReflection
) ) )
533 else if( xTypeConverter
.is() )
534 aConv
= xTypeConverter
->convertTo( Value
, _xNameContainer
->getElementType() );
536 throw RuntimeException( "no type converter service!" );
538 // Replace if present, otherwise insert
539 if (_xNameContainer
->hasByName( PropertyName
))
540 _xNameContainer
->replaceByName( PropertyName
, aConv
);
542 _xNameContainer
->insertByName( PropertyName
, aConv
);
545 throw UnknownPropertyException( "no introspection nor name container!" );
547 catch (UnknownPropertyException
&)
551 catch (CannotConvertException
&)
555 catch (InvocationTargetException
&)
559 catch (RuntimeException
&)
563 catch (const Exception
& exc
)
565 throw InvocationTargetException(
566 "exception occurred in setValue(): " + exc
.Message
,
567 Reference
< XInterface
>(), makeAny( exc
/* though sliced */ ) );
573 Any
Invocation_Impl::invoke( const OUString
& FunctionName
, const Sequence
<Any
>& InParams
,
574 Sequence
<sal_Int16
>& OutIndices
, Sequence
<Any
>& OutParams
)
577 return _xDirect
->invoke( FunctionName
, InParams
, OutIndices
, OutParams
);
579 if (_xIntrospectionAccess
.is())
581 // throw NoSuchMethodException if not exist
582 Reference
<XIdlMethod
> xMethod
= _xIntrospectionAccess
->getMethod(
583 FunctionName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
586 Sequence
<ParamInfo
> aFParams
= xMethod
->getParameterInfos();
587 const ParamInfo
* pFParams
= aFParams
.getConstArray();
588 sal_Int32 nFParamsLen
= aFParams
.getLength();
589 if (nFParamsLen
!= InParams
.getLength())
591 throw IllegalArgumentException(
592 "incorrect number of parameters passed invoking function " + FunctionName
+
593 ": expected " + OUString::number(nFParamsLen
) + ", got " + OUString::number(InParams
.getLength()),
594 static_cast<OWeakObject
*>(this), sal_Int16(1) );
598 const Any
* pInParams
= InParams
.getConstArray();
600 // Introspection Invoke Parameter
601 Sequence
<Any
> aInvokeParams( nFParamsLen
);
602 Any
* pInvokeParams
= aInvokeParams
.getArray();
605 OutIndices
.realloc( nFParamsLen
);
606 sal_Int16
* pOutIndices
= OutIndices
.getArray();
607 sal_uInt32 nOutIndex
= 0;
609 for ( sal_Int32 nPos
= 0; nPos
< nFParamsLen
; ++nPos
)
613 const ParamInfo
& rFParam
= pFParams
[nPos
];
614 const Reference
<XIdlClass
>& rDestType
= rFParam
.aType
;
616 // is IN/INOUT parameter?
617 if (rFParam
.aMode
!= ParamMode_OUT
)
619 if (rDestType
->isAssignableFrom( TypeToIdlClass( pInParams
[nPos
].getValueType(), xCoreReflection
) ))
621 pInvokeParams
[nPos
] = pInParams
[nPos
];
623 else if (xTypeConverter
.is())
625 Type
aDestType( rDestType
->getTypeClass(), rDestType
->getName() );
626 pInvokeParams
[nPos
] = xTypeConverter
->convertTo( pInParams
[nPos
], aDestType
);
630 CannotConvertException aExc
;
631 aExc
.Context
= *this;
632 aExc
.Message
= "invocation type mismatch!";
637 // is OUT/INOUT parameter?
638 if (rFParam
.aMode
!= ParamMode_IN
)
640 pOutIndices
[nOutIndex
] = static_cast<sal_Int16
>(nPos
);
641 if (rFParam
.aMode
== ParamMode_OUT
)
642 rDestType
->createObject( pInvokeParams
[nPos
] ); // default init
646 catch( CannotConvertException
& rExc
)
648 rExc
.ArgumentIndex
= nPos
; // Add optional parameter index
654 Any aRet
= xMethod
->invoke( _aMaterial
, aInvokeParams
);
657 OutIndices
.realloc( nOutIndex
);
658 pOutIndices
= OutIndices
.getArray();
659 OutParams
.realloc( nOutIndex
);
660 Any
* pOutParams
= OutParams
.getArray();
664 pOutParams
[nOutIndex
] = pInvokeParams
[ pOutIndices
[nOutIndex
] ];
670 RuntimeException aExc
;
671 aExc
.Context
= *this;
672 aExc
.Message
= "invocation lacking of introspection access!";
677 // Struct to optimize sorting
682 // Defines where the member comes from
683 enum Mode
{ NAMEACCESS
, PROPERTYSET
, METHOD
} eMode
;
685 // Index to respective sequence
686 // (Index to NameAccess sequence for eMode==NAMEACCESS etc.)
690 // Implementation of getting name or info
691 // String sequence will be filled when pStringSeq != NULL
692 // Info sequence will be filled when pInfoSeq != NULL
693 void Invocation_Impl::getInfoSequenceImpl
695 Sequence
< OUString
>* pStringSeq
,
696 Sequence
< InvocationInfo
>* pInfoSeq
699 //Sequence< OUString > aStrSeq;
701 //pStringSeq = &aStrSeq;
704 // Get all needed sequences
705 Sequence
<OUString
> aNameAccessNames
;
706 Sequence
<Property
> aPropertySeq
;
707 Sequence
< Reference
< XIdlMethod
> > aMethodSeq
;
709 if( _xNameAccess
.is() )
711 aNameAccessNames
= _xNameAccess
->getElementNames();
714 if( _xIntrospectionAccess
.is() )
716 aPropertySeq
= _xIntrospectionAccess
->getProperties
717 ( PropertyConcept::ALL
- PropertyConcept::DANGEROUS
);
719 aMethodSeq
= _xIntrospectionAccess
->getMethods
720 ( MethodConcept::ALL
- MethodConcept::DANGEROUS
);
723 sal_Int32 nNameAccessCount
= aNameAccessNames
.getLength();
724 sal_Int32 nPropertyCount
= aPropertySeq
.getLength();
725 sal_Int32 nMethodCount
= aMethodSeq
.getLength();
726 sal_Int32 nTotalCount
= nNameAccessCount
+ nPropertyCount
+ nMethodCount
;
728 // Create and fill array of MemberItems
729 std::unique_ptr
< MemberItem
[]> pItems( new MemberItem
[ nTotalCount
] );
730 const OUString
* pStrings
= aNameAccessNames
.getConstArray();
731 const Property
* pProps
= aPropertySeq
.getConstArray();
732 const Reference
< XIdlMethod
>* pMethods
= aMethodSeq
.getConstArray();
734 // Fill array of MemberItems
735 sal_Int32 i
, iTotal
= 0;
738 for( i
= 0 ; i
< nNameAccessCount
; i
++, iTotal
++ )
740 MemberItem
& rItem
= pItems
[ iTotal
];
741 rItem
.aName
= pStrings
[ i
];
742 rItem
.eMode
= MemberItem::NAMEACCESS
;
747 for( i
= 0 ; i
< nPropertyCount
; i
++, iTotal
++ )
749 MemberItem
& rItem
= pItems
[ iTotal
];
750 rItem
.aName
= pProps
[ i
].Name
;
751 rItem
.eMode
= MemberItem::PROPERTYSET
;
756 for( i
= 0 ; i
< nMethodCount
; i
++, iTotal
++ )
758 MemberItem
& rItem
= pItems
[ iTotal
];
759 Reference
< XIdlMethod
> xMethod
= pMethods
[ i
];
760 rItem
.aName
= xMethod
->getName();
761 rItem
.eMode
= MemberItem::METHOD
;
765 // Setting up result sequences
766 OUString
* pRetStrings
= nullptr;
769 pStringSeq
->realloc( nTotalCount
);
770 pRetStrings
= pStringSeq
->getArray();
773 InvocationInfo
* pRetInfos
= nullptr;
776 pInfoSeq
->realloc( nTotalCount
);
777 pRetInfos
= pInfoSeq
->getArray();
780 // Fill result sequences in the correct order of members
781 for( iTotal
= 0 ; iTotal
< nTotalCount
; iTotal
++ )
783 MemberItem
& rItem
= pItems
[ iTotal
];
786 pRetStrings
[ iTotal
] = rItem
.aName
;
791 if( rItem
.eMode
== MemberItem::NAMEACCESS
)
793 fillInfoForNameAccess( pRetInfos
[ iTotal
], rItem
.aName
);
795 else if( rItem
.eMode
== MemberItem::PROPERTYSET
)
797 fillInfoForProperty( pRetInfos
[ iTotal
], pProps
[ rItem
.nIndex
] );
799 else if( rItem
.eMode
== MemberItem::METHOD
)
801 fillInfoForMethod( pRetInfos
[ iTotal
], pMethods
[ rItem
.nIndex
] );
808 Sequence
< OUString
> SAL_CALL
Invocation_Impl::getMemberNames( )
812 return _xDirect2
->getMemberNames();
814 Sequence
< OUString
> aRetSeq
;
815 getInfoSequenceImpl( &aRetSeq
, nullptr );
819 Sequence
< InvocationInfo
> SAL_CALL
Invocation_Impl::getInfo( )
823 return _xDirect2
->getInfo();
825 Sequence
< InvocationInfo
> aRetSeq
;
826 getInfoSequenceImpl( nullptr, &aRetSeq
);
830 InvocationInfo SAL_CALL
Invocation_Impl::getInfoForName( const OUString
& aName
, sal_Bool bExact
)
834 return _xDirect2
->getInfoForName( aName
, bExact
);
838 OUString aExactName
= aName
;
839 InvocationInfo aRetInfo
;
842 aExactName
= getExactName( aName
);
843 if( !aExactName
.isEmpty() )
845 if( _xIntrospectionAccess
->hasMethod( aExactName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
) )
847 Reference
<XIdlMethod
> xMethod
= _xIntrospectionAccess
->getMethod
848 ( aExactName
, MethodConcept::ALL
^ MethodConcept::DANGEROUS
);
849 fillInfoForMethod( aRetInfo
, xMethod
);
854 if( _xIntrospectionAccess
.is() && _xIntrospectionAccess
->hasProperty
855 ( aExactName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
) )
857 Property aProp
= _xIntrospectionAccess
->getProperty
858 ( aExactName
, PropertyConcept::ALL
^ PropertyConcept::DANGEROUS
);
859 fillInfoForProperty( aRetInfo
, aProp
);
863 else if( _xNameAccess
.is() && _xNameAccess
->hasByName( aExactName
) )
865 fillInfoForNameAccess( aRetInfo
, aExactName
);
872 throw IllegalArgumentException(
873 "getExactName(), Unknown name " + aName
,
874 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
879 // Helper functions to fill InvocationInfo for XNameAccess
880 void Invocation_Impl::fillInfoForNameAccess
882 InvocationInfo
& rInfo
,
883 const OUString
& aName
887 rInfo
.eMemberType
= MemberType_PROPERTY
;
888 rInfo
.PropertyAttribute
= 0;
889 if( !_xNameContainer
.is() )
891 rInfo
.PropertyAttribute
= PropertyAttribute::READONLY
;
893 rInfo
.aType
= _xNameAccess
->getElementType();
896 void Invocation_Impl::fillInfoForProperty
898 InvocationInfo
& rInfo
,
899 const Property
& rProp
902 rInfo
.aName
= rProp
.Name
;
903 rInfo
.eMemberType
= MemberType_PROPERTY
;
904 rInfo
.PropertyAttribute
= rProp
.Attributes
;
905 rInfo
.aType
= rProp
.Type
;
908 void Invocation_Impl::fillInfoForMethod
910 InvocationInfo
& rInfo
,
911 const Reference
< XIdlMethod
>& xMethod
914 rInfo
.aName
= xMethod
->getName();
915 rInfo
.eMemberType
= MemberType_METHOD
;
916 Reference
< XIdlClass
> xReturnClass
= xMethod
->getReturnType();
917 Type
aReturnType( xReturnClass
->getTypeClass(), xReturnClass
->getName() );
918 rInfo
.aType
= aReturnType
;
919 Sequence
<ParamInfo
> aParamInfos
= xMethod
->getParameterInfos();
920 sal_Int32 nParamCount
= aParamInfos
.getLength();
921 if( nParamCount
> 0 )
923 const ParamInfo
* pInfo
= aParamInfos
.getConstArray();
925 rInfo
.aParamTypes
.realloc( nParamCount
);
926 Type
* pParamTypes
= rInfo
.aParamTypes
.getArray();
927 rInfo
.aParamModes
.realloc( nParamCount
);
928 ParamMode
* pParamModes
= rInfo
.aParamModes
.getArray();
930 for( sal_Int32 i
= 0 ; i
< nParamCount
; i
++ )
932 Reference
< XIdlClass
> xParamClass
= pInfo
[i
].aType
;
933 Type
aParamType( xParamClass
->getTypeClass(), xParamClass
->getName() );
934 pParamTypes
[ i
] = aParamType
;
935 pParamModes
[ i
] = pInfo
[i
].aMode
;
942 Sequence
< Type
> SAL_CALL
Invocation_Impl::getTypes()
944 static Sequence
< Type
> const * s_pTypes
= nullptr;
947 Sequence
< Type
> types( 4 + 10 );
948 Type
* pTypes
= types
.getArray();
951 pTypes
[ n
++ ] = cppu::UnoType
<XTypeProvider
>::get();
952 pTypes
[ n
++ ] = cppu::UnoType
<XWeak
>::get();
953 pTypes
[ n
++ ] = cppu::UnoType
<XInvocation
>::get();
954 pTypes
[ n
++ ] = cppu::UnoType
<XMaterialHolder
>::get();
956 // Invocation does not support XExactName if direct object supports
957 // XInvocation, but not XExactName.
958 if ((_xDirect
.is() && _xENDirect
.is()) ||
959 (!_xDirect
.is() && _xENIntrospection
.is()))
961 pTypes
[ n
++ ] = cppu::UnoType
<XExactName
>::get();
963 if( _xNameContainer
.is() )
965 pTypes
[ n
++ ] = cppu::UnoType
<XNameContainer
>::get();
967 if( _xNameReplace
.is() )
969 pTypes
[ n
++ ] = cppu::UnoType
<XNameReplace
>::get();
971 if( _xNameAccess
.is() )
973 pTypes
[ n
++ ] = cppu::UnoType
<XNameAccess
>::get();
975 if (_xIndexContainer
.is())
977 pTypes
[ n
++ ] = cppu::UnoType
<XIndexContainer
>::get();
979 if (_xIndexReplace
.is())
981 pTypes
[ n
++ ] = cppu::UnoType
<XIndexReplace
>::get();
983 if (_xIndexAccess
.is())
985 pTypes
[ n
++ ] = cppu::UnoType
<XIndexAccess
>::get();
987 if (_xEnumerationAccess
.is())
989 pTypes
[ n
++ ] = cppu::UnoType
<XEnumerationAccess
>::get();
991 if (_xElementAccess
.is())
993 pTypes
[ n
++ ] = cppu::UnoType
<XElementAccess
>::get();
995 // Invocation does not support XInvocation2, if direct object supports
996 // XInvocation, but not XInvocation2.
997 if ( ( _xDirect
.is() && _xDirect2
.is()) ||
998 (!_xDirect
.is() && _xIntrospectionAccess
.is() ) )
1000 pTypes
[ n
++ ] = cppu::UnoType
<XInvocation2
>::get();
1006 MutexGuard
guard( Mutex::getGlobalMutex() );
1009 static Sequence
< Type
> s_types( types
);
1010 s_pTypes
= &s_types
;
1016 Sequence
< sal_Int8
> SAL_CALL
Invocation_Impl::getImplementationId( )
1018 return css::uno::Sequence
<sal_Int8
>();
1022 class InvocationService
1023 : public WeakImplHelper
< XSingleServiceFactory
, XServiceInfo
>
1026 explicit InvocationService( const Reference
<XComponentContext
> & xCtx
);
1029 OUString SAL_CALL
getImplementationName() override
;
1030 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) override
;
1031 Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
1033 // XSingleServiceFactory
1034 Reference
<XInterface
> SAL_CALL
createInstance() override
;
1035 Reference
<XInterface
> SAL_CALL
createInstanceWithArguments(
1036 const Sequence
<Any
>& rArguments
) override
;
1038 Reference
<XComponentContext
> mxCtx
;
1039 Reference
<XMultiComponentFactory
> mxSMgr
;
1040 Reference
<XTypeConverter
> xTypeConverter
;
1041 Reference
<XIntrospection
> xIntrospection
;
1042 Reference
<XIdlReflection
> xCoreReflection
;
1045 InvocationService::InvocationService( const Reference
<XComponentContext
> & xCtx
)
1047 , mxSMgr( xCtx
->getServiceManager() )
1048 , xCoreReflection( css::reflection::theCoreReflection::get(mxCtx
) )
1051 mxSMgr
->createInstanceWithContext( "com.sun.star.script.Converter", xCtx
),
1053 xIntrospection
= theIntrospection::get(xCtx
);
1057 OUString
InvocationService::getImplementationName()
1059 return inv_getImplementationName();
1063 sal_Bool
InvocationService::supportsService(const OUString
& ServiceName
)
1065 return cppu::supportsService(this, ServiceName
);
1069 Sequence
< OUString
> InvocationService::getSupportedServiceNames()
1071 return inv_getSupportedServiceNames();
1075 Reference
<XInterface
> InvocationService::createInstance()
1077 //TODO:throw( Exception("no default construction of invocation adapter possible!", *this) );
1078 return Reference
<XInterface
>(); // dummy
1082 Reference
<XInterface
> InvocationService::createInstanceWithArguments(
1083 const Sequence
<Any
>& rArguments
)
1085 if (rArguments
.getLength() == 1)
1087 return Reference
< XInterface
>
1088 ( *new Invocation_Impl( *rArguments
.getConstArray(),
1089 xTypeConverter
, xIntrospection
, xCoreReflection
) );
1093 //TODO:throw( Exception("no default construction of invocation adapter possible!", *this) );
1094 return Reference
<XInterface
>();
1098 /// @throws RuntimeException
1099 Reference
<XInterface
> InvocationService_CreateInstance( const Reference
<XComponentContext
> & xCtx
)
1101 Reference
<XInterface
> xService( *new InvocationService( xCtx
) );
1107 using namespace stoc_inv
;
1108 static const struct ImplementationEntry g_entries
[] =
1111 InvocationService_CreateInstance
, inv_getImplementationName
,
1112 inv_getSupportedServiceNames
, createSingleComponentFactory
,
1115 { nullptr, nullptr, nullptr, nullptr, nullptr, 0 }
1118 extern "C" SAL_DLLPUBLIC_EXPORT
void * invocation_component_getFactory(
1119 const sal_Char
* pImplName
, void * pServiceManager
, void * pRegistryKey
)
1121 return component_getFactoryHelper( pImplName
, pServiceManager
, pRegistryKey
, g_entries
);
1124 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */