1 // Copyright (C) 2007-2010 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
23 // File : DSC_interface.cxx
24 // Author : André RIBES (EDF)
28 #include "DSC_interface.hxx"
40 Engines_DSC_interface::Engines_DSC_interface() {}
42 Engines_DSC_interface::~Engines_DSC_interface()
44 my_ports_it = my_ports.begin();
45 for(;my_ports_it != my_ports.end();my_ports_it++)
46 delete my_ports_it->second;
51 Engines_DSC_interface::add_provides_port(Ports::Port_ptr ref,
52 const char* provides_port_name,
53 Ports::PortProperties_ptr port_prop)
54 throw (Engines::DSC::PortAlreadyDefined,
55 Engines::DSC::NilPort,
56 Engines::DSC::BadProperty)
59 assert(provides_port_name);
60 if (CORBA::is_nil(ref))
61 throw Engines::DSC::NilPort();
62 if (CORBA::is_nil(port_prop))
63 throw Engines::DSC::BadProperty();
65 my_ports_it = my_ports.find(provides_port_name);
66 if (my_ports_it == my_ports.end()) {
67 // Creating a new port provides
68 port_t * new_port = new port_t();
69 new_port->type = provides;
70 new_port->connection_nbr = 0;
71 new_port->provides_port_ref = Ports::Port::_duplicate(ref);
72 new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
74 // Port into the port's map
75 my_ports[provides_port_name] = new_port;
78 throw Engines::DSC::PortAlreadyDefined();
82 Engines_DSC_interface::add_uses_port(const char* repository_id,
83 const char* uses_port_name,
84 Ports::PortProperties_ptr port_prop)
85 throw (Engines::DSC::PortAlreadyDefined,
86 Engines::DSC::BadProperty)
89 // Note : We can't be shure that repository id
90 // is a correct CORBA id.
91 assert(repository_id);
92 assert(uses_port_name);
93 if (CORBA::is_nil(port_prop))
94 throw Engines::DSC::BadProperty();
96 my_ports_it = my_ports.find(uses_port_name);
97 if (my_ports_it == my_ports.end()) {
98 // Creating a new uses port
99 port_t * new_port = new port_t();
100 new_port->type = uses;
101 new_port->connection_nbr = 0;
102 new_port->uses_port_refs.length(0);
103 new_port->repository_id = repository_id;
104 new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
106 // Port into port's map
107 my_ports[uses_port_name] = new_port;
110 throw Engines::DSC::PortAlreadyDefined();
114 Engines_DSC_interface::get_provides_port(const char* provides_port_name,
115 const CORBA::Boolean connection_error)
116 throw (Engines::DSC::PortNotDefined,
117 Engines::DSC::PortNotConnected,
118 Engines::DSC::BadPortType)
121 assert(provides_port_name);
123 Ports::Port_ptr rtn_port = Ports::Port::_nil();
124 // std::cout << "---- DSC_Interface : MARK 1 ---- Recherche de : " << provides_port_name << "----" << std::endl;
125 // ports::iterator it;
126 // std::cout << "----> ";
127 // for(it=my_ports.begin();it!=my_ports.end();++it)
128 // std::cout << "|"<<(*it).first<<"|, ";
129 // std::cout << std::endl;
131 // Searching the port
132 my_ports_it = my_ports.find(provides_port_name);
133 if (my_ports_it == my_ports.end())
134 throw Engines::DSC::PortNotDefined();
135 if (my_ports[provides_port_name]->type != provides) {
136 Engines::DSC::BadPortType BPT;
137 BPT.expected = CORBA::string_dup("Expected a provides port");
138 BPT.received = CORBA::string_dup((std::string("Received a uses/none port : ")+provides_port_name).c_str());
142 if (my_ports[provides_port_name]->connection_nbr == 0 && connection_error)
143 throw Engines::DSC::PortNotConnected();
145 rtn_port = Ports::Port::_duplicate(my_ports[provides_port_name]->provides_port_ref);
149 Engines::DSC::uses_port *
150 Engines_DSC_interface::get_uses_port(const char* uses_port_name)
151 throw (Engines::DSC::PortNotDefined,
152 Engines::DSC::PortNotConnected,
153 Engines::DSC::BadPortType)
156 assert(uses_port_name);
158 Engines::DSC::uses_port * rtn_port = NULL;
160 // Searching the uses port
161 my_ports_it = my_ports.find(uses_port_name);
162 if (my_ports_it == my_ports.end())
163 throw Engines::DSC::PortNotDefined();
164 if (my_ports[uses_port_name]->type != uses){
165 Engines::DSC::BadPortType BPT;
166 BPT.expected = CORBA::string_dup("Expected a uses port");
167 BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
169 std::cout << "---- DSC_Interface : MARK 1 ---- exception : " << uses_port_name << "----" << std::endl;
174 // Is the port connected ?
175 if (my_ports[uses_port_name]->connection_nbr > 0) {
176 rtn_port = new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs);
181 std::cout << "---- DSC_Interface : MARK 2 ---- exception : " << uses_port_name << "----" << std::endl;
183 throw Engines::DSC::PortNotConnected();
190 Engines_DSC_interface::connect_provides_port(const char* provides_port_name)
191 throw (Engines::DSC::PortNotDefined)
194 assert(provides_port_name);
196 // Searching the provides port
197 my_ports_it = my_ports.find(provides_port_name);
198 if (my_ports_it == my_ports.end())
199 throw Engines::DSC::PortNotDefined();
200 if (my_ports[provides_port_name]->type != provides)
201 throw Engines::DSC::PortNotDefined();
204 // Adding a new connection
205 my_ports[provides_port_name]->connection_nbr += 1;
206 // User code is informed
207 provides_port_changed(provides_port_name,
208 my_ports[provides_port_name]->connection_nbr,
209 Engines::DSC::AddingConnection
214 Engines_DSC_interface::connect_uses_port(const char* uses_port_name,
215 Ports::Port_ptr provides_port_ref)
216 throw (Engines::DSC::PortNotDefined,
217 Engines::DSC::BadPortType,
218 Engines::DSC::NilPort)
221 assert(uses_port_name);
223 if (CORBA::is_nil(provides_port_ref))
224 throw Engines::DSC::NilPort();
226 // Searching the uses port
227 my_ports_it = my_ports.find(uses_port_name);
228 if (my_ports_it == my_ports.end())
229 throw Engines::DSC::PortNotDefined();
230 if (my_ports[uses_port_name]->type != uses) {
231 Engines::DSC::BadPortType BPT;
232 BPT.expected = CORBA::string_dup("Expected a uses port");
233 BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
237 // repository_id test
238 const char * repository_id = my_ports[uses_port_name]->repository_id.c_str();
239 if (provides_port_ref->_is_a(repository_id))
241 // Adding provides port into the uses port sequence
242 CORBA::ULong lgth = my_ports[uses_port_name]->uses_port_refs.length();
243 my_ports[uses_port_name]->
244 uses_port_refs.length(lgth + 1);
245 my_ports[uses_port_name]->uses_port_refs[lgth] =
246 Ports::Port::_duplicate(provides_port_ref);
248 // Adding a new connection
249 my_ports[uses_port_name]->connection_nbr += 1;
250 // User code is informed
251 uses_port_changed(uses_port_name,
252 new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs),
253 Engines::DSC::AddingConnection);
256 Engines::DSC::BadPortType BPT;
257 BPT.expected = CORBA::string_dup("Expected ...");
258 BPT.received = CORBA::string_dup((std::string("Received an incorrect repository id type ")+
259 repository_id).c_str());
266 Engines_DSC_interface::is_connected(const char* port_name)
267 throw (Engines::DSC::PortNotDefined)
269 CORBA::Boolean rtn = false;
274 my_ports_it = my_ports.find(port_name);
275 if (my_ports_it == my_ports.end())
276 throw Engines::DSC::PortNotDefined();
279 if (my_ports[port_name]->connection_nbr > 0)
286 Engines_DSC_interface::disconnect_provides_port(const char* provides_port_name,
287 const Engines::DSC::Message message)
288 throw (Engines::DSC::PortNotDefined,
289 Engines::DSC::PortNotConnected)
292 assert(provides_port_name);
294 my_ports_it = my_ports.find(provides_port_name);
295 if (my_ports_it == my_ports.end())
296 throw Engines::DSC::PortNotDefined();
297 if (my_ports[provides_port_name]->type != provides)
298 throw Engines::DSC::PortNotDefined();
301 if (my_ports[provides_port_name]->connection_nbr > 0)
303 my_ports[provides_port_name]->connection_nbr -= 1;
304 provides_port_changed(provides_port_name,
305 my_ports[provides_port_name]->connection_nbr,
309 throw Engines::DSC::PortNotConnected();
313 Engines_DSC_interface::disconnect_uses_port(const char* uses_port_name,
314 Ports::Port_ptr provides_port_ref,
315 const Engines::DSC::Message message)
316 throw (Engines::DSC::PortNotDefined,
317 Engines::DSC::PortNotConnected,
318 Engines::DSC::BadPortReference)
321 assert(uses_port_name);
323 my_ports_it = my_ports.find(uses_port_name);
324 if (my_ports_it == my_ports.end())
325 throw Engines::DSC::PortNotDefined();
326 if (my_ports[uses_port_name]->type != uses)
327 throw Engines::DSC::PortNotDefined();
329 if (CORBA::is_nil(provides_port_ref))
330 throw Engines::DSC::BadPortReference();
333 if (my_ports[uses_port_name]->connection_nbr > 0) {
334 CORBA::Long port_index = -1;
335 CORBA::ULong seq_length = my_ports[uses_port_name]->uses_port_refs.length();
336 for(int i = 0; i < seq_length; i++)
338 if (my_ports[uses_port_name]->uses_port_refs[i]->_is_equivalent(provides_port_ref))
344 if (port_index == -1)
345 throw Engines::DSC::BadPortReference();
347 my_ports[uses_port_name]->connection_nbr -= 1;
348 Engines::DSC::uses_port * new_uses_port =
349 new Engines::DSC::uses_port();
350 new_uses_port->length(seq_length - 1);
352 int index_ancien = 0;
353 int index_nouveau = 0;
354 for(;index_ancien < seq_length;) {
355 if (index_ancien == port_index)
358 // On ne change pas le index du nouveau tableau
363 (*new_uses_port)[index_nouveau] = my_ports[uses_port_name]->uses_port_refs[index_ancien];
369 // New uses port's sequence
370 my_ports[uses_port_name]->uses_port_refs = *new_uses_port;
372 // The user code is informed
373 uses_port_changed(uses_port_name,
378 throw Engines::DSC::PortNotConnected();
381 Ports::PortProperties_ptr
382 Engines_DSC_interface::get_port_properties(const char* port_name)
383 throw (Engines::DSC::PortNotDefined)
385 Ports::PortProperties_ptr rtn_properties = Ports::PortProperties::_nil();
390 my_ports_it = my_ports.find(port_name);
391 if (my_ports_it == my_ports.end())
392 throw Engines::DSC::PortNotDefined();
394 rtn_properties = Ports::PortProperties::_duplicate(my_ports[port_name]->port_prop);
395 return rtn_properties;
398 //Trace functions for DSC operations: a local function (initTrace) and a class method (Engines_DSC_interface::writeEvent)
399 static int traceType=-1; // 0=stderr;1=file;
400 static int traceLevel=-1; // 0=no trace;1=normal trace;2=detailed trace
401 static std::ofstream traceFile;
402 static std::ostream *out;
404 //! Initialize the trace file
406 * The trace file depends on an environment variable (DSC_TRACE). If this variable
407 * is equal to 1, the trace file is a file with the name : <TMPDIR>/<container name>.tce.
408 * In all other cases, the trace file is stderr
409 * The environment variable DSC_TRACELEVEL can be used to suppress the trace (value 0)
411 * \param containerName the name of the container where the trace is built
413 static void initTrace(const std::string& containerName)
415 // if initialization has already been done do nothing
416 if(traceLevel >= 0)return;
418 std::string typeenv="0";
419 std::string levelenv="1";
421 valenv=getenv("DSC_TRACE");
422 if(valenv)typeenv=valenv;
423 valenv=getenv("DSC_TRACELEVEL");
424 if(valenv)levelenv=valenv;
427 traceLevel=0; // no trace
428 else if(levelenv=="2")
429 traceLevel=2; //detailed trace
431 traceLevel=1; // normal trace (default)
441 std::string logFilename=getenv("TEMP");
444 std::string logFilename="/tmp";
445 char* val = getenv("SALOME_TMP_DIR");
448 struct stat file_info;
449 stat(val, &file_info);
450 bool is_dir = S_ISDIR(file_info.st_mode);
451 if (is_dir)logFilename=val;
456 logFilename=logFilename+containerName+".tce";
457 traceFile.open(logFilename.c_str(), std::ios::out | std::ios::app);
462 //trace to stderr (default)
468 *out << "Elapsed time" ;
474 *out << "Container" ;
490 //! Write a record in the trace file
492 * \param request the name of the request executed
493 * \param containerName the name of the container where the request is executed
494 * \param instance_name the name of the component where the request is executed
495 * \param port_name the name of the port that is concerned
496 * \param error if an error has occured, a string that identifies the error
497 * \param message informations about error or about the request
499 void Engines_DSC_interface::writeEvent(const char* request,const std::string& containerName, const char* instance_name,
500 const char* port_name, const char* error, const char* message)
503 initTrace(containerName);
504 if(traceLevel == 0)return;
510 long tt0=tv.tv_sec/3600; //hours
514 //notifier (not used: salome notifier is now obsolete)
515 std::ostringstream msg;
519 long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
523 long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
527 long tt3=tv.tv_usec/1000; //milliseconds
535 //send event to notifier (containerName.c_str(),instance_name, request, msg.str().c_str())
543 long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
547 long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
551 long tt3=tv.tv_usec/1000; //milliseconds
559 *out << containerName ;
562 *out << instance_name ;