Version: 8.3.0
ComposedNode.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 "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 {
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 {
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  while(iterS!=lwstCmnAnctr)
311  {
312  iterS->buildDelegateOf(currentPortI, start, allAscendanceOfNodeStart);
313  iterS=iterS->_father;
314  }
315  bool ret=(pO.first)->addInPort(currentPortI);
316  end->edNotifyReferencedBy(pO.second);
317  return ret;
318 }
319 
321 
330 {
331  Node* n1=start->getNode();
332  Node* n2=end->getNode();
333  DEBTRACE( n1->getName() << ":" << n2->getName())
334  ComposedNode* father=getLowestCommonAncestor(n1,n2);
335  DEBTRACE( "ComposedNode::edAddDFLink: this="<<this->getName()
336  << " father=" << father->getName() )
337  DEBTRACE( "ComposedNode::edAddDFLink: OutPort=" << start->getName()
338  << " InPort=" << end->getName() )
339  if (father != this)
340  {
341  bool ret = father->edAddDFLink(start,end); // special treatement for loop
342  return ret;
343  }
344  if(n2 == father)
345  throw Exception("Back link authorized only in special context (loop for example)");
346 
347  bool ret= edAddLink(start,end);
348  if(n1 != father)
349  {
350  //add a control link only if nodes are not in the same descendance
351  //if n1 == father (n2 is after n1) : the control link is not needed
352  //if n2 == father (n1 is after n2) : it's a back link authorized only in loop context
353  while(n1->getFather() != father)
354  n1=n1->getFather();
355  while(n2->getFather() != father)
356  n2=n2->getFather();
357  try
358  {
359  edAddCFLink(n1,n2);
360  }
361  catch (Exception& ex)
362  {
363  // --- remove DF link already created in case of cycle dtection
364  DEBTRACE("Cycle detected, remove CF link");
365  if(start->isAlreadyLinkedWith(end))
366  edRemoveLink(start, end);
367  throw ex;
368  }
369  }
370  return ret;
371 }
372 
374 
384 {
385  Node* n1=start->getNode();
386  Node* n2=end->getNode();
387  if(n1==n2)
388  throw Exception("ComposedNode::edAddLink: can not add a control link to a node with itself",1);
389  ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode());
390  if(father==0)
391  throw Exception("ComposedNode::edAddLink: Trying to add CF link on orphan nodes.");
392  if(father!=this)
393  {
394  checkInMyDescendance(father);
395  return father->edAddLink(start,end);
396  }
397  bool ret=start->edAddInGate(end);
398  if(ret)
399  try
400  {
401  checkNoCyclePassingThrough(end->getNode());
402  }
403  catch (Exception& ex)
404  {
405  // --- remove created CF link in case of cycle detection
406  DEBTRACE("Cycle detected, remove CF link");
407  edRemoveCFLink(start->getNode(), end->getNode());
408  throw ex;
409  }
410  return ret;
411 }
412 
414 
418 {
419  return edAddLink(nodeS->getOutGate(),nodeE->getInGate());
420 }
421 
424 {
425  edRemoveLink(nodeS->getOutGate(),nodeE->getInGate());
426 }
427 
429 
438 {
439  if(!start->isAlreadyLinkedWith(end))
440  throw Exception("ComposedNode::edRemoveLink : unexisting link");
441  ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode());
442  checkInMyDescendance(lwstCmnAnctr);
443  list<ComposedNode *> allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr);
444  list<ComposedNode *> allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr);
445 
446  // --- Part of test if the link from 'start' to 'end' really exist particulary all eventually intermediate ports created
447 
448  ComposedNode *iterS=start->getNode()->_father;
449  pair<OutPort *,OutPort *> currentPortO(start,start);
450  vector<pair< ComposedNode * , pair < OutPort* , OutPort *> > > needsToDestroyO;
451 
452  Node *nodeOTemp=start->getNode();
453  if(*nodeOTemp<*lwstCmnAnctr)
454  {
455  iterS=nodeOTemp->_father;
456  while(iterS!=lwstCmnAnctr)
457  {
458  if (!iterS)
459  {
460  stringstream what;
461  what << "ComposedNode::edRemoveLink: "
462  << start->getNode()->getName() << "." <<start->getName() << "->"
463  << end->getNode()->getName() << "." << end->getName();
464  throw Exception(what.str());
465  }
466  OutPort *tmp=currentPortO.first;
467  iterS->getDelegateOf(currentPortO, end, allAscendanceOfNodeEnd);
468  needsToDestroyO.push_back(pair< ComposedNode * , pair < OutPort* , OutPort *> >(iterS,pair<OutPort* , OutPort *> (tmp,currentPortO.first)));
469  iterS=iterS->_father;
470  }
471  }
472  Node *nodeTemp=end->getNode();
473  InPort * currentPortI=end;
474  if(*nodeTemp<*lwstCmnAnctr)
475  {
476  iterS=nodeTemp->_father;
477  while(iterS!=lwstCmnAnctr)
478  {
479  if (!iterS)
480  {
481  stringstream what;
482  what << "ComposedNode::edRemoveLink: "
483  << start->getNode()->getName() << "." <<start->getName() << "->"
484  << end->getNode()->getName() << "." << end->getName();
485  throw Exception(what.str());
486  }
487  iterS->getDelegateOf(currentPortI, start, allAscendanceOfNodeStart);
488  iterS=iterS->_father;
489  }
490  }
491  // --- End of test for evt intermediate ports created
492 
493  (currentPortO.first)->removeInPort(currentPortI,false);
494  set<OutPort *> repr;
495  (currentPortO.second)->getAllRepresented(repr);
496  if(repr.size()==1)
497  end->edNotifyDereferencedBy(currentPortO.second);
498 
499  // --- Performing deletion of intermediate ports
500 
501  iterS=start->getNode()->_father;
502  vector<pair< ComposedNode * , pair < OutPort* , OutPort *> > >::reverse_iterator iter;
503  for(iter=needsToDestroyO.rbegin();iter!=needsToDestroyO.rend();iter++)
504  (*iter).first->releaseDelegateOf(((*iter).second).first, ((*iter).second).second, end,allAscendanceOfNodeEnd);
505  nodeTemp=end->getNode();
506  if(*nodeTemp<*lwstCmnAnctr)
507  {
508  iterS=end->getNode()->_father;
509  currentPortI=end;
510  while(iterS!=lwstCmnAnctr)
511  {
512  iterS->releaseDelegateOf(currentPortI, start, allAscendanceOfNodeStart);
513  iterS=iterS->_father;
514  }
515  }
516 }
517 
520 {
521  ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode());
522  if(father!=this)
523  throw Exception("edRemoveLink : nodes not in direct descendance of this");
524  start->edRemoveInGate(end);
525 }
526 
528 {
529  return false; // --- reimplemented in derived classes
530 }
531 
534 {
535  if(!node)
536  return;
537  if (node->_father!=this)
538  {
539  string what("node "); what+= node->getName() ; what+=" is not a child of node "; what += getName();
540  throw Exception(what);
541  }
542  node->edDisconnectAllLinksWithMe();
543  node->_father = 0;
544  //set _modified flag so edUpdateState() can refresh state
545  modified();
546 }
547 
549 
557 bool ComposedNode::splitNamesBySep(const std::string& globalName, const char separator[],
558  std::string& firstPart, std::string& lastPart, bool priority) throw(YACS::Exception)
559 {
560  const string delims(separator);
561  string portName, nodeName;
562  string::size_type idx;
563  if(priority)
564  idx = globalName.find_last_of(delims);
565  else
566  idx = globalName.find_first_of(delims);
567  if (idx == string::npos)
568  {
569  firstPart=globalName;
570  lastPart="";
571  return false;
572  }
573  firstPart = globalName.substr(0,idx);
574  lastPart = globalName.substr(idx+1);
575  if ((firstPart.empty()) || (lastPart.empty()))
576  {
577  string what("the name "); what+= globalName ; what+=" is not a valid port name";
578  throw Exception(what);
579  }
580  return true;
581 }
582 
583 std::vector< std::pair<OutPort *, InPort *> > ComposedNode::getSetOfInternalLinks() const
584 {
585  vector< pair<OutPort *, InPort *> > ret;
586  list<OutPort *> temp=getSetOfOutPort();
587  for(list<OutPort *>::const_iterator iter2=temp.begin();iter2!=temp.end();iter2++)
588  {
589  set<InPort *> temp2=(*iter2)->edSetInPort();
590  for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
591  if(isInMyDescendance((*iter3)->getNode()))
592  ret.push_back(pair<OutPort *, InPort *>((*iter2),(*iter3)));
593  }
594  return ret;
595 }
596 
597 std::vector< std::pair<OutPort *, InPort *> > ComposedNode::getSetOfLinksLeavingCurrentScope() const
598 {
599  vector< pair<OutPort *, InPort *> > ret;
600  std::set<OutPort *> ports=getAllOutPortsLeavingCurrentScope();
601  for(set<OutPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
602  {
603  set<InPort *> temp2=(*iter2)->edSetInPort();
604  for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
605  if(!isInMyDescendance((*iter3)->getNode()))
606  ret.push_back(pair<OutPort *, InPort *>(*iter2,*iter3));
607  }
608  return ret;
609 }
610 
612 {
613  info.clearAll();
614  info.setPointOfView((ComposedNode *)this);
615  performCFComputations(info);
616  list<InputPort *> setOfInToTest=getSetOfInputPort();
617  for(list<InputPort *>::iterator iter1=setOfInToTest.begin();iter1!=setOfInToTest.end();iter1++)
618  {
619  vector<OutPort *> candidateForAdvCheck;
620  set<OutPort *> outPorts=(*iter1)->edSetOutPort();
621  //Filtering among outPorts, which of them, are candidates to fill *iter1 at the current scope.
622  for(set<OutPort *>::iterator iter2=outPorts.begin();iter2!=outPorts.end();iter2++)
623  {
624  (*iter2)->checkConsistency(info);
625  ComposedNode *manager=getLowestCommonAncestor((*iter2)->getNode(),(*iter1)->getNode());
626  if(isInMyDescendance(manager))
627  candidateForAdvCheck.push_back(*iter2);
628  }
629  if(!candidateForAdvCheck.empty())
630  //End of filtering. Now regarding CF constraints for the current InPutPort.
631  try
632  {
633  checkLinksCoherenceRegardingControl(candidateForAdvCheck,*iter1,info);
634  }
635  catch(YACS::Exception& ex)
636  {
637  std::string what=ex.what();
638  what += "\nfor input port: ";
639  what += (*iter1)->getNode()->getName();
640  what += ".";
641  what += (*iter1)->getName();
642 
643  destructCFComputations(info);
644  throw YACS::Exception(what);
645  }
646  else
647  //No backlinks
648  if(!(*iter1)->canBeNull() && !(*iter1)->edIsManuallyInitialized())
649  info.pushErrLink(0,*iter1,E_NEVER_SET_INPUTPORT);
650  }
651  destructCFComputations(info);
652 }
653 
659 {
660  ComposedNode *nodeC=dynamic_cast<ComposedNode *>(node);
661  if(!nodeC)
662  return ;
663  list<ComposedNode *> ascendants=getAllAscendanceOf();
664  if(find(ascendants.begin(),ascendants.end(),nodeC)!=ascendants.end())
665  {
666  const char what[]="ComposedNode::checkNoCrossHierachyWith : ComposedNode with name \"";
667  string stream(what); stream+=node->getName(); stream+="\" is already in hierarchy ascendance of node with name \"";
668  stream+=_name; stream+="\" ; So it can't be now in its descendance !";
669  throw Exception(stream);
670  }
671 }
672 
675 {
676  list<Node *> nodes=edGetDirectDescendants();
677  for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
678  if(dynamic_cast<ComposedNode *>(*iter))
679  ((ComposedNode *)(*iter))->performCFComputations(info);
680 }
681 
684 {
685  list<Node *> nodes=edGetDirectDescendants();
686  for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
687  if(dynamic_cast<ComposedNode *>(*iter))
688  ((ComposedNode *)(*iter))->destructCFComputations(info);
689 }
690 
696 Node *ComposedNode::getLowestNodeDealingAll(const std::list<OutPort *>& ports) const
697 {
698  list< OutPort *>::const_iterator iter=ports.begin();
699  Node *ret=(*iter)->getNode();
700  iter++;
701  for(;iter!=ports.end();iter++)
702  {
703  Node *tmp=(*iter)->getNode();
704  if(*tmp>*ret)
705  ret=tmp;
706  }
707  return ret;
708 }
709 
713 void ComposedNode::checkLinksCoherenceRegardingControl(const std::vector<OutPort *>& starts, InputPort *end, LinkInfo& info) const throw(YACS::Exception)
714 {
715  map < ComposedNode *, list<OutPort *>, SortHierarc > outputs;//forward link classical
716  vector<OutPort *> outputsCross;//forward link cross
717  map < ComposedNode *, list<OutPort *>, SortHierarc > outputsBw;//backward
718  vector<OutPort *>::const_iterator iter1;
719  //vector<DataPort *> history=((*iter1).second)[0]->calculateHistoryOfLinkWith(end);
720  //DataPort *cross=DataPort::isCrossingType(history);
721  for(iter1=starts.begin();iter1!=starts.end();iter1++)
722  {
723  ComposedNode *manager=getLowestCommonAncestor((*iter1)->getNode(),end->getNode());
724  manager->checkControlDependancy((*iter1), end, false, outputs, outputsCross, outputsBw, info);
725  }
726  //Ok now let's regarding outputs all combinations : (outputs.size())*(outputs.size()-1)/2
727  unsigned char isAlreadyFed=FREE_ST;
728  //Dealing excusively with DS. Level is useless here because simultaneity is required for DS.
729  if(outputsCross.size()>0)
730  {
731  isAlreadyFed=FED_DS_ST;
732  if(outputsCross.size()>1)
733  for(vector< OutPort *>::const_iterator iter1=outputsCross.begin();iter1!=(outputsCross.end()-2);iter1++)
734  info.pushErrLink(*iter1,end,E_COLLAPSE_DS);
735  }
736  map < ComposedNode *, list<OutPort *>, SortHierarc >::iterator iter3=outputs.begin();
737  for(;iter3!=outputs.end();iter3++)
738  ((*iter3).first)->checkCFLinks((*iter3).second,end,isAlreadyFed,true,info);
739  if(isAlreadyFed==FREE_ST)
740  if(!end->edIsManuallyInitialized())
741  info.pushErrLink(0,end,E_ONLY_BACKWARD_DEFINED);
742  isAlreadyFed=FREE_ST;
743  //
744  map < ComposedNode *, list<OutPort *>, SortHierarc >::reverse_iterator iter5=outputsBw.rbegin();
745  for(;iter5!=outputsBw.rend();iter5++)
746  ((*iter5).first)->checkCFLinks((*iter5).second,end,isAlreadyFed,false,info);
747 }
748 
753 void ComposedNode::solveObviousOrDelegateCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
754 {
755  static const char what[]="ComposedNode::solveObviousOrDelegateCFLinks : Internal error occured - uncorrect hierarchy detected !";
756  if(starts.size()==1)
757  {
758  if(alreadyFed==FREE_ST)
759  {
760  if(!direction)
761  info.pushInfoLink(*(starts.begin()),end,I_BACK);
762  alreadyFed=FED_ST;
763  }
764  else if(alreadyFed==FED_ST)
765  info.pushInfoLink(*(starts.begin()),end,direction ? I_USELESS : I_BACK_USELESS);
766  else
767  info.pushErrLink(*(starts.begin()),end,E_COLLAPSE_DFDS);
768  }
769  else
770  {
771  Node *levelOfDecision=getLowestNodeDealingAll(starts);
772  if(levelOfDecision==this)
773  throw Exception(what);
774  if(dynamic_cast<ElementaryNode *>(levelOfDecision))
775  {
776  WarnReason reason;
777  if(alreadyFed==FREE_ST || alreadyFed==FED_ST)
778  {
779  if(alreadyFed==FREE_ST)
780  {
781  reason=direction ? W_COLLAPSE_EL : W_BACK_COLLAPSE_EL;
782  alreadyFed=FED_ST;
783  }
784  else
786  for(list< OutPort *>::const_iterator iter=starts.begin();iter!=starts.end();iter++)
787  info.pushWarnLink(*iter,end,reason);
788  }
789  }
790  else
791  ((ComposedNode *)levelOfDecision)->checkCFLinks(starts,end,alreadyFed,direction,info);
792  }
793 }
794 
796 
803 void ComposedNode::checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
804 {
805  static const char what[]="ComposedNode::checkCFLinks : Internal error occured - uncorrect hierarchy detected !";
806  Node *nodeEnd=isInMyDescendance(end->getNode());
807  if(!nodeEnd)
808  return solveObviousOrDelegateCFLinks(starts,end,alreadyFed,direction,info);
809  //This case is typically dedicated when direct son is ElementaryNode and self link is defined on this.
810  if(!dynamic_cast<ElementaryNode *>(nodeEnd))
811  throw Exception(what);
812 
813  list< OutPort *>::const_iterator iter=starts.begin();
814  Node *nodeStart=(*iter)->getNode();
815  iter++;
816  if(nodeEnd!=nodeStart)
817  throw Exception(what);
818 
819  for(;iter!=starts.end();iter++)
820  if((*iter)->getNode()!=nodeStart)
821  throw Exception(what);
822  //Ok at this step we are sure that we have back links on the same elementary node.
823  if(starts.size()>1)
824  for(iter=starts.begin();iter!=starts.end();iter++)
825  info.pushWarnLink(*iter,end,W_BACK_COLLAPSE_EL);
826  else//here no need to look at 'alreadyFed' var because it is waranteed to be equal to FREE_ST by construction.
827  info.pushInfoLink(*(starts.begin()),end,I_BACK);
828  alreadyFed=FED_ST;
829 }
830 
831 std::vector< std::pair<InPort *, OutPort *> > ComposedNode::getSetOfLinksComingInCurrentScope() const
832 {
833  vector< pair<InPort *, OutPort *> > ret;
834  set<InPort *> ports=getAllInPortsComingFromOutsideOfCurrentScope();
835  for(set<InPort *>::iterator iter2=ports.begin();iter2!=ports.end();iter2++)
836  {
837  set<OutPort *> temp2=(*iter2)->edSetOutPort();
838  for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
839  {
840  if(isInMyDescendance((*iter3)->getNode()))continue;
841  std::set<OutPort *> trueOutPorts;
842  (*iter3)->getAllRepresented(trueOutPorts);
843  for(std::set<OutPort *>::iterator iter4=trueOutPorts.begin();iter4!=trueOutPorts.end();++iter4)
844  ret.push_back(pair<InPort *, OutPort *>(*iter2,*iter4));
845  }
846  }
847  return ret;
848 }
849 
851 
858 {
859  set<OutPort *> ret;
860  list<OutPort *> temp=getSetOfOutPort();
861  for(list<OutPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
862  {
863  set<InPort *> temp2=(*iter2)->edSetInPort();
864  for(set<InPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
865  if(!isInMyDescendance((*iter3)->getNode()))
866  {
867  ret.insert(*iter2);
868  break;
869  }
870  }
871  return ret;
872 }
873 
875 
882 {
883  set<InPort *> ret;
884  list<InPort *> temp=getSetOfInPort();
885  for(list<InPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
886  {
887  set<OutPort *> temp2=(*iter2)->edSetOutPort();
888  for(set<OutPort *>::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++)
889  if(*iter3)
890  if(!isInMyDescendance((*iter3)->getNode()))
891  {
892  ret.insert(*iter2);
893  break;
894  }
895  }
896  return ret;
897 }
898 
900 {
901  //CF
902  DEBTRACE("-");
904  //Leaving part
905  DEBTRACE("--");
906  vector< pair<OutPort *, InPort *> > linksToDestroy=getSetOfLinksLeavingCurrentScope();
907  vector< pair<OutPort *, InPort *> >::iterator iter;
908  for(iter=linksToDestroy.begin();iter!=linksToDestroy.end();iter++)
909  {
910  DEBTRACE("---");
911  (*iter).first->removeInPort((*iter).second,true);
912  }
913  //Arriving part
914  vector< pair<InPort *, OutPort *> > linksToDestroy2=getSetOfLinksComingInCurrentScope();
915  vector< pair<InPort *, OutPort *> >::iterator iter2;
916  for(iter2=linksToDestroy2.begin();iter2!=linksToDestroy2.end();iter2++)
917  {
918  DEBTRACE("----");
919  (*iter2).second->removeInPort((*iter2).first,true);
920  }
921 }
922 
924 {
925  if(!_father)
926  return (ComposedNode *)this;
927  return Node::getRootNode();
928 }
929 
932 {
933  list<ComposedNode *> nodeAncestors = node->getAllAscendanceOf();
934  return find(nodeAncestors.begin(),nodeAncestors.end(),(ComposedNode *)this)!=nodeAncestors.end();
935 }
936 
938 
946 {
947  if(nodeToTest==0)
948  return 0;
949  if((ComposedNode *)nodeToTest==this)
950  return (Node *)this;
951  Node *iterBack=nodeToTest;
952  ComposedNode *iter=nodeToTest->_father;
953  while(iter!=0 && iter!=this)
954  {
955  iterBack=iter;
956  iter=iter->_father;
957  }
958  if(iter!=0)
959  return iterBack;
960  else
961  return 0;
962 }
963 
964 string ComposedNode::getChildName(const Node* node) const throw(YACS::Exception)
965 {
966  string nodeName=node->getQualifiedName();
967  if (!isNodeAlreadyAggregated(node))
968  {
969  if (node->getName() == "thisIsAFakeNode")
970  {
971  string child = node->getName()+".thisIsAFakeNode";
972  return child;
973  }
974  else
975  {
976  string what("node "); what+= node->getName() ; what+=" is not a child of node "; what += getName();
977  throw Exception(what);
978  }
979  }
980 
981  const Node *father = node->_father;
982  while (father != this)
983  {
984  nodeName = father->getQualifiedName() + SEP_CHAR_BTW_LEVEL + nodeName;
985  father = father->_father;
986  }
987  return nodeName;
988 }
989 
990 std::string ComposedNode::getMyQualifiedName(const Node *directSon) const
991 {
992  return directSon->getName();
993 }
994 
995 Node *ComposedNode::getChildByName(const std::string& name) const throw(YACS::Exception)
996 {
997  string potentiallyDirectSonName, remainsPath;
998  bool forwardNeeded=ComposedNode::splitNamesBySep(name, SEP_CHAR_BTW_LEVEL,
999  potentiallyDirectSonName,remainsPath,false);
1000  Node *child=getChildByShortName(potentiallyDirectSonName);
1001  if(!forwardNeeded)
1002  return child;
1003  else
1004  return child->getChildByName(remainsPath);
1005 }
1006 
1008 
1014 {
1015  const char whatC[]=" is not the descendance of node ";
1016  if(nodeToTest==0)
1017  {
1018  string what("node "); what+= nodeToTest->getName(); what+=" ";
1019  what+=whatC; what+=_name;
1020  throw Exception(what);
1021  }
1022  if((ComposedNode *)nodeToTest==this)
1023  return;
1024  ComposedNode *iter=nodeToTest->_father;
1025  while(iter!=0 && iter!=this)
1026  iter=iter->_father;
1027  if(iter==0)
1028  {
1029  string what("node "); what+= nodeToTest->getName(); what+=" ";
1030  what+=whatC; what+=_name;
1031  throw Exception(what);
1032  }
1033 }
1034 
1036 
1047 {
1048  const char what[]="The two nodes do not share the same genealogy";
1049  if(node1==0 || node2==0)
1050  throw Exception(what);
1051  ComposedNode *temp;
1052  if(dynamic_cast<ComposedNode *>(node1))
1053  temp=(ComposedNode *)node1;//->_father;
1054  else
1055  temp=(ComposedNode *)node1->_father;
1056  set<ComposedNode *> s;
1057  while(temp)
1058  {
1059  s.insert(temp);
1060  temp=temp->_father;
1061  }
1062  //
1063  if(dynamic_cast<ComposedNode *>(node2))
1064  temp=(ComposedNode *)node2;//->_father;
1065  else
1066  temp=(ComposedNode *)node2->_father;
1067  set<ComposedNode *>::iterator iter=s.find(temp);
1068  while(temp && iter==s.end())
1069  {
1070  iter=s.find(temp);
1071  temp=temp->_father;
1072  }
1073  if(iter==s.end())
1074  throw Exception(what);
1075  return *iter;
1076 }
1077 
1081 std::string ComposedNode::getLowestCommonAncestorStr(const std::string& node1, const std::string& node2)
1082 {
1083  std::string ret;
1084  std::size_t it1_b(0),it1_e(0),it2_b(0),it2_e(0);
1085  while(it1_b!=std::string::npos && it2_b!=std::string::npos)
1086  {
1087  it1_e=node1.find(SEP_CHAR_BTW_LEVEL,it1_b);
1088  it2_e=node2.find(SEP_CHAR_BTW_LEVEL,it2_b);
1089  if(it1_e!=it2_e && it1_e!=std::string::npos && it2_e!=std::string::npos)
1090  break;
1091  std::string elt1(node1.substr(it1_b,it1_e-it1_b)),elt2(node2.substr(it2_b,it2_e-it2_b));
1092  if(elt1!=elt2)
1093  break;
1094  if(!ret.empty())
1095  ret+=SEP_CHAR_BTW_LEVEL;
1096  ret+=elt1;
1097  it1_b=node1.find_first_not_of(SEP_CHAR_BTW_LEVEL,it1_e);
1098  it2_b=node2.find_first_not_of(SEP_CHAR_BTW_LEVEL,it2_e);
1099  }
1100  return ret;
1101 }
1102 
1107 {
1108  std::list<Node *> dd(edGetDirectDescendants());
1109  for(std::list<Node *>::const_iterator it=dd.begin();it!=dd.end();it++)
1110  {
1111  ComposedNode *elt(dynamic_cast<ComposedNode *>(*it));
1112  if(elt)
1114  }
1115 }
1116 
1117 list<ElementaryNode *> ComposedNode::getRecursiveConstituents() const
1118 {
1119  list<ElementaryNode *> ret;
1120  list<Node *> setOfNode=edGetDirectDescendants();
1121  for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1122  {
1123  list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1124  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1125  }
1126  return ret;
1127 }
1128 
1131 {
1132  list<Node *> ret;
1133  list<Node *> setOfNode=edGetDirectDescendants();
1134  for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1135  {
1136  if ( dynamic_cast<ComposedNode*> (*iter) )
1137  {
1138  list<Node *> myCurrentSet=((ComposedNode*)(*iter))->getAllRecursiveConstituents();
1139  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1140  ret.push_back(*iter);
1141  }
1142  else
1143  {
1144  list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1145  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1146  }
1147  }
1148  return ret;
1149 }
1150 
1153 {
1154  list<Node *> ret;
1155  list<Node *> setOfNode=edGetDirectDescendants();
1156  for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1157  {
1158  if ( dynamic_cast<ElementaryNode*> (*iter) )
1159  {
1160  list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1161  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1162  }
1163  else
1164  {
1165  list<Node *> myCurrentSet=((ComposedNode*)(*iter))->getAllRecursiveNodes();
1166  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1167  }
1168  }
1169  ret.push_back(this);
1170  return ret;
1171 }
1172 
1173 
1175 
1179 list<ProgressWeight> ComposedNode::getProgressWeight() const
1180 {
1181  list<ProgressWeight> ret;
1182  list<Node *> setOfNode=edGetDirectDescendants();
1183  for(list<Node *>::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1184  {
1185  list<ProgressWeight> myCurrentSet=((ComposedNode*)(*iter))->getProgressWeight();
1186  ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end());
1187  }
1188  return ret;
1189 }
1190 
1192 
1196 string ComposedNode::getInPortName(const InPort * inPort) const throw(YACS::Exception)
1197 {
1198  return getPortName<InPort>(inPort);
1199 }
1200 
1201 string ComposedNode::getOutPortName(const OutPort *outPort) const throw(YACS::Exception)
1202 {
1203  return getPortName<OutPort>(outPort);
1204 }
1205 
1207 {
1208  list<Node *> constituents=edGetDirectDescendants();
1209  int ret=0;
1210  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1211  ret+=(*iter)->getNumberOfInputPorts();
1212  return ret;
1213 }
1214 
1216 {
1217  list<Node *> constituents=edGetDirectDescendants();
1218  int ret=0;
1219  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1220  ret+=(*iter)->getNumberOfOutputPorts();
1221  return ret;
1222 }
1223 
1224 list<InputPort *> ComposedNode::getSetOfInputPort() const
1225 {
1226  list<Node *> constituents=edGetDirectDescendants();
1227  list<InputPort *> ret;
1228  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1229  {
1230  list<InputPort *> currentsPorts=(*iter)->getSetOfInputPort();
1231  ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1232  }
1233  return ret;
1234 }
1235 
1236 list<OutputPort *> ComposedNode::getSetOfOutputPort() const
1237 {
1238  list<Node *> constituents=edGetDirectDescendants();
1239  list<OutputPort *> ret;
1240  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1241  {
1242  list<OutputPort *> currentsPorts=(*iter)->getSetOfOutputPort();
1243  ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1244  }
1245  return ret;
1246 }
1247 
1248 list<InputDataStreamPort *> ComposedNode::getSetOfInputDataStreamPort() const
1249 {
1250  list<Node *> constituents=edGetDirectDescendants();
1251  list<InputDataStreamPort *> ret;
1252  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1253  {
1254  list<InputDataStreamPort *> currentsPorts=(*iter)->getSetOfInputDataStreamPort();
1255  ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1256  }
1257  return ret;
1258 }
1259 
1260 list<OutputDataStreamPort *> ComposedNode::getSetOfOutputDataStreamPort() const
1261 {
1262  list<Node *> constituents=edGetDirectDescendants();
1263  list<OutputDataStreamPort *> ret;
1264  for(list<Node *>::iterator iter=constituents.begin();iter!=constituents.end();iter++)
1265  {
1266  list<OutputDataStreamPort *> currentsPorts=(*iter)->getSetOfOutputDataStreamPort();
1267  ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end());
1268  }
1269  return ret;
1270 }
1271 
1272 OutPort *ComposedNode::getOutPort(const std::string& name) const throw(YACS::Exception)
1273 {
1274  string portName, nodeName;
1275  if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false))
1276  {
1277  Node *child = getChildByShortName(nodeName);
1278  return child->getOutPort(portName);
1279  }
1280  else
1281  {
1282  string what("ComposedNode::getOutPort : the port with name "); what+=name; what+=" does not exist on the current level";
1283  throw Exception(what);
1284  }
1285 }
1286 
1288 
1293 InputPort * ComposedNode::getInputPort(const std::string& name) const throw(YACS::Exception)
1294 {
1295  try {
1296  return Node::getInputPort(name);
1297  }
1298  catch(Exception& e) {}
1299 
1300  string portName, nodeName;
1301  if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true))
1302  {
1303  Node *child = getChildByName(nodeName);
1304  return child->getInputPort(portName);
1305  }
1306  else
1307  {
1308  string what("ComposedNode::getInputPort : the port with name "); what+=name; what+=" does not exist on the current level";
1309  throw Exception(what);
1310  }
1311 }
1312 
1314 
1318 OutputPort * ComposedNode::getOutputPort(const std::string& name) const throw(YACS::Exception)
1319 {
1320  string portName, nodeName;
1321  if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false))
1322  {
1323  Node *child = getChildByShortName(nodeName);
1324  return child->getOutputPort(portName);
1325  }
1326  else
1327  {
1328  string what("ComposedNode::getOutputPort : the port with name "); what+=name; what+=" does not exist on the current level";
1329  throw Exception(what);
1330  }
1331 }
1332 
1334 {
1335  string portName, nodeName;
1336  if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true))
1337  {
1338  Node *child = getChildByName(nodeName);
1339  return child->getInputDataStreamPort(portName);
1340  }
1341  else
1342  {
1343  string what("ComposedNode::getInputDataStreamPort : the port with name "); what+=name; what+=" does not exist on the current level";
1344  throw Exception(what);
1345  }
1346 }
1347 
1349 {
1350  string portName, nodeName;
1351  if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true))
1352  {
1353  Node *child = getChildByName(nodeName);
1354  return child->getOutputDataStreamPort(portName);
1355  }
1356  else
1357  {
1358  string what("ComposedNode::getOutputDataStreamPort : the port with name "); what+=name; what+=" does not exist on the current level";
1359  throw Exception(what);
1360  }
1361 }
1362 
1364 
1378 YACS::Event ComposedNode::updateStateFrom(Node *node, //* I : node emitting event
1379  YACS::Event event, //* I : event emitted
1380  const Executor *execInst
1381  )
1382 {
1383  DEBTRACE("updateStateFrom: " << node->getName() << " " << event);
1384  try
1385  {
1386  switch(event)
1387  {
1388  case YACS::START:
1389  return updateStateOnStartEventFrom(node);
1390  break;
1391  case YACS::FINISH:
1392  return updateStateOnFinishedEventFrom(node);
1393  break;
1394  case YACS::ABORT:
1395  return updateStateOnFailedEventFrom(node,execInst);
1396  break;
1397  default:
1398  return YACS::NOEVENT;//TODO unexpected type of event
1399  break;
1400  }
1401  }
1402  catch(YACS::Exception& ex)
1403  {
1404  //unexpected exception: probably a bug in engine
1405  //try to keep a consistent global state
1406  DEBTRACE( "updateStateFrom: " << ex.what() );
1407  _errorDetails="Internal error: ";
1408  _errorDetails=_errorDetails + ex.what();
1410  exForwardFailed();
1411  return YACS::ABORT;
1412  }
1413  catch(...)
1414  {
1415  //unexpected exception: probably a bug in engine
1416  //try to keep a consistent global state
1418  exForwardFailed();
1419  return YACS::ABORT;
1420  }
1421 }
1422 
1424 
1431 {
1433  return YACS::START;
1434 }
1435 
1438 {
1440  return YACS::ABORT;
1441 }
1442 
1443 void ComposedNode::checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
1444  InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd) throw(YACS::Exception)
1445 {
1446  if((dynamic_cast<DataFlowPort *>(start) || dynamic_cast<DataFlowPort *>(end))
1447  && (dynamic_cast<DataStreamPort *>(start) || dynamic_cast<DataStreamPort *>(end)))
1448  {//cross protocol required : deeper check needed
1449  bool isOK=false;
1450  list<ComposedNode *>::const_iterator iter;
1451  for(iter=pointsOfViewStart.begin();iter!=pointsOfViewStart.end() && !isOK;iter++)
1452  isOK=(*iter)->isRepeatedUnpredictablySeveralTimes();
1453  for(iter=pointsOfViewEnd.begin();iter!=pointsOfViewEnd.end() && !isOK;iter++)
1454  isOK=(*iter)->isRepeatedUnpredictablySeveralTimes();
1455  if(!isOK)
1456  throw Exception("ComposedNode::checkLinkPossibility : Request for cross protocol link impossible.");
1457  }
1458 }
1459 
1460 void ComposedNode::buildDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView)
1461 {
1462 }
1463 
1464 void ComposedNode::buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
1465 {
1466 }
1467 
1468 void ComposedNode::getDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView) throw(YACS::Exception)
1469 {
1470 }
1471 
1472 void ComposedNode::getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(YACS::Exception)
1473 {
1474 }
1475 
1476 void ComposedNode::releaseDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView) throw(YACS::Exception)
1477 {
1478 }
1479 
1480 void ComposedNode::releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(YACS::Exception)
1481 {
1482 }
1483 
1485 {
1486 }
1488 {
1489 }
1490 
1492 {
1493  list<Node *> constituents=edGetDirectDescendants();
1494  for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
1495  {
1496  (*iter)->accept(visitor);
1497  }
1498 }
1499 
1501 std::list<InputPort *> ComposedNode::getLocalInputPorts() const
1502 {
1503  std::list<InputPort *> lip; return lip; // empty list
1504 }
1505 
1507 std::list<OutputPort *> ComposedNode::getLocalOutputPorts() const
1508 {
1509  std::list<OutputPort *> lop; return lop; // empty list
1510 }
1511 
1512 bool ComposedNode::isNameAlreadyUsed(const std::string& name) const
1513 {
1514  return false;
1515 }
1516 
1518 {
1519  DEBTRACE("ComposedNode::edUpdateState(): " << _state << " " << _modified);
1521 
1522  try
1523  {
1525  _errorDetails="";
1526  }
1527  catch(Exception& e)
1528  {
1529  state=YACS::INVALID;
1530  _errorDetails=e.what();
1531  }
1532  DEBTRACE("ComposedNode::edUpdateState: " << _errorDetails);
1533 
1534  //update children if needed
1535  list<Node *> constituents=edGetDirectDescendants();
1536  for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
1537  {
1538  if(!(*iter)->isValid())
1539  state=YACS::INVALID;
1540  }
1541  if(state != _state)
1542  setState(state);
1543  _modified=0;
1544 }
1545 
1547 {
1548  DEBTRACE("ComposedNode::getErrorReport: " << getName() << " " << _state);
1549  YACS::StatesForNode effectiveState=getEffectiveState();
1550 
1551  if(effectiveState != YACS::INVALID && effectiveState != YACS::ERROR && effectiveState != YACS::FAILED)
1552  return "";
1553 
1554  std::string report="<error node= " + getName();
1555  switch(effectiveState)
1556  {
1557  case YACS::INVALID:
1558  report=report+" state= INVALID";
1559  break;
1560  case YACS::ERROR:
1561  report=report+" state= ERROR";
1562  break;
1563  case YACS::FAILED:
1564  report=report+" state= FAILED";
1565  break;
1566  default:
1567  break;
1568  }
1569  report=report + ">\n" ;
1570  if(_errorDetails != "")
1571  report=report+_errorDetails+"\n";
1572 
1573  list<Node *> constituents=edGetDirectDescendants();
1574  for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
1575  {
1576  std::string rep=(*iter)->getErrorReport();
1577  if(rep != "")
1578  {
1579  report=report+rep+"\n";
1580  }
1581  }
1582  report=report+"</error>";
1583  return report;
1584 }
1585 
1586 
1587 
1589 {
1590  DEBTRACE("ComposedNode::checkBasicConsistency");
1591  std::list<InputPort *>::const_iterator iter;
1592  std::list<InputPort *> inports=getLocalInputPorts();
1593  for(iter=inports.begin();iter!=inports.end();iter++)
1594  (*iter)->checkBasicConsistency();
1595 }
1596 
1598 
1601 void ComposedNode::shutdown(int level)
1602 {
1603  if(level==0)return;
1604  DEBTRACE("ComposedNode::shutdown");
1605  list<Node *> nodes=edGetDirectDescendants();
1606  for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
1607  (*iter)->shutdown(level);
1608 }
1609 
1611 
1615 {
1616  DEBTRACE("ComposedNode::cleanNodes");
1617  list<Node *> nodes=edGetDirectDescendants();
1618  for(list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
1619  (*iter)->cleanNodes();
1620 }
1621 
1624 {
1625  if(level==0)return;
1626 
1627  DEBTRACE("ComposedNode::resetState " << level << "," << _state);
1629  {
1630  Node::resetState(level);
1631  std::list<Node *> nodes=edGetDirectDescendants();
1632  for(std::list<Node *>::iterator iter=nodes.begin();iter!=nodes.end();iter++)
1633  (*iter)->resetState(level);
1634  }
1635 }