Version: 8.3.0
Proc.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 
20 #include "Proc.hxx"
21 #include "ElementaryNode.hxx"
22 #include "Runtime.hxx"
23 #include "Container.hxx"
24 #include "ComponentInstance.hxx"
25 #include "InputPort.hxx"
26 #include "OutputPort.hxx"
27 #include "TypeCode.hxx"
28 #include "Logger.hxx"
29 #include "Visitor.hxx"
30 #include "VisitorSaveSchema.hxx"
31 #include "VisitorSaveState.hxx"
32 #include <sstream>
33 #include <set>
34 
35 //#define _DEVDEBUG_
36 #include "YacsTrace.hxx"
37 
38 using namespace std;
39 using namespace YACS::ENGINE;
40 
48 Proc::Proc(const std::string& name):Bloc(name),_edition(false),_compoinstctr(0)
49 {
51  DEBTRACE("theRuntime->_tc_double->ref: " << theRuntime->_tc_double->getRefCnt());
52  DEBTRACE("theRuntime->_tc_int->ref: " << theRuntime->_tc_int->getRefCnt());
53  DEBTRACE("theRuntime->_tc_string->ref: " << theRuntime->_tc_string->getRefCnt());
54  DEBTRACE("theRuntime->_tc_bool->ref: " << theRuntime->_tc_bool->getRefCnt());
55  DEBTRACE("theRuntime->_tc_file->ref: " << theRuntime->_tc_file->getRefCnt());
56  theRuntime->_tc_double->incrRef();
57  theRuntime->_tc_string->incrRef();
58  theRuntime->_tc_int->incrRef();
59  theRuntime->_tc_bool->incrRef();
60  theRuntime->_tc_file->incrRef();
61  typeMap["double"]=theRuntime->_tc_double;
62  typeMap["string"]=theRuntime->_tc_string;
63  typeMap["int"]=theRuntime->_tc_int;
64  typeMap["bool"]=theRuntime->_tc_bool;
65  typeMap["file"]=theRuntime->_tc_file;
66 }
67 
69 {
70  DEBTRACE("Proc::~Proc");
71  //for the moment all nodes are owned, so no need to manage their destruction
72  //nodeMap, inlineMap, serviceMap will be cleared automatically
73  //but we need to destroy TypeCodes
74  std::map<std::string, TypeCode *>::iterator pt;
75  for(pt=typeMap.begin();pt!=typeMap.end();pt++)
76  ((*pt).second)->decrRef();
77 
79 
80  //get rid of loggers in logger map
81  std::map<std::string, Logger*>::const_iterator lt;
82  for(lt=_loggers.begin();lt!=_loggers.end();lt++)
83  delete (*lt).second;
84 }
85 
86 void Proc::writeDot(std::ostream &os) const
87 {
88  os << "digraph " << getQualifiedName() << " {\n" ;
89  os << "node [ style=\"filled\" ];\n" ;
90  os << "compound=true;";
91  os << "states [label=< <TABLE> <TR> <TD BGCOLOR=\"pink\" > Ready</TD> <TD BGCOLOR=\"magenta\" > Toload</TD> </TR> <TR> <TD BGCOLOR=\"magenta\" > Loaded</TD> <TD BGCOLOR=\"purple\" > Toactivate</TD> </TR> <TR> <TD BGCOLOR=\"blue\" > Activated</TD> <TD BGCOLOR=\"green\" > Done</TD> </TR> <TR> <TD BGCOLOR=\"red\" > Error</TD> <TD BGCOLOR=\"orange\" > Failed</TD> </TR> <TR> <TD BGCOLOR=\"grey\" > Disabled</TD> <TD BGCOLOR=\"white\" > Pause</TD> </TR> </TABLE>> \n shape = plaintext \n style = invis \n ];\n";
92 
93  Bloc::writeDot(os);
94  os << "}\n" ;
95 }
96 
97 std::ostream& operator<< (std::ostream& os, const Proc& p)
98 {
99  os << "Proc" ;
100  return os;
101 }
102 
103 TypeCode *Proc::createType(const std::string& name, const std::string& kind)
104 {
105  TypeCode* t;
106  if(kind=="double")
107  t=getRuntime()->_tc_double;
108  else if(kind=="string")
109  t=getRuntime()->_tc_string;
110  else if(kind=="int")
111  t=getRuntime()->_tc_int;
112  else if(kind=="bool")
113  t=getRuntime()->_tc_bool;
114  else
115  throw Exception("Unknown kind");
116 
117  if(typeMap.count(name)!=0)
118  typeMap[name]->decrRef();
119  t->incrRef();
120  typeMap[name]=t;
121  t->incrRef();
122  return t;
123 }
124 
126 
132 TypeCode *Proc::createInterfaceTc(const std::string& id, const std::string& name,
133  std::list<TypeCodeObjref *> ltc)
134 {
135  TypeCode* t = TypeCode::interfaceTc(id.c_str(),name.c_str(),ltc);
136  if(typeMap.count(name)!=0)
137  typeMap[name]->decrRef();
138  typeMap[name]=t;
139  t->incrRef();
140  return t;
141 }
142 
144 
150 TypeCode * Proc::createSequenceTc (const std::string& id, const std::string& name,
151  TypeCode *content)
152 {
153  TypeCode* t = TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
154  if(typeMap.count(name)!=0)
155  typeMap[name]->decrRef();
156  typeMap[name]=t;
157  t->incrRef();
158  return t;
159 }
160 
161 TypeCode * Proc::createStructTc (const std::string& id, const std::string& name)
162 {
163  TypeCode* t = TypeCode::structTc(id.c_str(),name.c_str());
164  if(typeMap.count(name)!=0)
165  typeMap[name]->decrRef();
166  typeMap[name]=t;
167  t->incrRef();
168  return t;
169 }
170 
171 TypeCode * Proc::getTypeCode (const std::string& name)
172 {
173  TypeCode* aTC=0;
174  if(typeMap.count(name)==0)
175  aTC=getRuntime()->getTypeCode(name);
176  else
177  aTC=typeMap[name];
178 
179  if(!aTC)
180  {
181  std::stringstream msg;
182  msg << "Type " << name << " does not exist" ;
183  msg << " (" <<__FILE__ << ":" << __LINE__ << ")";
184  throw Exception(msg.str());
185  }
186 
187  return aTC;
188 }
189 
190 void Proc::setTypeCode (const std::string& name,TypeCode *t)
191 {
192  if(typeMap.count(name)!=0)
193  typeMap[name]->decrRef();
194  typeMap[name]=t;
195  t->incrRef();
196 }
197 
198 
199 void Proc::accept(Visitor *visitor)
200 {
201  visitor->visitProc(this);
202 }
203 
204 void Proc::setName(const std::string& name)
205 {
206  _name = name;
207 }
208 
210 {
211  if(YACS::ENGINE::Node::idMap.count(numId) == 0)
212  {
213  cerr << "Unknown node id " << numId << endl;
214  return YACS::UNDEFINED;
215  }
218  return state;
219 }
220 
221 std::string Proc::getNodeProgress(int numId)
222 {
223  std::string progress = "0";
224  if(YACS::ENGINE::Node::idMap.count(numId) == 0)
225  {
226  cerr << "Unknown node id " << numId << endl;
227  }
228  else if (YACS::ENGINE::ComposedNode* node = dynamic_cast<YACS::ENGINE::ComposedNode*>(YACS::ENGINE::Node::idMap[numId]))
229  progress = node->getProgress();
230  return progress;
231 }
232 
234 {
235  list<ProgressWeight> weightList = getProgressWeight();
236  int weightDone = 0;
237  int weightTotal = 0;
238  int progressPercent = 0;
239  for(list<ProgressWeight>::const_iterator iter=weightList.begin();iter!=weightList.end();iter++)
240  {
241  weightDone += (*iter).weightDone;
242  weightTotal += (*iter).weightTotal;
243  }
244  if (weightTotal > 0)
245  progressPercent = int(float(weightDone) / float(weightTotal) * 100);
246  return progressPercent;
247 }
248 
249 std::string Proc::getXMLState(int numId)
250 {
251  if(YACS::ENGINE::Node::idMap.count(numId) == 0)
252  {
253  cerr << "Unknown node id " << numId << endl;
254  return "<state>unknown</state>";
255  }
257  stringstream msg;
258  msg << "<state>" << node->getEffectiveState() << "</state>";
259  msg << "<name>" << node->getQualifiedName() << "</name>";
260  msg << "<id>" << numId << "</id>";
261  return msg.str();
262 }
263 
264 std::string Proc::getInPortValue(int nodeNumId, std::string portName)
265 {
266  DEBTRACE("Proc::getInPortValue " << nodeNumId << " " << portName);
267  stringstream msg;
268  if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
269  {
270  msg << "<value><error>unknown node id: " << nodeNumId << "</error></value>";
271  return msg.str();
272  }
273  try
274  {
276  InputPort * inputPort = node->getInputPort(portName);
277  return inputPort->getAsString();
278  }
279  catch(YACS::Exception& ex)
280  {
281  DEBTRACE("Proc::getInPortValue " << ex.what());
282  msg << "<value><error>" << ex.what() << "</error></value>";
283  return msg.str();
284  }
285 }
286 
287 std::string Proc::setInPortValue(std::string nodeName, std::string portName, std::string value)
288 {
289  DEBTRACE("Proc::setInPortValue " << nodeName << " " << portName << " " << value);
290 
291  try
292  {
294  YACS::ENGINE::InputPort* inputPort = node->getInputPort(portName);
295 
296  switch (inputPort->edGetType()->kind())
297  {
298  case Double:
299  {
300  double val = atof(value.c_str());
301  inputPort->edInit(val);
302  }
303  break;
304  case Int:
305  {
306  int val = atoi(value.c_str());
307  inputPort->edInit(val);
308  }
309  break;
310  case String:
311  inputPort->edInit(value.c_str());
312  break;
313  case Bool:
314  {
315  if((!value.compare("False")) || (!value.compare("false")))
316  inputPort->edInit(false);
317  else if ((!value.compare("True")) || (!value.compare("true")))
318  inputPort->edInit(true);
319  else
320  {
321  int val = atoi(value.c_str());
322  inputPort->edInit(val);
323  }
324  }
325  break;
326  default:
327  DEBTRACE("Proc::setInPortValue: filtered type: " << inputPort->edGetType()->kind());
328  }
329  return value;
330  }
331  catch(YACS::Exception& ex)
332  {
333  DEBTRACE("Proc::setInPortValue " << ex.what());
334  stringstream msg;
335  msg << "<value><error>" << ex.what() << "</error></value>";
336  return msg.str();
337  }
338 }
339 
340 std::string Proc::getOutPortValue(int nodeNumId, std::string portName)
341 {
342  DEBTRACE("Proc::getOutPortValue " << nodeNumId << " " << portName);
343  stringstream msg;
344  if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
345  {
346  msg << "<value><error>unknown node id: " << nodeNumId << "</error></value>";
347  return msg.str();
348  }
349  try
350  {
352  OutputPort * outputPort = node->getOutputPort(portName);
353  return outputPort->getAsString();
354  }
355  catch(YACS::Exception& ex)
356  {
357  DEBTRACE("Proc::getOutPortValue " << ex.what());
358  msg << "<value><error>" << ex.what() << "</error></value>";
359  return msg.str();
360  }
361 }
362 
363 std::string Proc::getNodeErrorDetails(int nodeNumId)
364 {
365  DEBTRACE("Proc::getNodeErrorDetails " << nodeNumId);
366  stringstream msg;
367  if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
368  {
369  msg << "Unknown node id " << nodeNumId;
370  return msg.str();
371  }
373  return node->getErrorDetails();
374 }
375 
376 std::string Proc::getNodeErrorReport(int nodeNumId)
377 {
378  DEBTRACE("Proc::getNodeErrorReport " << nodeNumId);
379  stringstream msg;
380  if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
381  {
382  msg << "Unknown node id " << nodeNumId;
383  return msg.str();
384  }
386  return node->getErrorReport();
387 }
388 
389 std::string Proc::getNodeContainerLog(int nodeNumId)
390 {
391  DEBTRACE("Proc::getNodeContainerLog " << nodeNumId);
392  stringstream msg;
393  if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
394  {
395  msg << "Unknown node id " << nodeNumId;
396  return msg.str();
397  }
399  return node->getContainerLog();
400 }
401 
402 std::list<int> Proc::getNumIds()
403 {
404  list<YACS::ENGINE::Node *> nodes = getAllRecursiveConstituents();
405  int len = nodes.size();
406  list<int> numids;
407  for( list<YACS::ENGINE::Node *>::const_iterator iter = nodes.begin();
408  iter != nodes.end(); iter++)
409  {
410  numids.push_back((*iter)->getNumId());
411  }
412  numids.push_back(this->getNumId());
413  return numids;
414 }
415 
416 std::list<std::string> Proc::getIds()
417 {
418  list<YACS::ENGINE::Node *> nodes = getAllRecursiveConstituents();
419  int len = nodes.size();
420  list<string> ids;
421  for( list<YACS::ENGINE::Node *>::const_iterator iter = nodes.begin();
422  iter != nodes.end(); iter++)
423  {
424  ids.push_back(getChildName(*iter));
425  }
426  ids.push_back("_root_");
427  return ids;
428 }
429 
430 Logger *Proc::getLogger(const std::string& name)
431 {
432  Logger* logger;
433  LoggerMap::const_iterator it = _loggers.find(name);
434 
435  if (it != _loggers.end())
436  {
437  logger = it->second;
438  }
439  else
440  {
441  logger = new Logger(name);
442  _loggers[name]=logger;
443  }
444  return logger;
445 }
446 
447 void Proc::setEdition(bool edition)
448 {
449  DEBTRACE("Proc::setEdition: " << edition);
450  _edition=edition;
451  if(_edition)
452  edUpdateState();
453 }
455 
459 {
460  DEBTRACE("Proc::modified() " << _edition);
461  _modified=1;
462  if(_edition)
463  edUpdateState();
464 }
465 
467 
470 void Proc::saveSchema(const std::string& xmlSchemaFile)
471 {
472  VisitorSaveSchema vss(this);
473  vss.openFileSchema(xmlSchemaFile);
474  accept(&vss);
475  vss.closeFileSchema();
476 }
477 
479 
482 void Proc::saveState(const std::string& xmlStateFile)
483 {
484  VisitorSaveState vst(this);
485  vst.openFileDump(xmlStateFile);
486  accept(&vst);
487  vst.closeFileDump();
488 }
489 
491 {
492  //get rid of containers in container map
493  std::map<std::string, Container*>::const_iterator it;
494  for(it=containerMap.begin();it!=containerMap.end();it++)
495  ((*it).second)->decrRef();
496  containerMap.clear();
497 }
498 
500 
505 Container *Proc::createContainer(const std::string& name, const std::string& kind)
506 {
507  Container *co(getRuntime()->createContainer(kind));
508  co->setName(name);
509  if(containerMap.count(name)!=0)
510  containerMap[name]->decrRef();
511  containerMap[name]=co;
512  co->incrRef();
513  co->setProc(this);
514  return co;
515 }
516 
518 
525 void Proc::addComponentInstance(ComponentInstance* inst, const std::string& name, bool resetCtr)
526 {
527  if(name != "")
528  {
529  inst->setName(name);
530  inst->setAnonymous(false);
531  if(componentInstanceMap.count(name)!=0)
532  componentInstanceMap[name]->decrRef();
533  componentInstanceMap[name]=inst;
534  inst->incrRef();
535  }
536  else
537  {
538  //automatic naming : componame_<_compoinstctr>
539  std::string instname;
540  std::string componame=inst->getCompoName();
541  if (resetCtr)
542  _compoinstctr = 0;
543  while(1)
544  {
545  std::ostringstream buffer;
546  buffer << ++_compoinstctr;
547  instname=componame+"_"+buffer.str();
548  if(componentInstanceMap.count(instname)==0)
549  {
550  inst->setName(instname);
551  componentInstanceMap[instname]=inst;
552  inst->incrRef();
553  break;
554  }
555  }
556  }
557 }
558 
560 
566 {
567  if (componentInstanceMap.count(inst->getInstanceName()))
568  {
569  componentInstanceMap.erase(inst->getInstanceName());
570  inst->decrRef();
571  }
572 }
573 
575 
581 {
582  if (containerMap.count(cont->getName()))
583  {
584  containerMap.erase(cont->getName());
585  cont->decrRef();
586  }
587 }
588 
590 
598 ComponentInstance* Proc::createComponentInstance(const std::string& componame, const std::string& name,const std::string& kind)
599 {
600  ComponentInstance* inst= getRuntime()->createComponentInstance(componame,kind);
601  addComponentInstance(inst,name);
602  return inst;
603 }
604 
607 {
608  return this;
609 }
610 
612 const Proc * Proc::getProc() const
613 {
614  return this;
615 }
616 
622 {
623  std::map<std::string, Container*> myContainerMap;
624  std::map<std::string, ComponentInstance*> myComponentInstanceMap;
625  DeploymentTree treeToDup(getDeploymentTree());
626  vector<Container *> conts(treeToDup.getAllContainers());
627  for(vector<Container *>::const_iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
628  {
629  Container *tmp(*iterCt);
630  if(tmp)
631  {
632  if(myContainerMap.find(tmp->getName())!=myContainerMap.end())
633  {
634  std::ostringstream oss; oss << "Proc::updateContainersAndComponents : more than one container instance with name \"" << tmp->getName() << "\" !";
635  throw YACS::Exception(oss.str());
636  }
637  myContainerMap[tmp->getName()]=tmp;
638  tmp->incrRef();
639  }
640  vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
641  for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
642  {
643  ComponentInstance *tmp2(*iterCp);
644  if(tmp2)
645  {
646  if(myComponentInstanceMap.find(tmp2->getCompoName())!=myComponentInstanceMap.end())
647  {
648  std::ostringstream oss; oss << "Proc::updateContainersAndComponents : more than one component instance with name \"" << tmp2->getCompoName() << "\" !";
649  throw YACS::Exception(oss.str());
650  }
651  }
652  myComponentInstanceMap[tmp2->getCompoName()]=tmp2;
653  tmp2->incrRef();
654  }
655  }
657  containerMap=myContainerMap;
658  componentInstanceMap=myComponentInstanceMap;
659 }