Skip to content
Snippets Groups Projects
AvatarFromSysML.java 76.8 KiB
Newer Older
                                            "payload of set-timer transition is not well formed", transition.getRleft()));
                                    continue;
                                }

                                // update target state with its specific parameters
                                state.setTimerValue(((StxExpr)transition.getSendPayload().get(0)).toString().replaceAll(".","__"));
                                state.setTimerOriginalValue(((StxExpr)transition.getSendPayload().get(0)).toString());
                            }
                            else  { // unrecoved error, skip transition
                                addError(new AvatarFromSysMLError(AvatarFromSysMLError.HIGHERROR, transition.getLeft(),
                                        "set-timer transition should lead to a set-timer state", transition.getRleft()));
                                continue;
                            }

                        // reset-timer transitions =====================
                        else if (transition.getType() == AvatarFromSysMLSyntax.STXRESETTIMERTRANSITION) {
                            if(tgtState instanceof AvatarResetTimer) {
                                AvatarResetTimer state = (AvatarResetTimer) tgtState;

                                // an unrecovered error (transition skipped)
Sophie Coudert's avatar
Sophie Coudert committed
                                if (transition.getTimer() == null) {
                                    addError(new AvatarFromSysMLError(AvatarFromSysMLError.HIGHERROR, transition.getLeft(),
                                            "reset-timer transition has no associated timer", transition.getRleft()));
                                    continue;
Sophie Coudert's avatar
Sophie Coudert committed
                                }

                                // update target state with its specific parameter
                                state.setTimer(getTimerByName(transition.getTimer(), theBlock));
                            }
                            else  { // unrecoved error, skip transition
                                addError(new AvatarFromSysMLError(AvatarFromSysMLError.HIGHERROR, transition.getLeft(),
                                        "reset-timer transition should lead to a reset-timer state", transition.getRleft()));
                                continue;
                            }
                        // expire-timer transitions =====================
                        else if (transition.getType() == AvatarFromSysMLSyntax.STXEXPIRETIMERTRANSITION) {
                            if(tgtState instanceof AvatarExpireTimer) {
                                AvatarExpireTimer state = (AvatarExpireTimer) tgtState;

                                // an unrecovered error (transition skipped)
Sophie Coudert's avatar
Sophie Coudert committed
                                if (transition.getTimer() == null) {
                                    addError(new AvatarFromSysMLError(AvatarFromSysMLError.HIGHERROR, transition.getLeft(),
                                            "expire-timer transition has no associated timer", transition.getRleft()));
                                    continue;
Sophie Coudert's avatar
Sophie Coudert committed
                                }

                                // update target state with its specific parameter
                                state.setTimer(getTimerByName(transition.getTimer(), theBlock));
                            else  { // unrecoved error, skip transition
                                addError(new AvatarFromSysMLError(AvatarFromSysMLError.HIGHERROR, transition.getLeft(),
                                        "expire-timer transition should lead to a expire-timer state", transition.getRleft()));
                                continue;
                            }

                        // standard transitions to non-communicating state =====================
                        else if (! (tgtType == AvatarFromSysMLSyntax.STXSTOPSTATE ||
                                tgtType == AvatarFromSysMLSyntax.STXSTANDARDSTATE ||
                                tgtType == AvatarFromSysMLSyntax.STXRANDOMSTATE ||
                                tgtType == AvatarFromSysMLSyntax.STXCOUNTSTATE ||
                                tgtType == AvatarFromSysMLSyntax.STXSTARTSTATE) ) {
                            addError(new AvatarFromSysMLError(AvatarFromSysMLError.HIGHERROR, transition.getLeft(),
                                    "transition type is not consistant with the type of its target state", transition.getTarget().getLeft()));

                        // All unrecovered errors have been avoided, the transition can be added
                        asm.addElement(theTransition);
                        theSourceState.addNext(theTransition);
Sophie Coudert's avatar
Sophie Coudert committed
                        theTransition.addNext(tgtState);
                        addTransition(theTransition, tgtState); // memorize incoming transition for post-processing
Sophie Coudert's avatar
Sophie Coudert committed
                    }
            // post-processing: verify some constraints on incoming transitions
            transitionMap.forEach(new CheckIncommings());
        }
    }
    private class CheckIncommings implements BiConsumer<AvatarStateMachineElement, StateTransitions> {
        List<AvatarDataType> dataTypeList;
        public CheckIncommings(){}
        public void accept(AvatarStateMachineElement e, StateTransitions st) {
            int s = st.getTransitions().size();
            if (s == 0 && ! (e instanceof AvatarStartState)) {
                addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWERROR, "state " + e.getName() +
                        " of block " + st.getBlock().getName() + " is unreachable --> removed"));
                st.getBlock().getStateMachine().removeElement(e);
                for(AvatarStateMachineElement x : e.getNexts())
                    st.getBlock().getStateMachine().removeElement(x);
            }
            if (s > 0 && (e instanceof AvatarStartState)) {
                addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWERROR, "start state in bloc " +
                        st.getBlock().getName() + " has some input transition"));
                for(int i = 0; i < s; i++) {
                    st.getTransitions().get(i).getNexts().clear();
                    AvatarStopState nw = new AvatarStopState("errorstate",null, st.getBlock());
                    st.getTransitions().get(i).addNext(nw);
                    st.getBlock().getStateMachine().addElement(nw);
            if (s > 1 && !(e instanceof AvatarStartState || e instanceof AvatarStateElement)) {
                addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWERROR, "state " + e.getName() + " in bloc " +
                        st.getBlock().getName() + " has more than one incomming transition"));

                for(int i = 1; i < s; i++) {
                    st.getTransitions().get(i).getNexts().clear();
                    AvatarStopState nw = new AvatarStopState("errorstate",null, st.getBlock());
                    st.getTransitions().get(i).addNext(nw);
                    st.getBlock().getStateMachine().addElement(nw);
        }
    }
    private void buildBlocks(){
        stxSpec.getBlockMap().forEach(new BuildBlock());
        stxSpec.getBlockMap().forEach(new BuildStateMachine());
Sophie Coudert's avatar
Sophie Coudert committed
    private void setDistributionLaw(AvatarTransition _t, String distributionLaw, HashMap<String,String> delayExtra, StxTransition _st) {
        int law = -1;
        int size;
        if (distributionLaw == null || distributionLaw.equals("")) law = AvatarTransition.DELAY_UNIFORM_LAW;
        else {
            size = _t.DISTRIBUTION_LAWS.length;
            for (int i = 0; i < size; i++) {
                if (_t.DISTRIBUTION_LAWS[i].equals(distributionLaw)) {
                    law = i;
                    break;
                }
            }
Sophie Coudert's avatar
Sophie Coudert committed
            if (law == -1) {
                addError(new AvatarFromSysMLError(AvatarFromSysMLError.HIGHERROR, _st.getLeft(),
                 "transition with unknown transition law : " + distributionLaw + " (set to uniform)"));
                law = AvatarTransition.DELAY_UNIFORM_LAW;
            }
        }
        String extra1 = _t.LABELS_OF_EXTRA_ATTRIBUTES_1[law];
        String extra2 = _t.LABELS_OF_EXTRA_ATTRIBUTES_2[law];
        size = _t.NB_OF_EXTRA_ATTRIBUTES[law];
Sophie Coudert's avatar
Sophie Coudert committed
        String tmpString;
Sophie Coudert's avatar
Sophie Coudert committed
            tmpString = extra1;
            extra1 = delayExtra.get(extra1);
Sophie Coudert's avatar
Sophie Coudert committed
            if (extra1 == null) {
                addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWERROR, _st.getLeft(),
                 "transition law : " + distributionLaw + " requires a " + tmpString + " parameter"));
            }
Sophie Coudert's avatar
Sophie Coudert committed
                tmpString = extra2;
                extra2 = delayExtra.get(extra2);
Sophie Coudert's avatar
Sophie Coudert committed
                if (extra2 == null) {
                    addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWERROR, _st.getLeft(),
                     "transition law : " + distributionLaw + " requires a " + tmpString + " parameter"));
                }
Sophie Coudert's avatar
Sophie Coudert committed
        if (delayExtra != null && delayExtra.size() > size) {
Sophie Coudert's avatar
Sophie Coudert committed
                    addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWWARNING, _st.getLeft(),
                     "transition law : " + distributionLaw + " has too much parameters"));

        }
        _t.setDistributionLaw(law, extra1, extra2);
    }
    private void buildProfile(StxStructure ss, AvatarMethod am, AvatarBlock b) {
        AvatarAttribute aa;
        int size = ss.getSize();
        for (int i = 0; i < size; i++) {
            String type = ss.getFieldType(i);
            if (type.equals("Integer")){
                aa = new AvatarAttribute(ss.getFieldName(i), AvatarType.INTEGER, b, null);
Sophie Coudert's avatar
Sophie Coudert committed
                am.addOriginalParameter(aa);
                aa.setAsConstant(false);
                aa = new AvatarAttribute(ss.getFieldName(i), AvatarType.INTEGER, b, null);
                am.addParameter(aa);
                aa.setAsConstant(false);
           } else if (type.equals("Boolean")) {
                aa = new AvatarAttribute(ss.getFieldName(i), AvatarType.BOOLEAN, b, null);
Sophie Coudert's avatar
Sophie Coudert committed
                am.addOriginalParameter(aa);
                aa.setAsConstant(false);
                aa = new AvatarAttribute(ss.getFieldName(i), AvatarType.BOOLEAN, b, null);
                am.addParameter(aa);
                aa.setAsConstant(false);
Sophie Coudert's avatar
Sophie Coudert committed
                AvatarDataType adt = avSpec.getDataTypeByName(type);
Sophie Coudert's avatar
Sophie Coudert committed
                if (adt == null) {
                    addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWWARNING, ss.getLeft(),
                     "message profile uses undefined datatype " + type));
                String aaName = ss.getFieldName(i);
                aa = new AvatarAttribute(aaName, AvatarType.UNDEFINED, b, null);
Sophie Coudert's avatar
Sophie Coudert committed
                aa.setDataType(adt);
                am.addOriginalParameter(aa);
                aa.setAsConstant(false);
                aaName = aaName + "__";
                AvatarDataTypePrimitiveFields primitiveFields = primitiveFieldsMap.get(adt);
Sophie Coudert's avatar
Sophie Coudert committed
                int dtsize = primitiveFields.size();
                for (int j = 0; j < dtsize; j++) {
                    aa = new AvatarAttribute(aaName + primitiveFields.getName(j),
                             primitiveFields.getType(j), b, null);
                    am.addParameter(aa);
                    aa.setAsConstant(false);
                }
           }
        }
    }
    private String getStxAttributeType(String name, StxBlock blk){
        int size = blk.getNbAttributes();
        for (int i = 0; i < size; i++) {
            if (blk.getAttribute(i).getName().equals(name)) return blk.getAttribute(i).getType();
        }
        return null;
    }
    private String getStxPathType(String s, StxBlock b) {
        String[] path = s.split("__");
        String type = getStxAttributeType(path[0], b);
        int size = path.length;
        for (int i = 1; i < size; i++) {
Sophie Coudert's avatar
Sophie Coudert committed
            AvatarDataType adt = avSpec.getDataTypeByName(type);
            if (adt == null) return null;
            int nbFields = adt.attributeNb();
            int j;
            for (j = 0; j < nbFields; j++)
Sophie Coudert's avatar
Sophie Coudert committed
                if (adt.getAttribute(j).getName().equals(path[i])) break;
            if (j == nbFields) return null;
Sophie Coudert's avatar
Sophie Coudert committed
            AvatarType adtType = adt.getAttribute(j).getType();
            if (adtType == AvatarType.INTEGER)
Sophie Coudert's avatar
Sophie Coudert committed
            else if (adtType == AvatarType.BOOLEAN)
                type = adt.getAttribute(j).getDataType().getName();
    private String extendString;
    private AvatarDataType extendDataType;
    private AvatarType extendPrimitiveType;
    private String extendPath(String path, StxBlock b) {
        extendString = getStxPathType(path, b);
        if (extendString == null) {
            extendDataType = null;
            extendPrimitiveType = null;
            return null;
        }
        if (extendString.equals("Integer")) {
            extendDataType = null;
            extendPrimitiveType = AvatarType.INTEGER;
            return path;
        }
        if (extendString.equals("Boolean")) {
            extendDataType = null;
            extendPrimitiveType = AvatarType.BOOLEAN;
        extendPrimitiveType = null;
        extendDataType = avSpec.getDataTypeByName(extendString);
        if (extendDataType != null)
            return extendName(path, extendDataType);
        else return null;
    }
    private String extendName(String name, AvatarDataType adt) {
        if (adt != null) {
            AvatarDataTypePrimitiveFields primitiveFields = primitiveFieldsMap.get(adt);
Sophie Coudert's avatar
Sophie Coudert committed
            int size = primitiveFields.size() -1;
            StringBuffer res = new StringBuffer();
            int i;
            for (i = 0; i < size; i++)
                res.append(name + "__" + primitiveFields.getName(i) + ", ");
            res.append(name + "__" + primitiveFields.getName(i));
            return res.toString();
        }
        else return null;
    }
    private String extendIdent (String path, StxBlock b) {
        String result = extendPath(path, b);
        return (result.indexOf(',') == -1 ? result : "(" + result + ")");
    }
     private String extendCall (StxCall call, StxBlock b) {
        StringBuffer result = new StringBuffer();
        int size = call.getNbIdents();
        int i;
        for (i =0 ; i < size; i++) {
            result.append(call.getSegment(i));
            result.append(extendPath(call.getIdent(i).replaceAll("\\.", "__"), b));
        }
        result.append(call.getSegment(i));
        return result.toString().replaceAll("\\.", "__");
     }
     private String extendOriginalCall (StxCall call, StxBlock b) {
        StringBuffer result = new StringBuffer();
        int size = call.getNbIdents();
        int i;
        for (i =0 ; i < size; i++) {
            result.append(call.getSegment(i));
Sophie Coudert's avatar
Sophie Coudert committed
            result.append(call.getIdent(i));
        }
        result.append(call.getSegment(i));
        return result.toString();
     }
     // BUILD RELATIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    private void buildRelations(){
        stxSpec.getRelationMap().forEach(new BuildRelation());
    }
    private class BuildRelation implements BiConsumer<String, StxRelation> {
        public BuildRelation() {
        }
        public void accept(String n, StxRelation r) {
            if (!r.isDeclared()) {
                addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWERROR,
                        "relation " + r.getName() +" has been used but has not been declared"));
                int size = r.getSize();
                if (size == 0) {
                    addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWWARNING, r.getLeft(),
                     "relation is empty"));
                    return;
                } else {
                    int i = 0;
                    while (i < size && (r.getChannel(i).getBlockA() == null || r.getChannel(i).getBlockB() == null)) i++;
                    if (i == size) {
                        addError(new AvatarFromSysMLError(AvatarFromSysMLError.HIGHERROR,
                     "cannot determine blocs of relation " + r.getName()));
                        return;
                    }
                    r.setBlock1(stxSpec.getBlockMap().get(r.getChannel(i).getBlockA()));
                    r.setBlock2(stxSpec.getBlockMap().get(r.getChannel(i).getBlockB()));
                    if (r.getBlock1() == null || r.getBlock2() == null) {
                        addError(new AvatarFromSysMLError(AvatarFromSysMLError.HIGHERROR,
                     "cannot determine blocs of relation " + r.getName()));
                        return;
                    }
               }
            }
            AvatarBlock blk1 = getBlock(r.getBlock1());
            AvatarBlock blk2 = getBlock(r.getBlock2());
            AvatarRelation theRelation = new AvatarRelation(n, blk1, blk2, null);
            avSpec.addRelation(theRelation);
            theRelation.setAsynchronous(r.getAsynchronous());
            theRelation.setPrivate(r.getPrivate());
            theRelation.setLossy(r.getLossy());
            theRelation.setBlocking(r.getBlocking());
            theRelation.setSizeOfFIFO(r.getFifoSize());
            int size = r.getSize();
Sophie Coudert's avatar
Sophie Coudert committed
            if (size == 0) {
                addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWWARNING, r.getLeft(),
                 "relation " + r.getName() + " is empty"));
Sophie Coudert's avatar
Sophie Coudert committed
            }
            for (int i = 0; i < size; i++) {
                StxChannel c = r.getChannel(i);
                c.commuteSignals(r.getBlock1().getName());
                if (!blk1.getName().equals(c.getBlockA()) || !blk2.getName().equals(c.getBlockB())) {
                 addError(new AvatarFromSysMLError(AvatarFromSysMLError.HIGHERROR, c.getLeft(),
                 "inconsistency between blocs of channel " + c.getName() + " and relation " + r.getName()));
                 continue;
                }
                if (c.getSignalA() != null && c.getSignalB() != null)
                    theRelation.addSignals(getSignal(c.getSignalA()),getSignal(c.getSignalB()));
                else
                 addError(new AvatarFromSysMLError(AvatarFromSysMLError.LOWERROR, c.getLeft(),
                 "missing signal binding for channel"));
           }