Salome HOME
Implementation of producer/consumer mechanism and transaction mechanism for global...
[modules/kernel.git] / src / SALOMESDS / SALOMESDS_PickelizedPyObjRdExtServer.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony GEAY (EDF R&D)
20
21 #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
22 #include "SALOMESDS_DataScopeServer.hxx"
23 #include "SALOMESDS_Exception.hxx"
24
25 #include <iostream>
26 #include <sstream>
27
28 using namespace SALOMESDS;
29
30 PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
31 {
32 }
33
34 //! obj is consumed
35 PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServer(father,varName,obj)
36 {
37 }
38
39 PickelizedPyObjRdExtServer::~PickelizedPyObjRdExtServer()
40 {
41 }
42
43 /*!
44  * Called remotely -> to protect against throw
45  */
46 SALOME::PickelizedPyObjRdExtServer_ptr PickelizedPyObjRdExtServer::invokePythonMethodOn(const char *method, const SALOME::ByteVec& args)
47 {
48   if(!_self)
49     throw Exception("PickelizedPyObjRdExtServer::invokePythonMethodOn : self is NULL !");
50   std::string argsCpp;
51   FromByteSeqToCpp(args,argsCpp);
52   PyObject *argsPy(getPyObjFromPickled(argsCpp));
53   checkRdExtnessOf(method,argsPy);
54   //
55   PyObject *selfMeth(PyObject_GetAttrString(_self,method));
56   if(!selfMeth)
57     {
58       std::ostringstream oss; oss << "PickelizedPyObjRdExtServer::invokePythonMethodOn : Method \"" << method << "\" is not available !";
59       throw Exception(oss.str());
60     }
61   PyObject *res(PyObject_CallObject(selfMeth,argsPy));// self can have been modified by this call !
62   Py_XDECREF(selfMeth);
63   Py_XDECREF(argsPy);
64   if(!res)
65     {
66       std::ostringstream oss; oss << "PickelizedPyObjRdExtServer::invokePythonMethodOn : Problem during invokation serverside of Method \"" << method << "\" !";
67       throw Exception(oss.str());
68     }
69   PickelizedPyObjRdExtServer *ret(new PickelizedPyObjRdExtServer(_father,DataScopeServer::BuildTmpVarNameFrom(getVarNameCpp()),res));
70   PortableServer::POA_var poa(_father->getPOA());
71   PortableServer::ObjectId_var id(poa->activate_object(ret));
72   CORBA::Object_var obj(poa->id_to_reference(id));
73   return SALOME::PickelizedPyObjRdExtServer::_narrow(obj);
74 }
75
76 void PickelizedPyObjRdExtServer::checkRdExtnessOf(const std::string& methodName, PyObject *argsPy)
77 {
78   if(!_self)
79     {
80       Py_XDECREF(argsPy);
81       throw Exception("PickelizedPyObjRdExtServer::checkRdExtnessOf : self is NULL !");
82     }
83   if(PyTuple_Check(_self)==1 || PyString_Check(_self)==1 || PyInt_Check(_self)==1 || PyBool_Check(_self)==1 || PyFloat_Check(_self)==1)
84     return ;//_self is tuple, str, int or float -> immutable in python. So no method can break the RdExtness of _self.
85   if(PyList_Check(_self)==1)
86     checkListRdExtnessOf(methodName,argsPy);
87   else if(PyDict_Check(_self)==1)
88     checkDictRdExtnessOf(methodName,argsPy);
89   else
90     throw Exception("PickelizedPyObjRdExtServer::checkRdExtnessOf : Supported python types are [list,tuple,dict,str,int,float] !");
91 }
92
93 void PickelizedPyObjRdExtServer::checkListRdExtnessOf(const std::string& methodName, PyObject *argsPy)
94 {
95   static const char *THE_RDEXT_METH_OF_LIST[]={"__getitem__","append","extend","insert","reverse","sort"};
96   for(std::size_t i=0;i<sizeof(THE_RDEXT_METH_OF_LIST)/sizeof(const char *);i++)
97     if(methodName==THE_RDEXT_METH_OF_LIST[i])
98       return ;
99   Py_XDECREF(argsPy);
100   std::ostringstream oss; oss << "PickelizedPyObjRdExtServer::checkListRdExtnessOf : The method \"" << methodName << "\" is a method that can lead to a loss of data ! Supported method of \"list \"without loss of data are : __getitem__, append, extend, insert, reverse, sort !";
101   throw Exception(oss.str());
102 }
103
104 void PickelizedPyObjRdExtServer::checkDictRdExtnessOf(const std::string& methodName, PyObject *argsPy)
105 {
106   static const char *THE_RDEXT_METH_OF_DICT[]={"__getitem__","get","items","keys","setdefault","update","values"};
107   for(std::size_t i=0;i<sizeof(THE_RDEXT_METH_OF_DICT)/sizeof(const char *);i++)
108     if(methodName==THE_RDEXT_METH_OF_DICT[i])
109       return ;
110   if(methodName=="__setitem__")
111     {
112       checkDictSetitemRdExtness(argsPy);
113       return ;
114     }
115   Py_XDECREF(argsPy);
116   std::ostringstream oss; oss << "PickelizedPyObjRdExtServer::checkDictRdExtnessOf : The method \"" << methodName << "\" is a method that can lead to a loss of data ! Supported method of \"list \"without loss of data are : __getitem__, __setitem__(with conditions), get, items, keys, setdefault, update, values !";
117   throw Exception(oss.str());
118 }
119
120 void PickelizedPyObjRdExtServer::checkDictSetitemRdExtness(PyObject *argsPy)
121 {
122   if(PyTuple_Check(argsPy)==0)
123     {
124       Py_XDECREF(argsPy);
125       throw Exception("PickelizedPyObjRdExtServer::checkDictSetitemRdExtness : args of dic(self).__setitem__ is not a tuple !");
126     }
127   if(PyTuple_Size(argsPy)!=2)
128     {
129       Py_XDECREF(argsPy);
130       throw Exception("PickelizedPyObjRdExtServer::checkDictSetitemRdExtness : tuple of dic(self).__setitem__ has not a size equal to 2 !");
131     }
132   if(PyDict_GetItem(_self,PyTuple_GetItem(argsPy,0))!=0)
133     {// argsPy[0] is already a key of _self -> __setitem__ is NOT RdExt !
134       Py_XDECREF(argsPy);
135       throw Exception("PickelizedPyObjRdExtServer::checkDictSetitemRdExtness : specified key of __setitem__ already exists ! RdExt property is not applied !");
136     }
137 }