package uk.ac.ox.oucs.vle;
import uk.ac.ox.oucs.vle.CourseSignupService.Status;
import java.util.*;
/**
* This class models the progression through the statuses.
* This is a graph of directed nodes through which normal flow can occur.
* Next being forwards and previous being backwards.
*/
public class StatusProgressionImpl implements StatusProgression {
private Map<Status, Node> statuses = new HashMap<>();
private class Node {
private Status status;
private Set<Node> next = new HashSet<>();
private Set<Node> previous = new HashSet<>();
private Node(Status status, Node... previous) {
this.status = status;
for (Node node: previous) {
addPrevious(node);
}
if (statuses.containsKey(status)) {
throw new IllegalArgumentException("Status is already in the progression: "+ status);
}
statuses.put(status, this);
}
public void addPrevious(Node other) {
this.previous.add(other);
other.next.add(this);
}
}
public StatusProgressionImpl() {
// We build the graph up start at the beginning.
Node pending = new Node(Status.PENDING);
Node waiting = new Node(Status.WAITING, pending);
Node accepted = new Node(Status.ACCEPTED, waiting, pending);
Node approved = new Node(Status.APPROVED, accepted);
Node confirmed = new Node(Status.CONFIRMED, approved);
Node rejected = new Node(Status.REJECTED, waiting, pending, accepted);
Node withdrawn = new Node(Status.WITHDRAWN, pending);
}
@Override
public Collection<Status> next(Status status) {
Node node = statuses.get(status);
if (node != null) {
return toStatus(node.next);
}
return null;
}
@Override
public Collection<Status> previous(Status status) {
Node node = statuses.get(status);
if (node != null) {
return toStatus(node.previous);
}
return null;
}
protected List<Status> toStatus(Collection<Node> nodes) {
List<Status> statuses = new ArrayList<>(nodes.size());
for (Node node: nodes) {
statuses.add(node.status);
}
return statuses;
}
}