workcraft/workcraft

View on GitHub
workcraft/SonPlugin/src/org/workcraft/plugins/son/algorithm/TimeAlg.java

Summary

Maintainability
A
2 hrs
Test Coverage
package org.workcraft.plugins.son.algorithm;

import java.util.Collection;
import java.util.HashSet;

import org.workcraft.dom.Node;
import org.workcraft.plugins.son.SON;
import org.workcraft.plugins.son.connections.SONConnection;
import org.workcraft.plugins.son.connections.SONConnection.Semantics;
import org.workcraft.plugins.son.elements.ChannelPlace;
import org.workcraft.plugins.son.elements.Condition;
import org.workcraft.plugins.son.elements.PlaceNode;
import org.workcraft.plugins.son.elements.Time;
import org.workcraft.plugins.son.exception.AlternativeStructureException;
import org.workcraft.plugins.son.granularity.HourMins;
import org.workcraft.plugins.son.granularity.TimeGranularity;
import org.workcraft.plugins.son.granularity.YearYear;
import org.workcraft.plugins.son.gui.TimeConsistencyDialog.Granularity;
import org.workcraft.plugins.son.util.Interval;
import org.workcraft.plugins.son.util.ScenarioRef;

public class TimeAlg extends RelationAlgorithm {

    protected ScenarioRef scenario;
    protected Granularity g;
    protected TimeGranularity granularity;

    // default duration provided by user
    protected final Interval defaultDuration;

    public TimeAlg(SON net, Interval d, Granularity g, ScenarioRef s) throws AlternativeStructureException {
        super(net);
        this.scenario = s;
        this.g = g;
        this.defaultDuration = d;

        if (scenario == null && !hasConflict()) {
            scenario = getNonbranchSON();
        }

        if (scenario == null) {
            throw new AlternativeStructureException(
                    "Model involves more than one scenarios, generate and select a scenario first");
        }

        if (g == Granularity.YEAR_YEAR) {
            granularity = new YearYear();
        } else if (g == Granularity.HOUR_MINS) {
            granularity = new HourMins();
        }
    }

    // assign specified value from connections to nodes
    public void prepare() {
        for (SONConnection con : scenario.getConnections(net)) {
            if (con.getSemantics() == Semantics.PNLINE) {
                if (con.getTime().isSpecified()) {
                    Node first = con.getFirst();
                    if (first instanceof Time) {
                        Interval end = ((Time) first).getEndTime();
                        ((Time) first).setEndTime(Interval.getOverlapping(end, con.getTime()));
                    }
                    Node second = con.getSecond();
                    if (second instanceof Time) {
                        Interval start = ((Time) second).getStartTime();
                        ((Time) second).setStartTime(Interval.getOverlapping(start, con.getTime()));
                    }
                }
            }
        }
    }

    // assign estimated time value from nodes to connections
    public void complete() {
        SONAlg sonAlg = new SONAlg(net);
        Collection<PlaceNode> initial = sonAlg.getSONInitial();
        Collection<PlaceNode> finalM = sonAlg.getSONFinal();

        Interval defTime = new Interval();
        for (Time time : net.getTimeNodes()) {
            if (!initial.contains(time)) {
                time.setStartTime(defTime);
            }
            if (!finalM.contains(time)) {
                time.setEndTime(defTime);
            }
        }
    }

    private ScenarioRef getNonbranchSON() {
        ScenarioRef scenario = new ScenarioRef();
        for (Node node : net.getComponents()) {
            scenario.add(net.getNodeReference(node));
        }
        for (SONConnection con : net.getSONConnections()) {
            scenario.add(net.getNodeReference(con));
        }
        return scenario;
    }

    private boolean hasConflict() {
        RelationAlgorithm alg = new RelationAlgorithm(net);
        for (Condition c : net.getConditions()) {
            if (alg.hasPostConflictEvents(c)) {
                return true;
            } else if (alg.hasPreConflictEvents(c)) {
                return true;
            }
        }
        return false;
    }

    public static void setProperties(SON net) {
        for (Condition c : net.getConditions()) {
            if (net.getInputPNConnections(c).isEmpty()) {
                c.setInitial(true);
            }
            if (net.getOutputPNConnections(c).isEmpty()) {
                c.setFinal(true);
            }
        }
    }

    public static void removeProperties(SON net) {
        for (PlaceNode c : net.getPlaceNodes()) {
            if (c instanceof Condition) {
                ((Condition) c).setInitial(false);
                ((Condition) c).setFinal(false);
            }
        }
    }

    public void setDefaultTime(Node node) {
        Interval input = new Interval(0, 9999);
        if (node instanceof Condition) {
            Condition c = (Condition) node;
            if (c.isInitial() && !c.isFinal()) {
                c.setEndTime(input);
                return;
            } else if (c.isFinal() && !c.isInitial()) {
                c.setStartTime(input);
                return;
            } else if (!c.isFinal() && !c.isInitial()) {
                c.setStartTime(input);
                c.setEndTime(input);
            } else {
                return;
            }
        } else if (node instanceof Time) {
            ((Time) node).setStartTime(input);
            ((Time) node).setEndTime(input);
        }
    }

    protected Collection<ChannelPlace> getSyncCPs() {
        Collection<ChannelPlace> result = new HashSet<>();
        HashSet<Node> nodes = new HashSet<>();
        nodes.addAll(net.getTransitionNodes());
        nodes.addAll(net.getChannelPlaces());
        CSONCycleAlg cycleAlg = new CSONCycleAlg(net);

        for (Path path : cycleAlg.syncCycleTask(nodes)) {
            for (Node node : path) {
                if (node instanceof ChannelPlace) {
                    result.add((ChannelPlace) node);
                }
            }
        }
        return result;
    }

}