1 | package de.ugoe.cs.autoquest.plugin.usability2.rules.operator; |
---|
2 | |
---|
3 | import java.util.ArrayList; |
---|
4 | import java.util.Collections; |
---|
5 | import java.util.HashMap; |
---|
6 | import java.util.Iterator; |
---|
7 | import java.util.LinkedList; |
---|
8 | import java.util.List; |
---|
9 | import java.util.Map; |
---|
10 | import java.util.Queue; |
---|
11 | |
---|
12 | import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.FollowedByUtil; |
---|
13 | import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.ITaskEntry; |
---|
14 | import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.TaskProxy; |
---|
15 | import de.ugoe.cs.autoquest.plugin.usability2.rules.results.AbstractResult; |
---|
16 | import de.ugoe.cs.autoquest.plugin.usability2.rules.results.DefaultMatch; |
---|
17 | import de.ugoe.cs.autoquest.plugin.usability2.rules.results.IMatch; |
---|
18 | import de.ugoe.cs.autoquest.plugin.usability2.rules.results.IResult; |
---|
19 | import de.ugoe.cs.autoquest.plugin.usability2.rules.results.UnmatchableResult; |
---|
20 | import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; |
---|
21 | |
---|
22 | public class Follows extends AbstractFilterOperator { |
---|
23 | |
---|
24 | private final Map<String, ITask> EMPTY_MAP = Collections.emptyMap(); |
---|
25 | |
---|
26 | public Follows(List<IFilter> filters) { |
---|
27 | super(filters); |
---|
28 | } |
---|
29 | |
---|
30 | public Follows(IFilter... filters) { |
---|
31 | super(filters); |
---|
32 | } |
---|
33 | |
---|
34 | private class ResultPair { |
---|
35 | int filterIndex; |
---|
36 | ITask task; |
---|
37 | Map<String, ITask> labelMap; |
---|
38 | |
---|
39 | public ResultPair(int filterIndex, ITask task, Map<String, ITask> labelMap) { |
---|
40 | this.filterIndex = filterIndex; |
---|
41 | this.task = task; |
---|
42 | this.labelMap = labelMap; |
---|
43 | } |
---|
44 | } |
---|
45 | |
---|
46 | private class VisitorInstance { |
---|
47 | Queue<ResultPair> queue; |
---|
48 | ArrayList<IFilter> filters; |
---|
49 | |
---|
50 | private VisitorInstance(ITask root, List<IFilter> filters) { |
---|
51 | this.filters = new ArrayList<IFilter>(filters); |
---|
52 | queue = new LinkedList<ResultPair>(); |
---|
53 | queue.add(new ResultPair(0, root, EMPTY_MAP)); |
---|
54 | } |
---|
55 | |
---|
56 | public IMatch getNextMatch() { |
---|
57 | ResultPair pair; |
---|
58 | while( (pair = queue.poll()) != null ) { |
---|
59 | |
---|
60 | if (pair.filterIndex == -1) { |
---|
61 | return new DefaultMatch(pair.task, pair.labelMap); |
---|
62 | } |
---|
63 | |
---|
64 | visit(pair, queue); |
---|
65 | } |
---|
66 | |
---|
67 | return null; |
---|
68 | } |
---|
69 | |
---|
70 | private void visit(ResultPair pair, Queue<ResultPair> queue) { |
---|
71 | IFilter filter = filters.get(pair.filterIndex); |
---|
72 | IResult result = filter.match(pair.task); |
---|
73 | |
---|
74 | int index = pair.filterIndex+1; |
---|
75 | if (index >= filters.size()) |
---|
76 | index = -1; |
---|
77 | |
---|
78 | if(result.isPresent()) { |
---|
79 | List<ResultPair> match = new LinkedList<ResultPair>(); |
---|
80 | for (IMatch rMatch : result) { |
---|
81 | ITask iTask = rMatch.getTask(); |
---|
82 | |
---|
83 | Map<String, ITask> m = new HashMap<String, ITask>(pair.labelMap); |
---|
84 | m.putAll(rMatch.getLabeledResults()); |
---|
85 | |
---|
86 | if(iTask instanceof ITaskEntry) { |
---|
87 | if (iTask instanceof TaskProxy) { |
---|
88 | System.out.print("R"); |
---|
89 | } |
---|
90 | |
---|
91 | for (ITask task : ((ITaskEntry) iTask).getNext()) { |
---|
92 | match.add(new ResultPair(index, task, m)); |
---|
93 | } |
---|
94 | } else |
---|
95 | throw new RuntimeException(); |
---|
96 | } |
---|
97 | queue.addAll(match); |
---|
98 | } |
---|
99 | } |
---|
100 | } |
---|
101 | |
---|
102 | @Override |
---|
103 | public IResult match(ITask task, final List<IFilter> filters) { |
---|
104 | final ITask root = FollowedByUtil.generateFollowList(task); |
---|
105 | VisitorInstance v = new VisitorInstance(root, filters); |
---|
106 | IMatch match = v.getNextMatch(); |
---|
107 | |
---|
108 | if (match == null) |
---|
109 | return UnmatchableResult.NO_MATCH_FOUND; |
---|
110 | |
---|
111 | return new AbstractResult(true) { |
---|
112 | @Override |
---|
113 | public Iterator<IMatch> iterator() { |
---|
114 | return new Iterator<IMatch>() { |
---|
115 | VisitorInstance v = new VisitorInstance(root, filters); |
---|
116 | IMatch current; |
---|
117 | |
---|
118 | @Override |
---|
119 | public void remove() { |
---|
120 | throw new UnsupportedOperationException(); |
---|
121 | } |
---|
122 | |
---|
123 | @Override |
---|
124 | public IMatch next() { |
---|
125 | IMatch tmp = current; |
---|
126 | current = null; |
---|
127 | return tmp; |
---|
128 | } |
---|
129 | |
---|
130 | @Override |
---|
131 | public boolean hasNext() { |
---|
132 | if(current != null) |
---|
133 | return true; |
---|
134 | current = v.getNextMatch(); |
---|
135 | return current != null; |
---|
136 | } |
---|
137 | }; |
---|
138 | } |
---|
139 | }; |
---|
140 | } |
---|
141 | } |
---|