Salome HOME
[EDF17719] : Comparison between 2 objects is now a user defined function called ...
[modules/kernel.git] / src / SALOMESDS / SALOMESDS_DataScopeServer.cxx
index 99ea0d6755885d159f5813a11d7ba403c6a501d4..d8b70ef3a8f620bfddf96e5da172a5b57236d654 100644 (file)
@@ -65,6 +65,25 @@ void DataScopeKiller::shutdown()
   _orb->shutdown(0);
 }
 
+RequestSwitcher::RequestSwitcher(CORBA::ORB_ptr orb, DataScopeServerTransaction *ds):RequestSwitcherBase(orb),_ds(ds)
+{
+}
+
+SALOME::StringVec *RequestSwitcher::listVars()
+{
+  return _ds->listVars();
+}
+
+SALOME::ByteVec *RequestSwitcher::fetchSerializedContent(const char *varName)
+{
+  return _ds->fetchSerializedContent(varName);
+}
+
+void RequestSwitcher::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data)
+{
+  return _ds->fetchAndGetAccessOfVar(varName,access,data);
+}
+
 DataScopeServerBase::DataScopeServerBase(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):_globals(0),_locals(0),_pickler(0),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName),_killer(killer)
 {
 }
@@ -239,6 +258,24 @@ SALOME::SeqOfByteVec *DataScopeServerBase::getAllKeysOfVarWithTypeDict(const cha
   return ret;
 }
 
+void DataScopeServerBase::takeANap(CORBA::Double napDurationInSec)
+{
+  if(napDurationInSec<0.)
+    throw Exception("DataScopeServerBase::takeANap : negative value !");
+#ifndef WIN32
+  struct timespec req,rem;
+  long nbSec((long)napDurationInSec);
+  double remainTime(napDurationInSec-(double)nbSec);
+  req.tv_sec=nbSec;
+  req.tv_nsec=(long)(remainTime*1000000.);
+  int ret(nanosleep(&req,&rem));
+  if(ret!=0)
+    throw Exception("DataScopeServerBase::takeANap : nap not finished as expected !");
+#else
+  throw Exception("DataScopeServerBase::takeANap : not implemented for Windows !");
+#endif
+}
+
 void DataScopeServerBase::initializePython(int argc, char *argv[])
 {
   Py_Initialize();
@@ -308,11 +345,16 @@ std::vector< std::string > DataScopeServerBase::getAllVarNames() const
   return ret;
 }
 
-void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
+bool DataScopeServerBase::isExistingVar(const std::string& varName) const
 {
   std::vector<std::string> allNames(getAllVarNames());
   std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
-  if(it!=allNames.end())
+  return it!=allNames.end();
+}
+
+void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
+{
+  if(isExistingVar(varName))
     {
       std::ostringstream oss; oss << "DataScopeServerBase::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
       throw Exception(oss.str());
@@ -388,8 +430,7 @@ void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const s
     throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit : var is neither RdExt nor RdExtInit !");
   if(varc0)
     {
-      PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
-      PickelizedPyObjRdExtInitServer *newVar(new PickelizedPyObjRdExtInitServer(this,varName,pyobj));
+      PickelizedPyObjRdExtInitServer *newVar(varc0->buildInitInstanceFrom(varName));
       newVar->incrNbClients();
       CORBA::Object_var obj(newVar->activate());
       SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
@@ -412,8 +453,7 @@ void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt(const std::
     {
       if(varc0->decrNbClients())
         {
-          PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
-          PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj));
+          PickelizedPyObjRdExtServer *newVar(varc0->buildStdInstanceFrom(varName));
           CORBA::Object_var obj(newVar->activate());
           SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
           p.first=obj2; p.second=newVar;
@@ -564,6 +604,51 @@ void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varNa
   _vars.push_back(p);
 }
 
+void DataScopeServerTransaction::createRdExtVarFreeStyleInternal(const std::string& varName, const SALOME::ByteVec& constValue, std::string&& compareFuncContent, SALOME::AutoPyRef&& compareFunc)
+{
+  if(!isExistingVar(varName))
+    {
+      PickelizedPyObjRdExtFreeStyleServer *tmp(new PickelizedPyObjRdExtFreeStyleServer(this,varName,constValue,std::move(compareFuncContent),std::move(compareFunc)));
+      CORBA::Object_var ret(tmp->activate());
+      std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+      _vars.push_back(p);
+    }
+  else
+    {
+      BasicDataServer *ds(retrieveVarInternal2(varName));
+      if(!ds)
+        {
+          std::ostringstream oss;
+          oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : internal error 1 for varname \"" << varName << "\"!";
+          throw Exception(oss.str());
+        }
+      Sha1Keeper *ds2(dynamic_cast<Sha1Keeper *>(ds));
+      if(!ds2)
+        {
+          std::ostringstream oss;
+          oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists with a non Sha1Keeper type !";
+          throw Exception(oss.str());
+        }
+      PickelizedPyObjServer *ds3(dynamic_cast<PickelizedPyObjServer *>(ds));
+      if(!ds3)
+        {
+          std::ostringstream oss;
+          oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists with a non PickelizedPyObjServer type !";
+          throw Exception(oss.str());
+        }
+      std::vector<unsigned char> constValueAsCpp;
+      Transaction::FromByteSeqToVB(constValue,constValueAsCpp);
+      SALOME::AutoPyRef newObj(PickelizedPyObjServer::GetPyObjFromPickled(constValueAsCpp,this));
+      if(newObj.isNull())
+        {
+          std::ostringstream oss;
+          oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists but input pickelized object is not loadable !";
+          throw Exception(oss.str());
+        }
+      ds2->checkSame(varName,compareFuncContent,ds3->getPyObj(),newObj);
+    }
+}
+
 void DataScopeServerTransaction::createRdExtInitVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
 {
   checkNotAlreadyExistingVar(varName);
@@ -598,6 +683,13 @@ SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const
   return SALOME::Transaction::_narrow(obj);
 }
 
+SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarFreeStyleTransac(const char *varName, const SALOME::ByteVec& constValue, const char *compareFuncContent)
+{// no check on varName done here. Will be done on perform
+  TransactionRdExtVarFreeStyleCreate *ret(new TransactionRdExtVarFreeStyleCreate(this,varName,constValue,compareFuncContent));
+  CORBA::Object_var obj(ret->activate());
+  return SALOME::Transaction::_narrow(obj);
+}
+
 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtInitVarTransac(const char *varName, const SALOME::ByteVec& constValue)
 {
   checkNotAlreadyExistingVar(varName);
@@ -625,16 +717,25 @@ void DataScopeServerTransaction::pingKey(PyObject *keyObj)
 {
   std::size_t ii(0);
   // this part does nothing except to be sure that in notify key all will be OK.
+  PyObject *args(PyTuple_New(1));
+  PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
   for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
     {
       PyObject *waitKey((*it)->getKeyPyObj());
-      PyObject *res(PyObject_CallMethodObjArgs(keyObj, PyUnicode_DecodeASCII("__ne__", 6, NULL), waitKey));
+      PyObject *meth(PyObject_GetAttrString(waitKey,"__eq__"));
+      if(!meth)
+      {
+         std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
+         throw Exception(oss.str());
+      }
+      PyObject *res(PyObject_CallObject(meth,args));
+      Py_XDECREF(meth);
       if(res==NULL)
         {
           std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !";
           throw Exception(oss.str());
         }
-      PyLong_AsLong(res); // res is bool, but it s ok since __int__ is called
+      PyBool_Check(res);
       if(PyErr_Occurred())
         {
           std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
@@ -642,11 +743,14 @@ void DataScopeServerTransaction::pingKey(PyObject *keyObj)
         }
       Py_XDECREF(res);
     }
+  Py_XDECREF(args);
 }
 
 void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj)
 {
   std::size_t ii(0);
+  PyObject *args(PyTuple_New(1));
+  PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
   std::list< KeyWaiter *> newList,listOfEltToWakeUp;
   for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
     {
@@ -656,24 +760,31 @@ void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject
           continue;
         }
       PyObject *waitKey((*it)->getKeyPyObj());
-      PyObject *res(PyObject_CallMethodObjArgs(keyObj, PyUnicode_DecodeASCII("__ne__", 6, NULL), waitKey));
-      if(res==NULL)
-        {
-          std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during cmp(k,wk[i]) !";
-          throw Exception(oss.str());
-        }
-      long resCpp(PyLong_AsLong(res)); // res is bool, but it s ok since __int__ is called
+      PyObject *meth(PyObject_GetAttrString(waitKey,"__eq__"));
+      if(!meth)
+      {
+         std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
+         throw Exception(oss.str());
+      }
+      PyObject *res(PyObject_CallObject(meth,args));
+      Py_XDECREF(meth);
+      if(!PyBool_Check(res))
+      {
+         std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
+         throw Exception(oss.str());
+      }
       if(PyErr_Occurred())
         {
           std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
           throw Exception(oss.str());
         }
-      Py_XDECREF(res);
-      if(resCpp==0)
+      if(res==Py_True)
         listOfEltToWakeUp.push_back(*it);
       else
         newList.push_back(*it);
+      Py_XDECREF(res);
     }
+  Py_XDECREF(args);
   for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
     (*it)->valueJustCome(valueObj);
   for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
@@ -769,7 +880,7 @@ SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter
   KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
   if(!retc)
     throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
-  retc->_remove_ref();// restore the counter afer _poa_for_key_waiter->reference_to_servant(kw)
+  retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw)
   SALOME::ByteVec *zeRet(retc->waitForMonoThr());
   retc->enforcedRelease();
   return zeRet;
@@ -786,7 +897,7 @@ SALOME::ByteVec *DataScopeServerTransaction::waitForAndKill(SALOME::KeyWaiter_pt
   KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
   if(!retc)
     throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
-  retc->_remove_ref();// restore the counter afer _poa_for_key_waiter->reference_to_servant(kw)
+  retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw)
   SALOME::ByteVec *zeRet(retc->waitForAndKill());
   retc->enforcedRelease();
   return zeRet;
@@ -837,3 +948,12 @@ DataScopeServerTransaction::~DataScopeServerTransaction()
 {
 }
 
+SALOME::RequestSwitcher_ptr DataScopeServerTransaction::getRequestSwitcher()
+{
+  if(_rs.isNull())
+    {
+      _rs=new RequestSwitcher(_orb,this);
+    }
+  CORBA::Object_var obj(_rs->activate());
+  return SALOME::RequestSwitcher::_narrow(obj);
+}