Version: 9.15.0
ComposedNode.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2025 CEA, EDF
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 "ComposedNode.hxx"
21 #include "LinkInfo.hxx"
22 #include "Container.hxx"
23 #include "InputPort.hxx"
24 #include "OutputPort.hxx"
25 #include "ServiceNode.hxx"
26 #include "InlineNode.hxx"
27 #include "DataFlowPort.hxx"
28 #include "DataStreamPort.hxx"
29 #include "ElementaryNode.hxx"
30 #include "ComponentInstance.hxx"
31 
32 #include <iostream>
33 #include <set>
34 #include <string>
35 #include <sstream>
36 #include <algorithm>
37 
38 //#define _DEVDEBUG_
39 #include "YacsTrace.hxx"
40 
41 using namespace YACS::ENGINE;
42 using namespace std;
43 
52 const char ComposedNode::SEP_CHAR_BTW_LEVEL[]=".";
53 
54 ComposedNode::ComposedNode(const std::string& name):Node(name)
55 {
56 }
57 
58 ComposedNode::ComposedNode(const ComposedNode& other, ComposedNode *father):Node(other,father)
59 {
60 }
61 
63 {
64 }
65 
67 {
68  const ComposedNode &otherC=*(dynamic_cast<const ComposedNode *>(&other));
69  DeploymentTree treeToDup=otherC.getDeploymentTree();
70  list< ElementaryNode * > clones=otherC.getRecursiveConstituents();
71  vector<Container *> conts=treeToDup.getAllContainers();
72  //iterate on all containers
73  for(vector<Container *>::iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
74  {
75  vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
76  Container *contCloned=0;
77  if((*iterCt))
78  contCloned=(*iterCt)->clone();
79 
80  //iterate on all component instances linked to the container
81  for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
82  {
83  vector<Task *> tasks=treeToDup.getTasksLinkedToComponent(*iterCp);
84  ComponentInstance *curCloned=(*iterCp)->clone();
85  curCloned->setContainer(contCloned);
86  for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
87  {
88  //No risk for static cast : appendTask called by ComposedNode.
89  list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT));
90  //No risk here to because called only on cloning process...
91  ServiceNode *nodeC=(ServiceNode *)getChildByName(otherC.getChildName(*res));
92  nodeC->setComponent(curCloned);
93  }
94  curCloned->decrRef();
95  }
96 
97  // iterate on all tasks linked to the container
98  vector<Task *> tasks=treeToDup.getTasksLinkedToContainer(*iterCt);
99  for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
100  {
101  std::list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT));
103  nodeC->setContainer(contCloned);
104  }
105 
106  // ended with current container
107  if(contCloned)
108  contCloned->decrRef();
109  }
110 }
111 
113 {
114  const ComposedNode &otherC=*(dynamic_cast<const ComposedNode *>(&other));
115  DeploymentTree treeToDup=otherC.getDeploymentTree();
116  list< ElementaryNode * > clones=otherC.getRecursiveConstituents();
117  vector<Container *> conts=treeToDup.getAllContainers();
118  //iterate on all containers
119  for(vector<Container *>::iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
120  {
121  vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
122  Container *contCloned((*iterCt));
123 
124  //iterate on all component instances linked to the container
125  for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
126  {
127  vector<Task *> tasks=treeToDup.getTasksLinkedToComponent(*iterCp);
128  ComponentInstance *curCloned((*iterCp));
129  curCloned->setContainer(contCloned);
130  for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
131  {
132  //No risk for static cast : appendTask called by ComposedNode.
133  list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT));
134  //No risk here to because called only on cloning process...
135  ServiceNode *nodeC=(ServiceNode *)getChildByName(otherC.getChildName(*res));
136  nodeC->setComponent(curCloned);
137  }
138  }
139 
140  // iterate on all tasks linked to the container
141  vector<Task *> tasks=treeToDup.getTasksLinkedToContainer(*iterCt);
142  for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
143  {
144  std::list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT));
146  nodeC->setContainer(contCloned);
147  }
148  }
149 }
150 
152 {
153  if(_state==YACS::DONE)return true;
154  if(_state==YACS::ERROR)return true;
155  if(_state==YACS::FAILED)return true;
156  if(_state==YACS::DISABLED)return true;
157  return false;
158 }
159 
160 void ComposedNode::init(bool start)
161 {
162  Node::init(start);
163 }
164 
165 std::string ComposedNode::getName() const
166 {
167  return Node::getName();
168 }
169 
170 std::string ComposedNode::getTaskName(Task *task) const
171 {
172  return getChildName(dynamic_cast<ElementaryNode *>(task));
173 }
174 
177 {
178  DeploymentTree ret;
179  list< ElementaryNode * > tasks=getRecursiveConstituents();
180  for(list< ElementaryNode * >::iterator iter=tasks.begin();iter!=tasks.end();iter++)
181  ret.appendTask(*iter,(*iter)->getDynClonerIfExists(this));
182  return ret;
183 }
184 
186 
190 {
191  DeploymentTree ret;
192  list< ElementaryNode * > tasks=getRecursiveConstituents();
193  for(list< ElementaryNode * >::iterator iter=tasks.begin();iter!=tasks.end();iter++)
194  {
195  switch(ret.appendTask(*iter,(*iter)->getDynClonerIfExists(this)))
196  {
198  {
199  string what("ComposedNode::checkDeploymentTree : ServiceNode with name \""); what+=(*iter)->getName();
200  what+="\" coexists in a component with an another Task which context is incompatible with it.";
201  throw Exception(what);
202  }
204  {
205  if(deep)
206  {
207  string what("ComposedNode::checkDeploymentTree : ServiceNode with name \""); what+=(*iter)->getName();
208  what+="\" is deployable but no component is specified on it.";
209  throw Exception(what);
210  }
211  }
212  }
213  }
214  return ret;
215 }
216 
217 std::vector<Task *> ComposedNode::getNextTasks(bool& isMore)
218 {
219  vector<Task *> ret;
220  isMore=false;
221  getReadyTasks(ret);
222  isMore=!ret.empty();
223  return ret;
224 }
225 
227 
243 void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event
244  YACS::Event event, //* I : event emitted
245  const Executor *execInst
246  )
247 {
248  DEBTRACE("ComposedNode::notifyFrom " << event);
249  ElementaryNode *taskTyped=dynamic_cast<ElementaryNode *>((Task *)sender);
250  YACS::Event curEvent=event;
251  Node *lminus1LevelNode=taskTyped;
252  ComposedNode *curLevelNode=taskTyped->_father;
253  if(!curLevelNode)//Specific case of loop when 0 turn is specified without any enclosing bloc.
254  return ;
255  curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent,execInst);
256  while(curEvent!=YACS::NOEVENT && curLevelNode!=this)
257  {
258  lminus1LevelNode=curLevelNode;
259  curLevelNode=curLevelNode->_father;
260  curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent,execInst);
261  }
262 }
263 
265 
274 {
275  DEBTRACE("ComposedNode::edAddLink");
276  set<OutPort *> represented;
277 
278  start->getAllRepresented(represented);
279  if(represented.size()!=1)
280  {
281  bool ret=false;
282  for(set<OutPort *>::iterator iter=represented.begin();iter!=represented.end();iter++)
283  ret|=edAddLink(*iter,end);
284  return ret;
285  }
286  if(start->isAlreadyLinkedWith(end))
287  return false;
288  ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode());
289  list<ComposedNode *> allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr);
290  list<ComposedNode *> allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr);
291  checkInMyDescendance(lwstCmnAnctr);
292  lwstCmnAnctr->checkLinkPossibility(start,allAscendanceOfNodeStart,end,allAscendanceOfNodeEnd);
293  ComposedNode *iterS;
294  if(dynamic_cast<ComposedNode *>(start->getNode()))
295  iterS=(ComposedNode *)start->getNode();
296  else
297  iterS=start->getNode()->_father;
298  pair<OutPort *, OutPort *> pO(start,start);
299  while(iterS!=lwstCmnAnctr)
300  {
301  iterS->buildDelegateOf(pO, end, allAscendanceOfNodeEnd);
302  iterS=iterS->_father;
303  }
304  if(dynamic_cast<ComposedNode *>(end->getNode()))
305  iterS=(ComposedNode *)end->getNode();
306  else
307  iterS=end->getNode()->_father;
308 
309  InPort *currentPortI=end;
310  bool isLoopProofLink(true),isFirstTurn(true);
311  while(iterS!=lwstCmnAnctr)
312  {
313  if(!isFirstTurn && iterS->isLoop())// isFirstTurn is a way to filter special inputs like nbBranches, splitPort... These special inputs are loopProof -> they must not be realeased by ForEachLoop::exUpdateState
314  isLoopProofLink=false;
315  iterS->buildDelegateOf(currentPortI, start, allAscendanceOfNodeStart);
316  iterS=iterS->_father;
317  isFirstTurn=false;
318  }
319  bool ret=(pO.first)->addInPort(currentPortI);
320  end->edNotifyReferencedBy(pO.second,isLoopProofLink);
321  return ret;
322 }
323 
325 
334 {
335  Node* n1=start->getNode();
336  Node* n2=end->getNode();
337  DEBTRACE( n1->getName() << ":" << n2->getName())
338  ComposedNode* father=getLowestCommonAncestor(n1,n2);
339  DEBTRACE( "ComposedNode::edAddDFLink: this="<<this->getName()
340  << " father=" << father->getName() )
341  DEBTRACE( "ComposedNode::edAddDFLink: OutPort=" << start->getName()
342  << " InPort=" << end->getName() )
343  if (father != this)
344  {
345  bool ret = father->edAddDFLink(start,end); // special treatement for loop
346  return ret;
347  }
348  if(n2 == father)
349  throw Exception("Back link authorized only in special context (loop for example)");
350 
351  bool ret= edAddLink(start,end);
352  if(n1 != father)
353  {
354  //add a control link only if nodes are not in the same descendance
355  //if n1 == father (n2 is after n1) : the control link is not needed
356  //if n2 == father (n1 is after n2) : it's a back link authorized only in loop context
357  while(n1->getFather() != father)
358  n1=n1->getFather();
359  while(n2->getFather() != father)
360  n2=n2->getFather();
361  try
362  {
363  edAddCFLink(n1,n2);
364  }
365  catch (Exception& ex)
366  {
367  // --- remove DF link already created in case of cycle dtection
368  DEBTRACE("Cycle detected, remove CF link");
369  if(start->isAlreadyLinkedWith(end))
370  edRemoveLink(start, end);
371  throw ex;
372  }
373  }
374  return ret;
375 }
376 
378 
388 {
389  Node* n1=start->getNode();
390  Node* n2=end->getNode();
391  if(n1==n2)
392  throw Exception("ComposedNode::edAddLink: can not add a control link to a node with itself",1);
393  ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode());
394  if(father==0)
395  throw Exception("ComposedNode::edAddLink: Trying to add CF link on orphan nodes.");
396  if(father!=this)
397  {
398  checkInMyDescendance(father);
399  return father->edAddLink(start,end);
400  }
401  bool ret=start->edAddInGate(end);
402  if(ret)
403  try
404  {
406  }
407  catch (Exception& ex)
408  {
409  // --- remove created CF link in case of cycle detection
410  DEBTRACE("Cycle detected, remove CF link");
411  edRemoveCFLink(start->getNode(), end->getNode());
412  throw ex;
413  }
414  return ret;
415 }
416 
418 
421 bool ComposedNode::edAddCFLink(Node *nodeS, Node *nodeE)
422 {
423  return edAddLink(nodeS->getOutGate(),nodeE->getInGate());
424 }
425 
428 {
429  edRemoveLink(nodeS->getOutGate(),nodeE->getInGate());
430 }
431 
433 
442 {
443  if(!start->isAlreadyLinkedWith(end))
444  throw Exception("ComposedNode::edRemoveLink : unexisting link");
445  ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode());
446  checkInMyDescendance(lwstCmnAnctr);
447  list<ComposedNode *> allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr);
448  list<ComposedNode *> allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr);
449 
450  // --- Part of test if the link from 'start' to 'end' really exist particulary all eventually intermediate ports created
451 
452  ComposedNode *iterS=start->getNode()->_father;
453  pair<OutPort *,OutPort *> currentPortO(start,start);
454  vector<pair< ComposedNode * , pair < OutPort* , OutPort *> > > needsToDestroyO;
455 
456  Node *nodeOTemp=start->getNode();
457  if(*nodeOTemp<*lwstCmnAnctr)
458  {
459  iterS=nodeOTemp->_father;
460  while(iterS!=lwstCmnAnctr)
461  {
462  if (!iterS)
463  {
464  stringstream what;
465  what << "ComposedNode::edRemoveLink: "
466  << start->getNode()->getName() << "." <<start->getName() << "->"
467  << end->getNode()->getName() << "." << end->getName();
468  throw Exception(what.str());
469  }
470  OutPort *tmp=currentPortO.first;
471  iterS->getDelegateOf(currentPortO, end, allAscendanceOfNodeEnd);
472  needsToDestroyO.push_back(pair< ComposedNode * , pair < OutPort* , OutPort *> >(iterS,pair<OutPort* , OutPort *> (tmp,currentPortO.first)));
473  iterS=iterS->_father;
474  }
475  }
476  Node *nodeTemp=end->getNode();
477  InPort * currentPortI=end;
478  if(*nodeTemp<*lwstCmnAnctr)
479  {
480  iterS=nodeTemp->_father;
481  while(iterS!=lwstCmnAnctr)
482  {
483  if (!iterS)
484  {
485  stringstream what;
486  what << "ComposedNode::edRemoveLink: "
487  << start->getNode()->getName() << "." <<start->getName() << "->"
488  << end->getNode()->getName() << "." << end->getName();
489  throw Exception(what.str());
490  }
491  iterS->getDelegateOf(currentPortI, start, allAscendanceOfNodeStart);
492  iterS=iterS->_father;
493  }
494  }
495  // --- End of test for evt intermediate ports created
496 
497  (currentPortO.first)->removeInPort(currentPortI,false);
498  set<OutPort *> repr;
499  (currentPortO.second)->getAllRepresented(repr);
500  if(repr.size()==1)
501  end->edNotifyDereferencedBy(currentPortO.second);
502 
503  // --- Performing deletion of intermediate ports
504 
505  iterS=start->getNode()->_father;
506  vector<pair< ComposedNode * , pair < OutPort* , OutPort *> > >::reverse_iterator iter;
507  for(iter=needsToDestroyO.rbegin();iter!=needsToDestroyO.rend();iter++)
508  (*iter).first->releaseDelegateOf(((*iter).second).first, ((*iter).second).second, end,allAscendanceOfNodeEnd);
509  nodeTemp=end->getNode();
510  if(*nodeTemp<*lwstCmnAnctr)
511  {
512  iterS=end->getNode()->_father;
513  currentPortI=end;
514  while(iterS!=lwstCmnAnctr)
515  {
516  iterS->releaseDelegateOf(currentPortI, start, allAscendanceOfNodeStart);
517  iterS=iterS->_father;
518  }
519  }
520 }
521 
524 {
525  ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode());
526  if(father!=this)
527  throw Exception("edRemoveLink : nodes not in direct descendance of this");
528  start->edRemoveInGate(end);
529 }
530 
532 {
533  return false; // --- reimplemented in derived classes
534 }
535 
538 {
539  if(!node)
540  return;
541  if (node->_father!=this)
542  {
543  string what("node "); what+= node->getName() ; what+=" is not a child of node "; what += getName();
544  throw Exception(what);
545  }
547  node->_father = 0;
548  //set _modified flag so edUpdateState() can refresh state
549  modified();
550 }
551 
553 
561 bool ComposedNode::splitNamesBySep(const std::string& globalName, const char separator[],
562  std::string& firstPart, std::string& lastPart, bool priority)
563 {
564  const string delims(separator);
565  string portName, nodeName;
566  string::size_type idx;
567  if(priority)
568  idx = globalName.find_last_of(delims);
569  else
570  idx = globalName.find_first_of(delims);
571  if (idx == string::npos)
572  {
573  firstPart=globalName;
574  lastPart="";
575  return false;
576  }
577  firstPart = globalName.substr(0,idx);
578  lastPart = globalName.substr(idx+1);
579  if ((firstPart.empty()) || (lastPart.empty()))
580  {
581  string what("the name "); what+= globalName ; what+=" is not a valid port name";
582  throw Exception(what);
583  }
584  return true;
585 }
586 
587 std::vector< std::pair<OutPort *, InPort *> > ComposedNode::getSetOfInternalLinks() const
588 {
589  vector< pair<OutPort *, InPort *> > ret;
590  list<OutPort *> temp=getSetOfOutPort();
591  for(list<OutPort *>::const_iterator iter2=temp.begin();iter2!=temp.end();iter2++)
592  {
593  set<InPort *> temp2=(*iter2)->edSetInPort();
594  for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
595  if(isInMyDescendance((*iter3)->getNode()))
596  ret.push_back(pair<OutPort *, InPort *>((*iter2),(*iter3)));
597  }
598  return ret;
599 }
600 
601 std::vector< std::pair<OutPort *, InPort *> > ComposedNode::getSetOfLinksLeavingCurrentScope() const
602 {
603  vector< pair<OutPort *, InPort *> > ret;
604  std::set<OutPort *> ports=getAllOutPortsLeavingCurrentScope();
605  for(set<OutPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
606  {
607  set<InPort *> temp2=(*iter2)->edSetInPort();
608  for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
609  if(!isInMyDescendance((*iter3)->getNode()))
610  ret.push_back(pair<OutPort *, InPort *>(*iter2,*iter3));
611  }
612  return ret;
613 }
614 
616 {
617  info.clearAll();
618  info.setPointOfView((ComposedNode *)this);
619  performCFComputations(info);
620  list<InputPort *> setOfInToTest=getSetOfInputPort();
621  for(list<InputPort *>::iterator iter1=setOfInToTest.begin();iter1!=setOfInToTest.end();iter1++)
622  {
623  vector<OutPort *> candidateForAdvCheck;
624  set<OutPort *> outPorts=(*iter1)->edSetOutPort();
625  //Filtering among outPorts, which of them, are candidates to fill *iter1 at the current scope.
626  for(set<OutPort *>::iterator iter2=outPorts.begin();iter2!=outPorts.end();iter2++)
627  {
628  (*iter2)->checkConsistency(info);
629  ComposedNode *manager=getLowestCommonAncestor((*iter2)->getNode(),(*iter1)->getNode());
630  if(isInMyDescendance(manager))
631  candidateForAdvCheck.push_back(*iter2);
632  }
633  if(!candidateForAdvCheck.empty())
634  //End of filtering. Now regarding CF constraints for the current InPutPort.
635  try
636  {
637  checkLinksCoherenceRegardingControl(candidateForAdvCheck,*iter1,info);
638  }
639  catch(YACS::Exception& ex)
640  {
641  std::string what=ex.what();
642  what += "\nfor input port: ";
643  what += (*iter1)->getNode()->getName();
644  what += ".";
645  what += (*iter1)->getName();
646 
648  throw YACS::Exception(what);
649  }
650  else
651  //No backlinks
652  if(!(*iter1)->canBeNull() && !(*iter1)->edIsManuallyInitialized())
653  info.pushErrLink(0,*iter1,E_NEVER_SET_INPUTPORT);
654  }
656 }
657 
663 {
664  ComposedNode *nodeC=dynamic_cast<ComposedNode *>(node);
665  if(!nodeC)
666  return ;
667  list<ComposedNode *> ascendants=getAllAscendanceOf();
668  if(find(ascendants.begin(),ascendants.end(),nodeC)!=ascendants.end())
669  {
670  const char what[]="ComposedNode::checkNoCrossHierachyWith : ComposedNode with name \"";
671  string stream(what); stream+=node->getName(); stream+="\" is already in hierarchy ascendance of node with name \"";
672  stream+=_name; stream+="\" ; So it can't be now in its descendance !";
673  throw Exception(stream);
674  }
675 }
676 
679 {
680  list<Node *> nodes=edGetDirectDescendants();
681  for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
682  if(dynamic_cast<ComposedNode *>(*iter))
683  ((ComposedNode *)(*iter))->performCFComputations(info);
684 }
685 
688 {
689  list<Node *> nodes=edGetDirectDescendants();
690  for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
691  if(dynamic_cast<ComposedNode *>(*iter))
692  ((ComposedNode *)(*iter))->destructCFComputations(info);
693 }
694 
700 Node *ComposedNode::getLowestNodeDealingAll(const std::list<OutPort *>& ports) const
701 {
702  list< OutPort *>::const_iterator iter=ports.begin();
703  Node *ret=(*iter)->getNode();
704  iter++;
705  for(;iter!=ports.end();iter++)
706  {
707  Node *tmp=(*iter)->getNode();
708  if(*tmp>*ret)
709  ret=tmp;
710  }
711  return ret;
712 }
713 
717 void ComposedNode::checkLinksCoherenceRegardingControl(const std::vector<OutPort *>& starts, InputPort *end, LinkInfo& info) const
718 {
719  map < ComposedNode *, list<OutPort *>, SortHierarc > outputs;//forward link classical
720  vector<OutPort *> outputsCross;//forward link cross
721  map < ComposedNode *, list<OutPort *>, SortHierarc > outputsBw;//backward
722  vector<OutPort *>::const_iterator iter1;
723  //vector<DataPort *> history=((*iter1).second)[0]->calculateHistoryOfLinkWith(end);
724  //DataPort *cross=DataPort::isCrossingType(history);
725  for(iter1=starts.begin();iter1!=starts.end();iter1++)
726  {
727  ComposedNode *manager=getLowestCommonAncestor((*iter1)->getNode(),end->getNode());
728  manager->checkControlDependancy((*iter1), end, false, outputs, outputsCross, outputsBw, info);
729  }
730  //Ok now let's regarding outputs all combinations : (outputs.size())*(outputs.size()-1)/2
731  unsigned char isAlreadyFed=FREE_ST;
732  //Dealing excusively with DS. Level is useless here because simultaneity is required for DS.
733  if(outputsCross.size()>0)
734  {
735  isAlreadyFed=FED_DS_ST;
736  if(outputsCross.size()>1)
737  for(vector< OutPort *>::const_iterator iter1=outputsCross.begin();iter1!=(outputsCross.end()-2);iter1++)
738  info.pushErrLink(*iter1,end,E_COLLAPSE_DS);
739  }
740  map < ComposedNode *, list<OutPort *>, SortHierarc >::iterator iter3=outputs.begin();
741  for(;iter3!=outputs.end();iter3++)
742  ((*iter3).first)->checkCFLinks((*iter3).second,end,isAlreadyFed,true,info);
743  if(isAlreadyFed==FREE_ST)
744  if(!end->edIsManuallyInitialized())
746  isAlreadyFed=FREE_ST;
747  //
748  map < ComposedNode *, list<OutPort *>, SortHierarc >::reverse_iterator iter5=outputsBw.rbegin();
749  for(;iter5!=outputsBw.rend();iter5++)
750  ((*iter5).first)->checkCFLinks((*iter5).second,end,isAlreadyFed,false,info);
751 }
752 
757 void ComposedNode::solveObviousOrDelegateCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
758 {
759  static const char what[]="ComposedNode::solveObviousOrDelegateCFLinks : Internal error occured - uncorrect hierarchy detected !";
760  if(starts.size()==1)
761  {
762  if(alreadyFed==FREE_ST)
763  {
764  if(!direction)
765  info.pushInfoLink(*(starts.begin()),end,I_BACK);
766  alreadyFed=FED_ST;
767  }
768  else if(alreadyFed==FED_ST)
769  info.pushInfoLink(*(starts.begin()),end,direction ? I_USELESS : I_BACK_USELESS);
770  else
771  info.pushErrLink(*(starts.begin()),end,E_COLLAPSE_DFDS);
772  }
773  else
774  {
775  Node *levelOfDecision=getLowestNodeDealingAll(starts);
776  if(levelOfDecision==this)
777  throw Exception(what);
778  if(dynamic_cast<ElementaryNode *>(levelOfDecision))
779  {
780  WarnReason reason;
781  if(alreadyFed==FREE_ST || alreadyFed==FED_ST)
782  {
783  if(alreadyFed==FREE_ST)
784  {
785  reason=direction ? W_COLLAPSE_EL : W_BACK_COLLAPSE_EL;
786  alreadyFed=FED_ST;
787  }
788  else
790  for(list< OutPort *>::const_iterator iter=starts.begin();iter!=starts.end();iter++)
791  info.pushWarnLink(*iter,end,reason);
792  }
793  }
794  else
795  ((ComposedNode *)levelOfDecision)->checkCFLinks(starts,end,alreadyFed,direction,info);
796  }
797 }
798 
800 
807 void ComposedNode::checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
808 {
809  static const char what[]="ComposedNode::checkCFLinks : Internal error occured - uncorrect hierarchy detected !";
810  Node *nodeEnd=isInMyDescendance(end->getNode());
811  if(!nodeEnd)
812  return solveObviousOrDelegateCFLinks(starts,end,alreadyFed,direction,info);
813  //This case is typically dedicated when direct son is ElementaryNode and self link is defined on this.
814  if(!dynamic_cast<ElementaryNode *>(nodeEnd))
815  throw Exception(what);
816 
817  list< OutPort *>::const_iterator iter=starts.begin();
818  Node *nodeStart=(*iter)->getNode();
819  iter++;
820  if(nodeEnd!=nodeStart)
821  throw Exception(what);
822 
823  for(;iter!=starts.end();iter++)
824  if((*iter)->getNode()!=nodeStart)
825  throw Exception(what);
826  //Ok at this step we are sure that we have back links on the same elementary node.
827  if(starts.size()>1)
828  for(iter=starts.begin();iter!=starts.end();iter++)
829  info.pushWarnLink(*iter,end,W_BACK_COLLAPSE_EL);
830  else//here no need to look at 'alreadyFed' var because it is waranteed to be equal to FREE_ST by construction.
831  info.pushInfoLink(*(starts.begin()),end,I_BACK);
832  alreadyFed=FED_ST;
833 }
834 
835 std::vector< std::pair<InPort *, OutPort *> > ComposedNode::getSetOfLinksComingInCurrentScope() const
836 {
837  vector< pair<InPort *, OutPort *> > ret;
838  set<InPort *> ports=getAllInPortsComingFromOutsideOfCurrentScope();
839  for(set<InPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
840  {
841  set<OutPort *> temp2=(*iter2)->edSetOutPort();
842  for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
843  {
844  if(isInMyDescendance((*iter3)->getNode()))continue;
845  std::set<OutPort *> trueOutPorts;
846  (*iter3)->getAllRepresented(trueOutPorts);
847  for(std::set<OutPort *>::iterator iter4=trueOutPorts.begin();iter4!=trueOutPorts.end();++iter4)
848  ret.push_back(pair<InPort *, OutPort *>(*iter2,*iter4));
849  }
850  }
851  return ret;
852 }
853 
855 
862 {
863  set<OutPort *> ret;
864  list<OutPort *> temp=getSetOfOutPort();
865  for(list<OutPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
866  {
867  set<InPort *> temp2=(*iter2)->edSetInPort();
868  for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
869  if(!isInMyDescendance((*iter3)->getNode()))
870  {
871  ret.insert(*iter2);
872  break;
873  }
874  }
875  return ret;
876 }
877 
879 
886 {
887  set<InPort *> ret;
888  list<InPort *> temp=getSetOfInPort();
889  for(list<InPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
890  {
891  set<OutPort *> temp2=(*iter2)->edSetOutPort();
892  for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
893  if(*iter3)
894  if(!isInMyDescendance((*iter3)->getNode()))
895  {
896  ret.insert(*iter2);
897  break;
898  }
899  }
900  return ret;
901 }
902 
904 {
905  //CF
906  DEBTRACE("-");
908  //Leaving part
909  DEBTRACE("--");
910  vector< pair<OutPort *, InPort *> > linksToDestroy=getSetOfLinksLeavingCurrentScope();
911  vector< pair<OutPort *, InPort *> >::iterator iter;
912  for(iter=linksToDestroy.begin();iter!=linksToDestroy.end();iter++)
913  {
914  DEBTRACE("---");
915  (*iter).first->removeInPort((*iter).second,true);
916  }
917  //Arriving part
918  vector< pair<InPort *, OutPort *> > linksToDestroy2=getSetOfLinksComingInCurrentScope();
919  vector< pair<InPort *, OutPort *> >::iterator iter2;
920  for(iter2=linksToDestroy2.begin();iter2!=linksToDestroy2.end();iter2++)
921  {
922  DEBTRACE("----");
923  (*iter2).second->removeInPort((*iter2).first,true);
924  }
925 }
926 
928 {
929  if(!_father)
930  return (ComposedNode *)this;
931  return Node::getRootNode();
932 }
933 
936 {
937  list<ComposedNode *> nodeAncestors = node->getAllAscendanceOf();
938  return find(nodeAncestors.begin(),nodeAncestors.end(),(ComposedNode *)this)!=nodeAncestors.end();
939 }
940 
942 
950 {
951  if(nodeToTest==0)
952  return 0;
953  if((ComposedNode *)nodeToTest==this)
954  return (Node *)this;
955  Node *iterBack=nodeToTest;
956  ComposedNode *iter=nodeToTest->_father;
957  while(iter!=0 && iter!=this)
958  {
959  iterBack=iter;
960  iter=iter->_father;
961  }
962  if(iter!=0)
963  return iterBack;
964  else
965  return 0;
966 }
967 
968 string ComposedNode::getChildName(const Node* node) const
969 {
970  string nodeName=node->getQualifiedName();
971  if (!isNodeAlreadyAggregated(node))
972  {
973  if (node->getName() == "thisIsAFakeNode")
974  {
975  string child = node->getName()+".thisIsAFakeNode";
976  return child;
977  }
978  else
979  {
980  string what("node "); what+= node->getName() ; what+=" is not a child of node "; what += getName();
981  throw Exception(what);
982  }
983  }
984 
985  const Node *father = node->_father;
986  while (father != this)
987  {
988  nodeName = father->getQualifiedName() + SEP_CHAR_BTW_LEVEL + nodeName;
989  father = father->_father;
990  }
991  return nodeName;
992 }
993 
994 std::string ComposedNode::getMyQualifiedName(const Node *directSon) const
995 {
996  return directSon->getName();
997 }
998 
999 Node *ComposedNode::getChildByName(const std::string& name) const
1000 {
1001  string potentiallyDirectSonName, remainsPath;
1002  bool forwardNeeded=ComposedNode::splitNamesBySep(name, SEP_CHAR_BTW_LEVEL,
1003  potentiallyDirectSonName,remainsPath,false);
1004  Node *child=getChildByShortName(potentiallyDirectSonName);
1005  if(!forwardNeeded)
1006  return child;
1007  else
1008  return child->getChildByName(remainsPath);
1009 }
1010 
1012 
1018 {
1019  const char whatC[]=" is not the descendance of node ";
1020  if(nodeToTest==0)
1021  {
1022  string what("node "); what+= nodeToTest->getName(); what+=" ";
1023  what+=whatC; what+=_name;
1024  throw Exception(what);
1025  }
1026  if((ComposedNode *)nodeToTest==this)
1027  return;
1028  ComposedNode *iter=nodeToTest->_father;
1029  while(iter!=0 && iter!=this)
1030  iter=iter->_father;
1031  if(iter==0)
1032  {
1033  string what("node "); what+= nodeToTest->getName(); what+=" ";
1034  what+=whatC; what+=_name;
1035  throw Exception(what);
1036  }
1037 }
1038 
1040 
1051 {
1052  const char what[]="The two nodes do not share the same genealogy";
1053  if(node1==0 || node2==0)
1054  throw Exception(what);
1055  ComposedNode *temp;
1056  if(dynamic_cast<ComposedNode *>(node1))
1057  temp=(ComposedNode *)node1;//->_father;
1058  else
1059  temp=(ComposedNode *)node1->_father;
1060  set<ComposedNode *> s;
1061  while(temp)
1062  {
1063  s.insert(temp);
1064  temp=temp->_father;
1065  }
1066  //
1067  if(dynamic_cast<ComposedNode *>(node2))
1068  temp=(ComposedNode *)node2;//->_father;
1069  else
1070  temp=(ComposedNode *)node2->_father;
1071  set<ComposedNode *>::iterator iter=s.find(temp);
1072  while(temp && iter==s.end())
1073  {
1074  iter=s.find(temp);
1075  temp=temp->_father;
1076  }
1077  if(iter==s.end())
1078  throw Exception(what);
1079  return *iter;
1080 }
1081 
1085 std::string ComposedNode::getLowestCommonAncestorStr(const std::string& node1, const std::string& node2)
1086 {
1087  std::string ret;
1088  std::size_t it1_b(0),it1_e(0),it2_b(0),it2_e(0);
1089  while(it1_b!=std::string::npos && it2_b!=std::string::npos)
1090  {
1091  it1_e=node1.find(SEP_CHAR_BTW_LEVEL,it1_b);
1092  it2_e=node2.find(SEP_CHAR_BTW_LEVEL,it2_b);
1093  if(it1_e!=it2_e && it1_e!=std::string::npos && it2_e!=std::string::npos)
1094  break;
1095  std::string elt1(node1.substr(it1_b,it1_e-it1_b)),elt2(node2.substr(it2_b,it2_e-it2_b));
1096  if(elt1!=elt2)
1097  break;
1098  if(!ret.empty())
1099  ret+=SEP_CHAR_BTW_LEVEL;
1100  ret+=elt1;
1101  it1_b=node1.find_first_not_of(SEP_CHAR_BTW_LEVEL,it1_e);
1102  it2_b=node2.find_first_not_of(SEP_CHAR_BTW_LEVEL,it2_e);
1103  }
1104  return ret;
1105 }
1106 
1111 {
1112  std::list<Node *> dd(edGetDirectDescendants());
1113  for(std::list<Node *>::const_iterator it=dd.begin();it!=dd.end();it++)
1114  {
1115  ComposedNode *elt(dynamic_cast<ComposedNode *>(*it));
1116  if(elt)
1118  }
1119 }
1120 
1121 list<ElementaryNode *> ComposedNode::getRecursiveConstituents() const
1122 {
1123  list<ElementaryNode *> ret;
1124  list<Node *> setOfNode=edGetDirectDescendants();
1125  for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1126  {
1127  list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1128  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1129  }
1130  return ret;
1131 }
1132 
1135 {
1136  list<Node *> ret;
1137  list<Node *> setOfNode=edGetDirectDescendants();
1138  for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1139  {
1140  if ( dynamic_cast<ComposedNode*> (*iter) )
1141  {
1142  list<Node *> myCurrentSet=((ComposedNode*)(*iter))->getAllRecursiveConstituents();
1143  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1144  ret.push_back(*iter);
1145  }
1146  else
1147  {
1148  list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1149  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1150  }
1151  }
1152  return ret;
1153 }
1154 
1157 {
1158  list<Node *> ret;
1159  list<Node *> setOfNode=edGetDirectDescendants();
1160  for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1161  {
1162  if ( dynamic_cast<ElementaryNode*> (*iter) )
1163  {
1164  list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1165  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1166  }
1167  else
1168  {
1169  list<Node *> myCurrentSet=((ComposedNode*)(*iter))->getAllRecursiveNodes();
1170  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1171  }
1172  }
1173  ret.push_back(this);
1174  return ret;
1175 }
1176 
1177 
1179 
1183 list<ProgressWeight> ComposedNode::getProgressWeight() const
1184 {
1185  list<ProgressWeight> ret;
1186  list<Node *> setOfNode=edGetDirectDescendants();
1187  for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1188  {
1189  list<ProgressWeight> myCurrentSet=((ComposedNode*)(*iter))->getProgressWeight();
1190  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1191  }
1192  return ret;
1193 }
1194 
1196 
1200 string ComposedNode::getInPortName(const InPort * inPort) const
1201 {
1202  return getPortName<InPort>(inPort);
1203 }
1204 
1205 string ComposedNode::getOutPortName(const OutPort *outPort) const
1206 {
1207  return getPortName<OutPort>(outPort);
1208 }
1209 
1211 {
1212  list<Node *> constituents=edGetDirectDescendants();
1213  int ret=0;
1214  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1215  ret+=(*iter)->getNumberOfInputPorts();
1216  return ret;
1217 }
1218 
1220 {
1221  list<Node *> constituents=edGetDirectDescendants();
1222  int ret=0;
1223  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1224  ret+=(*iter)->getNumberOfOutputPorts();
1225  return ret;
1226 }
1227 
1228 list<InputPort *> ComposedNode::getSetOfInputPort() const
1229 {
1230  list<Node *> constituents=edGetDirectDescendants();
1231  list<InputPort *> ret;
1232  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1233  {
1234  list<InputPort *> currentsPorts=(*iter)->getSetOfInputPort();
1235  ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1236  }
1237  return ret;
1238 }
1239 
1240 list<OutputPort *> ComposedNode::getSetOfOutputPort() const
1241 {
1242  list<Node *> constituents=edGetDirectDescendants();
1243  list<OutputPort *> ret;
1244  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1245  {
1246  list<OutputPort *> currentsPorts=(*iter)->getSetOfOutputPort();
1247  ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1248  }
1249  return ret;
1250 }
1251 
1252 list<InputDataStreamPort *> ComposedNode::getSetOfInputDataStreamPort() const
1253 {
1254  list<Node *> constituents=edGetDirectDescendants();
1255  list<InputDataStreamPort *> ret;
1256  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1257  {
1258  list<InputDataStreamPort *> currentsPorts=(*iter)->getSetOfInputDataStreamPort();
1259  ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1260  }
1261  return ret;
1262 }
1263 
1264 list<OutputDataStreamPort *> ComposedNode::getSetOfOutputDataStreamPort() const
1265 {
1266  list<Node *> constituents=edGetDirectDescendants();
1267  list<OutputDataStreamPort *> ret;
1268  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1269  {
1270  list<OutputDataStreamPort *> currentsPorts=(*iter)->getSetOfOutputDataStreamPort();
1271  ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1272  }
1273  return ret;
1274 }
1275 
1276 OutPort *ComposedNode::getOutPort(const std::string& name) const
1277 {
1278  string portName, nodeName;
1279  if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false))
1280  {
1281  Node *child = getChildByShortName(nodeName);
1282  return child->getOutPort(portName);
1283  }
1284  else
1285  {
1286  string what("ComposedNode::getOutPort : the port with name "); what+=name; what+=" does not exist on the current level";
1287  throw Exception(what);
1288  }
1289 }
1290 
1292 
1297 InputPort * ComposedNode::getInputPort(const std::string& name) const
1298 {
1299  try {
1300  return Node::getInputPort(name);
1301  }
1302  catch(Exception& e) {}
1303 
1304  string portName, nodeName;
1305  if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true))
1306  {
1307  Node *child = getChildByName(nodeName);
1308  return child->getInputPort(portName);
1309  }
1310  else
1311  {
1312  string what("ComposedNode::getInputPort : the port with name "); what+=name; what+=" does not exist on the current level";
1313  throw Exception(what);
1314  }
1315 }
1316 
1318 
1322 OutputPort * ComposedNode::getOutputPort(const std::string& name) const
1323 {
1324  string portName, nodeName;
1325  if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false))
1326  {
1327  Node *child = getChildByShortName(nodeName);
1328  return child->getOutputPort(portName);
1329  }
1330  else
1331  {
1332  string what("ComposedNode::getOutputPort : the port with name "); what+=name; what+=" does not exist on the current level";
1333  throw Exception(what);
1334  }
1335 }
1336 
1338 {
1339  string portName, nodeName;
1340  if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true))
1341  {
1342  Node *child = getChildByName(nodeName);
1343  return child->getInputDataStreamPort(portName);
1344  }
1345  else
1346  {
1347  string what("ComposedNode::getInputDataStreamPort : the port with name "); what+=name; what+=" does not exist on the current level";
1348  throw Exception(what);
1349  }
1350 }
1351 
1353 {
1354  string portName, nodeName;
1355  if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true))
1356  {
1357  Node *child = getChildByName(nodeName);
1358  return child->getOutputDataStreamPort(portName);
1359  }
1360  else
1361  {
1362  string what("ComposedNode::getOutputDataStreamPort : the port with name "); what+=name; what+=" does not exist on the current level";
1363  throw Exception(what);
1364  }
1365 }
1366 
1368 
1382 YACS::Event ComposedNode::updateStateFrom(Node *node, //* I : node emitting event
1383  YACS::Event event, //* I : event emitted
1384  const Executor *execInst
1385  )
1386 {
1387  DEBTRACE("updateStateFrom: " << node->getName() << " " << event);
1388  try
1389  {
1390  switch(event)
1391  {
1392  case YACS::START:
1393  return updateStateOnStartEventFrom(node);
1394  break;
1395  case YACS::FINISH:
1396  return updateStateOnFinishedEventFrom(node);
1397  break;
1398  case YACS::ABORT:
1399  return updateStateOnFailedEventFrom(node,execInst);
1400  break;
1401  default:
1402  return YACS::NOEVENT;//TODO unexpected type of event
1403  break;
1404  }
1405  }
1406  catch(YACS::Exception& ex)
1407  {
1408  //unexpected exception: probably a bug in engine
1409  //try to keep a consistent global state
1410  DEBTRACE( "updateStateFrom: " << ex.what() );
1411  _errorDetails="Internal error: ";
1412  _errorDetails=_errorDetails + ex.what();
1414  exForwardFailed();
1415  return YACS::ABORT;
1416  }
1417  catch(...)
1418  {
1419  //unexpected exception: probably a bug in engine
1420  //try to keep a consistent global state
1422  exForwardFailed();
1423  return YACS::ABORT;
1424  }
1425 }
1426 
1428 
1435 {
1437  return YACS::START;
1438 }
1439 
1442 {
1444  return YACS::ABORT;
1445 }
1446 
1447 void ComposedNode::checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
1448  InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd)
1449 {
1450  if((dynamic_cast<DataFlowPort *>(start) || dynamic_cast<DataFlowPort *>(end))
1451  && (dynamic_cast<DataStreamPort *>(start) || dynamic_cast<DataStreamPort *>(end)))
1452  {//cross protocol required : deeper check needed
1453  bool isOK=false;
1454  list<ComposedNode *>::const_iterator iter;
1455  for(iter=pointsOfViewStart.begin();iter!=pointsOfViewStart.end() && !isOK;iter++)
1456  isOK=(*iter)->isRepeatedUnpredictablySeveralTimes();
1457  for(iter=pointsOfViewEnd.begin();iter!=pointsOfViewEnd.end() && !isOK;iter++)
1458  isOK=(*iter)->isRepeatedUnpredictablySeveralTimes();
1459  if(!isOK)
1460  throw Exception("ComposedNode::checkLinkPossibility : Request for cross protocol link impossible.");
1461  }
1462 }
1463 
1464 void ComposedNode::buildDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView)
1465 {
1466 }
1467 
1468 void ComposedNode::buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
1469 {
1470 }
1471 
1472 void ComposedNode::getDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView)
1473 {
1474 }
1475 
1476 void ComposedNode::getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
1477 {
1478 }
1479 
1480 void ComposedNode::releaseDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView)
1481 {
1482 }
1483 
1484 void ComposedNode::releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
1485 {
1486 }
1487 
1489 {
1490 }
1492 {
1493 }
1494 
1496 {
1497  list<Node *> constituents=edGetDirectDescendants();
1498  for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
1499  {
1500  (*iter)->accept(visitor);
1501  }
1502 }
1503 
1504 void ComposedNode::setProperty(const std::string& name,const std::string& value)
1505 {
1506  Node::setProperty(name, value);
1507 }
1508 
1509 std::string ComposedNode::getProperty(const std::string& name)
1510 {
1511  return Node::getProperty(name);
1512 }
1513 
1514 
1516 std::list<InputPort *> ComposedNode::getLocalInputPorts() const
1517 {
1518  std::list<InputPort *> lip; return lip; // empty list
1519 }
1520 
1522 std::list<OutputPort *> ComposedNode::getLocalOutputPorts() const
1523 {
1524  std::list<OutputPort *> lop; return lop; // empty list
1525 }
1526 
1527 bool ComposedNode::isNameAlreadyUsed(const std::string& name) const
1528 {
1529  return false;
1530 }
1531 
1533 {
1534  DEBTRACE("ComposedNode::edUpdateState(): " << _state << " " << _modified);
1536 
1537  try
1538  {
1540  _errorDetails="";
1541  }
1542  catch(Exception& e)
1543  {
1545  _errorDetails=e.what();
1546  }
1547  DEBTRACE("ComposedNode::edUpdateState: " << _errorDetails);
1548 
1549  //update children if needed
1550  list<Node *> constituents=edGetDirectDescendants();
1551  for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
1552  {
1553  if(!(*iter)->isValid())
1555  }
1556  if(state != _state)
1557  setState(state);
1558  _modified=0;
1559 }
1560 
1562 {
1563  DEBTRACE("ComposedNode::getErrorReport: " << getName() << " " << _state);
1564  YACS::StatesForNode effectiveState=getEffectiveState();
1565 
1566  if(effectiveState != YACS::INVALID && effectiveState != YACS::ERROR && effectiveState != YACS::FAILED)
1567  return "";
1568 
1569  std::string report="<error node= " + getName();
1570  switch(effectiveState)
1571  {
1572  case YACS::INVALID:
1573  report=report+" state= INVALID";
1574  break;
1575  case YACS::ERROR:
1576  report=report+" state= ERROR";
1577  break;
1578  case YACS::FAILED:
1579  report=report+" state= FAILED";
1580  break;
1581  default:
1582  break;
1583  }
1584  report=report + ">\n" ;
1585  if(_errorDetails != "")
1586  report=report+_errorDetails+"\n";
1587 
1588  list<Node *> constituents=edGetDirectDescendants();
1589  for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
1590  {
1591  std::string rep=(*iter)->getErrorReport();
1592  if(rep != "")
1593  {
1594  report=report+rep+"\n";
1595  }
1596  }
1597  report=report+"</error>";
1598  return report;
1599 }
1600 
1601 
1602 
1604 {
1605  DEBTRACE("ComposedNode::checkBasicConsistency");
1606  std::list<InputPort *>::const_iterator iter;
1607  std::list<InputPort *> inports=getLocalInputPorts();
1608  for(iter=inports.begin();iter!=inports.end();iter++)
1609  (*iter)->checkBasicConsistency();
1610 }
1611 
1613 
1616 void ComposedNode::shutdown(int level)
1617 {
1618  if(level==0)return;
1619  DEBTRACE("ComposedNode::shutdown");
1620  list<Node *> nodes=edGetDirectDescendants();
1621  for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
1622  (*iter)->shutdown(level);
1623 }
1624 
1626 
1630 {
1631  DEBTRACE("ComposedNode::cleanNodes");
1632  list<Node *> nodes=edGetDirectDescendants();
1633  for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
1634  (*iter)->cleanNodes();
1635 }
1636 
1639 {
1640  if(level==0)return;
1641 
1642  DEBTRACE("ComposedNode::resetState " << level << "," << _state);
1644  {
1645  Node::resetState(level);
1646  std::list<Node *> nodes=edGetDirectDescendants();
1647  for(std::list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
1648  (*iter)->resetState(level);
1649  }
1650 }
#define DEBTRACE(msg)
Definition: YacsTrace.hxx:31
Base class for all component instances.
virtual bool setContainer(Container *cont)
virtual ComponentInstance * clone() const =0
Base class for all composed nodes.
std::list< InputDataStreamPort * > getSetOfInputDataStreamPort() const
std::string getChildName(const Node *node) const
Node * getChildByName(const std::string &name) const
static const unsigned char FREE_ST
DeploymentTree checkDeploymentTree(bool deep) const
Perform check of deployment consistency of the current graph.
std::list< ProgressWeight > getProgressWeight() const
Get the progress weight for all elementary nodes.
std::list< InputPort * > getSetOfInputPort() const
virtual void buildDelegateOf(InPort *&port, OutPort *initialStart, const std::list< ComposedNode * > &pointsOfView)
std::list< ElementaryNode * > getRecursiveConstituents() const
std::list< Node * > getAllRecursiveNodes()
Get all children nodes elementary and composed including this node.
void performDuplicationOfPlacement(const Node &other)
performs a duplication of placement using clone method of containers and components....
std::list< OutputPort * > getLocalOutputPorts() const
redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself
virtual void getDelegateOf(InPort *&port, OutPort *initialStart, const std::list< ComposedNode * > &pointsOfView)
OutPort * getOutPort(const std::string &name) const
virtual std::list< Node * > edGetDirectDescendants() const =0
DeploymentTree getDeploymentTree() const
Essentially for test. Use checkDeploymentTree instead to be sure that returned DeploymentTree is cons...
std::vector< std::pair< OutPort *, InPort * > > getSetOfInternalLinks() const
void checkNoCrossHierachyWith(Node *node) const
virtual bool isNameAlreadyUsed(const std::string &name) const
std::string getName() const
void edRemoveCFLink(Node *nodeS, Node *nodeE)
Remove a controlflow link.
void solveObviousOrDelegateCFLinks(const std::list< OutPort * > &starts, InputPort *end, unsigned char &alreadyFed, bool direction, LinkInfo &info) const
void performShallowDuplicationOfPlacement(const Node &other)
performs a also duplication of placement but here containers and components are not copied at all wha...
OutputPort * getOutputPort(const std::string &name) const
Get an output port given its name.
static const char SEP_CHAR_BTW_LEVEL[]
InputPort * getInputPort(const std::string &name) const
Get an input port given its name.
virtual std::list< Node * > getAllRecursiveConstituents()
Idem getAllRecursiveNodes, but this node is NOT included.
std::list< OutputPort * > getSetOfOutputPort() const
std::list< InputPort * > getLocalInputPorts() const
redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself
Node * getLowestNodeDealingAll(const std::list< OutPort * > &ports) const
virtual void edRemoveChild(Node *node)
Remove a child node.
virtual void edUpdateState()
update the status of the node
virtual void checkBasicConsistency() const
bool isNodeAlreadyAggregated(const Node *node) const
Check that Node 'node' is already a direct son of this.
virtual std::string getErrorReport()
returns a string that contains an error report if the node is in error
virtual Node * getChildByShortName(const std::string &name) const =0
std::set< OutPort * > getAllOutPortsLeavingCurrentScope() const
List all output ports of children nodes that are linked to out of scope input ports.
static std::string getLowestCommonAncestorStr(const std::string &node1, const std::string &node2)
YACS::Event updateStateFrom(Node *node, YACS::Event event, const Executor *execInst)
Update node state on receiving event from a node.
void checkLinksCoherenceRegardingControl(const std::vector< OutPort * > &starts, InputPort *end, LinkInfo &info) const
std::list< OutputDataStreamPort * > getSetOfOutputDataStreamPort() const
virtual void removeRecursivelyRedundantCL()
virtual bool isLoop() const
virtual std::vector< std::pair< OutPort *, InPort * > > getSetOfLinksLeavingCurrentScope() const
virtual void shutdown(int level)
Stop all pending activities of the composed node.
virtual void performCFComputations(LinkInfo &info) const
perform recursively all CF computations.
std::string getProperty(const std::string &name) override
virtual std::string getMyQualifiedName(const Node *directSon) const
static bool splitNamesBySep(const std::string &globalName, const char separator[], std::string &firstPart, std::string &lastPart, bool priority)
Splits name globalName in 2 parts using separator.
void checkInMyDescendance(Node *nodeToTest) const
Check if a node is in the descendance of this node.
static const unsigned char FED_ST
virtual bool edAddDFLink(OutPort *start, InPort *end)
Connect an OutPort to an InPort and add the necessary control link.
std::string getOutPortName(const OutPort *) const
std::string getInPortName(const InPort *) const
Get the input port name.
virtual void resetState(int level)
Reset the state of the node and its children depending on the parameter level.
std::set< InPort * > getAllInPortsComingFromOutsideOfCurrentScope() const
List all input ports that are linked to out of scope ports.
virtual void releaseDelegateOf(InPort *&port, OutPort *initialStart, const std::list< ComposedNode * > &pointsOfView)
virtual void checkNoCyclePassingThrough(Node *node)=0
OutputDataStreamPort * getOutputDataStreamPort(const std::string &name) const
virtual YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst)
Method used to notify the node that a child node has failed.
virtual YACS::Event updateStateOnFinishedEventFrom(Node *node)=0
std::string getTaskName(Task *task) const
virtual void checkControlDependancy(OutPort *start, InPort *end, bool cross, std::map< ComposedNode *, std::list< OutPort * >, SortHierarc > &fw, std::vector< OutPort * > &fwCross, std::map< ComposedNode *, std::list< OutPort * >, SortHierarc > &bw, LinkInfo &info) const =0
void accept(Visitor *visitor)
virtual void cleanNodes()
Clean the composed node in case of not clean exit.
virtual bool edAddChild(Node *DISOWNnode)
void init(bool start=true)
static const unsigned char FED_DS_ST
bool edAddCFLink(Node *nodeS, Node *nodeE)
Add a controlflow link between two nodes.
bool edAddLink(OutPort *start, InPort *end)
Add a dataflow link between two data ports.
virtual void destructCFComputations(LinkInfo &info) const
destroy recursively all results of initial computations.
void setProperty(const std::string &name, const std::string &value) override
void checkConsistency(LinkInfo &info) const
void edRemoveLink(OutPort *start, InPort *end)
Remove a dataflow link.
std::vector< Task * > getNextTasks(bool &isMore)
Node * isInMyDescendance(Node *nodeToTest) const
Returns the parent of a node that is the direct child of this node.
virtual void checkLinkPossibility(OutPort *start, const std::list< ComposedNode * > &pointsOfViewStart, InPort *end, const std::list< ComposedNode * > &pointsOfViewEnd)
static ComposedNode * getLowestCommonAncestor(Node *node1, Node *node2)
Retrieves the lowest common ancestor of 2 nodes.
InputDataStreamPort * getInputDataStreamPort(const std::string &name) const
virtual std::vector< std::pair< InPort *, OutPort * > > getSetOfLinksComingInCurrentScope() const
ComposedNode * getRootNode() const
virtual void checkCFLinks(const std::list< OutPort * > &starts, InputPort *end, unsigned char &alreadyFed, bool direction, LinkInfo &info) const
check control flow links
void notifyFrom(const Task *sender, YACS::Event event, const Executor *execInst)
Notify the node a task has emitted an event.
virtual YACS::Event updateStateOnStartEventFrom(Node *node)
Method used to notify the node that a child node has started.
virtual Container * clone() const =0
WARNING ! clone behaviour MUST be in coherence with what is returned by isAttachedOnCloning() method
std::string getName() const
Definition: DataPort.hxx:55
std::vector< Task * > getTasksLinkedToComponent(ComponentInstance *comp) const
std::vector< ComponentInstance * > getComponentsLinkedToContainer(Container *cont) const
std::vector< Task * > getTasksLinkedToContainer(Container *cont) const
static const unsigned char DUP_TASK_NOT_COMPATIBLE_WITH_EXISTING_TREE
static const unsigned char DEPLOYABLE_BUT_NOT_SPECIFIED
unsigned char appendTask(Task *task, Scheduler *cloner)
std::vector< Container * > getAllContainers() const
Base class for all calculation nodes.
Threaded Executor.
Definition: Executor.hxx:63
virtual void edNotifyDereferencedBy(OutPort *fromPort)
Definition: InPort.cxx:102
virtual void edNotifyReferencedBy(OutPort *fromPort, bool isLoopProof=true)
Definition: InPort.cxx:93
Class for calculation node (function) inlined (and executed) in the schema.
Definition: InlineNode.hxx:93
virtual void setContainer(Container *container)
Definition: InlineNode.cxx:105
Base class for Input Ports.
Definition: InputPort.hxx:44
virtual bool edIsManuallyInitialized() const
Specifies if this port has been manually set by the call of InputPort::edInit.
Definition: InputPort.cxx:76
Class that deal with list of semantics links for high level analysis.
Definition: LinkInfo.hxx:83
void pushErrLink(OutPort *semStart, InPort *end, ErrReason reason)
Definition: LinkInfo.cxx:86
void pushInfoLink(OutPort *semStart, InPort *end, InfoReason reason)
Definition: LinkInfo.cxx:71
void pushWarnLink(OutPort *semStart, InPort *end, WarnReason reason)
Definition: LinkInfo.cxx:76
void setPointOfView(ComposedNode *pov)
Definition: LinkInfo.cxx:66
Base class for all nodes.
Definition: Node.hxx:70
std::string _name
Definition: Node.hxx:89
friend class ComposedNode
Definition: Node.hxx:79
virtual ComposedNode * getRootNode() const
Definition: Node.cxx:431
ComposedNode * _father
Definition: Node.hxx:90
virtual void setProperty(const std::string &name, const std::string &value)
Definition: Node.cxx:491
virtual void getReadyTasks(std::vector< Task * > &tasks)=0
virtual InputDataStreamPort * getInputDataStreamPort(const std::string &name) const =0
OutGate * getOutGate()
Definition: Node.hxx:124
virtual void modified()
Sets Node in modified state and its father if it exists.
Definition: Node.cxx:805
std::string getQualifiedName() const
same as Node::getName() in most cases, but differs for children of switch
Definition: Node.cxx:632
static ComposedNode * checkHavingCommonFather(Node *node1, Node *node2)
Definition: Node.cxx:468
virtual Node * getChildByName(const std::string &name) const =0
virtual void init(bool start=true)
Definition: Node.cxx:102
virtual OutPort * getOutPort(const std::string &name) const
Definition: Node.cxx:275
ComposedNode * getFather() const
Definition: Node.hxx:127
std::list< OutPort * > getSetOfOutPort() const
Definition: Node.cxx:299
std::list< ComposedNode * > getAllAscendanceOf(ComposedNode *levelToStop=0) const
Definition: Node.cxx:317
virtual void resetState(int level)
Reset the node state depending on the parameter level.
Definition: Node.cxx:851
std::list< InPort * > getSetOfInPort() const
Definition: Node.cxx:289
void setState(YACS::StatesForNode theState)
Sets the given state for node.
Definition: Node.cxx:652
InGate * getInGate()
Definition: Node.hxx:123
static const char SEP_CHAR_IN_PORT[]
Definition: Node.hxx:94
const std::string & getName() const
Definition: Node.hxx:125
virtual InputPort * getInputPort(const std::string &name) const
Definition: Node.cxx:260
virtual void exForwardFailed()
Definition: Node.cxx:378
virtual OutputPort * getOutputPort(const std::string &name) const =0
std::string _errorDetails
Definition: Node.hxx:93
virtual YACS::StatesForNode getEffectiveState() const
Return the node state in the context of its father.
Definition: Node.cxx:538
YACS::StatesForNode _state
Definition: Node.hxx:91
virtual std::string getProperty(const std::string &name)
Definition: Node.cxx:497
virtual OutputDataStreamPort * getOutputDataStreamPort(const std::string &name) const =0
virtual void edDisconnectAllLinksWithMe()
Definition: Node.cxx:395
void edRemoveInGate(InGate *inGate, bool coherenceWithInGate=true)
Definition: OutGate.cxx:120
bool edAddInGate(InGate *inGate)
Definition: OutGate.cxx:98
virtual bool isAlreadyLinkedWith(InPort *withp) const =0
virtual void getAllRepresented(std::set< OutPort * > &represented) const
Definition: OutPort.cxx:45
Node * getNode() const
Definition: Port.hxx:46
Class for calculation node associated with a component service.
Definition: ServiceNode.hxx:35
virtual void setComponent(ComponentInstance *compo)
Associate an existing component instance to this service node AND check the consistency regarding the...
const char * what(void) const noexcept
Definition: Exception.cxx:50
@ E_NEVER_SET_INPUTPORT
Definition: LinkInfo.hxx:69
@ E_ONLY_BACKWARD_DEFINED
Definition: LinkInfo.hxx:70
@ W_COLLAPSE_EL_AND_USELESS
Definition: LinkInfo.hxx:59
@ W_BACK_COLLAPSE_EL
Definition: LinkInfo.hxx:62
@ W_BACK_COLLAPSE_EL_AND_USELESS
Definition: LinkInfo.hxx:63
Event
Definition: define.hxx:56
@ ABORT
Definition: define.hxx:60
@ NOEVENT
Definition: define.hxx:57
@ START
Definition: define.hxx:58
@ FINISH
Definition: define.hxx:59
StatesForNode
Definition: define.hxx:34
@ INVALID
Definition: define.hxx:36
@ FAILED
Definition: define.hxx:51
@ READY
Definition: define.hxx:37
@ ACTIVATED
Definition: define.hxx:41
@ DONE
Definition: define.hxx:43
@ DISABLED
Definition: define.hxx:50
@ ERROR
Definition: define.hxx:52