package jsetool.gui; import java.util.*; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import jsetool.data.*; /** * @author Mike Lawson * * @since Nov 8, 2004 * * The DrawingToEngineDataAdapter class adapts drawing constructs to objects * understood by the processing engine. * * */ public class DrawingToEngineDataAdapter { /** * Simple inner class to provide a relationship between * a labelled state and a machine state. */ class LabeledStateMachineStateAssociation { private LabeledState ls; private MachineState ms; /** * @param ls * @param ms */ public LabeledStateMachineStateAssociation(LabeledState ls, MachineState ms) { super(); this.ls = ls; this.ms = ms; } public LabeledState getLs() { return ls; } public MachineState getMs() { return ms; } } protected MachineState initial; protected HashMap knownStates = new HashMap(); protected ArrayList knownTransitions = new ArrayList(); protected ArrayList statesToBeExplored = new ArrayList(); public void exploreAllStates() { while (exploreStates()) ; } /** * Gets the initial machine state * @return MachineState */ public MachineState getInitialState() { return initial; } /** * Sets the initial LabeledState for the adapter * @param l1 */ public void setInitial(LabeledState l1) { MachineState ms = new MachineState(); ms.setStateName(l1.getStateLabel()); LabeledStateMachineStateAssociation lsmsa = new LabeledStateMachineStateAssociation(l1, ms); statesToBeExplored.add(lsmsa); initial = ms; } /** * Returns the set of unused states * @return Collection */ public Collection getUnusedStates() { ArrayList unusedStates = new ArrayList(); for (Iterator iter = knownStates.values().iterator(); iter.hasNext(); ) { MachineState ms = (MachineState)iter.next(); if (ms.isExplored() == false) { unusedStates.add(ms); } } return unusedStates; } /** * Returns the set of unused transitions * @return Collection */ public Collection getUnusedTransitions() { ArrayList unusedTransitions = new ArrayList(); for (Iterator iter = knownTransitions.iterator(); iter.hasNext(); ) { Transition tx = (Transition)iter.next(); if (tx.isExplored() == false) { unusedTransitions.add(tx); } } return unusedTransitions; } /** * Gets the set of states to be explored at each iteration. * This method will return and clear out the list. * * @return Collection */ protected Collection getAllStatesToBeExplored() { ArrayList copy = new ArrayList(); copy.addAll(statesToBeExplored); statesToBeExplored = new ArrayList(); return copy; } /** * Creates a transition from the given source to the given target * based on the given edge. * @param edge * @param source * @param target * @return Transition */ private Transition createTransition(ConnectivityEdge edge, MachineState source, MachineState target) { String edgeLabel = edge.getEdgeLabel(); short edgeType = 0; if (edgeLabel.startsWith("-")) { edgeType = Transition.SEND; } else { edgeType = Transition.RECEIVE; } edgeLabel = edgeLabel.substring(1); // strip out leading + or - Transition t = new Transition(edgeType, source, target, edgeLabel); source.addTransition(t); return t; } /** * Explores a state * @param lsmsa */ private void exploreLabeledState(LabeledStateMachineStateAssociation lsmsa) { LabeledState ls = lsmsa.getLs(); if (ls.isExplored()) return; ls.setExplored(true); MachineState source = lsmsa.getMs(); // For each edge associated with the labeled state for (Iterator iter = ls.getAssociatedDrawable().iterator(); iter.hasNext();) { Drawable d = (Drawable) iter.next(); if (!(d instanceof ConnectivityEdge)) continue; ConnectivityEdge edge = (ConnectivityEdge) d; if (edge.getTarget().equals(ls)) continue; // Create a machine state for the associated state // and store in states to explore MachineState target = new MachineState(); target.setStateName(edge.getTarget().getStateLabel()); // If the known states already contains an object // that has the same hash as the one we just created // use that instance instead. if (knownStates.containsKey("" + target.hashCode())) { target = (MachineState) knownStates.get("" + target.hashCode()); } LabeledStateMachineStateAssociation toBeExplored = new LabeledStateMachineStateAssociation(edge.getTarget(), target); statesToBeExplored.add(toBeExplored); // Create transition for the source to target machine states. // and store in known transitions. Transition t = createTransition(edge, source, target); knownTransitions.add(t); } } /** * Explores all states. * */ private boolean exploreStates() { Collection toExplore = getAllStatesToBeExplored(); if (toExplore.size() == 0) return false; for (Iterator iter = toExplore.iterator(); iter.hasNext();) { LabeledStateMachineStateAssociation lsmsa = (LabeledStateMachineStateAssociation) iter.next(); exploreLabeledState(lsmsa); knownStates.put("" + lsmsa.getMs().hashCode(), lsmsa.getMs()); } return true; } }