167c7d1c1SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
367c7d1c1SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
467c7d1c1SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
567c7d1c1SAndrew Rist  * distributed with this work for additional information
667c7d1c1SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
767c7d1c1SAndrew Rist  * to you under the Apache License, Version 2.0 (the
867c7d1c1SAndrew Rist  * "License"); you may not use this file except in compliance
967c7d1c1SAndrew Rist  * with the License.  You may obtain a copy of the License at
1067c7d1c1SAndrew Rist  *
1167c7d1c1SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1267c7d1c1SAndrew Rist  *
1367c7d1c1SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1467c7d1c1SAndrew Rist  * software distributed under the License is distributed on an
1567c7d1c1SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1667c7d1c1SAndrew Rist  * KIND, either express or implied.  See the License for the
1767c7d1c1SAndrew Rist  * specific language governing permissions and limitations
1867c7d1c1SAndrew Rist  * under the License.
1967c7d1c1SAndrew Rist  *
2067c7d1c1SAndrew Rist  *************************************************************/
2167c7d1c1SAndrew Rist 
2267c7d1c1SAndrew Rist 
23cdf0e10cSrcweir #include "pyuno_impl.hxx"
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
26cdf0e10cSrcweir #include <rtl/strbuf.hxx>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <com/sun/star/beans/MethodConcept.hpp>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <cppuhelper/typeprovider.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir using rtl::OUStringToOString;
33cdf0e10cSrcweir using rtl::OUString;
34cdf0e10cSrcweir using rtl::OUStringBuffer;
35cdf0e10cSrcweir using rtl::OString;
36cdf0e10cSrcweir using rtl::OStringBuffer;
37cdf0e10cSrcweir 
38cdf0e10cSrcweir using com::sun::star::beans::XIntrospectionAccess;
39cdf0e10cSrcweir using com::sun::star::beans::XIntrospection;
40cdf0e10cSrcweir using com::sun::star::uno::Any;
41cdf0e10cSrcweir using com::sun::star::uno::makeAny;
42cdf0e10cSrcweir using com::sun::star::uno::Reference;
43cdf0e10cSrcweir using com::sun::star::uno::Sequence;
44cdf0e10cSrcweir using com::sun::star::uno::RuntimeException;
45cdf0e10cSrcweir using com::sun::star::uno::XInterface;
46cdf0e10cSrcweir using com::sun::star::uno::Type;
47cdf0e10cSrcweir using com::sun::star::lang::XUnoTunnel;
48cdf0e10cSrcweir using com::sun::star::lang::IllegalArgumentException;
49cdf0e10cSrcweir using com::sun::star::beans::UnknownPropertyException;
50cdf0e10cSrcweir using com::sun::star::script::CannotConvertException;
51cdf0e10cSrcweir using com::sun::star::reflection::InvocationTargetException;
52cdf0e10cSrcweir using com::sun::star::reflection::XIdlMethod;
53cdf0e10cSrcweir using com::sun::star::reflection::ParamInfo;
54cdf0e10cSrcweir using com::sun::star::reflection::XIdlClass;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir #define TO_ASCII(x) OUStringToOString( x , RTL_TEXTENCODING_ASCII_US).getStr()
57cdf0e10cSrcweir 
58cdf0e10cSrcweir namespace pyuno
59cdf0e10cSrcweir {
60cdf0e10cSrcweir 
Adapter(const PyRef & ref,const Sequence<Type> & types)61cdf0e10cSrcweir Adapter::Adapter( const PyRef & ref, const Sequence< Type > &types )
62cdf0e10cSrcweir     : mWrappedObject( ref ),
63cdf0e10cSrcweir       mInterpreter( (PyThreadState_Get()->interp) ),
64cdf0e10cSrcweir       mTypes( types )
65cdf0e10cSrcweir {}
66cdf0e10cSrcweir 
~Adapter()67cdf0e10cSrcweir Adapter::~Adapter()
68cdf0e10cSrcweir {
69cdf0e10cSrcweir     // Problem: We don't know, if we have the python interpreter lock
70cdf0e10cSrcweir     //       There is no runtime function to get to know this.
71cdf0e10cSrcweir     decreaseRefCount( mInterpreter, mWrappedObject.get() );
72cdf0e10cSrcweir     mWrappedObject.scratch();
73cdf0e10cSrcweir }
74cdf0e10cSrcweir 
75cdf0e10cSrcweir static cppu::OImplementationId g_id( sal_False );
76cdf0e10cSrcweir 
getUnoTunnelImplementationId()77cdf0e10cSrcweir Sequence<sal_Int8> Adapter::getUnoTunnelImplementationId()
78cdf0e10cSrcweir {
79cdf0e10cSrcweir     return g_id.getImplementationId();
80cdf0e10cSrcweir }
81cdf0e10cSrcweir 
getSomething(const Sequence<sal_Int8> & id)82cdf0e10cSrcweir sal_Int64 Adapter::getSomething( const Sequence< sal_Int8 > &id) throw (RuntimeException)
83cdf0e10cSrcweir {
84cdf0e10cSrcweir     if( id == g_id.getImplementationId() )
85cdf0e10cSrcweir         return reinterpret_cast<sal_Int64>(this);
86cdf0e10cSrcweir     return 0;
87cdf0e10cSrcweir }
88cdf0e10cSrcweir 
raiseInvocationTargetExceptionWhenNeeded(const Runtime & runtime)89cdf0e10cSrcweir void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime )
90cdf0e10cSrcweir     throw ( InvocationTargetException )
91cdf0e10cSrcweir {
92cdf0e10cSrcweir     if( PyErr_Occurred() )
93cdf0e10cSrcweir     {
94cdf0e10cSrcweir         PyRef excType, excValue, excTraceback;
95cdf0e10cSrcweir         PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback);
96cdf0e10cSrcweir         Any unoExc( runtime.extractUnoException( excType, excValue, excTraceback ) );
97cdf0e10cSrcweir         throw InvocationTargetException(
98cdf0e10cSrcweir             ((com::sun::star::uno::Exception*)unoExc.getValue())->Message,
99cdf0e10cSrcweir             Reference<XInterface>(), unoExc );
100cdf0e10cSrcweir     }
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
getIntrospection()103cdf0e10cSrcweir Reference< XIntrospectionAccess > Adapter::getIntrospection()
104cdf0e10cSrcweir     throw ( RuntimeException )
105cdf0e10cSrcweir {
106cdf0e10cSrcweir     // not supported
107cdf0e10cSrcweir     return Reference< XIntrospectionAccess > ();
108cdf0e10cSrcweir }
109cdf0e10cSrcweir 
getOutIndexes(const OUString & functionName)110cdf0e10cSrcweir Sequence< sal_Int16 > Adapter::getOutIndexes( const OUString & functionName )
111cdf0e10cSrcweir {
112cdf0e10cSrcweir     Sequence< sal_Int16 > ret;
113cdf0e10cSrcweir     MethodOutIndexMap::const_iterator ii = m_methodOutIndexMap.find( functionName );
114cdf0e10cSrcweir     if( ii == m_methodOutIndexMap.end() )
115cdf0e10cSrcweir     {
116cdf0e10cSrcweir 
117cdf0e10cSrcweir         Runtime runtime;
118cdf0e10cSrcweir         {
119cdf0e10cSrcweir             PyThreadDetach antiguard;
120cdf0e10cSrcweir 
121cdf0e10cSrcweir             // retrieve the adapter object again. It will be the same instance as before,
122cdf0e10cSrcweir             // (the adapter factory keeps a weak map inside, which I couldn't have outside)
123cdf0e10cSrcweir             Reference< XInterface > unoAdapterObject =
124cdf0e10cSrcweir                 runtime.getImpl()->cargo->xAdapterFactory->createAdapter( this, mTypes );
125cdf0e10cSrcweir 
126cdf0e10cSrcweir             // uuuh, that's really expensive. The alternative would have been, to store
127cdf0e10cSrcweir             // an instance of the introspection at (this), but this results in a cyclic
128cdf0e10cSrcweir             // reference, which is never broken (as it is up to OOo1.1.0).
129cdf0e10cSrcweir             Reference< XIntrospectionAccess > introspection =
130cdf0e10cSrcweir                 runtime.getImpl()->cargo->xIntrospection->inspect( makeAny( unoAdapterObject ) );
131cdf0e10cSrcweir 
132cdf0e10cSrcweir             if( !introspection.is() )
133cdf0e10cSrcweir             {
134cdf0e10cSrcweir                 throw RuntimeException(
135cdf0e10cSrcweir                     OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno bridge: Couldn't inspect uno adapter ( the python class must implement com.sun.star.lang.XTypeProvider !)" ) ),
136cdf0e10cSrcweir                     Reference< XInterface > () );
137cdf0e10cSrcweir             }
138cdf0e10cSrcweir 
139cdf0e10cSrcweir             Reference< XIdlMethod > method = introspection->getMethod(
140cdf0e10cSrcweir                 functionName, com::sun::star::beans::MethodConcept::ALL );
141cdf0e10cSrcweir             if( ! method.is( ) )
142cdf0e10cSrcweir             {
143cdf0e10cSrcweir                 throw RuntimeException(
144cdf0e10cSrcweir                     (OUString(
145cdf0e10cSrcweir                         RTL_CONSTASCII_USTRINGPARAM(
146cdf0e10cSrcweir                             "pyuno bridge: Couldn't get reflection for method "))
147cdf0e10cSrcweir                      + functionName),
148cdf0e10cSrcweir                     Reference< XInterface > () );
149cdf0e10cSrcweir             }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir             Sequence< ParamInfo > seqInfo = method->getParameterInfos();
152cdf0e10cSrcweir             int i;
153cdf0e10cSrcweir             int nOuts = 0;
154cdf0e10cSrcweir             for( i = 0 ; i < seqInfo.getLength() ; i ++ )
155cdf0e10cSrcweir             {
156cdf0e10cSrcweir                 if( seqInfo[i].aMode == com::sun::star::reflection::ParamMode_OUT ||
157cdf0e10cSrcweir                     seqInfo[i].aMode == com::sun::star::reflection::ParamMode_INOUT )
158cdf0e10cSrcweir                 {
159cdf0e10cSrcweir                     // sequence must be interpreted as return value/outparameter tuple !
160cdf0e10cSrcweir                     nOuts ++;
161cdf0e10cSrcweir                 }
162cdf0e10cSrcweir             }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir             if( nOuts )
165cdf0e10cSrcweir             {
166cdf0e10cSrcweir                 ret.realloc( nOuts );
167cdf0e10cSrcweir                 sal_Int32 nOutsAssigned = 0;
168cdf0e10cSrcweir                 for( i = 0 ; i < seqInfo.getLength() ; i ++ )
169cdf0e10cSrcweir                 {
170cdf0e10cSrcweir                     if( seqInfo[i].aMode == com::sun::star::reflection::ParamMode_OUT ||
171cdf0e10cSrcweir                         seqInfo[i].aMode == com::sun::star::reflection::ParamMode_INOUT )
172cdf0e10cSrcweir                     {
173cdf0e10cSrcweir                         ret[nOutsAssigned] = (sal_Int16) i;
174cdf0e10cSrcweir                         nOutsAssigned ++;
175cdf0e10cSrcweir                     }
176cdf0e10cSrcweir                 }
177cdf0e10cSrcweir             }
178cdf0e10cSrcweir         }
179cdf0e10cSrcweir         // guard active again !
180cdf0e10cSrcweir         m_methodOutIndexMap[ functionName ] = ret;
181cdf0e10cSrcweir     }
182cdf0e10cSrcweir     else
183cdf0e10cSrcweir     {
184cdf0e10cSrcweir         ret = ii->second;
185cdf0e10cSrcweir     }
186cdf0e10cSrcweir     return ret;
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
invoke(const OUString & aFunctionName,const Sequence<Any> & aParams,Sequence<sal_Int16> & aOutParamIndex,Sequence<Any> & aOutParam)189cdf0e10cSrcweir Any Adapter::invoke( const OUString &aFunctionName,
190cdf0e10cSrcweir                      const Sequence< Any >& aParams,
191cdf0e10cSrcweir                      Sequence< sal_Int16 > &aOutParamIndex,
192cdf0e10cSrcweir                      Sequence< Any > &aOutParam)
193cdf0e10cSrcweir     throw (IllegalArgumentException,CannotConvertException,InvocationTargetException,RuntimeException)
194cdf0e10cSrcweir {
195cdf0e10cSrcweir     Any ret;
196cdf0e10cSrcweir 
197cdf0e10cSrcweir     // special hack for the uno object identity concept. The XUnoTunnel.getSomething() call is
198cdf0e10cSrcweir     // always handled by the adapter directly.
199cdf0e10cSrcweir     if( aParams.getLength() == 1 && 0 == aFunctionName.compareToAscii( "getSomething" ) )
200cdf0e10cSrcweir     {
201cdf0e10cSrcweir         Sequence< sal_Int8 > id;
202cdf0e10cSrcweir         if( aParams[0] >>= id )
203cdf0e10cSrcweir             return com::sun::star::uno::makeAny( getSomething( id ) );
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir     RuntimeCargo *cargo = 0;
208cdf0e10cSrcweir     try
209cdf0e10cSrcweir     {
210cdf0e10cSrcweir     PyThreadAttach guard( mInterpreter );
211cdf0e10cSrcweir     {
212cdf0e10cSrcweir         // convert parameters to python args
213cdf0e10cSrcweir         // TODO: Out parameter
214cdf0e10cSrcweir         Runtime runtime;
215cdf0e10cSrcweir         cargo = runtime.getImpl()->cargo;
216cdf0e10cSrcweir         if( isLog( cargo, LogLevel::CALL ) )
217cdf0e10cSrcweir         {
218cdf0e10cSrcweir             logCall( cargo, "try     uno->py[0x",
219cdf0e10cSrcweir                      mWrappedObject.get(), aFunctionName, aParams );
220cdf0e10cSrcweir         }
221cdf0e10cSrcweir 
222cdf0e10cSrcweir         sal_Int32 size = aParams.getLength();
223cdf0e10cSrcweir         PyRef argsTuple(PyTuple_New( size ), SAL_NO_ACQUIRE );
224cdf0e10cSrcweir         int i;
225cdf0e10cSrcweir         // fill tuple with default values in case of exceptions
226cdf0e10cSrcweir         for(  i = 0 ;i < size ; i ++ )
227cdf0e10cSrcweir         {
228cdf0e10cSrcweir             Py_INCREF( Py_None );
229cdf0e10cSrcweir             PyTuple_SetItem( argsTuple.get(), i, Py_None );
230cdf0e10cSrcweir         }
231cdf0e10cSrcweir 
232cdf0e10cSrcweir         // convert args to python
233cdf0e10cSrcweir         for( i = 0; i < size ; i ++  )
234cdf0e10cSrcweir         {
235cdf0e10cSrcweir             PyRef val = runtime.any2PyObject( aParams[i] );
236cdf0e10cSrcweir             PyTuple_SetItem( argsTuple.get(), i, val.getAcquired() );
237cdf0e10cSrcweir         }
238cdf0e10cSrcweir 
239cdf0e10cSrcweir         // get callable
240cdf0e10cSrcweir         PyRef method(PyObject_GetAttrString( mWrappedObject.get(), (char*)TO_ASCII(aFunctionName)),
241cdf0e10cSrcweir                      SAL_NO_ACQUIRE);
242cdf0e10cSrcweir         raiseInvocationTargetExceptionWhenNeeded( runtime);
243cdf0e10cSrcweir         if( !method.is() )
244cdf0e10cSrcweir         {
245cdf0e10cSrcweir             OUStringBuffer buf;
246cdf0e10cSrcweir             buf.appendAscii( "pyuno::Adapater: Method " ).append( aFunctionName );
247cdf0e10cSrcweir             buf.appendAscii( " is not implemented at object " );
248cdf0e10cSrcweir             PyRef str( PyObject_Repr( mWrappedObject.get() ), SAL_NO_ACQUIRE );
249*77dc4149SPedro Giffuni             buf.append( pyString2ustring( str.get() ) );
250cdf0e10cSrcweir             throw IllegalArgumentException( buf.makeStringAndClear(), Reference< XInterface > (),0 );
251cdf0e10cSrcweir         }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir         PyRef pyRet( PyObject_CallObject( method.get(), argsTuple.get() ), SAL_NO_ACQUIRE );
254cdf0e10cSrcweir         raiseInvocationTargetExceptionWhenNeeded( runtime);
255cdf0e10cSrcweir         if( pyRet.is() )
256cdf0e10cSrcweir         {
257cdf0e10cSrcweir             ret = runtime.pyObject2Any( pyRet );
258cdf0e10cSrcweir 
259cdf0e10cSrcweir             if( ret.hasValue() &&
260cdf0e10cSrcweir                 ret.getValueTypeClass() == com::sun::star::uno::TypeClass_SEQUENCE &&
261cdf0e10cSrcweir                 0 != aFunctionName.compareToAscii( "getTypes" ) &&  // needed by introspection itself !
262cdf0e10cSrcweir                 0 != aFunctionName.compareToAscii( "getImplementationId" ) ) // needed by introspection itself !
263cdf0e10cSrcweir             {
264cdf0e10cSrcweir                 // the sequence can either be
265cdf0e10cSrcweir                 // 1)  a simple sequence return value
266cdf0e10cSrcweir                 // 2)  a sequence, where the first element is the return value
267cdf0e10cSrcweir                 //     and the following elements are interpreted as the outparameter
268cdf0e10cSrcweir                 // I can only decide for one solution by checking the method signature,
269cdf0e10cSrcweir                 // so I need the reflection of the adapter !
270cdf0e10cSrcweir                 aOutParamIndex = getOutIndexes( aFunctionName );
271cdf0e10cSrcweir                 if( aOutParamIndex.getLength() )
272cdf0e10cSrcweir                 {
273cdf0e10cSrcweir                     // out parameters exist, extract the sequence
274cdf0e10cSrcweir                     Sequence< Any  > seq;
275cdf0e10cSrcweir                     if( ! ( ret >>= seq ) )
276cdf0e10cSrcweir                     {
277cdf0e10cSrcweir                         throw RuntimeException(
278cdf0e10cSrcweir                             (OUString(
279cdf0e10cSrcweir                                 RTL_CONSTASCII_USTRINGPARAM(
280cdf0e10cSrcweir                                     "pyuno bridge: Couldn't extract out"
281cdf0e10cSrcweir                                     " parameters for method "))
282cdf0e10cSrcweir                              + aFunctionName),
283cdf0e10cSrcweir                             Reference< XInterface > () );
284cdf0e10cSrcweir                     }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir                     if( aOutParamIndex.getLength() +1 != seq.getLength() )
287cdf0e10cSrcweir                     {
288cdf0e10cSrcweir                         OUStringBuffer buf;
289cdf0e10cSrcweir                         buf.appendAscii( "pyuno bridge: expected for method " );
290cdf0e10cSrcweir                         buf.append( aFunctionName );
291cdf0e10cSrcweir                         buf.appendAscii( " one return value and " );
292cdf0e10cSrcweir                         buf.append( (sal_Int32) aOutParamIndex.getLength() );
293cdf0e10cSrcweir                         buf.appendAscii( " out parameters, got a sequence of " );
294cdf0e10cSrcweir                         buf.append( seq.getLength() );
295cdf0e10cSrcweir                         buf.appendAscii( " elements as return value." );
296cdf0e10cSrcweir                         throw RuntimeException(buf.makeStringAndClear(), *this );
297cdf0e10cSrcweir                     }
298cdf0e10cSrcweir 
299cdf0e10cSrcweir                     aOutParam.realloc( aOutParamIndex.getLength() );
300cdf0e10cSrcweir                     ret = seq[0];
301cdf0e10cSrcweir                     for( i = 0 ; i < aOutParamIndex.getLength() ; i ++ )
302cdf0e10cSrcweir                     {
303cdf0e10cSrcweir                         aOutParam[i] = seq[1+i];
304cdf0e10cSrcweir                     }
305cdf0e10cSrcweir                 }
306cdf0e10cSrcweir                 // else { sequence is a return value !}
307cdf0e10cSrcweir             }
308cdf0e10cSrcweir         }
309cdf0e10cSrcweir 
310cdf0e10cSrcweir         // log the reply, if desired
311cdf0e10cSrcweir         if( isLog( cargo, LogLevel::CALL ) )
312cdf0e10cSrcweir         {
313cdf0e10cSrcweir             logReply( cargo, "success uno->py[0x" ,
314cdf0e10cSrcweir                       mWrappedObject.get(), aFunctionName, ret, aOutParam );
315cdf0e10cSrcweir         }
316cdf0e10cSrcweir     }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir     }
319cdf0e10cSrcweir     catch(InvocationTargetException & e )
320cdf0e10cSrcweir     {
321cdf0e10cSrcweir         if( isLog( cargo, LogLevel::CALL ) )
322cdf0e10cSrcweir         {
323cdf0e10cSrcweir             logException(
324cdf0e10cSrcweir                 cargo, "except  uno->py[0x" ,
325cdf0e10cSrcweir                 mWrappedObject.get(), aFunctionName,
326cdf0e10cSrcweir                 e.TargetException.getValue(),e.TargetException.getValueType() );
327cdf0e10cSrcweir         }
328cdf0e10cSrcweir         throw;
329cdf0e10cSrcweir     }
330cdf0e10cSrcweir     catch( RuntimeException & e )
331cdf0e10cSrcweir     {
332cdf0e10cSrcweir         if( cargo && isLog( cargo, LogLevel::CALL ) )
333cdf0e10cSrcweir         {
334cdf0e10cSrcweir             logException(
335cdf0e10cSrcweir                 cargo, "except  uno->py[0x" ,
336cdf0e10cSrcweir                 mWrappedObject.get(), aFunctionName, &e,getCppuType(&e) );
337cdf0e10cSrcweir         }
338cdf0e10cSrcweir         throw;
339cdf0e10cSrcweir     }
340cdf0e10cSrcweir     catch( CannotConvertException & e )
341cdf0e10cSrcweir     {
342cdf0e10cSrcweir         if( isLog( cargo, LogLevel::CALL ) )
343cdf0e10cSrcweir         {
344cdf0e10cSrcweir             logException(
345cdf0e10cSrcweir                 cargo, "except  uno->py[0x" ,
346cdf0e10cSrcweir                 mWrappedObject.get(), aFunctionName, &e,getCppuType(&e) );
347cdf0e10cSrcweir         }
348cdf0e10cSrcweir         throw;
349cdf0e10cSrcweir     }
350cdf0e10cSrcweir     catch(  IllegalArgumentException & e )
351cdf0e10cSrcweir     {
352cdf0e10cSrcweir         if( isLog( cargo, LogLevel::CALL ) )
353cdf0e10cSrcweir         {
354cdf0e10cSrcweir             logException(
355cdf0e10cSrcweir                 cargo,  "except  uno->py[0x" ,
356cdf0e10cSrcweir                 mWrappedObject.get(), aFunctionName, &e,getCppuType(&e) );
357cdf0e10cSrcweir         }
358cdf0e10cSrcweir         throw;
359cdf0e10cSrcweir     }
360cdf0e10cSrcweir     return ret;
361cdf0e10cSrcweir }
362cdf0e10cSrcweir 
setValue(const OUString & aPropertyName,const Any & value)363cdf0e10cSrcweir void Adapter::setValue( const OUString & aPropertyName, const Any & value )
364cdf0e10cSrcweir     throw( UnknownPropertyException, CannotConvertException, InvocationTargetException,RuntimeException)
365cdf0e10cSrcweir {
3665731f97eSAriel Constenla-Haile     if( !hasProperty( aPropertyName ) )
3675731f97eSAriel Constenla-Haile     {
3685731f97eSAriel Constenla-Haile         OUStringBuffer buf;
3695731f97eSAriel Constenla-Haile         buf.appendAscii( "pyuno::Adapater: Property " ).append( aPropertyName );
3705731f97eSAriel Constenla-Haile         buf.appendAscii( " is unknown." );
3715731f97eSAriel Constenla-Haile         throw UnknownPropertyException( buf.makeStringAndClear(), Reference< XInterface > () );
3725731f97eSAriel Constenla-Haile     }
3735731f97eSAriel Constenla-Haile 
374cdf0e10cSrcweir     PyThreadAttach guard( mInterpreter );
375cdf0e10cSrcweir     try
376cdf0e10cSrcweir     {
377cdf0e10cSrcweir         Runtime runtime;
378cdf0e10cSrcweir         PyRef obj = runtime.any2PyObject( value );
379cdf0e10cSrcweir 
380cdf0e10cSrcweir         PyObject_SetAttrString(
381cdf0e10cSrcweir             mWrappedObject.get(), (char*)TO_ASCII(aPropertyName), obj.get() );
382cdf0e10cSrcweir         raiseInvocationTargetExceptionWhenNeeded( runtime);
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     }
385cdf0e10cSrcweir     catch( IllegalArgumentException & exc )
386cdf0e10cSrcweir     {
387cdf0e10cSrcweir         throw InvocationTargetException( exc.Message, *this, com::sun::star::uno::makeAny( exc ) );
388cdf0e10cSrcweir     }
389cdf0e10cSrcweir }
390cdf0e10cSrcweir 
getValue(const OUString & aPropertyName)391cdf0e10cSrcweir Any Adapter::getValue( const OUString & aPropertyName )
392cdf0e10cSrcweir     throw ( UnknownPropertyException, RuntimeException )
393cdf0e10cSrcweir {
394cdf0e10cSrcweir     Any ret;
395cdf0e10cSrcweir     PyThreadAttach guard( mInterpreter );
396cdf0e10cSrcweir     {
397cdf0e10cSrcweir         Runtime runtime;
398cdf0e10cSrcweir         PyRef pyRef(
399cdf0e10cSrcweir             PyObject_GetAttrString( mWrappedObject.get(), (char*)TO_ASCII(aPropertyName) ),
400cdf0e10cSrcweir             SAL_NO_ACQUIRE );
401cdf0e10cSrcweir 
402cdf0e10cSrcweir         raiseInvocationTargetExceptionWhenNeeded( runtime);
403cdf0e10cSrcweir         if( !pyRef.is() )
404cdf0e10cSrcweir         {
405cdf0e10cSrcweir             OUStringBuffer buf;
406cdf0e10cSrcweir             buf.appendAscii( "pyuno::Adapater: Property " ).append( aPropertyName );
407cdf0e10cSrcweir             buf.appendAscii( " is unknown." );
408cdf0e10cSrcweir             throw UnknownPropertyException( buf.makeStringAndClear(), Reference< XInterface > () );
409cdf0e10cSrcweir         }
410cdf0e10cSrcweir         ret = runtime.pyObject2Any( pyRef );
411cdf0e10cSrcweir     }
412cdf0e10cSrcweir     return ret;
413cdf0e10cSrcweir }
414cdf0e10cSrcweir 
hasMethod(const OUString & aMethodName)415cdf0e10cSrcweir sal_Bool Adapter::hasMethod( const OUString & aMethodName )
416cdf0e10cSrcweir     throw ( RuntimeException )
417cdf0e10cSrcweir {
418cdf0e10cSrcweir     return hasProperty( aMethodName );
419cdf0e10cSrcweir }
420cdf0e10cSrcweir 
hasProperty(const OUString & aPropertyName)421cdf0e10cSrcweir sal_Bool Adapter::hasProperty( const OUString & aPropertyName )
422cdf0e10cSrcweir     throw ( RuntimeException )
423cdf0e10cSrcweir {
424cdf0e10cSrcweir     bool bRet = false;
425cdf0e10cSrcweir     PyThreadAttach guard( mInterpreter );
426cdf0e10cSrcweir     {
427cdf0e10cSrcweir         bRet = PyObject_HasAttrString(
428cdf0e10cSrcweir             mWrappedObject.get() , (char*) TO_ASCII( aPropertyName ));
429cdf0e10cSrcweir     }
430cdf0e10cSrcweir     return bRet;
431cdf0e10cSrcweir }
432cdf0e10cSrcweir 
433cdf0e10cSrcweir }
434