Skip to content
Snippets Groups Projects
Commit 91a4cc7b authored by Sophie Coudert's avatar Sophie Coudert
Browse files

save. Avatar2SysML commented until line 1126, next: clean_guard

parent 1da61e82
No related branches found
No related tags found
3 merge requests!504merge first stable version of Avatar-SysML V2,!503merge the first stable version of the Avatar-SysML parser/generator,!501Avatar sys ml 04 2024
......@@ -45,6 +45,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.function.BiConsumer;
/**
......@@ -59,12 +60,10 @@ public class Avatar2SysML {
private AvatarSpecification avspec;
/** the buffer in which theSysML Model is written (returned at the end of the generation process) */
private StringBuffer avsysml;
/** signals concerned by AvatarQueryOnSignal */
/** signals concerned by AvatarQueryOnSignal (collected at beginning because require some specific handling)*/
private HashSet<AvatarSignal> fifoSet = new HashSet<AvatarSignal>();
/** infos about methods and signals collected while generation declarations and used while generating state machines */
private HashMap<AvatarMethod, MethodInfo> methodMap = new HashMap<AvatarMethod, MethodInfo>();
private HashMap<AvatarStateMachineElement, StateInfo> stateMap = new HashMap<AvatarStateMachineElement, StateInfo>();
private ArrayList<AvatarStateMachineElement> stateList = new ArrayList<AvatarStateMachineElement>();
private ArrayList<AvatarAttribute> timerList = new ArrayList<AvatarAttribute>();
/** path from top level to the block (block sequence) being currently handled */
private ArrayList<String> blockChain = new ArrayList<String>();
/** SysML code to make inner blocks visible at top level. Contains one declaration per inner block */
......@@ -93,8 +92,6 @@ public class Avatar2SysML {
public StringBuffer avatar2SysML() {
fifoSet.clear();
methodMap.clear();
stateMap.clear();
stateList.clear();
blockChain.clear();
indentation = "";
blockLinks = new StringBuffer(indentStep + "// Block Shortcut Links $$$$$$$$$$$$\n");
......@@ -116,7 +113,7 @@ public class Avatar2SysML {
/** infos collected while generating declarations of methods and signals, to be used later.
*
* (for example when handling ActionsOnSignal) */
* Used when generating state machine description, for example when handling ActionsOnSignal. */
static private class MethodInfo {
private String name; // method name
private String msgtype; // null for methods that are not signals
......@@ -319,7 +316,7 @@ public class Avatar2SysML {
* <li> in/out Messages (structures) declarations, linking them to channels. This providing signals with profiles </li>
* </ul>
*/
void communications2SysML(){
private void communications2SysML(){
int nbfiforelNumber = 0;
int bfiforelNumber = 0;
int syncrelNumber = 0;
......@@ -519,7 +516,7 @@ public class Avatar2SysML {
/** generates SysML declarations for block methods.
* To be called while generating block declarations. Directly put generated text in avsysml.
*/
void method2SysML(AvatarMethod am){
private void method2SysML(AvatarMethod am){
MethodInfo methodInfo; // to collect info
......@@ -601,15 +598,16 @@ public class Avatar2SysML {
* To be called while generating block declarations. Directly put generated text in avsysml. Signals used in AvatarQueryOnSignal elements must
* be typed as fifos (other ones are not constrained). Thus, fifoSet must have been computed before calling this method.
*/
void signal2SysML(AvatarSignal as){
private void signal2SysML(AvatarSignal as){
avsysml.append(indentation + "part " + methodMap.get(as).getName() + " : " +
(fifoSet.contains(as) ? "'#Fifo'" : "'#Channel'") + ";\n");
}
/** generates SysML declarations for blocks and declaration to directly access inner blocks through their name (not their full path) */
void block2SysML(AvatarBlock block){
/** generates SysML declarations for a blocks and direct access to inner blocks through their name (not their full path) */
private void block2SysML(AvatarBlock block){
String blockSYSMLname = blockSysMLname(block.getName());
timerList.clear(); // to memorize timers while iterating on attributes (delayed declarations)
// to memorize timers while iterating on attributes (delayed declarations)
ArrayList<AvatarAttribute> timerList = new ArrayList<AvatarAttribute>();
chainBlock(blockSYSMLname);
blocklink(); // to directly access inner blocks through their (short) name
......@@ -723,16 +721,24 @@ public class Avatar2SysML {
unchainBlock();
}
// handling all blocks
void blocks2SysML(){
/** generates SysML declarations for all blocks: iterate on specification block list */
private void blocks2SysML(){
avsysml.append("\n" + indentation + "// BLOCKS $$$$$$$$$$$$$$$$$$$$$$$$\n");
for(AvatarBlock block: avspec.getListOfBlocks())
if (block.getFather() == null) block2SysML(block);
}
Boolean stopState;
void statemachine2SysML(AvatarStateMachine asm) {
stateList.clear();
// associate names to future SysML states
/** generates state information for each state machine element of the specification and technically
* added states (before some communication elements). Put this information in a map which is returned.
*/
private HashMap<AvatarStateMachineElement, StateInfo> computeStateInfo(AvatarStateMachine asm) {
// the map to fill and return
HashMap<AvatarStateMachineElement, StateInfo> stateMap = new HashMap<AvatarStateMachineElement, StateInfo>();
// associate names to future SysML states.........................
// number to identify states in an unambigous way
int randomNumber = 0;
int countNumber = 0;
int sendNumber = 0;
......@@ -740,301 +746,383 @@ public class Avatar2SysML {
int setNumber = 0;
int resetNumber = 0;
int expireNumber = 0;
// produces and memorize stateinfo structure (couple name, prename) for all state machine element
for (AvatarStateMachineElement asme : asm.getListOfElements()) {
StateInfo stateinfo;
if (asme instanceof AvatarStartState)
// states without communication hav just a name.
if (asme instanceof AvatarStartState)
stateinfo = new StateInfo(startStateSysMLname());
else if (asme instanceof AvatarStopState)
stateinfo = new StateInfo(stopStateSysMLname());
else if (asme instanceof AvatarState)
stateinfo = new StateInfo(standardStateSysMLname(asme.getName()));
else if (asme instanceof AvatarQueryOnSignal)
stateinfo = new StateInfo(countStateSysMLname(((AvatarQueryOnSignal) asme).getSignal().getName(), countNumber++));
else if (asme instanceof AvatarRandom)
stateinfo = new StateInfo(randomStateSysMLname(randomNumber++));
// next cases rely on communication and thus, are subject to the introduction of an additional "preceding" state.
else if (asme instanceof AvatarActionOnSignal) {
if(((AvatarActionOnSignal)asme).isSending())
if (((AvatarActionOnSignal) asme).isSending())
stateinfo = new StateInfo(
sendStateSysMLname(((AvatarActionOnSignal)asme).getSignal().getName(), sendNumber),
presendStateSysMLname(((AvatarActionOnSignal)asme).getSignal().getName(), sendNumber++));
sendStateSysMLname(((AvatarActionOnSignal) asme).getSignal().getName(), sendNumber),
presendStateSysMLname(((AvatarActionOnSignal) asme).getSignal().getName(), sendNumber++));
else
stateinfo = new StateInfo(receiveStateSysMLname(((AvatarActionOnSignal)asme).getSignal().getName(), receiveNumber),
prereceiveStateSysMLname(((AvatarActionOnSignal)asme).getSignal().getName(), receiveNumber++));
}
else if (asme instanceof AvatarSetTimer) {
stateinfo = new StateInfo(setTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(),setNumber),
stateinfo = new StateInfo(receiveStateSysMLname(((AvatarActionOnSignal) asme).getSignal().getName(), receiveNumber),
prereceiveStateSysMLname(((AvatarActionOnSignal) asme).getSignal().getName(), receiveNumber++));
} else if (asme instanceof AvatarSetTimer) {
stateinfo = new StateInfo(setTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(), setNumber),
presetTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(), setNumber++));
}
else if (asme instanceof AvatarResetTimer) {
stateinfo = new StateInfo(resetTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(),resetNumber),
} else if (asme instanceof AvatarResetTimer) {
stateinfo = new StateInfo(resetTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(), resetNumber),
preresetTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(), resetNumber++));
}
else if (asme instanceof AvatarExpireTimer) {
stateinfo = new StateInfo(expireTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(),expireNumber),
} else if (asme instanceof AvatarExpireTimer) {
stateinfo = new StateInfo(expireTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(), expireNumber),
preexpireTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(), expireNumber++));
}
else if (asme instanceof AvatarQueryOnSignal)
stateinfo = new StateInfo(countStateSysMLname(((AvatarQueryOnSignal)asme).getSignal().getName(), countNumber++));
else if (asme instanceof AvatarRandom)
stateinfo = new StateInfo(randomStateSysMLname(randomNumber++));
else continue;
stateList.add(asme);
} else continue; // TODO ? curious states "AvatarEmpty" not handled
stateMap.put(asme, stateinfo);
}
return stateMap;
}
/** generates SysML description of state machine */
private void statemachine2SysML(AvatarStateMachine asm) {
HashMap<AvatarStateMachineElement, StateInfo> stateMap = computeStateInfo(asm);
// put state-machine header to avsysml.............................
avsysml.append(indentation + "exhibit state '@statemachine' : '#AvatarStateMachine' {\n");
indent(1);
// generate SysML states with associated transitions
stopState = false;
for (AvatarStateMachineElement asme : stateList) state2SysML(asme);
// put SysML states descriptions with associated transition descriptions.........
stateMap.forEach(new State2SysML(stateMap));
unindent(1);
avsysml.append(indentation + "}\n");
}
/** buffer to build SysML declarations of outgoing transitions from one state(filled by method transitionsAndRequests) */
StringBuffer sysMLtransitions = new StringBuffer();
/** buffer to build in-a-state requests associated to the outgoing transitions of this state (filled by method transitionsAndRequests) */
StringBuffer sysMLrequests = new StringBuffer();
/** communication (and timer) states that require an added state before (as they have incomming transitions with action, from the currently
* handled state) (filled by method transitionsAndRequests) */
List<AvatarStateMachineElement> requirePreCom = new ArrayList<AvatarStateMachineElement>();
void state2SysML(AvatarStateMachineElement asme){
indent(1);
transitionsAndRequests(stateMap.get(asme).getName(), asme.getNexts(), ((asme instanceof AvatarState) ? "'@pool'" : "'@request'"));
unindent(1);
String requests = sysMLrequests.toString();
/** to iterate on the state machine elements of one block. An iteration puts a state declaration in avsysml, followed by the declarations of
* its outgoing transitions. If the needed technically added pre-communication are detected while handling these transitions. The declarations
* of these added states are added after the transition declarations, followed by their own single outgoing transition.
*/
private class State2SysML implements BiConsumer<AvatarStateMachineElement, StateInfo> {
/** provides all states with name information */
HashMap<AvatarStateMachineElement, StateInfo> stateMap;
// State Description, depending on state type
/** false untill stopState has been encountered (as it can be encountered several times but generated only once) */
Boolean stopStateDone;
if(asme instanceof AvatarState){
avsysml.append("\n" + indentation + "state " + stateMap.get(asme).getName() + " : '#AvatarStandardState'");
if (requests.equals(""))
avsysml.append(";\n");
else
avsysml.append(" = '#AvatarStandardState'(\n" + requests + "\n" + indentation + ");\n");
} else
public State2SysML(HashMap<AvatarStateMachineElement, StateInfo> _stateMap) {
stateMap = _stateMap;
stopStateDone = false;
}
if(asme instanceof AvatarRandom){
avsysml.append("\n" + indentation + "state " + stateMap.get(asme).getName() + " : '#AvatarRandomState' = '#AvatarRandomState'(\n");
if (!requests.equals("")) avsysml.append(requests + ",\n");
indent(1);
avsysml.append(indentation + "'@state_action' = '#Assignment'(\n");
/** puts a state declaration in avsysml, followed by the declarations of
* its outgoing transitions. If the needed technically added pre-communication are detected while handling these transitions. The declarations
* of these added states are added after the transition declarations, followed by their own single outgoing transition.
*/
public void accept(AvatarStateMachineElement asme, StateInfo info) {
// compute transition declarations and request descriptions for the outgoing transitions of the state
// identify states that require an added pre-communication state
indent(1);
avsysml.append(indentation + "'@target' = " + attributeSysMLname(((AvatarRandom)asme).getVariable()) + ",\n");
avsysml.append(indentation + "'@value' = '#bound_random'(" +
expr2SysML(((AvatarRandom)asme).getMinValue().replaceAll("__",".")) + ", " +
expr2SysML(((AvatarRandom)asme).getMaxValue().replaceAll("__",".")) +")\n");
unindent(1);
avsysml.append(indentation + ")\n");
transitionsAndRequests(info.getName(), asme.getNexts(), ((asme instanceof AvatarState) ? "'@pool'" : "'@request'"), stateMap);
unindent(1);
avsysml.append(indentation + ");\n");
} else
if(asme instanceof AvatarQueryOnSignal){
avsysml.append("\n" + indentation + "state " + stateMap.get(asme).getName() + " : '#AvatarCountState' = '#AvatarCountState'(\n");
if (!requests.equals("")) avsysml.append(requests + ",\n");
indent(1);
avsysml.append(indentation + "'@state_action' = '#Assignment'(\n");
indent(1);
avsysml.append(indentation + "'@target' = " + attributeSysMLname(((AvatarQueryOnSignal)asme).getAttribute().getName()) + ",\n");
avsysml.append(indentation + "'@value' = " + methodMap.get(((AvatarQueryOnSignal)asme).getSignal()).getName() + ".'@amount'()\n");
unindent(1);
avsysml.append(indentation + ")\n");
unindent(1);
avsysml.append(indentation + ");\n");
} else
String requests = sysMLrequests.toString(); // to put after state declaration
if(asme instanceof AvatarActionOnSignal){
if(((AvatarActionOnSignal)asme).isSending()) {
avsysml.append("\n" + indentation + "state " + stateMap.get(asme).getName() + " : '#AvatarSendState'");
if (requests.equals(""))
avsysml.append(";\n");
else
avsysml.append(" = '#AvatarSendState'(\n" + requests + "\n" + indentation + ");\n");
} else {
avsysml.append("\n" + indentation + "state " + stateMap.get(asme).getName() + " : '#AvatarReceiveState'");
// put state Descriptions ................................
// depending on state type
if(asme instanceof AvatarState){
avsysml.append("\n" + indentation + "state " + info.getName() + " : '#AvatarStandardState'");
if (requests.equals(""))
avsysml.append(";\n");
else
avsysml.append(" = '#AvatarReceiveState'(\n" + requests + "\n" + indentation + ");\n");
}
} else
avsysml.append(" = '#AvatarStandardState'(\n" + requests + "\n" + indentation + ");\n");
} else
if(asme instanceof AvatarStartState){
avsysml.append("\n" + indentation + "entry action " + stateMap.get(asme).getName() + " :'#AvatarStartState'");
if (requests.equals(""))
avsysml.append(";\n");
else
avsysml.append(" = '#AvatarStartState'(\n" + requests + "\n" + indentation + ");\n");
} else
if(asme instanceof AvatarStopState){
if(! stopState)
avsysml.append("\n" + indentation + "exit action " + stateMap.get(asme).getName() + " :'#AvatarStopState';\n");
stopState = true;
} else
if(asme instanceof AvatarSetTimer){
avsysml.append("\n" + indentation + "state " + stateMap.get(asme).getName() + " : '#AvatarSetTimerState'");
if (requests.equals(""))
avsysml.append(";\n");
else
avsysml.append(" = '#AvatarSetTimerState'(\n" + requests + "\n" + indentation + ");\n");
} else
if(asme instanceof AvatarRandom){ // specific: assign a random value to a variable
avsysml.append("\n" + indentation + "state " + info.getName() + " : '#AvatarRandomState' = '#AvatarRandomState'(\n");
if (!requests.equals("")) avsysml.append(requests + ",\n"); // put request description (none means default request)
indent(1);
avsysml.append(indentation + "'@state_action' = '#Assignment'(\n");
indent(1);
// the variable to be assigned
avsysml.append(indentation + "'@target' = " + attributeSysMLname(((AvatarRandom)asme).getVariable()) + ",\n");
// the random value to assign
avsysml.append(indentation + "'@value' = '#bound_random'(" +
expr2SysML(((AvatarRandom)asme).getMinValue().replaceAll("__",".")) + ", " +
expr2SysML(((AvatarRandom)asme).getMaxValue().replaceAll("__",".")) +")\n");
unindent(1);
avsysml.append(indentation + ")\n");
unindent(1);
avsysml.append(indentation + ");\n");
} else
if(asme instanceof AvatarResetTimer){
avsysml.append("\n" + indentation + "state " + stateMap.get(asme).getName() + " : '#AvatarResetTimerState'");
if (requests.equals(""))
avsysml.append(";\n");
else
avsysml.append(" = '#AvatarResetTimerState'(\n" + requests + "\n" + indentation + ");\n");
} else
if(asme instanceof AvatarQueryOnSignal){ // specific: assign the content size of a signal to a variable
avsysml.append("\n" + indentation + "state " + info.getName() + " : '#AvatarCountState' = '#AvatarCountState'(\n");
if (!requests.equals("")) avsysml.append(requests + ",\n"); // put request description (none means default request)
indent(1);
avsysml.append(indentation + "'@state_action' = '#Assignment'(\n");
indent(1);
// the variable to assign
avsysml.append(indentation + "'@target' = " + attributeSysMLname(((AvatarQueryOnSignal)asme).getAttribute().getName()) + ",\n");
// the size of the content of the concerned signal
avsysml.append(indentation + "'@value' = " + methodMap.get(((AvatarQueryOnSignal)asme).getSignal()).getName() + ".'@amount'()\n");
unindent(1);
avsysml.append(indentation + ")\n");
unindent(1);
avsysml.append(indentation + ");\n");
} else
if(asme instanceof AvatarActionOnSignal){
if(((AvatarActionOnSignal)asme).isSending()) {
avsysml.append("\n" + indentation + "state " + info.getName() + " : '#AvatarSendState'");
if (requests.equals("")) // default request
avsysml.append(";\n");
else // put requests description
avsysml.append(" = '#AvatarSendState'(\n" + requests + "\n" + indentation + ");\n");
} else {
avsysml.append("\n" + indentation + "state " + info.getName() + " : '#AvatarReceiveState'");
if (requests.equals("")) // default request
avsysml.append(";\n");
else
avsysml.append(" = '#AvatarReceiveState'(\n" + requests + "\n" + indentation + ");\n");
}
} else
if(asme instanceof AvatarExpireTimer){
avsysml.append("\n" + indentation + "state " + stateMap.get(asme).getName() + " : '#AvatarExpireTimerState'");
if (requests.equals(""))
avsysml.append(";\n");
else
avsysml.append(" = '#AvatarExpireTimerState'(\n" + requests + "\n" + indentation + ");\n");
}
if(asme instanceof AvatarStartState){
avsysml.append("\n" + indentation + "entry action " + info.getName() + " :'#AvatarStartState'");
if (requests.equals("")) // default request
avsysml.append(";\n");
else // put requests description
avsysml.append(" = '#AvatarStartState'(\n" + requests + "\n" + indentation + ");\n");
} else
if(asme instanceof AvatarStopState){ // specific mandatory empty request list (implicite)
if(!stopStateDone)
avsysml.append("\n" + indentation + "exit action " + info.getName() + " :'#AvatarStopState';\n");
stopStateDone = true;
} else
if(asme instanceof AvatarSetTimer){
avsysml.append("\n" + indentation + "state " + info.getName() + " : '#AvatarSetTimerState'");
if (requests.equals("")) // default request
avsysml.append(";\n");
else // put requests description
avsysml.append(" = '#AvatarSetTimerState'(\n" + requests + "\n" + indentation + ");\n");
} else
// Transition descriptions
avsysml.append(sysMLtransitions);
if(asme instanceof AvatarResetTimer){
avsysml.append("\n" + indentation + "state " + info.getName() + " : '#AvatarResetTimerState'");
if (requests.equals("")) // default request
avsysml.append(";\n");
else // put requests description
avsysml.append(" = '#AvatarResetTimerState'(\n" + requests + "\n" + indentation + ");\n");
} else
// PreComm States and their outgoing transition
for (AvatarStateMachineElement aos: requirePreCom) {
StateInfo stateinfo = stateMap.get(aos);
if (aos instanceof AvatarActionOnSignal) {
MethodInfo signalinfo = methodMap.get(((AvatarActionOnSignal)aos).getSignal());
if(asme instanceof AvatarExpireTimer){
avsysml.append("\n" + indentation + "state " + info.getName() + " : '#AvatarExpireTimerState'");
if (requests.equals("")) // default request
avsysml.append(";\n");
else // put requests description
avsysml.append(" = '#AvatarExpireTimerState'(\n" + requests + "\n" + indentation + ");\n");
}
if (((AvatarActionOnSignal)aos).isSending()) {
// preComm State
avsysml.append("\n" + indentation + "state " + stateinfo.getPreName() + " : '#AvatarPreSendState' = '#AvatarPreSendState' (\n");
indent(1);
avsysml.append(indentation + "'@request' =\n");
indent(1);
avsysml.append(sendRequest2SysML(1, "0", "0", signalinfo, ((AvatarActionOnSignal)aos).getOriginalValues()) + "\n");
indentation = indentation.substring(2 * indentStepSize);
avsysml.append(indentation + ");\n");
// its transition
avsysml.append("\n" + indentation + "transition : '#AvatarTransition' first " + stateinfo.getPreName() +
" then " + stateinfo.getName() +
endTransition(0,"","", 1));
} else {
avsysml.append("\n" + indentation + "state " + stateinfo.getPreName() + " : '#AvatarPreReceiveState' = '#AvatarPreReceiveState' (\n");
indent(1);
avsysml.append(indentation + "'@request' =\n");
indent(1);
avsysml.append(receiveRequest2SysML(1, "0", "0", signalinfo) + "\n");
indentation = indentation.substring(2 * indentStepSize);
avsysml.append(indentation + ");\n");
// its transition
avsysml.append("\n" + indentation + "transition : '#AvatarTransition' first " + stateinfo.getPreName() + "\n");
indent(1);
String doAction = receiveActions2SysML(signalinfo, ((AvatarActionOnSignal)aos).getOriginalValues());
if (doAction.length() == 0)
avsysml.append(indentation + "then " + stateinfo.getName() +
endTransition(0,"","", 1));
else {
avsysml.append(doAction);
avsysml.append(" then " + stateinfo.getName() +
// put transition declarations .................................................
avsysml.append(sysMLtransitions);
// put pre-communication states to add and their single outgoing transition
for (AvatarStateMachineElement aos: requirePreCom) {
// the name of an added states is obtained by StateInfo.getPreName()
// the target of its outgoing transition is the communication state itself (StateInfo.getName())
// endTransition adds distribution law information at the end of the transition declarations
StateInfo stateinfo = stateMap.get(aos);
if (aos instanceof AvatarActionOnSignal) {
MethodInfo signalinfo = methodMap.get(((AvatarActionOnSignal)aos).getSignal());
if (((AvatarActionOnSignal)aos).isSending()) {
// put pre-communication State
avsysml.append("\n" + indentation + "state " + stateinfo.getPreName() + " : '#AvatarPreSendState' = '#AvatarPreSendState' (\n");
indent(1);
avsysml.append(indentation + "'@request' =\n");
indent(1);
// sending request from pre-send state to send state
avsysml.append(sendRequest2SysML(1, "0", "0", signalinfo, ((AvatarActionOnSignal)aos).getOriginalValues()) + "\n");
indentation = indentation.substring(2 * indentStepSize);
avsysml.append(indentation + ");\n");
// transition from pre-send state to send state
avsysml.append("\n" + indentation + "transition : '#AvatarTransition' first " + stateinfo.getPreName() +
" then " + stateinfo.getName() +
endTransition(0,"","", 1));
} else {
// put pre-communication State
avsysml.append("\n" + indentation + "state " + stateinfo.getPreName() + " : '#AvatarPreReceiveState' = '#AvatarPreReceiveState' (\n");
indent(1);
avsysml.append(indentation + "'@request' =\n");
indent(1);
// receiving request from pre-receive state to receive state
avsysml.append(receiveRequest2SysML(1, "0", "0", signalinfo) + "\n");
indentation = indentation.substring(2 * indentStepSize);
avsysml.append(indentation + ");\n");
// transition from pre-receive state to receive state
avsysml.append("\n" + indentation + "transition : '#AvatarTransition' first " + stateinfo.getPreName() + "\n");
indent(1);
// updating target variables with received values
String doAction = receiveActions2SysML(signalinfo, ((AvatarActionOnSignal)aos).getOriginalValues());
if (doAction.length() == 0) // receive simple signal (without carried value)
avsysml.append(indentation + "then " + stateinfo.getName() +
endTransition(0,"","", 1));
else { // put updating action
avsysml.append(doAction);
avsysml.append(" then " + stateinfo.getName() +
endTransition(0,"","", 1));
}
unindent(1);
}
unindent(1);
}
} else if (aos instanceof AvatarSetTimer) {
// preComm State
} else if (aos instanceof AvatarSetTimer) { // a special kind of send request
// put pre-communication State
avsysml.append("\n" + indentation + "state " + stateinfo.getPreName() + " : '#AvatarPreSendState' = '#AvatarPreSendState' (\n");
indent(1);
avsysml.append(indentation + "'@request' =\n");
indent(1);
// put the specific sending request, carrying a value
avsysml.append(setTimerRequest2SysML(1, "0", "0",
timerBlockSysMLname(((AvatarSetTimer) aos).getTimer().getName()) + ".'@set'" ,
((AvatarSetTimer)aos).getTimerValue()) + "\n");
indentation = indentation.substring(2 * indentStepSize);
unindent(2);
avsysml.append(indentation + ");\n");
// its transition
// put the associated transition
avsysml.append("\n" + indentation + "transition : '#AvatarTransition' first " + stateinfo.getPreName() +
" then " + stateinfo.getName() +
endTransition(0,"","", 1));
} else if (aos instanceof AvatarResetTimer) {
// preComm State
} else if (aos instanceof AvatarResetTimer) { // a special kind of send request
// put pre-communication State
avsysml.append("\n" + indentation + "state " + stateinfo.getPreName() + " : '#AvatarPreSendState' = '#AvatarPreSendState' (\n");
indent(1);
avsysml.append(indentation + "'@request' =\n");
indent(1);
// put the specific sending request, carrying no value
avsysml.append(resetTimerRequest2SysML(1, "0", "0",
timerBlockSysMLname(((AvatarResetTimer) aos).getTimer().getName()) + ".'@reset'" ) + "\n");
indentation = indentation.substring(2 * indentStepSize);
avsysml.append(indentation + ");\n");
// its transition
// put the associated transition
avsysml.append("\n" + indentation + "transition : '#AvatarTransition' first " + stateinfo.getPreName() +
" then " + stateinfo.getName() +
endTransition(0,"","", 1));
} else if (aos instanceof AvatarExpireTimer) {
} else if (aos instanceof AvatarExpireTimer) { // a special kind of send request
// put pre-communication State
avsysml.append("\n" + indentation + "state " + stateinfo.getPreName() + " : '#AvatarPreReceiveState' = '#AvatarPreReceiveState' (\n");
indent(1);
avsysml.append(indentation + "'@request' =\n");
indent(1);
// put the specific receiving request, carrying no value
avsysml.append(expireTimerRequest2SysML(1, "0", "0",
timerBlockSysMLname(((AvatarExpireTimer) aos).getTimer().getName()) + ".'@expire'" ) + "\n");
indentation = indentation.substring(2 * indentStepSize);
avsysml.append(indentation + ");\n");
// its transition
// put the associated transition
avsysml.append("\n" + indentation + "transition : '#AvatarTransition' first " + stateinfo.getPreName() +
endTransition(0,"","", 1));
indent(1);
avsysml.append(indentation + "then " + stateinfo.getName() + ";\n");
unindent(1);
}
}
}
}
/** distribution law information, to put at the end of associated the transition declarations */
String endTransition(int delayDistributionLaw, String delayExtra1, String delayExtra2, double probability){
if (delayDistributionLaw == DELAY_UNIFORM_LAW && probability == 1) return ";\n";
if (delayDistributionLaw == DELAY_UNIFORM_LAW && probability == 1) return ";\n"; // nothing because default
StringBuffer result = new StringBuffer(" {\n");
indent(1);
// put distribution law
result.append(indentation + "attribute '@delayDistributionLaw' : String = \"" + DISTRIBUTION_LAWS[delayDistributionLaw] + "\";\n");
if (probability != 1)
result.append(indentation + "attribute '@weight' : Real = " + probability + ";\n");
// put distribution law first parameter (if exists)
if (NB_OF_EXTRA_ATTRIBUTES[delayDistributionLaw] > 0)
result.append(indentation + "attribute '" + LABELS_OF_EXTRA_ATTRIBUTES_1[delayDistributionLaw] + "' : String = \""
+ delayExtra1 + "\";\n");
// put distribution law second parameter (if exists)
if (NB_OF_EXTRA_ATTRIBUTES[delayDistributionLaw] > 1)
result.append(indentation + "attribute '" + LABELS_OF_EXTRA_ATTRIBUTES_2[delayDistributionLaw] + "' : String = \""
+ delayExtra2 + "\";\n");
// put probability (if different from the default one)
if (probability != DEFAULT_PROBABILITY)
result.append(indentation + "attribute '@weight' : Real = " + probability + ";\n");
unindent(1);
result.append(indentation + "}\n");
return result.toString();
}
void transitionsAndRequests(String srcName, List<AvatarStateMachineElement> nexts, String poolName) {
/** computes transition declarations and request descriptions for the outgoing transitions of the state. Put the corresponding
* texts in the sysMLtransitions and sysMLrequests StringBuffers. While doing this, identify communication states that require
* an added pre-communication state.
* @param srcName name of the source state
* @param nexts outgoing transitions from the source state
* @param poolName "pool" or "request" depending on the number of allowed outgoing transitions
* @param stateMap to find state names
*/
void transitionsAndRequests(String srcName, List<AvatarStateMachineElement> nexts, String poolName,
HashMap<AvatarStateMachineElement,StateInfo> stateMap) {
// initialization
requirePreCom.clear();
sysMLtransitions.delete(0, sysMLtransitions.length());
sysMLrequests.delete(0, sysMLrequests.length());
int nb = nexts.size();
if (nb == 0) {
if (nb == 0) { // no transition
sysMLrequests.append(indentation + poolName + " = null\n");
return;
}
if (nb == 1) {
if (nb == 1) { // no parenthesis required
indent(1);
transitionAndRequest(srcName, (AvatarTransition)nexts.get(0), 0);
// handle the single transition
transitionAndRequest(srcName, (AvatarTransition)nexts.get(0), 0, stateMap);
unindent(1);
if(sysMLrequests.toString().trim().equals("'#immediate_request'")) {
if(sysMLrequests.toString().trim().equals("'#immediate_request'")) { // remove because it is the default
sysMLrequests.delete(0, sysMLrequests.length());
return;
}
// wrap without parenthesis
sysMLrequests.insert(0, indentation + poolName + " =\n");
return;
}
// more than one request -> list between parenthesis
indent(1);
// put list
for(int i=0; i<nb; i++){
transitionAndRequest(srcName, (AvatarTransition)nexts.get(i), i+1);
transitionAndRequest(srcName, (AvatarTransition)nexts.get(i), i+1, stateMap);
if(i != nb-1)
sysMLrequests.append(",\n");
else
sysMLrequests.append("\n");
}
unindent(1);
// wrap with parenthesis
sysMLrequests.insert(0, indentation + poolName + " = (\n");
sysMLrequests.append(indentation + ")");
}
private String clean_guard(String _guard) {
int open = _guard.indexOf('[');
int close = _guard.lastIndexOf(']');
......@@ -1043,7 +1131,7 @@ public class Avatar2SysML {
else return _guard;
}
// index is 0 if transition is alone
void transitionAndRequest(String srcName, AvatarTransition at, int index){
void transitionAndRequest(String srcName, AvatarTransition at, int index, HashMap<AvatarStateMachineElement, StateInfo> stateMap){
int transindex = ((index == 0) ? 1 : index);
// identifying cases
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment