1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "LoadState.hxx"
23 #include "ForLoop.hxx"
24 #include "WhileLoop.hxx"
27 #include "Runtime.hxx"
28 #include "InputPort.hxx"
29 #include "ElementaryNode.hxx"
30 #include "ForEachLoop.hxx"
32 #include "TypeConversions.hxx"
41 #include "YacsTrace.hxx"
43 using namespace YACS::ENGINE;
46 XMLReadState stateParser::_state;
47 std::string stateParser::_what;
48 std::stack<XMLReadState> stateParser::_stackState;
49 Proc* stateParser::_p;
50 Runtime* stateParser::_runtime;
51 std::map<std::string, YACS::StatesForNode> stateParser::_nodeStateValue;
52 std::map<std::string, YACS::StatesForNode> stateParser::_nodeStates;
54 // ----------------------------------------------------------------------------
55 void stateParser::setProc(Proc* p)
60 void stateParser::setRuntime(Runtime* runtime)
65 void stateParser::init(const xmlChar** p, xmlParserBase* father)
67 DEBTRACE("stateParser::init()");
68 _state = XMLNOCONTEXT;
70 _stackState.push(_state);
71 _nodeStateValue["READY"] =YACS::READY;
72 _nodeStateValue["TOLOAD"] =YACS::TOLOAD;
73 _nodeStateValue["LOADED"] =YACS::LOADED;
74 _nodeStateValue["TOACTIVATE"] =YACS::TOACTIVATE;
75 _nodeStateValue["ACTIVATED"] =YACS::ACTIVATED;
76 _nodeStateValue["DESACTIVATED"] =YACS::DESACTIVATED;
77 _nodeStateValue["DONE"] =YACS::DONE;
78 _nodeStateValue["SUSPENDED"] =YACS::SUSPENDED;
79 _nodeStateValue["LOADFAILED"] =YACS::LOADFAILED;
80 _nodeStateValue["EXECFAILED"] =YACS::EXECFAILED;
81 _nodeStateValue["PAUSE"] =YACS::PAUSE;
82 _nodeStateValue["INTERNALERR"] =YACS::INTERNALERR;
83 _nodeStateValue["DISABLED"] =YACS::DISABLED;
84 _nodeStateValue["FAILED"] =YACS::FAILED;
85 _nodeStateValue["ERROR"] =YACS::ERROR;
90 void stateParser::onStart (const XML_Char* elem, const xmlChar** p)
92 DEBTRACE("stateParser::onStart");
94 stateParser *parser = 0;
95 if (element == "graphState") parser = new graphParser();
98 _what = "expected <graphState>, got <" + element + ">";
99 _state = XMLFATALERROR;
104 _stackParser.push(parser);
105 XML_SetUserData(_xmlParser, parser);
111 void stateParser::onEnd (const XML_Char* name)
114 _state = _stackState.top();
115 //cerr << "end " << name << " " << _stackParser.size() << " " << _state << endl;
119 void stateParser::charData(std::string data)
121 //cerr << "data " << data << endl;
124 // ----------------------------------------------------------------------------
126 void graphParser::init(const xmlChar** p, xmlParserBase* father)
128 // DEBTRACE("graphParser::init()");
131 _stackState.push(_state);
132 if (p) getAttributes(p);
135 void graphParser::onStart (const XML_Char* elem, const xmlChar** p)
137 string element(elem);
138 stateParser *parser = 0;
139 if (element == "node") parser = new nodeParser();
142 _what = "expected <node>, got <" + element + ">";
143 _state = XMLFATALERROR;
148 _stackParser.push(parser);
149 XML_SetUserData(_xmlParser, parser);
150 parser->init(p, this);
155 void graphParser::onEnd (const XML_Char* name)
157 std::map<std::string, YACS::StatesForNode>::const_iterator it;
158 for (it = _nodeStates.begin(); it != _nodeStates.end(); it++)
161 string nodeName = it->first;
162 DEBTRACE("nodeName = " << nodeName);
163 if(_p->getName() == nodeName)
166 node = _p->getChildByName(nodeName);
168 InGate* inGate = node->getInGate();
169 list<OutGate*> backlinks = inGate->getBackLinks();
170 for (list<OutGate*>::iterator io = backlinks.begin(); io != backlinks.end(); io++)
172 Node* fromNode = (*io)->getNode();
174 if (fromNode == _p) fromName = fromNode->getName();
175 else fromName = _p->getChildName(fromNode);
176 if (_nodeStates[fromName] == YACS::DONE)
178 DEBTRACE(" fromNode = " << fromName);
179 inGate->setPrecursorDone(*io);
183 stateParser::onEnd(name);
186 // ----------------------------------------------------------------------------
188 class outputParser: public stateParser
191 virtual void init(const xmlChar** p, xmlParserBase* father=0)
193 //DEBTRACE("outputParser::init()");
194 _state = XMLNOCONTEXT;
196 YASSERT( dynamic_cast<nodeParser*> (father));
197 _stackState.push(_state);
198 if (p) getAttributes(p);
200 virtual void onStart (const XML_Char* elem, const xmlChar** p)
202 //DEBTRACE("outputParser::onStart" << elem);
203 string element(elem);
204 stateParser *parser = 0;
205 if (element == "name") parser = new attrParser();
206 else if (element == "value") parser = new valueParser();
209 _what = "expected name or value, got <" + element + ">";
210 _state = XMLFATALERROR;
215 _stackParser.push(parser);
216 XML_SetUserData(_xmlParser, parser);
217 parser->init(p, this);
220 virtual void onEnd (const XML_Char* name)
222 //DEBTRACE("outputParser::onEnd" << elem);
223 //DEBTRACE("portName: " << _mapAttrib["name"] << "value: " << _data );
224 stateParser::onEnd(name);
226 virtual void addData(std::string /*value*/)
228 //DEBTRACE("outputParser::addData" << elem);
232 // ----------------------------------------------------------------------------
234 void nodeParser::init(const xmlChar** p, xmlParserBase* father)
236 DEBTRACE("nodeParser::init()");
237 _loopSamples.clear();
240 _stackState.push(_state);
241 if (p) getAttributes(p);
245 void nodeParser::onStart (const XML_Char* elem, const xmlChar** p)
247 DEBTRACE("nodeParser::onStart" << elem);
248 string element(elem);
249 stateParser *parser = 0;
250 if (element == "inputPort") parser = new portParser();
251 else if (element == "name") parser = new attrParser();
252 else if (element == "state") parser = new attrParser();
253 else if (element == "nsteps") parser = new attrParser();
254 else if (element == "nbdone") parser = new attrParser();
255 else if (element == "condition") parser = new attrParser();
256 else if (element == "outputPort") parser = new outputParser();
257 else if (element == "loopOutputPort")
259 loopPortParser* sparser = new loopPortParser();
260 _loopSamples.push_back(sparser);
265 _what = "expected name, state or inputPort, got <" + element + ">";
266 _state = XMLFATALERROR;
271 _stackParser.push(parser);
272 XML_SetUserData(_xmlParser, parser);
273 parser->init(p, this);
277 void nodeParser::onEnd (const XML_Char* name)
279 string nodeName = _mapAttrib["name"];
280 string nodeType = _mapAttrib["type"];
281 string nodeState = _mapAttrib["state"];
282 DEBTRACE( "nodeName: " << nodeName << " nodeType: " << nodeType << " nodeState: " << nodeState );
283 // for (std::map< std::string, Node * >::iterator it=_p->nodeMap.begin(); it != _p->nodeMap.end(); it++)
284 // cerr << "nodeMap: " << it->first << endl;
285 _nodeStates[nodeName] = _nodeStateValue[nodeState];
287 if(_p->getName() == nodeName)
290 node = _p->getChildByName(nodeName);
292 YASSERT(_nodeStateValue.find(nodeState) != _nodeStateValue.end());
293 YACS::ENGINE::StateLoader(node, _nodeStateValue[nodeState]);
295 if (nodeType == "forLoop")
297 if (_mapAttrib.find("nsteps") == _mapAttrib.end())
299 _what = "no attribute nsteps in forLoop " + _mapAttrib["name"];
300 _state = XMLFATALERROR;
303 int nsteps = atoi(_mapAttrib["nsteps"].c_str());
305 if (_mapAttrib.find("nbdone") == _mapAttrib.end())
307 _what = "no attribute nbdone in forLoop " + _mapAttrib["name"];
308 _state = XMLFATALERROR;
311 int nbdone = atoi(_mapAttrib["nbdone"].c_str());
312 DEBTRACE("nsteps = " << nsteps << ", nbdone = " << nbdone);
314 ForLoop* loop = dynamic_cast<ForLoop*>(node);
317 _what = "node is not a ForLoop: " + _mapAttrib["name"];
318 _state = XMLFATALERROR;
321 loop->edGetNbOfTimesInputPort()->edInit(nsteps);
322 YACS::ENGINE::NbDoneLoader(loop, nbdone);
325 else if (nodeType == "whileLoop")
327 if (_mapAttrib.find("nbdone") == _mapAttrib.end())
329 _what = "no attribute nbdone in forLoop " + _mapAttrib["name"];
330 _state = XMLFATALERROR;
333 int nbdone = atoi(_mapAttrib["nbdone"].c_str());
335 if (_mapAttrib.find("condition") == _mapAttrib.end())
337 _what = "no attribute condition in forLoop " + _mapAttrib["name"];
338 _state = XMLFATALERROR;
341 bool condition = atoi(_mapAttrib["condition"].c_str());
342 DEBTRACE("condition = " << condition << ", nbdone = " << nbdone);
344 WhileLoop* loop = dynamic_cast<WhileLoop*>(node);
347 _what = "node is not a WhileLoop: " + _mapAttrib["name"];
348 _state = XMLFATALERROR;
351 loop->edGetConditionPort()->edInit(condition);
352 YACS::ENGINE::NbDoneLoader(loop, nbdone);
355 else if (nodeType == "switch")
357 if (_mapAttrib.find("condition") == _mapAttrib.end())
359 _what = "no attribute condition in switch " + _mapAttrib["name"];
360 _state = XMLFATALERROR;
363 int condition = atoi(_mapAttrib["condition"].c_str());
364 DEBTRACE("condition = " << condition);
366 Switch* mySwitch = dynamic_cast<Switch*>(node);
369 _what = "node is not a Switch: " + _mapAttrib["name"];
370 _state = XMLFATALERROR;
373 mySwitch->edGetConditionPort()->edInit(condition);
375 else if (nodeType == "forEachLoop")
377 ForEachLoop* feNode = dynamic_cast<ForEachLoop*>(node);
380 _what = "node is not a ForEachLoop: " + _mapAttrib["name"];
381 _state = XMLFATALERROR;
386 std::vector<unsigned int> passedIds;
387 std::vector<SequenceAny *> passedOutputs;
388 std::vector<std::string> nameOfOutputs;
389 bool firstPort = true;
390 std::list<loopPortParser*>::const_iterator itPort;
391 for(itPort=_loopSamples.begin(); itPort!=_loopSamples.end(); itPort++)
393 const std::string& portName =(*itPort)->getPortName();
394 nameOfOutputs.push_back(portName);
395 const YACS::ENGINE::TypeCode* tc = feNode->getOutputPortType(portName);
398 _what = "Impossible to find the type of the port " + portName;
399 _state = XMLFATALERROR;
403 unsigned int nbSamples = (*itPort)->getNbSamples();
404 SequenceAny* seqValues = SequenceAny::New(tc, nbSamples);
405 passedOutputs.push_back(seqValues);
406 for(unsigned int i = 0; i < nbSamples; i++)
408 unsigned int sampleId = (*itPort)->getSampleId(i);
409 const std::string& sampleData = (*itPort)->getSampleData(i);
410 Any* value = xmlToAny(sampleData, tc);
413 passedIds.push_back(sampleId);
414 seqValues->setEltAtRank(i, value);
418 unsigned int pos = 0;
419 while(pos < passedIds.size() && sampleId != passedIds[pos])
421 if(pos < passedIds.size())
422 seqValues->setEltAtRank(pos, value);
425 _what = "Inconsistent sample id in foreach node " + _mapAttrib["name"];
426 _state = XMLFATALERROR;
428 itPort=_loopSamples.end();
435 feNode->assignPassedResults(passedIds, passedOutputs, nameOfOutputs);
439 stateParser::onEnd(name);
442 Any* nodeParser::xmlToAny(const std::string& data, const YACS::ENGINE::TypeCode* tc)const
446 //YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(0);
447 YACS::ENGINE::Any *ob=NULL;
449 doc = xmlParseMemory(data.c_str(), data.length());
453 msg << "Problem in conversion: XML Document not parsed successfully ";
454 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
455 throw ConversionException(msg.str());
457 cur = xmlDocGetRootElement(doc);
462 msg << "Problem in conversion: empty XML Document";
463 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
464 throw ConversionException(msg.str());
468 if ((!xmlStrcmp(cur->name, (const xmlChar *)"value")))
470 ob=convertXmlNeutral(tc,doc,cur);
479 msg << "Problem in conversion: incorrect XML value";
480 msg << " (" << __FILE__ << ":" << __LINE__ << ")";
481 throw ConversionException(msg.str());
487 // ----------------------------------------------------------------------------
489 void attrParser::init(const xmlChar** p, xmlParserBase* father)
491 DEBTRACE("attrParser::init()");
492 //_state = XMLINNODE;
494 _stackState.push(_state); // keep current state
495 if (p) getAttributes(p);
499 void attrParser::onStart (const XML_Char* elem, const xmlChar** p)
501 string element(elem);
502 _what = "expected nothing, got <" + element + ">";
503 _state = XMLFATALERROR;
507 void attrParser::charData(std::string data)
512 void attrParser::onEnd (const XML_Char* name)
514 // cerr << "end attrParser " << name << " " << _stackParser.size() << endl;
516 _father->setAttribute((char*)name, _attrValue);
517 stateParser::onEnd(name);
520 // ----------------------------------------------------------------------------
522 void portParser::init(const xmlChar** p, xmlParserBase* father)
524 DEBTRACE("portParser::init()");
527 YASSERT( dynamic_cast<nodeParser*> (father));
528 _stackState.push(_state);
529 if (p) getAttributes(p);
533 void portParser::onStart (const XML_Char* elem, const xmlChar** p)
535 DEBTRACE("portParser::onStart" << elem);
536 string element(elem);
537 stateParser *parser = 0;
538 if (element == "name") parser = new attrParser();
539 else if (element == "value") parser = new valueParser();
542 _what = "expected name or value, got <" + element + ">";
543 _state = XMLFATALERROR;
548 _stackParser.push(parser);
549 XML_SetUserData(_xmlParser, parser);
550 parser->init(p, this);
554 void portParser::addData(std::string value)
559 void portParser::onEnd (const XML_Char* name)
561 DEBTRACE("portName: " << _mapAttrib["name"] << "value: " << _data );
562 string nodeName = _father->getAttribute("name");
563 string nodeType = _father->getAttribute("type");
564 Node *node = _p->getChildByName(nodeName);
565 if (nodeType == "elementaryNode")
567 ElementaryNode* eNode = dynamic_cast<ElementaryNode*>(node);
569 InputPort *port = eNode->getInputPort(_mapAttrib["name"]);
571 port->edInit("XML",_data.c_str());
573 else if (nodeType == "forLoop")
575 string what="no way to set a port value on port " + _mapAttrib["name"];
576 what += " in node " + nodeName + " of type " + nodeType;
577 throw Exception(what);
579 else if (nodeType == "whileLoop")
581 string what="no way to set a port value on port " + _mapAttrib["name"];
582 what += " in node " + nodeName + " of type " + nodeType;
583 throw Exception(what);
585 else if (nodeType == "switch")
587 string what="no way to set a port value on port " + _mapAttrib["name"];
588 what += " in node " + nodeName + " of type " + nodeType;
589 throw Exception(what);
591 else if (nodeType == "forEachLoop")
593 ForEachLoop* eNode = dynamic_cast<ForEachLoop*>(node);
595 InputPort *port = eNode->getInputPort(_mapAttrib["name"]);
597 port->edInit("XML",_data.c_str());
601 string what="no way to set a port value on port " + _mapAttrib["name"];
602 what += " in node " + nodeName + " of type " + nodeType;
603 throw Exception(what);
606 stateParser::onEnd(name);
609 // ----------------------------------------------------------------------------
611 void valueParser::init(const xmlChar** p, xmlParserBase* father)
613 DEBTRACE("valueParser::init()");
616 _stackState.push(_state);
617 if (p) getAttributes(p);
621 void valueParser::onStart (const XML_Char* elem, const xmlChar** p)
623 string element(elem);
624 DEBTRACE("value type " << element );
625 stateParser *parser = 0;
626 if (element == "data") parser = new dataParser();
627 else if (element == "array") parser = new arrayParser();
628 else parser = new simpleTypeParser();
631 _stackParser.push(parser);
632 XML_SetUserData(_xmlParser, parser);
633 parser->init(p, this);
637 void valueParser::addData(std::string value)
639 _data = "<value>" + value + "</value>";
642 void valueParser::onEnd (const XML_Char* name)
645 _father->addData(_data);
646 string elem = (char *) name;
647 //if (elem == "value" || elem == "data" || elem == "array")
648 stateParser::onEnd(name);
649 //else YASSERT(0); //DEBTRACE("valueParser::onEnd " << elem);
652 // ----------------------------------------------------------------------------
654 void arrayParser::init(const xmlChar** p, xmlParserBase* father)
656 DEBTRACE("arrayParser::init()");
659 _stackState.push(_state);
660 if (p) getAttributes(p);
664 void arrayParser::onStart (const XML_Char* elem, const xmlChar** p)
666 string element(elem);
667 DEBTRACE("array type " << element);
668 stateParser *parser = 0;
669 if (element == "data") parser = new dataParser();
672 _what = "expected data, got <" + element + ">";
673 _state = XMLFATALERROR;
678 _stackParser.push(parser);
679 XML_SetUserData(_xmlParser, parser);
680 parser->init(p, this);
684 void arrayParser::addData(std::string value)
686 string val = "<array>" + value + "</array>";
691 void arrayParser::onEnd (const XML_Char* name)
693 // cerr << "arrayParser::onEnd " << name << endl;
694 // cerr << _data << endl;
695 _father->addData(_data);
696 stateParser::onEnd(name);
699 // ----------------------------------------------------------------------------
701 void dataParser::init(const xmlChar** p, xmlParserBase* father)
703 DEBTRACE("dataParser::init()");
706 _stackState.push(_state);
707 if (p) getAttributes(p);
711 void dataParser::onStart (const XML_Char* elem, const xmlChar** p)
713 string element(elem);
714 DEBTRACE("data type " << element );
715 stateParser *parser = 0;
716 if (element == "value") parser = new valueParser();
719 _what = "expected value, got <" + element + ">";
720 _state = XMLFATALERROR;
725 _stackParser.push(parser);
726 XML_SetUserData(_xmlParser, parser);
727 parser->init(p, this);
731 void dataParser::addData(std::string value)
733 _dataList.push_back(value);
736 void dataParser::onEnd (const XML_Char* name)
738 // cerr << "dataParser::onEnd " << name << endl;
739 string val = "<data>";
740 while (!_dataList.empty())
742 val += _dataList.front();
743 _dataList.pop_front();
746 // cerr << val << endl;
747 _father->addData(val);
748 stateParser::onEnd(name);
751 // ----------------------------------------------------------------------------
753 void simpleTypeParser::init(const xmlChar** p, xmlParserBase* father)
755 DEBTRACE("simpleTypeParser::init()");
758 _stackState.push(_state);
759 if (p) getAttributes(p);
762 void simpleTypeParser::onStart (const XML_Char* elem, const xmlChar** p)
764 string element(elem);
765 _what = "expected nothing, got <" + element + ">";
766 _state = XMLFATALERROR;
770 void simpleTypeParser::onEnd (const XML_Char* name)
772 string val = string("<") + (char*) name + ">" + _data + "</" + (char*) name +">";
774 _father->addData(val);
775 stateParser::onEnd(name);
778 void simpleTypeParser::charData(std::string data)
780 _data = _data + data;
783 // ----------------------------------------------------------------------------
785 void loopPortParser::init(const xmlChar** p, xmlParserBase* father)
787 DEBTRACE("loopPortParser::init()");
788 //_state = XMLINPORT;
790 _stackState.push(_state);
793 if (p) getAttributes(p);
796 void loopPortParser::onStart(const XML_Char* elem, const xmlChar** p)
798 DEBTRACE("loopPortParser::onStart" << elem);
799 string element(elem);
800 stateParser *parser = 0;
801 if (element == "name") parser = new attrParser();
802 else if (element == "sample") parser = new sampleParser(this);
805 _what = "expected name or sample, got <" + element + ">";
806 _state = XMLFATALERROR;
811 _stackParser.push(parser);
812 XML_SetUserData(_xmlParser, parser);
813 parser->init(p, this);
817 void loopPortParser::onEnd(const XML_Char* name)
819 stateParser::onEnd(name);
822 void loopPortParser::charData(std::string data)
826 void loopPortParser::addSample(int index, const std::string data)
828 _ids.push_back(index);
829 _sampleData.push_back(data);
832 unsigned int loopPortParser::getNbSamples()const
837 unsigned int loopPortParser::getSampleId(unsigned int i)const
842 const std::string& loopPortParser::getSampleData(unsigned int i)const
844 return _sampleData[i];
847 const std::string& loopPortParser::getPortName()const
849 return _mapAttrib.at("name");
852 // ----------------------------------------------------------------------------
854 sampleParser::sampleParser(loopPortParser* father)
856 _sampleFather(father)
860 void sampleParser::init(const xmlChar** p, xmlParserBase* father)
862 DEBTRACE("sampleParser::init()");
863 //_state = XMLINPORT;
865 _stackState.push(_state);
866 if (p) getAttributes(p);
869 void sampleParser::onStart(const XML_Char* elem, const xmlChar** p)
871 DEBTRACE("sampleParser::onStart" << elem);
872 string element(elem);
873 stateParser *parser = 0;
874 if (element == "index") parser = new attrParser();
875 else if (element == "value") parser = new valueParser();
878 _what = "expected index or value, got <" + element + ">";
879 _state = XMLFATALERROR;
884 _stackParser.push(parser);
885 XML_SetUserData(_xmlParser, parser);
886 parser->init(p, this);
890 void sampleParser::onEnd(const XML_Char* name)
892 if (_mapAttrib.find("index") == _mapAttrib.end())
894 _what = "no attribute index in sample ";
895 _state = XMLFATALERROR;
898 int index = atoi(_mapAttrib["index"].c_str());
899 _sampleFather->addSample(index, _data);
900 stateParser::onEnd(name);
903 void sampleParser::charData(std::string data)
905 _data = _data + data;
908 // ----------------------------------------------------------------------------
910 stateLoader::stateLoader(xmlParserBase* parser,
911 YACS::ENGINE::Proc* p) : xmlReader(parser)
913 _runtime = getRuntime();
917 void stateLoader::parse(std::string xmlState)
919 DEBTRACE("stateLoader::parse");
920 stateParser *parser = dynamic_cast<stateParser*> (_rootParser);
922 parser->setRuntime(_runtime);
924 xmlReader::parse(xmlState);
926 DEBTRACE(parser->_state);
927 switch (parser->_state)
932 DEBTRACE("parse OK");
937 string what = "Abort Parse: " + parser->_what;
938 throw Exception(what);
943 string what = "Abort Parse: unknown execution problem";
944 throw Exception(what);
950 void YACS::ENGINE::loadState(YACS::ENGINE::Proc *p,const std::string& xmlStateFile)
952 DEBTRACE("YACS::ENGINE::loadState");
955 stateParser* rootParser = new stateParser();
956 stateLoader myStateLoader(rootParser, p);
957 myStateLoader.parse(xmlStateFile);