Skip to content
Snippets Groups Projects
EBRDDTranslator.java 13.3 KiB
Newer Older
/* 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 ui;

import req.ebrdd.*;
import tmltranslator.TMLType;
import translator.CheckingError;
import ui.ebrdd.EBRDDAttributeBox;
import ui.ebrdd.EBRDDPanel;
import ui.ebrdd.EBRDDStartState;
import ui.ebrdd.TGConnectorEBRDDERC;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;


* Class EBRDDTranslator
* Creation: 18/09/2009
* @author Ludovic APVRILLE
public class EBRDDTranslator {
	protected EBRDD ebrdd;
	protected LinkedList<CheckingError> checkingErrors, warnings;
	protected CorrespondanceTGElement listE; // usual list
	//protected CorrespondanceTGElement listB; // list for particular element -> first element of group of blocks
	
	public EBRDDTranslator() {
		reinit();
	}
	
	public void reinit() {
		checkingErrors = new LinkedList<CheckingError> ();
		warnings = new LinkedList<CheckingError> ();
		listE = new CorrespondanceTGElement();
		//listB = new CorrespondanceTGElement();
	}
	
	public LinkedList<CheckingError> getErrors() {
		return checkingErrors;
	}
	
	public LinkedList<CheckingError> getWarnings() {
		return warnings;
	}
	
	private void addCheckingError(CheckingError ce) {
		if (checkingErrors == null) {
			checkingErrors = new LinkedList<CheckingError> ();
		}
		checkingErrors.add (ce);
	}
	
	private void addWarning(CheckingError ce) {
		if (warnings == null) {
			warnings = new LinkedList<CheckingError> ();
		}
		warnings.add (ce);
	}
	
	public CorrespondanceTGElement getCorrespondanceTGElement() {
		return listE;
	}
	
	public EBRDD generateEBRDD(EBRDDPanel ebrddp, String _name) {
		ebrdd = new EBRDD(_name);
		
		// Search for start state
		List<TGComponent> list = ebrddp.getComponentList();
		Iterator<TGComponent> iterator = list.listIterator();
		TGComponent tgc, tgc1, tgc2, tgc3, tgc1tmp, tgc2tmp;
		TGComponent tss = null;
		int cptStart = 0;
		
		while(iterator.hasNext()) {
			tgc = iterator.next();
			if (tgc instanceof EBRDDStartState){
				tss = tgc;
				cptStart ++;
			}
		}
		
		if (tss == null) {
			UICheckingError ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, "No start state in EBRDD");
			ce.setTDiagramPanel(ebrddp);
			addCheckingError(ce);
			return ebrdd;
		}
		
		if (cptStart > 1) {
			UICheckingError ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, "More than one start state in EBRDD");
			ce.setTDiagramPanel(ebrddp);
			addCheckingError(ce);
			return ebrdd;
		}
		
		
		req.ebrdd.EBRDDActionState acst;
		req.ebrdd.EBRDDChoice ch;
		req.ebrdd.EBRDDERC erc;
		req.ebrdd.EBRDDLoop loop;
		req.ebrdd.EBRDDSequence seq;
		req.ebrdd.EBRDDStart start;
		req.ebrdd.EBRDDStop stop;
		req.ebrdd.EBRDDAttribute attr;
		ESO eso;
		ERB erb;
		TMLType tt;
		int i;
		
		int cpt=0;
		
		start = ebrdd.getStartState();
		listE.addCor(start, tss);
		
		// Creation of other elements
		iterator = list.listIterator();
		while(iterator.hasNext()) {
			cpt++;
			tgc = iterator.next();
			
			// Variables
			if (tgc instanceof EBRDDAttributeBox) {
				LinkedList<TAttribute> vv = ((EBRDDAttributeBox)tgc).getAttributeList();
                                for (TAttribute ta: vv) {
					if (ta.getType() == TAttribute.NATURAL) {
						tt = new TMLType(TMLType.NATURAL);
					} else if (ta.getType() == TAttribute.BOOLEAN) {
						tt = new TMLType(TMLType.BOOLEAN);
					} else {
						tt = new TMLType(TMLType.OTHER);
					}
					attr = new EBRDDAttribute(ta.getId(), ta.getInitialValue(), tt);
					if (!ebrdd.addAttribute(attr)) {
						UICheckingError ce = new UICheckingError(CheckingError.STRUCTURE_ERROR, "Duplicate declaration for variable " + ta.getId());
						ce.setTDiagramPanel(ebrddp);
						ce.setTGComponent(tgc);
						checkingErrors.add(ce);
					}
				}
				
			
			// Action
			} else if (tgc instanceof ui.ebrdd.EBRDDActionState) {
				acst = new req.ebrdd.EBRDDActionState("Action state"+cpt, tgc);
				acst.setAction(((ui.ebrdd.EBRDDActionState)tgc).getAction());
				listE.addCor(acst, tgc);
				
				// Stop
			} else if (tgc instanceof ui.ebrdd.EBRDDStopState) {
				stop = new req.ebrdd.EBRDDStop("Stop"+cpt, tgc);
				listE.addCor(stop, tgc);
				
				// Choice	
			} else if (tgc instanceof ui.ebrdd.EBRDDChoice) {
				// guards are added later on
				ch = new req.ebrdd.EBRDDChoice("Choice"+cpt, tgc);
				listE.addCor(ch, tgc);
				
				// Sequence
			} else if (tgc instanceof ui.ebrdd.EBRDDSequence) {
				// guards are added later on
				seq = new req.ebrdd.EBRDDSequence("Sequence"+cpt, tgc);
				listE.addCor(seq, tgc);
				
				// Loop
			} else if (tgc instanceof ui.ebrdd.EBRDDForLoop) {
				// guards are added later on
				loop = new req.ebrdd.EBRDDLoop("Loop"+cpt, tgc);
				listE.addCor(loop, tgc);
				loop.setInit(((ui.ebrdd.EBRDDForLoop)tgc).getInit());
				loop.setCondition(((ui.ebrdd.EBRDDForLoop)tgc).getCondition());
				loop.setIncrement(((ui.ebrdd.EBRDDForLoop)tgc).getIncrement());
				
				// ERC
			} else if (tgc instanceof ui.ebrdd.EBRDDERC) {
				// ERC's internal elements are built later on
				erc = new req.ebrdd.EBRDDERC("ERC"+cpt, tgc);
				listE.addCor(erc, tgc);
			}
		}
		
		Vector<Object> v = listE.getData();
		Object o;
		for(i=0; i<v.size(); i++) {
			o = v.get(i);
			if (o instanceof EBRDDComponent) {
				ebrdd.add((EBRDDComponent)o);
			}
		}
		
		// Build ERCs
		ui.ebrdd.EBRDDESO esotgc;
		ui.ebrdd.EBRDDERB erbtgc;
		
		iterator = list.listIterator();
		while(iterator.hasNext()) {
			tgc = iterator.next();
			
			if (tgc instanceof ui.ebrdd.EBRDDERC) {
				erc = (req.ebrdd.EBRDDERC)(listE.getEBRDDGeneralComponent(tgc));
				if (erc != null) {
					for(i=0; i<tgc.getChildCount(); i++) {
						tgc1 = tgc.getInternalTGComponent(i);
						
						if (tgc1 instanceof ui.ebrdd.EBRDDESO) {
							esotgc = (ui.ebrdd.EBRDDESO)tgc1;
							eso = new req.ebrdd.ESO("ESO"+cpt, esotgc);
							listE.addCor(eso, esotgc);
							eso.setID(esotgc.getID());
							eso.setTimeout(esotgc.getTimeout());
							eso.setOncePerEvent(esotgc.getOncePerEvent());
							eso.setN(esotgc.getN());
							eso.setM(esotgc.getM());
							erc.addTreeElement(eso);
							
						} else if (tgc1 instanceof ui.ebrdd.EBRDDERB) {
							erbtgc = (ui.ebrdd.EBRDDERB)tgc1;
							erb = new req.ebrdd.ERB("ERB" + cpt, erbtgc);
							listE.addCor(erb, erbtgc);
							erb.setEvent(erbtgc.getEvent());
							erb.setAction(erbtgc.getAction());
							erb.setCondition(erbtgc.getCondition());
							erc.addTreeElement(erb);
						}
					}
				}
			}
		}
		
		
		// Interconnection between elements
        //TGConnectorEBRDD tgco;
		//TGConnectorEBRDDERC tgcoerc;
		TGConnector tgco;
        TGConnectingPoint p1, p2;
        EBRDDComponent eb1, eb2;
		EBRDDGeneralComponent ebg1, ebg2;
        int j, index;
        
        iterator = list.listIterator();
        while(iterator.hasNext()) {
            tgc = iterator.next();
            if (tgc instanceof TGConnector) {
                //tgco = (TGConnectorEBRDD)tgc;
				tgco = (TGConnector)tgc;
                p1 = tgco.getTGConnectingPointP1();
                p2 = tgco.getTGConnectingPointP2();
                
                // Identification of connected components
                tgc1 = null; tgc2 = null;
                for(j=0; j<list.size(); j++) {
                    tgc3 = list.get(j);
                    tgc1tmp = tgc3.belongsToMeOrSon(p1);
					tgc2tmp = tgc3.belongsToMeOrSon(p2);
					if (tgc1tmp != null) {
						tgc1 = tgc1tmp;
					}
					if (tgc2tmp != null) {
						tgc2 = tgc2tmp;
					}
                     
                }
                
                // Connecting ebrdd modeling components
                if ((tgc1 != null) && (tgc2 != null)) {
                    //ADComponent ad1, ad2;
                    ebg1 = listE.getEBRDDGeneralComponent(tgc1);
                    ebg2 = listE.getEBRDDGeneralComponent(tgc2);
                    if ((ebg1 != null ) && (ebg2 != null)) {
						if ((ebg1 instanceof EBRDDComponent) && (ebg2 instanceof EBRDDComponent)) {
							eb1 = (EBRDDComponent)ebg1;
							eb2 = (EBRDDComponent)ebg2;
							//Special case if "for loop" or if "choice"
							
							if (eb1 instanceof req.ebrdd.EBRDDLoop) {
								index = tgc1.indexOf(p1) - 1;
								if (index == 0) {
									eb1.addNext(0, eb2);
								} else {
									eb1.addNext(eb2);
								}
							} else if (eb1 instanceof req.ebrdd.EBRDDChoice) {
								index = tgc1.indexOf(p1) - 1;
								((req.ebrdd.EBRDDChoice)eb1).addGuard(((ui.ebrdd.EBRDDChoice)tgc1).getGuard(index));
							} else if (eb1 instanceof req.ebrdd.EBRDDSequence) {
								index = tgc1.indexOf(p1) - 1;
								((req.ebrdd.EBRDDSequence)eb1).addIndex(index);
								eb1.addNext(eb2);
							} else {
								eb1.addNext(eb2);
							}
						} else if ((ebg1 instanceof ERCElement) && (ebg2 instanceof ERCElement)) {
							if ((ebg1 instanceof req.ebrdd.ESO) && (tgco instanceof TGConnectorEBRDDERC)) {
								index = tgc1.indexOf(p1) - 1;
								((req.ebrdd.ESO)ebg1).addIndex(index);
								((req.ebrdd.ESO)ebg1).addSon((ERCElement)ebg2);
								((ERCElement)ebg2).setNegated(tgco.getNegation());
							}
						}
                    }
                }
            } 
        }
		
		// Sorting nexts elements of Sequence and ESOs
		for(j=0; j<ebrdd.size(); j++) {
			eb1 = ebrdd.get(j);
			if (eb1 instanceof req.ebrdd.EBRDDSequence) {
				((req.ebrdd.EBRDDSequence)eb1).sortNexts();
			} else  if (eb1 instanceof req.ebrdd.EBRDDERC) {
				((req.ebrdd.EBRDDERC)eb1).sortNexts();
			}
		}
        
        // Check that each "for" has two nexts
        // Check that Choice have compatible guards
		// Check validity of ERC (no cycles, etc.)
        iterator = list.listIterator();
        while(iterator.hasNext()) {
            tgc = iterator.next();
			if (tgc instanceof ui.ebrdd.EBRDDChoice) {
                ch = (req.ebrdd.EBRDDChoice)(listE.getEBRDDGeneralComponent(tgc));
                ch.orderGuards();
				
                if (ch.hasMoreThanOneElse()) {
                    UICheckingError ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, "Choice should have only one [else] guard");
                    ce.setTDiagramPanel(ebrddp);
                    ce.setTGComponent(tgc);
                    checkingErrors.add(ce);
                } 
            } else if (tgc instanceof ui.ebrdd.EBRDDForLoop) {
				loop = (req.ebrdd.EBRDDLoop)(listE.getEBRDDGeneralComponent(tgc));
				if (loop.getNbNext() != 2) {
					UICheckingError ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, "Loop should have exactly two next elements");
                    ce.setTDiagramPanel(ebrddp);
                    ce.setTGComponent(tgc);
                    checkingErrors.add(ce);
				}
			} else if (tgc instanceof ui.ebrdd.EBRDDERC) {
				erc = (req.ebrdd.EBRDDERC)(listE.getEBRDDGeneralComponent(tgc));
				if (!erc.makeRoot()) {
					UICheckingError ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, "Badly formed ERC");
                    ce.setTDiagramPanel(ebrddp);
                    ce.setTGComponent(tgc);
                    checkingErrors.add(ce);
				}
			}
        }
		
		
		
		
		// Remove all elements not reachable from start state
		int sizeb = ebrdd.size();
		ebrdd.removeAllNonReferencedElts();
		int sizea = ebrdd.size();
		if (sizeb > sizea) {
			UICheckingError ce = new UICheckingError(CheckingError.BEHAVIOR_ERROR, "Non reachable elements have been removed in EBRDD");
			ce.setTGComponent(null);
			ce.setTDiagramPanel(ebrddp);
			addWarning(ce);