1 // Copyright (C) 2007-2024 CEA, EDF, 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, or (at your option) any later version.
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"
38 #include "utilities.h"
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)
56 assert(provides_port_name);
57 if (CORBA::is_nil(ref))
58 throw Engines::DSC::NilPort();
59 if (CORBA::is_nil(port_prop))
60 throw Engines::DSC::BadProperty();
62 my_ports_it = my_ports.find(provides_port_name);
63 if (my_ports_it == my_ports.end()) {
64 // Creating a new port provides
65 port_t * new_port = new port_t();
66 new_port->type = provides;
67 new_port->connection_nbr = 0;
68 new_port->provides_port_ref = Ports::Port::_duplicate(ref);
69 new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
71 // Port into the port's map
72 my_ports[provides_port_name] = new_port;
75 throw Engines::DSC::PortAlreadyDefined();
79 Engines_DSC_interface::add_uses_port(const char* repository_id,
80 const char* uses_port_name,
81 Ports::PortProperties_ptr port_prop)
84 // Note : We can't be shure that repository id
85 // is a correct CORBA id.
86 assert(repository_id);
87 assert(uses_port_name);
88 if (CORBA::is_nil(port_prop))
89 throw Engines::DSC::BadProperty();
91 my_ports_it = my_ports.find(uses_port_name);
92 if (my_ports_it == my_ports.end()) {
93 // Creating a new uses port
94 port_t * new_port = new port_t();
95 new_port->type = uses;
96 new_port->connection_nbr = 0;
97 new_port->uses_port_refs.length(0);
98 new_port->repository_id = repository_id;
99 new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
101 // Port into port's map
102 my_ports[uses_port_name] = new_port;
105 throw Engines::DSC::PortAlreadyDefined();
109 Engines_DSC_interface::get_provides_port(const char* provides_port_name,
110 const CORBA::Boolean connection_error)
113 assert(provides_port_name);
115 Ports::Port_ptr rtn_port = Ports::Port::_nil();
116 // std::cout << "---- DSC_Interface : MARK 1 ---- Recherche de : " << provides_port_name << "----" << std::endl;
117 // ports::iterator it;
118 // std::cout << "----> ";
119 // for(it=my_ports.begin();it!=my_ports.end();++it)
120 // std::cout << "|"<<(*it).first<<"|, ";
121 // std::cout << std::endl;
123 // Searching the port
124 my_ports_it = my_ports.find(provides_port_name);
125 if (my_ports_it == my_ports.end())
126 throw Engines::DSC::PortNotDefined();
127 if (my_ports[provides_port_name]->type != provides) {
128 Engines::DSC::BadPortType BPT;
129 BPT.expected = CORBA::string_dup("Expected a provides port");
130 BPT.received = CORBA::string_dup((std::string("Received a uses/none port : ")+provides_port_name).c_str());
134 if (my_ports[provides_port_name]->connection_nbr == 0 && connection_error)
135 throw Engines::DSC::PortNotConnected();
137 rtn_port = Ports::Port::_duplicate(my_ports[provides_port_name]->provides_port_ref);
141 Engines::DSC::uses_port *
142 Engines_DSC_interface::get_uses_port(const char* uses_port_name)
145 assert(uses_port_name);
147 Engines::DSC::uses_port * rtn_port = NULL;
149 // Searching the uses port
150 my_ports_it = my_ports.find(uses_port_name);
151 if (my_ports_it == my_ports.end())
152 throw Engines::DSC::PortNotDefined();
153 if (my_ports[uses_port_name]->type != uses){
154 Engines::DSC::BadPortType BPT;
155 BPT.expected = CORBA::string_dup("Expected a uses port");
156 BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
158 if (SALOME::VerbosityActivated())
159 std::cout << "---- DSC_Interface : MARK 1 ---- exception : " << uses_port_name << "----" << std::endl;
164 // Is the port connected ?
165 if (my_ports[uses_port_name]->connection_nbr > 0) {
166 rtn_port = new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs);
170 if (SALOME::VerbosityActivated())
171 std::cout << "---- DSC_Interface : MARK 2 ---- exception : " << uses_port_name << "----" << std::endl;
173 throw Engines::DSC::PortNotConnected();
180 Engines_DSC_interface::connect_provides_port(const char* provides_port_name)
183 assert(provides_port_name);
185 // Searching the provides port
186 my_ports_it = my_ports.find(provides_port_name);
187 if (my_ports_it == my_ports.end())
188 throw Engines::DSC::PortNotDefined();
189 if (my_ports[provides_port_name]->type != provides)
190 throw Engines::DSC::PortNotDefined();
193 // Adding a new connection
194 my_ports[provides_port_name]->connection_nbr += 1;
195 // User code is informed
196 provides_port_changed(provides_port_name,
197 my_ports[provides_port_name]->connection_nbr,
198 Engines::DSC::AddingConnection
203 Engines_DSC_interface::connect_uses_port(const char* uses_port_name,
204 Ports::Port_ptr provides_port_ref)
207 assert(uses_port_name);
209 if (CORBA::is_nil(provides_port_ref))
210 throw Engines::DSC::NilPort();
212 // Searching the uses port
213 my_ports_it = my_ports.find(uses_port_name);
214 if (my_ports_it == my_ports.end())
215 throw Engines::DSC::PortNotDefined();
216 if (my_ports[uses_port_name]->type != uses) {
217 Engines::DSC::BadPortType BPT;
218 BPT.expected = CORBA::string_dup("Expected a uses port");
219 BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
223 // repository_id test
224 const char * repository_id = my_ports[uses_port_name]->repository_id.c_str();
225 if (provides_port_ref->_is_a(repository_id))
227 // Adding provides port into the uses port sequence
228 CORBA::ULong lgth = my_ports[uses_port_name]->uses_port_refs.length();
229 my_ports[uses_port_name]->
230 uses_port_refs.length(lgth + 1);
231 my_ports[uses_port_name]->uses_port_refs[lgth] =
232 Ports::Port::_duplicate(provides_port_ref);
234 // Adding a new connection
235 my_ports[uses_port_name]->connection_nbr += 1;
236 // User code is informed
237 uses_port_changed(uses_port_name,
238 new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs),
239 Engines::DSC::AddingConnection);
242 Engines::DSC::BadPortType BPT;
243 BPT.expected = CORBA::string_dup("Expected ...");
244 BPT.received = CORBA::string_dup((std::string("Received an incorrect repository id type ")+
245 repository_id).c_str());
252 Engines_DSC_interface::is_connected(const char* port_name)
254 CORBA::Boolean rtn = false;
259 my_ports_it = my_ports.find(port_name);
260 if (my_ports_it == my_ports.end())
261 throw Engines::DSC::PortNotDefined();
264 if (my_ports[port_name]->connection_nbr > 0)
271 Engines_DSC_interface::disconnect_provides_port(const char* provides_port_name,
272 const Engines::DSC::Message message)
275 assert(provides_port_name);
277 my_ports_it = my_ports.find(provides_port_name);
278 if (my_ports_it == my_ports.end())
279 throw Engines::DSC::PortNotDefined();
280 if (my_ports[provides_port_name]->type != provides)
281 throw Engines::DSC::PortNotDefined();
284 if (my_ports[provides_port_name]->connection_nbr > 0)
286 my_ports[provides_port_name]->connection_nbr -= 1;
287 provides_port_changed(provides_port_name,
288 my_ports[provides_port_name]->connection_nbr,
292 throw Engines::DSC::PortNotConnected();
296 Engines_DSC_interface::disconnect_uses_port(const char* uses_port_name,
297 Ports::Port_ptr provides_port_ref,
298 const Engines::DSC::Message message)
301 assert(uses_port_name);
303 my_ports_it = my_ports.find(uses_port_name);
304 if (my_ports_it == my_ports.end())
305 throw Engines::DSC::PortNotDefined();
306 if (my_ports[uses_port_name]->type != uses)
307 throw Engines::DSC::PortNotDefined();
309 if (CORBA::is_nil(provides_port_ref))
310 throw Engines::DSC::BadPortReference();
313 if (my_ports[uses_port_name]->connection_nbr > 0) {
314 CORBA::Long port_index = -1;
315 CORBA::ULong seq_length = my_ports[uses_port_name]->uses_port_refs.length();
316 for(int i = 0; i < (int)seq_length; i++)
318 if (my_ports[uses_port_name]->uses_port_refs[i]->_is_equivalent(provides_port_ref))
324 if (port_index == -1)
325 throw Engines::DSC::BadPortReference();
327 my_ports[uses_port_name]->connection_nbr -= 1;
328 Engines::DSC::uses_port * new_uses_port =
329 new Engines::DSC::uses_port();
330 new_uses_port->length(seq_length - 1);
332 int index_ancien = 0;
333 int index_nouveau = 0;
334 for(;index_ancien < (int)seq_length;) {
335 if (index_ancien == port_index)
338 // On ne change pas le index du nouveau tableau
343 (*new_uses_port)[index_nouveau] = my_ports[uses_port_name]->uses_port_refs[index_ancien];
349 // New uses port's sequence
350 my_ports[uses_port_name]->uses_port_refs = *new_uses_port;
352 // The user code is informed
353 uses_port_changed(uses_port_name,
358 throw Engines::DSC::PortNotConnected();
361 Ports::PortProperties_ptr
362 Engines_DSC_interface::get_port_properties(const char* port_name)
364 Ports::PortProperties_ptr rtn_properties = Ports::PortProperties::_nil();
369 my_ports_it = my_ports.find(port_name);
370 if (my_ports_it == my_ports.end())
371 throw Engines::DSC::PortNotDefined();
373 rtn_properties = Ports::PortProperties::_duplicate(my_ports[port_name]->port_prop);
374 return rtn_properties;
377 //Trace functions for DSC operations: a local function (initTrace) and a class method (Engines_DSC_interface::writeEvent)
378 static int traceType=-1; // 0=stderr;1=file;
379 static int traceLevel=-1; // 0=no trace;1=normal trace;2=detailed trace
380 static std::ofstream traceFile;
381 static std::ostream *out;
383 //! Initialize the trace file
385 * The trace file depends on an environment variable (DSC_TRACE). If this variable
386 * is equal to 1, the trace file is a file with the name : <TMPDIR>/<container name>.tce.
387 * In all other cases, the trace file is stderr
388 * The environment variable DSC_TRACELEVEL can be used to suppress the trace (value 0)
390 * \param containerName the name of the container where the trace is built
392 static void initTrace(const std::string& containerName)
394 // if initialization has already been done do nothing
395 if(traceLevel >= 0)return;
397 std::string typeenv="0";
398 std::string levelenv="1";
400 valenv=getenv("DSC_TRACE");
401 if(valenv)typeenv=valenv;
402 valenv=getenv("DSC_TRACELEVEL");
403 if(valenv)levelenv=valenv;
406 traceLevel=0; // no trace
407 else if(levelenv=="2")
408 traceLevel=2; //detailed trace
410 traceLevel=1; // normal trace (default)
420 std::string logFilename=getenv("TEMP");
423 std::string logFilename="/tmp";
424 char* val = getenv("SALOME_TMP_DIR");
427 struct stat file_info;
428 stat(val, &file_info);
429 bool is_dir = S_ISDIR(file_info.st_mode);
430 if (is_dir)logFilename=val;
435 logFilename=logFilename+containerName+".tce";
436 traceFile.open(logFilename.c_str(), std::ios::out | std::ios::app);
441 //trace to stderr (default)
447 *out << "Elapsed time" ;
453 *out << "Container" ;
469 //! Write a record in the trace file
471 * \param request the name of the request executed
472 * \param containerName the name of the container where the request is executed
473 * \param instance_name the name of the component where the request is executed
474 * \param port_name the name of the port that is concerned
475 * \param error if an error has occured, a string that identifies the error
476 * \param message informations about error or about the request
478 void Engines_DSC_interface::writeEvent(const char* request,const std::string& containerName, const char* instance_name,
479 const char* port_name, const char* error, const char* message)
482 initTrace(containerName);
483 if(traceLevel == 0)return;
489 long tt0=tv.tv_sec/3600; //hours
493 //notifier (not used: salome notifier is now obsolete)
494 std::ostringstream msg;
498 long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
502 long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
506 long tt3=tv.tv_usec/1000; //milliseconds
514 //send event to notifier (containerName.c_str(),instance_name, request, msg.str().c_str())
522 long tt1=(tv.tv_sec-3600*tt0)/60;//minutes
526 long tt2=tv.tv_sec - 3600*tt0-60*tt1; //seconds
530 long tt3=tv.tv_usec/1000; //milliseconds
538 *out << containerName ;
541 *out << instance_name ;