Salome HOME
Copyrights update 2015.
[modules/kernel.git] / src / SALOMESDS / SALOMESDS_DataScopeServer.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_DataScopeServer.hxx"
22 #include "SALOMESDS_DataServerManager.hxx"
23 #include "SALOMESDS_PickelizedPyObjRdOnlyServer.hxx"
24 #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
25 #include "SALOMESDS_PickelizedPyObjRdWrServer.hxx"
26 #include "SALOME_NamingService.hxx"
27 #include "SALOMESDS_Exception.hxx"
28
29 #include <sstream>
30 #include <iterator>
31 #include <algorithm>
32
33 // agy : awful, to be factorized with ContainerManager.
34 #ifndef WIN32
35 #include <unistd.h>
36 #else
37 #include <process.h>
38 #define getpid _getpid
39 #endif
40
41 using namespace SALOMESDS;
42
43 std::size_t DataScopeServer::COUNTER=0;
44
45 DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, const std::string& scopeName):_globals(0),_locals(0),_pickler(0),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName)
46 {
47 }
48
49 DataScopeServer::DataScopeServer(const DataScopeServer& other):_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars)
50 {
51 }
52
53 DataScopeServer::~DataScopeServer()
54 {
55   // _globals is borrowed ref -> do nothing
56   Py_XDECREF(_locals);
57   Py_XDECREF(_pickler);
58 }
59
60 /*!
61  * Called remotely -> to protect against throw
62  */
63 void DataScopeServer::ping()
64 {
65 }
66
67 /*!
68  * Called remotely -> to protect against throw
69  */
70 char *DataScopeServer::getScopeName()
71 {
72   return CORBA::string_dup(_name.c_str());
73 }
74
75 /*!
76  * Called remotely -> to protect against throw
77  */
78 SALOME::StringVec *DataScopeServer::listVars()
79 {
80   SALOME::StringVec *ret(new SALOME::StringVec);
81   std::size_t sz(_vars.size());
82   ret->length(sz);
83   std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(_vars.begin());
84   for(std::size_t i=0;i<sz;it++,i++)
85     {
86       BasicDataServer *obj((*it).second);
87       std::string name(obj->getVarNameCpp());
88       (*ret)[i]=CORBA::string_dup(name.c_str());
89     }
90   return ret;
91 }
92
93 SALOME::BasicDataServer_ptr DataScopeServer::retrieveVar(const char *varName)
94 {
95   std::string varNameCpp(varName);
96   std::vector<std::string> allNames(getAllVarNames());
97   std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
98   if(it==allNames.end())
99     {
100       std::ostringstream oss; oss << "DataScopeServer::retrieveVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
101       std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
102       throw Exception(oss.str());
103     }
104   std::size_t pos(std::distance(allNames.begin(),it));
105   std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
106   for(std::size_t i=0;i<pos;i++,it0++);
107   return SALOME::BasicDataServer::_duplicate((*it0).first);
108 }
109
110 void DataScopeServer::deleteVar(const char *varName)
111 {
112   std::string varNameCpp(varName);
113   std::vector<std::string> allNames(getAllVarNames());
114   std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
115   if(it==allNames.end())
116     {
117       std::ostringstream oss; oss << "DataScopeServer::deleteVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
118       std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
119       throw Exception(oss.str());
120     }
121   std::size_t pos(std::distance(allNames.begin(),it));
122   std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
123   (*it0).first->UnRegister();
124   _vars.erase(it0);
125 }
126
127 SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
128 {
129   std::string varNameCpp(varName);
130   checkNotAlreadyExistingVar(varNameCpp);
131   PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
132   CORBA::Object_var ret(activateWithDedicatedPOA(tmp));
133   std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
134   _vars.push_back(p);
135   return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
136 }
137
138 SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
139 {
140   std::string varNameCpp(varName);
141   checkNotAlreadyExistingVar(varNameCpp);
142   PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
143   CORBA::Object_var ret(activateWithDedicatedPOA(tmp));
144   std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
145   _vars.push_back(p);
146   return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
147 }
148
149 /*!
150  * Called remotely -> to protect against throw
151  */
152 SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
153 {
154   std::string varNameCpp(varName),typeNameCpp(typeName);
155   checkNotAlreadyExistingVar(varNameCpp);
156   PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
157   CORBA::Object_var ret(activateWithDedicatedPOA(tmp));
158   std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
159   _vars.push_back(p);
160   return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
161 }
162
163 void DataScopeServer::shutdownIfNotHostedByDSM()
164 {
165   SALOME_NamingService ns(_orb);
166   CORBA::Object_var obj(ns.Resolve(DataServerManager::NAME_IN_NS));
167   SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(obj));
168   if(CORBA::is_nil(dsm))
169     return ;
170   // destroy ref in the naming service
171   std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
172   ns.Destroy_Name(fullScopeName.c_str());
173   // establish if dsm and this shared the same POA. If yes dsm and this are collocated !
174   PortableServer::ServantBase *ret(0);
175   try
176     {
177       ret=_poa->reference_to_servant(dsm);
178     }
179   catch(...) { ret=0; }
180   //
181   if(!ret)
182     _orb->shutdown(0);
183   else
184     {
185       PortableServer::ObjectId_var oid(_poa->servant_to_id(this));
186       _poa->deactivate_object(oid);
187       ret->_remove_ref();
188     }
189 }
190
191 void DataScopeServer::initializePython(int argc, char *argv[])
192 {
193   Py_Initialize();
194   PySys_SetArgv(argc,argv);
195   PyObject *mainmod(PyImport_AddModule("__main__"));
196   _globals=PyModule_GetDict(mainmod);
197   if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
198     {
199       PyObject *bimod(PyImport_ImportModule("__builtin__"));
200       if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
201         Py_FatalError("can't add __builtins__ to __main__");
202       Py_XDECREF(bimod);
203     }
204   _locals=PyDict_New();
205   PyObject *tmp(PyList_New(0));
206   _pickler=PyImport_ImportModuleLevel(const_cast<char *>("cPickle"),_globals,_locals,tmp,-1);
207 }
208
209 void DataScopeServer::registerToSalomePiDict() const
210 {
211   PyObject *mod(PyImport_ImportModule("addToKillList"));
212   if(!mod)
213     return;
214   PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));
215   if(!meth)
216     { Py_XDECREF(mod); return ; }
217   PyObject *args(PyTuple_New(2));
218   PyTuple_SetItem(args,0,PyInt_FromLong(getpid()));
219   PyTuple_SetItem(args,1,PyString_FromString("SALOME_DataScopeServer"));
220   PyObject *res(PyObject_CallObject(meth,args));
221   Py_XDECREF(args);
222   Py_XDECREF(res);
223   Py_XDECREF(mod);
224 }
225
226 /*!
227  * \a ptr has been activated by the POA \a poa.
228  */
229 void DataScopeServer::setPOAAndRegister(PortableServer::POA_var poa, SALOME::DataScopeServer_ptr ptr)
230 {
231   _poa=poa;
232   std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
233   SALOME_NamingService ns(_orb);
234   ns.Register(ptr,fullScopeName.c_str());
235 }
236
237 std::string DataScopeServer::BuildTmpVarNameFrom(const std::string& varName)
238 {
239   std::ostringstream oss;
240   oss << varName << "@" << COUNTER++;
241   return oss.str();
242 }
243
244 std::vector< std::string > DataScopeServer::getAllVarNames() const
245 {
246   std::size_t sz(_vars.size());
247   std::vector<std::string> ret(sz);
248   std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
249   for(std::size_t i=0;i<sz;it++,i++)
250     ret[i]=(*it).second->getVarNameCpp();
251   return ret;
252 }
253
254 CORBA::Object_var DataScopeServer::activateWithDedicatedPOA(BasicDataServer *ds)
255 {
256   PortableServer::ObjectId_var id(_poa->activate_object(ds));
257   CORBA::Object_var ret(_poa->id_to_reference(id));
258   return ret;
259 }
260
261 void DataScopeServer::checkNotAlreadyExistingVar(const std::string& varName)
262 {
263   std::vector<std::string> allNames(getAllVarNames());
264   std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
265   if(it!=allNames.end())
266     {
267       std::ostringstream oss; oss << "DataScopeServer::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
268       throw Exception(oss.str());
269     }
270 }