1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pyuno_callable.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include "pyuno_impl.hxx"
32 #include <osl/thread.h>
33 #include <rtl/ustrbuf.hxx>
35 using rtl::OUStringToOString
;
37 using com::sun::star::uno::Sequence
;
38 using com::sun::star::uno::Reference
;
39 using com::sun::star::uno::XInterface
;
40 using com::sun::star::uno::Any
;
41 using com::sun::star::uno::Type
;
42 using com::sun::star::uno::TypeClass
;
43 using com::sun::star::uno::RuntimeException
;
44 using com::sun::star::uno::XComponentContext
;
45 using com::sun::star::lang::XSingleServiceFactory
;
46 using com::sun::star::script::XTypeConverter
;
47 using com::sun::star::script::XInvocation2
;
53 Reference
<XInvocation2
> xInvocation
;
54 Reference
<XSingleServiceFactory
> xInvocationFactory
;
55 Reference
<XTypeConverter
> xTypeConverter
;
58 } PyUNO_callable_Internals
;
63 PyUNO_callable_Internals
* members
;
66 void PyUNO_callable_del (PyObject
* self
)
70 me
= (PyUNO_callable
*) self
;
77 PyObject
* PyUNO_callable_call (PyObject
* self
, PyObject
* args
, PyObject
*)
81 Sequence
<short> aOutParamIndex
;
82 Sequence
<Any
> aOutParam
;
83 Sequence
<Any
> aParams
;
84 Sequence
<Type
> aParamTypes
;
88 RuntimeCargo
*cargo
= 0;
89 me
= (PyUNO_callable
*) self
;
95 cargo
= runtime
.getImpl()->cargo
;
96 any_params
= runtime
.pyObject2Any (args
, me
->members
->mode
);
98 if (any_params
.getValueTypeClass () == com::sun::star::uno::TypeClass_SEQUENCE
)
100 any_params
>>= aParams
;
105 aParams
[0] <<= any_params
;
109 PyThreadDetach antiguard
; //pyhton free zone
111 // do some logging if desired ...
112 if( isLog( cargo
, LogLevel::CALL
) )
114 logCall( cargo
, "try py->uno[0x", me
->members
->xInvocation
.get(),
115 me
->members
->methodName
, aParams
);
119 ret_value
= me
->members
->xInvocation
->invoke (
120 me
->members
->methodName
, aParams
, aOutParamIndex
, aOutParam
);
122 // log the reply, if desired
123 if( isLog( cargo
, LogLevel::CALL
) )
125 logReply( cargo
, "success py->uno[0x", me
->members
->xInvocation
.get(),
126 me
->members
->methodName
, ret_value
, aOutParam
);
131 PyRef temp
= runtime
.any2PyObject (ret_value
);
132 if( aOutParam
.getLength() )
134 PyRef
return_list( PyTuple_New (1+aOutParam
.getLength()), SAL_NO_ACQUIRE
);
135 PyTuple_SetItem (return_list
.get(), 0, temp
.getAcquired());
137 // initialize with defaults in case of exceptions
139 for( i
= 1 ; i
< 1+aOutParam
.getLength() ; i
++ )
141 Py_INCREF( Py_None
);
142 PyTuple_SetItem( return_list
.get() , i
, Py_None
);
145 for( i
= 0 ; i
< aOutParam
.getLength() ; i
++ )
147 PyRef ref
= runtime
.any2PyObject( aOutParam
[i
] );
148 PyTuple_SetItem (return_list
.get(), 1+i
, ref
.getAcquired());
157 catch( com::sun::star::reflection::InvocationTargetException
& e
)
160 if( isLog( cargo
, LogLevel::CALL
) )
162 logException( cargo
, "except py->uno[0x", me
->members
->xInvocation
.get() ,
163 me
->members
->methodName
, e
.TargetException
.getValue(), e
.TargetException
.getValueTypeRef());
165 raisePyExceptionWithAny( e
.TargetException
);
167 catch( com::sun::star::script::CannotConvertException
&e
)
169 if( isLog( cargo
, LogLevel::CALL
) )
171 logException( cargo
, "error py->uno[0x", me
->members
->xInvocation
.get() ,
172 me
->members
->methodName
, &e
, getCppuType(&e
).getTypeLibType());
174 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e
) );
176 catch( com::sun::star::lang::IllegalArgumentException
&e
)
178 if( isLog( cargo
, LogLevel::CALL
) )
180 logException( cargo
, "error py->uno[0x", me
->members
->xInvocation
.get() ,
181 me
->members
->methodName
, &e
, getCppuType(&e
).getTypeLibType());
183 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e
) );
185 catch (::com::sun::star::uno::RuntimeException
&e
)
187 if( cargo
&& isLog( cargo
, LogLevel::CALL
) )
189 logException( cargo
, "error py->uno[0x", me
->members
->xInvocation
.get() ,
190 me
->members
->methodName
, &e
, getCppuType(&e
).getTypeLibType());
192 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e
) );
195 return ret
.getAcquired();
199 static PyTypeObject PyUNO_callable_Type
=
201 PyObject_HEAD_INIT (&PyType_Type
)
203 const_cast< char * >("PyUNO_callable"),
204 sizeof (PyUNO_callable
),
206 (destructor
) ::pyuno::PyUNO_callable_del
,
216 (ternaryfunc
) ::pyuno::PyUNO_callable_call
,
248 #if PY_VERSION_HEX >= 0x02060000
253 PyRef
PyUNO_callable_new (
254 const Reference
<XInvocation2
> &my_inv
,
255 const OUString
& methodName
,
256 const Reference
<XSingleServiceFactory
> &xInvocationFactory
,
257 const Reference
<XTypeConverter
> &tc
,
258 enum ConversionMode mode
)
260 PyUNO_callable
* self
;
262 self
= PyObject_New (PyUNO_callable
, &PyUNO_callable_Type
);
264 return NULL
; //NULL == Error!
266 self
->members
= new PyUNO_callable_Internals
;
267 self
->members
->xInvocation
= my_inv
;
268 self
->members
->methodName
= methodName
;
269 self
->members
->xInvocationFactory
= xInvocationFactory
;
270 self
->members
->xTypeConverter
= tc
;
271 self
->members
->mode
= mode
;
273 return PyRef( (PyObject
*)self
, SAL_NO_ACQUIRE
);