]> SALOME platform Git repositories - modules/yacs.git/blob - src/yacsloader/LoadState.cxx
Salome HOME
bb57af20fdbf662dfe04db10c7408c1d4248569c
[modules/yacs.git] / src / yacsloader / LoadState.cxx
1 // Copyright (C) 2006-2012  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
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 }
84
85
86 void stateParser::onStart (const XML_Char* elem, const xmlChar** p)
87 {
88   DEBTRACE("stateParser::onStart");
89   string element(elem);
90   stateParser *parser = 0;
91   if (element == "graphState") parser = new graphParser();
92   else
93     { 
94       _what = "expected <graphState>, got <" + element + ">";
95       _state = XMLFATALERROR;
96       stopParse(_what);
97     }
98   if (parser)
99     {
100       _stackParser.push(parser);
101       XML_SetUserData(_xmlParser, parser);
102       parser->init(p);
103     }
104 }
105
106
107 void stateParser::onEnd   (const XML_Char* name)
108 {
109   _stackState.pop();
110   _state = _stackState.top();
111   //cerr << "end " << name << " " << _stackParser.size() << " " << _state << endl;
112 }
113
114
115 void stateParser::charData(std::string data)
116 {
117   //cerr << "data " << data << endl;
118 }
119
120 // ----------------------------------------------------------------------------
121
122 void graphParser::init(const xmlChar** p, xmlParserBase* father)
123 {
124   //  DEBTRACE("graphParser::init()");
125   _state = XMLINGRAPH;
126   _father = father;
127   _stackState.push(_state);
128   if (p) getAttributes(p);
129 }
130
131 void graphParser::onStart (const XML_Char* elem, const xmlChar** p)
132 {
133   string element(elem);
134   stateParser *parser = 0;
135   if (element == "node") parser = new nodeParser();
136   else
137     { 
138       _what = "expected <node>, got <" + element + ">";
139       _state = XMLFATALERROR;
140       stopParse(_what);
141     }
142   if (parser)
143     {
144       _stackParser.push(parser);
145       XML_SetUserData(_xmlParser, parser);
146       parser->init(p, this);
147     }
148 }
149
150
151 void graphParser::onEnd   (const XML_Char* name)
152 {
153   std::map<std::string, YACS::StatesForNode>::const_iterator it;
154   for (it = _nodeStates.begin(); it != _nodeStates.end(); it++)
155     {
156       Node *node =0;
157       string nodeName = it->first;
158       DEBTRACE("nodeName = " << nodeName);
159       if(_p->getName() == nodeName)
160         node = _p;
161       else
162         node = _p->getChildByName(nodeName);
163
164       InGate* inGate = node->getInGate();
165       list<OutGate*> backlinks = inGate->getBackLinks();
166       for (list<OutGate*>::iterator io = backlinks.begin(); io != backlinks.end(); io++)
167         {
168           Node* fromNode = (*io)->getNode();
169           string fromName;
170           if (fromNode == _p) fromName = fromNode->getName();
171           else fromName = _p->getChildName(fromNode);
172           if (_nodeStates[fromName] == YACS::DONE)
173             {
174               DEBTRACE("   fromNode = " << fromName);
175               inGate->setPrecursorDone(*io);
176             }
177         }
178     }
179   stateParser::onEnd(name);
180 }
181
182 // ----------------------------------------------------------------------------
183
184 void nodeParser::init(const xmlChar** p, xmlParserBase* father)
185 {
186   DEBTRACE("nodeParser::init()");
187   _state = XMLINNODE;
188   _father = father;
189   _stackState.push(_state);
190   if (p) getAttributes(p);
191 }
192
193
194 void nodeParser::onStart (const XML_Char* elem, const xmlChar** p)
195 {
196   DEBTRACE("nodeParser::onStart" << elem);
197   string element(elem);
198   stateParser *parser = 0;
199   if (element == "inputPort")      parser = new portParser();
200   else if (element == "name")      parser = new attrParser();
201   else if (element == "state")     parser = new attrParser();
202   else if (element == "nsteps")    parser = new attrParser();
203   else if (element == "nbdone")    parser = new attrParser();
204   else if (element == "condition") parser = new attrParser();
205   else if (element == "inputPort") parser = new portParser();
206   else
207     { 
208       _what = "expected name, state or inputPort, got <" + element + ">";
209       _state = XMLFATALERROR;
210       stopParse(_what);
211     }
212   if (parser)
213     {
214       _stackParser.push(parser);
215       XML_SetUserData(_xmlParser, parser);
216       parser->init(p, this);
217     }
218 }
219
220 void nodeParser::onEnd   (const XML_Char* name)
221 {
222   string nodeName = _mapAttrib["name"];
223   string nodeType = _mapAttrib["type"];
224   string nodeState = _mapAttrib["state"];
225   DEBTRACE( "nodeName: " << nodeName << " nodeType: " << nodeType << " nodeState: " << nodeState );
226 //   for (std::map< std::string, Node * >::iterator it=_p->nodeMap.begin(); it != _p->nodeMap.end(); it++)
227 //     cerr << "nodeMap: " << it->first << endl;
228   _nodeStates[nodeName] = _nodeStateValue[nodeState];
229   Node *node =0;
230   if(_p->getName() == nodeName)
231     node=_p;
232   else 
233     node = _p->getChildByName(nodeName);
234
235   YASSERT(_nodeStateValue.find(nodeState) != _nodeStateValue.end());
236   YACS::ENGINE::StateLoader(node, _nodeStateValue[nodeState]);
237
238   if (nodeType == "forLoop")
239     {
240       if (_mapAttrib.find("nsteps") == _mapAttrib.end())
241         {
242           _what = "no attribute nsteps in forLoop " + _mapAttrib["name"];
243           _state = XMLFATALERROR;
244           stopParse(_what);
245         }
246       int nsteps =  atoi(_mapAttrib["nsteps"].c_str());
247
248       if (_mapAttrib.find("nbdone") == _mapAttrib.end())
249         {
250           _what = "no attribute nbdone in forLoop " + _mapAttrib["name"];
251           _state = XMLFATALERROR;
252           stopParse(_what);
253         }
254       int nbdone =  atoi(_mapAttrib["nbdone"].c_str());
255       DEBTRACE("nsteps = " << nsteps << ", nbdone = " << nbdone);
256
257       ForLoop* loop = dynamic_cast<ForLoop*>(node);
258       if (!loop)
259         {
260           _what = "node is not a ForLoop: " + _mapAttrib["name"];
261           _state = XMLFATALERROR;
262           stopParse(_what);
263         }
264       loop->edGetNbOfTimesInputPort()->edInit(nsteps);
265       YACS::ENGINE::NbDoneLoader(loop, nbdone);
266     }
267
268   else if (nodeType == "whileLoop")
269     {
270       if (_mapAttrib.find("nbdone") == _mapAttrib.end())
271         {
272           _what = "no attribute nbdone in forLoop " + _mapAttrib["name"];
273           _state = XMLFATALERROR;
274           stopParse(_what);
275         }
276       int nbdone =  atoi(_mapAttrib["nbdone"].c_str());
277
278       if (_mapAttrib.find("condition") == _mapAttrib.end())
279         {
280           _what = "no attribute condition in forLoop " + _mapAttrib["name"];
281           _state = XMLFATALERROR;
282           stopParse(_what);
283         }
284       bool condition =  atoi(_mapAttrib["condition"].c_str());
285       DEBTRACE("condition = " << condition << ", nbdone = " << nbdone);
286
287       WhileLoop* loop = dynamic_cast<WhileLoop*>(node);
288       if (!loop)
289         {
290           _what = "node is not a WhileLoop: " + _mapAttrib["name"];
291           _state = XMLFATALERROR;
292           stopParse(_what);
293         }
294       loop->edGetConditionPort()->edInit(condition);
295       YACS::ENGINE::NbDoneLoader(loop, nbdone);
296     }
297
298   else if (nodeType == "switch")
299     {
300       if (_mapAttrib.find("condition") == _mapAttrib.end())
301         {
302           _what = "no attribute condition in switch " + _mapAttrib["name"];
303           _state = XMLFATALERROR;
304           stopParse(_what);
305         }
306       int condition =  atoi(_mapAttrib["condition"].c_str());
307       DEBTRACE("condition = " << condition);
308
309       Switch* mySwitch = dynamic_cast<Switch*>(node);
310       if (!mySwitch)
311         {
312           _what = "node is not a Switch: " + _mapAttrib["name"];
313           _state = XMLFATALERROR;
314           stopParse(_what);
315         }
316       mySwitch->edGetConditionPort()->edInit(condition);
317     }
318
319   stateParser::onEnd(name);
320 }
321
322 // ----------------------------------------------------------------------------
323
324 void attrParser::init(const xmlChar** p, xmlParserBase* father)
325 {
326   DEBTRACE("attrParser::init()");
327   //_state = XMLINNODE;
328   _father = father;
329   _stackState.push(_state); // keep current state
330   if (p) getAttributes(p);
331 }
332
333
334 void attrParser::onStart (const XML_Char* elem, const xmlChar** p)
335 {
336   string element(elem);
337   _what = "expected nothing, got <" + element + ">";
338   _state = XMLFATALERROR;
339   stopParse(_what);
340 }
341
342 void attrParser::charData(std::string data)
343 {
344   _attrValue = data;
345 }
346
347 void attrParser::onEnd   (const XML_Char* name)
348 {
349   // cerr << "end attrParser " << name << " " << _stackParser.size() << endl;
350   YASSERT(_father);
351   _father->setAttribute((char*)name, _attrValue);
352   stateParser::onEnd(name);
353 }
354
355 // ----------------------------------------------------------------------------
356
357 void portParser::init(const xmlChar** p, xmlParserBase* father)
358 {
359   DEBTRACE("portParser::init()");
360   _state = XMLINPORT;
361   _father = father;
362   YASSERT( dynamic_cast<nodeParser*> (father));
363   _stackState.push(_state);
364   if (p) getAttributes(p);
365 }
366
367
368 void portParser::onStart (const XML_Char* elem, const xmlChar** p)
369 {
370   DEBTRACE("portParser::onStart" << elem);
371   string element(elem);
372   stateParser *parser = 0;
373   if      (element == "name")      parser = new attrParser();
374   else if (element == "value")     parser = new valueParser();
375   else
376     { 
377       _what = "expected name or value, got <" + element + ">";
378       _state = XMLFATALERROR;
379       stopParse(_what);
380     }
381   if (parser)
382     {
383       _stackParser.push(parser);
384       XML_SetUserData(_xmlParser, parser);
385       parser->init(p, this);
386     }
387 }
388
389 void portParser::addData(std::string value)
390 {
391   _data = value;
392 }
393
394 void portParser::onEnd   (const XML_Char* name)
395 {
396   DEBTRACE("portName: " << _mapAttrib["name"] << "value: " << _data );
397   string nodeName = _father->getAttribute("name");
398   string nodeType = _father->getAttribute("type");
399   Node *node = _p->getChildByName(nodeName);
400   if (nodeType == "elementaryNode")
401     {
402       ElementaryNode* eNode = dynamic_cast<ElementaryNode*>(node);
403       YASSERT(eNode);
404       InputPort *port = eNode->getInputPort(_mapAttrib["name"]);
405       if(_data != "")
406         port->edInit("XML",_data.c_str());
407     }
408   else if (nodeType == "forLoop")
409     {
410       string what="no way to set a port value on port " +  _mapAttrib["name"];
411       what += " in node " + nodeName + " of type " + nodeType;
412       throw Exception(what);
413     }
414   else if (nodeType == "whileLoop")
415     {
416       string what="no way to set a port value on port " +  _mapAttrib["name"];
417       what += " in node " + nodeName + " of type " + nodeType;
418       throw Exception(what);
419     }
420   else if (nodeType == "switch")
421     {
422       string what="no way to set a port value on port " +  _mapAttrib["name"];
423       what += " in node " + nodeName + " of type " + nodeType;
424       throw Exception(what);
425     }
426   else if (nodeType == "foreachLoop")
427     {
428       string what="no way to set a port value on port " +  _mapAttrib["name"];
429       what += " in node " + nodeName + " of type " + nodeType;
430       throw Exception(what);
431     }
432   else 
433     {
434       string what="no way to set a port value on port " +  _mapAttrib["name"];
435       what += " in node " + nodeName + " of type " + nodeType;
436       throw Exception(what);
437     }
438
439   stateParser::onEnd(name);
440 }
441
442 // ----------------------------------------------------------------------------
443
444 void valueParser::init(const xmlChar** p, xmlParserBase* father)
445 {
446   DEBTRACE("valueParser::init()");
447   _state = XMLINVALUE;
448   _father = father;
449   _stackState.push(_state);
450   if (p) getAttributes(p);
451 }
452
453
454 void valueParser::onStart (const XML_Char* elem, const xmlChar** p)
455 {
456   string element(elem);
457   DEBTRACE("value type " << element );
458   stateParser *parser = 0;
459   if      (element == "data")      parser = new dataParser();
460   else if (element == "array")     parser = new arrayParser();
461   else                             parser = new simpleTypeParser();
462   if (parser)
463     {
464       _stackParser.push(parser);
465       XML_SetUserData(_xmlParser, parser);
466       parser->init(p, this);
467     }
468 }
469
470 void valueParser::addData(std::string value)
471 {
472   _data = "<value>" + value + "</value>";
473 }
474
475 void valueParser::onEnd   (const XML_Char* name)
476 {
477   DEBTRACE( _data );
478   _father->addData(_data);
479   string elem = (char *) name;
480   //if (elem == "value" || elem == "data" || elem == "array")
481   stateParser::onEnd(name);
482   //else YASSERT(0); //DEBTRACE("valueParser::onEnd " << elem);
483 }
484
485 // ----------------------------------------------------------------------------
486
487 void arrayParser::init(const xmlChar** p, xmlParserBase* father)
488 {
489   DEBTRACE("arrayParser::init()");
490   _state = XMLINVALUE;
491   _father = father;
492   _stackState.push(_state);
493   if (p) getAttributes(p);
494 }
495
496
497 void arrayParser::onStart (const XML_Char* elem, const xmlChar** p)
498 {
499   string element(elem);
500   DEBTRACE("array type " << element);
501   stateParser *parser = 0;
502   if      (element == "data")      parser = new dataParser();
503   else
504     { 
505       _what = "expected data, got <" + element + ">";
506       _state = XMLFATALERROR;
507       stopParse(_what);
508     }
509   if (parser)
510     {
511       _stackParser.push(parser);
512       XML_SetUserData(_xmlParser, parser);
513       parser->init(p, this);
514     }
515 }
516
517 void arrayParser::addData(std::string value)
518 {
519   string val = "<array>" + value + "</array>";
520   _data = val;
521 }
522
523
524 void arrayParser::onEnd   (const XML_Char* name)
525 {
526   // cerr << "arrayParser::onEnd " << name << endl;
527   // cerr << _data << endl;
528   _father->addData(_data);
529   stateParser::onEnd(name);
530 }
531
532 // ----------------------------------------------------------------------------
533
534 void dataParser::init(const xmlChar** p, xmlParserBase* father)
535 {
536   DEBTRACE("dataParser::init()");
537   _state = XMLINVALUE;
538   _father = father;
539   _stackState.push(_state);
540   if (p) getAttributes(p);
541 }
542
543
544 void dataParser::onStart (const XML_Char* elem, const xmlChar** p)
545 {
546   string element(elem);
547   DEBTRACE("data type " << element );
548   stateParser *parser = 0;
549   if      (element == "value")      parser = new valueParser();
550   else
551     { 
552       _what = "expected value, 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 dataParser::addData(std::string value)
565 {
566   _dataList.push_back(value);
567 }
568
569 void dataParser::onEnd   (const XML_Char* name)
570 {
571   // cerr << "dataParser::onEnd " << name << endl;
572   string val = "<data>";
573   while (!_dataList.empty())
574     {
575       val += _dataList.front();
576       _dataList.pop_front();
577     }
578   val += "</data>";
579   // cerr << val << endl;
580   _father->addData(val);
581   stateParser::onEnd(name);
582 }
583
584 // ----------------------------------------------------------------------------
585
586 void simpleTypeParser::init(const xmlChar** p, xmlParserBase* father)
587 {
588   DEBTRACE("simpleTypeParser::init()");
589   _state = XMLINVALUE;
590   _father = father;
591   _stackState.push(_state);
592   if (p) getAttributes(p);
593 }
594
595 void simpleTypeParser::onStart (const XML_Char* elem, const xmlChar** p)
596 {
597   string element(elem);
598   _what = "expected nothing, got <" + element + ">";
599   _state = XMLFATALERROR;
600   stopParse(_what);
601 }
602
603 void simpleTypeParser::onEnd   (const XML_Char* name)
604 {
605   string val = string("<") + (char*) name + ">" + _data + "</"  + (char*) name +">";
606   DEBTRACE( val );
607   _father->addData(val);
608   stateParser::onEnd(name);
609 }
610
611 void simpleTypeParser::charData(std::string data)
612 {
613   _data = _data + data;
614 }
615
616
617
618 // ----------------------------------------------------------------------------
619
620 stateLoader::stateLoader(xmlParserBase* parser,
621                          YACS::ENGINE::Proc* p) : xmlReader(parser)
622 {
623   _runtime = getRuntime();
624   _p = p;
625 }
626
627 void stateLoader::parse(std::string xmlState)
628 {
629   DEBTRACE("stateLoader::parse");
630   stateParser *parser = dynamic_cast<stateParser*> (_rootParser);
631   parser->setProc(_p);
632   parser->setRuntime(_runtime);
633
634   xmlReader::parse(xmlState);
635
636   DEBTRACE(parser->_state);
637   switch (parser->_state)
638     {
639     case XMLNOCONTEXT:
640     case XMLDONE:
641       {
642         DEBTRACE("parse OK");
643         break;
644       }
645     case XMLFATALERROR:
646       {
647         string what = "Abort Parse: " + parser->_what;
648         throw Exception(what);
649         break;
650       }
651     default:
652       {
653         string what = "Abort Parse: unknown execution problem";
654         throw Exception(what);
655         break;
656       }
657     }
658 }
659
660 void YACS::ENGINE::loadState(YACS::ENGINE::Proc *p,const std::string& xmlStateFile)
661 {
662   DEBTRACE("YACS::ENGINE::loadState");
663   p->init();
664   p->exUpdateState();
665   stateParser* rootParser = new stateParser();
666   stateLoader myStateLoader(rootParser, p);
667   myStateLoader.parse(xmlStateFile);
668 }