Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / yacsloader / LoadState.cxx
1 //  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "LoadState.hxx"
20 #include "Proc.hxx"
21 #include "Node.hxx"
22 #include "ForLoop.hxx"
23 #include "WhileLoop.hxx"
24 #include "Switch.hxx"
25 #include "InGate.hxx"
26 #include "Runtime.hxx"
27 #include "InputPort.hxx"
28 #include "ElementaryNode.hxx"
29
30 #include <iostream>
31 #include <string>
32 #include <cstdlib>
33 #include <cstdarg>
34 #include <cassert>
35
36 //#define _DEVDEBUG_
37 #include "YacsTrace.hxx"
38
39 using namespace YACS::ENGINE;
40 using namespace std;
41
42 XMLReadState    stateParser::_state;
43 std::string     stateParser::_what;
44 std::stack<XMLReadState> stateParser::_stackState;
45 Proc* stateParser::_p;
46 Runtime* stateParser::_runtime;
47 std::map<std::string, YACS::StatesForNode> stateParser::_nodeStateValue;
48 std::map<std::string, YACS::StatesForNode> stateParser::_nodeStates;
49
50 // ----------------------------------------------------------------------------
51 void stateParser::setProc(Proc* p)
52 {
53   _p= p;
54 }
55
56 void stateParser::setRuntime(Runtime* runtime)
57 {
58   _runtime = runtime;
59 }
60
61 void stateParser::init(const xmlChar** p, xmlParserBase* father)
62 {
63   DEBTRACE("stateParser::init()");
64   _state = XMLNOCONTEXT;
65   _father = father;
66   _stackState.push(_state);
67   _nodeStateValue["READY"] =YACS::READY;
68   _nodeStateValue["TOLOAD"] =YACS::TOLOAD;
69   _nodeStateValue["LOADED"] =YACS::LOADED;
70   _nodeStateValue["TOACTIVATE"] =YACS::TOACTIVATE;
71   _nodeStateValue["ACTIVATED"] =YACS::ACTIVATED;
72   _nodeStateValue["DESACTIVATED"] =YACS::DESACTIVATED;
73   _nodeStateValue["DONE"] =YACS::DONE;
74   _nodeStateValue["SUSPENDED"] =YACS::SUSPENDED;
75   _nodeStateValue["LOADFAILED"] =YACS::LOADFAILED;
76   _nodeStateValue["EXECFAILED"] =YACS::EXECFAILED;
77   _nodeStateValue["PAUSE"] =YACS::PAUSE;
78   _nodeStateValue["INTERNALERR"] =YACS::INTERNALERR;
79   _nodeStateValue["DISABLED"] =YACS::DISABLED;
80   _nodeStateValue["FAILED"] =YACS::FAILED;
81   _nodeStateValue["ERROR"] =YACS::ERROR;
82 }
83
84
85 void stateParser::onStart (const XML_Char* elem, const xmlChar** p)
86 {
87   DEBTRACE("stateParser::onStart");
88   string element(elem);
89   stateParser *parser = 0;
90   if (element == "graphState") parser = new graphParser();
91   else
92     { 
93       _what = "expected <graphState>, got <" + element + ">";
94       _state = XMLFATALERROR;
95       stopParse(_what);
96     }
97   if (parser)
98     {
99       _stackParser.push(parser);
100       XML_SetUserData(_xmlParser, parser);
101       parser->init(p);
102     }
103 }
104
105
106 void stateParser::onEnd   (const XML_Char* name)
107 {
108   _stackState.pop();
109   _state = _stackState.top();
110   //cerr << "end " << name << " " << _stackParser.size() << " " << _state << endl;
111 }
112
113
114 void stateParser::charData(std::string data)
115 {
116   //cerr << "data " << data << endl;
117 }
118
119 // ----------------------------------------------------------------------------
120
121 void graphParser::init(const xmlChar** p, xmlParserBase* father)
122 {
123   //  DEBTRACE("graphParser::init()");
124   _state = XMLINGRAPH;
125   _father = father;
126   _stackState.push(_state);
127   if (p) getAttributes(p);
128 }
129
130 void graphParser::onStart (const XML_Char* elem, const xmlChar** p)
131 {
132   string element(elem);
133   stateParser *parser = 0;
134   if (element == "node") parser = new nodeParser();
135   else
136     { 
137       _what = "expected <node>, got <" + element + ">";
138       _state = XMLFATALERROR;
139       stopParse(_what);
140     }
141   if (parser)
142     {
143       _stackParser.push(parser);
144       XML_SetUserData(_xmlParser, parser);
145       parser->init(p, this);
146     }
147 }
148
149
150 void graphParser::onEnd   (const XML_Char* name)
151 {
152   std::map<std::string, YACS::StatesForNode>::const_iterator it;
153   for (it = _nodeStates.begin(); it != _nodeStates.end(); it++)
154     {
155       Node *node =0;
156       string nodeName = it->first;
157       DEBTRACE("nodeName = " << nodeName);
158       if(_p->getName() == nodeName)
159         node = _p;
160       else
161         node = _p->getChildByName(nodeName);
162
163       InGate* inGate = node->getInGate();
164       list<OutGate*> backlinks = inGate->getBackLinks();
165       for (list<OutGate*>::iterator io = backlinks.begin(); io != backlinks.end(); io++)
166         {
167           Node* fromNode = (*io)->getNode();
168           string fromName;
169           if (fromNode == _p) fromName = fromNode->getName();
170           else fromName = _p->getChildName(fromNode);
171           if (_nodeStates[fromName] == YACS::DONE)
172             {
173               DEBTRACE("   fromNode = " << fromName);
174               inGate->setPrecursorDone(*io);
175             }
176         }
177     }
178   stateParser::onEnd(name);
179 }
180
181 // ----------------------------------------------------------------------------
182
183 void nodeParser::init(const xmlChar** p, xmlParserBase* father)
184 {
185   DEBTRACE("nodeParser::init()");
186   _state = XMLINNODE;
187   _father = father;
188   _stackState.push(_state);
189   if (p) getAttributes(p);
190 }
191
192
193 void nodeParser::onStart (const XML_Char* elem, const xmlChar** p)
194 {
195   DEBTRACE("nodeParser::onStart" << elem);
196   string element(elem);
197   stateParser *parser = 0;
198   if (element == "inputPort")      parser = new portParser();
199   else if (element == "name")      parser = new attrParser();
200   else if (element == "state")     parser = new attrParser();
201   else if (element == "nsteps")    parser = new attrParser();
202   else if (element == "nbdone")    parser = new attrParser();
203   else if (element == "condition") parser = new attrParser();
204   else if (element == "inputPort") parser = new portParser();
205   else
206     { 
207       _what = "expected name, state or inputPort, got <" + element + ">";
208       _state = XMLFATALERROR;
209       stopParse(_what);
210     }
211   if (parser)
212     {
213       _stackParser.push(parser);
214       XML_SetUserData(_xmlParser, parser);
215       parser->init(p, this);
216     }
217 }
218
219 void nodeParser::onEnd   (const XML_Char* name)
220 {
221   string nodeName = _mapAttrib["name"];
222   string nodeType = _mapAttrib["type"];
223   string nodeState = _mapAttrib["state"];
224   DEBTRACE( "nodeName: " << nodeName << " nodeType: " << nodeType << " nodeState: " << nodeState );
225 //   for (std::map< std::string, Node * >::iterator it=_p->nodeMap.begin(); it != _p->nodeMap.end(); it++)
226 //     cerr << "nodeMap: " << it->first << endl;
227   _nodeStates[nodeName] = _nodeStateValue[nodeState];
228   Node *node =0;
229   if(_p->getName() == nodeName)
230     node=_p;
231   else 
232     node = _p->getChildByName(nodeName);
233
234   assert(_nodeStateValue.find(nodeState) != _nodeStateValue.end());
235   YACS::ENGINE::StateLoader(node, _nodeStateValue[nodeState]);
236
237   if (nodeType == "forLoop")
238     {
239       if (_mapAttrib.find("nsteps") == _mapAttrib.end())
240         {
241           _what = "no attribute nsteps in forLoop " + _mapAttrib["name"];
242           _state = XMLFATALERROR;
243           stopParse(_what);
244         }
245       int nsteps =  atoi(_mapAttrib["nsteps"].c_str());
246
247       if (_mapAttrib.find("nbdone") == _mapAttrib.end())
248         {
249           _what = "no attribute nbdone in forLoop " + _mapAttrib["name"];
250           _state = XMLFATALERROR;
251           stopParse(_what);
252         }
253       int nbdone =  atoi(_mapAttrib["nbdone"].c_str());
254       DEBTRACE("nsteps = " << nsteps << ", nbdone = " << nbdone);
255
256       ForLoop* loop = dynamic_cast<ForLoop*>(node);
257       if (!loop)
258         {
259           _what = "node is not a ForLoop: " + _mapAttrib["name"];
260           _state = XMLFATALERROR;
261           stopParse(_what);
262         }
263       loop->edGetNbOfTimesInputPort()->edInit(nsteps);
264       YACS::ENGINE::NbDoneLoader(loop, nbdone);
265     }
266
267   else if (nodeType == "whileLoop")
268     {
269       if (_mapAttrib.find("nbdone") == _mapAttrib.end())
270         {
271           _what = "no attribute nbdone in forLoop " + _mapAttrib["name"];
272           _state = XMLFATALERROR;
273           stopParse(_what);
274         }
275       int nbdone =  atoi(_mapAttrib["nbdone"].c_str());
276
277       if (_mapAttrib.find("condition") == _mapAttrib.end())
278         {
279           _what = "no attribute condition in forLoop " + _mapAttrib["name"];
280           _state = XMLFATALERROR;
281           stopParse(_what);
282         }
283       bool condition =  atoi(_mapAttrib["condition"].c_str());
284       DEBTRACE("condition = " << condition << ", nbdone = " << nbdone);
285
286       WhileLoop* loop = dynamic_cast<WhileLoop*>(node);
287       if (!loop)
288         {
289           _what = "node is not a WhileLoop: " + _mapAttrib["name"];
290           _state = XMLFATALERROR;
291           stopParse(_what);
292         }
293       loop->edGetConditionPort()->edInit(condition);
294       YACS::ENGINE::NbDoneLoader(loop, nbdone);
295     }
296
297   else if (nodeType == "switch")
298     {
299       if (_mapAttrib.find("condition") == _mapAttrib.end())
300         {
301           _what = "no attribute condition in switch " + _mapAttrib["name"];
302           _state = XMLFATALERROR;
303           stopParse(_what);
304         }
305       int condition =  atoi(_mapAttrib["condition"].c_str());
306       DEBTRACE("condition = " << condition);
307
308       Switch* mySwitch = dynamic_cast<Switch*>(node);
309       if (!mySwitch)
310         {
311           _what = "node is not a Switch: " + _mapAttrib["name"];
312           _state = XMLFATALERROR;
313           stopParse(_what);
314         }
315       mySwitch->edGetConditionPort()->edInit(condition);
316     }
317
318   stateParser::onEnd(name);
319 }
320
321 // ----------------------------------------------------------------------------
322
323 void attrParser::init(const xmlChar** p, xmlParserBase* father)
324 {
325   DEBTRACE("attrParser::init()");
326   //_state = XMLINNODE;
327   _father = father;
328   _stackState.push(_state); // keep current state
329   if (p) getAttributes(p);
330 }
331
332
333 void attrParser::onStart (const XML_Char* elem, const xmlChar** p)
334 {
335   string element(elem);
336   _what = "expected nothing, got <" + element + ">";
337   _state = XMLFATALERROR;
338   stopParse(_what);
339 }
340
341 void attrParser::charData(std::string data)
342 {
343   _attrValue = data;
344 }
345
346 void attrParser::onEnd   (const XML_Char* name)
347 {
348   // cerr << "end attrParser " << name << " " << _stackParser.size() << endl;
349   assert(_father);
350   _father->setAttribute((char*)name, _attrValue);
351   stateParser::onEnd(name);
352 }
353
354 // ----------------------------------------------------------------------------
355
356 void portParser::init(const xmlChar** p, xmlParserBase* father)
357 {
358   DEBTRACE("portParser::init()");
359   _state = XMLINPORT;
360   _father = father;
361   assert( dynamic_cast<nodeParser*> (father));
362   _stackState.push(_state);
363   if (p) getAttributes(p);
364 }
365
366
367 void portParser::onStart (const XML_Char* elem, const xmlChar** p)
368 {
369   DEBTRACE("portParser::onStart" << elem);
370   string element(elem);
371   stateParser *parser = 0;
372   if      (element == "name")      parser = new attrParser();
373   else if (element == "value")     parser = new valueParser();
374   else
375     { 
376       _what = "expected name or value, got <" + element + ">";
377       _state = XMLFATALERROR;
378       stopParse(_what);
379     }
380   if (parser)
381     {
382       _stackParser.push(parser);
383       XML_SetUserData(_xmlParser, parser);
384       parser->init(p, this);
385     }
386 }
387
388 void portParser::addData(std::string value)
389 {
390   _data = value;
391 }
392
393 void portParser::onEnd   (const XML_Char* name)
394 {
395   DEBTRACE("portName: " << _mapAttrib["name"] << "value: " << _data );
396   string nodeName = _father->getAttribute("name");
397   string nodeType = _father->getAttribute("type");
398   Node *node = _p->getChildByName(nodeName);
399   if (nodeType == "elementaryNode")
400     {
401       ElementaryNode* eNode = dynamic_cast<ElementaryNode*>(node);
402       assert(eNode);
403       InputPort *port = eNode->getInputPort(_mapAttrib["name"]);
404       if(_data != "")
405         port->edInit("XML",_data.c_str());
406     }
407   else if (nodeType == "forLoop")
408     {
409       string what="no way to set a port value on port " +  _mapAttrib["name"];
410       what += " in node " + nodeName + " of type " + nodeType;
411       throw Exception(what);
412     }
413   else if (nodeType == "whileLoop")
414     {
415       string what="no way to set a port value on port " +  _mapAttrib["name"];
416       what += " in node " + nodeName + " of type " + nodeType;
417       throw Exception(what);
418     }
419   else if (nodeType == "switch")
420     {
421       string what="no way to set a port value on port " +  _mapAttrib["name"];
422       what += " in node " + nodeName + " of type " + nodeType;
423       throw Exception(what);
424     }
425   else if (nodeType == "foreachLoop")
426     {
427       string what="no way to set a port value on port " +  _mapAttrib["name"];
428       what += " in node " + nodeName + " of type " + nodeType;
429       throw Exception(what);
430     }
431   else 
432     {
433       string what="no way to set a port value on port " +  _mapAttrib["name"];
434       what += " in node " + nodeName + " of type " + nodeType;
435       throw Exception(what);
436     }
437
438   stateParser::onEnd(name);
439 }
440
441 // ----------------------------------------------------------------------------
442
443 void valueParser::init(const xmlChar** p, xmlParserBase* father)
444 {
445   DEBTRACE("valueParser::init()");
446   _state = XMLINVALUE;
447   _father = father;
448   _stackState.push(_state);
449   if (p) getAttributes(p);
450 }
451
452
453 void valueParser::onStart (const XML_Char* elem, const xmlChar** p)
454 {
455   string element(elem);
456   DEBTRACE("value type " << element );
457   stateParser *parser = 0;
458   if      (element == "data")      parser = new dataParser();
459   else if (element == "array")     parser = new arrayParser();
460   else                             parser = new simpleTypeParser();
461   if (parser)
462     {
463       _stackParser.push(parser);
464       XML_SetUserData(_xmlParser, parser);
465       parser->init(p, this);
466     }
467 }
468
469 void valueParser::addData(std::string value)
470 {
471   _data = "<value>" + value + "</value>";
472 }
473
474 void valueParser::onEnd   (const XML_Char* name)
475 {
476   DEBTRACE( _data );
477   _father->addData(_data);
478   string elem = (char *) name;
479   //if (elem == "value" || elem == "data" || elem == "array")
480   stateParser::onEnd(name);
481   //else assert(0); //DEBTRACE("valueParser::onEnd " << elem);
482 }
483
484 // ----------------------------------------------------------------------------
485
486 void arrayParser::init(const xmlChar** p, xmlParserBase* father)
487 {
488   DEBTRACE("arrayParser::init()");
489   _state = XMLINVALUE;
490   _father = father;
491   _stackState.push(_state);
492   if (p) getAttributes(p);
493 }
494
495
496 void arrayParser::onStart (const XML_Char* elem, const xmlChar** p)
497 {
498   string element(elem);
499   DEBTRACE("array type " << element);
500   stateParser *parser = 0;
501   if      (element == "data")      parser = new dataParser();
502   else
503     { 
504       _what = "expected data, got <" + element + ">";
505       _state = XMLFATALERROR;
506       stopParse(_what);
507     }
508   if (parser)
509     {
510       _stackParser.push(parser);
511       XML_SetUserData(_xmlParser, parser);
512       parser->init(p, this);
513     }
514 }
515
516 void arrayParser::addData(std::string value)
517 {
518   string val = "<array>" + value + "</array>";
519   _data = val;
520 }
521
522
523 void arrayParser::onEnd   (const XML_Char* name)
524 {
525   // cerr << "arrayParser::onEnd " << name << endl;
526   // cerr << _data << endl;
527   _father->addData(_data);
528   stateParser::onEnd(name);
529 }
530
531 // ----------------------------------------------------------------------------
532
533 void dataParser::init(const xmlChar** p, xmlParserBase* father)
534 {
535   DEBTRACE("dataParser::init()");
536   _state = XMLINVALUE;
537   _father = father;
538   _stackState.push(_state);
539   if (p) getAttributes(p);
540 }
541
542
543 void dataParser::onStart (const XML_Char* elem, const xmlChar** p)
544 {
545   string element(elem);
546   DEBTRACE("data type " << element );
547   stateParser *parser = 0;
548   if      (element == "value")      parser = new valueParser();
549   else
550     { 
551       _what = "expected value, got <" + element + ">";
552       _state = XMLFATALERROR;
553       stopParse(_what);
554     }
555   if (parser)
556     {
557       _stackParser.push(parser);
558       XML_SetUserData(_xmlParser, parser);
559       parser->init(p, this);
560     }
561 }
562
563 void dataParser::addData(std::string value)
564 {
565   _dataList.push_back(value);
566 }
567
568 void dataParser::onEnd   (const XML_Char* name)
569 {
570   // cerr << "dataParser::onEnd " << name << endl;
571   string val = "<data>";
572   while (!_dataList.empty())
573     {
574       val += _dataList.front();
575       _dataList.pop_front();
576     }
577   val += "</data>";
578   // cerr << val << endl;
579   _father->addData(val);
580   stateParser::onEnd(name);
581 }
582
583 // ----------------------------------------------------------------------------
584
585 void simpleTypeParser::init(const xmlChar** p, xmlParserBase* father)
586 {
587   DEBTRACE("simpleTypeParser::init()");
588   _state = XMLINVALUE;
589   _father = father;
590   _stackState.push(_state);
591   if (p) getAttributes(p);
592 }
593
594 void simpleTypeParser::onStart (const XML_Char* elem, const xmlChar** p)
595 {
596   string element(elem);
597   _what = "expected nothing, got <" + element + ">";
598   _state = XMLFATALERROR;
599   stopParse(_what);
600 }
601
602 void simpleTypeParser::onEnd   (const XML_Char* name)
603 {
604   string val = string("<") + (char*) name + ">" + _data + "</"  + (char*) name +">";
605   DEBTRACE( val );
606   _father->addData(val);
607   stateParser::onEnd(name);
608 }
609
610 void simpleTypeParser::charData(std::string data)
611 {
612   _data = _data + data;
613 }
614
615
616
617 // ----------------------------------------------------------------------------
618
619 stateLoader::stateLoader(xmlParserBase* parser,
620                          YACS::ENGINE::Proc* p) : xmlReader(parser)
621 {
622   _runtime = getRuntime();
623   _p = p;
624 }
625
626 void stateLoader::parse(std::string xmlState)
627 {
628   DEBTRACE("stateLoader::parse");
629   stateParser *parser = dynamic_cast<stateParser*> (_rootParser);
630   parser->setProc(_p);
631   parser->setRuntime(_runtime);
632
633   xmlReader::parse(xmlState);
634
635   DEBTRACE(parser->_state);
636   switch (parser->_state)
637     {
638     case XMLNOCONTEXT:
639     case XMLDONE:
640       {
641         DEBTRACE("parse OK");
642         break;
643       }
644     case XMLFATALERROR:
645       {
646         string what = "Abort Parse: " + parser->_what;
647         throw Exception(what);
648         break;
649       }
650     default:
651       {
652         string what = "Abort Parse: unknown execution problem";
653         throw Exception(what);
654         break;
655       }
656     }
657 }
658
659 void YACS::ENGINE::loadState(YACS::ENGINE::Proc *p,const std::string& xmlStateFile)
660 {
661   DEBTRACE("YACS::ENGINE::loadState");
662   p->init();
663   p->exUpdateState();
664   stateParser* rootParser = new stateParser();
665   stateLoader myStateLoader(rootParser, p);
666   myStateLoader.parse(xmlStateFile);
667 }