tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / stoc / source / invocation / invocation.cxx
blob228332a3a5729e707d89f1e8a175135a469aa8c0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
47 #include <memory>
48 #include <vector>
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;
56 using namespace cppu;
58 namespace stoc_inv
62 // TODO: Implement centrally
63 static Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XIdlReflection > & xRefl )
65 return xRefl->forName( rType.getTypeName() );
68 namespace {
70 class Invocation_Impl
71 : public OWeakObject
72 , public XInvocation2
73 , public XNameContainer
74 , public XIndexContainer
75 , public XEnumerationAccess
76 , public XExactName
77 , public XMaterialHolder
78 , public XTypeProvider
80 public:
81 Invocation_Impl( const Any & rAdapted, const Reference<XTypeConverter> &,
82 const Reference<XIntrospection> &,
83 const Reference<XIdlReflection> &,
84 bool bFromOLE );
86 // XInterface
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(); }
92 // XTypeProvider
93 virtual Sequence< css::uno::Type > SAL_CALL getTypes( ) override;
94 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId( ) override;
96 // XMaterialHolder
97 virtual Any SAL_CALL getMaterial() override;
99 // XInvocation
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;
107 // XInvocation2
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
113 // XElementAccess
114 virtual Type SAL_CALL getElementType() override
115 { return _xElementAccess->getElementType(); }
117 virtual sal_Bool SAL_CALL hasElements() override
118 { return _xElementAccess->hasElements(); }
120 // XNameContainer
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 ); }
127 // XNameReplace
128 virtual void SAL_CALL replaceByName( const OUString& Name, const Any& Element ) override
129 { _xNameReplace->replaceByName( Name, Element ); }
131 // XNameAccess
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 ); }
141 // XIndexContainer
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 ); }
148 // XIndexReplace
149 virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element ) override
150 { _xIndexReplace->replaceByIndex( Index, Element ); }
152 // XIndexAccess
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(); }
163 // XExactName
164 virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) override;
167 private:
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;
179 Any _aMaterial;
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;
199 bool mbFromOLE;
204 Invocation_Impl::Invocation_Impl
206 const Any & rAdapted,
207 const Reference<XTypeConverter> & rTC,
208 const Reference<XIntrospection> & rI,
209 const Reference<XIdlReflection> & rCR,
210 bool bFromOLE
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) );
230 if( a.hasValue() )
232 return a;
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.
239 if (mbFromOLE ||
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.
293 if ( mbFromOLE ||
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;
311 if( _xDirect.is() )
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();
325 return _aMaterial;
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 );
351 else
353 // Make Invocation on the Introspection
354 if (xIntrospection.is())
356 _xIntrospectionAccess = xIntrospection->inspect( _aMaterial );
357 if( _xIntrospectionAccess.is() )
359 _xElementAccess.set(
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 );
369 _xIndexAccess.set(
370 _xIntrospectionAccess->queryAdapter(
371 cppu::UnoType<XIndexAccess>::get()), UNO_QUERY );
373 if( _xIndexAccess.is() )
375 _xIndexReplace.set(
376 _xIntrospectionAccess->queryAdapter(
377 cppu::UnoType<XIndexReplace>::get()), UNO_QUERY );
379 _xIndexContainer.set(
380 _xIntrospectionAccess->queryAdapter(
381 cppu::UnoType<XIndexContainer>::get()), UNO_QUERY );
384 _xNameAccess.set(
385 _xIntrospectionAccess->queryAdapter(
386 cppu::UnoType<XNameAccess>::get()), UNO_QUERY );
388 if( _xNameAccess.is() )
390 _xNameReplace.set(
391 _xIntrospectionAccess->queryAdapter(
392 cppu::UnoType<XNameReplace>::get()), UNO_QUERY );
394 _xNameContainer.set(
395 _xIntrospectionAccess->queryAdapter(
396 cppu::UnoType<XNameContainer>::get()), UNO_QUERY );
400 _xPropertySet.set( _xIntrospectionAccess->queryAdapter( cppu::UnoType<XPropertySet>::get()),
401 UNO_QUERY );
403 _xENIntrospection.set( _xIntrospectionAccess, UNO_QUERY );
410 OUString Invocation_Impl::getExactName( const OUString& rApproximateName )
412 if (_xENDirect.is())
413 return _xENDirect->getExactName( rApproximateName );
415 OUString aRet;
416 if (_xENIntrospection.is())
417 aRet = _xENIntrospection->getExactName( rApproximateName );
418 return aRet;
422 Reference<XIntrospectionAccess> Invocation_Impl::getIntrospection()
424 if( _xDirect.is() )
425 return _xDirect->getIntrospection();
426 else
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 );
437 return false;
441 sal_Bool Invocation_Impl::hasProperty( const OUString& Name )
443 if (_xDirect.is())
445 bool bRet = _xDirect->hasProperty( Name );
446 if (bRet || !mbFromOLE)
447 return bRet;
449 // PropertySet
450 if( _xIntrospectionAccess.is()
451 && _xIntrospectionAccess->hasProperty( Name, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
452 return true;
453 // NameAccess
454 if( _xNameAccess.is() )
455 return _xNameAccess->hasByName( Name );
456 return false;
460 Any Invocation_Impl::getValue( const OUString& PropertyName )
464 if (_xDirect.is())
465 return _xDirect->getValue( PropertyName );
467 catch (Exception &)
469 if (!mbFromOLE)
470 throw;
474 // PropertySet
475 if( _xIntrospectionAccess.is() && _xPropertySet.is()
476 && _xIntrospectionAccess->hasProperty
477 ( PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
479 return _xPropertySet->getPropertyValue( PropertyName );
481 // NameAccess
482 if( _xNameAccess.is() && _xNameAccess->hasByName( PropertyName ) )
483 return _xNameAccess->getByName( PropertyName );
485 catch (UnknownPropertyException &)
487 throw;
489 catch (RuntimeException &)
491 throw;
493 catch (Exception &)
497 throw UnknownPropertyException( "cannot get value " + PropertyName );
501 void Invocation_Impl::setValue( const OUString& PropertyName, const Any& Value )
505 if (_xDirect.is())
507 _xDirect->setValue( PropertyName, Value );
508 return;
511 catch (Exception &)
513 if (!mbFromOLE)
514 throw;
518 // Properties
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 ) );
531 else
532 throw RuntimeException( u"no type converter service!"_ustr );
534 // NameContainer
535 else if( _xNameContainer.is() )
537 // Note: This misfeature deliberately not adapted to apply to objects which
538 // have XNameReplace but not XNameContainer
539 Any aConv;
540 Reference < XIdlClass > r =
541 TypeToIdlClass( _xNameContainer->getElementType(), xCoreReflection );
542 if( r->isAssignableFrom(TypeToIdlClass( Value.getValueType(), xCoreReflection ) ) )
543 aConv = Value;
544 else if( xTypeConverter.is() )
545 aConv = xTypeConverter->convertTo( Value, _xNameContainer->getElementType() );
546 else
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 );
552 else
553 _xNameContainer->insertByName( PropertyName, aConv );
555 else
556 throw UnknownPropertyException( u"no introspection nor name container!"_ustr );
558 catch (UnknownPropertyException &)
560 throw;
562 catch (CannotConvertException &)
564 throw;
566 catch (InvocationTargetException &)
568 throw;
570 catch (RuntimeException &)
572 throw;
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 );
596 // ParameterInfos
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) );
608 // IN Parameter
609 const Any* pInParams = InParams.getConstArray();
611 // Introspection Invoke Parameter
612 Sequence<Any> aInvokeParams( nFParamsLen );
613 Any* pInvokeParams = aInvokeParams.getArray();
615 // OUT Indices
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 );
639 else
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
651 ++nOutIndex;
654 catch( CannotConvertException& rExc )
656 rExc.ArgumentIndex = nPos; // Add optional parameter index
657 throw;
661 // execute Method
662 Any aRet = xMethod->invoke( _aMaterial, aInvokeParams );
664 // OUT Params
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]; });
671 return aRet;
674 throw RuntimeException(u"invocation lacking of introspection access!"_ustr, *this);
677 namespace {
679 // Struct to optimize sorting
680 struct MemberItem
682 OUString aName;
684 // Defines where the member comes from
685 enum class Mode { NameAccess, PropertySet, Method };
686 Mode eMode;
688 // Index to respective sequence
689 // (Index to NameAccess sequence for eMode==Mode::NameAccess etc.)
690 sal_Int32 nIndex;
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;
705 //if( !pStringSeq )
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;
742 // Name Access
743 for( i = 0 ; i < nNameAccessCount ; i++, iTotal++ )
745 MemberItem& rItem = pItems[ iTotal ];
746 rItem.aName = pStrings[ i ];
747 rItem.eMode = MemberItem::Mode::NameAccess;
748 rItem.nIndex = i;
751 // Property set
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;
757 rItem.nIndex = i;
760 // Methods
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;
767 rItem.nIndex = i;
770 // Setting up result sequences
771 OUString* pRetStrings = nullptr;
772 if( pStringSeq )
774 pStringSeq->realloc( nTotalCount );
775 pRetStrings = pStringSeq->getArray();
778 InvocationInfo* pRetInfos = nullptr;
779 if( pInfoSeq )
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 ];
789 if( pRetStrings )
791 pRetStrings[ iTotal ] = rItem.aName;
794 if( pRetInfos )
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 ] );
812 // XInvocation2
813 Sequence< OUString > SAL_CALL Invocation_Impl::getMemberNames( )
815 if( _xDirect2.is() )
817 return _xDirect2->getMemberNames();
819 Sequence< OUString > aRetSeq;
820 getInfoSequenceImpl( &aRetSeq, nullptr );
821 return aRetSeq;
824 Sequence< InvocationInfo > SAL_CALL Invocation_Impl::getInfo( )
826 if( _xDirect2.is() )
828 return _xDirect2->getInfo();
830 Sequence< InvocationInfo > aRetSeq;
831 getInfoSequenceImpl( nullptr, &aRetSeq );
832 return aRetSeq;
835 InvocationInfo SAL_CALL Invocation_Impl::getInfoForName( const OUString& aName, sal_Bool bExact )
837 if( _xDirect2.is() )
839 return _xDirect2->getInfoForName( aName, bExact );
842 bool bFound = false;
843 OUString aExactName = aName;
844 InvocationInfo aRetInfo;
846 if( bExact )
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 );
855 bFound = true;
857 else
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 );
865 bFound = true;
867 // NameAccess
868 else if( _xNameAccess.is() && _xNameAccess->hasByName( aExactName ) )
870 fillInfoForNameAccess( aRetInfo, aExactName );
871 bFound = true;
875 if( !bFound )
877 throw IllegalArgumentException(
878 "getExactName(), Unknown name " + aName,
879 getXWeak(), 0 );
881 return aRetInfo;
884 // Helper functions to fill InvocationInfo for XNameAccess
885 void Invocation_Impl::fillInfoForNameAccess
887 InvocationInfo& rInfo,
888 const OUString& aName
891 rInfo.aName = 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 )
926 return;
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;
944 // XTypeProvider
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);
980 }();
981 return s_types;
984 Sequence< sal_Int8 > SAL_CALL Invocation_Impl::getImplementationId( )
986 return css::uno::Sequence<sal_Int8>();
989 namespace {
991 class InvocationService
992 : public WeakImplHelper< XSingleServiceFactory, XServiceInfo >
994 public:
995 explicit InvocationService( const Reference<XComponentContext> & xCtx );
997 // XServiceInfo
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;
1006 private:
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 )
1017 : mxCtx( xCtx )
1018 , mxSMgr( xCtx->getServiceManager() )
1019 , xCoreReflection( css::reflection::theCoreReflection::get(mxCtx) )
1021 xTypeConverter.set(
1022 mxSMgr->createInstanceWithContext( u"com.sun.star.script.Converter"_ustr, xCtx ),
1023 UNO_QUERY );
1024 xIntrospection = theIntrospection::get(xCtx);
1027 // XServiceInfo
1028 OUString InvocationService::getImplementationName()
1030 return u"com.sun.star.comp.stoc.Invocation"_ustr;
1033 // XServiceInfo
1034 sal_Bool InvocationService::supportsService(const OUString& ServiceName)
1036 return cppu::supportsService(this, ServiceName);
1039 // XServiceInfo
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)
1058 OUString aArg1;
1059 if ((rArguments[1] >>= aArg1) &&
1060 aArg1 == "FromOLE")
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: */