00001 #include "DQMServices/XdaqCollector/interface/StateMachine.h"
00002 #include "log4cplus/logger.h"
00003
00004 #include "xgi/Method.h"
00005 #include "xgi/Utils.h"
00006
00007 #include "xoap/SOAPEnvelope.h"
00008 #include "xoap/SOAPBody.h"
00009 #include "xoap/domutils.h"
00010
00011 #include <string>
00012
00013 using namespace dqm;
00014
00015 StateMachine::StateMachine(xdaq::ApplicationStub *s) :
00016 xdaq::Application(s),
00017 fsm_(getApplicationLogger())
00018 {
00019 wsm_.addState('H', "Halted" , this, &StateMachine::statePage);
00020 wsm_.addState('R', "Ready" , this, &StateMachine::statePage);
00021 wsm_.addState('E', "Enabled" , this, &StateMachine::statePage);
00022 wsm_.addState('S', "Suspended", this, &StateMachine::statePage);
00023
00024
00025 wsm_.addStateTransition('H', 'R', "Configure", this,
00026 &StateMachine::webConfigure, &StateMachine::failurePage);
00027 wsm_.addStateTransition('R', 'E', "Enable", this,
00028 &StateMachine::webEnable, &StateMachine::failurePage);
00029 wsm_.addStateTransition('E', 'S', "Suspend", this,
00030 &StateMachine::webSuspend, &StateMachine::failurePage);
00031 wsm_.addStateTransition('S', 'E', "Resume", this,
00032 &StateMachine::webResume, &StateMachine::failurePage);
00033 wsm_.addStateTransition('H', 'H', "Halt", this,
00034 &StateMachine::webHalt, &StateMachine::failurePage);
00035 wsm_.addStateTransition('R', 'H', "Halt", this,
00036 &StateMachine::webHalt, &StateMachine::failurePage);
00037 wsm_.addStateTransition('E', 'H', "Halt", this,
00038 &StateMachine::webHalt, &StateMachine::failurePage);
00039 wsm_.addStateTransition('S', 'H', "Halt", this,
00040 &StateMachine::webHalt, &StateMachine::failurePage);
00041
00042 wsm_.setInitialState('H');
00043
00044 fsm_.init<dqm::StateMachine>(this);
00045 xgi::bind(this, &StateMachine::dispatch, "dispatch");
00046 }
00047
00048 void StateMachine::bind(std::string page)
00049 {
00050 page_ = page;
00051 xgi::bind(this, &StateMachine::Default, page);
00052 }
00053
00054 xoap::MessageReference StateMachine::fireEvent(xoap::MessageReference msg)
00055 throw (xoap::exception::Exception)
00056 {
00057 xoap::SOAPPart part = msg->getSOAPPart();
00058 xoap::SOAPEnvelope env = part.getEnvelope();
00059 xoap::SOAPBody body = env.getBody();
00060 DOMNode *node = body.getDOMNode();
00061 DOMNodeList *bodyList = node->getChildNodes();
00062 DOMNode *command = 0;
00063 std::string commandName;
00064
00065 for (unsigned int i = 0; i < bodyList->getLength(); i++)
00066 {
00067 command = bodyList->item(i);
00068
00069 if(command->getNodeType() == DOMNode::ELEMENT_NODE)
00070 {
00071 commandName = xoap::XMLCh2String(command->getLocalName());
00072 wsm_.fireEvent(commandName,0,0);
00073 return fsm_.processFSMCommand(commandName);
00074 }
00075 }
00076
00077 XCEPT_RAISE(xoap::exception::Exception, "Command not found");
00078 }
00079
00080
00081
00082
00083 void StateMachine::statePage( xgi::Output * out )
00084 throw (xgi::exception::Exception)
00085 {
00086 if(out)
00087 {
00088 std::string url = "/";
00089 url += getApplicationDescriptor()->getURN();
00090 std::string purl = url + "/" + page_;
00091
00092 *out << cgicc::HTMLDoctype(cgicc::HTMLDoctype::eStrict) << std::endl;
00093 *out << cgicc::html().set("lang", "en").set("dir","ltr") << std::endl;
00094 *out << "<head>" << std::endl;
00095 *out << "<META HTTP-EQUIV=refresh CONTENT=\"30; URL=";
00096 *out << purl << "\">" << std::endl;
00097 *out << "<META HTTP-EQUIV=Window-target CONTENT=\"_self\">" << std::endl;
00098 *out << "<title> " << "fsm" << "</title>" << std::endl;
00099 *out << "</head>" << std::endl;
00100 *out << "<body>" << std::endl;
00101
00102
00103 url += "/dispatch";
00104
00105
00106
00107
00108 std::set<std::string>::iterator i;
00109 std::set<std::string> possibleInputs = wsm_.getInputs(wsm_.getCurrentState());
00110 std::set<std::string> allInputs = wsm_.getInputs();
00111
00112
00113
00114
00115 *out << cgicc::h3("Finite State Machine").set("style", "font-family: arial") << std::endl;
00116 *out << "<table border cellpadding=10 cellspacing=0>" << std::endl;
00117 *out << "<tr>" << std::endl;
00118 *out << "<th>" << wsm_.getStateName(wsm_.getCurrentState()) << "</th>" << std::endl;
00119 *out << "</tr>" << std::endl;
00120 *out << "<tr>" << std::endl;
00121
00122 for ( i = allInputs.begin(); i != allInputs.end(); i++)
00123 {
00124 *out << "<td>";
00125 *out << cgicc::form().set("method","post").set("target","_self").set("action", url).set("enctype","multipart/form-data") << std::endl;
00126
00127 if ( possibleInputs.find(*i) != possibleInputs.end() )
00128 {
00129 *out << cgicc::input().set("type", "submit").set("name", "StateInput").set("value", (*i) );
00130 }
00131 else
00132 {
00133 *out << cgicc::input() .set("type", "submit").set("name", "StateInput").set("value", (*i) ).set("disabled", "true");
00134 }
00135
00136 *out << cgicc::form();
00137 *out << "</td>" << std::endl;
00138 }
00139
00140 *out << "</tr>" << std::endl;
00141 *out << "</table>" << std::endl;
00142 *out << cgicc::html();
00143
00144
00145 }
00146 }
00147
00148
00149
00150
00151 void StateMachine::failurePage(xgi::Output * out, xgi::exception::Exception & e)
00152 throw (xgi::exception::Exception)
00153 {
00154 if(out)
00155 {
00156 *out << cgicc::HTMLDoctype(cgicc::HTMLDoctype::eStrict) << std::endl;
00157 *out << cgicc::html().set("lang", "en").set("dir","ltr") << std::endl;
00158
00159 xgi::Utils::getPageHeader(*out, "WebStateMachine Home", "Failure");
00160
00161
00162 *out << cgicc::br() << e.what() << cgicc::br() << std::endl;
00163 std::string url = "/";
00164 url += getApplicationDescriptor()->getURN();
00165
00166 *out << cgicc::br() << "<a href=\"" << url << "\">" << "retry" << "</a>" << cgicc::br() << std::endl;
00167
00168 xgi::Utils::getPageFooter(*out);
00169
00170 }
00171 }
00172