Salome HOME
DCQ : Merge with Ecole_Ete_a6.
[modules/superv.git] / src / Supervision / StreamGraph_Impl.cxx
1 //  SUPERV Supervision : contains the implementation of interfaces of SuperVision described in SUPERV.idl
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : StreamGraph_Impl.cxx
25 //  Author : Jean Rahuel
26 //  Module : SUPERV
27 //  $Header: 
28
29 using namespace std;
30
31 #include "StreamGraph_Impl.hxx"
32
33 StreamGraph_Impl::StreamGraph_Impl( CORBA::ORB_ptr orb ,
34                                     PortableServer::POA_ptr poa ,
35                                     PortableServer::ObjectId * contId , 
36                                     const char *instanceName ,
37                                     const char *interfaceName ,
38                                     const char *aDataFlowName ) :
39   Graph_Impl(orb, poa, contId, instanceName, interfaceName, aDataFlowName , SUPERV::DataStreamGraph ) {
40 //  MESSAGE("StreamGraph_Impl::StreamGraph_Impl activate object instanceName("
41 //          << instanceName << ") interfaceName(" << interfaceName << ") --> "
42 //          << hex << (void *) this << dec )
43   beginService( "StreamGraph_Impl::StreamGraph_Impl" );
44   _thisObj = this ;
45   _id = _poa->activate_object(_thisObj);
46   _Orb = CORBA::ORB::_duplicate(orb);
47   _Poa = poa ;
48   _ContId = contId ;
49
50   endService( "StreamGraph_Impl::StreamGraph_Impl" );
51 }
52
53 StreamGraph_Impl::StreamGraph_Impl() {
54 }
55
56 StreamGraph_Impl::~StreamGraph_Impl() {
57   beginService( "StreamGraph_Impl::~StreamGraph_Impl" );
58   endService( "StreamGraph_Impl::~StreamGraph_Impl" );
59 }
60
61 void StreamGraph_Impl::destroy() {
62   beginService( "StreamGraph_Impl::destroy" );
63   _poa->deactivate_object(*_id) ;
64   CORBA::release(_poa) ;
65   delete(_id) ;
66   _thisObj->_remove_ref();
67   endService( "StreamGraph_Impl::destroy" );
68 }
69
70 SUPERV::StreamGraph_ptr StreamGraph_Impl::StreamCopy() {
71   beginService( "StreamGraph_Impl::StreamCopy" );
72   StreamGraph_Impl * myStreamGraph ;
73   myStreamGraph = new StreamGraph_Impl( _Orb , _Poa, _ContId,
74                                         instanceName() , interfaceName() ,
75                                         DataFlowEditor()->Graph()->Name() ) ;
76   PortableServer::ObjectId * id = myStreamGraph->getId() ;
77   CORBA::Object_var obj = _poa->id_to_reference(*id);
78   SUPERV::StreamGraph_var iobject ;
79   iobject = SUPERV::StreamGraph::_narrow(obj) ;
80   GraphBase::SGraph * aSGraph = GetGraph() ;
81   myStreamGraph->LoadGraph( aSGraph ) ;
82   endService( "StreamGraph_Impl::StreamCopy" );
83   return SUPERV::StreamGraph::_duplicate(iobject) ;
84 }
85
86 SUPERV::StreamLink_ptr StreamGraph_Impl::StreamLink(  SUPERV::StreamPort_ptr OutStreamPort ,
87                                                       SUPERV::StreamPort_ptr InStreamPort ) {
88   beginService( "StreamGraph_Impl::StreamLink" );
89   SUPERV::StreamLink_var iobject = SUPERV::StreamLink::_nil() ;
90   if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() &&
91        OutStreamPort->IsDataStream() && InStreamPort->IsDataStream() ) {
92     GraphBase::InPort * anInPort = DataFlowEditor()->GetNode( InStreamPort->Node()->Name() )->ComputingNode()->GetChangeInPort( InStreamPort->Name() ) ;
93     GraphBase::OutPort * anOutPort = DataFlowEditor()->GetNode( OutStreamPort->Node()->Name() )->ComputingNode()->GetChangeOutPort( OutStreamPort->Name() ) ;
94     if ( CORBA::is_nil( anOutPort->InPortObjRef( anInPort ) ) ) {
95       const char * DataFlowOutNodeName = OutStreamPort->Node()->Name() ;
96       GraphEditor::InNode * DataFlowOutNode = DataFlowEditor()->GetNode( DataFlowOutNodeName ) ;
97       const char * DataFlowInNodeName = InStreamPort->Node()->Name() ;
98       GraphEditor::InNode * DataFlowInNode = DataFlowEditor()->GetNode( DataFlowInNodeName ) ;
99       if ( DataFlowOutNode && DataFlowInNode ) {
100         bool Success ;
101         StreamLink_Impl * myStreamLink = new StreamLink_Impl( _Orb , _Poa , _ContId ,
102                                             instanceName() , interfaceName() ,
103                                             DataFlowEditor() ,
104                                             DataFlowInNode ,
105                                             InStreamPort->Name() ,
106                                             DataFlowOutNode ,
107                                             OutStreamPort->Name() ,
108                                             true , Success ) ;
109         if ( Success ) {
110           PortableServer::ObjectId * id = myStreamLink->getId() ;
111           CORBA::Object_var obj = _poa->id_to_reference(*id);
112           iobject = SUPERV::StreamLink::_narrow(obj) ;
113           anOutPort->AddInPortObjRef( anInPort , SUPERV::StreamLink::_duplicate(iobject) ) ;
114           DataFlowEditor()->UnValid() ;
115         }
116       }
117     }
118     else {
119       iobject = SUPERV::StreamLink::_narrow( anOutPort->InPortObjRef( anInPort ) ) ;
120     }
121   }
122   endService( "StreamGraph_Impl::StreamLink" );
123   return SUPERV::StreamLink::_duplicate(iobject) ;
124 }
125
126 SUPERV::ListOfStreamLinks * StreamGraph_Impl::GStreamLinks() {
127   return StreamLinks( NULL , NULL ) ;
128 }
129
130 SUPERV::ListOfStreamLinks * StreamGraph_Impl::StreamLinks( GraphBase::ComputingNode * theNode ,
131                                                            const char * anInputParam ) {
132   bool begin = true ;
133   SUPERV::ListOfStreamLinks_var RetVal = new SUPERV::ListOfStreamLinks ;
134   int i , j , countlink ;
135   countlink = 0 ;
136   for ( i = 0 ; i < DataFlowEditor()->Graph()->GraphNodesSize() ; i++ ) {
137     GraphEditor::InNode * aNode = NULL ;
138     aNode = (GraphEditor::InNode * ) DataFlowEditor()->Graph()->GraphNodes( i )->GetInNode() ;
139     bool ToProcess = false ;
140     if ( theNode == NULL ) {
141       ToProcess = true ;
142     }
143     else {
144       if ( !strcmp( theNode->Name() , aNode->Name() ) ) {
145         if ( !theNode->IsEndSwitchNode() ) {
146           ToProcess = true ;
147         }
148       }
149       else if ( theNode->IsEndSwitchNode() ) {
150         ToProcess = true ;
151       }
152     }
153     if ( ToProcess ) {
154       for ( j = 0 ; j < aNode->GetNodeInPortsSize() ; j++ ) {
155         GraphBase::InPort * anInPort = NULL ;
156         anInPort = aNode->GetChangeNodeInPort( j ) ;
157         if ( anInputParam == NULL ||
158              !strcmp( anInPort->PortName() , anInputParam ) ) {
159           GraphBase::OutPort * anOutPort = NULL ;
160           anOutPort = anInPort->GetOutPort() ;
161           if ( anOutPort && anOutPort->IsDataStream() ) {
162             if ( strcmp( anOutPort->NodeName() , Name() ) ) {
163               MESSAGE("StreamGraph_Impl::StreamLinks " << anOutPort->NodeName() << "("
164                       << anOutPort->PortName() << ") --> " << aNode->Name() << "("
165                       << anInPort->PortName() << ")" ) ;
166               if ( theNode == NULL ||
167                    ( theNode != NULL && !theNode->IsEndSwitchNode() &&
168                      !strcmp( theNode->Name() , aNode->Name() ) ) ) {
169                 if ( anInPort->IsLoop() || anOutPort->IsLoop() ||
170                      ( aNode->IsEndLoopNode() && !strcmp( aNode->CoupledNode()->Name() ,
171                                                           anOutPort->NodeName() ) ) ) {
172                   MESSAGE( "StreamLink " << anOutPort->NodeName() << "("
173                           << anOutPort->PortName() << ") --> " << aNode->Name() << "("
174                           << anInPort->PortName() << ")" << " ignored" ) ;
175                 }
176                 else if ( CORBA::is_nil( anOutPort->InPortObjRef( anInPort ) ) ) {
177                   if ( begin ) {
178                     beginService( "StreamGraph_Impl::StreamLinks" );
179                     begin = false ;
180                   }
181                   GraphEditor::InNode * anOutNode = NULL ;
182                   anOutNode = (GraphEditor::InNode * ) DataFlowEditor()->Graph()->GetChangeGraphNode( anOutPort->NodeName() )->GetInNode() ;
183                   if ( anOutNode ) {
184                     bool Success ;
185                     StreamLink_Impl * myStreamLink = new StreamLink_Impl(
186                                           _Orb , _Poa , _ContId ,
187                                           instanceName() , interfaceName() ,
188                                           DataFlowEditor() ,
189                                           aNode ,
190                                           anInPort->PortName() ,
191                                           anOutNode ,
192                                           anOutPort->PortName() ,
193                                           false , Success ) ;
194                     if ( Success ) {
195                       PortableServer::ObjectId * id = myStreamLink->getId() ;
196                       CORBA::Object_var obj = _poa->id_to_reference(*id);
197                       SUPERV::StreamLink_var iobject ;
198                       iobject = SUPERV::StreamLink::_narrow(obj) ;
199                       RetVal->length( countlink + 1 ) ;
200                       RetVal[ countlink++ ] = SUPERV::StreamLink::_duplicate( iobject ) ;
201                       anOutPort->AddInPortObjRef( anInPort , SUPERV::StreamLink::_duplicate( iobject ) ) ;
202                       MESSAGE( "Link" << countlink-1 << " "
203                                << RetVal[countlink-1]->OutStreamPort()->Node()->Name() << "("
204                                << RetVal[countlink-1]->OutStreamPort()->Name() << ") --> "
205                                << RetVal[countlink-1]->InStreamPort()->Node()->Name() << "("
206                                << RetVal[countlink-1]->InStreamPort()->Name() << ")" ) ;
207                     }
208                   }
209                 }
210                 else {
211                   RetVal->length( countlink + 1 ) ;
212                   RetVal[ countlink++ ] = SUPERV::StreamLink::_duplicate( SUPERV::StreamLink::_narrow( anOutPort->InPortObjRef( anInPort ) ) ) ;
213                   MESSAGE( "Link" << countlink-1 << " "
214                            << RetVal[countlink-1]->OutStreamPort()->Node()->Name() << "("
215                            << RetVal[countlink-1]->OutStreamPort()->Name() << ") --> "
216                            << RetVal[countlink-1]->InStreamPort()->Node()->Name() << "("
217                            << RetVal[countlink-1]->InStreamPort()->Name() << ")" ) ;
218                 }
219               }
220             }
221           }
222         }
223       }
224     }
225     for ( j = 0 ; j < aNode->GetNodeOutPortsSize() ; j++ ) {
226       GraphBase::OutPort * anOutPort = aNode->GetChangeNodeOutPort( j ) ;
227       int k ;
228       for ( k = 0 ; k < anOutPort->InPortsSize() ; k++ ) {
229         GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( k ) ;
230         GraphEditor::InNode * toNode = (GraphEditor::InNode * ) DataFlowEditor()->Graph()->GetChangeGraphNode( anInPort->NodeName() )->GetInNode() ;
231         if ( theNode == NULL ||
232              !strcmp( theNode->Name() , aNode->Name() ) ) {
233           if ( anInPort->IsDataStream() ) {
234             if ( theNode || ( toNode->IsEndSwitchNode() && !aNode->IsSwitchNode() ) ) {
235               if ( anInputParam == NULL ||
236                    !strcmp( anInPort->PortName() , anInputParam ) ) {
237                 MESSAGE( "StreamLink " << anOutPort->NodeName() << "("
238                          << anOutPort->PortName() << ") --> " << toNode->Name() << "("
239                          << anInPort->PortName() << ")" ) ;
240                 MESSAGE( "           IOR " << DataFlowEditor()->ObjectToString( anOutPort->InPortObjRef( anInPort ) ) ) ;
241                 if ( anInPort->IsLoop() || anOutPort->IsLoop() ||
242                      ( toNode->IsEndLoopNode() && !strcmp( toNode->CoupledNode()->Name() ,
243                                                            anOutPort->NodeName() ) ) ) {
244                   MESSAGE( "StreamLink " << anOutPort->NodeName() << "("
245                            << anOutPort->PortName() << ") --> " << toNode->Name() << "("
246                            << anInPort->PortName() << ")" << " ignored" ) ;
247                 }
248                 else if ( CORBA::is_nil( anOutPort->InPortObjRef( anInPort ) ) ) {
249                   if ( begin ) {
250                     beginService( "Graph_Impl::StreamLinks" );
251                     begin = false ;
252                   }
253                   bool Success ;
254                   StreamLink_Impl * myStreamLink = new StreamLink_Impl(
255                                         _Orb , _Poa , _ContId ,
256                                         instanceName() , interfaceName() ,
257                                         DataFlowEditor() ,
258                                         toNode ,
259                                         anInPort->PortName() ,
260                                         aNode ,
261                                         anOutPort->PortName() ,
262                                         false , Success ) ;
263                   if ( Success ) {
264                     PortableServer::ObjectId * id = myStreamLink->getId() ;
265                     CORBA::Object_var obj = _poa->id_to_reference(*id);
266                     SUPERV::StreamLink_var iobject ;
267                     iobject = SUPERV::StreamLink::_narrow(obj) ;
268                     RetVal->length( countlink + 1 ) ;
269                     RetVal[ countlink++ ] = SUPERV::StreamLink::_duplicate( iobject ) ;
270                     anOutPort->AddInPortObjRef( anInPort , SUPERV::StreamLink::_duplicate( iobject ) ) ;
271                     MESSAGE( "Link" << countlink-1 << " "
272                              << RetVal[countlink-1]->OutStreamPort()->Node()->Name() << "("
273                              << RetVal[countlink-1]->OutStreamPort()->Name() << ") --> "
274                              << RetVal[countlink-1]->InStreamPort()->Node()->Name() << "("
275                              << RetVal[countlink-1]->InStreamPort()->Name() << ")" ) ;
276                   }
277                 }
278                 else {
279                   RetVal->length( countlink + 1 ) ;
280                   RetVal[ countlink++ ] = SUPERV::StreamLink::_duplicate( SUPERV::StreamLink::_narrow( anOutPort->InPortObjRef( anInPort ) ) ) ;
281                   MESSAGE( "Link" << countlink-1 << " "
282                            << RetVal[countlink-1]->OutStreamPort()->Node()->Name() << "("
283                            << RetVal[countlink-1]->OutStreamPort()->Name() << ") --> "
284                            << RetVal[countlink-1]->InStreamPort()->Node()->Name() << "("
285                            << RetVal[countlink-1]->InStreamPort()->Name() << ")" ) ;
286                 }
287               }
288               else {
289                 MESSAGE( "StreamLink " << anOutPort->NodeName() << "("
290                          << anOutPort->PortName() << ") --> " << toNode->Name() << "("
291                          << anInPort->PortName() << ")" << " skipped" ) ;
292               }
293             }
294           }
295         }
296       }
297     }
298   }
299 //#if 0
300   const char * NodeName = "" ;
301   const char * InputParamName = "" ;
302   if ( theNode ) {
303     NodeName = theNode->Name() ;
304   }
305   if ( anInputParam ) {
306     InputParamName = anInputParam ;
307   }
308   MESSAGE( RetVal->length() << " StreamLinks of Node " << NodeName << " and of InPort " << InputParamName ) ;
309   for ( i = 0 ; i < (int ) RetVal->length() ; i++ ) {
310     MESSAGE( "Link" << i << " " << RetVal[i]->OutStreamPort()->Node()->Name() << "("
311              << RetVal[i]->OutStreamPort()->Name() << ") --> "
312              << RetVal[i]->InStreamPort()->Node()->Name() << "("
313              << RetVal[i]->InStreamPort()->Name() << ")" ) ;
314   }
315 //#endif
316   if ( !begin ) {
317     endService( "StreamGraph_Impl::StreamLinks" );
318   }
319   return ( RetVal._retn() ) ;
320 }
321
322 bool StreamGraph_Impl::SetStreamParams( const long Timeout ,
323                                         const SUPERV::KindOfDataStreamTrace DataStreamTrace ,
324                                         const double  DeltaTime ) {
325   bool sts = DataFlowEditor()->StreamGraph()->SetStreamParams( Timeout , DataStreamTrace , DeltaTime ) ;
326   if ( sts ) {
327     DataFlowEditor()->UnValid() ;
328   }
329   return sts ;
330 }
331
332 void StreamGraph_Impl::StreamParams( long & Timeout ,
333                                      SUPERV::KindOfDataStreamTrace & DataStreamTrace ,
334                                      double & DeltaTime ) {
335   DataFlowEditor()->StreamGraph()->StreamParams( Timeout , DataStreamTrace , DeltaTime ) ;
336 }
337
338 long StreamGraph_Impl::SubStreamGraphsNumber() {
339 //  beginService( "StreamGraph_Impl::StreamGraphsNumber" );
340   long RetVal = 0 ;
341   if ( DataFlowEditor()->IsExecutable() ) {
342     RetVal =  DataFlowEditor()->SubStreamGraphsNumber() ;
343   }
344 //  endService( "StreamGraph_Impl::SubStreamGraphsNumber" );
345   return RetVal ;
346 }
347
348 SUPERV::ListOfNodes * StreamGraph_Impl::SubStreamGraphsNodes( const long aSubStreamGraphNumber ) {
349   beginService( "StreamGraph_Impl::SubStreamGraphsNodes" );
350   SUPERV::ListOfNodes_var RetVal = new SUPERV::ListOfNodes ;
351   if ( DataFlowEditor()->IsEditing() ) {
352     SUPERV::ListOfNodes * aGraphNodes = Nodes() ;
353     int i ;
354 // ComputingNodes
355     for ( i = 0 ; i < (int ) aGraphNodes->CNodes.length() ; i++ ) {
356       SUPERV::CNode_var aNode = (aGraphNodes->CNodes)[ i ] ;
357       if ( aNode->SubStreamGraph() == aSubStreamGraphNumber ) {
358         RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
359       }
360     }
361 // FactoryNodes
362     for ( i = 0 ; i < (int ) aGraphNodes->FNodes.length() ; i++ ) {
363       SUPERV::FNode_var aNode = (aGraphNodes->FNodes)[ i ] ;
364       if ( aNode->SubStreamGraph() == aSubStreamGraphNumber ) {
365         RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
366       }
367     }
368 // InLineNodes
369     for ( i = 0 ; i < (int ) aGraphNodes->INodes.length() ; i++ ) {
370       SUPERV::INode_var aNode = (aGraphNodes->INodes)[ i ] ;
371       if ( aNode->SubStreamGraph() == aSubStreamGraphNumber ) {
372         RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
373       }
374     }
375 // GOTONodes
376     for ( i = 0 ; i < (int ) aGraphNodes->GNodes.length() ; i++ ) {
377       SUPERV::GNode_var aNode = (aGraphNodes->GNodes)[ i ] ;
378       if ( aNode->SubStreamGraph() == aSubStreamGraphNumber ) {
379         RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
380       }
381     }
382 // LoopNodes
383     for ( i = 0 ; i < (int ) aGraphNodes->LNodes.length() ; i++ ) {
384       SUPERV::LNode_var aNode = (aGraphNodes->LNodes)[ i ] ;
385       if ( aNode->SubStreamGraph() == aSubStreamGraphNumber ) {
386         RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
387       }
388     }
389 // EndLoopNodes
390     for ( i = 0 ; i < (int ) aGraphNodes->ELNodes.length() ; i++ ) {
391       SUPERV::ELNode_var aNode = (aGraphNodes->ELNodes)[ i ] ;
392       if ( aNode->SubStreamGraph() == aSubStreamGraphNumber ) {
393         RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
394       }
395     }
396 // SwitchNodes
397     for ( i = 0 ; i < (int ) aGraphNodes->SNodes.length() ; i++ ) {
398       SUPERV::SNode_var aNode = (aGraphNodes->SNodes)[ i ] ;
399       if ( aNode->SubStreamGraph() == aSubStreamGraphNumber ) {
400         RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
401       }
402     }
403 // EndSwitchNodes
404     for ( i = 0 ; i < (int ) aGraphNodes->ESNodes.length() ; i++ ) {
405       SUPERV::ESNode_var aNode = (aGraphNodes->ESNodes)[ i ] ;
406       if ( aNode->SubStreamGraph() == aSubStreamGraphNumber ) {
407         RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
408       }
409     }
410   }
411   endService( "StreamGraph_Impl::SubStreamGraphsNodes" );
412   return ( RetVal._retn() ) ;
413 }
414
415 SUPERV::Graph_ptr StreamGraph_Impl::ToFlowGraph() {
416   SUPERV::Graph_var iobject = SUPERV::Graph::_nil() ;
417   beginService( "StreamGraph_Impl::ToFlowGraph" );
418 //  Graph_Impl * myFlowGraph = new Graph_Impl( _Orb , _Poa , _ContId ,
419 //                                             instanceName() , interfaceName() ) ;
420 //  PortableServer::ObjectId * id = myFlowGraph->getId() ;
421 //  CORBA::Object_var obj = _poa->id_to_reference(*id);
422   if ( !CORBA::is_nil( DataFlowEditor()->StreamGraph()->ObjRef() ) ) {
423     iobject = SUPERV::Graph::_narrow( DataFlowEditor()->StreamGraph()->ObjRef() ) ;
424   }
425   endService( "StreamGraph_Impl::ToFlowGraph" );
426   return SUPERV::Graph::_duplicate( iobject ) ;
427 }
428
429 bool StreamGraph_Impl::StreamMerge(const SUPERV::StreamGraph_ptr aStreamGraph ) {
430   beginService( "StreamGraph_Impl::StreamMerge" );
431   map< string , int > aMapOfNodes ;
432   bool RetVal = Merge( aStreamGraph , aMapOfNodes ) ;
433   if ( RetVal ) {
434     SUPERV::ListOfStreamLinks * aGraphLinks = aStreamGraph->GStreamLinks() ;
435     SUPERV::ListOfStreamPorts * aGraphPorts = aStreamGraph->StreamPorts() ;
436     cout << "Graph_Impl::Merge " << aGraphLinks->length() << " links " << aGraphPorts->length() << " GraphPorts"
437          << endl ;
438     int i ;
439     for ( i = 0 ; i < (int ) aGraphLinks->length() ; i++ ) {
440       SUPERV::StreamLink_var aLink = (*aGraphLinks)[ i ] ;
441       SUPERV::StreamPort_var OutPort = aLink->OutStreamPort() ;
442       SUPERV::StreamPort_var InPort = aLink->InStreamPort() ;
443       string * aLinkFromNodeName = new string( OutPort->Node()->Name() ) ;
444       string * aLinkToNodeName = new string( InPort->Node()->Name() ) ;
445       cout << "Graph_Impl::Merge " << aLinkFromNodeName << "(" << OutPort->Name() << ") ---> "
446            << aLinkToNodeName << "(" << InPort->Name() << ")" << endl ;
447       RetVal = DataFlowEditor()->AddLink( DataFlowEditor()->Graph()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
448                                           OutPort->Name() ,
449                                           DataFlowEditor()->Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
450                                           InPort->Name() ) ;
451       cout << "Graph_Impl::Merge " << aLinkFromNodeName << "(" << OutPort->Name() << ") ---> "
452            << aLinkToNodeName << "(" << InPort->Name() << ") RetVal" << RetVal << endl ;
453       if ( RetVal ) {
454         int j ;
455         for ( j = 1 ; j <= aLink->CoordsSize() ; j++ ) {
456           long X , Y ;
457           RetVal = aLink->Coords( j , X , Y ) ;
458           if ( !RetVal )
459             break ;
460           RetVal = DataFlowEditor()->AddLinkCoord( DataFlowEditor()->Graph()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
461                                                    OutPort->Name() ,
462                                                    DataFlowEditor()->Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
463                                                    InPort->Name() ,
464                                                    j , X , Y ) ;
465           if ( !RetVal ) {
466             break ;
467           }
468         }
469       }
470       delete aLinkFromNodeName ;
471       delete aLinkToNodeName ;
472       if ( !RetVal ) {
473         break ;
474       }
475     }
476     if ( RetVal ) {
477       for ( i = 0 ; i < (int ) aGraphPorts->length() ; i++ ) {
478         SUPERV::StreamPort_var aPort = (*aGraphPorts)[ i ] ;
479         if ( !aPort->IsGate() ) {
480           MESSAGE( "Graph_Impl::Merge " << i << ". " << aPort->Node()->Name() << " " << aPort->Name() ) ;
481           char * aPortName = aPort->Name() ;
482           char * aNodeName = new char[ strlen( aPortName ) + 1 ] ;
483           strcpy( aNodeName , aPortName ) ;
484           char * thePortName = strchr( aNodeName , '\\' ) ;
485           thePortName[ 0 ] = '\0' ;
486           bool hasinput = aStreamGraph->Node( aNodeName )->Port( thePortName + 1 )->HasInput() ;
487 //          cout << "Graph_Impl::Merge " << " aNodeName " << aNodeName << " aPort " << thePortName + 1
488 //               << " HasInput " << hasinput << endl ;
489           if ( hasinput ) {
490             RetVal = DataFlowEditor()->AddInputData( DataFlowEditor()->StreamGraph()->GetGraphNode( aMapOfNodes[ aNodeName ] )->Name() ,
491                                                      thePortName + 1 ,
492                                                      *(aPort->ToAny()) ) ;
493           }
494           delete [] aNodeName ;
495           if ( !RetVal ) {
496             break ;
497           }
498         }
499       }
500     }
501   }
502   endService( "StreamGraph_Impl::StreamMerge" );
503   return RetVal ;
504 }
505