00001 #include "otsdaq-core/FiniteStateMachine/FiniteStateMachine.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00004
00005 #include <sstream>
00006 #include <map>
00007
00008 using namespace ots;
00009
00010
00011 FiniteStateMachine::FiniteStateMachine(void)
00012 : stateEntranceTime_(0)
00013 , inTransition_ (false)
00014 , provenanceState_ ('X')
00015 , theErrorMessage_ ("")
00016 {
00017 __COUT__ << "Constructing FiniteStateMachine" << std::endl;
00018 }
00019
00020
00021 FiniteStateMachine::~FiniteStateMachine(void)
00022 {}
00023
00024
00025 toolbox::fsm::State FiniteStateMachine::getProvenanceState(void)
00026 {
00027 return provenanceState_;
00028 }
00029
00030
00031 toolbox::fsm::State FiniteStateMachine::getTransitionFinalState(const std::string& transition) throw (toolbox::fsm::exception::Exception)
00032 {
00033 if(stateTransitionTable_[currentState_].find(transition) != stateTransitionTable_[currentState_].end())
00034 return stateTransitionTable_[currentState_][transition];
00035 else
00036 {
00037 std::ostringstream error;
00038 error << "Cannot find transition name with transition: " << transition << ", unknown!";
00039 XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());
00040 }
00041 }
00042
00043
00044 std::string FiniteStateMachine::getProvenanceStateName(void)
00045 {
00046 return getStateName(getProvenanceState());
00047 }
00048
00049
00050 std::string FiniteStateMachine::getCurrentStateName(void)
00051 {
00052 return getStateName(getCurrentState());
00053 }
00054
00055
00056
00057
00058
00059 time_t FiniteStateMachine::getTimeInState (void)
00060 {
00061 return stateEntranceTime_?(time(0) - stateEntranceTime_):0;
00062 }
00063
00064
00065 std::string FiniteStateMachine::getCurrentTransitionName(const std::string& transition) throw (toolbox::fsm::exception::Exception)
00066 {
00067 if(stateTransitionNameTable_[currentState_].find(transition) != stateTransitionNameTable_[currentState_].end())
00068 {
00069 return stateTransitionNameTable_[currentState_][transition];
00070 }
00071 else
00072 {
00073 std::ostringstream error;
00074 error << "Cannot find transition name with transition: " << transition << ", unknown!";
00075 XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());
00076 }
00077 }
00078
00079
00080 std::string FiniteStateMachine::getTransitionName(const toolbox::fsm::State from, const std::string& transition) throw (toolbox::fsm::exception::Exception)
00081 {
00082 if(stateTransitionNameTable_[from].find(transition) != stateTransitionNameTable_[from].end())
00083 {
00084 return stateTransitionNameTable_[from][transition];
00085 }
00086 else
00087 {
00088 std::ostringstream error;
00089 error << "Cannot find transition name from " << from << " with transition: " << transition << ", unknown!";
00090 XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());
00091 }
00092 }
00093
00094
00095 std::string FiniteStateMachine::getTransitionParameter(const toolbox::fsm::State from, const std::string& transition) throw (toolbox::fsm::exception::Exception)
00096 {
00097 if(stateTransitionParameterTable_[from].find(transition) != stateTransitionParameterTable_[from].end())
00098 {
00099 return stateTransitionParameterTable_[from][transition];
00100 }
00101 return "";
00102 }
00103
00104
00105 std::string FiniteStateMachine::getTransitionFinalStateName(const std::string& transition) throw (toolbox::fsm::exception::Exception)
00106 {
00107 return getStateName(getTransitionFinalState(transition));
00108 }
00109
00110
00111 bool FiniteStateMachine::execTransition(const std::string& transition) throw (toolbox::fsm::exception::Exception)
00112 {
00113 const xoap::MessageReference message;
00114 return execTransition(transition,message);
00115 }
00116
00117
00118 bool FiniteStateMachine::execTransition(const std::string& transition, const xoap::MessageReference& message) throw (toolbox::fsm::exception::Exception)
00119 {
00120
00121 if(inTransition_) return false;
00122 inTransition_ = true;
00123 bool transitionSuccessful = true;
00124 provenanceState_ = getCurrentState();
00125
00126 std::map<std::string, toolbox::fsm::State> transitions = getTransitions(getCurrentState());
00127 if(transitions.find(transition) == transitions.end())
00128 {
00129 inTransition_ = false;
00130 std::ostringstream error;
00131 error << transition << " is not in the list of the transitions from current state " << getStateName (getCurrentState());
00132 __COUT_ERR__ << error.str() << std::endl;
00133 XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());
00134
00135
00136 return false;
00137 }
00138
00139 try
00140 {
00141 toolbox::Event::Reference e(new toolbox::Event(transition, this));
00142 theMessage_ = message;
00143 this->fireEvent(e);
00144 }
00145 catch (toolbox::fsm::exception::Exception& e)
00146 {
00147 inTransition_ = false;
00148 transitionSuccessful = false;
00149 std::ostringstream error;
00150 error << "Transition " << transition << " cannot be executed from current state " << getStateName (getCurrentState());
00151 __COUT_ERR__ << error.str() << std::endl;
00152
00153 XCEPT_RAISE (toolbox::fsm::exception::Exception, error.str());
00154 }
00155
00156 inTransition_ = false;
00157
00158
00159 stateEntranceTime_ = time(0);
00160 return transitionSuccessful;
00161 }
00162
00163
00164 bool FiniteStateMachine::isInTransition(void)
00165 {
00166 return inTransition_;
00167 }
00168
00169
00170 void FiniteStateMachine::setErrorMessage(const std::string &errMessage)
00171 {
00172 theErrorMessage_ = errMessage;
00173 }
00174
00175
00176 const std::string& FiniteStateMachine::getErrorMessage() const
00177 {
00178 return theErrorMessage_;
00179 }
00180
00181
00182 void FiniteStateMachine::setInitialState(toolbox::fsm::State state)
00183 {
00184 toolbox::fsm::FiniteStateMachine::setInitialState(state);
00185 provenanceState_ = state;
00186 stateEntranceTime_ = time(0);
00187 }
00188
00189
00190 const xoap::MessageReference& FiniteStateMachine::getCurrentMessage(void)
00191 {
00192 return theMessage_;
00193 }