]> SALOME platform Git repositories - modules/superv.git/blob - src/GraphBase/DataFlowBase_SwitchNode.cxx
Salome HOME
Error messages
[modules/superv.git] / src / GraphBase / DataFlowBase_SwitchNode.cxx
1 //  SUPERV GraphBase : contains fondamental classes for Services, Input Ports, Output Ports Links and Nodes.
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : DataFlowBase_SwitchNode.cxx
8 //  Author : Jean Rahuel, CEA
9 //  Module : SUPERV
10 //  $Header:
11
12 using namespace std;
13 //#include <sstream>
14 //#include <iostream>
15
16 #include "DataFlowBase_SwitchNode.hxx"
17 #include "DataFlowBase_EndOfSwitchNode.hxx"
18 #include "DataFlowBase_Graph.hxx"
19
20 GraphBase::SwitchNode::SwitchNode() :
21   GraphBase::GOTONode::GOTONode() {
22
23   cdebug << "GraphBase::SwitchNode::SwitchNode "  << this 
24          << " _Name " << (void *) Name() << " " << Name() << " _Comment "
25          << (void *) Comment() << " "  << Comment() << " "  << endl ;
26
27 }
28
29 GraphBase::SwitchNode::SwitchNode( CORBA::ORB_ptr ORB ,
30                                    SALOME_NamingService* ptrNamingService ,
31                                    const char * FuncName ,
32                                    const SUPERV::ListOfStrings & aPythonFunction ,
33                                    const char *NodeName ,
34                                    const SUPERV::KindOfNode akind ,
35                                    const SUPERV::SDate NodeFirstCreation ,
36                                    const SUPERV::SDate NodeLastModification  ,
37                                    const char * NodeEditorRelease ,
38                                    const char * NodeAuthor ,
39                                    const char * NodeComment ,
40                                    const bool   GeneratedName ,
41                                    const long   X ,
42                                    const long   Y ,
43                                    int * Graph_prof_debug ,
44                                    ofstream * Graph_fdebug ) :
45   GraphBase::GOTONode::GOTONode( ORB , ptrNamingService , FuncName , aPythonFunction ,
46                                  NodeName , akind , NodeFirstCreation ,
47                                  NodeLastModification  , NodeEditorRelease ,
48                                  NodeAuthor , NodeComment , GeneratedName ,
49                                  X , Y , Graph_prof_debug , Graph_fdebug ) {
50
51   cdebug_in << "GraphBase::SwitchNode::SwitchNode "  << this 
52             << "' _Name " << (void *) Name() << " '" << Name() << " _Comment "
53             << (void *) Comment() << " "  << Comment() << " " 
54             << " KindOfNode " << Kind() << " FuncName " << FuncName
55             << " ServiceName " << ServiceName() << " In("
56             << ServiceInParameter().length()
57             << ") Out(" << ServiceOutParameter().length() << ")" << endl ;
58
59   cdebug_out << "GraphBase::SwitchNode::SwitchNode" << endl;
60 }
61
62 GraphBase::SwitchNode::~SwitchNode() {
63   cdebug << "GraphBase::SwitchNode::~SwitchNode "  << this 
64          << " _Name " << (void *) Name() << " " << Name() << " _Comment "
65          << (void *) Comment() << " "  << Comment() << " "  << endl ;
66 //  if ( _ComponentName != NULLSTRING )
67 //    delete [] _ComponentName ;
68 //  delete [] _Name ;
69 //  delete [] _EditorRelease ;
70 //  if ( _Author != NULLSTRING )
71 //    delete [] _Author ;
72 //  if ( _Computer != FACTORYSERVER )
73 //    delete [] _Computer;
74 //  if ( _Comment != NULLSTRING )
75 //    delete [] _Comment;
76 }
77
78 bool GraphBase::SwitchNode::CheckSwitch() const {
79   GraphBase::EndOfSwitchNode * anEndSwitchNode ;
80   anEndSwitchNode = (GraphBase::EndOfSwitchNode * ) CoupledNode() ;
81   cdebug_in << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
82             << anEndSwitchNode->Name() << endl;
83   int i ;
84
85   string anErrorMessage = string( "SwitchCheck of " ) + string( Name() ) + " --> " +
86                           string( anEndSwitchNode->Name() ) + string( " :\n" ) ;
87   bool RetVal = true ;
88
89 //All nodes between Switch and EndSwitch will have _BranchOfSwitchDone to false
90 //When we have to execute such a node in a switchbranch, if _BranchOfSwitchDone is true we have
91 // an error ; else we set _BranchOfSwitchDone to true
92   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
93     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
94     if ( anOutPort->IsSwitch() || anOutPort->IsGate() ) {
95       int j ;
96       for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
97         GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( j ) ;
98         GraphBase::ComputingNode * aNode ;
99         aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
100         if ( aNode && aNode != anEndSwitchNode ) {
101           aNode->InitBranchOfSwitchDone( true , anEndSwitchNode , anErrorMessage ) ;
102         }
103       }
104     }
105   }
106
107   bool DefaultConnected = false ;
108 //OutPorts of the SwitchNode
109   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
110     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
111     if ( anOutPort->IsSwitch() || anOutPort->IsGate() ) {
112 // We have a branch of the switch
113       anErrorMessage = anErrorMessage + string( "Branch " ) + string( Name() ) + string( "( " ) +
114                        string( anOutPort->PortName() ) + string( " ) :\n" ) ;
115       cdebug << endl << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
116              << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
117              << " SWITCHBRANCH" << endl
118              << "===================================================================================="
119              << endl ;
120
121 //JR 11.02.2005 : if Default is not connected and if Default is true at execution time, the SwitchNode
122 // execution will be aborted
123 //Behavior : in that case, that means that a SwitchBranch should be a DefaultBranch and it is not the case !
124 //1. DEFAULT_OUTPORT
125 //JR 07.04.2005 Debug : an OutPort of the SwitchNode may be linked to the DefaultPort of
126 //                      the EndSwitchNode <==>
127 //                      SwitchNode( Default ) --> EndSwitchNode( Default )
128       bool EndSwitchNode_Default = false ;
129       if ( anOutPort->InPortsSize() ) {
130         GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( 0 ) ;
131         GraphBase::ComputingNode * aNode ;
132         aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
133         if ( aNode == anEndSwitchNode ) {
134           EndSwitchNode_Default = true ;
135         }
136       }
137 //JR 07.04.2005      if ( anOutPort->IsGate() ) {
138       if ( anOutPort->IsGate() || EndSwitchNode_Default ) {
139         if ( anOutPort->InPortsSize() == 0 ) {
140 // DefaultPort of the SwitchNode is not connected
141           cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
142                  << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName() << " "
143                  << anOutPort->InPortsSize() << " InPortsSize EndSwitch(Default) "
144                  << anEndSwitchNode->GetNodeInGate()->PortStatus() << "WARNING" << endl;
145         }
146         else {
147 // But the DefaultPort of the EndSwitchNode is connected : so there is a branch going to
148 // that DefaultPort
149           cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
150                  << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName() << " "
151                  << " " << anOutPort->PortStatus() << " " << anOutPort->InPortsSize() << " InPortsSize "
152                      << endl ;
153           DefaultConnected = true ;
154
155           anEndSwitchNode->InitEndSwitchInPortLinked() ;
156
157 // That DefaultBranch have to go directly to the EndSwitchNode
158           GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( 0 ) ;
159           GraphBase::ComputingNode * aNode ;
160           aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
161           if ( aNode != anEndSwitchNode ) {
162             anErrorMessage = anErrorMessage + string( Name() ) + "( " +
163                              string( anOutPort->PortName() ) +
164                              string( " ) should not be linked to " ) +
165                              string( aNode->Name() ) + string( "( " ) +
166                              string( anInPort->PortName() ) + string ( " )\n" ) ;
167             cdebug << "1. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
168                    << anEndSwitchNode->Name() << " for OutPort " << anOutPort->PortName()
169                    << " linked to " << aNode->Name() << " ERROR false" << endl;
170             RetVal = false ;
171           }
172           cdebug << endl << Name() << " Check of " << anOutPort->PortName() << " switch port branch"
173                  << " to EndSwitchNode" << endl ;
174 // All of InPorts of the EndSwitchNode have to be done :
175           int k ;
176           for ( k = 0 ; k < GetNodeOutPortsSize() ; k++ ) {
177             GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( k ) ;
178 //JR 06.07.2005 : the InGatePort must also be counted now (enhancement) ...
179 //                But it is done in EndSwitchNode::CheckEndSwitchInPortsLinked
180             if ( !anOutPort->IsGate() ) {
181               GraphBase::InPort * anInPort = NULL ;
182 //JR 22.06.2005 : Enhancement of the behaviour :
183 //                For the DefaultBranch, if we have same PortsNames, Values are automatically
184 //                    transmitted
185 //                But for the DefaultBranch, if we have NOT same PortsNames, we may create links.
186 //                Look at GraphSyrControlAve* ...
187               int kk ;
188 //JR 22.06.2005 : At first look at OutPorts linked to InPorts of the EndSwitchNode with
189 //                different PortsNames :
190               for ( kk = 0 ; kk < anOutPort->InPortsSize() ; kk++ ) {
191                 anInPort = anOutPort->ChangeInPorts( kk ) ;
192                 if ( GraphOfNode()->GetGraphNode( anInPort->NodeName() ) == anEndSwitchNode ) {
193                   if ( !anEndSwitchNode->GetChangeInPort( anOutPort->PortName() ) ) {
194                     if ( anInPort && !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ,
195                                                                                   anErrorMessage ) ) {
196                       cdebug << "2. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode : "
197                              << anEndSwitchNode->Name() << " to port " << anInPort->PortName()
198                              << " from port " << Name() << "( " << anOutPort->PortName()
199                              << " ) ERROR false" << endl;
200                       RetVal = false ;
201                     }
202                   }
203                 }
204               }
205 //Get an InPort of the EndSwitchNode with the same name as that OutPort of the SwitchNode
206               anInPort = anEndSwitchNode->GetChangeInPort( anOutPort->PortName() ) ;
207               if ( anInPort && !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ,
208                                                                             anErrorMessage ) ) {
209                 cdebug << "3. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
210                        << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
211                        << " ERROR false" << endl;
212                 RetVal = false ;
213               }
214               else {
215                 cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
216                        << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName()
217                        << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
218                        << " not in EndSwitchNode : IGNORED"
219                        << endl;
220               }
221 //JR 06.07.2005 : the InGatePort must also be counted now (enhancement) ...
222 //                But it is done in EndSwitchNode::CheckEndSwitchInPortsLinked
223             }
224             else {
225               cdebug << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
226                      << anEndSwitchNode->Name() << " OutPort " << anOutPort->PortName()
227                      << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
228                      << " SwitchPort or Gate : IGNORED"
229                      << endl;
230             }
231           }
232 // Check that all InPorts of the EndSwitchNode have a value :
233           if ( !anEndSwitchNode->CheckEndSwitchInPortsLinked( anErrorMessage ) ) {
234             cdebug << "4. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
235                    << anEndSwitchNode->Name() << " " << aNode->Name()
236                    << " ERROR false" << endl;
237             RetVal = false ;
238           }
239         }
240       }
241
242 //2. SWITCH_OUTPORT
243       else {
244 // We have a SwitchPort which is connected to Gates
245 // We initialize the _NodeDoneInBranchOfSwitch field to false for each node of the
246 // InPortsSize() branch(es)
247         int j ;
248         for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
249           GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( j ) ;
250           GraphBase::ComputingNode * aNode ;
251           aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
252           if ( aNode && aNode != anEndSwitchNode ) {
253             if ( !aNode->InitBranchOfSwitchDone( false , anEndSwitchNode , anErrorMessage ) ) {
254               anErrorMessage = anErrorMessage + string( Name() ) +
255                                string( " Node(s) are common to two or more branchs of switch.\n" ) ;
256               cdebug << "5. " << Name() << "->ComputingNode::InitBranchOfSwitchDone ERROR false"
257                      << " Node common to two or more branchs of switch" << endl ;
258               RetVal = false ;
259             }
260           }
261         }
262
263         anEndSwitchNode->InitEndSwitchInPortLinked() ;
264
265 // At first all of not SwitchPort should have to be done also :
266 // Not Switch Branches (Gate not connected to a switch port of a SwitchNode) :
267 // They are always executed except if we execute the DefaultBranch ...
268         
269         cdebug << "1. " << Name() << "->SwitchNode::CheckSwitch at first NOTSWITCHBRANCH_OUTPORT FOR "
270                << anOutPort->PortName() << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
271                << " :" << endl ;
272         for ( j = 0 ; j < GetNodeOutPortsSize() ; j++ ) {
273           GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( j ) ;
274           cdebug << Name() << "->SwitchNode::CheckSwitch for OutPort" << j << " "
275                  << anOutPort->PortName() << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
276                  << " InPortsSize " << anOutPort->InPortsSize() << endl ;
277           if ( !anOutPort->IsSwitch() && !anOutPort->IsGate() ) {
278 //JR 23.06.2005 : implicit connection with same PortsNames was missing in SwitchNodeBranches :
279             if ( anOutPort->IsExternConnected() ) {
280               GraphBase::InPort * anInPort ;
281               anInPort = anEndSwitchNode->GetChangeInPort( anOutPort->PortName() ) ;
282               if ( anInPort ) {
283                 anErrorMessage = anErrorMessage + string( "Implicit NotSwitchBranch " ) +
284                                  string( Name() ) + string( "( " ) + string( anOutPort->PortName() ) +
285                                  string( " ) --> " ) + string( anEndSwitchNode->Name() ) +
286                                  string( "( " ) + string( anInPort->PortName() ) + string( " ).\n" ) ;
287                 if ( !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ,
288                                                                   anErrorMessage ) ) {
289                   cdebug << "6. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
290                          << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
291                          << " ERROR false" << endl;
292                   RetVal = false ;
293                 }
294                 cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
295                        << anOutPort->PortName() << "' " << anOutPort->Kind()
296                        << " NOT switch port Branch to EndSwitchNode "
297                        << anEndSwitchNode->Name() << " is done" << endl ;
298               }
299               else {
300                 cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
301                        << anOutPort->PortName() << "' " << anOutPort->Kind()
302                        << " NOT switch port does not exist in EndSwitchNode. Ignoed " << endl ;
303               }
304             }
305             else {
306               int k ;
307               for ( k = 0 ; k < anOutPort->InPortsSize() ; k++ ) {
308                 GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( k ) ;
309                 GraphBase::ComputingNode * aNode ;
310                 aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
311                 if ( aNode ) {
312                   const GraphBase::InPort * anInGatePort = aNode->GetNodeInGate() ;
313                   cdebug << Name() << "->SwitchNode::CheckSwitch InPort" << k << ". "
314                          << anInPort->PortName() << " of " << aNode->Name() << " :" << endl ;
315 // Direct Connexion to the EndSwitchNode : always executed (except for DefaultBranch)
316                   if ( aNode == anEndSwitchNode ) {
317                     anErrorMessage = anErrorMessage + string( "NotSwitchBranch " ) + string( Name() ) +
318                                      string( "( " ) + string( anOutPort->PortName() ) +
319                                      string( " ) --> " ) + string( aNode->Name() ) +
320                                      string( "( " ) + string( anInPort->PortName() ) +
321                                      string( " ).\n" ) ;
322                     if ( !anEndSwitchNode->DecrEndSwitchInPortLinked( anInPort ,
323                                                                       anErrorMessage ) ) {
324                       cdebug << "7. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
325                              << anEndSwitchNode->Name() << " for port " << anInPort->PortName()
326                              << " ERROR false" << endl;
327                       RetVal = false ;
328                     }
329                     cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
330                            << anOutPort->PortName() << "' " << anOutPort->Kind()
331                            << " NOT switch port Branch to EndSwitchNode "
332                            << aNode->Name() << " is done" << endl ;
333                   }
334 // Check that InGate is not linked from a SwitchPort or a GatePort of the SwitchNode :
335                   else if ( !anInGatePort->GetOutPort() ) {
336                     cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
337                            << anOutPort->PortName() << "' " << anOutPort->Kind()
338                            << " NOT switch port Branch to node "
339                            << aNode->Name() << " will be done" << endl ;
340                     anErrorMessage = anErrorMessage + string( "NotSwitchBranch " ) + string( Name() ) +
341                                      string( "( " ) + string( anOutPort->PortName() ) +
342                                      string( " ) --> " ) + string( aNode->Name() ) +
343                                      string( "( " ) + string( anInPort->PortName() ) +
344                                      string( " ).\n" ) ;
345                     if ( !aNode->CheckSwitch( anEndSwitchNode , anErrorMessage ) ) {
346                       cdebug << "8. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
347                              << anEndSwitchNode->Name() << " " << aNode->Name()
348                              << " ERROR false" << endl;
349                       RetVal = false ;
350                     }
351                     cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
352                            << anOutPort->PortName() << "' " << anOutPort->Kind()
353                            << " NOT switch port Branch to node "
354                            << aNode->Name() << " is done" << endl ;
355                   }
356                   else {
357                     cdebug << Name() << "->SwitchNode::CheckSwitch Check of '"
358                            << anOutPort->PortName() << "' " << anOutPort->Kind()
359                            << " NOT switch port Branch to node "
360                            << aNode->Name() << " has InGate connected IGNORED for that branch"
361                            << endl ;
362                   }
363                 }
364               }
365             }
366           }
367         }
368
369         cdebug << "2. "<< Name() << "->SwitchNode::CheckSwitch and now SWITCH_BRANCH_OUTPORT "
370                << anOutPort->PortName()
371                << " " << anOutPort->PortStatus() << " " << anOutPort->Kind() << endl ;
372 // And all links from the switchport anOutPort (connected to Gates) will be checked
373         for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
374           GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( j ) ;
375           GraphBase::ComputingNode * aNode ;
376           aNode = GraphOfNode()->GetChangeGraphNode( anInPort->NodeName() ) ;
377           if ( aNode == NULL ) {
378             cdebug << Name() << "->SwitchNode::CheckSwitch Check of " << anOutPort->PortName()
379                    << " switch port branch "
380                    << aNode->Name() << " ignored" << endl ;
381           }
382
383
384           else {
385 // That branch does not go directly to the EndSwitchNode
386 // Control the OutPorts Values of the SwitchNode through the branch
387             cdebug << Name() << " Check of " << anOutPort->PortName()
388                    << " switch port Branch to node "
389                    << aNode->Name() << endl ;
390             if ( !aNode->CheckSwitch( anEndSwitchNode , anErrorMessage ) ) {
391               cdebug << "9. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
392                      << anEndSwitchNode->Name() << " " << aNode->Name() << " ERROR false"
393                      << endl;
394               RetVal = false ;
395             }
396           }
397         }
398 // Check that all InPorts of the EndSwitchNode have a value :
399         if ( !anEndSwitchNode->CheckEndSwitchInPortsLinked( anErrorMessage ) ) {
400           cdebug << "10. " << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
401                  << anEndSwitchNode->Name() << " CheckEndSwitchInPortsLinked ERROR false"
402                  << endl;
403           RetVal = false ;
404         }
405         else {
406           cdebug << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
407                  << " " << anOutPort->PortStatus() << " " << anOutPort->Kind()
408                  << " SWITCHBRANCH IS OK" << endl << endl ;
409         }
410       }
411     }
412     else {
413       cdebug << Name() << "->SwitchNode::CheckSwitch OutPort " << anOutPort->PortName()
414              << " " << anOutPort->PortStatus() << " " << anOutPort->Kind() << " NOTSWITCHBRANCH"
415              << " IGNORED" << endl ;
416     }
417   }
418
419   if ( !RetVal ) {
420     GraphOfNode()->SetMessages( anErrorMessage ) ;
421   }
422
423   cdebug_out << Name() << "->SwitchNode::CheckSwitch EndSwitchNode "
424              << anEndSwitchNode->Name() << " RetVal " << RetVal << endl;
425   return RetVal ;
426 }
427