Commit 1537b4b9 by amir

finished writing first version

before testing
parent 0066b077
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef SEH_ENUMS_H #ifndef SEH_ENUMS_H
#define SEH_ENUMS_H #define SEH_ENUMS_H
#include <map>
namespace nsEnums namespace nsEnums
{ {
enum eRetStat enum eRetStat
...@@ -18,8 +19,24 @@ namespace nsEnums ...@@ -18,8 +19,24 @@ namespace nsEnums
eActionType_Regular, eActionType_Regular,
eActionType_If, eActionType_If,
eActionType_While, eActionType_While,
eActionType_Switch eActionType_Switch,
eActionType_Max
}; };
static std::map<const char*,eEventActionType> eventActionTypeMap = {
{ "Action", eActionType_Regular},
{ "If",eActionType_If},
{"While",eActionType_While},
{"Switch",eActionType_Switch}
};
static eEventActionType ResolveEventActionType(const char* eventActionType)
{
auto iterator = eventActionTypeMap.find(eventActionType);
if (iterator != eventActionTypeMap.end())
return iterator->second;
return eActionType_Max;
}
} }
#endif //SEH_ENUMS_H #endif //SEH_ENUMS_H
...@@ -204,7 +204,7 @@ struct NextState ...@@ -204,7 +204,7 @@ struct NextState
this->stateName.assign(stateName); this->stateName.assign(stateName);
} }
void setStateName(char* stateName) { void setStateName(const char* stateName) {
this->stateName.assign(stateName); this->stateName.assign(stateName);
} }
...@@ -376,6 +376,7 @@ struct CallFlow ...@@ -376,6 +376,7 @@ struct CallFlow
struct ICallFlowBuilder { struct ICallFlowBuilder {
virtual void Clear() = 0;
virtual RetStat BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, IBaseSEH *p_baseSEHObject) = 0; virtual RetStat BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, IBaseSEH *p_baseSEHObject) = 0;
virtual RetStat BuildFlowTableFromString(string& flowFSM, CallFlow* p_callFlow, IBaseSEH *baseSEHObject) = 0; virtual RetStat BuildFlowTableFromString(string& flowFSM, CallFlow* p_callFlow, IBaseSEH *baseSEHObject) = 0;
}; };
......
...@@ -6,8 +6,14 @@ ...@@ -6,8 +6,14 @@
#include <document.h> #include <document.h>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <bits/unique_ptr.h>
void JsonCallFlowBuilder::Clear() {
if(p_callFlow_)
delete p_callFlow_;
}
RetStat JsonCallFlowBuilder::BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, RetStat JsonCallFlowBuilder::BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow,
IBaseSEH *p_baseSEHObject) { IBaseSEH *p_baseSEHObject) {
RetStat retStat; RetStat retStat;
...@@ -71,6 +77,7 @@ RetStat JsonCallFlowBuilder::BuildFlowTableFromString(string& flowFSM, CallFlow* ...@@ -71,6 +77,7 @@ RetStat JsonCallFlowBuilder::BuildFlowTableFromString(string& flowFSM, CallFlow*
} }
JsonCallFlowBuilder::JsonCallFlowBuilder() { JsonCallFlowBuilder::JsonCallFlowBuilder() {
this->p_callFlow_ = nullptr;
this->eventAction_.Reset(); this->eventAction_.Reset();
this->eventData_.Reset(); this->eventData_.Reset();
this->flowFileName_.clear(); this->flowFileName_.clear();
...@@ -198,6 +205,549 @@ RetStat JsonCallFlowBuilder::GetState(Document &stateNode, State *p_State) { ...@@ -198,6 +205,549 @@ RetStat JsonCallFlowBuilder::GetState(Document &stateNode, State *p_State) {
return retStat; return retStat;
} }
/**
* Getting the event data
* @param eventNode
* @return
*/
RetStat JsonCallFlowBuilder::GetEvent(Document &eventNode) { RetStat JsonCallFlowBuilder::GetEvent(Document &eventNode) {
return RetStat(); RetStat retStat;
this->eventData_.Reset();
/*
* Going over the Event children
*/
/*
* checking for leaf : Event name / Next state
*/
/*******************************
* Getting the event name
******************************/
auto& eventNameNode = eventNode[nsConstants::C_NAME.c_str()];
if (eventNameNode.IsString())
this->eventData_.eventName.assign(eventNameNode.GetString());
/*******************************
* Getting the event next state
******************************/
auto& eventNextStateNode = eventNode[nsConstants::C_NEXT_STATE.c_str()];
if (eventNextStateNode.IsString())
{
string nextStateStr = eventNextStateNode.GetString();
if (nextStateStr.compare(nsConstants::C_NEXT_STATE) == 0)
{
this->eventData_.nextState.Reset();
}
else
{
this->eventData_.nextState.stateName = nextStateStr;
}
}
/*****************************
* Getting the Event Actions
*****************************/
auto& eventActionsNode = (Document&)eventNode[nsConstants::C_ACTIONS.c_str()];
retStat = GetEventActions(eventActionsNode);
if (retStat.Fail())
{
if (retStat.GetError().empty())
retStat.SetFail(string("JsonCallFlowBuilder.GetEvent-\tFailed to get event actions for event: ")
.append(this->eventData_.eventName));
return retStat;
}
return retStat;
}
/**
* Getting the event actions, resolving their names to functions pointers
* and storing them
* @param eventActionsNode
* @return
*/
RetStat JsonCallFlowBuilder::GetEventActions(Document &eventActionsNode) {
RetStat retStat;
/*
* Going over the Event actions
*/
for (auto actionNodePtr = eventActionsNode.Begin(); actionNodePtr != eventActionsNode.End(); ++actionNodePtr)
{
Document& actionNode = *(Document*)actionNodePtr;
/*******************************
* Resolving the action
*******************************/
retStat = GetAction(actionNode );
if (retStat.Fail())
return retStat;
/*****************************
* Storing the action
****************************/
this->eventData_.AddAction(*this->p_eventAction_);
delete(this->p_eventAction_);
}
return retStat;
}
/**
* Getting the Action
* example:
* [
{
"Type":"Action",
"Name":"SimpleAction"
},
{
"Type":"Action",
"Name": "ActionWithParamInt",
"Params": { "TO": "20" }
}
]
* @param actionNode
* @return
*/
RetStat JsonCallFlowBuilder::GetAction(Document &actionNode) {
RetStat retStat;
this->eventAction_.Reset();
/*
* getting the type
*/
auto& actionTypeNode = actionNode[nsConstants::C_TYPE.c_str()];
if (actionTypeNode.IsString())
{
nsEnums::eEventActionType eventActonType = nsEnums::ResolveEventActionType(actionTypeNode.GetString());
if (eventActonType != nsEnums::eActionType_Max)
{
switch (eventActonType) {
case eActionType_Regular:
// Handle action
this->p_eventAction_ = new EventAction();
this->p_eventAction_->Reset();
retStat = ResolveSimpleAction(this->p_eventAction_, actionNode );
break;
case eActionType_If:
this->p_eventAction_ = new EventIfAction();
this->p_eventAction_->Reset();
/*******************************
* Getting the condition action
********************************/
retStat = HandleEventIfAction((EventIfAction*) this->p_eventAction_,actionNode );
break;
case eActionType_Switch:
this->p_eventAction_ = new EventSwitchAction();
this->p_eventAction_->Reset();
/*******************************
* Getting the condition action
********************************/
retStat = HandleEventSwitchAction((EventSwitchAction*) this->p_eventAction_, actionNode);
break;
case eActionType_While:
this->p_eventAction_ = new EventWhileAction();
this->p_eventAction_->Reset();
/*******************************
* Getting the condition action
********************************/
retStat = HandleEventWhileAction((EventWhileAction*) this->p_eventAction_, actionNode);
break;
default:
break;
}
};
}
else
{
retStat.SetFail("JsonCallFlowBuilder.GetAction-\tno type for action");
}
return retStat;
}
/**
* resolving a simple action - not a condition like if/while/switch
* @param p_eventAction
* @param actionNode
* @return
*/
RetStat JsonCallFlowBuilder::ResolveSimpleAction(EventAction *p_eventAction, Document &actionNode) {
RetStat retStat;
/*
* get action params
*/
auto& actionParamsNode = actionNode[nsConstants::C_ACTION_PARAMS.c_str()];
if (actionParamsNode.IsObject())
GetActionParams(p_eventAction, (Document&)actionParamsNode );
auto& actionNameNode = actionNode[nsConstants::C_NAME.c_str()];
if (actionNameNode.IsString())
{
retStat = ResolveActionFunc(p_eventAction,actionNameNode.GetString());
//retStat = ResolveAction(actionPtr,actionNameNode.asText());
if (retStat.Success())
{
/*
* checking for action priority
*/
const char* p_actionParam = getParamString(actionNode, nsConstants::C_ACTION_PRIORITY.c_str());
if(p_actionParam)
{
if(strncasecmp(p_actionParam,nsConstants::C_ACTION_PRIORITY_MANDATORY.c_str(),nsConstants::C_ACTION_PRIORITY_MANDATORY_LEN) == 0)
{
p_eventAction->bIsMandatory = true;
} else if (strncasecmp(p_actionParam,nsConstants::C_ACTION_PRIORITY_CRITICAL.c_str(),nsConstants::C_ACTION_PRIORITY_CRITICAL_LEN) == 0)
{
p_eventAction->bIsCritical = true;
}
}
}
}
else
{
retStat.SetFail("JsonCallFlowBuilder.ResolveSimpleAction-\tno action name");
}
return retStat;
} }
/**
* {
"Type":"If",
"Name": "IfElseAction",
"Then": {
"Actions": [
{
"Type":"Action",
"Name":"SimpleAction"
},
{
"Type":"Action",
"Name": "ActionWithParamInt",
"Params": { "TO": "30000" }
},
{
"Type":"Action",
"Name":"SimpleAction"
}
],
"NextState": "Idle_IfThenState"
},
"Else": {
"Actions": [
{
"Type":"Action",
"Name": "ActionWithParamInt",
"Params": { "TO": "5000" }
},
{
"Type":"Action",
"Name":"SimpleAction"
},
{
"Type":"Action",
"Name":"SimpleAction"
}
],
"NextState": "Idle_IfElseState"
}
}
* @param p_eventIfAction
* @param actionNode
* @return
*/
RetStat JsonCallFlowBuilder::HandleEventIfAction(EventIfAction *p_eventIfAction, Document &actionNode) {
RetStat retStat;
/*******************************
* Getting the condition action
*******************************/
retStat = ResolveSimpleAction(p_eventIfAction, actionNode );
if (retStat.Fail())
{
if (retStat.GetError().empty())
retStat.SetFail(string("JsonCallFlowBuilder.HandleEventIfAction-\tFailed to Resolve the action")
.append(actionNode.GetString()));
SEH_METHOD_ERROR(retStat.GetError());
return retStat;
}
/*
* get then/else actions
*/
auto& thenNode = actionNode[nsConstants::C_IF_THEN.c_str()];
auto& elseNode = actionNode[nsConstants::C_IF_ELSE.c_str()];
if (thenNode.IsObject() && elseNode.IsObject())
{
retStat = GetEventData(p_eventIfAction->trueActions, (Document&)thenNode );
if (retStat.Success())
{
retStat = GetEventData(p_eventIfAction->falseActions, (Document&)elseNode );
}
}
else
{
retStat.SetFail(string("JsonCallFlowBuilder.HandleEventIfAction-\tNo true actions in: ")
.append(actionNode.GetString()));
}
return retStat;
}
/**
* handling the switch action :
*
* <pre>
* {@code
*{
"Type": "Switch",
"Name": "SwitchAction",
"Cases": [{
"Val1": {
"Actions": [{
"Type": "Action",
"Name": "SimpleAction"
}, {
"Type": "Action",
"Name": "ActionWithParamInt",
"Params": {
"TDCause": "8"
}
}, {
"Type": "Action",
"Name": "ActionWithParamString",
"Params": {
"Party": "ICP"
}
}],
"NextState": "Idle"
}
}, {
"Val2": {
"Actions": [{
"Type": "Action",
"Name": "ActionWithParamInt",
"Params": {
"TDCause": "8"
}
}, {
"Type": "Action",
"Name": "ActionWithParamString",
"Params": {
"Party": "ICP"
}
}],
"NextState": "Idle_NestState1"
}
}]
}
*
* @param p_eventSwitchAction
* @param actionNode
* @return
*/
RetStat JsonCallFlowBuilder::HandleEventSwitchAction(EventSwitchAction *p_eventSwitchAction, Document &actionNode) {
RetStat retStat;
/******************************************************
* Getting the condition action - the resolving here is different
* because the return status also holds the value as integer
*****************************************************/
retStat = ResolveSimpleAction(p_eventSwitchAction,actionNode );
if (retStat.Success())
{
/************************************
* Getting the switch actions
************************************/
auto& casesArrayNode = (Document&)actionNode[nsConstants::C_CASES.c_str()];
if (casesArrayNode.IsArray())
{
/************************************
* now going on every case
************************************/
for(auto caseNodeIterator = casesArrayNode.Begin(); caseNodeIterator != casesArrayNode.End(); ++caseNodeIterator)
{
for(auto caseIterator = caseNodeIterator->MemberBegin(); caseIterator != caseNodeIterator->MemberEnd(); ++caseIterator)
{
if (caseIterator->value.IsObject()) {
unique_ptr<EventData> p_eventData( new EventData());
retStat = GetEventData(*p_eventData, (Document&)caseIterator->value );
if (retStat.Fail())
break;
/*
* add the event data
*/
p_eventSwitchAction->switchActions.push_back(*p_eventData);
} else {
retStat.SetFail(string("JsonCallFlowBuilder.HandleEventSwitchAction-\tno case object: ").append(p_eventSwitchAction->name));
}
}
}
}
else
{
retStat.SetFail(string("JsonCallFlowBuilder.HandleEventSwitchAction-\tNo switch cases after: ").append(p_eventSwitchAction->name));
}
}
else
{
retStat.SetFail(string("JsonCallFlowBuilder.HandleEventSwitchAction-\tFailed to Resolve the action :").append(p_eventSwitchAction->name));
}
return retStat;
}
/**
* Handling Event If actions, the format is:
*
* <pre>
* {@code
* <While>
* <Action>condAction</Action>
* <Actions>
* <Action>...</Action>
* <Action>...</Action>
* <Action>...</Action>
* </Actions>
* <NextState>nextState</NextState>
* </While>
* }
* </pre>
*
*
* @param p_eventWhileAction
* @param actionNode
* @return
*/
RetStat JsonCallFlowBuilder::HandleEventWhileAction(EventWhileAction *p_eventWhileAction, Document &actionNode) {
RetStat retStat;
/*******************************
* Getting the condition action
*******************************/
retStat = ResolveSimpleAction(p_eventWhileAction, actionNode );
if (retStat.Success())
{
/************************************
* Getting the while actions
************************************/
retStat = GetEventData(p_eventWhileAction->whileActions, actionNode);
if (retStat.Fail())
{
retStat.SetFail(string("JsonCallFlowBuilder.HandleEventWhileAction-\tNo while actions after: ")
.append(actionNode.GetString()));
}
}
else
{
if (retStat.GetError().empty())
retStat.SetFail(string("JsonCallFlowBuilder.HandleEventIfAction-\tFailed to Resolve the action")
.append(actionNode.GetString()));
SEH_METHOD_ERROR(retStat.GetError());
return retStat;
}
return retStat;
}
/**
* Getting the Action parameters
* @param p_eventAction
* @param actionParamNode
*/
void JsonCallFlowBuilder::GetActionParams(EventAction *p_eventAction, Document &actionParamNode) {
/*****************************
* Allocating the action parmas class and Going over the params
******************************/
p_eventAction->p_param_ = this->p_baseSEHObject_->getNewSEHParam();
if (p_eventAction->p_param_ != nullptr)
{
/*
* Going over the Parameters
*/
auto nextParam = actionParamNode.MemberBegin();
while(nextParam != actionParamNode.MemberEnd())
{
/*
* Setting the parameter in the param object
*/
p_eventAction->p_param_->SetParam(nextParam->name.GetString(),nextParam->value.GetString());
++nextParam;
}
}
}
/**
* resolving the function and setting the function pointer
* in the event function
* @param p_eventAction
* @param p_actionFuncName
* @return
*/
RetStat JsonCallFlowBuilder::ResolveActionFunc(EventAction *p_eventAction, const char *p_actionFuncName) {
RetStat retStat;
/*********************************
* Resolve action
********************************/
p_eventAction->action = this->p_baseSEHObject_->resolveAction(p_actionFuncName);
if (p_eventAction->action == nullptr)
{
retStat.SetFail(string("JsonCallFlowBuilder.ResolveAction-\tFailed to Resolve the action: ").append(p_actionFuncName));
}
return retStat;
}
/**
* Getting all the event data , including it's next state Calling this
* method when node is pointing to <Actions> tag
* @param eventData
* @param eventNode
* @return
*/
RetStat JsonCallFlowBuilder::GetEventData(EventData &eventData, Document &eventNode) {
RetStat retStat;
eventData.Reset();
/*****************************
* Going over the actions
****************************/
auto& actionArrayNode = eventNode[nsConstants::C_ACTIONS.c_str()];
if (actionArrayNode.IsArray())
{
for (auto actionNodeIterator = actionArrayNode.Begin();
actionNodeIterator != actionArrayNode.End(); ++actionNodeIterator)
{
/*******************************
* Resolving the action
*******************************/
unique_ptr<EventAction> p_eventAction( new EventAction());
p_eventAction->Reset();
retStat = ResolveSimpleAction(p_eventAction.get(), (Document&)*actionNodeIterator);
if (retStat.Fail())
{
//p_eventAction = nullptr;
return retStat;
}
/*****************************
* Storing the action
****************************/
eventData.AddAction(*p_eventAction);
}
} else
{
retStat.SetFail("JsonCallFlowBuilder.GetEventData-\tNo Event Actions");
return retStat;
}
/***********************************
* Getting the next state - optional sometimes there won't be next
* state
**********************************/
const char* p_nextState = getParamString(eventNode,nsConstants::C_NEXT_STATE.c_str());
if(p_nextState)
{
if (strcasecmp(p_nextState,nsConstants::C_NULL_STATE.c_str()) != 0)
eventData.nextState.setStateName(p_nextState);
else
eventData.nextState.Reset();
}
return retStat;
}
...@@ -34,6 +34,33 @@ public: ...@@ -34,6 +34,33 @@ public:
RetStat GetState(Document &stateNode, State *p_State); RetStat GetState(Document &stateNode, State *p_State);
RetStat GetEvent(Document &eventNode); RetStat GetEvent(Document &eventNode);
RetStat GetEventActions(Document &eventActionsNode);
RetStat GetAction(Document &actionNode);
RetStat ResolveSimpleAction(EventAction *p_eventAction, Document &actionNode);
RetStat HandleEventIfAction(EventIfAction *p_eventIfAction, Document &actionNode);
RetStat HandleEventSwitchAction(EventSwitchAction *p_eventSwitchAction, Document &actionNode);
RetStat HandleEventWhileAction(EventWhileAction *p_eventWhileAction, Document &actionNode);
const char *getParamString(Document &document, const char *p_str){
Value &value = document[p_str];
if(value.IsString())
return value.GetString();
return nullptr;
}
void GetActionParams(EventAction *p_eventAction, Document &actionParamNode);
RetStat ResolveActionFunc(EventAction *p_eventAction, const char *p_actionFuncName);
RetStat GetEventData(EventData &eventData, Document &eventNode);
virtual void Clear() override;
}; };
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
#include "XMLCallFlowBuilder.h" #include "XMLCallFlowBuilder.h"
void XMLCallFlowBuilder::Clear() {
}
RetStat XMLCallFlowBuilder::BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, IBaseSEH *p_baseSEHObject) { RetStat XMLCallFlowBuilder::BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, IBaseSEH *p_baseSEHObject) {
return RetStat(); return RetStat();
} }
......
...@@ -14,6 +14,8 @@ public: ...@@ -14,6 +14,8 @@ public:
virtual RetStat BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, IBaseSEH *p_baseSEHObject) override; virtual RetStat BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, IBaseSEH *p_baseSEHObject) override;
virtual RetStat BuildFlowTableFromString(string& flowFSM, CallFlow* p_callFlow, IBaseSEH *baseSEHObject) override; virtual RetStat BuildFlowTableFromString(string& flowFSM, CallFlow* p_callFlow, IBaseSEH *baseSEHObject) override;
virtual void Clear() override;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment