// 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.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
/**
*
* TODO comment
*
*
* @author Patrick Harms
*/
public class TaskTreeValidator {
/**
*
*/
public void validate(List userSessions, boolean checkInstances) {
validate(userSessions);
if (!checkInstances) {
return;
}
Map> allTasks = new HashMap>();
for (IUserSession userSession : userSessions) {
getAllTasksAndInstances(userSession, allTasks);
}
for (Map.Entry> entry : allTasks.entrySet()) {
assertEquals(entry.getKey(), "number of task instances of task " + entry.getKey() +
" in the sessions is not equal to those referenced by the model",
entry.getValue().size(), entry.getKey().getInstances().size());
for (ITaskInstance candidate : entry.getValue()) {
boolean found = false;
for (ITaskInstance instance : entry.getKey().getInstances()) {
if (candidate.equals(instance)) {
if (!found) {
found = true;
}
else {
fail(entry.getKey(), "the same instance is referred twice by the task");
}
}
}
assertTrue(candidate.getTask(), "instance " + candidate +
" is not referred by task", found);
}
}
}
/**
*
*/
public void validate(List userSessions) {
for (IUserSession userSession : userSessions) {
validate(userSession);
}
}
/**
*
*/
public void validate(ITaskInstanceList taskInstances) {
for (ITaskInstance taskInstance : taskInstances) {
validate(taskInstance);
}
}
/**
*
*/
public void validate(ITask task) {
assertTrue(task, "task has no instances", task.getInstances().size() > 0);
assertTrue(task, "task has no instances", task.getInstances().iterator().hasNext());
assertNotNull(task, "task has no instances", task.getInstances().iterator().next());
for (ITaskInstance taskInstance : task.getInstances()) {
assertSame(task, "task of instance does not match task", task, taskInstance.getTask());
validate(taskInstance);
}
}
/**
*
*/
public void validate(ITaskInstance taskInstance) {
ITask task = taskInstance.getTask();
assertNotNull(task, "task model of task instance must not be null", task);
if (task instanceof ISequence) {
ISequence seq = (ISequence) taskInstance.getTask();
assertEquals(seq, "number of children of sequence instance must match sequence model",
((ISequenceInstance) taskInstance).size(), seq.getChildren().size());
for (int i = 0; i < ((ISequenceInstance) taskInstance).size(); i++) {
assertNotNull(seq, "sequence instance child " + i + " was null",
((ISequenceInstance) taskInstance).get(i));
ITask childTask = ((ISequenceInstance) taskInstance).get(i).getTask();
assertSame(seq, "task of sequence instance child " + i + "(" +
((ISequenceInstance) taskInstance).get(i) + ") does not match " +
"sequence model (" + seq.getChildren().get(i) + ")",
childTask, seq.getChildren().get(i));
}
}
else if (task instanceof ISelection) {
ISelection sel = (ISelection) task;
assertNotNull(sel, "number of children of selection instance must be 1",
((ISelectionInstance) taskInstance).getChild());
assertTrue(sel, "number of children of selection must be larger 0",
sel.getChildren().size() > 0);
boolean found = false;
for (ITask childTask : sel.getChildren()) {
assertNotNull(sel, "child of selection model must not be null", childTask);
assertFalse(sel, "child of selection model must not be a selection",
childTask instanceof ISelection);
/*assertFalse("child of selection model must not be an optional",
childTask instanceof IOptional);*/
if (childTask.equals(((ISelectionInstance) taskInstance).getChild().getTask())) {
found = true;
break;
}
}
assertTrue(sel, "no child of the selection model matches the model of child of the " +
"selection instance", found);
}
else if (task instanceof IIteration) {
ITask childTask = ((IIteration) task).getMarkedTask();
assertNotNull(task, "child task of iteration model must not be null", childTask);
assertFalse(task, "child of iteration model must not be an iteration",
childTask instanceof IIteration);
assertFalse(task, "child of iteration model must not be an optional",
childTask instanceof IOptional);
for (int i = 0; i < ((IIterationInstance) taskInstance).size(); i++) {
assertNotNull(task, "iteration instance child " + i + " was null",
((IIterationInstance) taskInstance).get(i));
assertSame(task, "task of iteration child " + i + " does not match iteration model",
childTask, ((IIterationInstance) taskInstance).get(i).getTask());
}
}
else if (task instanceof IOptional) {
ITask childTask = ((IOptional) task).getMarkedTask();
assertNotNull(task, "child task of optional model must not be null", childTask);
assertFalse(task, "child of optional model must not be an optional",
childTask instanceof IOptional);
if (((IOptionalInstance) taskInstance).getChild() != null) {
assertSame(task, "task of optional child does not match optional model", childTask,
((IOptionalInstance) taskInstance).getChild().getTask());
}
}
else if (task instanceof IEventTask) {
IEventTask eventTask = (IEventTask) task;
assertNotNull(task, "event task model must not be null", eventTask);
assertNotNull(task, "event of event task instance must not be null",
((IEventTaskInstance) taskInstance).getEvent());
}
else {
fail(task, "unknown task model: " + task);
}
if (taskInstance instanceof ITaskInstanceList) {
for (ITaskInstance child : (ITaskInstanceList) taskInstance) {
validate(child);
}
}
else if (taskInstance instanceof ISelectionInstance) {
validate(((ISelectionInstance) taskInstance).getChild());
}
else if (taskInstance instanceof IOptionalInstance) {
if (((IOptionalInstance) taskInstance).getChild() != null) {
validate(((IOptionalInstance) taskInstance).getChild());
}
}
}
/**
*
*/
private void getAllTasksAndInstances(ITaskInstanceList taskInstances,
final Map> allTasks)
{
for (ITaskInstance taskInstance : taskInstances) {
taskInstance.accept(new DefaultTaskInstanceTraversingVisitor() {
/* (non-Javadoc)
* @see DefaultTaskInstanceTraversingVisitor#visit(IOptionalInstance)
*/
@Override
public void visit(IOptionalInstance optionalInstance) {
addToInstanceList(optionalInstance);
super.visit(optionalInstance);
}
/* (non-Javadoc)
* @see DefaultTaskInstanceTraversingVisitor#visit(ISelectionInstance)
*/
@Override
public void visit(ISelectionInstance selectionInstance) {
addToInstanceList(selectionInstance);
super.visit(selectionInstance);
}
/* (non-Javadoc)
* @see DefaultTaskInstanceTraversingVisitor#visit(IEventTaskInstance)
*/
@Override
public void visit(IEventTaskInstance eventTaskInstance) {
addToInstanceList(eventTaskInstance);
super.visit(eventTaskInstance);
}
/* (non-Javadoc)
* @see DefaultTaskInstanceTraversingVisitor#visit(IIterationInstance)
*/
@Override
public void visit(IIterationInstance iterationInstance) {
addToInstanceList(iterationInstance);
super.visit(iterationInstance);
}
/* (non-Javadoc)
* @see DefaultTaskInstanceTraversingVisitor#visit(ISequenceInstance)
*/
@Override
public void visit(ISequenceInstance sequenceInstance) {
addToInstanceList(sequenceInstance);
super.visit(sequenceInstance);
}
private void addToInstanceList(ITaskInstance taskInstance) {
List instances = allTasks.get(taskInstance.getTask());
if (instances == null) {
instances = new LinkedList();
allTasks.put(taskInstance.getTask(), instances);
}
boolean found = false;
for (ITaskInstance candidate : instances) {
if (candidate.equals(taskInstance)) {
found = true;
break;
}
}
assertFalse(taskInstance.getTask(), "instance " + taskInstance +
" occurred twice", found);
instances.add(taskInstance);
}
});
}
}
/**
*
* TODO: comment
*
*
* @param string
*/
private void fail(ITask task, String message) {
System.err.println("failing validation for task " + task);
System.err.println("message: " + message);
new TaskTreeEncoder().encode(task, System.err);
throw new RuntimeException(message);
}
/**
*
* TODO: comment
*
*
* @param string
* @param task
*/
private void assertNotNull(ITask task, String message, Object object) {
if (object == null) {
System.err.println("failing validation for task " + task);
System.err.println("message: " + message);
new TaskTreeEncoder().encode(task, System.err);
throw new RuntimeException(message);
}
}
/**
*
* TODO: comment
*
*
* @param string
* @param found
*/
private void assertTrue(ITask task, String message, boolean value) {
if (!value) {
System.err.println("failing validation for task " + task);
System.err.println("message: " + message);
new TaskTreeEncoder().encode(task, System.err);
throw new RuntimeException(message);
}
}
/**
*
* TODO: comment
*
*
* @param string
* @param found
*/
private void assertFalse(ITask task, String message, boolean value) {
if (value) {
System.err.println("failing validation for task " + task);
System.err.println("message: " + message);
new TaskTreeEncoder().encode(task, System.err);
throw new RuntimeException(message);
}
}
/**
*
* TODO: comment
*
*
* @param string
* @param childTask
* @param task
*/
private void assertEquals(ITask task, String message, Object object1, Object object2) {
if (!object1.equals(object2)) {
System.err.println("failing validation for task " + task);
System.err.println("message: " + message);
new TaskTreeEncoder().encode(task, System.err);
throw new RuntimeException(message);
}
}
/**
*
* TODO: comment
*
*
* @param string
* @param childTask
* @param task
*/
private void assertSame(ITask task, String message, Object object1, Object object2) {
if (object1 != object2) {
System.err.println("failing validation for task " + task);
System.err.println("message: " + message);
new TaskTreeEncoder().encode(task, System.err);
throw new RuntimeException(message);
}
}
}