package org.drugis.common.threading.activity;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.drugis.common.threading.Task;
/**
* Represents a complex (possibly multi-threaded) task as a number of interrelated SimpleTasks.
* The representation mirrors UML 2 activity diagrams.
*/
public class ActivityModel {
private final Task d_start;
private final Task d_end;
private Map<Task, Transition> d_transitions = new HashMap<Task, Transition>();
public ActivityModel(Task start, Task end, Collection<? extends Transition> transitions) {
d_start = start;
d_end = end;
for (Transition t : transitions) {
for (Task s : t.getSources()) {
d_transitions.put(s, t);
}
}
}
/**
* Builds a list of all states that are accessible, but not yet finished.
* @return A list of tasks to run.
*/
public Set<Task> getNextStates() {
if (isFinished()) {
return Collections.emptySet();
}
return findAccessibleStates(d_start);
}
private Set<Task> findAccessibleStates(Task state) {
// if this state is not finished yet, no successors need to be evaluated
if (!state.isFinished()) {
return Collections.singleton(state);
}
// find the relevant transition and evaluate it if ready
Transition trans = d_transitions.get(state);
if (!trans.isReady()) {
return Collections.emptySet();
}
Set<Task> accessible = new HashSet<Task>();
List<Task> next = trans.transition();
for (Task task : next) {
accessible.addAll(findAccessibleStates(task));
}
return accessible;
}
public boolean isFinished() {
return d_end.isFinished();
}
public Task getStartState() {
return d_start;
}
public Task getEndState() {
return d_end;
}
public Set<Task> getStates() {
Set<Task> tasks = new HashSet<Task>(d_transitions.keySet());
tasks.add(d_end);
return tasks;
}
public Task getStateByName(String name) {
for (Task t : getStates()) {
if(name.equals(t.toString())) {
return t;
}
}
return null;
}
public Set<Transition> getTransitions() {
return new HashSet<Transition>(d_transitions.values());
}
}