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