1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : DSC_interface.cxx
23 // Author : André RIBES (EDF)
27 #include "DSC_interface.hxx"
39 Engines_DSC_interface::Engines_DSC_interface() {}
41 Engines_DSC_interface::~Engines_DSC_interface()
43 my_ports_it = my_ports.begin();
44 for(;my_ports_it != my_ports.end();my_ports_it++)
45 delete my_ports_it->second;
50 Engines_DSC_interface::add_provides_port(Ports::Port_ptr ref,
51 const char* provides_port_name,
52 Ports::PortProperties_ptr port_prop)
53 throw (Engines::DSC::PortAlreadyDefined,
54 Engines::DSC::NilPort,
55 Engines::DSC::BadProperty)
58 assert(provides_port_name);
59 if (CORBA::is_nil(ref))
60 throw Engines::DSC::NilPort();
61 if (CORBA::is_nil(port_prop))
62 throw Engines::DSC::BadProperty();
64 my_ports_it = my_ports.find(provides_port_name);
65 if (my_ports_it == my_ports.end()) {
66 // Creating a new port provides
67 port_t * new_port = new port_t();
68 new_port->type = provides;
69 new_port->connection_nbr = 0;
70 new_port->provides_port_ref = Ports::Port::_duplicate(ref);
71 new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
73 // Port into the port's map
74 my_ports[provides_port_name] = new_port;
77 throw Engines::DSC::PortAlreadyDefined();
81 Engines_DSC_interface::add_uses_port(const char* repository_id,
82 const char* uses_port_name,
83 Ports::PortProperties_ptr port_prop)
84 throw (Engines::DSC::PortAlreadyDefined,
85 Engines::DSC::BadProperty)
88 // Note : We can't be shure that repository id
89 // is a correct CORBA id.
90 assert(repository_id);
91 assert(uses_port_name);
92 if (CORBA::is_nil(port_prop))
93 throw Engines::DSC::BadProperty();
95 my_ports_it = my_ports.find(uses_port_name);
96 if (my_ports_it == my_ports.end()) {
97 // Creating a new uses port
98 port_t * new_port = new port_t();
99 new_port->type = uses;
100 new_port->connection_nbr = 0;
101 new_port->uses_port_refs.length(0);
102 new_port->repository_id = repository_id;
103 new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
105 // Port into port's map
106 my_ports[uses_port_name] = new_port;
109 throw Engines::DSC::PortAlreadyDefined();
113 Engines_DSC_interface::get_provides_port(const char* provides_port_name,
114 const CORBA::Boolean connection_error)
115 throw (Engines::DSC::PortNotDefined,
116 Engines::DSC::PortNotConnected,
117 Engines::DSC::BadPortType)
120 assert(provides_port_name);
122 Ports::Port_ptr rtn_port = Ports::Port::_nil();
123 // std::cout << "---- DSC_Interface : MARK 1 ---- Recherche de : " << provides_port_name << "----" << std::endl;
124 // ports::iterator it;
125 // std::cout << "----> ";
126 // for(it=my_ports.begin();it!=my_ports.end();++it)
127 // std::cout << "|"<<(*it).first<<"|, ";
128 // std::cout << std::endl;
130 // Searching the port
131 my_ports_it = my_ports.find(provides_port_name);
132 if (my_ports_it == my_ports.end())
133 throw Engines::DSC::PortNotDefined();
134 if (my_ports[provides_port_name]->type != provides) {
135 Engines::DSC::BadPortType BPT;
136 BPT.expected = CORBA::string_dup("Expected a provides port");
137 BPT.received = CORBA::string_dup((std::string("Received a uses/none port : ")+provides_port_name).c_str());
141 if (my_ports[provides_port_name]->connection_nbr == 0 && connection_error)
142 throw Engines::DSC::PortNotConnected();
144 rtn_port = Ports::Port::_duplicate(my_ports[provides_port_name]->provides_port_ref);
148 Engines::DSC::uses_port *
149 Engines_DSC_interface::get_uses_port(const char* uses_port_name)
150 throw (Engines::DSC::PortNotDefined,
151 Engines::DSC::PortNotConnected,
152 Engines::DSC::BadPortType)
155 assert(uses_port_name);
157 Engines::DSC::uses_port * rtn_port = NULL;
159 // Searching the uses port
160 my_ports_it = my_ports.find(uses_port_name);
161 if (my_ports_it == my_ports.end())
162 throw Engines::DSC::PortNotDefined();
163 if (my_ports[uses_port_name]->type != uses){
164 Engines::DSC::BadPortType BPT;
165 BPT.expected = CORBA::string_dup("Expected a uses port");
166 BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
168 std::cout << "---- DSC_Interface : MARK 1 ---- exception : " << uses_port_name << "----" << std::endl;
173 // Is the port connected ?
174 if (my_ports[uses_port_name]->connection_nbr > 0) {
175 rtn_port = new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs);
180 std::cout << "---- DSC_Interface : MARK 2 ---- exception : " << uses_port_name << "----" << std::endl;
182 throw Engines::DSC::PortNotConnected();
189 Engines_DSC_interface::connect_provides_port(const char* provides_port_name)
190 throw (Engines::DSC::PortNotDefined)
193 assert(provides_port_name);
195 // Searching the provides port
196 my_ports_it = my_ports.find(provides_port_name);
197 if (my_ports_it == my_ports.end())
198 throw Engines::DSC::PortNotDefined();
199 if (my_ports[provides_port_name]->type != provides)
200 throw Engines::DSC::PortNotDefined();
203 // Adding a new connection
204 my_ports[provides_port_name]->connection_nbr += 1;
205 // User code is informed
206 provides_port_changed(provides_port_name,
207 my_ports[provides_port_name]->connection_nbr,
208 Engines::DSC::AddingConnection
213 Engines_DSC_interface::connect_uses_port(const char* uses_port_name,
214 Ports::Port_ptr provides_port_ref)
215 throw (Engines::DSC::PortNotDefined,
216 Engines::DSC::BadPortType,
217 Engines::DSC::NilPort)
220 assert(uses_port_name);
222 if (CORBA::is_nil(provides_port_ref))
223 throw Engines::DSC::NilPort();
225 // Searching the uses port
226 my_ports_it = my_ports.find(uses_port_name);
227 if (my_ports_it == my_ports.end())
228 throw Engines::DSC::PortNotDefined();
229 if (my_ports[uses_port_name]->type != uses) {
230 Engines::DSC::BadPortType BPT;
231 BPT.expected = CORBA::string_dup("Expected a uses port");
232 BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
236 // repository_id test
237 const char * repository_id = my_ports[uses_port_name]->repository_id.c_str();
238 if (provides_port_ref->_is_a(repository_id))
240 // Adding provides port into the uses port sequence
241 CORBA::ULong lgth = my_ports[uses_port_name]->uses_port_refs.length();
242 my_ports[uses_port_name]->
243 uses_port_refs.length(lgth + 1);
244 my_ports[uses_port_name]->uses_port_refs[lgth] =
245 Ports::Port::_duplicate(provides_port_ref);
247 // Adding a new connection
248 my_ports[uses_port_name]->connection_nbr += 1;
249 // User code is informed
250 uses_port_changed(uses_port_name,
251 new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs),
252 Engines::DSC::AddingConnection);
255 Engines::DSC::BadPortType BPT;
256 BPT.expected = CORBA::string_dup("Expected ...");
257 BPT.received = CORBA::string_dup((std::string("Received an incorrect repository id type ")+
258 repository_id).c_str());
265 Engines_DSC_interface::is_connected(const char* port_name)
266 throw (Engines::DSC::PortNotDefined)
268 CORBA::Boolean rtn = false;
273 my_ports_it = my_ports.find(port_name);
274 if (my_ports_it == my_ports.end())
275 throw Engines::DSC::PortNotDefined();
278 if (my_ports[port_name]->connection_nbr > 0)
285 Engines_DSC_interface::disconnect_provides_port(const char* provides_port_name,
286 const Engines::DSC::Message message)
287 throw (Engines::DSC::PortNotDefined,
288 Engines::DSC::PortNotConnected)
291 assert(provides_port_name);
293 my_ports_it = my_ports.find(provides_port_name);
294 if (my_ports_it == my_ports.end())
295 throw Engines::DSC::PortNotDefined();
296 if (my_ports[provides_port_name]->type != provides)
297 throw Engines::DSC::PortNotDefined();
300 if (my_ports[provides_port_name]->connection_nbr > 0)
302 my_ports[provides_port_name]->connection_nbr -= 1;
303 provides_port_changed(provides_port_name,
304 my_ports[provides_port_name]->connection_nbr,
308 throw Engines::DSC::PortNotConnected();
312 Engines_DSC_interface::disconnect_uses_port(const char* uses_port_name,
313 Ports::Port_ptr provides_port_ref,
314 const Engines::DSC::Message message)
315 throw (Engines::DSC::PortNotDefined,
316 Engines::DSC::PortNotConnected,
317 Engines::DSC::BadPortReference)
320 assert(uses_port_name);
322 my_ports_it = my_ports.find(uses_port_name);
323 if (my_ports_it == my_ports.end())
324 throw Engines::DSC::PortNotDefined();
325 if (my_ports[uses_port_name]->type != uses)
326 throw Engines::DSC::PortNotDefined();
328 if (CORBA::is_nil(provides_port_ref))
329 throw Engines::DSC::BadPortReference();
332 if (my_ports[uses_port_name]->connection_nbr > 0) {
333 CORBA::Long port_index = -1;
334 CORBA::ULong seq_length = my_ports[uses_port_name]->uses_port_refs.length();
335 for(int i = 0; i < seq_length; i++)
337 if (my_ports[uses_port_name]->uses_port_refs[i]->_is_equivalent(provides_port_ref))
343 if (port_index == -1)
344 throw Engines::DSC::BadPortReference();
346 my_ports[uses_port_name]->connection_nbr -= 1;
347 Engines::DSC::uses_port * new_uses_port =
348 new Engines::DSC::uses_port();
349 new_uses_port->length(seq_length - 1);
351 int index_ancien = 0;
352 int index_nouveau = 0;
353 for(;index_ancien < seq_length;) {
354 if (index_ancien == port_index)
357 // On ne change pas le index du nouveau tableau
362 (*new_uses_port)[index_nouveau] = my_ports[uses_port_name]->uses_port_refs[index_ancien];
368 // New uses port's sequence
369 my_ports[uses_port_name]->uses_port_refs = *new_uses_port;
371 // The user code is informed
372 uses_port_changed(uses_port_name,
377 throw Engines::DSC::PortNotConnected();
380 Ports::PortProperties_ptr
381 Engines_DSC_interface::get_port_properties(const char* port_name)
382 throw (Engines::DSC::PortNotDefined)
384 Ports::PortProperties_ptr rtn_properties = Ports::PortProperties::_nil();
389 my_ports_it = my_ports.find(port_name);
390 if (my_ports_it == my_ports.end())
391 throw Engines::DSC::PortNotDefined();
393 rtn_properties = Ports::PortProperties::_duplicate(my_ports[port_name]->port_prop);
394 return rtn_properties;
397 //Trace functions for DSC operations: a local function (initTrace) and a class method (Engines_DSC_interface::writeEvent)
398 static int traceType=-1; // 0=stderr;1=file;
399 static int traceLevel=-1; // 0=no trace;1=normal trace;2=detailed trace
400 static std::ofstream traceFile;
401 static std::ostream *out;
403 //! Initialize the trace file
405 * The trace file depends on an environment variable (DSC_TRACE). If this variable
406 * is equal to 1, the trace file is a file with the name : <TMPDIR>/<container name>.tce.
407 * In all other cases, the trace file is stderr
408 * The environment variable DSC_TRACELEVEL can be used to suppress the trace (value 0)
410 * \param containerName the name of the container where the trace is built
412 static void initTrace(const std::string& containerName)
414 // if initialization has already been done do nothing
415 if(traceLevel >= 0)return;
417 std::string typeenv="0";
418 std::string levelenv="1";
420 valenv=getenv("DSC_TRACE");
421 if(valenv)typeenv=valenv;
422 valenv=getenv("DSC_TRACELEVEL");
423 if(valenv)levelenv=valenv;
426 traceLevel=0; // no trace
427 else if(levelenv=="2")
428 traceLevel=2; //detailed trace
430 traceLevel=1; // normal trace (default)
440 std::string logFilename=getenv("TEMP");
443 std::string logFilename="/tmp";
444 char* val = getenv("SALOME_TMP_DIR");
447 struct stat file_info;
448 stat(val, &file_info);
449 bool is_dir = S_ISDIR(file_info.st_mode);
450 if (is_dir)logFilename=val;
455 logFilename=logFilename+containerName+".tce";
456 traceFile.open(logFilename.c_str(), std::ios::out | std::ios::app);
461 //trace to stderr (default)
467 *out << "Elapsed time" ;
473 *out << "Container" ;
489 //! Write a record in the trace file
491 * \param request the name of the request executed
492 * \param containerName the name of the container where the request is executed
493 * \param instance_name the name of the component where the request is executed
494 * \param port_name the name of the port that is concerned
495 * \param error if an error has occured, a string that identifies the error
496 * \param message informations about error or about the request
498 void Engines_DSC_interface::writeEvent(const char* request,const std::string& containerName, const char* instance_name,
499 const char* port_name, const char* error, const char* message)
502 initTrace(containerName);
503 if(traceLevel == 0)return;
509 long tt0=tv.tv_sec/3600; //hours
513 //notifier (not used: salome notifier is now obsolete)
514 std::ostringstream msg;
518 long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
522 long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
526 long tt3=tv.tv_usec/1000; //milliseconds
534 //send event to notifier (containerName.c_str(),instance_name, request, msg.str().c_str())
542 long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
546 long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
550 long tt3=tv.tv_usec/1000; //milliseconds
558 *out << containerName ;
561 *out << instance_name ;