Skip to content
Snippets Groups Projects
Avatar2SysML.java 57.7 KiB
Newer Older
Sophie Coudert's avatar
Sophie Coudert committed
/* 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.AvatarTransition.*;
Sophie Coudert's avatar
Sophie Coudert committed
import static avatartranslator.tosysmlv2.Avatar2SysMLNames.*;
import java.util.HashMap;
import java.util.HashSet;
Sophie Coudert's avatar
Sophie Coudert committed
import java.util.List;
import java.util.ArrayList;



public class Avatar2SysML {

    /**
     * Memorized while declaring channels, to be reused for generating states
     */
    class MethodInfo {
        private String msgtype; // null for methods that are not signals
        private ArrayList<String> fieldNames;
Sophie Coudert's avatar
Sophie Coudert committed
        private ArrayList<AvatarType> fieldTypes;
        private ArrayList<AvatarDataType> dataTypes;
Sophie Coudert's avatar
Sophie Coudert committed
        private AvatarType returnType;
        private AvatarDataType returnDataType;

       MethodInfo(String _name) { // for void methods
            msgtype = null;
            fieldNames = new ArrayList<String>();
Sophie Coudert's avatar
Sophie Coudert committed
            fieldTypes = new ArrayList<AvatarType>();
Sophie Coudert's avatar
Sophie Coudert committed
            dataTypes = new ArrayList<AvatarDataType>();
Sophie Coudert's avatar
Sophie Coudert committed
            returnType = null;
            returnDataType = null;
Sophie Coudert's avatar
Sophie Coudert committed
       MethodInfo(String _name, AvatarType _returnType, AvatarDataType dt) { // for non-void methods
            name = _name;
            msgtype = null;
            fieldNames = new ArrayList<String>();
Sophie Coudert's avatar
Sophie Coudert committed
            fieldTypes = new ArrayList<AvatarType>();
Sophie Coudert's avatar
Sophie Coudert committed
            dataTypes = new ArrayList<AvatarDataType>();
            returnType = _returnType;
Sophie Coudert's avatar
Sophie Coudert committed
            if (_returnType != AvatarType.UNDEFINED)
                returnDataType = null;
            else
                returnDataType = dt;
        }
       MethodInfo(String _name, String _msgtype) { // for signals
            name = _name;
            msgtype = _msgtype;
            fieldNames = new ArrayList<String>();
Sophie Coudert's avatar
Sophie Coudert committed
            fieldTypes = new ArrayList<AvatarType>();
Sophie Coudert's avatar
Sophie Coudert committed
            dataTypes = new ArrayList<AvatarDataType>();
Sophie Coudert's avatar
Sophie Coudert committed
            returnType = null;
            returnDataType = null;
       }
Sophie Coudert's avatar
Sophie Coudert committed
       public void addField(String _fieldName, AvatarType _type, AvatarDataType _dt){
           if (_type == AvatarType.UNDEFINED)
               dataTypes.add(_dt);
Sophie Coudert's avatar
Sophie Coudert committed
           else if (!(_type == AvatarType.BOOLEAN || _type == AvatarType.INTEGER))
               return; // unknown type
Sophie Coudert's avatar
Sophie Coudert committed
           else
               dataTypes.add(null);
           fieldNames.add(_fieldName);
           fieldTypes.add(_type);
       }
       public int getArity() { return fieldNames.size(); }
       public String getName(){ return name; }
       public String getMessageType(){ return msgtype; }
Sophie Coudert's avatar
Sophie Coudert committed
       public AvatarType getReturnType(){ return returnType; }
       public AvatarDataType getReturnDataType(){ return returnDataType; }
       public String getFieldName(int i){ return fieldNames.get(i); }
Sophie Coudert's avatar
Sophie Coudert committed
       public AvatarType getFieldType(int i){ return fieldTypes.get(i); }
       public AvatarDataType getDataType(int i){ return dataTypes.get(i); }
Sophie Coudert's avatar
Sophie Coudert committed
   /**
     * Memorized while naming states, to be reused for generating states
     */
Sophie Coudert's avatar
Sophie Coudert committed
   class StateInfo {
Sophie Coudert's avatar
Sophie Coudert committed
       private String name;
       private String prename = "";
        StateInfo(String _name) {
            name = _name;
        }
        StateInfo(String _name, String _prename) {
Sophie Coudert's avatar
Sophie Coudert committed
            name = _name;
Sophie Coudert's avatar
Sophie Coudert committed
            prename = _prename;
Sophie Coudert's avatar
Sophie Coudert committed
        }
        public String getName(){ return name; }
Sophie Coudert's avatar
Sophie Coudert committed
        public String getPreName(){ return prename; }
Sophie Coudert's avatar
Sophie Coudert committed
   }
Sophie Coudert's avatar
Sophie Coudert committed

    public Avatar2SysML(AvatarSpecification _avspec) { avspec = _avspec; }
    private AvatarSpecification avspec;
    StringBuffer avsysml;

    HashSet<AvatarSignal> fifoSet = new HashSet<AvatarSignal>();
    HashMap<AvatarMethod, MethodInfo> methodMap = new HashMap<AvatarMethod, MethodInfo>();
Sophie Coudert's avatar
Sophie Coudert committed
    HashMap<AvatarStateMachineElement, StateInfo> stateMap = new HashMap<AvatarStateMachineElement, StateInfo>();
    ArrayList<AvatarStateMachineElement> stateList = new ArrayList<AvatarStateMachineElement>();
    ArrayList<AvatarAttribute> timerList = new ArrayList<AvatarAttribute>();
Sophie Coudert's avatar
Sophie Coudert committed

    void searchCountSignals() {
        fifoSet.clear();
        for(AvatarBlock block: avspec.getListOfBlocks()) {
            for(AvatarStateMachineElement sme : block.getStateMachine().getListOfElements()) {
                    if(sme instanceof AvatarQueryOnSignal)
                        fifoSet.add(((AvatarQueryOnSignal) sme).getSignal());
            }
        }
    }
Sophie Coudert's avatar
Sophie Coudert committed
    ArrayList<String> blockChain = new ArrayList<String>();
    void chainBlock(String _block) { blockChain.add(_block); }
    void unchainBlock() { if(blockChain.size() > 0) blockChain.remove(blockChain.size() - 1); }
    void blocklink() {
Sophie Coudert's avatar
Sophie Coudert committed
        int size = blockChain.size();
        if (size < 2) return;
Sophie Coudert's avatar
Sophie Coudert committed
        StringBuffer chain = new StringBuffer();
Sophie Coudert's avatar
Sophie Coudert committed
        for (int i=0; i < size-1; i++){
            chain.append(blockChain.get(i) + ".");
        }
Sophie Coudert's avatar
Sophie Coudert committed
        chain.append(blockChain.get(size - 1));
        blockLinks.append( indentStep + "part " + blockChain.get(size - 1) +
                " : '#AvatarBlock' :> " + chain.toString() + " = " + chain.toString() + ";\n" );
Sophie Coudert's avatar
Sophie Coudert committed
    }
    StringBuffer blockLinks = new StringBuffer();

Sophie Coudert's avatar
Sophie Coudert committed
    String indentStep = "    ";
    int indentStepSize = 4;
    String indent = "";
Sophie Coudert's avatar
Sophie Coudert committed
    String header = "package AvatarInstance {\n" +
        indentStep + "import ScalarValues::String;\n" +
Sophie Coudert's avatar
Sophie Coudert committed
        indentStep + "import ScalarValues::Positive;\n" +
        indentStep + "import ScalarValues::Integer;\n" +
        indentStep + "import ScalarValues::Boolean;\n" +
        indentStep + "import ScalarValues::Real;\n" +
Sophie Coudert's avatar
Sophie Coudert committed
        indentStep + "import AvatarBlockTypes::*;\n" +
        indentStep + "import AvatarCommunication::*;\n";

Sophie Coudert's avatar
Sophie Coudert committed

    StringBuffer avatar2SysML() {
        methodMap.clear();
Sophie Coudert's avatar
Sophie Coudert committed
        stateMap.clear();
        stateList.clear();
Sophie Coudert's avatar
Sophie Coudert committed
        blockChain.clear();
        blockLinks = new StringBuffer(indentStep + "// Block Shortcut Links $$$$$$$$$$$$\n");
Sophie Coudert's avatar
Sophie Coudert committed
        avsysml = new StringBuffer(header);
Sophie Coudert's avatar
Sophie Coudert committed
        indent += indentStep;
        searchCountSignals();;
        dataTypes2SysML();
Sophie Coudert's avatar
Sophie Coudert committed
        communications2SysML();
        blocks2SysML();
Sophie Coudert's avatar
Sophie Coudert committed
        avsysml.append(blockLinks);
Sophie Coudert's avatar
Sophie Coudert committed
        //AvatarFromSysML parser = new AvatarFromSysML();
        //parser.sysMLtoSpec(avsysml.toString()); /// !!!!!!!!!!!!!! TESTEUR
Sophie Coudert's avatar
Sophie Coudert committed
        return avsysml;
Sophie Coudert's avatar
Sophie Coudert committed
    }
Sophie Coudert's avatar
Sophie Coudert committed
    String removeFieldName(String fullName, int index, AvatarDataType dt) {
        if (fullName == null || dt.getAttributeNb() -1 < index) return fullName;
        String fieldString = dt.getFieldString(index);
Sophie Coudert's avatar
Sophie Coudert committed
        int prefixSize = fullName.length() - fieldString.length() - 2;
        if (fieldString.equals(fullName.substring(fullName.length() - fieldString.length()))
            && prefixSize >= 0)
            return fullName.substring(0, prefixSize);
        else
            return null;
    }
    void dataTypes2SysML(){
        if (avspec.getDataTypes() == null || avspec.getDataTypes().size() == 0) return;
        avsysml.append("\n" + indent + "// DATATYPES $$$$$$$$$$$$$$$$$$$$$$$$\n");
        for(AvatarDataType dt : avspec.getDataTypes()){
Sophie Coudert's avatar
Sophie Coudert committed
            avsysml.append("\n" + indent + "attribute def " + dataTypeSysMLname(dt.getName()) + " :> '#AvatarDataType'");
Sophie Coudert's avatar
Sophie Coudert committed
            int nbFields = dt.getAttributeNb();
            if (nbFields == 0)
                avsysml.append(";\n");
            else {
                avsysml.append(" { \n");
                indent += indentStep;
                for (int i = 0; i < nbFields; i++) {
Sophie Coudert's avatar
Sophie Coudert committed
                    avsysml.append( indent + "attribute " + fieldSysMLname(dt.getAttribute(i).getName()) + " : " );
                    if (dt.getAttribute(i).getType() == AvatarType.BOOLEAN)
                        avsysml.append("Boolean;\n");
Sophie Coudert's avatar
Sophie Coudert committed
                    else if (dt.getAttribute(i).getType() == AvatarType.INTEGER)
                        avsysml.append("Integer;\n");
                    else
                        avsysml.append(dt.getDataTypeName(i) + ";\n");
                }
                indent = indent.substring(indentStepSize);
                avsysml.append(indent + "}\n");
            }
        }
    }
Sophie Coudert's avatar
Sophie Coudert committed
    void communications2SysML(){
        int nbfiforelNumber = 0;
        int bfiforelNumber = 0;
        int syncrelNumber = 0;

        if (avspec.getRelations() == null || avspec.getRelations().size() == 0) return;
Sophie Coudert's avatar
Sophie Coudert committed

        avsysml.append("\n" + indent + "// COMMUNICATIONS $$$$$$$$$$$$$$$$$$$$$$$$\n");
Sophie Coudert's avatar
Sophie Coudert committed
        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
            String blk1 = ar.getBlock1().getName();
            String blk2 = ar.getBlock2().getName();
            String blk1SysMLname = blockSysMLname(blk1);
            String blk2SysMLname = blockSysMLname(blk2);
            relationParameters = "('@block1' = " + blk1SysMLname + ", '@block2' = " + blk2SysMLname;
Sophie Coudert's avatar
Sophie Coudert committed
            if (! ar.isAsynchronous()) { // sync relation
                relationType = SYNC;
                relationNumber = syncrelNumber++;
                relationConstructor = "'#Sync_Rel'";
                channelConstructor = "'#Sync'";
                if(ar.isPrivate()) relationParameters += ", '@private'=true)";
Sophie Coudert's avatar
Sophie Coudert committed
            }
            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() + ")";
Sophie Coudert's avatar
Sophie Coudert committed
                        else
                            relationParameters += ", '@private'=true, '@lossy'=true)";
Sophie Coudert's avatar
Sophie Coudert committed
                    else
                        if(ar.getSizeOfFIFO() > 1) // default size: 1
                            relationParameters += ", '@private'=true, '@max_size'=" + ar.getSizeOfFIFO() + ")";
Sophie Coudert's avatar
Sophie Coudert committed
                        else
                            relationParameters += ", '@private'=true)";
Sophie Coudert's avatar
Sophie Coudert committed
                else
                    if(ar.isLossy()) // default: false
                        if(ar.getSizeOfFIFO() > 1) // default size: 1
                            relationParameters += ", '@lossy'=true, '@max_size'=" + ar.getSizeOfFIFO() + ")";
Sophie Coudert's avatar
Sophie Coudert committed
                        else
                            relationParameters += ", '@lossy'=true)";
Sophie Coudert's avatar
Sophie Coudert committed
                    else
                        if(ar.getSizeOfFIFO() > 1) // default size: 1
                            relationParameters += ", '@max_size'=" + ar.getSizeOfFIFO() + ")";
Sophie Coudert's avatar
Sophie Coudert committed

                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 relationSYSMLname = relationSysMLname(blk1, blk2, relationType, relationNumber);

            // relation declaration --------------------

            avsysml.append("\n" + indent + "// Relation " + relationSYSMLname + "=============\n");
Sophie Coudert's avatar
Sophie Coudert committed
            avsysml.append(indent + "part " +  relationSYSMLname + ": " + relationConstructor);
Sophie Coudert's avatar
Sophie Coudert committed
            if(relationParameters != null)
                 avsysml.append(" = " + relationConstructor + relationParameters);
Sophie Coudert's avatar
Sophie Coudert committed

            // Channels and associated Messages declarations ----------------

            int relationSize = ar.getSignals1().size();
            for(int i=0; i<relationSize; i++) {
                AvatarSignal sig1 = ar.getSignals1().get(i);
                AvatarSignal sig2 = ar.getSignals2().get(i);
                boolean in2out = (sig1.getInOut() == AvatarSignal.IN);

                // to remove
                String channelName = channelName(blk1, blk2, sig1.getName(), sig2.getName(), in2out);

                String channelSYSMLname = channelSysMLname(channelName(blk1, blk2, sig1.getName(), sig2.getName(), in2out), relationType);
                String sig1SYSMLname = signalSysMLname(sig1.getName());
                String sig2SYSMLname = signalSysMLname(sig2.getName());
                String message1SYSMLname = messageSysMLname(blk1,sig1.getName());
                String message2SYSMLname = messageSysMLname(blk2,sig2.getName());
                MethodInfo sig1Info = new MethodInfo(sig1SYSMLname, message1SYSMLname);
                MethodInfo sig2Info = new MethodInfo(sig2SYSMLname, message2SYSMLname);
Sophie Coudert's avatar
Sophie Coudert committed

                // Channel declaration .........................

                avsysml.append("\n" + indent + "// Channel " + channelSYSMLname + "-------------\n");
Sophie Coudert's avatar
Sophie Coudert committed
                avsysml.append(indent + "part " + channelSYSMLname + " : " + channelConstructor + " = "
                        + channelConstructor + "('@relation' = " + relationSYSMLname + ");\n");
                    avsysml.append(indent + "binding : '#InSignalBinding' bind " + blk1SysMLname + "." + sig1SYSMLname + " = " + channelSYSMLname +
                            ";\n");
                    avsysml.append(indent + "binding : '#OutSignalBinding' bind " + blk2SysMLname + "." + sig2SYSMLname + " = " + channelSYSMLname +
                            ";\n");
                    avsysml.append(indent + "binding : '#OutSignalBinding' bind " + blk1SysMLname + "." + sig1SYSMLname + " = " + channelSYSMLname + ";\n");
                    avsysml.append(indent + "binding : '#InSignalBinding' bind " + blk2SysMLname + "." + sig2SYSMLname + " = " + channelSYSMLname + ";\n");
Sophie Coudert's avatar
Sophie Coudert committed
                // Message declaration .........................

Sophie Coudert's avatar
Sophie Coudert committed
                StringBuffer msg1Buf = new StringBuffer(indent + "\n// Message of signal " + blk1SysMLname + "." + sig1SYSMLname + "............\n");
                StringBuffer msg2Buf = new StringBuffer(indent + "\n// Message of signal " + blk2SysMLname  + "." + sig2SYSMLname + "............\n");
                    msg1Buf.append(indent + "part def " + message1SYSMLname + " :> '#InMessage' {\n" +
                            indent + indentStep + "private part '@channel' : '#Channel' = " + channelSYSMLname + ";\n");
                    msg2Buf.append(indent + "part def " + message2SYSMLname + " :> '#OutMessage', " + message1SYSMLname + " {\n");
                    msg1Buf.append(indent + "part def " + message1SYSMLname + " :> '#OutMessage', " + message2SYSMLname + " {\n");
                    msg2Buf.append(indent + "part def " + message2SYSMLname + " :> '#InMessage' {\n" +
                            indent + indentStep + "private part '@channel' : '#Channel' = " + channelSYSMLname + ";\n");
Sophie Coudert's avatar
Sophie Coudert committed
                indent += indentStep;
Sophie Coudert's avatar
Sophie Coudert committed
                // message fields. SysML names preserve Avatar sender and receiver names
Sophie Coudert's avatar
Sophie Coudert committed
                int channelSize = sig1.getListOfOriginalAttributes().size();
                int j=0;
Sophie Coudert's avatar
Sophie Coudert committed
                AvatarType type;
                String attributeType;
                String fieldName1;
                String fieldName2;
                while (j < channelSize ) { // browse channels' parameters
Sophie Coudert's avatar
Sophie Coudert committed
                    AvatarAttribute aa1 = sig1.getListOfOriginalAttributes().get(j);
                    AvatarDataType dataType = null;
                    if (aa1.isDataType()) {
                        dataType = aa1.getDataType();
                        attributeType = dataTypeSysMLname(dataType.getName()) + ";\n";
Sophie Coudert's avatar
Sophie Coudert committed
                        type = AvatarType.UNDEFINED;
Sophie Coudert's avatar
Sophie Coudert committed
                    else if (aa1.isBool()) {
                        attributeType = "Boolean;\n";
                        type = AvatarType.BOOLEAN;
                    }
                    else if (aa1.isInt()) {
                        attributeType = "Integer;\n";
                        type = AvatarType.INTEGER;
                    } else { attributeType = "Integer;\n"; type = AvatarType.INTEGER; } // ERROR: SHOULD NOT BE TIMER
                    fieldName1 = fieldSysMLname(aa1.getName());
                    fieldName2 = fieldSysMLname(sig2.getListOfOriginalAttributes().get(j).getName());
                    j++;
                    if (in2out) {
                       msg1Buf.append(indent + "attribute " + fieldName1 + " : " + attributeType);
                       msg2Buf.append(indent + "attribute " + fieldName2 + " redefines " + fieldName1 + ";\n");
                    } else {
                       msg1Buf.append(indent + "attribute " + fieldName1 + " redefines " + fieldName2 + ";\n");
                       msg2Buf.append(indent + "attribute " + fieldName2 + " : " + attributeType);
                    }
                    sig1Info.addField(fieldName1, type, dataType);
                    sig2Info.addField(fieldName2, type, dataType);
Sophie Coudert's avatar
Sophie Coudert committed
                }
Sophie Coudert's avatar
Sophie Coudert committed
                indent = indent.substring(indentStepSize);
                msg1Buf.append(indent + "}\n");
                msg2Buf.append(indent + "}\n");
                if (in2out) {
                    avsysml.append(msg1Buf);
                    avsysml.append(msg2Buf);
                } else {
                    avsysml.append(msg2Buf);
                    avsysml.append(msg1Buf);
                }

Sophie Coudert's avatar
Sophie Coudert committed

                methodMap.put(sig1,sig1Info);
                methodMap.put(sig2,sig2Info);
Sophie Coudert's avatar
Sophie Coudert committed
            }
        }
    }
Sophie Coudert's avatar
Sophie Coudert committed
    void method2SysML(AvatarMethod am){
        // "return tuple" not handled
        String returnType;
Sophie Coudert's avatar
Sophie Coudert committed
        List<AvatarAttribute> returns = am.getListOfOriginalReturnAttributes();
        AvatarDataType returnDataType;
        MethodInfo methodInfo;
        if(returns.size() == 0) {
            returnType = null;
            methodInfo = new MethodInfo(methodSysMLname(am.getName()));
        }
            returnDataType = returns.get(0).getDataType();
            if (returns.get(0).isDataType()) {
                returnType = dataTypeSysMLname(returns.get(0).getDataType().getName());
                methodInfo = new MethodInfo(methodSysMLname(am.getName()), AvatarType.UNDEFINED, returnDataType);

            }
            else if (returns.get(0).isBool()) {
                    returnType = "Boolean";
Sophie Coudert's avatar
Sophie Coudert committed
                    methodInfo = new MethodInfo(methodSysMLname(am.getName()), AvatarType.BOOLEAN, null);
            } else if (returns.get(0).isInt()) {
                    returnType = "Integer";
                    methodInfo = new MethodInfo(methodSysMLname(am.getName()), AvatarType.INTEGER, null);
            } else { // ERROR : TIMER, should not happen
                    returnType = "Integer";
                    methodInfo = new MethodInfo(methodSysMLname(am.getName()), AvatarType.INTEGER, null);
        if (returnType == null)
Sophie Coudert's avatar
Sophie Coudert committed
            avsysml.append(indent + "action " + methodSysMLname(am.getName()) +  ": '#AvatarVoidMethod' {\n");
Sophie Coudert's avatar
Sophie Coudert committed
            avsysml.append(indent + "calc " + methodSysMLname(am.getName()) +  ": '#AvatarCalcMethod' {\n");
        indent += indentStep;

        int j = 0;
        int nbFields = am.getListOfOriginalAttributes().size();
        while (j < nbFields) {
            AvatarAttribute aa = am.getListOfOriginalAttributes().get(j);
            if (aa.isDataType()) {
                avsysml.append(indent + "attribute " + fieldSysMLname(aa.getName())
                        + " : " + dataTypeSysMLname(aa.getDataType().getName())+ ";\n");
                methodInfo.addField(fieldSysMLname(aa.getName()), AvatarType.UNDEFINED, aa.getDataType());
            } else if (aa.isInt()) {
                avsysml.append(indent + "attribute " + fieldSysMLname(aa.getName()) + " : Integer;\n");
                methodInfo.addField(fieldSysMLname(aa.getName()), AvatarType.INTEGER, null);
            } else if (aa.isBool()){
                avsysml.append(indent + "attribute " + fieldSysMLname(aa.getName()) + " : Boolean;\n");
                methodInfo.addField(fieldSysMLname(aa.getName()), AvatarType.BOOLEAN, null);
            } else { // ERROR should not happen
                avsysml.append(indent + "attribute " + fieldSysMLname(aa.getName()) + " : Integer;\n");
                methodInfo.addField(fieldSysMLname(aa.getName()), AvatarType.INTEGER, null);
Sophie Coudert's avatar
Sophie Coudert committed
            j++;
Sophie Coudert's avatar
Sophie Coudert committed
        }
        if (returnType != null)
            avsysml.append(indent + "return : " + returnType + ";\n");
        indent = indent.substring(indentStepSize);
        avsysml.append(indent + "}\n");
        methodMap.put(am, methodInfo);
Sophie Coudert's avatar
Sophie Coudert committed
    }

Sophie Coudert's avatar
Sophie Coudert committed
    void signal2SysML(AvatarSignal as){
        avsysml.append(indent + "part " + methodMap.get(as).getName() + " : " +
Sophie Coudert's avatar
Sophie Coudert committed
                (fifoSet.contains(as) ? "'#Fifo'" : "'#Channel'") + ";\n");
    }
Sophie Coudert's avatar
Sophie Coudert committed
    // handling one block
    void block2SysML(AvatarBlock block){
        String blockSYSMLname = blockSysMLname(block.getName());
        timerList.clear();
        chainBlock(blockSYSMLname);
        blocklink();
Sophie Coudert's avatar
Sophie Coudert committed

        // block header --------------------
        avsysml.append("\n" + indent + "// Block " + blockSYSMLname + "=============\n");
Sophie Coudert's avatar
Sophie Coudert committed
        avsysml.append(indent + "part " + blockSYSMLname + " : '#AvatarBlock' {\n");
        indent += indentStep;

        // attributes --------------------
        if (block.getAttributes() != null && block.getAttributes().size() != 0) {
            avsysml.append("\n" + indent + "// Attributes ---------------------\n");
            int j = 0;
            int nbAttributes = block.getOriginalAttributes().size();
            while(j < nbAttributes)  {
                AvatarAttribute aa = block.getOriginalAttributes().get(j);
                if (aa.isDataType()) {
                    avsysml.append(indent + "attribute " + attributeSysMLname(aa.getName()) +
                            " : " + dataTypeSysMLname(aa.getDataType().getName()) + ";\n");
                else if (aa.isInt()) {
                    avsysml.append(indent + "attribute " + attributeSysMLname(aa.getName()) + " : Integer");
                    if (aa.hasInitialValue()) avsysml.append(" := " + aa.getInitialValue().trim());
                    avsysml.append(";\n");
                else if (aa.isBool()) {
                    avsysml.append(indent + "attribute " + attributeSysMLname(aa.getName()) + " : Boolean");
                    if (aa.hasInitialValue()) avsysml.append(" := " + aa.getInitialValue().trim());
                    avsysml.append(";\n");
                }
                else if (aa.isTimer()) {
                    timerList.add(aa);
                } else {} // ERROR, should not happen
                j++;
        // constants --------------------
        if (block.getConstants() != null && block.getConstants().size() != 0) {
            avsysml.append("\n" + indent + "// Constants ---------------------\n");
            int j = 0;
            int nbConstants = block.getConstants().size();
            while(j < nbConstants)  {
                AvatarAttribute aa = block.getOriginalAttributes().get(j);
                if (aa.isDataType()) {
                    avsysml.append(indent + "readolny attribute " + attributeSysMLname(aa.getName()) +
                            " : " + dataTypeSysMLname(aa.getDataType().getName()) + ";\n");
                }
                else if (aa.isInt()) {
                    avsysml.append(indent + "readolny attribute " + attributeSysMLname(aa.getName()) + " : Integer");
                    if (aa.hasInitialValue()) avsysml.append(" := " + aa.getInitialValue().trim());
                    avsysml.append(";\n");
                }
                else if (aa.isBool()) {
                    avsysml.append(indent + "readolny attribute " + attributeSysMLname(aa.getName()) + " : Boolean");
                    if (aa.hasInitialValue()) avsysml.append(" := " + aa.getInitialValue().trim());
                    avsysml.append(";\n");
                }
                else {} // ERROR, should not happen
                j++;
Sophie Coudert's avatar
Sophie Coudert committed
        // methods --------------------
        if (block.getMethods() != null && block.getMethods().size() != 0) {
            avsysml.append("\n" + indent + "// Methods ---------------------\n");
            for (AvatarMethod am : block.getMethods()) method2SysML(am);
        }
        if (block.getSignals() != null && block.getSignals().size() != 0) {
            avsysml.append("\n" + indent + "// Signals ---------------------\n");
            for (AvatarSignal as : block.getSignals()) signal2SysML(as);
        }
        // timers -------------------
        if (timerList != null && timerList.size() != 0) {
            avsysml.append("\n" + indent + "// Timers ---------------------\n");
Sophie Coudert's avatar
Sophie Coudert committed
            for (AvatarAttribute timer : timerList)
                avsysml.append(indent + "part " + timerBlockSysMLname(timer.getName()) + ": '#AvatarTimer' = '#AvatarTimer'();\n");
Sophie Coudert's avatar
Sophie Coudert committed
        // state-machine --------------------
        avsysml.append("\n" + indent + "// state-machine -------------------\n");
        statemachine2SysML(block.getStateMachine());
Sophie Coudert's avatar
Sophie Coudert committed
        // sub-blocks -------------------
        List<AvatarBlock> subBlockList = new ArrayList<AvatarBlock>();
        for(AvatarBlock blk: avspec.getListOfBlocks()) { if (blk.getFather() == block) subBlockList.add(blk); }
        if (subBlockList != null && subBlockList.size() != 0) {
            avsysml.append("\n" + indent + "// Sub-Blocks øøøøøøøøøøøøøøøøøøøøøøø\n");
            for (AvatarBlock blk : subBlockList) if (blk.getFather() == block) block2SysML(blk);
        }
Sophie Coudert's avatar
Sophie Coudert committed
        indent = indent.substring(indentStepSize);
Sophie Coudert's avatar
Sophie Coudert committed
        avsysml.append(indent + "}\n");
        unchainBlock();
Sophie Coudert's avatar
Sophie Coudert committed
    }

    // handling all blocks
    void blocks2SysML(){
        avsysml.append("\n" + indent + "// BLOCKS $$$$$$$$$$$$$$$$$$$$$$$$\n");
Sophie Coudert's avatar
Sophie Coudert committed
        for(AvatarBlock block: avspec.getListOfBlocks())
            if (block.getFather() == null) block2SysML(block);
    }
Sophie Coudert's avatar
Sophie Coudert committed
    void statemachine2SysML(AvatarStateMachine asm) {
Sophie Coudert's avatar
Sophie Coudert committed
        stateList.clear();
Sophie Coudert's avatar
Sophie Coudert committed
        // associate names to future SysML states
        int randomNumber = 0;
        int countNumber = 0;
        int sendNumber = 0;
        int receiveNumber = 0;
Sophie Coudert's avatar
Sophie Coudert committed
        int setNumber = 0;
        int resetNumber = 0;
        int expireNumber = 0;
Sophie Coudert's avatar
Sophie Coudert committed
        for (AvatarStateMachineElement asme : asm.getListOfElements()) {
            StateInfo stateinfo;
            if      (asme instanceof AvatarStartState)
Sophie Coudert's avatar
Sophie Coudert committed
                stateinfo = new StateInfo(startStateSysMLname());
Sophie Coudert's avatar
Sophie Coudert committed
            else if (asme instanceof AvatarStopState)
Sophie Coudert's avatar
Sophie Coudert committed
                stateinfo = new StateInfo(stopStateSysMLname());
Sophie Coudert's avatar
Sophie Coudert committed
            else if (asme instanceof AvatarState)
Sophie Coudert's avatar
Sophie Coudert committed
                stateinfo = new StateInfo(standardStateSysMLname(asme.getName()));
Sophie Coudert's avatar
Sophie Coudert committed
            else if (asme instanceof AvatarActionOnSignal) {
                if(((AvatarActionOnSignal)asme).isSending())
Sophie Coudert's avatar
Sophie Coudert committed
                    stateinfo = new StateInfo(
                            sendStateSysMLname(((AvatarActionOnSignal)asme).getSignal().getName(), sendNumber),
                            presendStateSysMLname(((AvatarActionOnSignal)asme).getSignal().getName(), sendNumber++));
Sophie Coudert's avatar
Sophie Coudert committed
                else
Sophie Coudert's avatar
Sophie Coudert committed
                    stateinfo = new StateInfo(receiveStateSysMLname(((AvatarActionOnSignal)asme).getSignal().getName(), receiveNumber),
Sophie Coudert's avatar
Sophie Coudert committed
                            prereceiveStateSysMLname(((AvatarActionOnSignal)asme).getSignal().getName(), receiveNumber++));
Sophie Coudert's avatar
Sophie Coudert committed
            }
Sophie Coudert's avatar
Sophie Coudert committed
            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),
                        preresetTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(), resetNumber++));
            }
            else if (asme instanceof AvatarExpireTimer) {
                stateinfo = new StateInfo(expireTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(),expireNumber),
                        preexpireTimerStateSysMLname(((AvatarTimerOperator) asme).getTimer().getName(), expireNumber++));

            }
Sophie Coudert's avatar
Sophie Coudert committed
            else if (asme instanceof AvatarQueryOnSignal)
Sophie Coudert's avatar
Sophie Coudert committed
                stateinfo = new StateInfo(countStateSysMLname(((AvatarQueryOnSignal)asme).getSignal().getName(), countNumber++));
Sophie Coudert's avatar
Sophie Coudert committed
            else if (asme instanceof AvatarRandom)
Sophie Coudert's avatar
Sophie Coudert committed
                stateinfo = new StateInfo(randomStateSysMLname(randomNumber++));
Sophie Coudert's avatar
Sophie Coudert committed
            else continue;
            stateList.add(asme);
            stateMap.put(asme, stateinfo);
        }
        avsysml.append(indent + "exhibit state '@statemachine' : '#AvatarStateMachine' {\n");
Sophie Coudert's avatar
Sophie Coudert committed
        indent += indentStep;
        // generate SysML states with associated transitions
Sophie Coudert's avatar
Sophie Coudert committed
        for (AvatarStateMachineElement asme : stateList) state2SysML(asme);
Sophie Coudert's avatar
Sophie Coudert committed
        indent = indent.substring(indentStepSize);
Sophie Coudert's avatar
Sophie Coudert committed
        avsysml.append(indent + "}\n");
    }
Sophie Coudert's avatar
Sophie Coudert committed
    StringBuffer sysMLtransitions = new StringBuffer();
    StringBuffer sysMLrequests = new StringBuffer();
Sophie Coudert's avatar
Sophie Coudert committed
    List<AvatarStateMachineElement> requirePreCom = new ArrayList<AvatarStateMachineElement>();
Sophie Coudert's avatar
Sophie Coudert committed

    void state2SysML(AvatarStateMachineElement asme){
        indent += indentStep;
        transitionsAndRequests(stateMap.get(asme).getName(), asme.getNexts(), ((asme instanceof AvatarState) ? "'@pool'" : "'@request'"));
Sophie Coudert's avatar
Sophie Coudert committed
        indent = indent.substring(indentStepSize);

        String requests = sysMLrequests.toString();

        // State Description, depending on state type

        if(asme instanceof AvatarState){
            avsysml.append("\n" + indent + "state " + stateMap.get(asme).getName() + " : '#AvatarStandardState'");
Sophie Coudert's avatar
Sophie Coudert committed
            if (requests.equals(""))
Sophie Coudert's avatar
Sophie Coudert committed
            else
Sophie Coudert's avatar
Sophie Coudert committed
                avsysml.append(" = '#AvatarStandardState'(\n" + requests + "\n" + indent + ");\n");
Sophie Coudert's avatar
Sophie Coudert committed
        } else

        if(asme instanceof AvatarRandom){
            avsysml.append("\n" + indent + "state " + stateMap.get(asme).getName() + " : '#AvatarRandomState' = '#AvatarRandomState'(\n");
Sophie Coudert's avatar
Sophie Coudert committed
            if (!requests.equals("")) avsysml.append(requests + ",\n");
Sophie Coudert's avatar
Sophie Coudert committed
            indent += indentStep;
            avsysml.append(indent + "'@state_action'  = '#Assignment'(\n");
Sophie Coudert's avatar
Sophie Coudert committed
            indent += indentStep;
Sophie Coudert's avatar
Sophie Coudert committed
            avsysml.append(indent + "'@target' = " + attributeSysMLname(((AvatarRandom)asme).getVariable()) + ",\n");
            avsysml.append(indent + "'@value' = '#bound_random'(" +
                    expr2SysML(((AvatarRandom)asme).getMinValue().replaceAll("__",".")) + ", " +
                    expr2SysML(((AvatarRandom)asme).getMaxValue().replaceAll("__",".")) +")\n");
Sophie Coudert's avatar
Sophie Coudert committed
            indent = indent.substring(indentStepSize);
            avsysml.append(indent + ")\n");
            indent = indent.substring(indentStepSize);
            avsysml.append(indent + ");\n");
Sophie Coudert's avatar
Sophie Coudert committed
        } else

        if(asme instanceof AvatarQueryOnSignal){
            avsysml.append("\n" + indent + "state " + stateMap.get(asme).getName() + " : '#AvatarCountState' = '#AvatarCountState'(\n");
Sophie Coudert's avatar
Sophie Coudert committed
            if (!requests.equals("")) avsysml.append(requests + ",\n");
Sophie Coudert's avatar
Sophie Coudert committed
            indent += indentStep;
            avsysml.append(indent + "'@state_action'  = '#Assignment'(\n");
Sophie Coudert's avatar
Sophie Coudert committed
            indent += indentStep;
Sophie Coudert's avatar
Sophie Coudert committed
            avsysml.append(indent + "'@target' = " + attributeSysMLname(((AvatarQueryOnSignal)asme).getAttribute().getName()) + ",\n");
            avsysml.append(indent + "'@value' = " + methodMap.get(((AvatarQueryOnSignal)asme).getSignal()).getName() + ".'@amount'()\n");
Sophie Coudert's avatar
Sophie Coudert committed
            indent = indent.substring(indentStepSize);
            avsysml.append(indent + ")\n");
            indent = indent.substring(indentStepSize);
            avsysml.append(indent + ");\n");
Sophie Coudert's avatar
Sophie Coudert committed
       } else

        if(asme instanceof AvatarActionOnSignal){
            if(((AvatarActionOnSignal)asme).isSending()) {
                avsysml.append("\n" + indent + "state " + stateMap.get(asme).getName() + " : '#AvatarSendState'");
Sophie Coudert's avatar
Sophie Coudert committed
                if (requests.equals(""))
Sophie Coudert's avatar
Sophie Coudert committed
                else
Sophie Coudert's avatar
Sophie Coudert committed
                    avsysml.append(" = '#AvatarSendState'(\n" + requests + "\n" +indent + ");\n");
Sophie Coudert's avatar
Sophie Coudert committed
            } else {
                avsysml.append("\n" + indent + "state " + stateMap.get(asme).getName() + " : '#AvatarReceiveState'");
Sophie Coudert's avatar
Sophie Coudert committed
                if (requests.equals(""))
Sophie Coudert's avatar
Sophie Coudert committed
                else
Sophie Coudert's avatar
Sophie Coudert committed
                    avsysml.append(" = '#AvatarReceiveState'(\n" + requests + "\n" + indent + ");\n");
Sophie Coudert's avatar
Sophie Coudert committed
            }
        } else

        if(asme instanceof AvatarStartState){
            avsysml.append("\n" + indent + "entry action " + stateMap.get(asme).getName() + " :'#AvatarStartState'");
Sophie Coudert's avatar
Sophie Coudert committed
            if (requests.equals(""))
Sophie Coudert's avatar
Sophie Coudert committed
            else
Sophie Coudert's avatar
Sophie Coudert committed
                avsysml.append(" = '#AvatarStartState'(\n" + requests + "\n" + indent + ");\n");
Sophie Coudert's avatar
Sophie Coudert committed
        } else

        if(asme instanceof AvatarStopState){
                avsysml.append("\n" + indent + "exit action " + stateMap.get(asme).getName() + " :'#AvatarStopState';\n");
        } else

        if(asme instanceof AvatarSetTimer){
            avsysml.append("\n" + indent + "state " + stateMap.get(asme).getName() + " : '#AvatarSetTimerState'");
            if (requests.equals(""))
Sophie Coudert's avatar
Sophie Coudert committed
                avsysml.append(" = '#AvatarSetTimerState'(\n" + requests + "\n" + indent + ");\n");
        } else

        if(asme instanceof AvatarResetTimer){
            avsysml.append("\n" + indent + "state " + stateMap.get(asme).getName() + " : '#AvatarResetTimerState'");
            if (requests.equals(""))
Sophie Coudert's avatar
Sophie Coudert committed
                avsysml.append(" = '#AvatarResetTimerState'(\n" + requests + "\n" + indent + ");\n");
        } else

        if(asme instanceof AvatarExpireTimer){
            avsysml.append("\n" + indent + "state " + stateMap.get(asme).getName() + " : '#AvatarExpireTimerState'");
            if (requests.equals(""))
Sophie Coudert's avatar
Sophie Coudert committed
                avsysml.append(" = '#AvatarExpireTimerState'(\n" + requests + "\n" + indent + ");\n");
Sophie Coudert's avatar
Sophie Coudert committed
        }

        // Transition descriptions
        avsysml.append(sysMLtransitions);

        // PreComm States and their outgoing transition
Sophie Coudert's avatar
Sophie Coudert committed
        for (AvatarStateMachineElement aos: requirePreCom) {
Sophie Coudert's avatar
Sophie Coudert committed
            StateInfo stateinfo = stateMap.get(aos);
Sophie Coudert's avatar
Sophie Coudert committed
            if (aos instanceof AvatarActionOnSignal) {
                MethodInfo signalinfo = methodMap.get(((AvatarActionOnSignal)aos).getSignal());
Sophie Coudert's avatar
Sophie Coudert committed

                if (((AvatarActionOnSignal)aos).isSending()) {
                    // preComm State
                    avsysml.append("\n" + indent + "state " + stateinfo.getPreName() + " : '#AvatarPreSendState' = '#AvatarPreSendState' (\n");
Sophie Coudert's avatar
Sophie Coudert committed
                    indent += indentStep;
                    avsysml.append(indent + "'@request' =\n");
Sophie Coudert's avatar
Sophie Coudert committed
                    indent += indentStep;
                    avsysml.append(sendRequest2SysML(1, "0", "0", signalinfo, ((AvatarActionOnSignal)aos).getOriginalValues()) + "\n");
Sophie Coudert's avatar
Sophie Coudert committed
                    indent = indent.substring(2 * indentStepSize);
                    avsysml.append(indent + ");\n");
Sophie Coudert's avatar
Sophie Coudert committed
                    // its transition
                    avsysml.append("\n" + indent + "transition : '#AvatarTransition' first " + stateinfo.getPreName() +
                            " then " + stateinfo.getName() +
                            endTransition(0,"","", 1));
Sophie Coudert's avatar
Sophie Coudert committed
                } else {
                    avsysml.append("\n" + indent + "state " + stateinfo.getPreName() + " : '#AvatarPreReceiveState' = '#AvatarPreReceiveState' (\n");
Sophie Coudert's avatar
Sophie Coudert committed
                    indent += indentStep;
                    avsysml.append(indent + "'@request' =\n");
Sophie Coudert's avatar
Sophie Coudert committed
                    indent += indentStep;
                    avsysml.append(receiveRequest2SysML(1, "0", "0", signalinfo) + "\n");
                    indent = indent.substring(2 * indentStepSize);
                    avsysml.append(indent + ");\n");
Sophie Coudert's avatar
Sophie Coudert committed
                    // its transition
                    avsysml.append("\n" + indent + "transition : '#AvatarTransition' first " + stateinfo.getPreName() + "\n");
Sophie Coudert's avatar
Sophie Coudert committed
                    indent += indentStep;
                    String doAction = receiveActions2SysML(signalinfo, ((AvatarActionOnSignal)aos).getOriginalValues());
Sophie Coudert's avatar
Sophie Coudert committed
                    if (doAction.length() == 0)
                        avsysml.append(indent + "then " + stateinfo.getName() +
                                endTransition(0,"","", 1));
Sophie Coudert's avatar
Sophie Coudert committed
                    else {
                        avsysml.append(doAction);
                        avsysml.append(" then " + stateinfo.getName() +
                                endTransition(0,"","", 1));
Sophie Coudert's avatar
Sophie Coudert committed
                    }
                    indent = indent.substring(indentStepSize);
Sophie Coudert's avatar
Sophie Coudert committed
                }
            } else if (aos instanceof AvatarSetTimer) {
                    // preComm State
                    avsysml.append("\n" + indent + "state " + stateinfo.getPreName() + " : '#AvatarPreSendState' = '#AvatarPreSendState' (\n");
                    indent += indentStep;
                    avsysml.append(indent + "'@request' =\n");
                    indent += indentStep;
                    avsysml.append(setTimerRequest2SysML(1, "0", "0",
Sophie Coudert's avatar
Sophie Coudert committed
                            timerBlockSysMLname(((AvatarSetTimer) aos).getTimer().getName()) + ".'@set'" ,
                            ((AvatarSetTimer)aos).getTimerValue()) + "\n");
                    indent = indent.substring(2 * indentStepSize);
                    avsysml.append(indent + ");\n");
                    // its transition
                    avsysml.append("\n" + indent + "transition : '#AvatarTransition' first " + stateinfo.getPreName() +
                            " then " + stateinfo.getName() +
                            endTransition(0,"","", 1));

            } else if (aos instanceof AvatarResetTimer) {
                    // preComm State
                    avsysml.append("\n" + indent + "state " + stateinfo.getPreName() + " : '#AvatarPreSendState' = '#AvatarPreSendState' (\n");
                    indent += indentStep;
                    avsysml.append(indent + "'@request' =\n");
                    indent += indentStep;
                    avsysml.append(resetTimerRequest2SysML(1, "0", "0",
Sophie Coudert's avatar
Sophie Coudert committed
                            timerBlockSysMLname(((AvatarResetTimer) aos).getTimer().getName()) + ".'@reset'" ) + "\n");
                    indent = indent.substring(2 * indentStepSize);
                    avsysml.append(indent + ");\n");
                    // its transition
                    avsysml.append("\n" + indent + "transition : '#AvatarTransition' first " + stateinfo.getPreName() +
                            " then " + stateinfo.getName() +
                            endTransition(0,"","", 1));

            } else if (aos instanceof AvatarExpireTimer) {
                    avsysml.append("\n" + indent + "state " + stateinfo.getPreName() + " : '#AvatarPreReceiveState' = '#AvatarPreReceiveState' (\n");
                    indent += indentStep;
                    avsysml.append(indent + "'@request' =\n");
                    indent += indentStep;
                    avsysml.append(expireTimerRequest2SysML(1, "0", "0",
Sophie Coudert's avatar
Sophie Coudert committed
                            timerBlockSysMLname(((AvatarExpireTimer) aos).getTimer().getName()) + ".'@expire'" ) + "\n");
                    indent = indent.substring(2 * indentStepSize);
                    avsysml.append(indent + ");\n");
                    // its transition
                    avsysml.append("\n" + indent + "transition : '#AvatarTransition' first " + stateinfo.getPreName() +
                            endTransition(0,"","", 1));
                    indent += indentStep;
                    avsysml.append(indent + "then " + stateinfo.getName() + ";\n");
                    indent = indent.substring(indentStepSize);
Sophie Coudert's avatar
Sophie Coudert committed
            }
        }
    }

    String endTransition(int delayDistributionLaw, String delayExtra1, String delayExtra2, double probability){
        if (delayDistributionLaw == DELAY_UNIFORM_LAW && probability == 1) return ";\n";
        StringBuffer result = new StringBuffer(" {\n");
        indent += indentStep;
        result.append(indent + "attribute '@delayDistributionLaw' : String = \"" + DISTRIBUTION_LAWS[delayDistributionLaw] + "\";\n");
            result.append(indent + "attribute '@weight' : Real = " + probability + ";\n");
        if (NB_OF_EXTRA_ATTRIBUTES[delayDistributionLaw] > 0)
            result.append(indent + "attribute '" + LABELS_OF_EXTRA_ATTRIBUTES_1[delayDistributionLaw] + "' : String = \""
                + delayExtra1 + "\";\n");
        if (NB_OF_EXTRA_ATTRIBUTES[delayDistributionLaw] > 1)
            result.append(indent + "attribute '" + LABELS_OF_EXTRA_ATTRIBUTES_2[delayDistributionLaw] + "' : String = \""
                + delayExtra2 + "\";\n");
        indent = indent.substring(indentStepSize);
        result.append(indent + "}\n");
        return result.toString();
    }
Sophie Coudert's avatar
Sophie Coudert committed
    void transitionsAndRequests(String srcName, List<AvatarStateMachineElement> nexts, String poolName) {
Sophie Coudert's avatar
Sophie Coudert committed
        requirePreCom.clear();
Sophie Coudert's avatar
Sophie Coudert committed
        sysMLtransitions.delete(0, sysMLtransitions.length());
        sysMLrequests.delete(0, sysMLrequests.length());
        int nb = nexts.size();
        if (nb == 0) {
Sophie Coudert's avatar
Sophie Coudert committed
            sysMLrequests.append(indent + poolName + " = null\n");
Sophie Coudert's avatar
Sophie Coudert committed
            return;
        }
        if (nb == 1) {
            indent += indentStep;
            transitionAndRequest(srcName, (AvatarTransition)nexts.get(0), 0);
            indent = indent.substring(indentStepSize);

Sophie Coudert's avatar
Sophie Coudert committed
            if(sysMLrequests.toString().trim().equals("'#immediate_request'")) {
Sophie Coudert's avatar
Sophie Coudert committed
                sysMLrequests.delete(0, sysMLrequests.length());
                return;
            }
            sysMLrequests.insert(0, indent + poolName + " =\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");
Sophie Coudert's avatar
Sophie Coudert committed
        sysMLrequests.append(indent + ")");
Sophie Coudert's avatar
Sophie Coudert committed
   }
   private String clean_guard(String _guard) {
        int open = _guard.indexOf('[');
        int close = _guard.lastIndexOf(']');
        if (open != -1 && close != -1 && close > open)
            return _guard.substring(open+1, close);
        else return _guard;
Sophie Coudert's avatar
Sophie Coudert committed
   }
    // 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;
Sophie Coudert's avatar
Sophie Coudert committed
        int requestType = 0; // 0:trivial, 1:Send, 2:Receive, 3:SetTimer, 4: ResetTimer, 5:ExpireTimer
Sophie Coudert's avatar
Sophie Coudert committed

Sophie Coudert's avatar
Sophie Coudert committed
        if((at.getActions()!=null && at.getActions().size()!=0) &&
                (target instanceof AvatarActionOnSignal || target instanceof AvatarTimerOperator)) { // preCommunication Required
            requirePreCom.add(target);
Sophie Coudert's avatar
Sophie Coudert committed
            tgtName = stateMap.get(target).getPreName();
Sophie Coudert's avatar
Sophie Coudert committed
        }
        else {
            tgtName = stateMap.get(target).getName();
            if(target instanceof AvatarActionOnSignal){
                if (((AvatarActionOnSignal)target).isSending())
                    requestType = 1;
                else
                    requestType = 2;
            }
Sophie Coudert's avatar
Sophie Coudert committed
            else if (target instanceof AvatarSetTimer)
                requestType = 3;
            else if (target instanceof AvatarResetTimer)
                requestType = 4;
            else if (target instanceof AvatarExpireTimer)
                requestType = 5;
Sophie Coudert's avatar
Sophie Coudert committed
        }
        // computing request
        if (guarded) {
Sophie Coudert's avatar
Sophie Coudert committed
            sysMLrequests.append(indent + "if " +
                    expr2SysML(clean_guard(((AvatarTransition)at).getOriginalGuard())) + " ?\n");
Sophie Coudert's avatar
Sophie Coudert committed
            indent += indentStep;
        }
        String minDelay = ( at.getOriginalMinDelay().length()==0 ? "0" : expr2SysML(at.getOriginalMinDelay()) );
        String maxDelay = ( at.getOriginalMaxDelay().length()==0 ? "0" : expr2SysML(at.getOriginalMaxDelay()) );
Sophie Coudert's avatar
Sophie Coudert committed
        if(requestType == 0) // Trivial
            sysMLrequests.append(trivialRequest2SysML(transindex,
                    minDelay,
                    maxDelay));
Sophie Coudert's avatar
Sophie Coudert committed
        else if (requestType == 1) // Send
            sysMLrequests.append(sendRequest2SysML(transindex,
                    minDelay,
                    maxDelay,
                     methodMap.get(((AvatarActionOnSignal)target).getSignal()),
Sophie Coudert's avatar
Sophie Coudert committed
                    ((AvatarActionOnSignal)target).getValues()));
        else if (requestType == 2) // Receive
Sophie Coudert's avatar
Sophie Coudert committed
            sysMLrequests.append(receiveRequest2SysML(transindex,
                    minDelay,
                    maxDelay,
                    methodMap.get(((AvatarActionOnSignal)target).getSignal())));
        else if (requestType == 3) // Set
            sysMLrequests.append(setTimerRequest2SysML(transindex,
                    minDelay,
                    maxDelay,
Sophie Coudert's avatar
Sophie Coudert committed
                    timerBlockSysMLname(((AvatarTimerOperator) target).getTimer().getName()) + ".'@set'",
                    ((AvatarSetTimer) target).getTimerValue()));
        else  if (requestType == 4) // Reset
            sysMLrequests.append(resetTimerRequest2SysML(transindex,
                    minDelay,
                    maxDelay,
Sophie Coudert's avatar
Sophie Coudert committed
                    timerBlockSysMLname(((AvatarTimerOperator) target).getTimer().getName()) + ".'@reset'" ));
        else // Expire
            sysMLrequests.append(expireTimerRequest2SysML(transindex,
                    minDelay,
                    maxDelay,
Sophie Coudert's avatar
Sophie Coudert committed
                    timerBlockSysMLname(((AvatarTimerOperator) target).getTimer().getName()) + ".'@expire'" ));
Sophie Coudert's avatar
Sophie Coudert committed
        if(guarded) {
            indent = indent.substring(indentStepSize);
Sophie Coudert's avatar
Sophie Coudert committed
            sysMLrequests.append("\n" + indent + "else '#nok_request'(" + transindex + ")");
Sophie Coudert's avatar
Sophie Coudert committed
        }

        // computing transition
Sophie Coudert's avatar
Sophie Coudert committed
        indent = indent.substring(2 * indentStepSize);
Sophie Coudert's avatar
Sophie Coudert committed
        String doAction;
        indent += indentStep;
        if(requestType == 2)
            doAction = receiveActions2SysML(methodMap.get(((AvatarActionOnSignal)target).getSignal()),
                    ((AvatarActionOnSignal)target).getOriginalValues());
Sophie Coudert's avatar
Sophie Coudert committed
        else
            doAction = transitionActions2SysML(at);
Sophie Coudert's avatar
Sophie Coudert committed
        indent = indent.substring(indentStepSize);

        sysMLtransitions.append("\n" + indent + "transition : '#AvatarTransition' first " + srcName);
Sophie Coudert's avatar
Sophie Coudert committed
        if(index > 0)
            sysMLtransitions.append(" if '@index' == " + index + "\n");
Sophie Coudert's avatar
Sophie Coudert committed
        else
            sysMLtransitions.append("\n");
        indent += indentStep;
Sophie Coudert's avatar
Sophie Coudert committed
        if (doAction == null || doAction.length() == 0)
            sysMLtransitions.append(indent + "then " + tgtName +
                    endTransition(at.getDelayDistributionLaw(), at.getDelayExtra1(), at.getDelayExtra2(), at.getProbability()));
Sophie Coudert's avatar
Sophie Coudert committed
        else {
            sysMLtransitions.append(doAction);
            sysMLtransitions.append(" then " + tgtName +
                    endTransition(at.getDelayDistributionLaw(),at.getDelayExtra1(),at.getDelayExtra2(), at.getProbability()));
Sophie Coudert's avatar
Sophie Coudert committed
        }
Sophie Coudert's avatar
Sophie Coudert committed
        indent += indentStep;
Sophie Coudert's avatar
Sophie Coudert committed
    }
    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'('@index' =  " + index + ")";
Sophie Coudert's avatar
Sophie Coudert committed
            else
                if (index == 1)
                    return indent + "'#TrivialRequest'('@delay' = " + min + ")";