diff options
author | Matthew J. Francis <mjay.francis@gmail.com> | 2015-07-23 11:36:38 +0800 |
---|---|---|
committer | Matthew Francis <mjay.francis@gmail.com> | 2015-07-27 07:40:34 +0000 |
commit | 9c5a217681935d661aad4d5667a775319382d22a (patch) | |
tree | 29c94ae9316f3a8899ffa8a7ecaf6123e15748b4 | |
parent | 165c939818b18d68216864600097b99e5d8c2266 (diff) |
Tweak introspection/invocation to be more useful to PyUNO
- Make introspection/invocation handle XNameReplace and
XIndexReplace
- Make introspection handle XUnoTunnel
- Adapt PyUNO to take advantage of the additionally handled
interfaces
Change-Id: Ie848d10fd2c31cad76fcc3a746262a490a2c9ae1
Reviewed-on: https://gerrit.libreoffice.org/17314
Reviewed-by: Matthew Francis <mjay.francis@gmail.com>
Tested-by: Matthew Francis <mjay.francis@gmail.com>
-rw-r--r-- | pyuno/source/module/pyuno.cxx | 95 | ||||
-rw-r--r-- | pyuno/source/module/pyuno_adapter.cxx | 27 | ||||
-rw-r--r-- | pyuno/source/module/pyuno_impl.hxx | 9 | ||||
-rw-r--r-- | pyuno/source/module/pyuno_module.cxx | 4 | ||||
-rw-r--r-- | pyuno/source/module/pyuno_runtime.cxx | 22 | ||||
-rw-r--r-- | stoc/source/inspect/introspection.cxx | 193 | ||||
-rw-r--r-- | stoc/source/invocation/invocation.cxx | 50 |
7 files changed, 288 insertions, 112 deletions
diff --git a/pyuno/source/module/pyuno.cxx b/pyuno/source/module/pyuno.cxx index f068961fb9aa..ccab344b5b44 100644 --- a/pyuno/source/module/pyuno.cxx +++ b/pyuno/source/module/pyuno.cxx @@ -60,6 +60,7 @@ using com::sun::star::uno::XComponentContext; using com::sun::star::lang::XSingleServiceFactory; using com::sun::star::lang::XServiceInfo; using com::sun::star::lang::XTypeProvider; +using com::sun::star::lang::XUnoTunnel; using com::sun::star::script::XTypeConverter; using com::sun::star::script::XInvocation2; using com::sun::star::beans::XMaterialHolder; @@ -563,7 +564,7 @@ sal_Int32 lcl_detach_getLength( PyUNO *me ) // returned by getElementNames(), or the user may be surprised. // For XIndexContainer - Reference< XIndexAccess > xIndexAccess( me->members->wrappedObject, UNO_QUERY ); + Reference< XIndexAccess > xIndexAccess( me->members->xInvocation, UNO_QUERY ); if ( xIndexAccess.is() ) { return xIndexAccess->getCount(); @@ -571,7 +572,7 @@ sal_Int32 lcl_detach_getLength( PyUNO *me ) // For XNameContainer // Not terribly efficient - get the count of all the names - Reference< XNameAccess > xNameAccess( me->members->wrappedObject, UNO_QUERY ); + Reference< XNameAccess > xNameAccess( me->members->xInvocation, UNO_QUERY ); if ( xNameAccess.is() ) { return xNameAccess->getElementNames().getLength(); @@ -782,7 +783,7 @@ PyObject* lcl_getitem_index( PyUNO *me, PyObject *pKey, Runtime& runtime ) { PyThreadDetach antiguard; - Reference< XIndexAccess > xIndexAccess( me->members->wrappedObject, UNO_QUERY ); + Reference< XIndexAccess > xIndexAccess( me->members->xInvocation, UNO_QUERY ); if ( xIndexAccess.is() ) { if (nIndex < 0) @@ -809,7 +810,7 @@ PyObject* lcl_getitem_slice( PyUNO *me, PyObject *pKey ) { PyThreadDetach antiguard; - xIndexAccess.set( me->members->wrappedObject, UNO_QUERY ); + xIndexAccess.set( me->members->xInvocation, UNO_QUERY ); if ( xIndexAccess.is() ) nLen = xIndexAccess->getCount(); } @@ -850,7 +851,7 @@ PyObject* lcl_getitem_string( PyUNO *me, PyObject *pKey, Runtime& runtime ) { PyThreadDetach antiguard; - Reference< XNameAccess > xNameAccess( me->members->wrappedObject, UNO_QUERY ); + Reference< XNameAccess > xNameAccess( me->members->xInvocation, UNO_QUERY ); if ( xNameAccess.is() ) { aRet = xNameAccess->getByName( sKey ); @@ -914,8 +915,8 @@ PyObject* PyUNO_getitem( PyObject *self, PyObject *pKey ) // If the object is an XIndexAccess and/or XNameAccess, but the // key passed wasn't suitable, give a TypeError which specifically // describes this - Reference< XIndexAccess > xIndexAccess( me->members->wrappedObject, UNO_QUERY ); - Reference< XNameAccess > xNameAccess( me->members->wrappedObject, UNO_QUERY ); + Reference< XIndexAccess > xIndexAccess( me->members->xInvocation, UNO_QUERY ); + Reference< XNameAccess > xNameAccess( me->members->xInvocation, UNO_QUERY ); if ( xIndexAccess.is() || xNameAccess.is() ) { PyErr_SetString( PyExc_TypeError, "subscription with invalid type" ); @@ -985,11 +986,11 @@ int lcl_setitem_index( PyUNO *me, PyObject *pKey, PyObject *pValue ) { PyThreadDetach antiguard; - xIndexContainer.set( me->members->wrappedObject, UNO_QUERY ); + xIndexContainer.set( me->members->xInvocation, UNO_QUERY ); if ( xIndexContainer.is() ) xIndexReplace.set( xIndexContainer, UNO_QUERY ); else - xIndexReplace.set( me->members->wrappedObject, UNO_QUERY ); + xIndexReplace.set( me->members->xInvocation, UNO_QUERY ); if ( xIndexReplace.is() && nIndex < 0 ) nIndex += xIndexReplace->getCount(); @@ -1032,11 +1033,11 @@ int lcl_setitem_slice( PyUNO *me, PyObject *pKey, PyObject *pValue ) { PyThreadDetach antiguard; - xIndexContainer.set( me->members->wrappedObject, UNO_QUERY ); + xIndexContainer.set( me->members->xInvocation, UNO_QUERY ); if ( xIndexContainer.is() ) xIndexReplace.set( xIndexContainer, UNO_QUERY ); else - xIndexReplace.set( me->members->wrappedObject, UNO_QUERY ); + xIndexReplace.set( me->members->xInvocation, UNO_QUERY ); if ( xIndexReplace.is() ) nLen = xIndexReplace->getCount(); @@ -1165,12 +1166,12 @@ int lcl_setitem_string( PyUNO *me, PyObject *pKey, PyObject *pValue ) { PyThreadDetach antiguard; - Reference< XNameContainer > xNameContainer( me->members->wrappedObject, UNO_QUERY ); + Reference< XNameContainer > xNameContainer( me->members->xInvocation, UNO_QUERY ); Reference< XNameReplace > xNameReplace; if ( xNameContainer.is() ) xNameReplace.set( xNameContainer, UNO_QUERY ); else - xNameReplace.set( me->members->wrappedObject, UNO_QUERY ); + xNameReplace.set( me->members->xInvocation, UNO_QUERY ); if ( xNameReplace.is() ) { @@ -1277,17 +1278,17 @@ PyObject* PyUNO_iter( PyObject *self ) { PyThreadDetach antiguard; - xEnumerationAccess.set( me->members->wrappedObject, UNO_QUERY ); + xEnumerationAccess.set( me->members->xInvocation, UNO_QUERY ); if ( xEnumerationAccess.is() ) xEnumeration = xEnumerationAccess->createEnumeration(); else xEnumeration.set( me->members->wrappedObject, UNO_QUERY ); if ( !xEnumeration.is() ) - xIndexAccess.set( me->members->wrappedObject, UNO_QUERY ); + xIndexAccess.set( me->members->xInvocation, UNO_QUERY ); if ( !xIndexAccess.is() ) - xNameAccess.set( me->members->wrappedObject, UNO_QUERY ); + xNameAccess.set( me->members->xInvocation, UNO_QUERY ); } // XEnumerationAccess iterator @@ -1373,7 +1374,7 @@ int PyUNO_contains( PyObject *self, PyObject *pKey ) { PyThreadDetach antiguard; - xNameAccess.set( me->members->wrappedObject, UNO_QUERY ); + xNameAccess.set( me->members->xInvocation, UNO_QUERY ); if ( xNameAccess.is() ) { bool hasKey = xNameAccess->hasByName( sKey ); @@ -1765,51 +1766,43 @@ PyRef getPyUnoClass() return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) ); } -PyObject* PyUNO_new ( - const Any & targetInterface, const Reference<XSingleServiceFactory> &ssf) -{ - Reference<XInterface> tmp_interface; - - targetInterface >>= tmp_interface; - - if (!tmp_interface.is ()) - { - // empty reference ! - Py_INCREF( Py_None ); - return Py_None; - } - return PyUNO_new_UNCHECKED (targetInterface, ssf); -} - - -PyObject* PyUNO_new_UNCHECKED ( +PyRef PyUNO_new ( const Any &targetInterface, - const Reference<XSingleServiceFactory> &ssf ) + const Reference<XSingleServiceFactory> &ssf, + const bool bCheckExisting ) { - Reference<XInterface> tmp_interface; - Reference<XInvocation2> tmp_invocation; + Reference<XInvocation2> xInvocation; + { PyThreadDetach antiguard; - Sequence<Any> arguments(1); - arguments[0] <<= targetInterface; - tmp_interface = ssf->createInstanceWithArguments(arguments); - tmp_invocation.set(tmp_interface, UNO_QUERY); - if (!tmp_invocation.is() && tmp_interface.is()) { + xInvocation.set( + ssf->createInstanceWithArguments( Sequence<Any>( &targetInterface, 1 ) ), UNO_QUERY ); + if( !xInvocation.is() ) throw RuntimeException("XInvocation2 not implemented, cannot interact with object"); + + if (bCheckExisting) + { + Reference<XUnoTunnel> xUnoTunnel ( + xInvocation->getIntrospection()->queryAdapter(cppu::UnoType<XUnoTunnel>::get()), UNO_QUERY ); + if( xUnoTunnel.is() ) + { + sal_Int64 that = xUnoTunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() ); + if( that ) + return PyRef( reinterpret_cast<Adapter*>(that)->getWrappedObject() ); + } } } - if (!tmp_interface.is()) - { - Py_INCREF( Py_None ); - return Py_None; - } + if( !Py_IsInitialized() ) + throw RuntimeException(); + PyUNO* self = PyObject_New (PyUNO, &PyUNOType); if (self == NULL) - return NULL; // == error + return PyRef(); // == error self->members = new PyUNOInternals(); - self->members->xInvocation = tmp_invocation; + self->members->xInvocation = xInvocation; self->members->wrappedObject = targetInterface; - return reinterpret_cast<PyObject*>(self); + return PyRef( reinterpret_cast<PyObject*>(self), SAL_NO_ACQUIRE ); + } } diff --git a/pyuno/source/module/pyuno_adapter.cxx b/pyuno/source/module/pyuno_adapter.cxx index 1fbfcba1b48b..ce4995d41eaa 100644 --- a/pyuno/source/module/pyuno_adapter.cxx +++ b/pyuno/source/module/pyuno_adapter.cxx @@ -80,6 +80,9 @@ sal_Int64 Adapter::getSomething( const Sequence< sal_Int8 > &id) throw (RuntimeE void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime ) throw ( InvocationTargetException ) { + if( !Py_IsInitialized() ) + throw InvocationTargetException(); + if( PyErr_Occurred() ) { PyRef excType, excValue, excTraceback; @@ -195,6 +198,9 @@ Any Adapter::invoke( const OUString &aFunctionName, { PyThreadAttach guard( mInterpreter ); { + if( !Py_IsInitialized() ) + throw InvocationTargetException(); + // convert parameters to python args // TODO: Out parameter Runtime runtime; @@ -219,12 +225,18 @@ Any Adapter::invoke( const OUString &aFunctionName, for( i = 0; i < size ; i ++ ) { PyRef val = runtime.any2PyObject( aParams[i] ); + + // any2PyObject() can release the GIL + if( !Py_IsInitialized() ) + throw InvocationTargetException(); + PyTuple_SetItem( argsTuple.get(), i, val.getAcquired() ); } // get callable PyRef method(PyObject_GetAttrString( mWrappedObject.get(), TO_ASCII(aFunctionName)), SAL_NO_ACQUIRE); + raiseInvocationTargetExceptionWhenNeeded( runtime); if( !method.is() ) { @@ -355,9 +367,16 @@ void Adapter::setValue( const OUString & aPropertyName, const Any & value ) PyThreadAttach guard( mInterpreter ); try { + if( !Py_IsInitialized() ) + throw InvocationTargetException(); + Runtime runtime; PyRef obj = runtime.any2PyObject( value ); + // any2PyObject() can release the GIL + if( !Py_IsInitialized() ) + throw InvocationTargetException(); + PyObject_SetAttrString( mWrappedObject.get(), TO_ASCII(aPropertyName), obj.get() ); raiseInvocationTargetExceptionWhenNeeded( runtime); @@ -375,6 +394,10 @@ Any Adapter::getValue( const OUString & aPropertyName ) Any ret; PyThreadAttach guard( mInterpreter ); { + // Should probably be InvocationTargetException, but the interface doesn't allow it + if( !Py_IsInitialized() ) + throw RuntimeException(); + Runtime runtime; PyRef pyRef( PyObject_GetAttrString( mWrappedObject.get(), TO_ASCII(aPropertyName) ), @@ -404,6 +427,10 @@ sal_Bool Adapter::hasProperty( const OUString & aPropertyName ) bool bRet = false; PyThreadAttach guard( mInterpreter ); { + // Should probably be InvocationTargetException, but the interface doesn't allow it + if( !Py_IsInitialized() ) + throw RuntimeException(); + bRet = PyObject_HasAttrString( mWrappedObject.get() , TO_ASCII( aPropertyName )); } diff --git a/pyuno/source/module/pyuno_impl.hxx b/pyuno/source/module/pyuno_impl.hxx index 11fbfa27e73f..669386f090e0 100644 --- a/pyuno/source/module/pyuno_impl.hxx +++ b/pyuno/source/module/pyuno_impl.hxx @@ -205,13 +205,10 @@ typedef std::unordered_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSe int PyUNO_initType(); -PyObject* PyUNO_new( +PyRef PyUNO_new ( const com::sun::star::uno::Any & targetInterface, - const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf); - -PyObject* PyUNO_new_UNCHECKED ( - const com::sun::star::uno::Any & targetInterface, - const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf); + const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf, + const bool bCheckExisting ); typedef struct { diff --git a/pyuno/source/module/pyuno_module.cxx b/pyuno/source/module/pyuno_module.cxx index 722e9226b1a7..7d282c2f27c7 100644 --- a/pyuno/source/module/pyuno_module.cxx +++ b/pyuno/source/module/pyuno_module.cxx @@ -406,8 +406,8 @@ static PyObject *createUnoStructHelper( if (idl_class.is ()) { idl_class->createObject (IdlStruct); - PyUNO *me = reinterpret_cast<PyUNO*>(PyUNO_new_UNCHECKED( IdlStruct, c->xInvocation )); - PyRef returnCandidate( reinterpret_cast<PyObject*>(me), SAL_NO_ACQUIRE ); + PyRef returnCandidate( PyUNO_new( IdlStruct, c->xInvocation, false ) ); + PyUNO *me = reinterpret_cast<PyUNO*>( returnCandidate.get() ); TypeDescription desc( typeName ); OSL_ASSERT( desc.is() ); // could already instantiate an XInvocation2 ! diff --git a/pyuno/source/module/pyuno_runtime.cxx b/pyuno/source/module/pyuno_runtime.cxx index cda8e8b1b669..f14b84b4baa7 100644 --- a/pyuno/source/module/pyuno_runtime.cxx +++ b/pyuno/source/module/pyuno_runtime.cxx @@ -481,7 +481,7 @@ PyRef Runtime::any2PyObject (const Any &a ) const case typelib_TypeClass_STRUCT: { PyRef excClass = getClass( a.getValueType().getTypeName(), *this ); - PyRef value = PyRef( PyUNO_new_UNCHECKED (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE); + PyRef value = PyUNO_new( a, getImpl()->cargo->xInvocation, false ); PyRef argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE, NOT_NULL ); PyTuple_SetItem( argsTuple.get() , 0 , value.getAcquired() ); PyRef ret( PyObject_CallObject( excClass.get() , argsTuple.get() ), SAL_NO_ACQUIRE ); @@ -551,22 +551,12 @@ PyRef Runtime::any2PyObject (const Any &a ) const } case typelib_TypeClass_INTERFACE: { - // fdo#46678 must unlock GIL because getSomething could acquire locks, - // and queryInterface too... - { - PyThreadDetach d; + Reference<XInterface> tmp_interface; + a >>= tmp_interface; + if (!tmp_interface.is ()) + return Py_None; - Reference<XUnoTunnel> tunnel; - a >>= tunnel; - if (tunnel.is()) - { - sal_Int64 that = tunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() ); - if( that ) - return reinterpret_cast<Adapter*>(that)->getWrappedObject(); - } - } - //This is just like the struct case: - return PyRef( PyUNO_new (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE ); + return PyUNO_new (a, getImpl()->cargo->xInvocation, true); } default: { diff --git a/stoc/source/inspect/introspection.cxx b/stoc/source/inspect/introspection.cxx index cd621b801b63..98a18c04146e 100644 --- a/stoc/source/inspect/introspection.cxx +++ b/stoc/source/inspect/introspection.cxx @@ -44,6 +44,7 @@ #include <com/sun/star/lang/XSingleServiceFactory.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/reflection/XIdlReflection.hpp> #include <com/sun/star/reflection/XIdlClass.hpp> #include <com/sun/star/reflection/XIdlField2.hpp> @@ -86,7 +87,7 @@ namespace typedef WeakImplHelper< XIntrospectionAccess, XMaterialHolder, XExactName, XPropertySet, XFastPropertySet, XPropertySetInfo, XNameContainer, XIndexContainer, XEnumerationAccess, - XIdlArray > IntrospectionAccessHelper; + XIdlArray, XUnoTunnel > IntrospectionAccessHelper; @@ -201,11 +202,14 @@ class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject bool mbFastPropSet; bool mbElementAccess; bool mbNameAccess; + bool mbNameReplace; bool mbNameContainer; bool mbIndexAccess; + bool mbIndexReplace; bool mbIndexContainer; bool mbEnumerationAccess; bool mbIdlArray; + bool mbUnoTunnel; // Original handles of FastPropertySets sal_Int32* mpOrgPropertyHandleArray; @@ -273,11 +277,14 @@ IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlR mbFastPropSet = false; mbElementAccess = false; mbNameAccess = false; + mbNameReplace = false; mbNameContainer = false; mbIndexAccess = false; + mbIndexReplace = false; mbIndexContainer = false; mbEnumerationAccess = false; mbIdlArray = false; + mbUnoTunnel = false; mpOrgPropertyHandleArray = NULL; @@ -716,19 +723,27 @@ class ImplIntrospectionAccess : public IntrospectionAccessHelper // Original interfaces of the objects Reference<XElementAccess> mxObjElementAccess; Reference<XNameContainer> mxObjNameContainer; + Reference<XNameReplace> mxObjNameReplace; Reference<XNameAccess> mxObjNameAccess; - Reference<XIndexAccess> mxObjIndexAccess; Reference<XIndexContainer> mxObjIndexContainer; + Reference<XIndexReplace> mxObjIndexReplace; + Reference<XIndexAccess> mxObjIndexAccess; Reference<XEnumerationAccess> mxObjEnumerationAccess; Reference<XIdlArray> mxObjIdlArray; Reference<XElementAccess> getXElementAccess(); Reference<XNameContainer> getXNameContainer(); + Reference<XNameReplace> getXNameReplace(); Reference<XNameAccess> getXNameAccess(); Reference<XIndexContainer> getXIndexContainer(); + Reference<XIndexReplace> getXIndexReplace(); Reference<XIndexAccess> getXIndexAccess(); Reference<XEnumerationAccess> getXEnumerationAccess(); Reference<XIdlArray> getXIdlArray(); + Reference<XUnoTunnel> getXUnoTunnel(); + + void cacheXNameContainer(); + void cacheXIndexContainer(); public: ImplIntrospectionAccess( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ ); @@ -804,11 +819,13 @@ public: virtual Sequence< OUString > SAL_CALL getElementNames() throw( RuntimeException, std::exception ) SAL_OVERRIDE; virtual sal_Bool SAL_CALL hasByName(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE; + // Methods from XNameReplace + virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element) + throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE; + // Methods from XNameContainer virtual void SAL_CALL insertByName(const OUString& Name, const Any& Element) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE; - virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element) - throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE; virtual void SAL_CALL removeByName(const OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE; @@ -817,11 +834,13 @@ public: virtual Any SAL_CALL getByIndex(sal_Int32 Index) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE; + // Methods from XIndexReplace + virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element) + throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE; + // Methods from XIndexContainer virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE; - virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element) - throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE; virtual void SAL_CALL removeByIndex(sal_Int32 Index) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE; @@ -836,6 +855,10 @@ public: throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception ) SAL_OVERRIDE; virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value) throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception ) SAL_OVERRIDE; + + // Methods from XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const Sequence< sal_Int8 >& aIdentifier ) + throw (RuntimeException, std::exception) SAL_OVERRIDE; }; ImplIntrospectionAccess::ImplIntrospectionAccess @@ -871,62 +894,138 @@ Reference<XElementAccess> ImplIntrospectionAccess::getXElementAccess() return mxObjElementAccess; } +void ImplIntrospectionAccess::cacheXNameContainer() +{ + Reference<XNameContainer> xNameContainer; + Reference<XNameReplace> xNameReplace; + Reference<XNameAccess> xNameAccess; + if (mpStaticImpl->mbNameContainer) + { + xNameContainer = Reference<XNameContainer>::query( mxIface ); + xNameReplace = Reference<XNameReplace>::query( xNameContainer ); + xNameAccess = Reference<XNameAccess>::query( xNameContainer ); + } + else if (mpStaticImpl->mbNameReplace) + { + xNameReplace = Reference<XNameReplace>::query( mxIface ); + xNameAccess = Reference<XNameAccess>::query( xNameReplace ); + } + else if (mpStaticImpl->mbNameAccess) + { + xNameAccess = Reference<XNameAccess>::query( mxIface ); + } + + { + MutexGuard aGuard( m_aMutex ); + if( !mxObjNameContainer.is() ) + mxObjNameContainer = xNameContainer; + if( !mxObjNameReplace.is() ) + mxObjNameReplace = xNameReplace; + if( !mxObjNameAccess.is() ) + mxObjNameAccess = xNameAccess; + } +} + Reference<XNameContainer> ImplIntrospectionAccess::getXNameContainer() { - ResettableGuard< Mutex > aGuard( m_aMutex ); + ClearableGuard< Mutex > aGuard( m_aMutex ); if( !mxObjNameContainer.is() ) { aGuard.clear(); - Reference<XNameContainer> xNameContainer = Reference<XNameContainer>::query( mxIface ); - aGuard.reset(); - if( !mxObjNameContainer.is() ) - mxObjNameContainer = xNameContainer; + cacheXNameContainer(); } return mxObjNameContainer; } +Reference<XNameReplace> ImplIntrospectionAccess::getXNameReplace() +{ + ClearableGuard< Mutex > aGuard( m_aMutex ); + + if( !mxObjNameReplace.is() ) + { + aGuard.clear(); + cacheXNameContainer(); + } + return mxObjNameReplace; +} + Reference<XNameAccess> ImplIntrospectionAccess::getXNameAccess() { - ResettableGuard< Mutex > aGuard( m_aMutex ); + ClearableGuard< Mutex > aGuard( m_aMutex ); if( !mxObjNameAccess.is() ) { aGuard.clear(); - Reference<XNameAccess> xNameAccess = Reference<XNameAccess>::query( mxIface ); - aGuard.reset(); - if( !mxObjNameAccess.is() ) - mxObjNameAccess = xNameAccess; + cacheXNameContainer(); } return mxObjNameAccess; } +void ImplIntrospectionAccess::cacheXIndexContainer() +{ + Reference<XIndexContainer> xIndexContainer; + Reference<XIndexReplace> xIndexReplace; + Reference<XIndexAccess> xIndexAccess; + if (mpStaticImpl->mbIndexContainer) + { + xIndexContainer = Reference<XIndexContainer>::query( mxIface ); + xIndexReplace = Reference<XIndexReplace>::query( xIndexContainer ); + xIndexAccess = Reference<XIndexAccess>::query( xIndexContainer ); + } + else if (mpStaticImpl->mbIndexReplace) + { + xIndexReplace = Reference<XIndexReplace>::query( mxIface ); + xIndexAccess = Reference<XIndexAccess>::query( xIndexReplace ); + } + else if (mpStaticImpl->mbIndexAccess) + { + xIndexAccess = Reference<XIndexAccess>::query( mxIface ); + } + + { + MutexGuard aGuard( m_aMutex ); + if( !mxObjIndexContainer.is() ) + mxObjIndexContainer = xIndexContainer; + if( !mxObjIndexReplace.is() ) + mxObjIndexReplace = xIndexReplace; + if( !mxObjIndexAccess.is() ) + mxObjIndexAccess = xIndexAccess; + } +} + Reference<XIndexContainer> ImplIntrospectionAccess::getXIndexContainer() { - ResettableGuard< Mutex > aGuard( m_aMutex ); + ClearableGuard< Mutex > aGuard( m_aMutex ); if( !mxObjIndexContainer.is() ) { aGuard.clear(); - Reference<XIndexContainer> xIndexContainer = Reference<XIndexContainer>::query( mxIface ); - aGuard.reset(); - if( !mxObjIndexContainer.is() ) - mxObjIndexContainer = xIndexContainer; + cacheXIndexContainer(); } return mxObjIndexContainer; } +Reference<XIndexReplace> ImplIntrospectionAccess::getXIndexReplace() +{ + ClearableGuard< Mutex > aGuard( m_aMutex ); + + if( !mxObjIndexReplace.is() ) + { + aGuard.clear(); + cacheXIndexContainer(); + } + return mxObjIndexReplace; +} + Reference<XIndexAccess> ImplIntrospectionAccess::getXIndexAccess() { - ResettableGuard< Mutex > aGuard( m_aMutex ); + ClearableGuard< Mutex > aGuard( m_aMutex ); if( !mxObjIndexAccess.is() ) { aGuard.clear(); - Reference<XIndexAccess> xIndexAccess = Reference<XIndexAccess>::query( mxIface ); - aGuard.reset(); - if( !mxObjIndexAccess.is() ) - mxObjIndexAccess = xIndexAccess; + cacheXIndexContainer(); } return mxObjIndexAccess; } @@ -961,6 +1060,10 @@ Reference<XIdlArray> ImplIntrospectionAccess::getXIdlArray() return mxObjIdlArray; } +Reference<XUnoTunnel> ImplIntrospectionAccess::getXUnoTunnel() +{ + return Reference<XUnoTunnel>::query( mxIface ); +} // Methods from XInterface Any SAL_CALL ImplIntrospectionAccess::queryInterface( const Type& rType ) @@ -983,11 +1086,14 @@ Any SAL_CALL ImplIntrospectionAccess::queryInterface( const Type& rType ) if( ( mpStaticImpl->mbElementAccess && (aRet = ::cppu::queryInterface ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() ) || ( mpStaticImpl->mbNameAccess && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() ) + || ( mpStaticImpl->mbNameReplace && (aRet = ::cppu::queryInterface( rType, static_cast< XNameReplace* >( this ) ) ).hasValue() ) || ( mpStaticImpl->mbNameContainer && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() ) || ( mpStaticImpl->mbIndexAccess && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() ) + || ( mpStaticImpl->mbIndexReplace && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexReplace* >( this ) ) ).hasValue() ) || ( mpStaticImpl->mbIndexContainer && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() ) || ( mpStaticImpl->mbEnumerationAccess && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() ) || ( mpStaticImpl->mbIdlArray && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() ) + || ( mpStaticImpl->mbUnoTunnel && (aRet = ::cppu::queryInterface( rType, static_cast< XUnoTunnel* >( this ) ) ).hasValue() ) ) { } @@ -1141,7 +1247,7 @@ void ImplIntrospectionAccess::insertByName(const OUString& Name, const Any& Elem void ImplIntrospectionAccess::replaceByName(const OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) { - getXNameContainer()->replaceByName( Name, Element ); + getXNameReplace()->replaceByName( Name, Element ); } void ImplIntrospectionAccess::removeByName(const OUString& Name) @@ -1173,7 +1279,7 @@ void ImplIntrospectionAccess::insertByIndex(sal_Int32 Index, const Any& Element) void ImplIntrospectionAccess::replaceByIndex(sal_Int32 Index, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) { - getXIndexContainer()->replaceByIndex( Index, Element ); + getXIndexReplace()->replaceByIndex( Index, Element ); } void ImplIntrospectionAccess::removeByIndex(sal_Int32 Index) @@ -1214,6 +1320,12 @@ void ImplIntrospectionAccess::set(Any& array, sal_Int32 index, const Any& value) getXIdlArray()->set( array, index, value ); } +// Methods from XUnoTunnel +sal_Int64 ImplIntrospectionAccess::getSomething( const Sequence< sal_Int8 >& aIdentifier ) + throw (RuntimeException, std::exception) +{ + return getXUnoTunnel()->getSomething( aIdentifier ); +} //*** Implementation of ImplIntrospectionAccess *** @@ -1433,11 +1545,14 @@ Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type || rType == cppu::UnoType<XPropertySetInfo>::get() || rType == cppu::UnoType<XElementAccess>::get() || rType == cppu::UnoType<XNameAccess>::get() + || rType == cppu::UnoType<XNameReplace>::get() || rType == cppu::UnoType<XNameContainer>::get() || rType == cppu::UnoType<XIndexAccess>::get() + || rType == cppu::UnoType<XIndexReplace>::get() || rType == cppu::UnoType<XIndexContainer>::get() || rType == cppu::UnoType<XEnumerationAccess>::get() - || rType == cppu::UnoType<XIdlArray>::get() ) + || rType == cppu::UnoType<XIdlArray>::get() + || rType == cppu::UnoType<XUnoTunnel>::get() ) { queryInterface( rType ) >>= xRet; } @@ -1971,6 +2086,14 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect( { rMethodConcept_i |= NAMECONTAINER; pAccess->mbNameContainer = true; + pAccess->mbNameReplace = true; + pAccess->mbNameAccess = true; + pAccess->mbElementAccess = true; + } else if ((className + == "com.sun.star.container.XNameReplace")) + { + rMethodConcept_i |= NAMECONTAINER; + pAccess->mbNameReplace = true; pAccess->mbNameAccess = true; pAccess->mbElementAccess = true; } else if ((className @@ -1984,6 +2107,14 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect( { rMethodConcept_i |= INDEXCONTAINER; pAccess->mbIndexContainer = true; + pAccess->mbIndexReplace = true; + pAccess->mbIndexAccess = true; + pAccess->mbElementAccess = true; + } else if ((className + == "com.sun.star.container.XIndexReplace")) + { + rMethodConcept_i |= INDEXCONTAINER; + pAccess->mbIndexReplace = true; pAccess->mbIndexAccess = true; pAccess->mbElementAccess = true; } else if ((className @@ -2002,6 +2133,10 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect( == "com.sun.star.reflection.XIdlArray") { pAccess->mbIdlArray = true; + } else if (className + == "com.sun.star.lang.XUnoTunnel") + { + pAccess->mbUnoTunnel = true; } // If the name is too short, it isn't anything diff --git a/stoc/source/invocation/invocation.cxx b/stoc/source/invocation/invocation.cxx index 7671471682b2..751901f14104 100644 --- a/stoc/source/invocation/invocation.cxx +++ b/stoc/source/invocation/invocation.cxx @@ -150,14 +150,15 @@ public: throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE { _xNameContainer->insertByName( Name, Element ); } - virtual void SAL_CALL replaceByName( const OUString& Name, const Any& Element ) - throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE - { _xNameContainer->replaceByName( Name, Element ); } - virtual void SAL_CALL removeByName( const OUString& Name ) throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE { _xNameContainer->removeByName( Name ); } + // XNameReplace + virtual void SAL_CALL replaceByName( const OUString& Name, const Any& Element ) + throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE + { _xNameReplace->replaceByName( Name, Element ); } + // XNameAccess virtual Any SAL_CALL getByName( const OUString& Name ) throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE @@ -174,14 +175,15 @@ public: throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE { _xIndexContainer->insertByIndex( Index, Element ); } - virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element ) - throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE - { _xIndexContainer->replaceByIndex( Index, Element ); } - virtual void SAL_CALL removeByIndex( sal_Int32 Index ) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE { _xIndexContainer->removeByIndex( Index ); } + // XIndexReplace + virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element ) + throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE + { _xIndexReplace->replaceByIndex( Index, Element ); } + // XIndexAccess virtual sal_Int32 SAL_CALL getCount() throw( RuntimeException, std::exception ) SAL_OVERRIDE { return _xIndexAccess->getCount(); } @@ -220,8 +222,10 @@ private: // supplied Interfaces Reference<XNameContainer> _xNameContainer; + Reference<XNameReplace> _xNameReplace; Reference<XNameAccess> _xNameAccess; Reference<XIndexContainer> _xIndexContainer; + Reference<XIndexReplace> _xIndexReplace; Reference<XIndexAccess> _xIndexAccess; Reference<XEnumerationAccess> _xEnumerationAccess; Reference<XElementAccess> _xElementAccess; @@ -285,6 +289,11 @@ Any SAL_CALL Invocation_Impl::queryInterface( const Type & aType ) if( _xNameContainer.is() ) return makeAny( Reference< XNameContainer >( (static_cast< XNameContainer* >(this)) ) ); } + else if ( aType == cppu::UnoType<XNameReplace>::get()) + { + if( _xNameReplace.is() ) + return makeAny( Reference< XNameReplace >( (static_cast< XNameReplace* >(this)) ) ); + } else if ( aType == cppu::UnoType<XNameAccess>::get()) { if( _xNameAccess.is() ) @@ -295,6 +304,11 @@ Any SAL_CALL Invocation_Impl::queryInterface( const Type & aType ) if (_xIndexContainer.is()) return makeAny( Reference< XIndexContainer >( (static_cast< XIndexContainer* >(this)) ) ); } + else if ( aType == cppu::UnoType<XIndexReplace>::get()) + { + if (_xIndexReplace.is()) + return makeAny( Reference< XIndexReplace >( (static_cast< XIndexReplace* >(this)) ) ); + } else if ( aType == cppu::UnoType<XIndexAccess>::get()) { if (_xIndexAccess.is()) @@ -371,8 +385,10 @@ void Invocation_Impl::setMaterial( const Any& rMaterial ) _xElementAccess = Reference<XElementAccess>::query( _xDirect ); _xEnumerationAccess = Reference<XEnumerationAccess>::query( _xDirect ); _xIndexAccess = Reference<XIndexAccess>::query( _xDirect ); + _xIndexReplace = Reference<XIndexReplace>::query( _xDirect ); _xIndexContainer = Reference<XIndexContainer>::query( _xDirect ); _xNameAccess = Reference<XNameAccess>::query( _xDirect ); + _xNameReplace = Reference<XNameReplace>::query( _xDirect ); _xNameContainer = Reference<XNameContainer>::query( _xDirect ); _xENDirect = Reference<XExactName>::query( _xDirect ); _xDirect2 = Reference<XInvocation2>::query( _xDirect ); @@ -405,6 +421,10 @@ void Invocation_Impl::setMaterial( const Any& rMaterial ) if( _xIndexAccess.is() ) { + _xIndexReplace = Reference<XIndexReplace>::query( + _xIntrospectionAccess->queryAdapter( + cppu::UnoType<XIndexReplace>::get()) ); + _xIndexContainer = Reference<XIndexContainer>::query( _xIntrospectionAccess->queryAdapter( cppu::UnoType<XIndexContainer>::get()) ); @@ -416,6 +436,10 @@ void Invocation_Impl::setMaterial( const Any& rMaterial ) if( _xNameAccess.is() ) { + _xNameReplace = Reference<XNameReplace>::query( + _xIntrospectionAccess->queryAdapter( + cppu::UnoType<XNameReplace>::get()) ); + _xNameContainer = Reference<XNameContainer>::query( _xIntrospectionAccess->queryAdapter( cppu::UnoType<XNameContainer>::get()) ); @@ -559,6 +583,8 @@ void Invocation_Impl::setValue( const OUString& PropertyName, const Any& Value ) // NameContainer else if( _xNameContainer.is() ) { + // Note: This misfeature deliberately not adapted to apply to objects which + // have XNameReplace but not XNameContainer Any aConv; Reference < XIdlClass > r = TypeToIdlClass( _xNameContainer->getElementType(), xCoreReflection ); @@ -1002,6 +1028,10 @@ Sequence< Type > SAL_CALL Invocation_Impl::getTypes() throw( RuntimeException, s { pTypes[ n++ ] = cppu::UnoType<XNameContainer>::get(); } + if( _xNameReplace.is() ) + { + pTypes[ n++ ] = cppu::UnoType<XNameReplace>::get(); + } if( _xNameAccess.is() ) { pTypes[ n++ ] = cppu::UnoType<XNameAccess>::get(); @@ -1010,6 +1040,10 @@ Sequence< Type > SAL_CALL Invocation_Impl::getTypes() throw( RuntimeException, s { pTypes[ n++ ] = cppu::UnoType<XIndexContainer>::get(); } + if (_xIndexReplace.is()) + { + pTypes[ n++ ] = cppu::UnoType<XIndexReplace>::get(); + } if (_xIndexAccess.is()) { pTypes[ n++ ] = cppu::UnoType<XIndexAccess>::get(); |