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"
36 Engines_DSC_interface::Engines_DSC_interface() {}
38 Engines_DSC_interface::~Engines_DSC_interface()
40 my_ports_it = my_ports.begin();
41 for(;my_ports_it != my_ports.end();my_ports_it++)
42 delete my_ports_it->second;
47 Engines_DSC_interface::add_provides_port(Ports::Port_ptr ref,
48 const char* provides_port_name,
49 Ports::PortProperties_ptr port_prop)
50 throw (Engines::DSC::PortAlreadyDefined,
51 Engines::DSC::NilPort,
52 Engines::DSC::BadProperty)
55 assert(provides_port_name);
56 if (CORBA::is_nil(ref))
57 throw Engines::DSC::NilPort();
58 if (CORBA::is_nil(port_prop))
59 throw Engines::DSC::BadProperty();
61 my_ports_it = my_ports.find(provides_port_name);
62 if (my_ports_it == my_ports.end()) {
63 // Creating a new port provides
64 port_t * new_port = new port_t();
65 new_port->type = provides;
66 new_port->connection_nbr = 0;
67 new_port->provides_port_ref = Ports::Port::_duplicate(ref);
68 new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
70 // Port into the port's map
71 my_ports[provides_port_name] = new_port;
74 throw Engines::DSC::PortAlreadyDefined();
78 Engines_DSC_interface::add_uses_port(const char* repository_id,
79 const char* uses_port_name,
80 Ports::PortProperties_ptr port_prop)
81 throw (Engines::DSC::PortAlreadyDefined,
82 Engines::DSC::BadProperty)
85 // Note : We can't be shure that repository id
86 // is a correct CORBA id.
87 assert(repository_id);
88 assert(uses_port_name);
89 if (CORBA::is_nil(port_prop))
90 throw Engines::DSC::BadProperty();
92 my_ports_it = my_ports.find(uses_port_name);
93 if (my_ports_it == my_ports.end()) {
94 // Creating a new uses port
95 port_t * new_port = new port_t();
96 new_port->type = uses;
97 new_port->connection_nbr = 0;
98 new_port->uses_port_refs.length(0);
99 new_port->repository_id = repository_id;
100 new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
102 // Port into port's map
103 my_ports[uses_port_name] = new_port;
106 throw Engines::DSC::PortAlreadyDefined();
110 Engines_DSC_interface::get_provides_port(const char* provides_port_name,
111 const CORBA::Boolean connection_error)
112 throw (Engines::DSC::PortNotDefined,
113 Engines::DSC::PortNotConnected,
114 Engines::DSC::BadPortType)
117 assert(provides_port_name);
119 Ports::Port_ptr rtn_port = Ports::Port::_nil();
120 // std::cout << "---- DSC_Interface : MARK 1 ---- Recherche de : " << provides_port_name << "----" << std::endl;
121 // ports::iterator it;
122 // std::cout << "----> ";
123 // for(it=my_ports.begin();it!=my_ports.end();++it)
124 // std::cout << "|"<<(*it).first<<"|, ";
125 // std::cout << std::endl;
127 // Searching the port
128 my_ports_it = my_ports.find(provides_port_name);
129 if (my_ports_it == my_ports.end())
130 throw Engines::DSC::PortNotDefined();
131 if (my_ports[provides_port_name]->type != provides) {
132 Engines::DSC::BadPortType BPT;
133 BPT.expected = CORBA::string_dup("Expected a provides port");
134 BPT.received = CORBA::string_dup((std::string("Received a uses/none port : ")+provides_port_name).c_str());
138 if (my_ports[provides_port_name]->connection_nbr == 0 && connection_error)
139 throw Engines::DSC::PortNotConnected();
141 rtn_port = Ports::Port::_duplicate(my_ports[provides_port_name]->provides_port_ref);
145 Engines::DSC::uses_port *
146 Engines_DSC_interface::get_uses_port(const char* uses_port_name)
147 throw (Engines::DSC::PortNotDefined,
148 Engines::DSC::PortNotConnected,
149 Engines::DSC::BadPortType)
152 assert(uses_port_name);
154 Engines::DSC::uses_port * rtn_port = NULL;
156 // Searching the uses port
157 my_ports_it = my_ports.find(uses_port_name);
158 if (my_ports_it == my_ports.end())
159 throw Engines::DSC::PortNotDefined();
160 if (my_ports[uses_port_name]->type != uses){
161 Engines::DSC::BadPortType BPT;
162 BPT.expected = CORBA::string_dup("Expected a uses port");
163 BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
165 std::cout << "---- DSC_Interface : MARK 1 ---- exception : " << uses_port_name << "----" << std::endl;
170 // Is the port connected ?
171 if (my_ports[uses_port_name]->connection_nbr > 0) {
172 rtn_port = new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs);
177 std::cout << "---- DSC_Interface : MARK 2 ---- exception : " << uses_port_name << "----" << std::endl;
179 throw Engines::DSC::PortNotConnected();
186 Engines_DSC_interface::connect_provides_port(const char* provides_port_name)
187 throw (Engines::DSC::PortNotDefined)
190 assert(provides_port_name);
192 // Searching the provides port
193 my_ports_it = my_ports.find(provides_port_name);
194 if (my_ports_it == my_ports.end())
195 throw Engines::DSC::PortNotDefined();
196 if (my_ports[provides_port_name]->type != provides)
197 throw Engines::DSC::PortNotDefined();
200 // Adding a new connection
201 my_ports[provides_port_name]->connection_nbr += 1;
202 // User code is informed
203 provides_port_changed(provides_port_name,
204 my_ports[provides_port_name]->connection_nbr,
205 Engines::DSC::AddingConnection
210 Engines_DSC_interface::connect_uses_port(const char* uses_port_name,
211 Ports::Port_ptr provides_port_ref)
212 throw (Engines::DSC::PortNotDefined,
213 Engines::DSC::BadPortType,
214 Engines::DSC::NilPort)
217 assert(uses_port_name);
219 if (CORBA::is_nil(provides_port_ref))
220 throw Engines::DSC::NilPort();
222 // Searching the uses port
223 my_ports_it = my_ports.find(uses_port_name);
224 if (my_ports_it == my_ports.end())
225 throw Engines::DSC::PortNotDefined();
226 if (my_ports[uses_port_name]->type != uses) {
227 Engines::DSC::BadPortType BPT;
228 BPT.expected = CORBA::string_dup("Expected a uses port");
229 BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
233 // repository_id test
234 const char * repository_id = my_ports[uses_port_name]->repository_id.c_str();
235 if (provides_port_ref->_is_a(repository_id))
237 // Adding provides port into the uses port sequence
238 CORBA::ULong lgth = my_ports[uses_port_name]->uses_port_refs.length();
239 my_ports[uses_port_name]->
240 uses_port_refs.length(lgth + 1);
241 my_ports[uses_port_name]->uses_port_refs[lgth] =
242 Ports::Port::_duplicate(provides_port_ref);
244 // Adding a new connection
245 my_ports[uses_port_name]->connection_nbr += 1;
246 // User code is informed
247 uses_port_changed(uses_port_name,
248 new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs),
249 Engines::DSC::AddingConnection);
252 Engines::DSC::BadPortType BPT;
253 BPT.expected = CORBA::string_dup("Expected ...");
254 BPT.received = CORBA::string_dup((std::string("Received an incorrect repository id type ")+
255 repository_id).c_str());
262 Engines_DSC_interface::is_connected(const char* port_name)
263 throw (Engines::DSC::PortNotDefined)
265 CORBA::Boolean rtn = false;
270 my_ports_it = my_ports.find(port_name);
271 if (my_ports_it == my_ports.end())
272 throw Engines::DSC::PortNotDefined();
275 if (my_ports[port_name]->connection_nbr > 0)
282 Engines_DSC_interface::disconnect_provides_port(const char* provides_port_name,
283 const Engines::DSC::Message message)
284 throw (Engines::DSC::PortNotDefined,
285 Engines::DSC::PortNotConnected)
288 assert(provides_port_name);
290 my_ports_it = my_ports.find(provides_port_name);
291 if (my_ports_it == my_ports.end())
292 throw Engines::DSC::PortNotDefined();
293 if (my_ports[provides_port_name]->type != provides)
294 throw Engines::DSC::PortNotDefined();
297 if (my_ports[provides_port_name]->connection_nbr > 0)
299 my_ports[provides_port_name]->connection_nbr -= 1;
300 provides_port_changed(provides_port_name,
301 my_ports[provides_port_name]->connection_nbr,
305 throw Engines::DSC::PortNotConnected();
309 Engines_DSC_interface::disconnect_uses_port(const char* uses_port_name,
310 Ports::Port_ptr provides_port_ref,
311 const Engines::DSC::Message message)
312 throw (Engines::DSC::PortNotDefined,
313 Engines::DSC::PortNotConnected,
314 Engines::DSC::BadPortReference)
317 assert(uses_port_name);
319 my_ports_it = my_ports.find(uses_port_name);
320 if (my_ports_it == my_ports.end())
321 throw Engines::DSC::PortNotDefined();
322 if (my_ports[uses_port_name]->type != uses)
323 throw Engines::DSC::PortNotDefined();
325 if (CORBA::is_nil(provides_port_ref))
326 throw Engines::DSC::BadPortReference();
329 if (my_ports[uses_port_name]->connection_nbr > 0) {
330 CORBA::Long port_index = -1;
331 CORBA::ULong seq_length = my_ports[uses_port_name]->uses_port_refs.length();
332 for(int i = 0; i < seq_length; i++)
334 if (my_ports[uses_port_name]->uses_port_refs[i]->_is_equivalent(provides_port_ref))
340 if (port_index == -1)
341 throw Engines::DSC::BadPortReference();
343 my_ports[uses_port_name]->connection_nbr -= 1;
344 Engines::DSC::uses_port * new_uses_port =
345 new Engines::DSC::uses_port();
346 new_uses_port->length(seq_length - 1);
348 int index_ancien = 0;
349 int index_nouveau = 0;
350 for(;index_ancien < seq_length;) {
351 if (index_ancien == port_index)
354 // On ne change pas le index du nouveau tableau
359 (*new_uses_port)[index_nouveau] = my_ports[uses_port_name]->uses_port_refs[index_ancien];
365 // New uses port's sequence
366 my_ports[uses_port_name]->uses_port_refs = *new_uses_port;
368 // The user code is informed
369 uses_port_changed(uses_port_name,
374 throw Engines::DSC::PortNotConnected();
377 Ports::PortProperties_ptr
378 Engines_DSC_interface::get_port_properties(const char* port_name)
379 throw (Engines::DSC::PortNotDefined)
381 Ports::PortProperties_ptr rtn_properties = Ports::PortProperties::_nil();
386 my_ports_it = my_ports.find(port_name);
387 if (my_ports_it == my_ports.end())
388 throw Engines::DSC::PortNotDefined();
390 rtn_properties = Ports::PortProperties::_duplicate(my_ports[port_name]->port_prop);
391 return rtn_properties;
394 //Trace functions for DSC operations: a local function (initTrace) and a class method (Engines_DSC_interface::writeEvent)
395 static int traceType=-1; // 0=stderr;1=file;
396 static int traceLevel=-1; // 0=no trace;1=normal trace;2=detailed trace
397 static std::ofstream traceFile;
398 static std::ostream *out;
400 //! Initialize the trace file
402 * The trace file depends on an environment variable (DSC_TRACE). If this variable
403 * is equal to 1, the trace file is a file with the name : <TMPDIR>/<container name>.tce.
404 * In all other cases, the trace file is stderr
405 * The environment variable DSC_TRACELEVEL can be used to suppress the trace (value 0)
407 * \param containerName the name of the container where the trace is built
409 static void initTrace(const std::string& containerName)
411 // if initialization has already been done do nothing
412 if(traceLevel >= 0)return;
414 std::string typeenv="0";
415 std::string levelenv="1";
417 valenv=getenv("DSC_TRACE");
418 if(valenv)typeenv=valenv;
419 valenv=getenv("DSC_TRACELEVEL");
420 if(valenv)levelenv=valenv;
423 traceLevel=0; // no trace
424 else if(levelenv=="2")
425 traceLevel=2; //detailed trace
427 traceLevel=1; // normal trace (default)
437 std::string logFilename=getenv("TEMP");
440 std::string logFilename="/tmp";
441 char* val = getenv("SALOME_TMP_DIR");
444 struct stat file_info;
445 stat(val, &file_info);
446 bool is_dir = S_ISDIR(file_info.st_mode);
447 if (is_dir)logFilename=val;
452 logFilename=logFilename+containerName+".tce";
453 traceFile.open(logFilename.c_str(), std::ios::out | std::ios::app);
458 //trace to stderr (default)
464 *out << "Elapsed time" ;
470 *out << "Container" ;
486 //! Write a record in the trace file
488 * \param request the name of the request executed
489 * \param containerName the name of the container where the request is executed
490 * \param instance_name the name of the component where the request is executed
491 * \param port_name the name of the port that is concerned
492 * \param error if an error has occured, a string that identifies the error
493 * \param message informations about error or about the request
495 void Engines_DSC_interface::writeEvent(const char* request,const std::string& containerName, const char* instance_name,
496 const char* port_name, const char* error, const char* message)
499 initTrace(containerName);
500 if(traceLevel == 0)return;
504 long tt0=tv.tv_sec/3600; //hours
508 //notifier (not used: salome notifier is now obsolete)
509 std::ostringstream msg;
513 long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
517 long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
521 long tt3=tv.tv_usec/1000; //milliseconds
529 //send event to notifier (containerName.c_str(),instance_name, request, msg.str().c_str())
537 long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
541 long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
545 long tt3=tv.tv_usec/1000; //milliseconds
553 *out << containerName ;
556 *out << instance_name ;