[Libreoffice-commits] core.git: pyuno/source stoc/source
Matthew J. Francis
mjay.francis at gmail.com
Mon Jul 27 00:41:07 PDT 2015
pyuno/source/module/pyuno.cxx | 95 +++++++---------
pyuno/source/module/pyuno_adapter.cxx | 27 ++++
pyuno/source/module/pyuno_impl.hxx | 9 -
pyuno/source/module/pyuno_module.cxx | 4
pyuno/source/module/pyuno_runtime.cxx | 22 +--
stoc/source/inspect/introspection.cxx | 193 ++++++++++++++++++++++++++++------
stoc/source/invocation/invocation.cxx | 50 +++++++-
7 files changed, 288 insertions(+), 112 deletions(-)
New commits:
commit 9c5a217681935d661aad4d5667a775319382d22a
Author: Matthew J. Francis <mjay.francis at gmail.com>
Date: Thu Jul 23 11:36:38 2015 +0800
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 at gmail.com>
Tested-by: Matthew Francis <mjay.francis at gmail.com>
diff --git a/pyuno/source/module/pyuno.cxx b/pyuno/source/module/pyuno.cxx
index f068961..ccab344 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 1fbfcba..ce4995d 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 11fbfa2..669386f 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 722e922..7d282c2 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 cda8e8b..f14b84b 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 cd621b8..98a18c0 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 7671471..751901f 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();
More information about the Libreoffice-commits
mailing list