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 string what="no way to set a port value on port " + _mapAttrib["name"];
594 what += " in node " + nodeName + " of type " + nodeType;
595 throw Exception(what);
599 string what="no way to set a port value on port " + _mapAttrib["name"];
600 what += " in node " + nodeName + " of type " + nodeType;
601 throw Exception(what);
604 stateParser::onEnd(name);
607 // ----------------------------------------------------------------------------
609 void valueParser::init(const xmlChar** p, xmlParserBase* father)
611 DEBTRACE("valueParser::init()");
614 _stackState.push(_state);
615 if (p) getAttributes(p);
619 void valueParser::onStart (const XML_Char* elem, const xmlChar** p)
621 string element(elem);
622 DEBTRACE("value type " << element );
623 stateParser *parser = 0;
624 if (element == "data") parser = new dataParser();
625 else if (element == "array") parser = new arrayParser();
626 else parser = new simpleTypeParser();
629 _stackParser.push(parser);
630 XML_SetUserData(_xmlParser, parser);
631 parser->init(p, this);
635 void valueParser::addData(std::string value)
637 _data = "<value>" + value + "</value>";
640 void valueParser::onEnd (const XML_Char* name)
643 _father->addData(_data);
644 string elem = (char *) name;
645 //if (elem == "value" || elem == "data" || elem == "array")
646 stateParser::onEnd(name);
647 //else YASSERT(0); //DEBTRACE("valueParser::onEnd " << elem);
650 // ----------------------------------------------------------------------------
652 void arrayParser::init(const xmlChar** p, xmlParserBase* father)
654 DEBTRACE("arrayParser::init()");
657 _stackState.push(_state);
658 if (p) getAttributes(p);
662 void arrayParser::onStart (const XML_Char* elem, const xmlChar** p)
664 string element(elem);
665 DEBTRACE("array type " << element);
666 stateParser *parser = 0;
667 if (element == "data") parser = new dataParser();
670 _what = "expected data, got <" + element + ">";
671 _state = XMLFATALERROR;
676 _stackParser.push(parser);
677 XML_SetUserData(_xmlParser, parser);
678 parser->init(p, this);
682 void arrayParser::addData(std::string value)
684 string val = "<array>" + value + "</array>";
689 void arrayParser::onEnd (const XML_Char* name)
691 // cerr << "arrayParser::onEnd " << name << endl;
692 // cerr << _data << endl;
693 _father->addData(_data);
694 stateParser::onEnd(name);
697 // ----------------------------------------------------------------------------
699 void dataParser::init(const xmlChar** p, xmlParserBase* father)
701 DEBTRACE("dataParser::init()");
704 _stackState.push(_state);
705 if (p) getAttributes(p);
709 void dataParser::onStart (const XML_Char* elem, const xmlChar** p)
711 string element(elem);
712 DEBTRACE("data type " << element );
713 stateParser *parser = 0;
714 if (element == "value") parser = new valueParser();
717 _what = "expected value, got <" + element + ">";
718 _state = XMLFATALERROR;
723 _stackParser.push(parser);
724 XML_SetUserData(_xmlParser, parser);
725 parser->init(p, this);
729 void dataParser::addData(std::string value)
731 _dataList.push_back(value);
734 void dataParser::onEnd (const XML_Char* name)
736 // cerr << "dataParser::onEnd " << name << endl;
737 string val = "<data>";
738 while (!_dataList.empty())
740 val += _dataList.front();
741 _dataList.pop_front();
744 // cerr << val << endl;
745 _father->addData(val);
746 stateParser::onEnd(name);
749 // ----------------------------------------------------------------------------
751 void simpleTypeParser::init(const xmlChar** p, xmlParserBase* father)
753 DEBTRACE("simpleTypeParser::init()");
756 _stackState.push(_state);
757 if (p) getAttributes(p);
760 void simpleTypeParser::onStart (const XML_Char* elem, const xmlChar** p)
762 string element(elem);
763 _what = "expected nothing, got <" + element + ">";
764 _state = XMLFATALERROR;
768 void simpleTypeParser::onEnd (const XML_Char* name)
770 string val = string("<") + (char*) name + ">" + _data + "</" + (char*) name +">";
772 _father->addData(val);
773 stateParser::onEnd(name);
776 void simpleTypeParser::charData(std::string data)
778 _data = _data + data;
781 // ----------------------------------------------------------------------------
783 void loopPortParser::init(const xmlChar** p, xmlParserBase* father)
785 DEBTRACE("loopPortParser::init()");
786 //_state = XMLINPORT;
788 _stackState.push(_state);
791 if (p) getAttributes(p);
794 void loopPortParser::onStart(const XML_Char* elem, const xmlChar** p)
796 DEBTRACE("loopPortParser::onStart" << elem);
797 string element(elem);
798 stateParser *parser = 0;
799 if (element == "name") parser = new attrParser();
800 else if (element == "sample") parser = new sampleParser(this);
803 _what = "expected name or sample, got <" + element + ">";
804 _state = XMLFATALERROR;
809 _stackParser.push(parser);
810 XML_SetUserData(_xmlParser, parser);
811 parser->init(p, this);
815 void loopPortParser::onEnd(const XML_Char* name)
817 stateParser::onEnd(name);
820 void loopPortParser::charData(std::string data)
824 void loopPortParser::addSample(int index, const std::string data)
826 _ids.push_back(index);
827 _sampleData.push_back(data);
830 unsigned int loopPortParser::getNbSamples()const
835 unsigned int loopPortParser::getSampleId(unsigned int i)const
840 const std::string& loopPortParser::getSampleData(unsigned int i)const
842 return _sampleData[i];
845 const std::string& loopPortParser::getPortName()const
847 return _mapAttrib.at("name");
850 // ----------------------------------------------------------------------------
852 sampleParser::sampleParser(loopPortParser* father)
854 _sampleFather(father)
858 void sampleParser::init(const xmlChar** p, xmlParserBase* father)
860 DEBTRACE("sampleParser::init()");
861 //_state = XMLINPORT;
863 _stackState.push(_state);
864 if (p) getAttributes(p);
867 void sampleParser::onStart(const XML_Char* elem, const xmlChar** p)
869 DEBTRACE("sampleParser::onStart" << elem);
870 string element(elem);
871 stateParser *parser = 0;
872 if (element == "index") parser = new attrParser();
873 else if (element == "value") parser = new valueParser();
876 _what = "expected index or value, got <" + element + ">";
877 _state = XMLFATALERROR;
882 _stackParser.push(parser);
883 XML_SetUserData(_xmlParser, parser);
884 parser->init(p, this);
888 void sampleParser::onEnd(const XML_Char* name)
890 if (_mapAttrib.find("index") == _mapAttrib.end())
892 _what = "no attribute index in sample ";
893 _state = XMLFATALERROR;
896 int index = atoi(_mapAttrib["index"].c_str());
897 _sampleFather->addSample(index, _data);
898 stateParser::onEnd(name);
901 void sampleParser::charData(std::string data)
903 _data = _data + data;
906 // ----------------------------------------------------------------------------
908 stateLoader::stateLoader(xmlParserBase* parser,
909 YACS::ENGINE::Proc* p) : xmlReader(parser)
911 _runtime = getRuntime();
915 void stateLoader::parse(std::string xmlState)
917 DEBTRACE("stateLoader::parse");
918 stateParser *parser = dynamic_cast<stateParser*> (_rootParser);
920 parser->setRuntime(_runtime);
922 xmlReader::parse(xmlState);
924 DEBTRACE(parser->_state);
925 switch (parser->_state)
930 DEBTRACE("parse OK");
935 string what = "Abort Parse: " + parser->_what;
936 throw Exception(what);
941 string what = "Abort Parse: unknown execution problem";
942 throw Exception(what);
948 void YACS::ENGINE::loadState(YACS::ENGINE::Proc *p,const std::string& xmlStateFile)
950 DEBTRACE("YACS::ENGINE::loadState");
953 stateParser* rootParser = new stateParser();
954 stateLoader myStateLoader(rootParser, p);
955 myStateLoader.parse(xmlStateFile);