// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils; import java.io.PrintStream; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskTraversingVisitor; import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskPath; /** *

* TODO comment *

* * @author Patrick Harms */ public class TaskTraversal { /** */ private List traversalPaths = new LinkedList(); /** */ private TaskPath[] traversalPathArray = null; /** */ private ITask task = null; /** * */ public static TaskTraversal getTraversal(ITask task, final List untraversedPaths) { final TaskTraversal result = new TaskTraversal(); final TaskPath currentPath = new TaskPath(); final int[] currentIndex = new int[1]; currentIndex[0] = 0; task.accept(new DefaultTaskTraversingVisitor() { @Override public void visit(IEventTask eventTask) { currentPath.add(eventTask, currentIndex[0]); result.add(new TaskPath(currentPath)); currentPath.removeLast(); } @Override public void visit(ISequence relationship) { currentPath.add(relationship, currentIndex[0]); if (pathIsInList(currentPath, untraversedPaths)) { result.add(new TaskPath(currentPath)); } else { int indexBuffer = currentIndex[0]; List children = relationship.getChildren(); for (int i = 0; i < children.size(); i++) { currentIndex[0] = i; super.visit(children.get(i)); } currentIndex[0] = indexBuffer; } currentPath.removeLast(); } @Override public void visit(ISelection relationship) { // selections are never traversed as a traversal can have different orders // for semantically identical selections currentPath.add(relationship, currentIndex[0]); result.add(new TaskPath(currentPath)); currentPath.removeLast(); } @Override public void visit(IMarkingTemporalRelationship relationship) { ITask markedTask = relationship.getMarkedTask(); while (markedTask instanceof IMarkingTemporalRelationship) { markedTask = ((IMarkingTemporalRelationship) markedTask).getMarkedTask(); } currentPath.add(relationship, currentIndex[0]); if (pathIsInList(currentPath, untraversedPaths)) { result.add(new TaskPath(currentPath)); } // if the child is an event task we do not traverse this marking temporal // relationship else if (markedTask instanceof IEventTask) { result.add(new TaskPath(currentPath)); } else { int indexBuffer = currentIndex[0]; currentIndex[0] = 0; super.visit(relationship); currentIndex[0] = indexBuffer; } currentPath.removeLast(); } }); result.setComplete(); return result; } /** * */ public int[] getIndexesRootedBy(TaskPath pathToRoot) { int[] indexes = new int[] { -1, -1 }; for (int i = 0; i < traversalPathArray.length; i++) { TaskPath path = traversalPathArray[i]; // check if the path starts with the path to the root if (path.size() >= pathToRoot.size()) { boolean startsWithPathToRoot = true; for (int j = 0; (j < pathToRoot.size()) && (j < path.size()); j++) { if (!pathToRoot.get(j).equals(path.get(j))) { startsWithPathToRoot = false; break; } } if (startsWithPathToRoot) { if (indexes[0] < 0) { indexes[0] = i; } indexes[1] = i; } } } return indexes; } /** * */ public TaskPath[] subList(int fromIndex, int toIndex) { return Arrays.copyOfRange(traversalPathArray, fromIndex, toIndex); } /** * */ public ITask getTask() { return task; } /** * */ public ITask get(int i) { return traversalPathArray[i].getLast(); } /** * */ public int size() { return traversalPathArray.length; } /** * @return the traversalPaths */ public TaskPath[] getTraversalPaths() { return traversalPathArray; } /** * */ public void dump(PrintStream out) { for (TaskPath path : traversalPathArray) { out.print(path.getLast().getId()); out.print('\t'); } out.println(); } /** * */ private void add(TaskPath taskPath) { traversalPaths.add(taskPath); } /** * */ private void setComplete() { traversalPathArray = traversalPaths.toArray(new TaskPath[traversalPaths.size()]); traversalPaths = null; task = traversalPathArray[0].getTask(0); } /** * */ private static boolean pathIsInList(TaskPath path, List pathList) { if (pathList != null) { for (TaskPath candidate : pathList) { if (path.equals(candidate)) { return true; } } } return false; } }