workcraft/workcraft

View on GitHub
workcraft/WtgPlugin/src/org/workcraft/plugins/wtg/utils/WtgUtils.java

Summary

Maintainability
A
3 hrs
Test Coverage
package org.workcraft.plugins.wtg.utils;

import org.workcraft.dom.math.MathNode;
import org.workcraft.observation.PropertyChangedEvent;
import org.workcraft.plugins.dtd.EntryEvent;
import org.workcraft.plugins.dtd.ExitEvent;
import org.workcraft.plugins.dtd.Signal;
import org.workcraft.plugins.dtd.TransitionEvent;
import org.workcraft.plugins.wtg.Guard;
import org.workcraft.plugins.wtg.State;
import org.workcraft.plugins.wtg.Waveform;
import org.workcraft.plugins.wtg.Wtg;

import java.util.*;

public class WtgUtils {

    public static Set<String> getUnstableSignalNames(Wtg wtg) {
        Set<String> result = new HashSet<>();
        for (Waveform waveform : wtg.getWaveforms()) {
            for (TransitionEvent srcTransition : wtg.getTransitions(waveform)) {
                TransitionEvent.Direction direction = srcTransition.getDirection();
                if ((direction == TransitionEvent.Direction.DESTABILISE) ||
                        (direction == TransitionEvent.Direction.STABILISE)) {
                    Signal signal = srcTransition.getSignal();
                    String signalName = wtg.getName(signal);
                    result.add(signalName);
                }
            }

            for (Signal signal : wtg.getSignals(waveform)) {
                if (signal.getInitialState() == Signal.State.UNSTABLE) {
                    result.add(wtg.getName(signal));
                }
            }
        }
        return result;
    }

    public static Set<String> getEntryEventSignalNames(Wtg wtg, Waveform waveform) {
        Set<String> result = new HashSet<>();
        for (EntryEvent entry : wtg.getEntries(waveform)) {
            result.add(wtg.getName(entry.getSignal()));
            String signalName = wtg.getName(entry.getSignal());
            result.add(signalName);
        }
        return result;
    }

    public static Set<String> getExitEventSignalNames(Wtg wtg, Waveform waveform) {
        Set<String> result = new HashSet<>();
        for (ExitEvent exit : wtg.getExits(waveform)) {
            result.add(wtg.getName(exit.getSignal()));
            String signalName = wtg.getName(exit.getSignal());
            result.add(signalName);
        }
        return result;
    }

    public static Map<String, Guard> getGuardFromState(Wtg wtg, State state) {
        Map<String, Guard> result = new HashMap<>();
        for (MathNode node : wtg.getPostset(state)) {
            if (node instanceof Waveform) {
                result.put(wtg.getName(node), ((Waveform) node).getGuard());
            }
        }
        return result;
    }

    public static Map<String, Signal.State> getFinalSignalStatesFromWaveform(Wtg wtg, Waveform waveform) {
        Map<String, Signal.State> result = new HashMap<>();
        for (ExitEvent exit : wtg.getExits(waveform)) {
            String signalName = wtg.getName(exit.getSignal());
            Signal.State previousState = wtg.getPreviousState(exit);
            result.put(signalName, previousState);
        }
        return result;
    }

    public static Map<String, Signal.State> getInitialSignalStates(Wtg wtg) {
        Map<String, Signal.State> result = new HashMap<>();

        //BFS initialization
        int remainingSignals = wtg.getSignalNames().size();
        State initialState = wtg.getInitialState();
        Set<MathNode> visitedNodes = new HashSet<>();
        Queue<MathNode> nodesToVisit = new LinkedList<>();
        nodesToVisit.add(initialState);
        visitedNodes.add(initialState);
        //BFS main loop
        while ((!nodesToVisit.isEmpty()) && (remainingSignals > 0)) {
            MathNode node = nodesToVisit.poll();

            if (node instanceof Waveform) {
                Waveform waveform = (Waveform) node;
                for (Signal signal : wtg.getSignals(waveform)) {
                    String signalName = wtg.getName(signal);
                    if (!result.containsKey(signalName)) {
                        result.put(signalName, signal.getInitialState());
                        remainingSignals -= 1;
                    }
                }
            }

            for (MathNode n : wtg.getPostset(node)) {
                if (!visitedNodes.contains(n)) {
                    nodesToVisit.add(n);
                    visitedNodes.add(n);
                }
            }
        }
        return result;
    }

    public static Signal.State getFinalSignalStateForSignalFromNode(Wtg wtg, MathNode node, String signalName) {
        //Returns the final signal state for a signal in a waveform or state.
        //The search is propagated backwards until the first instance of the signal is found

        Set<MathNode> visitedNodes = new HashSet<>();
        Queue<MathNode> nodesToVisit = new LinkedList<>();
        visitedNodes.add(node);
        nodesToVisit.add(node);
        while (!nodesToVisit.isEmpty()) {
            MathNode visitingNode = nodesToVisit.poll();
            if (visitingNode instanceof Waveform) {
                Waveform predecesorWaveform = (Waveform) visitingNode;
                Map<String, Signal.State> finalSignalStates = getFinalSignalStatesFromWaveform(wtg, predecesorWaveform);
                if (finalSignalStates.containsKey(signalName)) {
                    return finalSignalStates.get(signalName);
                }
            }

            for (MathNode n : wtg.getPreset(visitingNode)) {
                if (!visitedNodes.contains(n)) {
                    nodesToVisit.add(n);
                    visitedNodes.add(n);
                }
            }
        }
        return null;
    }

    public static void renameSignal(Wtg wtg, String oldName, String newName) {
        if ((oldName == null) || (newName == null) || oldName.equals(newName)) {
            return;
        }
        for (Signal signal : wtg.getSignals()) {
            if (!oldName.equals(wtg.getName(signal))) continue;
            wtg.setName(signal, newName);
            signal.sendNotification(new PropertyChangedEvent(signal, Signal.PROPERTY_NAME));
        }
        for (Waveform waveform : wtg.getWaveforms()) {
            Guard guard = waveform.getGuard();
            if (!guard.containsKey(oldName)) continue;
            Guard newGuard = new Guard();
            for (Map.Entry<String, Boolean> entry : guard.entrySet()) {
                String key = oldName.equals(entry.getKey()) ? newName : entry.getKey();
                newGuard.put(key, entry.getValue());
            }
            waveform.setGuard(newGuard);
        }
    }

}