Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / pyuno / source / module / pyuno_except.cxx
blobcf02bd007534358122dd91a2c91f1e5dcee446b4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include "pyuno_impl.hxx"
21 #include <rtl/ustrbuf.hxx>
23 #include <typelib/typedescription.hxx>
26 using com::sun::star::uno::RuntimeException;
27 using com::sun::star::uno::Sequence;
28 using com::sun::star::uno::Type;
29 using com::sun::star::uno::Reference;
30 using com::sun::star::uno::XInterface;
31 using com::sun::star::uno::TypeDescription;
33 namespace pyuno
36 void raisePyExceptionWithAny( const com::sun::star::uno::Any &anyExc )
38 try
40 Runtime runtime;
41 PyRef exc = runtime.any2PyObject( anyExc );
42 if( exc.is() )
44 PyRef type( getClass( anyExc.getValueType().getTypeName(),runtime ) );
45 PyErr_SetObject( type.get(), exc.get());
47 else
49 com::sun::star::uno::Exception e;
50 anyExc >>= e;
52 OUStringBuffer buf;
53 buf.appendAscii( "Couldn't convert uno exception to a python exception (" );
54 buf.append(anyExc.getValueType().getTypeName());
55 buf.appendAscii( ": " );
56 buf.append(e.Message );
57 buf.appendAscii( ")" );
58 PyErr_SetString(
59 PyExc_SystemError,
60 OUStringToOString(buf.makeStringAndClear(),RTL_TEXTENCODING_ASCII_US).getStr() );
63 catch(const com::sun::star::lang::IllegalArgumentException & e)
65 PyErr_SetString( PyExc_SystemError,
66 OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US).getStr() );
68 catch(const com::sun::star::script::CannotConvertException & e)
70 PyErr_SetString( PyExc_SystemError,
71 OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US).getStr() );
73 catch(const RuntimeException & e)
75 PyErr_SetString( PyExc_SystemError,
76 OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US).getStr() );
81 static PyRef createClass( const OUString & name, const Runtime &runtime )
82 throw ( RuntimeException )
84 // assuming that this is never deleted !
85 // note I don't have the knowledge how to initialize these type objects correctly !
86 TypeDescription desc( name );
87 if( ! desc.is() )
89 OUStringBuffer buf;
90 buf.appendAscii( "pyuno.getClass: uno exception " );
91 buf.append(name).appendAscii( " is unknown" );
92 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
95 sal_Bool isStruct = desc.get()->eTypeClass == typelib_TypeClass_STRUCT;
96 sal_Bool isExc = desc.get()->eTypeClass == typelib_TypeClass_EXCEPTION;
97 sal_Bool isInterface = desc.get()->eTypeClass == typelib_TypeClass_INTERFACE;
98 if( !isStruct && !isExc && ! isInterface )
100 OUStringBuffer buf;
101 buf.appendAscii( "pyuno.getClass: " ).append(name).appendAscii( "is a " );
102 buf.appendAscii(
103 typeClassToString( (com::sun::star::uno::TypeClass) desc.get()->eTypeClass));
104 buf.appendAscii( ", expected EXCEPTION, STRUCT or INTERFACE" );
105 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface>() );
108 // retrieve base class
109 PyRef base;
110 if( isInterface )
112 typelib_InterfaceTypeDescription *pDesc = (typelib_InterfaceTypeDescription * )desc.get();
113 if( pDesc->pBaseTypeDescription )
115 base = getClass( pDesc->pBaseTypeDescription->aBase.pTypeName, runtime );
117 else
119 // must be XInterface !
122 else
124 typelib_CompoundTypeDescription *pDesc = (typelib_CompoundTypeDescription*)desc.get();
125 if( pDesc->pBaseTypeDescription )
127 base = getClass( pDesc->pBaseTypeDescription->aBase.pTypeName, runtime );
129 else
131 if( isExc )
132 // we are currently creating the root UNO exception
133 base = PyRef(PyExc_Exception);
136 PyRef args( PyTuple_New( 3 ), SAL_NO_ACQUIRE );
138 PyRef pyTypeName = ustring2PyString( name /*.replace( '.', '_' )*/ );
140 PyRef bases;
141 if( base.is() )
143 { // for CC, keeping ref-count being 1
144 bases = PyRef( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
146 PyTuple_SetItem( bases.get(), 0 , base.getAcquired() );
148 else
150 bases = PyRef( PyTuple_New( 0 ), SAL_NO_ACQUIRE );
153 PyTuple_SetItem( args.get(), 0, pyTypeName.getAcquired());
154 PyTuple_SetItem( args.get(), 1, bases.getAcquired() );
155 PyTuple_SetItem( args.get(), 2, PyDict_New() );
157 PyRef ret(
158 PyObject_CallObject(reinterpret_cast<PyObject *>(&PyType_Type) , args.get()),
159 SAL_NO_ACQUIRE );
161 // now overwrite ctor and attrib functions
162 if( isInterface )
164 PyObject_SetAttrString(
165 ret.get(), "__pyunointerface__",
166 ustring2PyString(name).get() );
168 else
170 PyRef ctor = getObjectFromUnoModule( runtime,"_uno_struct__init__" );
171 PyRef setter = getObjectFromUnoModule( runtime,"_uno_struct__setattr__" );
172 PyRef getter = getObjectFromUnoModule( runtime,"_uno_struct__getattr__" );
173 PyRef repr = getObjectFromUnoModule( runtime,"_uno_struct__repr__" );
174 PyRef eq = getObjectFromUnoModule( runtime,"_uno_struct__eq__" );
176 PyObject_SetAttrString(
177 ret.get(), "__pyunostruct__",
178 ustring2PyString(name).get() );
179 PyObject_SetAttrString(
180 ret.get(), "typeName",
181 ustring2PyString(name).get() );
182 PyObject_SetAttrString(
183 ret.get(), "__init__", ctor.get() );
184 PyObject_SetAttrString(
185 ret.get(), "__getattr__", getter.get() );
186 PyObject_SetAttrString(
187 ret.get(), "__setattr__", setter.get() );
188 PyObject_SetAttrString(
189 ret.get(), "__repr__", repr.get() );
190 PyObject_SetAttrString(
191 ret.get(), "__str__", repr.get() );
192 PyObject_SetAttrString(
193 ret.get(), "__eq__", eq.get() );
195 return ret;
198 bool isInstanceOfStructOrException( PyObject *obj)
200 PyRef attr(
201 PyObject_GetAttrString(obj, "__class__"),
202 SAL_NO_ACQUIRE );
203 if(attr.is())
204 return PyObject_HasAttrString(attr.get(), "__pyunostruct__");
205 else
206 return false;
209 sal_Bool isInterfaceClass( const Runtime &runtime, PyObject * obj )
211 const ClassSet & set = runtime.getImpl()->cargo->interfaceSet;
212 return set.find( obj ) != set.end();
215 PyRef getClass( const OUString & name , const Runtime &runtime)
217 PyRef ret;
219 RuntimeCargo *cargo =runtime.getImpl()->cargo;
220 ExceptionClassMap::iterator ii = cargo->exceptionMap.find( name );
221 if( ii == cargo->exceptionMap.end() )
223 ret = createClass( name, runtime );
224 cargo->exceptionMap[name] = ret;
225 if( PyObject_HasAttrString(
226 ret.get(), "__pyunointerface__" ) )
227 cargo->interfaceSet.insert( ret );
229 PyObject_SetAttrString(
230 ret.get(), "__pyunointerface__",
231 ustring2PyString(name).get() );
233 else
235 ret = ii->second;
238 return ret;
244 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */