package de.ugoe.cs.autoquest.plugin.usability2.rules.operator; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.FollowedByUtil; import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.ITaskEntry; import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.TaskProxy; import de.ugoe.cs.autoquest.plugin.usability2.rules.results.AbstractResult; import de.ugoe.cs.autoquest.plugin.usability2.rules.results.DefaultMatch; 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.ITask; public class Follows extends AbstractFilterOperator { private final Map EMPTY_MAP = Collections.emptyMap(); public Follows(List filters) { super(filters); } public Follows(IFilter... filters) { super(filters); } private class ResultPair { int filterIndex; ITask task; Map labelMap; public ResultPair(int filterIndex, ITask task, Map labelMap) { this.filterIndex = filterIndex; this.task = task; this.labelMap = labelMap; } } private class VisitorInstance { Queue queue; ArrayList filters; private VisitorInstance(ITask root, List filters) { this.filters = new ArrayList(filters); queue = new LinkedList(); queue.add(new ResultPair(0, root, EMPTY_MAP)); } public IMatch getNextMatch() { ResultPair pair; while( (pair = queue.poll()) != null ) { if (pair.filterIndex == -1) { return new DefaultMatch(pair.task, pair.labelMap); } visit(pair, queue); } return null; } private void visit(ResultPair pair, Queue queue) { IFilter filter = filters.get(pair.filterIndex); IResult result = filter.match(pair.task); int index = pair.filterIndex+1; if (index >= filters.size()) index = -1; if(result.isPresent()) { List match = new LinkedList(); for (IMatch rMatch : result) { ITask iTask = rMatch.getTask(); Map m = new HashMap(pair.labelMap); m.putAll(rMatch.getLabeledResults()); if(iTask instanceof ITaskEntry) { if (iTask instanceof TaskProxy) { System.out.print("R"); } for (ITask task : ((ITaskEntry) iTask).getNext()) { match.add(new ResultPair(index, task, m)); } } else throw new RuntimeException(); } queue.addAll(match); } } } @Override public IResult match(ITask task, final List filters) { final ITask root = FollowedByUtil.generateFollowList(task); VisitorInstance v = new VisitorInstance(root, filters); IMatch match = v.getNextMatch(); if (match == null) return UnmatchableResult.NO_MATCH_FOUND; return new AbstractResult(true) { @Override public Iterator iterator() { return new Iterator() { VisitorInstance v = new VisitorInstance(root, filters); IMatch current; @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; current = v.getNextMatch(); return current != null; } }; } }; } }