Back to index

salome-kernel  6.5.0
DSC_interface.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  File   : DSC_interface.cxx
00024 //  Author : André RIBES (EDF)
00025 //  Module : KERNEL
00026 //
00027 #include <string>
00028 #include "DSC_interface.hxx"
00029 #ifdef WNT
00030 #else
00031 #include <sys/time.h>
00032 #endif
00033 #include <fstream>
00034 #include <sys/stat.h>
00035 #include <sstream>
00036 #include <stdlib.h>
00037 
00038 //#define MYDEBUG
00039 
00040 Engines_DSC_interface::Engines_DSC_interface() {}
00041 
00042 Engines_DSC_interface::~Engines_DSC_interface() 
00043 {
00044   my_ports_it = my_ports.begin();
00045   for(;my_ports_it != my_ports.end();my_ports_it++)
00046     delete my_ports_it->second;
00047 
00048 }
00049 
00050 void
00051 Engines_DSC_interface::add_provides_port(Ports::Port_ptr ref, 
00052                                  const char* provides_port_name,
00053                                  Ports::PortProperties_ptr port_prop) 
00054 throw (Engines::DSC::PortAlreadyDefined,
00055        Engines::DSC::NilPort,
00056        Engines::DSC::BadProperty) 
00057 {
00058   // Method args test
00059   assert(provides_port_name);
00060   if (CORBA::is_nil(ref))
00061     throw Engines::DSC::NilPort();
00062   if (CORBA::is_nil(port_prop))
00063     throw Engines::DSC::BadProperty();
00064 
00065   my_ports_it = my_ports.find(provides_port_name);
00066   if (my_ports_it ==  my_ports.end()) {
00067     // Creating a new port provides
00068     port_t * new_port = new port_t();
00069     new_port->type = provides;
00070     new_port->connection_nbr = 0;
00071     new_port->provides_port_ref = Ports::Port::_duplicate(ref);
00072     new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
00073 
00074     // Port into the port's map
00075     my_ports[provides_port_name] = new_port;
00076   }
00077   else
00078     throw Engines::DSC::PortAlreadyDefined();
00079 }
00080 
00081 void
00082 Engines_DSC_interface::add_uses_port(const char* repository_id, 
00083                              const char* uses_port_name,
00084                              Ports::PortProperties_ptr port_prop) 
00085 throw (Engines::DSC::PortAlreadyDefined,
00086        Engines::DSC::BadProperty) 
00087 {
00088   // Method args test
00089   // Note : We can't be shure that repository id
00090   // is a correct CORBA id.
00091   assert(repository_id);
00092   assert(uses_port_name);
00093   if (CORBA::is_nil(port_prop))
00094     throw Engines::DSC::BadProperty();
00095 
00096   my_ports_it = my_ports.find(uses_port_name);
00097   if (my_ports_it ==  my_ports.end()) {
00098     // Creating a new uses port
00099     port_t * new_port = new port_t();
00100     new_port->type = uses;
00101     new_port->connection_nbr = 0;
00102     new_port->uses_port_refs.length(0);
00103     new_port->repository_id = repository_id;
00104     new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
00105 
00106     // Port into port's map
00107     my_ports[uses_port_name] = new_port;
00108   }
00109   else
00110     throw Engines::DSC::PortAlreadyDefined();
00111 }
00112 
00113 Ports::Port_ptr
00114 Engines_DSC_interface::get_provides_port(const char* provides_port_name,
00115                                  const CORBA::Boolean connection_error) 
00116   throw (Engines::DSC::PortNotDefined,
00117          Engines::DSC::PortNotConnected, 
00118          Engines::DSC::BadPortType) 
00119 {
00120   // Method arg test
00121   assert(provides_port_name);
00122 
00123   Ports::Port_ptr rtn_port = Ports::Port::_nil();
00124 //   std::cout << "---- DSC_Interface : MARK 1 ---- Recherche de : " << provides_port_name << "----" << std::endl;
00125 //   ports::iterator it;
00126 //   std::cout << "----> ";
00127 //   for(it=my_ports.begin();it!=my_ports.end();++it) 
00128 //     std::cout << "|"<<(*it).first<<"|, ";
00129 //   std::cout << std::endl;
00130  
00131   // Searching the port
00132   my_ports_it = my_ports.find(provides_port_name);
00133   if (my_ports_it ==  my_ports.end())
00134     throw Engines::DSC::PortNotDefined();
00135   if (my_ports[provides_port_name]->type != provides) {
00136     Engines::DSC::BadPortType BPT;
00137     BPT.expected = CORBA::string_dup("Expected a provides port");
00138     BPT.received = CORBA::string_dup((std::string("Received a uses/none port : ")+provides_port_name).c_str());
00139     throw BPT;
00140   }
00141 
00142   if (my_ports[provides_port_name]->connection_nbr == 0 && connection_error)
00143     throw Engines::DSC::PortNotConnected();
00144 
00145   rtn_port = Ports::Port::_duplicate(my_ports[provides_port_name]->provides_port_ref);
00146   return rtn_port;
00147 }
00148 
00149 Engines::DSC::uses_port * 
00150 Engines_DSC_interface::get_uses_port(const char* uses_port_name) 
00151   throw (Engines::DSC::PortNotDefined,
00152          Engines::DSC::PortNotConnected,
00153          Engines::DSC::BadPortType) 
00154 {
00155   // Method arg test
00156   assert(uses_port_name);
00157 
00158   Engines::DSC::uses_port * rtn_port = NULL;  
00159 
00160   // Searching the uses port
00161   my_ports_it = my_ports.find(uses_port_name);
00162   if (my_ports_it == my_ports.end())
00163     throw Engines::DSC::PortNotDefined();
00164   if (my_ports[uses_port_name]->type != uses){
00165     Engines::DSC::BadPortType BPT;
00166     BPT.expected = CORBA::string_dup("Expected a uses port");
00167     BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
00168 #ifdef MYDEBUG
00169    std::cout << "---- DSC_Interface : MARK 1 ---- exception : " << uses_port_name << "----" << std::endl;
00170 #endif
00171     throw BPT;
00172   }
00173 
00174   // Is the port connected ?
00175   if (my_ports[uses_port_name]->connection_nbr > 0) {
00176     rtn_port = new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs);
00177   }
00178   else
00179     {
00180 #ifdef MYDEBUG
00181    std::cout << "---- DSC_Interface : MARK 2 ---- exception : " << uses_port_name << "----" << std::endl;
00182 #endif
00183     throw Engines::DSC::PortNotConnected();
00184     }
00185   
00186   return rtn_port;
00187 }
00188 
00189 void
00190 Engines_DSC_interface::connect_provides_port(const char* provides_port_name)
00191     throw (Engines::DSC::PortNotDefined)
00192 {
00193   // Method arg test
00194   assert(provides_port_name);
00195 
00196   // Searching the provides port
00197   my_ports_it = my_ports.find(provides_port_name);
00198   if (my_ports_it ==  my_ports.end())
00199     throw Engines::DSC::PortNotDefined();
00200   if (my_ports[provides_port_name]->type != provides)
00201     throw Engines::DSC::PortNotDefined();
00202 
00203 
00204   // Adding a new connection
00205   my_ports[provides_port_name]->connection_nbr += 1;
00206   // User code is informed
00207   provides_port_changed(provides_port_name, 
00208                         my_ports[provides_port_name]->connection_nbr,
00209                         Engines::DSC::AddingConnection
00210                        );
00211 }
00212 
00213 void
00214 Engines_DSC_interface::connect_uses_port(const char* uses_port_name,
00215                                          Ports::Port_ptr provides_port_ref) 
00216   throw (Engines::DSC::PortNotDefined,
00217          Engines::DSC::BadPortType,
00218          Engines::DSC::NilPort)
00219 {
00220   // Method arg test
00221   assert(uses_port_name);
00222 
00223   if (CORBA::is_nil(provides_port_ref))
00224     throw Engines::DSC::NilPort();
00225 
00226   // Searching the uses port
00227   my_ports_it = my_ports.find(uses_port_name);
00228   if (my_ports_it ==  my_ports.end())
00229     throw Engines::DSC::PortNotDefined();
00230   if (my_ports[uses_port_name]->type != uses) {
00231     Engines::DSC::BadPortType BPT;
00232     BPT.expected = CORBA::string_dup("Expected a uses port");
00233     BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
00234     throw BPT;
00235   }
00236 
00237   // repository_id test
00238   const char * repository_id = my_ports[uses_port_name]->repository_id.c_str();
00239   if (provides_port_ref->_is_a(repository_id)) 
00240   {
00241     // Adding provides port into the uses port sequence
00242     CORBA::ULong lgth = my_ports[uses_port_name]->uses_port_refs.length();
00243     my_ports[uses_port_name]->
00244       uses_port_refs.length(lgth + 1);
00245     my_ports[uses_port_name]->uses_port_refs[lgth] = 
00246       Ports::Port::_duplicate(provides_port_ref);
00247 
00248     // Adding a new connection
00249     my_ports[uses_port_name]->connection_nbr += 1;
00250     // User code is informed
00251     uses_port_changed(uses_port_name,
00252                       new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs),
00253                       Engines::DSC::AddingConnection);
00254   }
00255   else {
00256     Engines::DSC::BadPortType BPT;
00257     BPT.expected = CORBA::string_dup("Expected ...");
00258     BPT.received = CORBA::string_dup((std::string("Received an incorrect repository id type ")+
00259                                       repository_id).c_str());
00260     throw BPT;
00261   }
00262 
00263 }
00264 
00265 CORBA::Boolean
00266 Engines_DSC_interface::is_connected(const char* port_name) 
00267   throw (Engines::DSC::PortNotDefined) 
00268 {
00269   CORBA::Boolean rtn = false;
00270 
00271   // Method arg test
00272   assert(port_name);
00273 
00274   my_ports_it = my_ports.find(port_name);
00275   if (my_ports_it ==  my_ports.end())
00276     throw Engines::DSC::PortNotDefined();
00277 
00278   // Is it connected ?
00279   if (my_ports[port_name]->connection_nbr > 0)
00280     rtn = true;
00281 
00282   return rtn;
00283 }
00284 
00285 void
00286 Engines_DSC_interface::disconnect_provides_port(const char* provides_port_name,
00287                                         const Engines::DSC::Message message)
00288 throw (Engines::DSC::PortNotDefined,
00289        Engines::DSC::PortNotConnected)
00290 {
00291   // Method args test
00292   assert(provides_port_name);
00293 
00294   my_ports_it = my_ports.find(provides_port_name);
00295   if (my_ports_it ==  my_ports.end())
00296     throw Engines::DSC::PortNotDefined();
00297   if (my_ports[provides_port_name]->type != provides)
00298     throw Engines::DSC::PortNotDefined();
00299 
00300   // Is it connected ?
00301   if (my_ports[provides_port_name]->connection_nbr > 0) 
00302   {
00303     my_ports[provides_port_name]->connection_nbr -= 1;
00304     provides_port_changed(provides_port_name,
00305                           my_ports[provides_port_name]->connection_nbr,
00306                           message);
00307   }
00308   else
00309     throw Engines::DSC::PortNotConnected();
00310 }
00311 
00312 void
00313 Engines_DSC_interface::disconnect_uses_port(const char* uses_port_name,
00314                                     Ports::Port_ptr provides_port_ref,
00315                                     const Engines::DSC::Message message)
00316 throw (Engines::DSC::PortNotDefined,
00317        Engines::DSC::PortNotConnected,
00318        Engines::DSC::BadPortReference) 
00319 {
00320   // Method args test
00321   assert(uses_port_name);
00322 
00323   my_ports_it = my_ports.find(uses_port_name);
00324   if (my_ports_it ==  my_ports.end())
00325     throw Engines::DSC::PortNotDefined();
00326   if (my_ports[uses_port_name]->type != uses)
00327     throw Engines::DSC::PortNotDefined();
00328 
00329   if (CORBA::is_nil(provides_port_ref))
00330     throw Engines::DSC::BadPortReference();
00331 
00332   // Is it connected ?
00333   if (my_ports[uses_port_name]->connection_nbr > 0) {
00334     CORBA::Long port_index = -1;
00335     CORBA::ULong seq_length = my_ports[uses_port_name]->uses_port_refs.length(); 
00336     for(int i = 0; i < seq_length; i++)
00337     {
00338       if (my_ports[uses_port_name]->uses_port_refs[i]->_is_equivalent(provides_port_ref))
00339       {
00340         port_index = i;
00341         break;
00342       }
00343     }
00344     if (port_index == -1)
00345       throw Engines::DSC::BadPortReference();
00346 
00347     my_ports[uses_port_name]->connection_nbr -= 1;
00348     Engines::DSC::uses_port * new_uses_port = 
00349       new Engines::DSC::uses_port();
00350     new_uses_port->length(seq_length - 1);
00351 
00352     int index_ancien = 0;
00353     int index_nouveau = 0;
00354     for(;index_ancien < seq_length;) {
00355       if (index_ancien == port_index) 
00356       {
00357         // Rien a faire !
00358         // On ne change pas le index du nouveau tableau
00359         index_ancien += 1;
00360       }
00361       else 
00362       {
00363         (*new_uses_port)[index_nouveau] = my_ports[uses_port_name]->uses_port_refs[index_ancien];
00364         index_ancien += 1;
00365         index_nouveau += 1;
00366       }
00367     }
00368 
00369     // New uses port's sequence
00370     my_ports[uses_port_name]->uses_port_refs = *new_uses_port;
00371 
00372     // The user code is informed
00373     uses_port_changed(uses_port_name,
00374                       new_uses_port,
00375                       message);
00376   }
00377   else
00378     throw Engines::DSC::PortNotConnected();
00379 }
00380 
00381 Ports::PortProperties_ptr
00382 Engines_DSC_interface::get_port_properties(const char* port_name) 
00383   throw (Engines::DSC::PortNotDefined) 
00384 {
00385   Ports::PortProperties_ptr rtn_properties = Ports::PortProperties::_nil();
00386 
00387   // Method arg test
00388   assert(port_name);
00389 
00390   my_ports_it = my_ports.find(port_name);
00391   if (my_ports_it ==  my_ports.end())
00392     throw Engines::DSC::PortNotDefined();
00393 
00394   rtn_properties = Ports::PortProperties::_duplicate(my_ports[port_name]->port_prop);
00395   return rtn_properties;
00396 }
00397 
00398 //Trace functions for DSC operations: a local function (initTrace) and a class method (Engines_DSC_interface::writeEvent)
00399 static  int traceType=-1; // 0=stderr;1=file;
00400 static  int traceLevel=-1; // 0=no trace;1=normal trace;2=detailed trace
00401 static  std::ofstream traceFile;
00402 static  std::ostream *out;
00403 
00405 
00413 static void initTrace(const std::string& containerName)
00414 {
00415   // if initialization has already been done do nothing
00416   if(traceLevel >= 0)return;
00417 
00418   std::string typeenv="0";
00419   std::string levelenv="1";
00420   char* valenv=0;
00421   valenv=getenv("DSC_TRACE");
00422   if(valenv)typeenv=valenv;
00423   valenv=getenv("DSC_TRACELEVEL");
00424   if(valenv)levelenv=valenv;
00425 
00426   if(levelenv=="0")
00427     traceLevel=0; // no trace
00428   else if(levelenv=="2")
00429     traceLevel=2; //detailed trace
00430   else
00431     traceLevel=1; // normal trace (default)
00432 
00433   if(traceLevel==0)
00434     return;
00435 
00436   if(typeenv=="1")
00437     {
00438       //trace in file
00439       traceType=1;
00440 #ifdef WNT
00441       std::string logFilename=getenv("TEMP");
00442       logFilename += "\\";
00443 #else
00444       std::string logFilename="/tmp";
00445       char* val = getenv("SALOME_TMP_DIR");
00446       if(val)
00447         {
00448           struct stat file_info;
00449           stat(val, &file_info);
00450           bool is_dir = S_ISDIR(file_info.st_mode);
00451           if (is_dir)logFilename=val;
00452         }
00453       logFilename += "/";
00454 #endif
00455 
00456       logFilename=logFilename+containerName+".tce";
00457       traceFile.open(logFilename.c_str(), std::ios::out | std::ios::app);
00458       out=&traceFile;
00459     }
00460   else
00461     {
00462       //trace to stderr (default)
00463       traceType=0;
00464       out=&std::cerr;
00465     }
00466   //trace heading
00467   out->width(17);
00468   *out << "Elapsed time" ;
00469   *out << " | " ;
00470   out->width(16);
00471   *out << "Request" ;
00472   *out << " | " ;
00473   out->width(16);
00474   *out << "Container" ;
00475   *out << " | " ;
00476   out->width(16);
00477   *out << "Instance" ;
00478   *out << " | " ;
00479   out->width(16);
00480   *out << "Port" ;
00481   *out << " | " ;
00482   out->width(24);
00483   *out << "Error";
00484   *out << " | " ;
00485   *out << "Infos" ;
00486   *out << std::endl;
00487 }
00488 
00489 
00491 
00499 void Engines_DSC_interface::writeEvent(const char* request,const std::string& containerName, const char* instance_name, 
00500                                        const char* port_name, const char* error, const char* message)
00501 {
00502   if(traceLevel < 0)
00503     initTrace(containerName);
00504   if(traceLevel == 0)return;
00505 
00506 #ifdef WNT
00507 #else
00508   struct timeval tv;
00509   gettimeofday(&tv,0);
00510   long tt0=tv.tv_sec/3600; //hours
00511 
00512   if(traceType == 2)
00513     {
00514       //notifier (not used: salome notifier is now obsolete)
00515       std::ostringstream msg;
00516       msg.width(7);
00517       msg << tt0 ;
00518       msg << ":" ;
00519       long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
00520       msg.width(2);
00521       msg << tt1 ;
00522       msg << ":" ;
00523       long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
00524       msg.width(2);
00525       msg << tt2 ;
00526       msg << ":" ;
00527       long tt3=tv.tv_usec/1000; //milliseconds
00528       msg.width(3);
00529       msg << tt3 ;
00530       msg << " | " ;
00531       msg.width(24);
00532       msg << error;
00533       msg << " | " ;
00534       msg << message ;
00535       //send event to notifier (containerName.c_str(),instance_name, request, msg.str().c_str())
00536     }
00537   else
00538     {
00539       //cerr or file
00540       out->width(7);
00541       *out << tt0 ;
00542       *out << ":" ;
00543       long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
00544       out->width(2);
00545       *out << tt1 ;
00546       *out << ":" ;
00547       long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
00548       out->width(2);
00549       *out << tt2 ;
00550       *out << ":" ;
00551       long tt3=tv.tv_usec/1000; //milliseconds
00552       out->width(3);
00553       *out << tt3 ;
00554       *out << " | " ;
00555       out->width(16);
00556       *out << request ;
00557       *out << " | " ;
00558       out->width(16);
00559       *out << containerName ;
00560       *out << " | " ;
00561       out->width(16);
00562       *out << instance_name ;
00563       *out << " | " ;
00564       out->width(16);
00565       *out << port_name ;
00566       *out << " | " ;
00567       out->width(24);
00568       *out << error;
00569       *out << " | " ;
00570       *out << message ;
00571       *out << std::endl;
00572     }
00573 #endif
00574 }
00575