]> SALOME platform Git repositories - modules/yacs.git/blob - src/hmi/guiObservers.cxx
Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / hmi / guiObservers.cxx
1
2 #include <Python.h>
3 #include "guiObservers.hxx"
4 #include "commandsProc.hxx"
5 #include "Node.hxx"
6 #include "ComposedNode.hxx"
7 #include "Bloc.hxx"
8 #include "Proc.hxx"
9 #include "ElementaryNode.hxx"
10 #include "InlineNode.hxx"
11 #include "ServiceNode.hxx"
12 #include "PythonNode.hxx"
13 #include "CORBANode.hxx"
14 #include "CppNode.hxx"
15 #include "XMLNode.hxx"
16 #include "SalomePythonNode.hxx"
17 #include "DataNode.hxx"
18 #include "PresetNode.hxx"
19 #include "OutNode.hxx"
20 #include "StudyNodes.hxx"
21 #include "ForLoop.hxx"
22 #include "ForEachLoop.hxx"
23 #include "WhileLoop.hxx"
24 #include "Switch.hxx"
25 #include "OptimizerLoop.hxx"
26 #include "InputPort.hxx"
27 #include "OutputPort.hxx"
28 #include "InputDataStreamPort.hxx"
29 #include "OutputDataStreamPort.hxx"
30 #include "SalomeContainer.hxx"
31 #include "SalomeComponent.hxx"
32 #include "ComponentDefinition.hxx"
33 #include "TypeCode.hxx"
34
35 #include "guiContext.hxx"
36
37 #include <string>
38 #include <sstream>
39 #include <vector>
40
41 //#define _DEVDEBUG_
42 #include "YacsTrace.hxx"
43
44 using namespace std;
45
46 using namespace YACS;
47 using namespace YACS::HMI;
48 using namespace YACS::ENGINE;
49
50 // ----------------------------------------------------------------------------
51
52 void Subject::erase(Subject* sub)
53 {
54   sub->clean();
55   delete sub;
56 }
57
58 // ----------------------------------------------------------------------------
59
60 Subject::Subject(Subject *parent) : _parent(parent)
61 {
62   _destructible = true;
63 }
64
65 /*!
66  *  Destructor must only be called by Subject::erase to clean
67  *  completely the context (detach observers), before the delete
68  *  process itself. Some actions involving dynamic_cast can't be done
69  *  in destructor.
70  */
71 Subject::~Subject()
72 {
73   DEBTRACE("Subject::~Subject " << this << " "<< getName());
74 }
75
76 /*!
77  * Clean process prior to delete is redefined in derived classes: a local clean
78  * treatment relative to the derived class, then a call to the parent class clean
79  * method.
80  */
81 void Subject::clean()
82 {
83   localClean();
84 }
85
86 /*!
87  *  the local clean method of base class of subjects take care of Observers.
88  *  Remaining Observers in the list are detached, if an abserver has no more
89  *  Subject to observe, it can be deleted.
90  */
91 void Subject::localClean()
92 {
93   DEBTRACE("Subject::localClean ");
94   set<GuiObserver*>::iterator it;
95   set<GuiObserver*> copySet = _setObs;
96   for (it = copySet.begin(); it != copySet.end(); ++it)
97   {
98     GuiObserver* anObs = (*it);
99     detach(anObs);
100     int nbsub = anObs->getNbSubjects();
101     DEBTRACE("nbSubjects=" << nbsub);
102     if (nbsub <= 0) delete anObs ;
103   }
104   _setObs.clear();
105 }
106
107 void Subject::attach(GuiObserver *obs)
108 {
109   _setObs.insert(obs);
110   obs->incrementSubjects(this);
111 }
112
113 void Subject::detach(GuiObserver *obs)
114 {
115   DEBTRACE("Subject::detach " << obs);
116   obs->decrementSubjects(this);
117   _setObs.erase(obs);
118 }
119
120 std::string Subject::getName()
121 {
122   return "generic";
123 }
124
125 bool Subject::setName(std::string name)
126 {
127   return false;
128 }
129
130 void Subject::select(bool isSelected)
131 {
132   DEBTRACE("Subject::select " << isSelected << " " << this);
133   for (set<GuiObserver *>::iterator it = _setObs.begin(); it != _setObs.end(); ++it)
134     {
135       GuiObserver* currOb = *it;
136       currOb->select(isSelected);
137     }
138 }
139
140 void Subject::update(GuiEvent event,int type, Subject* son)
141 {
142   DEBTRACE("Subject::update " << type << "," << event << "," << son);
143   for (set<GuiObserver *>::iterator it = _setObs.begin(); it != _setObs.end(); ++it)
144     {
145       DEBTRACE("Subject::update " << *it);
146       (*it)->update(event, type, son);
147     }
148 }
149
150 Subject* Subject::getParent()
151 {
152   return _parent;
153 }
154
155 bool Subject::destroy(Subject *son)
156 {
157   string toDestroy = son->getName();
158   DEBTRACE("Subject::destroy " << toDestroy);
159   Proc *proc = GuiContext::getCurrent()->getProc();
160   string position = "";
161
162   if (dynamic_cast<SubjectProc*>(son))
163     position = proc->getName();
164   else
165     {
166       if (SubjectNode *subNode = dynamic_cast<SubjectNode*>(son))
167         {
168           if (subNode->getNode()->getFather() )
169             position = proc->getChildName(subNode->getNode());
170         }
171       else if (dynamic_cast<SubjectDataPort*>(son))
172         {
173           SubjectNode *subNodep = dynamic_cast<SubjectNode*>(son->getParent());
174           if (dynamic_cast<SubjectProc*>(subNodep))
175             position = proc->getName();
176           else
177             position = proc->getChildName(subNodep->getNode());
178         }
179       else if (dynamic_cast<SubjectLink*>(son))
180         {
181           SubjectNode *subNodep = dynamic_cast<SubjectNode*>(son->getParent());
182           if (dynamic_cast<SubjectProc*>(subNodep))
183             position = proc->getName();
184           else
185             position = proc->getChildName(subNodep->getNode());
186         }
187     }
188   if (son->isDestructible())
189     {
190       CommandDestroy* command = new CommandDestroy(position, son);
191       if (command->execute())
192         {
193           DEBTRACE("Destruction done: " << toDestroy);
194           return true;
195         }
196       else delete command;
197     }
198   return false;
199 }
200
201 void Subject::loadChildren()
202 {
203 }
204
205 void Subject::loadLinks()
206 {
207 }
208
209 void Subject::addSubjectReference(Subject *ref)
210 {
211   DEBTRACE("Subject::addSubjectReference " << getName() << " " << ref->getName());
212   SubjectReference *son = new SubjectReference(ref, this);
213   update(ADDREF, 0, son);
214 }
215
216 // ----------------------------------------------------------------------------
217
218 GuiObserver::GuiObserver()
219 {
220   DEBTRACE("GuiObserver::GuiObserver " << this);
221   _subjectSet.clear();
222 }
223
224 GuiObserver::~GuiObserver()
225 {
226   DEBTRACE("GuiObserver::~GuiObserver " << this);
227 }
228
229 void GuiObserver::select(bool isSelected)
230 {
231   DEBTRACE("GuiObserver::select() " << isSelected);
232 }
233
234 void GuiObserver::update(GuiEvent event, int type,  Subject* son)
235 {
236   DEBTRACE("GuiObserver::update, event not handled " << event << " " << type );
237 }
238
239 /*!
240  * only called by subject when attach to subject.
241  * @see Subject::attach
242  */
243 void GuiObserver::incrementSubjects(Subject *subject)
244 {
245   if (_subjectSet.count(subject))
246     DEBTRACE("subject " << subject << " is already a subject of observer " << this << "---------------------------");
247   _subjectSet.insert(subject);
248   //DEBTRACE(this << " " << _subjectSet.size());
249 }
250
251 /*!
252  * only called by subject when detach from subject.
253  * @see Subject::detach
254  */
255 void GuiObserver::decrementSubjects(Subject *subject)
256 {
257   if (_subjectSet.count(subject))
258     _subjectSet.erase(subject);
259   else
260     DEBTRACE("subject " << subject << " is not a subject of observer " << this << "---------------------------");
261   //DEBTRACE(this << " " << _subjectSet.size());
262 }
263
264 /*! 
265  * Gets the number of subjects observed.
266  * used by subject. When the subject is erased (Subject::erase),
267  * remaining observers are detached from subjects. If an observer has no
268  * more subject, it can be deleted.
269  * @see Subject::erase Subject::localClean
270  */
271 int GuiObserver::getNbSubjects()
272 {
273   return _subjectSet.size();
274 }
275
276 // ----------------------------------------------------------------------------
277
278 SubjectReference::SubjectReference(Subject* ref, Subject *parent)
279   : Subject(parent), _reference(ref)
280 {
281 }
282
283 SubjectReference::~SubjectReference()
284 {
285 }
286
287 void SubjectReference::clean()
288 {
289   localClean();
290   Subject::clean();
291 }
292
293 void SubjectReference::localClean()
294 {
295   DEBTRACE("SubjectReference::localClean ");
296 }
297
298 std::string SubjectReference::getName()
299 {
300   std::stringstream name;
301   name << "ref-->" << _reference->getName();
302   return name.str();
303 }
304
305 Subject* SubjectReference::getReference() const
306 {
307   return _reference;
308 }
309
310 // ----------------------------------------------------------------------------
311
312 SubjectNode::SubjectNode(YACS::ENGINE::Node *node, Subject *parent)
313   : Subject(parent), _node(node)
314 {
315   _listSubjectInputPort.clear();
316   _listSubjectOutputPort.clear();
317   _listSubjectIDSPort.clear();
318   _listSubjectODSPort.clear();
319   _listSubjectLink.clear();
320   _listSubjectControlLink.clear();
321   Dispatcher* d=Dispatcher::getDispatcher();
322   d->addObserver(this,node,"status");
323 }
324
325 /*!
326  * all destruction is done in generic class SubjectNode
327  */
328 SubjectNode::~SubjectNode()
329 {
330   DEBTRACE("SubjectNode::~SubjectNode " << getName());
331   Dispatcher::getDispatcher()->removeObserver(this,_node,"status");
332
333   ComposedNode* father = _node->getFather();
334   if (father)
335     try
336       {
337         Bloc *bloc = dynamic_cast<Bloc*>(father);
338         if (bloc) bloc->edRemoveChild(_node);
339         else
340           {
341             Loop *loop = dynamic_cast<Loop*>(father);
342             if (loop) loop->edRemoveChild(_node);
343             else
344               {
345                 ForEachLoop *feloop = dynamic_cast<ForEachLoop*>(father);
346                 if (feloop && getName() != ForEachLoop::NAME_OF_SPLITTERNODE) {
347                   DEBTRACE("SubjectNode::localClean: remove for each loop body");
348                   feloop->edRemoveChild(_node);
349                 }
350                 else
351                   {
352                     Switch *aSwitch = dynamic_cast<Switch*>(father);
353                     if (aSwitch) aSwitch->edRemoveChild(_node);
354                   }
355               }
356           }
357       }
358     catch (YACS::Exception &e)
359       {
360         DEBTRACE("------------------------------------------------------------------------------");
361         DEBTRACE("SubjectNode::localClean: father->edRemoveChild: YACS exception " << e.what());
362         DEBTRACE("------------------------------------------------------------------------------");
363       }
364 }
365
366 void SubjectNode::clean()
367 {
368   localClean();
369   Subject::clean();
370 }
371
372 void SubjectNode::localClean()
373 {
374   DEBTRACE("SubjectNode::localClean ");
375   removeExternalLinks();
376   {
377     list<SubjectLink*>::iterator its;
378     list<SubjectLink*> cpll = _listSubjectLink;
379     for (its = cpll.begin(); its != cpll.end(); ++its)
380       erase(*its);
381   }
382   {
383     list<SubjectControlLink*>::iterator its;
384     list<SubjectControlLink*> cplcl = _listSubjectControlLink;
385     for (its = cplcl.begin(); its != cplcl.end(); ++its)
386       erase(*its);
387   }
388   {
389     list<SubjectInputPort*>::iterator iti;
390     list<SubjectInputPort*> cpli = _listSubjectInputPort;
391     for(iti = cpli.begin(); iti != cpli.end(); ++iti)
392       erase(*iti);
393   }
394   {
395     list<SubjectOutputPort*>::iterator ito;
396     list<SubjectOutputPort*> cplo = _listSubjectOutputPort;
397     for(ito = cplo.begin(); ito != cplo.end(); ++ito)
398       erase(*ito);
399   }
400   {
401     list<SubjectInputDataStreamPort*>::iterator itid;
402     list<SubjectInputDataStreamPort*> cplid = _listSubjectIDSPort;
403     for(itid = cplid.begin(); itid != cplid.end(); ++itid)
404       erase(*itid);
405   }
406   {
407     list<SubjectOutputDataStreamPort*>::iterator itod;
408     list<SubjectOutputDataStreamPort*> cplod = _listSubjectODSPort;
409     for(itod = cplod.begin(); itod != cplod.end(); ++itod)
410       erase(*itod);
411   }
412   if (_parent)
413     {
414       if( SubjectBloc* sb = dynamic_cast<SubjectBloc*>(_parent) )
415         sb->removeNode(this);
416       else if( SubjectForLoop* sfl = dynamic_cast<SubjectForLoop*>(_parent) )
417         sfl->completeChildrenSubjectList( 0 );
418       else if( SubjectWhileLoop* swl = dynamic_cast<SubjectWhileLoop*>(_parent) )
419         swl->completeChildrenSubjectList( 0 );
420       else if( SubjectForEachLoop* sfel = dynamic_cast<SubjectForEachLoop*>(_parent) )
421         sfel->completeChildrenSubjectList( 0 );
422     }
423 }
424
425 void SubjectNode::reparent(Subject* parent)
426 {
427   // remove this node from children list of an old parent
428   if (_parent)
429   {
430     if( SubjectBloc* sb = dynamic_cast<SubjectBloc*>(_parent) )
431       sb->removeNode(this);
432   }
433
434   // reparent
435   _parent = parent;
436   
437   // add this node into the children list of a new parent
438   if (_parent)
439   {
440     if( SubjectBloc* sb = dynamic_cast<SubjectBloc*>(_parent) )
441       sb->completeChildrenSubjectList(this);
442     else if( SubjectSwitch* ss = dynamic_cast<SubjectSwitch*>(_parent) )
443       ss->completeChildrenSubjectList(this);
444   }  
445 }
446
447 std::string SubjectNode::getName()
448 {
449   return _node->getName();
450 }
451
452 YACS::ENGINE::Node* SubjectNode::getNode()
453 {
454   return _node;
455 }
456
457 bool SubjectNode::setName(std::string name)
458 {
459   DEBTRACE("SubjectNode::setName " << name);
460   Proc *proc = GuiContext::getCurrent()->getProc();
461   string position = "";
462   if (proc != dynamic_cast<Proc*>(_node))
463     position = proc->getChildName(_node);
464   else
465     position = _node->getName();
466   CommandRenameNode* command = new CommandRenameNode(position, name);
467   if (command->execute())
468     {
469       GuiContext::getCurrent()->getInvoc()->add(command);
470       update(RENAME, 0, this);
471       return true;
472     }
473   else delete command;
474   return false;
475 }
476 void SubjectNode::notifyObserver(Node* object,const std::string& event)
477 {
478   DEBTRACE("SubjectNode::notifyObserver " << object->getName() << " " << event);
479   TypeOfElem ntyp = ProcInvoc::getTypeOfNode(object);
480   update(UPDATE, ntyp , 0 );
481 }
482
483 SubjectInputPort* SubjectNode::addSubjectInputPort(YACS::ENGINE::InputPort *port,
484                                                    std::string name)
485 {
486   string theName = name;
487   if (name.empty()) theName =port->getName();
488   DEBTRACE("SubjectNode::addSubjectInputPort "<< theName);
489   SubjectInputPort *son = new SubjectInputPort(port, this);
490   GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
491   _listSubjectInputPort.push_back(son);
492   if (!name.empty()) son->setName(name);
493   update(ADD, INPUTPORT ,son);
494   YACS::ENGINE::TypeCode *typcod = port->edGetType();
495   GuiContext::getCurrent()->getSubjectProc()->addSubjectDataType(typcod);
496   return son;
497 }
498
499 void SubjectNode::update( GuiEvent event, int type, Subject* son )
500 {
501   Subject::update( event, type, son );
502   
503   // remove subject data type if necessary
504   YACS::HMI::SubjectDataPort* aSPort = dynamic_cast< YACS::HMI::SubjectDataPort* >( son );
505   if ( aSPort && event == REMOVE )
506   {
507     YACS::ENGINE::DataPort* aEPort = aSPort->getPort();
508     if ( aEPort )
509     {
510       YACS::ENGINE::TypeCode* aTypeCode = aEPort->edGetType();
511       if ( aTypeCode )
512         GuiContext::getCurrent()->getSubjectProc()->removeSubjectDataType( aTypeCode );
513     }
514   }
515 }
516
517 SubjectOutputPort* SubjectNode::addSubjectOutputPort(YACS::ENGINE::OutputPort *port,
518                                                      std::string name)
519 {
520   string theName = name;
521   if (name.empty()) theName =port->getName();
522   DEBTRACE("SubjectNode::addSubjectOutputPort "<< theName);
523   SubjectOutputPort *son = new SubjectOutputPort(port, this);
524   GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
525   _listSubjectOutputPort.push_back(son);
526   if (!name.empty()) son->setName(name);
527   update(ADD, OUTPUTPORT ,son);
528   YACS::ENGINE::TypeCode *typcod = port->edGetType();
529   GuiContext::getCurrent()->getSubjectProc()->addSubjectDataType(typcod);
530   return son;
531 }
532
533 SubjectInputDataStreamPort* SubjectNode::addSubjectIDSPort(YACS::ENGINE::InputDataStreamPort *port,
534                                                            std::string name)
535 {
536   string theName = name;
537   if (name.empty()) theName =port->getName();
538   DEBTRACE("SubjectNode::addSubjectIDSPort "<< theName);
539   SubjectInputDataStreamPort *son = new SubjectInputDataStreamPort(port, this);
540   GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
541   _listSubjectIDSPort.push_back(son);
542   if (!name.empty()) son->setName(name);
543   update(ADD, INPUTDATASTREAMPORT ,son);
544   YACS::ENGINE::TypeCode *typcod = port->edGetType();
545   GuiContext::getCurrent()->getSubjectProc()->addSubjectDataType(typcod);
546   return son;
547 }
548
549
550 SubjectOutputDataStreamPort* SubjectNode::addSubjectODSPort(YACS::ENGINE::OutputDataStreamPort *port,
551                                                             std::string name)
552 {
553   string theName = name;
554   if (name.empty()) theName =port->getName();
555   DEBTRACE("SubjectNode::addSubjectODSPort "<< theName);
556   SubjectOutputDataStreamPort *son = new SubjectOutputDataStreamPort(port, this);
557   GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
558   _listSubjectODSPort.push_back(son);
559   if (!name.empty()) son->setName(name);
560   update(ADD, OUTPUTDATASTREAMPORT ,son);
561   YACS::ENGINE::TypeCode *typcod = port->edGetType();
562   GuiContext::getCurrent()->getSubjectProc()->addSubjectDataType(typcod);
563   return son;
564 }
565
566 bool SubjectNode::tryCreateLink(SubjectNode *subOutNode, SubjectNode *subInNode)
567 {
568   DEBTRACE("SubjectNode::tryCreateLink " << subOutNode->getName() << " " << subInNode->getName());
569   Proc *proc = GuiContext::getCurrent()->getProc();
570   Node *outNode = subOutNode->getNode();
571   string outNodePos = proc->getChildName(outNode);
572   Node *inNode = subInNode->getNode();
573   string inNodePos = proc->getChildName(inNode);
574   CommandAddControlLink *command = new CommandAddControlLink(outNodePos, inNodePos);
575   if (command->execute())
576     {
577       GuiContext::getCurrent()->getInvoc()->add(command);
578       ComposedNode *cla = ComposedNode::getLowestCommonAncestor(outNode->getFather(),
579                                                                 inNode->getFather());
580       SubjectComposedNode *scla = dynamic_cast<SubjectComposedNode*>(subOutNode->getParent());
581       ComposedNode *ancestor = outNode->getFather();
582       while (ancestor && ancestor != cla)
583         {
584           ancestor = ancestor->getFather();
585           scla = dynamic_cast<SubjectComposedNode*>(scla->getParent());
586           assert(scla);
587         }
588       DEBTRACE(scla->getName());
589       scla->addSubjectControlLink(subOutNode,subInNode);
590       return true;
591     }
592   else
593     {
594       delete command;
595       return false;
596     }
597 }
598
599 void SubjectNode::removeExternalLinks()
600 {
601   DEBTRACE("SubjectNode::removeExternalLinks " << getName());
602   std::vector< std::pair<OutPort *, InPort *> > listLeaving  = getNode()->getSetOfLinksLeavingCurrentScope();
603   std::vector< std::pair<InPort *, OutPort *> > listIncoming = getNode()->getSetOfLinksComingInCurrentScope();
604   std::vector< std::pair<OutPort *, InPort *> > globalList = listLeaving;
605   std::vector< std::pair<InPort *, OutPort *> >::iterator it1;
606   for (it1 = listIncoming.begin(); it1 != listIncoming.end(); ++it1)
607     {
608       std::pair<OutPort *, InPort *> outin = std::pair<OutPort *, InPort *>((*it1).second, (*it1).first);
609       globalList.push_back(outin);
610     }
611   std::vector< std::pair<OutPort *, InPort *> >::iterator it2;
612   for (it2 = globalList.begin(); it2 != globalList.end(); ++it2)
613     {
614       SubjectLink* subject = 0;
615       if (GuiContext::getCurrent()->_mapOfSubjectLink.count(*it2))
616         {
617           subject = GuiContext::getCurrent()->_mapOfSubjectLink[*it2];
618           assert(subject);
619           DEBTRACE("link to remove " << subject->getName());
620           erase(subject);
621           GuiContext::getCurrent()->_mapOfSubjectLink.erase(*it2);
622         }
623       else
624         {
625           DEBTRACE("------------------------------------------------------------------------------");
626           DEBTRACE("SubjectNode::removeExternalLinks(): an external link not in map...");
627           DEBTRACE("------------------------------------------------------------------------------");
628         }
629     } 
630       
631 }
632
633 // ----------------------------------------------------------------------------
634
635 SubjectComposedNode::SubjectComposedNode(YACS::ENGINE::ComposedNode *composedNode,
636                                          Subject *parent)
637   : SubjectNode(composedNode, parent), _composedNode(composedNode)
638 {
639 }
640
641 /*!
642  * all generic destruction is done in generic class SubjectNode
643  */
644 SubjectComposedNode::~SubjectComposedNode()
645 {
646   DEBTRACE("SubjectComposedNode::~SubjectComposedNode " << getName());
647 }
648
649 void SubjectComposedNode::clean()
650 {
651   localClean();
652   SubjectNode::clean();
653 }
654
655 void SubjectComposedNode::localClean()
656 {
657   DEBTRACE("SubjectComposedNode::localClean ");
658 }
659
660 SubjectNode* SubjectComposedNode::addNode(YACS::ENGINE::Catalog *catalog,
661                                           std::string compo,
662                                           std::string type,
663                                           std::string name)
664 {
665   DEBTRACE("SubjectComposedNode::addNode("<<catalog<<","<<compo<<","<<type<<","<<name<<")");
666   SubjectNode* body = 0;
667   return body;
668 }
669
670 SubjectNode *SubjectComposedNode::createNode(YACS::ENGINE::Catalog *catalog,
671                                              std::string compo,
672                                              std::string type,
673                                              std::string name,
674                                              int swCase)
675 {
676   Proc *proc = GuiContext::getCurrent()->getProc();
677   string position = "";
678   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
679   CommandAddNodeFromCatalog *command = new CommandAddNodeFromCatalog(catalog,
680                                                                      compo,
681                                                                      type,
682                                                                      position,
683                                                                      name,
684                                                                      swCase);
685   if (command->execute())
686     {
687       GuiContext::getCurrent()->getInvoc()->add(command);
688       Node * node = command->getNode();
689       SubjectNode *son = addSubjectNode(node,"",catalog,compo,type);
690       son->loadChildren();
691       son->loadLinks();
692       return son;
693     }
694   else delete command;
695   return 0;
696 }
697
698 SubjectNode *SubjectComposedNode::addSubjectNode(YACS::ENGINE::Node * node,
699                                                  std::string name,
700                                                  YACS::ENGINE::Catalog *catalog,
701                                                  std::string compo,
702                                                  std::string type)
703 {
704   string theName = name;
705   if (name.empty()) theName =node->getName();
706   DEBTRACE("SubjectComposedNode::addSubjectNode "<< theName);
707   TypeOfElem ntyp = ProcInvoc::getTypeOfNode(node);
708   DEBTRACE("TypeOfNode: " << ntyp);
709   SubjectNode *son = 0;
710   switch(ntyp)
711     {
712     case BLOC:
713       son = new SubjectBloc(dynamic_cast<YACS::ENGINE::Bloc*>(node), this);
714       break;
715     case PYTHONNODE:
716       son = new SubjectPythonNode(dynamic_cast<YACS::ENGINE::PythonNode*>(node), this);
717       break;
718     case PYFUNCNODE:
719       son = new SubjectPyFuncNode(dynamic_cast<YACS::ENGINE::PyFuncNode*>(node), this);
720       break;
721     case CORBANODE:
722       son = new SubjectCORBANode(dynamic_cast<YACS::ENGINE::CORBANode*>(node), this);
723       break;
724     case CPPNODE:
725       son = new SubjectCppNode(dynamic_cast<YACS::ENGINE::CppNode*>(node), this);
726       break;
727     case SALOMENODE:
728       son = new SubjectSalomeNode(dynamic_cast<YACS::ENGINE::SalomeNode*>(node), this);
729       break;
730     case SALOMEPYTHONNODE:
731       son = new SubjectSalomePythonNode(dynamic_cast<YACS::ENGINE::SalomePythonNode*>(node), this);
732       break;
733     case XMLNODE:
734       son = new SubjectXmlNode(dynamic_cast<YACS::ENGINE::XmlNode*>(node), this);
735       break;
736     case SPLITTERNODE:
737       son = new SubjectSplitterNode(dynamic_cast<YACS::ENGINE::SplitterNode*>(node), this);
738       break;
739     case PRESETNODE:
740       son = new SubjectPresetNode(dynamic_cast<YACS::ENGINE::PresetNode*>(node), this);
741       break;
742     case OUTNODE:
743       son = new SubjectOutNode(dynamic_cast<YACS::ENGINE::OutNode*>(node), this);
744       break;
745     case STUDYINNODE:
746       son = new SubjectStudyInNode(dynamic_cast<YACS::ENGINE::StudyInNode*>(node), this);
747       break;
748     case STUDYOUTNODE:
749       son = new SubjectStudyOutNode(dynamic_cast<YACS::ENGINE::StudyOutNode*>(node), this);
750       break;
751     case FORLOOP:
752       son = new SubjectForLoop(dynamic_cast<YACS::ENGINE::ForLoop*>(node), this);
753       break;
754     case WHILELOOP:
755       son = new SubjectWhileLoop(dynamic_cast<YACS::ENGINE::WhileLoop*>(node), this);
756       break;
757     case SWITCH:
758       son = new SubjectSwitch(dynamic_cast<YACS::ENGINE::Switch*>(node), this);
759       break;
760     case FOREACHLOOP:
761       son = new SubjectForEachLoop(dynamic_cast<YACS::ENGINE::ForEachLoop*>(node), this);
762       break;
763     case OPTIMIZERLOOP:
764       son = new SubjectOptimizerLoop(dynamic_cast<YACS::ENGINE::OptimizerLoop*>(node), this);
765       break;
766     default:
767       throw YACS::Exception("Not implemented");
768       //assert(0);
769     }
770   assert(son);
771   GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(node)] = son;
772   if (!name.empty()) son->setName(name);
773   completeChildrenSubjectList(son);
774   update(ADD, ntyp ,son);
775   if (SubjectServiceNode *service = dynamic_cast<SubjectServiceNode*>(son))
776     if (catalog && !compo.empty() && !type.empty()) // --- clone from catalog: set component
777       service->setComponentFromCatalog(catalog,compo,type);
778     else
779       service->setComponent();
780   return son;
781 }
782
783 void SubjectComposedNode::completeChildrenSubjectList(SubjectNode *son)
784 {
785 }
786
787 void SubjectComposedNode::loadChildren()
788 {
789   list<Node *> setOfNode= _composedNode->edGetDirectDescendants();
790   if (ForEachLoop *feloop = dynamic_cast<ForEachLoop*>(_composedNode))
791     {
792       Node *node2Insert=feloop->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
793       if(find(setOfNode.begin(),setOfNode.end(),node2Insert)==setOfNode.end())
794         setOfNode.push_back(node2Insert);
795     }
796   for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
797     {
798       try
799         {
800           SubjectNode * son = addSubjectNode(*iter);
801           son->loadChildren();
802         }
803       catch(YACS::Exception& ex)
804         {
805           std::cerr << "Unknown type of node" << std::endl;
806         }
807     }
808   list<InputPort*>  listInputPorts  = _composedNode->getLocalInputPorts();
809   list<OutputPort*> listOutputPorts = _composedNode->getLocalOutputPorts();
810   list<InputDataStreamPort*>  listIDSPorts = _composedNode->getSetOfInputDataStreamPort();
811   list<OutputDataStreamPort*> listODSPorts = _composedNode->getSetOfOutputDataStreamPort();
812   list<InputPort*>::const_iterator iti;
813   for (iti = listInputPorts.begin(); iti != listInputPorts.end(); ++iti)
814     addSubjectInputPort(*iti);
815   list<OutputPort*>::const_iterator ito;
816   for (ito = listOutputPorts.begin(); ito != listOutputPorts.end(); ++ito)
817     addSubjectOutputPort(*ito);
818 }
819
820 SubjectLink* SubjectComposedNode::addSubjectLink(SubjectNode *sno,
821                                                  SubjectDataPort *spo,
822                                                  SubjectNode *sni,
823                                                  SubjectDataPort *spi)
824 {
825   DEBTRACE("SubjectComposedNode::addSubjectLink");
826   SubjectLink *son = new SubjectLink(sno, spo, sni, spi, this);
827   OutPort *outp = sno->getNode()->getOutPort(spo->getName());
828   InPort *inp = sni->getNode()->getInPort(spi->getName());
829   pair<OutPort*,InPort*> keyLink(outp,inp);
830   GuiContext::getCurrent()->_mapOfSubjectLink[keyLink] = son;
831   _listSubjectLink.push_back(son);
832   spo->addSubjectLink(son);
833   spi->addSubjectLink(son);
834   update(ADDLINK, DATALINK, son);
835   DEBTRACE("addSubjectLink: " << getName() << " " << son->getName());
836   return son;
837 }
838
839 void SubjectComposedNode::removeLink(SubjectLink* link)
840 {
841   DEBTRACE("removeSubjectLink: " << getName());
842   link->getSubjectOutPort()->removeSubjectLink(link);
843   link->getSubjectInPort()->removeSubjectLink(link);
844   _listSubjectLink.remove(link);
845 }
846
847 SubjectControlLink* SubjectComposedNode::addSubjectControlLink(SubjectNode *sno,
848                                                         SubjectNode *sni)
849 {
850   SubjectControlLink *son = new SubjectControlLink(sno, sni, this);
851   Node *outn = sno->getNode();
852   Node *inn = sni->getNode();
853   pair<Node*,Node*> keyLink(outn,inn);
854
855   GuiContext::getCurrent()->_mapOfSubjectControlLink[keyLink] = son;
856   _listSubjectControlLink.push_back(son);
857   sno->addSubjectControlLink(son);
858   sni->addSubjectControlLink(son);
859   update(ADDCONTROLLINK, CONTROLLINK, son);
860   DEBTRACE("addSubjectControlLink: " << getName() << " " << son->getName());
861   return son;
862 }
863
864 void SubjectComposedNode::removeControlLink(SubjectControlLink* link)
865 {
866   DEBTRACE("removeSubjectControlLink: " << getName());
867   link->getSubjectOutNode()->removeSubjectControlLink(link);
868   link->getSubjectInNode()->removeSubjectControlLink(link);
869   _listSubjectControlLink.remove(link);
870 }
871
872 /*!
873  * loadLinks is used when an existing scheme has been loaded in memory, to create gui representation.
874  * Gui representation of links is done after node representation (loadChildren).
875  * Proc is explored recursively to find the composedNodes and create the corresponding links
876  * representation, from bottom to top.
877  * For each composedNode, data links representation are created first and stored in a map to avoid
878  * double represention. Then control links representation are created.
879  */
880 void SubjectComposedNode::loadLinks()
881 {
882   list<Node *> setOfNode= _composedNode->edGetDirectDescendants();
883   for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
884     {
885       ComposedNode *cnSon = dynamic_cast<ComposedNode*>(*iter);
886       if (cnSon)
887         {
888           SubjectNode *subSon = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(*iter)];
889           assert(subSon);
890           SubjectComposedNode *subCnSon = dynamic_cast<SubjectComposedNode*>(subSon);
891           assert (subCnSon);
892           subCnSon->loadLinks();
893         }
894     }
895
896   std::vector<std::pair<OutPort*,InPort*> > setOfLinks = _composedNode->getSetOfInternalLinks();
897   std::vector<std::pair<OutPort*,InPort*> >::iterator itp;
898   for (itp = setOfLinks.begin(); itp != setOfLinks.end(); ++itp)
899     if (!GuiContext::getCurrent()->_mapOfSubjectLink.count(*itp))
900       {
901         OutPort *outp = (*itp).first;
902         InPort *inp = (*itp).second;
903         Node *outn = outp->getNode();
904         Node *inn = inp->getNode();
905         DEBTRACE(outn->getName()<<"."<<outp->getName()<<"->"<<inn->getName()<<"."<<inp->getName());
906         SubjectNode *sno = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(outn)];
907         SubjectNode *sni = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(inn)];
908         SubjectDataPort *spo = GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(outp)];
909         SubjectDataPort *spi = GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(inp)];
910         addSubjectLink(sno,spo,sni,spi);
911       }
912
913   std::list<Node*> setOfNodes = _composedNode->edGetDirectDescendants();
914   std::list<Node*>::const_iterator itn;
915   for(itn = setOfNodes.begin(); itn != setOfNodes.end(); ++itn)
916     {
917       SubjectNode* sno = GuiContext::getCurrent()->_mapOfSubjectNode[*itn];
918       OutGate* outgate = (*itn)->getOutGate();
919       std::set<InGate*> setIngate = outgate->edSetInGate();
920       std::set<InGate*>::const_iterator itg;
921       for(itg = setIngate.begin(); itg != setIngate.end(); ++itg)
922         {
923           Node* inNode = (*itg)->getNode();
924           SubjectNode* sni = GuiContext::getCurrent()->_mapOfSubjectNode[inNode];
925           addSubjectControlLink(sno,sni);
926         }
927     }
928 }
929
930 //! Retrieves the lowest common ancestor of 2 nodes
931 /*!
932  * 
933  * \note Retrieves the lowest common ancestor of 'node1' AND 'node2'. 
934  *       If  'node1' or 'node2' are both or indiscriminately instances of ComposedNode and that
935  *       'node1' is in descendance of 'node2' (resp. 'node2' in descendance of 'node1')
936  *       'node2' is returned (resp. 'node1').
937  * \exception Exception : if 'node1' and 'node2' do not share the same genealogy.
938  * \return The lowest common ancestor if it exists.
939  *
940  */
941 SubjectComposedNode* SubjectComposedNode::getLowestCommonAncestor(SubjectNode* snode1, SubjectNode* snode2)
942 {
943   Node* node1 = snode1->getNode();
944   Node* node2 = snode2->getNode();
945
946   ComposedNode *node = ComposedNode::getLowestCommonAncestor(node1->getFather(), node2->getFather());
947   SubjectComposedNode* snode = dynamic_cast<SubjectComposedNode*>( GuiContext::getCurrent()->_mapOfSubjectNode[node] );
948   return snode;
949 }
950
951 // ----------------------------------------------------------------------------
952
953 SubjectBloc::SubjectBloc(YACS::ENGINE::Bloc *bloc, Subject *parent)
954   : SubjectComposedNode(bloc, parent), _bloc(bloc)
955 {
956   _children.clear();
957 }
958
959 /*!
960  * all generic destruction is done in generic class SubjectNode
961  */
962 SubjectBloc::~SubjectBloc()
963 {
964   DEBTRACE("SubjectBloc::~SubjectBloc " << getName());
965 }
966
967 void SubjectBloc::clean()
968 {
969   localClean();
970   SubjectComposedNode::clean();
971 }
972
973 void SubjectBloc::localClean()
974 {
975   DEBTRACE("SubjectBloc::localClean ");
976   set<SubjectNode*>::iterator it;
977   set<SubjectNode*> copyChildren = _children;
978   for (it = copyChildren.begin(); it !=copyChildren.end(); ++it)
979     erase(*it);
980 }
981
982 SubjectNode* SubjectBloc::addNode(YACS::ENGINE::Catalog *catalog,
983                                   std::string compo,
984                                   std::string type,
985                                   std::string name)
986 {
987   DEBTRACE("SubjectBloc::addNode( " << catalog << ", " << compo << ", " << type << ", " << name << " )");
988   SubjectNode* child = createNode(catalog, compo, type, name);
989   return child;
990 }
991
992 void SubjectBloc::completeChildrenSubjectList(SubjectNode *son)
993 {
994   _children.insert(son);
995 }
996
997 void SubjectBloc::removeNode(SubjectNode* child)
998 {
999   _children.erase(child);
1000 }
1001
1002 SubjectNode* SubjectBloc::getChild(YACS::ENGINE::Node* node) const
1003 {
1004   SubjectNode* aChild = 0;
1005
1006   if (node)
1007   {
1008     set<SubjectNode*>::iterator it = _children.begin();
1009     for ( ; it != _children.end(); it++ )
1010       if ( (*it)->getNode() == node )
1011       {
1012         aChild = (*it);
1013         break;
1014       }
1015   }
1016
1017   return aChild;
1018 }
1019
1020 // ----------------------------------------------------------------------------
1021
1022 SubjectProc::SubjectProc(YACS::ENGINE::Proc *proc, Subject *parent)
1023   : SubjectBloc(proc, parent), _proc(proc)
1024 {
1025 }
1026
1027 SubjectProc::~SubjectProc()
1028 {
1029   DEBTRACE("SubjectProc::~SubjectProc " << getName());
1030 }
1031
1032 void SubjectProc::clean()
1033 {
1034   localClean();
1035   SubjectBloc::clean();
1036 }
1037
1038 void SubjectProc::localClean()
1039 {
1040   DEBTRACE("SubjectProc::localClean ");
1041 }
1042
1043 void SubjectProc::loadProc()
1044 {
1045   DEBTRACE("SubjectProc::loadProc "  << getName());
1046   loadChildren();
1047   loadLinks();
1048   loadComponents();
1049   loadContainers();
1050 }
1051
1052 /*!
1053  * loadComponents is used when an existing scheme has been loaded in memory,
1054  * to create subjects for components stored in the schema file, but are not
1055  * associated with any service nodes. Note, that if such component is associated
1056  * to any container, the subject for this container is also created, if it is not
1057  * exist yet.
1058  */
1059 void SubjectProc::loadComponents()
1060 {
1061   Proc* aProc = GuiContext::getCurrent()->getProc();
1062   for (map<pair<string,int>, ComponentInstance*>::const_iterator itComp = aProc->componentInstanceMap.begin();
1063        itComp != aProc->componentInstanceMap.end(); ++itComp)
1064     if ( GuiContext::getCurrent()->_mapOfSubjectComponent.find((*itComp).second)
1065          ==
1066          GuiContext::getCurrent()->_mapOfSubjectComponent.end() )
1067     { // engine object for component already exists => add only a subject for it
1068       addSubjectComponent((*itComp).second);
1069     }
1070 }
1071
1072 /*!
1073  * loadContainers is used when an existing scheme has been loaded in memory,
1074  * to create subjects for containers stored in the schema file, but are not
1075  * associated with components.
1076  */
1077 void SubjectProc::loadContainers()
1078 {
1079   Proc* aProc = GuiContext::getCurrent()->getProc();
1080   for (map<string, Container*>::const_iterator itCont = aProc->containerMap.begin();
1081        itCont != aProc->containerMap.end(); ++itCont)
1082     if ( GuiContext::getCurrent()->_mapOfSubjectContainer.find((*itCont).second)
1083          ==
1084          GuiContext::getCurrent()->_mapOfSubjectContainer.end() )
1085       // engine object for container already exists => add only a subject for it
1086       addSubjectContainer((*itCont).second, (*itCont).second->getName());
1087 }
1088
1089 SubjectComponent* SubjectProc::addComponent(std::string name)
1090 {
1091   DEBTRACE("SubjectProc::addComponent " << name);
1092   CommandAddComponentInstance *command = new CommandAddComponentInstance(name);
1093   if (command->execute())
1094     {
1095       GuiContext::getCurrent()->getInvoc()->add(command);
1096       ComponentInstance *compo = command->getComponentInstance();
1097       SubjectComponent *son = addSubjectComponent(compo);
1098       return son;
1099     }
1100   else delete command;
1101   return 0;
1102 }
1103
1104 SubjectContainer* SubjectProc::addContainer(std::string name, std::string ref)
1105 {
1106   DEBTRACE("SubjectProc::addContainer " << name << " " << ref);
1107   if (! GuiContext::getCurrent()->getProc()->containerMap.count(name))
1108     {
1109       CommandAddContainer *command = new CommandAddContainer(name,ref);
1110       if (command->execute())
1111         {
1112           GuiContext::getCurrent()->getInvoc()->add(command);
1113           Container *cont = command->getContainer();
1114           SubjectContainer *son = addSubjectContainer(cont, name);
1115           GuiContext::getCurrent()->getProc()->containerMap[name] = cont;
1116           return son;
1117         }
1118       else
1119           delete command;
1120     }
1121   else GuiContext::getCurrent()->_lastErrorMessage = "There is already a container with that name";
1122   return 0;
1123 }
1124
1125 SubjectDataType* SubjectProc::addDataType(YACS::ENGINE::Catalog* catalog, std::string typeName)
1126 {
1127   DEBTRACE("SubjectProc::addDataType " << typeName);
1128   CommandAddDataTypeFromCatalog *command = new CommandAddDataTypeFromCatalog(catalog, typeName);
1129   if (command->execute())
1130     {
1131       DEBTRACE("new datatype " << typeName);
1132       GuiContext::getCurrent()->getInvoc()->add(command);
1133       SubjectDataType *son = addSubjectDataType(command->getTypeCode());
1134       return son;
1135     }
1136   else delete command;
1137   return 0;
1138 }
1139
1140 SubjectComponent* SubjectProc::addSubjectComponent(YACS::ENGINE::ComponentInstance* compo)
1141 {
1142   DEBTRACE("SubjectProc::addSubjectComponent " << compo->getInstanceName());
1143   SubjectComponent *son = new SubjectComponent(compo, this);
1144   GuiContext::getCurrent()->_mapOfSubjectComponent[compo] = son;
1145   update(ADD, COMPONENT, son);
1146   son->setContainer();
1147   return son;
1148 }
1149
1150 SubjectContainer* SubjectProc::addSubjectContainer(YACS::ENGINE::Container* cont,
1151                                                    std::string name)
1152 {
1153   DEBTRACE("SubjectProc::addSubjectContainer " << name);
1154   SubjectContainer *son = new SubjectContainer(cont, this);
1155   GuiContext::getCurrent()->_mapOfSubjectContainer[cont] = son;
1156   update(ADD, CONTAINER, son);
1157   return son;
1158 }
1159
1160 SubjectDataType* SubjectProc::addSubjectDataType(YACS::ENGINE::TypeCode *type)
1161 {
1162   string typeName = type->name();
1163   DEBTRACE("SubjectProc::addSubjectDataType " << typeName);
1164   Proc* proc = GuiContext::getCurrent()->getProc();
1165   SubjectDataType* son = 0;
1166   if (! proc->typeMap.count(typeName))
1167     proc->typeMap[ typeName ] = type->clone();
1168   else 
1169     proc->typeMap[ typeName ]->incrRef();
1170   if (! GuiContext::getCurrent()->_mapOfSubjectDataType.count(typeName))
1171     {
1172       son = new SubjectDataType(type, this);
1173       GuiContext::getCurrent()->_mapOfSubjectDataType[typeName] = son;
1174       update(ADD, DATATYPE, son);
1175     }
1176   else
1177     GuiContext::getCurrent()->_lastErrorMessage = "Typecode " + typeName + " already had added in proc";
1178   return son;
1179 }
1180
1181 void SubjectProc::removeSubjectDataType( YACS::ENGINE::TypeCode* theType )
1182 {
1183   if ( !theType )
1184     return;
1185
1186   YACS::HMI::GuiContext* aContext = GuiContext::getCurrent();
1187   if ( !aContext )
1188     return;
1189
1190   YACS::ENGINE::Proc* aProc = aContext->getProc();
1191   if ( !aProc )
1192     return;
1193
1194   string typeName = theType->name();
1195   if ( !aProc->typeMap.count( typeName ) )
1196     return;
1197   
1198   YACS::ENGINE::TypeCode* aTypeCode = aProc->typeMap[ typeName ];
1199   if ( !aTypeCode )
1200     return;
1201
1202   if ( !aContext->_mapOfSubjectDataType.count( typeName ) )
1203     return;
1204
1205   YACS::HMI::SubjectDataType* aSDataType = aContext->_mapOfSubjectDataType[ typeName ];
1206   if ( !aSDataType )
1207     return;
1208
1209   unsigned int aRefCnt = aTypeCode->getRefCnt();
1210   if ( aRefCnt == 1 )
1211   {
1212     update( REMOVE, DATATYPE, aSDataType );
1213     aContext->_mapOfSubjectDataType.erase( typeName );
1214     aProc->typeMap.erase( typeName );
1215   }
1216
1217   aTypeCode->decrRef();
1218 }
1219
1220 // ----------------------------------------------------------------------------
1221
1222 SubjectElementaryNode::SubjectElementaryNode(YACS::ENGINE::ElementaryNode *elementaryNode,
1223                                              Subject *parent)
1224   : SubjectNode(elementaryNode, parent), _elementaryNode(elementaryNode)
1225 {
1226 }
1227
1228 /*!
1229  * all generic destruction is done in generic class SubjectNode
1230  */
1231 SubjectElementaryNode::~SubjectElementaryNode()
1232 {
1233   DEBTRACE("SubjectElementaryNode::~SubjectElementaryNode " << getName());
1234 }
1235
1236 void SubjectElementaryNode::clean()
1237 {
1238   localClean();
1239   SubjectNode::clean();
1240 }
1241
1242 void SubjectElementaryNode::localClean()
1243 {
1244   DEBTRACE("SubjectElementaryNode::localClean ");
1245 }
1246
1247
1248 SubjectDataPort* SubjectElementaryNode::addInputPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
1249 {
1250   DEBTRACE("SubjectElementaryNode::addInputPort( " << catalog << ", " << type << ", " << name << " )");
1251   Proc *proc = GuiContext::getCurrent()->getProc();
1252   string position = "";
1253   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1254   else assert(0);
1255   CommandAddInputPortFromCatalog *command = new CommandAddInputPortFromCatalog(catalog,
1256                                                                                type,
1257                                                                                position,
1258                                                                                name);
1259   if (command->execute())
1260     {
1261       GuiContext::getCurrent()->getInvoc()->add(command);
1262       InputPort * port = command->getInputPort();
1263       SubjectInputPort *son = addSubjectInputPort(port, name);
1264       return son;
1265     }
1266   else delete command;
1267   return 0;
1268 }
1269
1270 SubjectDataPort* SubjectElementaryNode::addOutputPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
1271 {
1272   DEBTRACE("SubjectElementaryNode::addOutputPort( " << catalog << ", " << type << ", " << name << " )");
1273   Proc *proc = GuiContext::getCurrent()->getProc();
1274   string position = "";
1275   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1276   else assert(0);
1277   CommandAddOutputPortFromCatalog *command = new CommandAddOutputPortFromCatalog(catalog,
1278                                                                                  type,
1279                                                                                  position,
1280                                                                                  name);
1281   if (command->execute())
1282     {
1283       GuiContext::getCurrent()->getInvoc()->add(command);
1284       OutputPort * port = command->getOutputPort();
1285       SubjectOutputPort *son = addSubjectOutputPort(port, name);
1286       return son;
1287     }
1288   else delete command;
1289   return 0;
1290 }
1291
1292 SubjectDataPort* SubjectElementaryNode::addIDSPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
1293 {
1294   DEBTRACE("SubjectElementaryNode::addIDSPort( " << catalog << ", " << type << ", " << name << " )");
1295   Proc *proc = GuiContext::getCurrent()->getProc();
1296   string position = "";
1297   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1298   else assert(0);
1299   CommandAddIDSPortFromCatalog *command = new CommandAddIDSPortFromCatalog(catalog,
1300                                                                            type,
1301                                                                            position,
1302                                                                            name);
1303   if (command->execute())
1304     {
1305       GuiContext::getCurrent()->getInvoc()->add(command);
1306       InputDataStreamPort * port = command->getIDSPort();
1307       SubjectInputDataStreamPort *son = addSubjectIDSPort(port, name);
1308       return son;
1309     }
1310   else delete command;
1311   return 0;
1312 }
1313
1314 SubjectDataPort* SubjectElementaryNode::addODSPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
1315 {
1316   DEBTRACE("SubjectElementaryNode::addODSPort( " << catalog << ", " << type << ", " << name << " )");
1317   Proc *proc = GuiContext::getCurrent()->getProc();
1318   string position = "";
1319   if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1320   else assert(0);
1321   CommandAddODSPortFromCatalog *command = new CommandAddODSPortFromCatalog(catalog,
1322                                                                            type,
1323                                                                            position,
1324                                                                            name);
1325   if (command->execute())
1326     {
1327       GuiContext::getCurrent()->getInvoc()->add(command);
1328       OutputDataStreamPort * port = command->getODSPort();
1329       SubjectOutputDataStreamPort *son = addSubjectODSPort(port, name);
1330       return son;
1331     }
1332   else delete command;
1333   return 0;
1334 }
1335
1336 void SubjectElementaryNode::removePort(SubjectDataPort* port)
1337 {
1338   DEBTRACE("SubjectElementaryNode::removePort " << port->getName());
1339   if (SubjectInputPort* inp = dynamic_cast<SubjectInputPort*>(port))
1340     {
1341       DEBTRACE("-");
1342       _listSubjectInputPort.remove(inp);
1343     }
1344   else if(SubjectOutputPort* outp = dynamic_cast<SubjectOutputPort*>(port))
1345     {
1346       DEBTRACE("--");
1347       _listSubjectOutputPort.remove(outp);
1348     }
1349   if (SubjectInputDataStreamPort* idsp = dynamic_cast<SubjectInputDataStreamPort*>(port))
1350     {
1351       DEBTRACE("---");
1352       _listSubjectIDSPort.remove(idsp);
1353     }
1354   else if(SubjectOutputDataStreamPort* odsp = dynamic_cast<SubjectOutputDataStreamPort*>(port))
1355     {
1356       DEBTRACE("----");
1357       _listSubjectODSPort.remove(odsp);
1358     }
1359 }
1360
1361 void SubjectElementaryNode::loadChildren()
1362 {
1363   list<InputPort*>  listInputPorts  = _elementaryNode->getLocalInputPorts();
1364   list<OutputPort*> listOutputPorts = _elementaryNode->getLocalOutputPorts();
1365   list<InputDataStreamPort*>  listIDSPorts = _elementaryNode->getSetOfInputDataStreamPort();
1366   list<OutputDataStreamPort*> listODSPorts = _elementaryNode->getSetOfOutputDataStreamPort();
1367   if (SplitterNode *splitterNode = dynamic_cast<SplitterNode*>(_elementaryNode))
1368     listInputPorts.push_back(splitterNode->getFather()->getInputPort("SmplsCollection"));
1369   list<InputPort*>::const_iterator iti;
1370   for (iti = listInputPorts.begin(); iti != listInputPorts.end(); ++iti)
1371     addSubjectInputPort(*iti);
1372   list<OutputPort*>::const_iterator ito;
1373   for (ito = listOutputPorts.begin(); ito != listOutputPorts.end(); ++ito)
1374     addSubjectOutputPort(*ito);
1375   list<InputDataStreamPort*>::const_iterator itids;
1376   for (itids = listIDSPorts.begin(); itids != listIDSPorts.end(); ++itids)
1377     addSubjectIDSPort(*itids);
1378   list<OutputDataStreamPort*>::const_iterator itods;
1379   for (itods = listODSPorts.begin(); itods != listODSPorts.end(); ++itods)
1380     addSubjectODSPort(*itods);
1381 }
1382
1383 // ----------------------------------------------------------------------------
1384
1385
1386 SubjectInlineNode::SubjectInlineNode(YACS::ENGINE::InlineNode *inlineNode, Subject *parent)
1387   : SubjectElementaryNode(inlineNode, parent), _inlineNode(inlineNode)
1388 {
1389 }
1390
1391 SubjectInlineNode::~SubjectInlineNode()
1392 {
1393   DEBTRACE("SubjectInlineNode::~SubjectInlineNode " << getName());
1394 }
1395
1396 bool SubjectInlineNode::setScript(std::string script)
1397 {
1398   Proc *proc = GuiContext::getCurrent()->getProc();
1399   CommandSetInlineNodeScript *command =
1400     new CommandSetInlineNodeScript(proc->getChildName(_node), script);
1401   if (command->execute())
1402     {
1403       GuiContext::getCurrent()->getInvoc()->add(command);
1404       return true;
1405     }
1406   else delete command;
1407   return false;
1408 }
1409
1410 std::string SubjectInlineNode::getScript()
1411 {
1412   return _inlineNode->getScript();
1413 }
1414
1415 void SubjectInlineNode::clean()
1416 {
1417   localClean();
1418   SubjectElementaryNode::clean();
1419 }
1420
1421 void SubjectInlineNode::localClean()
1422 {
1423   DEBTRACE("SubjectInlineNode::localClean ");
1424 }
1425
1426
1427 // ----------------------------------------------------------------------------
1428
1429 SubjectServiceNode::SubjectServiceNode(YACS::ENGINE::ServiceNode *serviceNode, Subject *parent)
1430   : SubjectElementaryNode(serviceNode, parent), _serviceNode(serviceNode)
1431 {
1432   _subjectReference=0;
1433 }
1434
1435 SubjectServiceNode::~SubjectServiceNode()
1436 {
1437   DEBTRACE("SubjectServiceNode::~SubjectServiceNode " << getName());
1438 }
1439
1440 void SubjectServiceNode::clean()
1441 {
1442   localClean();
1443   SubjectElementaryNode::clean();
1444 }
1445
1446 void SubjectServiceNode::localClean()
1447 {
1448   DEBTRACE("SubjectServiceNode::localClean ");
1449   if (_subjectReference)
1450     {
1451       update( REMOVE, REFERENCE, _subjectReference );
1452       erase( _subjectReference );
1453       _subjectReference = 0;
1454     }
1455 }
1456
1457
1458 /*!
1459  *  When cloning a service node from a catalog, create the component associated to the node,
1460  *  if not already existing, and create the corresponding subject.
1461  */
1462 void SubjectServiceNode::setComponentFromCatalog(YACS::ENGINE::Catalog *catalog,
1463                                                  std::string compo,
1464                                                  std::string service)
1465 {
1466   DEBTRACE("SubjectServiceNode::setComponent " << compo);
1467   if (catalog->_componentMap.count(compo))
1468     {
1469       YACS::ENGINE::ComponentDefinition* compodef = catalog->_componentMap[compo];
1470       if (compodef->_serviceMap.count(service))
1471         {
1472           Proc* proc = GuiContext::getCurrent()->getProc();
1473           ComponentInstance *instance = 0;
1474           instance = new SalomeComponent(compo);
1475           pair<string,int> key = pair<string,int>(compo, instance->getNumId());
1476           proc->componentInstanceMap[key] = instance;
1477           SubjectComponent* subCompo = GuiContext::getCurrent()->getSubjectProc()->addSubjectComponent(instance);
1478           assert(subCompo);
1479           addSubjectReference(subCompo);
1480           _serviceNode->setComponent(instance);
1481         }
1482     }
1483 }
1484
1485 /*!
1486  *  When loading scheme from file, get the component associated to the node, if any,
1487  *  and create the corresponding subject.
1488  */
1489 void SubjectServiceNode::setComponent()
1490 {
1491   ComponentInstance *instance = _serviceNode->getComponent();
1492   if (instance)
1493     {
1494       Proc* proc = GuiContext::getCurrent()->getProc();
1495       string compo = instance->getCompoName();
1496       SubjectComponent* subCompo = 0;
1497       if (! GuiContext::getCurrent()->_mapOfSubjectComponent.count(instance))
1498         {
1499           DEBTRACE("SubjectServiceNode::setComponent : create subject for compo = " << compo.c_str());
1500           pair<string,int> key = pair<string,int>(compo, instance->getNumId());
1501           proc->componentInstanceMap[key] = instance;
1502           subCompo =
1503             GuiContext::getCurrent()->getSubjectProc()->addSubjectComponent(instance);
1504         }
1505       else
1506         {
1507           DEBTRACE("SubjectServiceNode::setComponent : get already created subject for compo = " <<compo.c_str());
1508           subCompo = GuiContext::getCurrent()->_mapOfSubjectComponent[instance];
1509         }       
1510       assert(subCompo);
1511       addSubjectReference(subCompo);
1512     }
1513 }
1514
1515 void SubjectServiceNode::associateToComponent(SubjectComponent *subcomp)
1516 {
1517   DEBTRACE("SubjectServiceNode::associateToComponent " << getName() << " " << subcomp->getName());
1518   SubjectReference* oldSReference = _subjectReference;
1519   string aName = GuiContext::getCurrent()->getProc()->getChildName(_serviceNode);
1520   CommandAssociateServiceToComponent *command =
1521     new CommandAssociateServiceToComponent(aName, subcomp->getKey());
1522   if (command->execute())
1523     {
1524       if (oldSReference) removeSubjectReference(oldSReference);
1525       GuiContext::getCurrent()->getInvoc()->add(command);
1526       addSubjectReference(subcomp);
1527     }
1528   else delete command;
1529 }
1530
1531 void SubjectServiceNode::removeSubjectReference(Subject *ref)
1532 {
1533   DEBTRACE("Subject::removeSubjectReference " << getName() << " " << ref->getName());
1534   update( REMOVE, REFERENCE, ref );
1535   erase( ref );
1536 }
1537
1538 void SubjectServiceNode::addSubjectReference(Subject *ref)
1539 {
1540   DEBTRACE("Subject::addSubjectReference " << getName() << " " << ref->getName());
1541   SubjectReference *son = new SubjectReference(ref, this);
1542   _subjectReference = son;
1543   update(ADDREF, 0, son);
1544 }
1545
1546 SubjectReference* SubjectServiceNode::getSubjectReference()
1547 {
1548   return _subjectReference;
1549 }
1550
1551 // ----------------------------------------------------------------------------
1552
1553 SubjectPythonNode::SubjectPythonNode(YACS::ENGINE::PythonNode *pythonNode, Subject *parent)
1554   : SubjectInlineNode(pythonNode, parent), _pythonNode(pythonNode)
1555 {
1556 }
1557
1558 SubjectPythonNode::~SubjectPythonNode()
1559 {
1560   DEBTRACE("SubjectPythonNode::~SubjectPythonNode " << getName());
1561 }
1562
1563 void SubjectPythonNode::clean()
1564 {
1565   localClean();
1566   SubjectInlineNode::clean();
1567 }
1568
1569 void SubjectPythonNode::localClean()
1570 {
1571   DEBTRACE("SubjectPythonNode::localClean ");
1572 }
1573
1574
1575 // ----------------------------------------------------------------------------
1576
1577 SubjectPyFuncNode::SubjectPyFuncNode(YACS::ENGINE::PyFuncNode *pyFuncNode, Subject *parent)
1578   : SubjectInlineNode(pyFuncNode, parent), _pyFuncNode(pyFuncNode)
1579 {
1580 }
1581
1582 SubjectPyFuncNode::~SubjectPyFuncNode()
1583 {
1584   DEBTRACE("SubjectPyFuncNode::~SubjectPyFuncNode " << getName());
1585 }
1586
1587 bool SubjectPyFuncNode::setFunctionName(std::string funcName)
1588 {
1589   Proc *proc = GuiContext::getCurrent()->getProc();
1590   CommandSetFuncNodeFunctionName *command =
1591     new CommandSetFuncNodeFunctionName(proc->getChildName(_node), funcName);
1592   if (command->execute())
1593     {
1594       GuiContext::getCurrent()->getInvoc()->add(command);
1595       return true;
1596     }
1597   else delete command;
1598   return false;
1599 }
1600
1601 void SubjectPyFuncNode::clean()
1602 {
1603   localClean();
1604   SubjectInlineNode::clean();
1605 }
1606
1607 void SubjectPyFuncNode::localClean()
1608 {
1609   DEBTRACE("SubjectPyFuncNode::localClean ");
1610 }
1611
1612
1613 // ----------------------------------------------------------------------------
1614
1615 SubjectCORBANode::SubjectCORBANode(YACS::ENGINE::CORBANode *corbaNode, Subject *parent)
1616   : SubjectServiceNode(corbaNode, parent), _corbaNode(corbaNode)
1617 {
1618 }
1619
1620 SubjectCORBANode::~SubjectCORBANode()
1621 {
1622   DEBTRACE("SubjectCORBANode::~SubjectCORBANode " << getName());
1623 }
1624
1625 void SubjectCORBANode::clean()
1626 {
1627   localClean();
1628   SubjectServiceNode::clean();
1629 }
1630
1631 void SubjectCORBANode::localClean()
1632 {
1633   DEBTRACE("SubjectCORBANode::localClean ");
1634 }
1635
1636
1637 // ----------------------------------------------------------------------------
1638
1639 SubjectCppNode::SubjectCppNode(YACS::ENGINE::CppNode *cppNode, Subject *parent)
1640   : SubjectServiceNode(cppNode, parent), _cppNode(cppNode)
1641 {
1642 }
1643
1644 SubjectCppNode::~SubjectCppNode()
1645 {
1646   DEBTRACE("SubjectCppNode::~SubjectCppNode " << getName());
1647 }
1648
1649 void SubjectCppNode::clean()
1650 {
1651   localClean();
1652   SubjectServiceNode::clean();
1653 }
1654
1655 void SubjectCppNode::localClean()
1656 {
1657   DEBTRACE("SubjectCppNode::localClean ");
1658 }
1659
1660
1661 // ----------------------------------------------------------------------------
1662
1663 SubjectSalomeNode::SubjectSalomeNode(YACS::ENGINE::SalomeNode *salomeNode, Subject *parent)
1664   : SubjectServiceNode(salomeNode, parent), _salomeNode(salomeNode)
1665 {
1666 }
1667
1668 SubjectSalomeNode::~SubjectSalomeNode()
1669 {
1670   DEBTRACE("SubjectSalomeNode::~SubjectSalomeNode " << getName());
1671 }
1672
1673 void SubjectSalomeNode::clean()
1674 {
1675   localClean();
1676   SubjectServiceNode::clean();
1677 }
1678
1679 void SubjectSalomeNode::localClean()
1680 {
1681   DEBTRACE("SubjectSalomeNode::localClean ");
1682 }
1683
1684
1685 // ----------------------------------------------------------------------------
1686
1687 SubjectSalomePythonNode::SubjectSalomePythonNode(YACS::ENGINE::SalomePythonNode *salomePythonNode,
1688                                                  Subject *parent)
1689   : SubjectServiceNode(salomePythonNode, parent), _salomePythonNode(salomePythonNode)
1690 {
1691 }
1692
1693 SubjectSalomePythonNode::~SubjectSalomePythonNode()
1694 {
1695   DEBTRACE("SubjectSalomePythonNode::~SubjectSalomePythonNode " << getName());
1696 }
1697
1698 void SubjectSalomePythonNode::clean()
1699 {
1700   localClean();
1701   SubjectServiceNode::clean();
1702 }
1703
1704 void SubjectSalomePythonNode::localClean()
1705 {
1706   DEBTRACE("SubjectSalomePythonNode::localClean ");
1707 }
1708
1709
1710 // ----------------------------------------------------------------------------
1711
1712 SubjectXmlNode::SubjectXmlNode(YACS::ENGINE::XmlNode *xmlNode, Subject *parent)
1713   : SubjectServiceNode(xmlNode, parent), _xmlNode(xmlNode)
1714 {
1715 }
1716
1717 SubjectXmlNode::~SubjectXmlNode()
1718 {
1719   DEBTRACE("SubjectXmlNode::~SubjectXmlNode " << getName());
1720 }
1721
1722 void SubjectXmlNode::clean()
1723 {
1724   localClean();
1725   SubjectServiceNode::clean();
1726 }
1727
1728 void SubjectXmlNode::localClean()
1729 {
1730   DEBTRACE("SubjectXmlNode::localClean ");
1731 }
1732
1733
1734 // ----------------------------------------------------------------------------
1735
1736 SubjectSplitterNode::SubjectSplitterNode(YACS::ENGINE::SplitterNode *splitterNode, Subject *parent)
1737   : SubjectElementaryNode(splitterNode, parent), _splitterNode(splitterNode)
1738 {
1739   _destructible = false;
1740 }
1741
1742 SubjectSplitterNode::~SubjectSplitterNode()
1743 {
1744   DEBTRACE("SubjectSplitterNode::~SubjectSplitterNode " << getName());
1745 }
1746
1747 void SubjectSplitterNode::clean()
1748 {
1749   localClean();
1750   SubjectElementaryNode::clean();
1751 }
1752
1753 void SubjectSplitterNode::localClean()
1754 {
1755   DEBTRACE("SubjectSplitterNode::localClean ");
1756 }
1757
1758
1759 std::string SubjectSplitterNode::getName()
1760 {
1761   return "splitter";
1762 }
1763
1764 // ----------------------------------------------------------------------------
1765
1766 SubjectDataNode::SubjectDataNode(YACS::ENGINE::DataNode *dataNode, Subject *parent)
1767   : SubjectElementaryNode(dataNode, parent), _dataNode(dataNode)
1768 {
1769   _destructible = true;
1770 }
1771
1772 SubjectDataNode::~SubjectDataNode()
1773 {
1774   DEBTRACE("SubjectDataNode::~SubjectDataNode " << getName());
1775 }
1776
1777 void SubjectDataNode::clean()
1778 {
1779   localClean();
1780   SubjectElementaryNode::clean();
1781 }
1782
1783 void SubjectDataNode::localClean()
1784 {
1785   DEBTRACE("SubjectDataNode::localClean ");
1786 }
1787
1788 // ----------------------------------------------------------------------------
1789
1790 SubjectPresetNode::SubjectPresetNode(YACS::ENGINE::PresetNode *presetNode, Subject *parent)
1791   : SubjectDataNode(presetNode, parent), _presetNode(presetNode)
1792 {
1793   _destructible = true;
1794 }
1795
1796 SubjectPresetNode::~SubjectPresetNode()
1797 {
1798   DEBTRACE("SubjectPresetNode::~SubjectPresetNode " << getName());
1799 }
1800
1801 void SubjectPresetNode::clean()
1802 {
1803   localClean();
1804   SubjectDataNode::clean();
1805 }
1806
1807 void SubjectPresetNode::localClean()
1808 {
1809   DEBTRACE("SubjectPresetNode::localClean ");
1810 }
1811
1812 // ----------------------------------------------------------------------------
1813
1814 SubjectOutNode::SubjectOutNode(YACS::ENGINE::OutNode *outNode, Subject *parent)
1815   : SubjectDataNode(outNode, parent), _outNode(outNode)
1816 {
1817   _destructible = true;
1818 }
1819
1820 SubjectOutNode::~SubjectOutNode()
1821 {
1822   DEBTRACE("SubjectOutNode::~SubjectOutNode " << getName());
1823 }
1824
1825 void SubjectOutNode::clean()
1826 {
1827   localClean();
1828   SubjectDataNode::clean();
1829 }
1830
1831 void SubjectOutNode::localClean()
1832 {
1833   DEBTRACE("SubjectOutNode::localClean ");
1834 }
1835
1836 // ----------------------------------------------------------------------------
1837
1838 SubjectStudyInNode::SubjectStudyInNode(YACS::ENGINE::StudyInNode *studyInNode, Subject *parent)
1839   : SubjectDataNode(studyInNode, parent), _studyInNode(studyInNode)
1840 {
1841   _destructible = true;
1842 }
1843
1844 SubjectStudyInNode::~SubjectStudyInNode()
1845 {
1846   DEBTRACE("SubjectStudyInNode::~SubjectStudyInNode " << getName());
1847 }
1848
1849 void SubjectStudyInNode::clean()
1850 {
1851   localClean();
1852   SubjectDataNode::clean();
1853 }
1854
1855 void SubjectStudyInNode::localClean()
1856 {
1857   DEBTRACE("SubjectStudyInNode::localClean ");
1858 }
1859
1860 // ----------------------------------------------------------------------------
1861
1862 SubjectStudyOutNode::SubjectStudyOutNode(YACS::ENGINE::StudyOutNode *studyOutNode, Subject *parent)
1863   : SubjectDataNode(studyOutNode, parent), _studyOutNode(studyOutNode)
1864 {
1865   _destructible = true;
1866 }
1867
1868 SubjectStudyOutNode::~SubjectStudyOutNode()
1869 {
1870   DEBTRACE("SubjectStudyOutNode::~SubjectStudyOutNode " << getName());
1871 }
1872
1873 void SubjectStudyOutNode::clean()
1874 {
1875   localClean();
1876   SubjectDataNode::clean();
1877 }
1878
1879 void SubjectStudyOutNode::localClean()
1880 {
1881   DEBTRACE("SubjectStudyOutNode::localClean ");
1882 }
1883
1884 // ----------------------------------------------------------------------------
1885
1886 SubjectForLoop::SubjectForLoop(YACS::ENGINE::ForLoop *forLoop, Subject *parent)
1887   : SubjectComposedNode(forLoop, parent), _forLoop(forLoop)
1888 {
1889   _body = 0;
1890 }
1891
1892 SubjectForLoop::~SubjectForLoop()
1893 {
1894   DEBTRACE("SubjectForLoop::~SubjectForLoop " << getName());
1895 }
1896
1897 void SubjectForLoop::clean()
1898 {
1899   localClean();
1900   SubjectComposedNode::clean();
1901 }
1902
1903 void SubjectForLoop::localClean()
1904 {
1905   DEBTRACE("SubjectForLoop::localClean ");
1906   if (_body)
1907     erase(_body);
1908 }
1909
1910
1911 SubjectNode* SubjectForLoop::addNode(YACS::ENGINE::Catalog *catalog,
1912                                      std::string compo,
1913                                      std::string type,
1914                                      std::string name)
1915 {
1916   DEBTRACE("SubjectForLoop::addNode(catalog, compo, type, name)");
1917   SubjectNode* body = 0;
1918   if (_body) return body;
1919   body = createNode(catalog, compo, type, name);
1920   return body;
1921 }
1922
1923 void SubjectForLoop::completeChildrenSubjectList(SubjectNode *son)
1924 {
1925   _body = son;
1926 }
1927
1928 // ----------------------------------------------------------------------------
1929
1930 SubjectWhileLoop::SubjectWhileLoop(YACS::ENGINE::WhileLoop *whileLoop, Subject *parent)
1931   : SubjectComposedNode(whileLoop, parent), _whileLoop(whileLoop)
1932 {
1933   _body = 0;
1934 }
1935
1936 SubjectWhileLoop::~SubjectWhileLoop()
1937 {
1938   DEBTRACE("SubjectWhileLoop::~SubjectWhileLoop " << getName());
1939 }
1940
1941 void SubjectWhileLoop::clean()
1942 {
1943   localClean();
1944   SubjectComposedNode::clean();
1945 }
1946
1947 void SubjectWhileLoop::localClean()
1948 {
1949   DEBTRACE("SubjectWhileLoop::localClean ");
1950   if (_body)
1951     erase(_body);
1952 }
1953
1954 SubjectNode* SubjectWhileLoop::addNode(YACS::ENGINE::Catalog *catalog,
1955                                        std::string compo,
1956                                        std::string type,
1957                                        std::string name)
1958 {
1959   DEBTRACE("SubjectWhileLoop::addNode(catalog, compo, type, name)");
1960   SubjectNode* body = 0;
1961   if (_body) return body;
1962   body = createNode(catalog, compo, type, name);
1963   return body;
1964 }
1965
1966 void SubjectWhileLoop::completeChildrenSubjectList(SubjectNode *son)
1967 {
1968   _body = son;
1969 }
1970
1971 // ----------------------------------------------------------------------------
1972
1973 SubjectSwitch::SubjectSwitch(YACS::ENGINE::Switch *aSwitch, Subject *parent)
1974   : SubjectComposedNode(aSwitch, parent), _switch(aSwitch)
1975 {
1976   _bodyMap.clear();
1977 }
1978
1979 SubjectSwitch::~SubjectSwitch()
1980 {
1981   DEBTRACE("SubjectSwitch::~SubjectSwitch " << getName());
1982 }
1983
1984 void SubjectSwitch::clean()
1985 {
1986   localClean();
1987   SubjectComposedNode::clean();
1988 }
1989
1990 void SubjectSwitch::localClean()
1991 {
1992   DEBTRACE("SubjectSwitch::localClean ");
1993   map<int, SubjectNode*>::iterator it;
1994   for (it = _bodyMap.begin(); it != _bodyMap.end(); ++it)
1995     erase((*it).second);
1996 }
1997
1998 SubjectNode* SubjectSwitch::addNode(YACS::ENGINE::Catalog *catalog,
1999                                     std::string compo,
2000                                     std::string type,
2001                                     std::string name,
2002                                     int swCase,
2003                                     bool replace)
2004 {
2005   DEBTRACE("SubjectSwitch::addNode("<<catalog<<","<<compo<<","<<type<<","<<name<<","<<swCase<<","<<(int)replace<<")");
2006   SubjectNode* body = 0;
2007   if (!replace && _bodyMap.count(swCase)) return body;
2008   body = createNode(catalog, compo, type, name, swCase);
2009   return body;
2010 }
2011
2012 void SubjectSwitch::removeNode(SubjectNode* son)
2013 {
2014   DEBTRACE("SubjectSwitch::removeNode("<<son->getName()<<")");
2015   if (son)
2016   {
2017     int id;
2018     bool isFound = false;
2019     map<int, SubjectNode*>::const_iterator it;
2020     for (it = _bodyMap.begin(); it != _bodyMap.end(); ++it)
2021     {
2022       if ( (*it).second == son )
2023       {
2024         isFound = true;
2025         id = (*it).first;
2026         break;
2027       }
2028     }
2029     if (isFound)
2030     {
2031       DEBTRACE("id = "<<id);
2032       _bodyMap.erase(id);
2033     }
2034   }
2035 }
2036
2037 std::map<int, SubjectNode*> SubjectSwitch::getBodyMap()
2038 {
2039   return _bodyMap;
2040 }
2041
2042 void SubjectSwitch::completeChildrenSubjectList(SubjectNode *son)
2043 {
2044   _bodyMap[_switch->getRankOfNode(son->getNode())] = son;
2045 }
2046
2047 SubjectNode* SubjectSwitch::getChild(YACS::ENGINE::Node* node) const
2048 {
2049   SubjectNode* aChild = 0;
2050
2051   if (node)
2052   {
2053     map<int, SubjectNode*>::const_iterator it;
2054     for (it = _bodyMap.begin(); it != _bodyMap.end(); ++it)
2055       if ( (*it).second->getNode() == node )
2056       {
2057         aChild = (*it).second;
2058         break;
2059       }
2060   }
2061
2062   return aChild;
2063 }
2064
2065 // ----------------------------------------------------------------------------
2066
2067 SubjectForEachLoop::SubjectForEachLoop(YACS::ENGINE::ForEachLoop *forEachLoop, Subject *parent)
2068   : SubjectComposedNode(forEachLoop, parent), _forEachLoop(forEachLoop)
2069 {
2070   _body = 0;
2071   _splitter = 0;
2072 }
2073
2074 SubjectForEachLoop::~SubjectForEachLoop()
2075 {
2076   DEBTRACE("SubjectForEachLoop::~SubjectForEachLoop " << getName());
2077 }
2078
2079 void SubjectForEachLoop::clean()
2080 {
2081   Node* aSplitterEngine = 0;
2082   if (_splitter) aSplitterEngine = _splitter->getNode();
2083
2084   localClean();
2085   SubjectComposedNode::clean();
2086
2087   if (_forEachLoop && aSplitterEngine)
2088     {
2089       DEBTRACE("SubjectForEachLoop::clean: remove for each loop splitter");
2090       _forEachLoop->edRemoveChild(aSplitterEngine);
2091     }
2092 }
2093
2094 void SubjectForEachLoop::localClean()
2095 {
2096   DEBTRACE("SubjectForEachLoop::localClean ");
2097   if (_body)
2098     {
2099       DEBTRACE(_body->getName());
2100       erase(_body);
2101     }
2102   if (_splitter)
2103     {
2104       DEBTRACE(_splitter->getName());
2105       erase(_splitter);
2106     }
2107 }
2108
2109
2110 SubjectNode* SubjectForEachLoop::addNode(YACS::ENGINE::Catalog *catalog,
2111                                          std::string compo,
2112                                          std::string type,
2113                                          std::string name)
2114 {
2115   DEBTRACE("SubjectForEachLoop::addNode(catalog, compo, type, name)");
2116   SubjectNode* body = 0;
2117   if (_body) return body;
2118   body = createNode(catalog, compo, type, name);
2119   return body;
2120 }
2121
2122 void SubjectForEachLoop::completeChildrenSubjectList(SubjectNode *son)
2123 {
2124   if ( !son )
2125   {
2126     _body = son;
2127     return;
2128   }
2129
2130   string name = son->getName();
2131   DEBTRACE("SubjectForEachLoop::completeChildrenSubjectList " << name);
2132   if (name == ForEachLoop::NAME_OF_SPLITTERNODE)
2133     _splitter = son;
2134   else
2135     _body = son;
2136 }
2137
2138
2139 // ----------------------------------------------------------------------------
2140
2141 SubjectOptimizerLoop::SubjectOptimizerLoop(YACS::ENGINE::OptimizerLoop *optimizerLoop,
2142                                            Subject *parent)
2143   : SubjectComposedNode(optimizerLoop, parent), _optimizerLoop(optimizerLoop)
2144 {
2145   _body = 0;
2146 }
2147
2148 SubjectOptimizerLoop::~SubjectOptimizerLoop()
2149 {
2150   DEBTRACE("SubjectOptimizerLoop::~SubjectOptimizerLoop " << getName());
2151 }
2152
2153 void SubjectOptimizerLoop::clean()
2154 {
2155   localClean();
2156   SubjectComposedNode::clean();
2157 }
2158
2159 void SubjectOptimizerLoop::localClean()
2160 {
2161   DEBTRACE("SubjectOptimizerLoop::localClean ");
2162   if (_body)
2163     erase(_body);
2164 }
2165
2166 SubjectNode* SubjectOptimizerLoop::addNode(YACS::ENGINE::Catalog *catalog,
2167                                            std::string compo,
2168                                            std::string type,
2169                                            std::string name)
2170 {
2171   DEBTRACE("SubjectOptimizerLoop::addNode(catalog, compo, type, name)");
2172   SubjectNode* body = 0;
2173   if (_body) return body;
2174   body = createNode(catalog, compo, type, name);
2175   return body;
2176 }
2177
2178 void SubjectOptimizerLoop::completeChildrenSubjectList(SubjectNode *son)
2179 {
2180   _body = son;
2181 }
2182
2183 // ----------------------------------------------------------------------------
2184
2185 SubjectDataPort::SubjectDataPort(YACS::ENGINE::DataPort* port, Subject *parent)
2186   : Subject(parent), _dataPort(port)
2187 {
2188   _listSubjectLink.clear();
2189 }
2190
2191 SubjectDataPort::~SubjectDataPort()
2192 {
2193   DEBTRACE("SubjectDataPort::~SubjectDataPort " << getName());
2194   if (isDestructible())
2195     {
2196       Node* node = _dataPort->getNode();
2197       assert(node);
2198       ElementaryNode * father = dynamic_cast<ElementaryNode*>(node);
2199       if (father)
2200         {
2201           DEBTRACE("father->edRemovePort(_dataPort)");
2202           try
2203             {
2204               father->edRemovePort(_dataPort);
2205             }
2206           catch (YACS::Exception &e)
2207             {
2208               DEBTRACE("------------------------------------------------------------------------------");
2209               DEBTRACE("SubjectDataPort::~SubjectDataPort: father->edRemovePort: YACS exception " << e.what());
2210               DEBTRACE("------------------------------------------------------------------------------");
2211             }
2212         }
2213     }
2214 }
2215
2216 void SubjectDataPort::clean()
2217 {
2218   localClean();
2219   Subject::clean();
2220 }
2221
2222 void SubjectDataPort::localClean()
2223 {
2224   DEBTRACE("SubjectDataPort::localClean ");
2225   list<SubjectLink*> lsl = getListOfSubjectLink();
2226   for (list<SubjectLink*>::iterator it = lsl.begin(); it != lsl.end(); ++it)
2227     erase(*it);
2228 }
2229
2230 std::string SubjectDataPort::getName()
2231 {
2232   return _dataPort->getName();
2233 }
2234
2235 YACS::ENGINE::DataPort* SubjectDataPort::getPort()
2236 {
2237   return _dataPort;
2238 }
2239
2240 bool SubjectDataPort::tryCreateLink(SubjectDataPort *subOutport, SubjectDataPort *subInport)
2241 {
2242   DEBTRACE("SubjectDataPort::tryCreateLink");
2243   Proc *proc = GuiContext::getCurrent()->getProc();
2244
2245   string outNodePos = "";
2246   SubjectNode *sno = dynamic_cast<SubjectNode*>(subOutport->getParent());
2247   assert(sno);
2248   Node *outNode = sno->getNode();
2249   outNodePos = proc->getChildName(outNode);
2250   string outportName = subOutport->getName();
2251
2252   string inNodePos = "";
2253   SubjectNode *sni = dynamic_cast<SubjectNode*>(subInport->getParent());
2254   assert(sni);
2255   Node *inNode = sni->getNode();
2256   inNodePos = proc->getChildName(inNode);
2257   string inportName = subInport->getName();
2258   
2259   CommandAddLink *command = new CommandAddLink(outNodePos, outportName,
2260                                                inNodePos, inportName);
2261   if (command->execute())
2262     {
2263       GuiContext::getCurrent()->getInvoc()->add(command);
2264       
2265       ComposedNode *cla = ComposedNode::getLowestCommonAncestor(outNode->getFather(),
2266                                                                 inNode->getFather());
2267       SubjectComposedNode *scla = dynamic_cast<SubjectComposedNode*>(sno->getParent());
2268       ComposedNode *ancestor = outNode->getFather();
2269       while (ancestor && ancestor != cla)
2270         {
2271           ancestor = ancestor->getFather();
2272           scla = dynamic_cast<SubjectComposedNode*>(scla->getParent());
2273           assert(scla);
2274         }
2275       DEBTRACE(scla->getName());
2276       scla->addSubjectLink(sno, subOutport, sni, subInport);
2277       return true;
2278     }
2279   else
2280     {
2281       delete command;
2282       return false;
2283     }
2284 }
2285
2286 // ----------------------------------------------------------------------------
2287
2288 SubjectInputPort::SubjectInputPort(YACS::ENGINE::InputPort *port, Subject *parent)
2289   : SubjectDataPort(port, parent), _inputPort(port)
2290 {
2291   Node *node = _inputPort->getNode();
2292   if (ForLoop* forloop = dynamic_cast<ForLoop*>(node))
2293     {
2294       if (_inputPort->getName() == "nsteps") _destructible = false;
2295     }
2296   else if (WhileLoop* whileloop = dynamic_cast<WhileLoop*>(node))
2297     {
2298       if (_inputPort->getName() == "condition") _destructible = false;
2299     }
2300   else if (Switch* aSwitch = dynamic_cast<Switch*>(node))
2301     {
2302       if (_inputPort->getName() == "select") _destructible = false;
2303     }
2304   else if (ForEachLoop* foreach = dynamic_cast<ForEachLoop*>(node))
2305     {
2306       if (_inputPort->getName() == "nbBranches") _destructible = false;
2307     }
2308   else if (OptimizerLoop* optil = dynamic_cast<OptimizerLoop*>(node))
2309     {
2310       if (_inputPort->getName() == "nbBranches") _destructible = false;
2311     }
2312   else if (SplitterNode* split = dynamic_cast<SplitterNode*>(node))
2313     {
2314       if (_inputPort->getName() == "SmplsCollection") _destructible = false;
2315     }
2316
2317 }
2318
2319 SubjectInputPort::~SubjectInputPort()
2320 {
2321   DEBTRACE("SubjectInputPort::~SubjectInputPort " << getName());
2322 }
2323
2324 void SubjectInputPort::clean()
2325 {
2326   localClean();
2327   SubjectDataPort::clean();
2328 }
2329
2330 void SubjectInputPort::localClean()
2331 {
2332   DEBTRACE("SubjectInputPort::localClean ");
2333   if (_parent)
2334     {
2335       SubjectElementaryNode* elem = dynamic_cast<SubjectElementaryNode*>(_parent);
2336       if (elem) elem->removePort(this);
2337     }
2338 }
2339
2340 // ----------------------------------------------------------------------------
2341
2342 SubjectOutputPort::SubjectOutputPort(YACS::ENGINE::OutputPort *port, Subject *parent)
2343   : SubjectDataPort(port, parent), _outputPort(port)
2344 {
2345   Node *node = _outputPort->getNode();
2346   if (ForEachLoop* foreach = dynamic_cast<ForEachLoop*>(node))
2347     {
2348       if (_outputPort->getName() == "SmplPrt") _destructible = false;
2349     }
2350   else if (OptimizerLoop* optil = dynamic_cast<OptimizerLoop*>(node))
2351     {
2352       if (_outputPort->getName() == "SmplPrt") _destructible = false;
2353     }
2354 }
2355
2356 SubjectOutputPort::~SubjectOutputPort()
2357 {
2358   DEBTRACE("SubjectOutputPort::~SubjectOutputPort " << getName());
2359 }
2360
2361 void SubjectOutputPort::clean()
2362 {
2363   localClean();
2364   SubjectDataPort::clean();
2365 }
2366
2367 void SubjectOutputPort::localClean()
2368 {
2369   DEBTRACE("SubjectOutputPort::localClean ");
2370   if (_parent)
2371     {
2372       SubjectElementaryNode* elem = dynamic_cast<SubjectElementaryNode*>(_parent);
2373       if (elem) elem->removePort(this);
2374     }
2375 }
2376
2377 // ----------------------------------------------------------------------------
2378
2379 SubjectInputDataStreamPort::SubjectInputDataStreamPort(YACS::ENGINE::InputDataStreamPort *port,
2380                                                        Subject *parent)
2381   : SubjectDataPort(port, parent), _inputDataStreamPort(port)
2382 {
2383 }
2384
2385 SubjectInputDataStreamPort::~SubjectInputDataStreamPort()
2386 {
2387   DEBTRACE("SubjectInputDataStreamPort::~SubjectInputDataStreamPort " << getName());
2388 }
2389
2390 std::map<std::string, std::string> SubjectInputDataStreamPort::getProperties()
2391 {
2392   return _inputDataStreamPort->getPropertyMap();
2393 }
2394
2395 bool SubjectInputDataStreamPort::setProperties(std::map<std::string, std::string> properties)
2396 {
2397   Proc *proc = GuiContext::getCurrent()->getProc();
2398   CommandSetDSPortProperties *command =
2399     new CommandSetDSPortProperties(proc->getChildName(getPort()->getNode()), getName(), true, properties);
2400   if (command->execute())
2401     {
2402       GuiContext::getCurrent()->getInvoc()->add(command);
2403       return true;
2404     }
2405   else delete command;
2406   return false;
2407 }
2408
2409 void SubjectInputDataStreamPort::clean()
2410 {
2411   localClean();
2412   SubjectDataPort::clean();
2413 }
2414
2415 void SubjectInputDataStreamPort::localClean()
2416 {
2417   DEBTRACE("SubjectInputDataStreamPort::localClean ");
2418 }
2419
2420 // ----------------------------------------------------------------------------
2421
2422 SubjectOutputDataStreamPort::SubjectOutputDataStreamPort(YACS::ENGINE::OutputDataStreamPort *port,
2423                                                          Subject *parent)
2424   : SubjectDataPort(port, parent), _outputDataStreamPort(port)
2425 {
2426 }
2427
2428 SubjectOutputDataStreamPort::~SubjectOutputDataStreamPort()
2429 {
2430   DEBTRACE("SubjectOutputDataStreamPort::~SubjectOutputDataStreamPort " << getName());
2431 }
2432
2433 std::map<std::string, std::string> SubjectOutputDataStreamPort::getProperties()
2434 {
2435   return _outputDataStreamPort->getPropertyMap();
2436 }
2437
2438 bool SubjectOutputDataStreamPort::setProperties(std::map<std::string, std::string> properties)
2439 {
2440   Proc *proc = GuiContext::getCurrent()->getProc();
2441   CommandSetDSPortProperties *command =
2442     new CommandSetDSPortProperties(proc->getChildName(getPort()->getNode()), getName(), false, properties);
2443   if (command->execute())
2444     {
2445       GuiContext::getCurrent()->getInvoc()->add(command);
2446       return true;
2447     }
2448   else delete command;
2449   return false;
2450 }
2451
2452 void SubjectOutputDataStreamPort::clean()
2453 {
2454   localClean();
2455   SubjectDataPort::clean();
2456 }
2457
2458 void SubjectOutputDataStreamPort::localClean()
2459 {
2460   DEBTRACE("SubjectOutputDataStreamPort::localClean ");
2461 }
2462
2463 // ----------------------------------------------------------------------------
2464
2465 SubjectLink::SubjectLink(SubjectNode* subOutNode,
2466                          SubjectDataPort* outPort,
2467                          SubjectNode* subInNode,
2468                          SubjectDataPort* inPort,
2469                          Subject *parent)
2470   : Subject(parent),
2471     _subOutNode(subOutNode), _outPort(outPort), _subInNode(subInNode), _inPort(inPort)
2472 {
2473   _name = "";
2474   ComposedNode *cla = ComposedNode::getLowestCommonAncestor(_subOutNode->getNode()->getFather(),
2475                                                             _subInNode->getNode()->getFather());
2476   DEBTRACE(_subOutNode->getName() << "." << _outPort->getName());
2477   DEBTRACE(_subInNode->getName() << "." << _inPort->getName());
2478   DEBTRACE(cla->getName());
2479   _name += cla->getChildName(_subOutNode->getNode());
2480   _name += "." + _outPort->getName();
2481   _name += "->";
2482   _name += cla->getChildName(_subInNode->getNode());
2483   _name += "." + _inPort->getName();
2484   DEBTRACE("SubjectLink::SubjectLink " << _name);
2485 }
2486
2487 SubjectLink::~SubjectLink()
2488 {
2489   DEBTRACE("SubjectLink::~SubjectLink " << getName());
2490 }
2491
2492 void SubjectLink::clean()
2493 {
2494   localClean();
2495   Subject::clean();
2496 }
2497
2498 void SubjectLink::localClean()
2499 {
2500   DEBTRACE("SubjectLink::localClean ");
2501   if (_parent)
2502     {
2503       DEBTRACE("clean link: " << _parent->getName() << " " << getName());
2504       SubjectComposedNode* father = dynamic_cast<SubjectComposedNode*>(_parent);
2505       assert(father);
2506       father->removeLink(this); // --- clean subjects first
2507       _cla = dynamic_cast<ComposedNode*>(father->getNode());
2508       assert(_cla);
2509       _outp = dynamic_cast<OutPort*>(_outPort->getPort());
2510       assert(_outp);
2511       _inp = dynamic_cast<InPort*>(_inPort->getPort());
2512       assert(_inp);
2513       if (isDestructible())
2514         _cla->edRemoveLink(_outp, _inp);
2515     }
2516 }
2517
2518 std::string SubjectLink::getName()
2519 {
2520   return _name;
2521 }
2522 // ----------------------------------------------------------------------------
2523
2524 SubjectControlLink::SubjectControlLink(SubjectNode* subOutNode,
2525                                        SubjectNode* subInNode,
2526                                        Subject *parent)
2527   : Subject(parent),
2528     _subOutNode(subOutNode), _subInNode(subInNode)
2529 {
2530   _name = "";
2531   ComposedNode *cla = ComposedNode::getLowestCommonAncestor(_subOutNode->getNode()->getFather(),
2532                                                             _subInNode->getNode()->getFather());
2533   DEBTRACE(_subOutNode->getName());
2534   DEBTRACE(_subInNode->getName());
2535   DEBTRACE(cla->getName());
2536   _name += cla->getChildName(_subOutNode->getNode());
2537   _name += "-->>";
2538   _name += cla->getChildName(_subInNode->getNode());
2539   DEBTRACE("SubjectControlLink::SubjectControlLink " << _name);
2540 }
2541
2542 SubjectControlLink::~SubjectControlLink()
2543 {
2544   DEBTRACE("SubjectControlLink::~SubjectControlLink " << getName());
2545   if (isDestructible())
2546     {
2547       try
2548         {
2549
2550           _cla->edRemoveCFLink(_subOutNode->getNode(), _subInNode->getNode());
2551         }
2552       catch (YACS::Exception &e)
2553         {
2554           DEBTRACE("------------------------------------------------------------------------------");
2555           DEBTRACE("SubjectControlLink::~SubjectControlLink: edRemoveLink YACS exception " << e.what());
2556           DEBTRACE("------------------------------------------------------------------------------");
2557         }
2558     }
2559 }
2560
2561 void SubjectControlLink::clean()
2562 {
2563   localClean();
2564   Subject::clean();
2565 }
2566
2567 void SubjectControlLink::localClean()
2568 {
2569   DEBTRACE("SubjectControlLink::localClean ");
2570   if (_parent)
2571     {
2572       DEBTRACE("clean control link: " << _parent->getName() << " " << getName());
2573       SubjectComposedNode* father = dynamic_cast<SubjectComposedNode*>(_parent);
2574       assert(father);
2575       father->removeControlLink(this); // --- clean subjects first
2576       _cla = dynamic_cast<ComposedNode*>(father->getNode());
2577       assert(_cla);
2578     }
2579 }
2580
2581 std::string SubjectControlLink::getName()
2582 {
2583   return _name;
2584 }
2585
2586 // ----------------------------------------------------------------------------
2587
2588 SubjectComponent::SubjectComponent(YACS::ENGINE::ComponentInstance* component, Subject *parent)
2589   : Subject(parent), _compoInst(component)
2590 {
2591   _compoInst->incrRef();
2592 }
2593
2594 SubjectComponent::~SubjectComponent()
2595 {
2596   Proc* aProc = GuiContext::getCurrent()->getProc();
2597   if ( aProc )
2598   {
2599     pair<string,int> key = pair<string,int>(_compoInst->getCompoName(),_compoInst->getNumId());
2600     aProc->componentInstanceMap.erase(key);
2601     
2602     std::map<std::string, ServiceNode*>::iterator it = aProc->serviceMap.begin();
2603     for ( ; it!=aProc->serviceMap.end(); it++ )
2604       if ( (*it).second->getComponent() == _compoInst )
2605         (*it).second->setComponent(0);
2606    
2607     GuiContext::getCurrent()->_mapOfSubjectComponent.erase(_compoInst);
2608     
2609     //if ( SalomeComponent* aSalomeCompo = static_cast<SalomeComponent*>(_compoInst) )
2610     //delete aSalomeCompo;
2611   }
2612   _compoInst->decrRef();
2613 }
2614
2615 void SubjectComponent::clean()
2616 {
2617   localClean();
2618   Subject::clean();
2619 }
2620
2621 void SubjectComponent::localClean()
2622 {
2623   DEBTRACE("SubjectComponent::localClean ");
2624 }
2625
2626 std::string SubjectComponent::getName()
2627 {
2628   DEBTRACE("SubjectComponent::getName()********************************************************************************");
2629   return _compoInst->getInstanceName();
2630 }
2631
2632 std::pair<std::string, int> SubjectComponent::getKey()
2633 {
2634   std::pair<std::string, int> key = std::pair<std::string, int>(_compoInst->getCompoName(), _compoInst->getNumId());
2635   return key;
2636 }
2637
2638 YACS::ENGINE::ComponentInstance* SubjectComponent::getComponent() const
2639 {
2640   return _compoInst;
2641 }
2642
2643 /*!
2644  *  When loading scheme from file, get the container associated to the component, if any,
2645  *  and create the corresponding subject.
2646  */
2647 void SubjectComponent::setContainer()
2648 {
2649   DEBTRACE("SubjectComponent::setContainer " << getName());
2650   Container* container = _compoInst->getContainer();
2651   if (container)
2652     {
2653       SubjectContainer *subContainer;
2654       if (GuiContext::getCurrent()->_mapOfSubjectContainer.find(container)
2655           ==
2656           GuiContext::getCurrent()->_mapOfSubjectContainer.end())
2657         subContainer = 
2658           GuiContext::getCurrent()->getSubjectProc()->addSubjectContainer(container, container->getName());
2659       else
2660         subContainer = GuiContext::getCurrent()->_mapOfSubjectContainer[container];
2661       addSubjectReference(subContainer);
2662     }
2663 }
2664
2665 void SubjectComponent::associateToContainer(SubjectContainer* subcont)
2666 {
2667   DEBTRACE("SubjectComponent::associateToContainer " << getName() << subcont->getName());
2668   CommandAssociateComponentToContainer *command =
2669     new CommandAssociateComponentToContainer(getKey(), subcont->getName());
2670   if (command->execute())
2671     {
2672       GuiContext::getCurrent()->getInvoc()->add(command);
2673       addSubjectReference(subcont);
2674     }
2675   else delete command;
2676 }
2677
2678 // ----------------------------------------------------------------------------
2679
2680 SubjectContainer::SubjectContainer(YACS::ENGINE::Container* container, Subject *parent)
2681   : Subject(parent), _container(container)
2682 {
2683 }
2684
2685 SubjectContainer::~SubjectContainer()
2686 {
2687   Proc* aProc = GuiContext::getCurrent()->getProc();
2688   if ( aProc )
2689   {
2690     aProc->containerMap.erase(_container->getName());
2691     
2692     map<ComponentInstance*,SubjectComponent*>::iterator it = GuiContext::getCurrent()->_mapOfSubjectComponent.begin();
2693     for ( ; it!=GuiContext::getCurrent()->_mapOfSubjectComponent.end(); it++ )
2694       if ( (*it).first && (*it).first->getContainer() == _container )
2695       {
2696         (*it).first->setContainer(0);
2697         GuiContext::getCurrent()->getSubjectProc()->destroy((*it).second);
2698       }
2699    
2700     GuiContext::getCurrent()->_mapOfSubjectContainer.erase(_container);
2701   }
2702 }
2703
2704 std::map<std::string, std::string> SubjectContainer::getProperties()
2705 {
2706   return _container->getProperties();
2707 }
2708
2709 bool SubjectContainer::setProperties(std::map<std::string, std::string> properties)
2710 {
2711   CommandSetContainerProperties *command = new CommandSetContainerProperties(getName(), properties);
2712   if (command->execute())
2713     {
2714       GuiContext::getCurrent()->getInvoc()->add(command);
2715       return true;
2716     }
2717   else delete command;
2718   return false;
2719 }
2720
2721 void SubjectContainer::clean()
2722 {
2723   localClean();
2724   Subject::clean();
2725 }
2726
2727 void SubjectContainer::localClean()
2728 {
2729   DEBTRACE("SubjectContainer::localClean ");
2730 }
2731
2732 std::string SubjectContainer::getName()
2733 {
2734   return _container->getName();
2735 }
2736
2737 YACS::ENGINE::Container* SubjectContainer::getContainer() const
2738 {
2739   return _container;
2740 }
2741
2742 // ----------------------------------------------------------------------------
2743
2744 SubjectDataType::SubjectDataType(YACS::ENGINE::TypeCode *typeCode, Subject *parent)
2745   : Subject(parent), _typeCode(typeCode)
2746 {
2747 }
2748
2749 SubjectDataType::~SubjectDataType()
2750 {
2751 }
2752
2753 void SubjectDataType::clean()
2754 {
2755   localClean();
2756   Subject::clean();
2757 }
2758
2759 void SubjectDataType::localClean()
2760 {
2761   DEBTRACE("SubjectDataType::localClean ");
2762 }
2763
2764 std::string SubjectDataType::getName()
2765 {
2766   return _typeCode->name();
2767 }
2768
2769 YACS::ENGINE::TypeCode* SubjectDataType::getTypeCode()
2770 {
2771   return _typeCode;
2772 }
2773
2774 // ----------------------------------------------------------------------------