1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 #include "pyuno_impl.hxx" 28 29 #include <osl/thread.h> 30 #include <rtl/ustrbuf.hxx> 31 32 using rtl::OUStringToOString; 33 using rtl::OUString; 34 using com::sun::star::uno::Sequence; 35 using com::sun::star::uno::Reference; 36 using com::sun::star::uno::XInterface; 37 using com::sun::star::uno::Any; 38 using com::sun::star::uno::Type; 39 using com::sun::star::uno::TypeClass; 40 using com::sun::star::uno::RuntimeException; 41 using com::sun::star::uno::XComponentContext; 42 using com::sun::star::lang::XSingleServiceFactory; 43 using com::sun::star::script::XTypeConverter; 44 using com::sun::star::script::XInvocation2; 45 46 namespace pyuno 47 { 48 typedef struct 49 { 50 Reference<XInvocation2> xInvocation; 51 Reference<XSingleServiceFactory> xInvocationFactory; 52 Reference<XTypeConverter> xTypeConverter; 53 OUString methodName; 54 ConversionMode mode; 55 } PyUNO_callable_Internals; 56 57 typedef struct 58 { 59 PyObject_HEAD 60 PyUNO_callable_Internals* members; 61 } PyUNO_callable; 62 63 void PyUNO_callable_del (PyObject* self) 64 { 65 PyUNO_callable* me; 66 67 me = (PyUNO_callable*) self; 68 delete me->members; 69 PyObject_Del (self); 70 71 return; 72 } 73 74 PyObject* PyUNO_callable_call (PyObject* self, PyObject* args, PyObject*) 75 { 76 PyUNO_callable* me; 77 78 Sequence<short> aOutParamIndex; 79 Sequence<Any> aOutParam; 80 Sequence<Any> aParams; 81 Sequence<Type> aParamTypes; 82 Any any_params; 83 Any out_params; 84 Any ret_value; 85 RuntimeCargo *cargo = 0; 86 me = (PyUNO_callable*) self; 87 88 PyRef ret; 89 try 90 { 91 Runtime runtime; 92 cargo = runtime.getImpl()->cargo; 93 any_params = runtime.pyObject2Any (args, me->members->mode); 94 95 if (any_params.getValueTypeClass () == com::sun::star::uno::TypeClass_SEQUENCE) 96 { 97 any_params >>= aParams; 98 } 99 else 100 { 101 aParams.realloc (1); 102 aParams [0] <<= any_params; 103 } 104 105 { 106 PyThreadDetach antiguard; //pyhton free zone 107 108 // do some logging if desired ... 109 if( isLog( cargo, LogLevel::CALL ) ) 110 { 111 logCall( cargo, "try py->uno[0x", me->members->xInvocation.get(), 112 me->members->methodName, aParams ); 113 } 114 115 // do the call 116 ret_value = me->members->xInvocation->invoke ( 117 me->members->methodName, aParams, aOutParamIndex, aOutParam); 118 119 // log the reply, if desired 120 if( isLog( cargo, LogLevel::CALL ) ) 121 { 122 logReply( cargo, "success py->uno[0x", me->members->xInvocation.get(), 123 me->members->methodName, ret_value, aOutParam); 124 } 125 } 126 127 128 PyRef temp = runtime.any2PyObject (ret_value); 129 if( aOutParam.getLength() ) 130 { 131 PyRef return_list( PyTuple_New (1+aOutParam.getLength()), SAL_NO_ACQUIRE ); 132 PyTuple_SetItem (return_list.get(), 0, temp.getAcquired()); 133 134 // initialize with defaults in case of exceptions 135 int i; 136 for( i = 1 ; i < 1+aOutParam.getLength() ; i ++ ) 137 { 138 Py_INCREF( Py_None ); 139 PyTuple_SetItem( return_list.get() , i , Py_None ); 140 } 141 142 for( i = 0 ; i < aOutParam.getLength() ; i ++ ) 143 { 144 PyRef ref = runtime.any2PyObject( aOutParam[i] ); 145 PyTuple_SetItem (return_list.get(), 1+i, ref.getAcquired()); 146 } 147 ret = return_list; 148 } 149 else 150 { 151 ret = temp; 152 } 153 } 154 catch( com::sun::star::reflection::InvocationTargetException & e ) 155 { 156 157 if( isLog( cargo, LogLevel::CALL ) ) 158 { 159 logException( cargo, "except py->uno[0x", me->members->xInvocation.get() , 160 me->members->methodName, e.TargetException.getValue(), e.TargetException.getValueTypeRef()); 161 } 162 raisePyExceptionWithAny( e.TargetException ); 163 } 164 catch( com::sun::star::script::CannotConvertException &e ) 165 { 166 if( isLog( cargo, LogLevel::CALL ) ) 167 { 168 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() , 169 me->members->methodName, &e, getCppuType(&e).getTypeLibType()); 170 } 171 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); 172 } 173 catch( com::sun::star::lang::IllegalArgumentException &e ) 174 { 175 if( isLog( cargo, LogLevel::CALL ) ) 176 { 177 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() , 178 me->members->methodName, &e, getCppuType(&e).getTypeLibType()); 179 } 180 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); 181 } 182 catch (::com::sun::star::uno::RuntimeException &e) 183 { 184 if( cargo && isLog( cargo, LogLevel::CALL ) ) 185 { 186 logException( cargo, "error py->uno[0x", me->members->xInvocation.get() , 187 me->members->methodName, &e, getCppuType(&e).getTypeLibType()); 188 } 189 raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) ); 190 } 191 192 return ret.getAcquired(); 193 } 194 195 196 static PyTypeObject PyUNO_callable_Type = 197 { 198 PyObject_HEAD_INIT (&PyType_Type) 199 0, 200 const_cast< char * >("PyUNO_callable"), 201 sizeof (PyUNO_callable), 202 0, 203 (destructor) ::pyuno::PyUNO_callable_del, 204 (printfunc) 0, 205 (getattrfunc) 0, 206 (setattrfunc) 0, 207 (cmpfunc) 0, 208 (reprfunc) 0, 209 0, 210 0, 211 0, 212 (hashfunc) 0, 213 (ternaryfunc) ::pyuno::PyUNO_callable_call, 214 (reprfunc) 0, 215 (getattrofunc)0, 216 (setattrofunc)0, 217 NULL, 218 0, 219 NULL, 220 (traverseproc)0, 221 (inquiry)0, 222 (richcmpfunc)0, 223 0, 224 (getiterfunc)0, 225 (iternextfunc)0, 226 NULL, 227 NULL, 228 NULL, 229 NULL, 230 NULL, 231 (descrgetfunc)0, 232 (descrsetfunc)0, 233 0, 234 (initproc)0, 235 (allocfunc)0, 236 (newfunc)0, 237 (freefunc)0, 238 (inquiry)0, 239 NULL, 240 NULL, 241 NULL, 242 NULL, 243 NULL, 244 (destructor)0 245 #if PY_VERSION_HEX >= 0x02060000 246 , 0 247 #endif 248 }; 249 250 PyRef PyUNO_callable_new ( 251 const Reference<XInvocation2> &my_inv, 252 const OUString & methodName, 253 const Reference<XSingleServiceFactory> &xInvocationFactory, 254 const Reference<XTypeConverter> &tc, 255 enum ConversionMode mode ) 256 { 257 PyUNO_callable* self; 258 259 self = PyObject_New (PyUNO_callable, &PyUNO_callable_Type); 260 if (self == NULL) 261 return NULL; //NULL == Error! 262 263 self->members = new PyUNO_callable_Internals; 264 self->members->xInvocation = my_inv; 265 self->members->methodName = methodName; 266 self->members->xInvocationFactory = xInvocationFactory; 267 self->members->xTypeConverter = tc; 268 self->members->mode = mode; 269 270 return PyRef( (PyObject*)self, SAL_NO_ACQUIRE ); 271 } 272 273 } 274