diff --git a/src/main/java/avatartranslator/tosysmlv2/Avatar2SysML.java b/src/main/java/avatartranslator/tosysmlv2/Avatar2SysML.java new file mode 100644 index 0000000000000000000000000000000000000000..89405303587dfa64faca01b34d216114f7ff616f --- /dev/null +++ b/src/main/java/avatartranslator/tosysmlv2/Avatar2SysML.java @@ -0,0 +1,665 @@ +/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille + * + * ludovic.apvrille AT enst.fr + * + * This software is a computer program whose purpose is to allow the + * edition of TURTLE analysis, design and deployment diagrams, to + * allow the generation of RT-LOTOS or Java code from this diagram, + * and at last to allow the analysis of formal validation traces + * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP + * from INRIA Rhone-Alpes. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + */ +package avatartranslator.tosysmlv2; + +import avatartranslator.*; + +import static avatartranslator.tosysmlv2.Avatar2SysMLNames.*; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; + + + +public class Avatar2SysML { + + /** + * Memorized while declaring channels, to be reused for generating states + */ + class ChannelInfo { + private String name; + private String msgtype; + private ArrayList<String> profile; + ChannelInfo(String _name, String _msgtype) { + name = _name; + msgtype = _msgtype; + profile = new ArrayList<String>(); + } + public void addField(String _fieldName){ profile.add(_fieldName); } + public String getName(){ return name; } + public String getMessageType(){ return msgtype; } + public List<String> getProfile(){ return profile; } + } + /** + * Memorized while naming states, to be reused for generating states + */ + class StateInfo { + private String name; + private int number; + StateInfo(String _name, int _number) { + name = _name; + number = _number; + } + public String getName(){ return name; } + public int getNumber(){ return number; } + } + + public Avatar2SysML(AvatarSpecification _avspec) { avspec = _avspec; } + private AvatarSpecification avspec; + StringBuffer avsysml; + + HashMap<AvatarSignal, ChannelInfo> signalMap = new HashMap<AvatarSignal, ChannelInfo>(); + HashMap<AvatarStateMachineElement, StateInfo> stateMap = new HashMap<AvatarStateMachineElement, StateInfo>(); + ArrayList<AvatarStateMachineElement> stateList = new ArrayList<AvatarStateMachineElement>(); + + String header = "package AvatarInstance {\n" + + "import ScalarValues::Positive;\n" + + "import ScalarValues::Integer;\n" + + "import ScalarValues::Boolean;\n" + + "import AvatarBlockTypes::*;\n" + + "import AvatarCommunication::*;\n"; + + void avatar2SysML(AvatarSpecification _avspec) { + avspec = _avspec; + signalMap.clear(); + stateMap.clear(); + stateList.clear(); + avsysml = new StringBuffer(header); + communications2SysML(); + blocks2SysML(); + avsysml.append("}\n"); + } + void communications2SysML(){ + int nbfiforelNumber = 0; + int bfiforelNumber = 0; + int syncrelNumber = 0; + + avsysml.append("// COMMUNICATIONS $$$$$$$$$$$$$$$$$$$$$$$$\n"); + + for(AvatarRelation ar: avspec.getRelations()) { + + // parameters depending on relation type ============== + int relationType; + int relationNumber; + String relationConstructor; + String relationParameters = null; + String channelConstructor; + + // computine parameters depending on relation type ============== + // if (ar.isAMS()) throw exception + + if (! ar.isAsynchronous()) { // sync relation + relationType = SYNC; + relationNumber = syncrelNumber++; + relationConstructor = "'#Sync_Rel'"; + channelConstructor = "'#Sync'"; + if(ar.isPrivate()) relationParameters = "('private'=true)"; + } + else { // fifo relation + if(ar.isPrivate()) // default: false + if(ar.isLossy()) // default: false + if(ar.getSizeOfFIFO() > 1) // default size: 1 + relationParameters= "('private'=true, lossy=true, max_size=" + ar.getSizeOfFIFO() + ")"; + else + relationParameters= "('private'=true, lossy=true)"; + else + if(ar.getSizeOfFIFO() > 1) // default size: 1 + relationParameters= "('private'=true, max_size=" + ar.getSizeOfFIFO() + ")"; + else + relationParameters= "('private'=true)"; + else + if(ar.isLossy()) // default: false + if(ar.getSizeOfFIFO() > 1) // default size: 1 + relationParameters= "(lossy=true, max_size=" + ar.getSizeOfFIFO() + ")"; + else + relationParameters= "(lossy=true)"; + else + if(ar.getSizeOfFIFO() > 1) // default size: 1 + relationParameters= "(max_size=" + ar.getSizeOfFIFO() + ")"; + + if (ar.isBlocking()) { // blocking fifo relation + relationType = BFIFO; + relationNumber = bfiforelNumber++; + relationConstructor = "'#Bfifo_Rel'"; + channelConstructor = "'#Bfifo'"; + } + else { // non blocking fifo relation + relationType = NBFIFO; + relationNumber = nbfiforelNumber++; + relationConstructor = "'#NBfifo_Rel'"; + channelConstructor = "'#NBfifo'"; + } + } + + // general type-independent generation ============== + + String blk1 = ar.getBlock1().getName(); + String blk2 = ar.getBlock2().getName(); + String relationSYSMLname = relationSysMLname(blk1, blk2, relationType, relationNumber); + + // relation declaration -------------------- + + avsysml.append("// Relation " + relationSYSMLname + "=============\n"); + avsysml.append( "part " + relationSYSMLname + ": " + relationConstructor); + if(relationParameters != null) + avsysml.append(" = " + relationConstructor + relationParameters); + avsysml.append(";\n"); + + // Channels and associated Messages declarations ---------------- + + int relationSize = ar.getSignals1().size(); + for(int i=0; i<relationSize; i++) { + boolean in2out = true; + if (ar.getSignals1().get(i).getInOut() == AvatarSignal.OUT) in2out = false; + + String channelName = signalsName(blk1, blk2, + ar.getSignals1().get(i).getName(), ar.getSignals2().get(i).getName(),in2out ); + + String channelSYSMLname = channelSysMLname(channelName, relationType); + String messageSYSMLname = messageSysMLname(channelName); + + ChannelInfo channelInfo = new ChannelInfo(channelSYSMLname, messageSYSMLname); + + // Channel declaration ......................... + + avsysml.append("// Channel " + channelSYSMLname + "-------------\n"); + avsysml.append("part " + channelSYSMLname + " : " + channelConstructor + " = " + channelConstructor + "(relation = " + relationSYSMLname + ");\n"); + + + // Message declaration ......................... + + avsysml.append("part def " + messageSYSMLname + " :> '#DataMessage' {\n"); + + // message fields. SysML names preserve Avatar sender and receiver names + int channelSize = ar.getSignals1().get(i).getListOfAttributes().size(); + for (int j=0; j<channelSize; j++) { // browse channels' parameters + String fieldName = + fieldSysMLname( + ar.getSignals1().get(i).getListOfAttributes().get(j).getName() + "." + + ar.getSignals2().get(i).getListOfAttributes().get(j).getName() ); + + avsysml.append(" attribute " + fieldName +" : "); + if (ar.getSignals1().get(i).getListOfAttributes().get(j).isInt()) + avsysml.append("Integer;\n"); + else + avsysml.append("Boolean;\n"); + + channelInfo.addField(fieldName); + } + avsysml.append("}\n"); + + signalMap.put(ar.getSignals1().get(i),channelInfo); + signalMap.put(ar.getSignals2().get(i),channelInfo); + } + } + } + String indentStep = " "; + int indentStepSize = 4; + String indent; + + void attribute2SysML(AvatarAttribute aa, String prefix){ + avsysml.append(indent + prefix + "attribute " + attributeSysMLname(aa.getName() + " : ")); + if (aa.isInt()) avsysml.append("Integer;\n"); + else avsysml.append("Boolean;\n"); + } + + void method2SysML(AvatarMethod am){ + // "return tuple" not handled + String returnType = null; + if(am.getListOfReturnAttributes().size() == 1) + returnType = am.getListOfReturnAttributes().get(0).getType().getStringType(); + if (returnType == null) { + avsysml.append(indent + "action " + methodSysMLname(am.getName()) + ": '#AvatarVoidMethod' {\n"); + indent += indentStep; + for (AvatarAttribute aa : am.getListOfAttributes()) attribute2SysML(aa, "in "); + indent = indent.substring(indentStepSize); + avsysml.append(indent + "}\n"); + } else { + avsysml.append(indent + "calc " + methodSysMLname(am.getName()) + ": '#AvatarCalcMethod' {\n"); + indent += indentStep; + for (AvatarAttribute aa : am.getListOfAttributes()) attribute2SysML(aa, "in "); + avsysml.append(indent + "return : " + returnType + ";\n"); + indent = indent.substring(indentStepSize); + avsysml.append(indent + "}\n"); + } + } + + // handling one block + void block2SysML(AvatarBlock block){ + String blockSYSMLname = blockSysMLname(block.getName()); + + // block header -------------------- + avsysml.append(indent + "// Block " + blockSYSMLname + "=============\n"); + avsysml.append(indent + "part " + blockSYSMLname + " : '#AvatarBlock' {\n"); + indent += indentStep; + + // attributes -------------------- + for (AvatarAttribute aa : block.getAttributes()) attribute2SysML(aa, ""); + + // methods -------------------- + for (AvatarMethod am : block.getMethods()) method2SysML(am); + + // state-machine -------------------- + statemachine2SysML(block.getStateMachine()); + + // sub-blocks ------------------- + for(AvatarBlock blk: avspec.getListOfBlocks()) { if (blk.getFather() == block) block2SysML(blk); } + + indent = indent.substring(indentStepSize); + avsysml.append(indent + "}\n"); + } + + // handling all blocks + void blocks2SysML(){ + indent = ""; + avsysml.append("// BLOCKS $$$$$$$$$$$$$$$$$$$$$$$$\n"); + for(AvatarBlock block: avspec.getListOfBlocks()) + if (block.getFather() == null) block2SysML(block); + } + + void statemachine2SysML(AvatarStateMachine asm) { + + // associate names to future SysML states + int stateNumber = 0; + int randomNumber = 0; + int countNumber = 0; + int sendNumber = 0; + int receiveNumber = 0; + for (AvatarStateMachineElement asme : asm.getListOfElements()) { + StateInfo stateinfo; + if (asme instanceof AvatarStartState) + stateinfo = new StateInfo(startStateSysMLname(), 0); + else if (asme instanceof AvatarStopState) + stateinfo = new StateInfo(stopStateSysMLname(), 0); + else if (asme instanceof AvatarState) + stateinfo = new StateInfo(standardStateSysMLname(stateNumber), stateNumber++); + else if (asme instanceof AvatarActionOnSignal) { + if(((AvatarActionOnSignal)asme).isSending()) + stateinfo = new StateInfo(sendStateSysMLname(stateNumber), sendNumber++); + else + stateinfo = new StateInfo(receiveStateSysMLname(stateNumber), receiveNumber++); + } + else if (asme instanceof AvatarQueryOnSignal) + stateinfo = new StateInfo(countStateSysMLname(stateNumber), countNumber++); + else if (asme instanceof AvatarRandom) + stateinfo = new StateInfo(randomStateSysMLname(stateNumber), randomNumber++); + else continue; + stateList.add(asme); + stateMap.put(asme, stateinfo); + } + avsysml.append(indent + "// state-machine description +++++\n" + + indent + "exhibit state '@statemachine' : '#AvatarStateMachine' {\n"); + indent += indentStep; + // generate SysML states with associated transitions + for (AvatarStateMachineElement asme : stateList) state2SysML(asme); + indent = indent.substring(indentStepSize); + avsysml.append(indent + "}\n"); + } + StringBuffer sysMLtransitions; + StringBuffer sysMLrequests; + List<AvatarActionOnSignal> requirePreCom; + + void state2SysML(AvatarStateMachineElement asme){ + indent += indentStep; + transitionsAndRequests(stateMap.get(asme).getName(), asme.getNexts(), ((asme instanceof AvatarState) ? "pool" : "request")); + indent = indent.substring(indentStepSize); + + String requests = sysMLrequests.toString(); + + // State Description, depending on state type + + if(asme instanceof AvatarState){ + avsysml.append("state " + stateMap.get(asme).getName() + " : '#AvatarStandardState'"); + if (requests.equals("")) + avsysml.append(";\n"); + else + avsysml.append(" = '#AvatarStandardState'(\n" + requests + "\n);\n"); + } else + + if(asme instanceof AvatarRandom){ + avsysml.append("state " + stateMap.get(asme).getName() + " : '#AvatarRandomState' = '#AvatarRandomState'(\n"); + if (!requests.equals("")) avsysml.append(requests); + avsysml.append(indent + "state_action = '#Assignment'(\n"); + indent += indentStep; + avsysml.append(indent + "target = " + attributeSysMLname(((AvatarRandom)asme).getVariable()) + ",\n"); + avsysml.append(indent + "value = '#bound_random'(" + expr2SysML(((AvatarRandom)asme).getMinValue()) + ", " + expr2SysML(((AvatarRandom)asme).getMaxValue()) +")\n"); + indent = indent.substring(indentStepSize); + avsysml.append(indent + ")\n"); + indent = indent.substring(indentStepSize); + avsysml.append(indent + ");\n"); + } else + + if(asme instanceof AvatarQueryOnSignal){ + avsysml.append("state " + stateMap.get(asme).getName() + " : '#AvatarCountState' = '#AvatarCountState'(\n"); + if (!requests.equals("")) avsysml.append(requests); + avsysml.append(indent + "state_action = '#Assignment'(\n"); + indent += indentStep; + avsysml.append(indent + "target = " + attributeSysMLname(((AvatarQueryOnSignal)asme).getAttribute().getName()) + ",\n"); + avsysml.append(indent + "value = " + signalMap.get(((AvatarQueryOnSignal)asme).getSignal()).getName() + ".amount()\n"); + indent = indent.substring(indentStepSize); + avsysml.append(indent + ")\n"); + indent = indent.substring(indentStepSize); + avsysml.append(indent + ");\n)"); + } else + + if(asme instanceof AvatarActionOnSignal){ + if(((AvatarActionOnSignal)asme).isSending()) { + avsysml.append("state " + stateMap.get(asme).getName() + " : '#AvatarSendState'"); + if (requests.equals("")) + avsysml.append(";\n"); + else + avsysml.append(" = '#AvatarSenddState'(\n" + requests + "\n);\n"); + } else { + avsysml.append("state " + stateMap.get(asme).getName() + " : '#AvatarReceiveState'"); + if (requests.equals("")) + avsysml.append(";\n"); + else + avsysml.append(" = '#AvatarReceiveState'(\n" + requests + "\n);\n"); + } + } else + + if(asme instanceof AvatarStartState){ + avsysml.append("state " + stateMap.get(asme).getName() + " :'#AvatarStartState'"); + if (requests.equals("")) + avsysml.append(";\n"); + else + avsysml.append(" = '#AvatarStartState'(\n" + requests + "\n);\n"); + } else + + if(asme instanceof AvatarStopState){ + avsysml.append("state " + stateMap.get(asme).getName() + " :'#AvatarStopState'"); + if (requests.equals("")) + avsysml.append(";\n"); + else + avsysml.append(" = '#AvatarStopState'(\n" + requests + "\n);\n"); + } + + // Transition descriptions + avsysml.append(sysMLtransitions); + + // PreComm States and their outgoing transition + for (AvatarActionOnSignal aos: requirePreCom) { + StateInfo stateinfo = stateMap.get(asme); + ChannelInfo signalinfo = signalMap.get(((AvatarActionOnSignal)asme).getSignal()); + + if (((AvatarActionOnSignal)asme).isSending()) { + String prestatename = presendStateSysMLname(stateinfo.getNumber()); + + // preComm State + avsysml.append(indent + "state " + prestatename + " : '#AvatarPreSendState' = '#AvatarPreSendState' (\n"); + indent += indentStep; + avsysml.append(indent + "request =\n"); + indent += indentStep; + avsysml.append(sendRequest2SysML(1, "0", "0", signalinfo, ((AvatarActionOnSignal) asme).getValues())); + indent = indent.substring(2 * indentStepSize); + avsysml.append(indent + ");\n"); + // its transition + sysMLtransitions.append(indent + "transition : '#AvatarTransition' first " + prestatename + + " then " + stateinfo.getName() + ";\n"); + } else { + String prestatename = prereceiveStateSysMLname(stateinfo.getNumber()); + avsysml.append(indent + "state " + prestatename + " : '#AvatarPreReceiveState' = '#AvatarPreReceiveState' (\n"); + indent += indentStep; + avsysml.append(indent + "request =\n"); + indent += indentStep; + avsysml.append(receiveRequest2SysML(1, "0", "0", signalinfo)); + indent = indent.substring(2 * indentStepSize); + avsysml.append(indent + ");\n"); + // its transition + sysMLtransitions.append(indent + "transition : '#AvatarTransition' first " + prestatename + "\n"); + indent += indentStep; + String doAction = receiveActions2SysM(signalinfo, ((AvatarActionOnSignal)asme).getValues()); + if (doAction.length() == 0) + sysMLtransitions.append(indent + "then " + stateinfo.getName() + ";\n"); + else { + sysMLtransitions.append(doAction); + sysMLtransitions.append(" then " + stateinfo.getName() + ";\n"); + } + indent = indent.substring(indentStepSize); + } + } + } + void transitionsAndRequests(String srcName, List<AvatarStateMachineElement> nexts, String poolName) { + sysMLtransitions.delete(0, sysMLtransitions.length()); + sysMLrequests.delete(0, sysMLrequests.length()); + int nb = nexts.size(); + if (nb == 0) { + sysMLrequests.append(indent + "null;"); + return; + } + if (nb == 1) { + indent += indentStep; + transitionAndRequest(srcName, (AvatarTransition)nexts.get(0), 0); + indent = indent.substring(indentStepSize); + + if(sysMLrequests.toString().trim().equals("'#immediate_transition'")) { + sysMLrequests.delete(0, sysMLrequests.length()); + return; + } + sysMLrequests.insert(0, indent + poolName + " =\n"); + sysMLrequests.append("\n"); + return; + } + indent += indentStep; + for(int i=0; i<nb; i++){ + transitionAndRequest(srcName, (AvatarTransition)nexts.get(i), i+1); + if(i != nb-1) + sysMLrequests.append(",\n"); + else + sysMLrequests.append("\n"); + } + indent = indent.substring(indentStepSize); + sysMLrequests.insert(0, indent + poolName + " = (\n"); + sysMLrequests.append("\n)\n"); + } + // index is 0 if transition is alone + void transitionAndRequest(String srcName, AvatarTransition at, int index){ + int transindex = ((index == 0) ? 1 : index); + + // identifying cases + boolean guarded = !at.hasNonDeterministicGuard(); + AvatarStateMachineElement target = at.getNext(0); + String tgtName; + int requestType = 0; // 0:trivial, 1:Send, 2:Receive + + if((at.getActions()!=null && at.getActions().size()!=0) && target instanceof AvatarActionOnSignal) { // preCommunication Required + requirePreCom.add((AvatarActionOnSignal)target); + if (((AvatarActionOnSignal)target).isSending()) + tgtName = presendStateSysMLname(stateMap.get(target).getNumber()); + else + tgtName = prereceiveStateSysMLname(stateMap.get(target).getNumber()); + } + else { + tgtName = stateMap.get(target).getName(); + if(target instanceof AvatarActionOnSignal){ + if (((AvatarActionOnSignal)target).isSending()) + requestType = 1; + else + requestType = 2; + } + } + + // computing request + if (guarded) { + sysMLrequests.append(indent + "if " + expr2SysML(((AvatarTransition)at).getGuard().toString()) + " ?\n"); + indent += indentStep; + } + + if(requestType == 0) // Trivial + sysMLrequests.append(trivialRequest2SysML(transindex, + expr2SysML(at.getMinDelay().toString()), + expr2SysML(at.getMaxDelay().toString()))); + else if (requestType == 1) // Send + sysMLrequests.append(sendRequest2SysML(transindex, + expr2SysML(at.getMinDelay().toString()), + expr2SysML(at.getMaxDelay().toString()), + signalMap.get(((AvatarActionOnSignal)target).getSignal()), + ((AvatarActionOnSignal)target).getValues())); + else // Receive + sysMLrequests.append(receiveRequest2SysML(transindex, + expr2SysML(at.getMinDelay().toString()), + expr2SysML(at.getMaxDelay().toString()), + signalMap.get(((AvatarActionOnSignal)target).getSignal()))); + if(guarded) { + indent = indent.substring(indentStepSize); + sysMLrequests.append(indent + "else '#nok_request'(" + transindex + ")"); + } + + // computing transition + String doAction; + indent += indentStep; + if(requestType == 2) + doAction = receiveActions2SysM(signalMap.get(((AvatarActionOnSignal)target).getSignal()), ((AvatarActionOnSignal)target).getValues()); + else + doAction = transitionActions2SysM(at.getActions()); + indent = indent.substring(indentStepSize); + + sysMLtransitions.append(indent + "transition : '#AvatarTransition' first " + srcName); + if(index > 0) + sysMLtransitions.append(" if response.transition_index == " + index + "\n"); + else + sysMLtransitions.append("\n"); + indent += indentStep; + if (doAction.length() == 0) + sysMLtransitions.append(indent + "then " + tgtName + ";\n"); + else { + sysMLtransitions.append(doAction); + sysMLtransitions.append(" then " + tgtName + ";\n"); + } + indent = indent.substring(indentStepSize); + } + String trivialRequest2SysML(int index, String min, String max) { + if (max.equals("0")) + if (min.equals("0")) + if (index == 1) + return indent + "'#immediate_request'"; + else + return indent + "'#TrivialRequest'(transition_index= " + index + ")"; + else + if (index == 1) + return indent + "'#TrivialRequest'(delay= " + min + ")"; + else + return indent + "'#TrivialRequest'(transition_index= " + index + ", delay= " + min + ")"; + else + if(index == 1) + return indent + "'#TrivialRequest'(delay= '#bound_random'(" + min + ", " + max + "))"; + else + return indent + "'#TrivialRequest'(transition_index= " + index + ", delay= '#bound_random'(" + min + ", " + max + "))"; + } + + String sendRequest2SysML(int index, String min, String max, ChannelInfo chinfo, List<String> values) { + StringBuffer result = new StringBuffer(indent + "’#SendRequest’(\n"); + indent += indentStep; + result.append(indent + "transition_index= " + index + ",\n" + + indent + "channel= " + chinfo.getName() + ",\n"); + if (max.equals("0")) { + if (!min.equals("0")) + result.append(indent + "delay= " + min + ",\n"); + } + else + result.append(indent + "delay= '#bound_random'(" + min + ", " + max + "),\n"); + if (values.size() == 0) + result.append(indent + "payload= " + chinfo.getMessageType() + "()\n"); + else { + result.append(indent + "payload= " + chinfo.getMessageType() + "(\n"); + indent += indentStep; + for(String vl : values) + result.append(indent + expr2SysML(vl) + ",\n"); + result.replace(result.length()-2, result.length(), " )\n"); + indent = indent.substring(indentStepSize); + } + indent = indent.substring(indentStepSize); + result.append(indent + ")\n"); + return result.toString(); + } + + String receiveRequest2SysML(int index, String min, String max, ChannelInfo chinfo) { + StringBuffer result = new StringBuffer(indent + "’#ReceiveRequest’(\n"); + indent += indentStep; + result.append(indent + "transition_index= " + index + ",\n" + + indent + "channel= " + chinfo.getName()); + if (max.equals("0")) + if (!min.equals("0")) + result.append(",\n" + indent + "delay= " + min + "\n"); + else + result.append("\n"); + else + result.append(",\n" + indent + "delay= '#bound_random'(" + min + ", " + max + ")\n"); + indent = indent.substring(indentStepSize); + result.append(indent + ")\n"); + return result.toString(); + } + String transitionActions2SysM(List<AvatarAction> aas) { + StringBuffer result; + if (aas == null || aas.size() == 0) return ""; + result = new StringBuffer(indent + "do action (\n" + indent + indentStep + "first start;\n"); + indent += indentStep; + for(AvatarAction aa : aas) { + if(aa instanceof AvatarActionAssignment) { + AvatarLeftHand lh = ((AvatarActionAssignment)aa).getLeftHand(); + if(lh instanceof AvatarAttribute) { // tuples are not yet handled + result.append(indent + "then assign " + attributeSysMLname(aa.getName()) + ":= "); + result.append(expr2SysML(((AvatarActionAssignment)aa).getRightHand().getName()) + ";\n"); + } + } + else { + result.append(indent + "then action = " + expr2SysML(aa.getName()) + ";\n"); + } + } + indent = indent.substring(indentStepSize); + result.append(indent + ")"); + return result.toString(); + } + + String receiveActions2SysM(ChannelInfo chinfo, List<String> values) { + if (values != null && values.size() != 0) return ""; + StringBuffer result = new StringBuffer(indent + "do action (\n"); + indent += indentStep; + result.append(indent + "item msg : " + chinfo.getMessageType() + " = response.payload as " + chinfo.getMessageType() + + ";\n" + indent + "first start;\n"); + List<String> fields = chinfo.getProfile(); + int length = values.size(); // must be equal to fields.size() + for (int i = 0; i<length; i++) { + result.append("then assign " + attributeSysMLname(values.get(i)) + " := msg." + fields.get(i) + ";\n"); + } + indent = indent.substring(indentStepSize); + result.append(indent + ")"); + return result.toString(); + } + +} diff --git a/src/main/java/avatartranslator/tosysmlv2/Avatar2SysMLNames.java b/src/main/java/avatartranslator/tosysmlv2/Avatar2SysMLNames.java new file mode 100644 index 0000000000000000000000000000000000000000..95aecb0c9a36a3509c3d473c3b3924a73e8b55f1 --- /dev/null +++ b/src/main/java/avatartranslator/tosysmlv2/Avatar2SysMLNames.java @@ -0,0 +1,82 @@ +/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille + * + * ludovic.apvrille AT enst.fr + * + * This software is a computer program whose purpose is to allow the + * edition of TURTLE analysis, design and deployment diagrams, to + * allow the generation of RT-LOTOS or Java code from this diagram, + * and at last to allow the analysis of formal validation traces + * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP + * from INRIA Rhone-Alpes. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + */ +package avatartranslator.tosysmlv2; + +public class Avatar2SysMLNames { + public final static int SYNC = 0; + public final static int BFIFO = 1; + public final static int NBFIFO = 2; + + public static String blockSysMLname(String name){ return "'@blk:" + name + "'"; } + public static String attributeSysMLname(String name){ return "'$" + name + "'"; } + public static String methodSysMLname(String name){ return "'$" + name + "'"; } + public static String fieldSysMLname(String name){ return "'" + name + "'"; } + + public static String relationSysMLname(String b1, String b2, int type, int n){ + if (type == NBFIFO) return "'@NBF" + n + ":" + b1 + "-" + b2 + "'"; + if (type == BFIFO) return "'@BF" + n + ":" + b1 + "-" + b2 + "'"; + if (type == SYNC) return "'@SYN" + n + ":" + b1 + "-" + b2 + "'"; + return ""; + } + public static String signalsName(String b1, String b2, String s1, String s2, boolean in2out){ + if(in2out) return b1 + "." + s1 + ">" + b2 + "." + s2; + else return b1 + "." + s1 + "<" + b2 + "." + s2; + } + + public static String channelSysMLname(String _signalname, int type){ + if (type == NBFIFO) return "'@nbf:" + _signalname + "'"; + if (type == BFIFO) return "'@bf:" + _signalname + "'"; + if (type == SYNC) return "'@syn:" + _signalname + "'"; + return ""; + } + public static String messageSysMLname(String _signalsname){ return "'@MSG:" + _signalsname + "'"; } + + public static String startStateSysMLname(){ return "'@st:start'"; } + public static String stopStateSysMLname(){ return "'@st:stop'"; } + public static String standardStateSysMLname(int number){ return "'@st:state" + number + "'"; } + public static String randomStateSysMLname(int number){ return "'@st:random" + number + "'"; } + public static String countStateSysMLname(int number){ return "'@st:count" + number + "'"; } + public static String sendStateSysMLname(int number){ return "'@st:send" + number + "'"; } + public static String receiveStateSysMLname(int number){ return "'@st:receive" + number + "'"; } + public static String presendStateSysMLname(int number){ return "'@st:presend" + number + "'"; } + public static String prereceiveStateSysMLname(int number){ return "'@st:prereceive" + number + "'"; } + + public static String expr2SysML(String _expr){ return "expression"; } // TO IMPLEMENT + +} +