package de.ugoe.cs.autoquest.plugin.usability2.rules.operator.visitors; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Queue; import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.IFilter; import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.IResultTransformer; import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.MarkingFilter; import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.ITaskEntry; import de.ugoe.cs.autoquest.plugin.usability2.rules.results.AbstractResult; import de.ugoe.cs.autoquest.plugin.usability2.rules.results.IMatch; import de.ugoe.cs.autoquest.plugin.usability2.rules.results.IResult; import de.ugoe.cs.autoquest.plugin.usability2.rules.results.UnmatchableResult; import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional; import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; public abstract class AbstractBFSContinuableScanner extends MarkingFilter { public AbstractBFSContinuableScanner(IFilter marked) { super(marked); } public AbstractBFSContinuableScanner(IFilter marked, IResultTransformer transformer) { super(marked, transformer); } private static final List EMPTY_LIST = Collections.emptyList(); private List getChildren(ITask task) { if (task instanceof ITaskEntry) return getChildren((ITaskEntry) task); else if (task instanceof ISequence) return getChildren((ISequence) task); else if (task instanceof IOptional) return getChildren((IOptional) task); else if (task instanceof IIteration) return getChildren((IIteration) task); else if (task instanceof ISelection) return getChildren((ISelection) task); return EMPTY_LIST; } private List getChildren(ITaskEntry task) { return task.getChildren(); } private List getChildren(ISelection task) { return task.getChildren(); } private List getChildren(IOptional task) { return Arrays.asList(task.getMarkedTask()); } private List getChildren(IIteration task) { return Arrays.asList(task.getMarkedTask()); } private List getChildren(ISequence task) { return task.getChildren(); } class VisitorInstance { Queue queue; IFilter filter; VisitorInstance(ITask root, IFilter filter) { queue = new LinkedList(); queue.add(root); this.filter = filter; } public IResult getNextMatch() { ITask task; while( (task = queue.poll()) != null ) { visit(task, filter, queue); IResult r = accept(task, filter); if (r.isPresent()) return r; } return null; } } protected void visit(ITask task, IFilter filter, Queue queue) { ITask taskType = task; if (taskType instanceof ITaskEntry) taskType = ((ITaskEntry) task).getReference(); List children = getChildren(task); if (taskType instanceof ISequence) visitSequence(children, queue); else if (taskType instanceof IOptional) visitOptional(children, queue); else if (taskType instanceof IIteration) visitIteration(children, queue); else if (taskType instanceof ISelection) visitSelection(children, queue); } protected void visitSelection(List children, Queue queue) { queue.addAll(children); } protected void visitIteration(List children, Queue queue) { queue.addAll(children); } protected void visitOptional(List children, Queue queue) { queue.addAll(children); } protected void visitSequence(List children, Queue queue) { queue.addAll(children); } protected IResult accept(ITask task, IFilter filter) { return filter.match(task); } @Override protected IResult match(final ITask task, final IFilter filter) { final VisitorInstance v = new VisitorInstance(task, filter); final IResult match = v.getNextMatch(); if (match == null) return UnmatchableResult.NO_MATCH_FOUND; return new AbstractResult(true) { @Override public Iterator iterator() { return new Iterator() { IMatch current; VisitorInstance v = new VisitorInstance(task, filter); IResult curResult = v.getNextMatch(); Iterator result = null; @Override public void remove() { throw new UnsupportedOperationException(); } @Override public IMatch next() { IMatch tmp = current; current = null; return tmp; } @Override public boolean hasNext() { if (current != null) return true; if (curResult == null) return false; do { if(result == null) result = curResult.iterator(); if (result.hasNext()) { current = result.next(); return true; } else result = null; } while ( (curResult = v.getNextMatch()) != null ); return false; } }; } }; } }