source: trunk/autoquest-core-usability-evaluation/src/main/java/de/ugoe/cs/autoquest/usability/rules/patterns/InteractionPattern.java @ 1320

Last change on this file since 1320 was 1320, checked in by khartmann, 11 years ago

Removed accidently commited debug-code

  • Property svn:mime-type set to text/plain
File size: 7.9 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.usability.rules.patterns;
16
17import java.util.Collection;
18import java.util.Iterator;
19import java.util.List;
20
21import com.google.common.base.Optional;
22import com.google.common.base.Predicate;
23import com.google.common.collect.Iterables;
24
25import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
26import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
27import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
28import de.ugoe.cs.autoquest.usability.taskmodel.filter.ITaskModelFilter;
29import de.ugoe.cs.autoquest.usability.taskmodel.filter.TaskModelFilter;
30import de.ugoe.cs.autoquest.usability.taskmodel.filter.types.TaskTypeFilter;
31
32/**
33 * <p>
34 * A interaction pattern is a simple approach to describe the structure of usage behaviour.
35 * </p>
36 *
37 * @author Alexander Deicke
38 */
39public class InteractionPattern {
40
41    /**
42     * <p>
43     * {@link TaskModelFilterAccessor}, which is used to filter a task model after different {@link ITask}s
44     * </p>
45     */
46    private ITaskModelFilter taskTreeFilter = new TaskModelFilter();
47
48    /**
49     * <p>
50     * Type of root task. Determines the order in which sub task appear.
51     * </p>
52     */
53    private TaskTypeFilter rootTask;
54
55    /**
56     * <p>
57     * Helper objects, which decide whether or not a defined pattern condition holds.
58     * </p>
59     */
60    private List<InteractionPatternVisitor> patternVisitors;
61
62    /**
63     * <p>
64     * Flag, which indicates if the interaction pattern was found within a given task model.
65     * </p>
66     */
67    private boolean present = false;
68
69    /**
70     * <p>
71     * Constructor. Creates a new interaction pattern for a given root task and a collection of
72     * {@link InteractionPatternVisitor}s.
73     * </p>
74     *
75     * @param rootTask
76     *            Type of root task, which determines the order in which sub task appear.
77     * @param patternVisitors
78     *            {@link InteractionPatternVisitor}s, which decide whether or not a defined pattern
79     *            condition holds
80     */
81    public InteractionPattern(TaskTypeFilter rootTask,
82                              List<InteractionPatternVisitor> patternVisitors)
83    {
84        this.patternVisitors = patternVisitors;
85        this.rootTask = rootTask;
86    }
87
88    /**
89     *
90     * <p>
91     * Checks if a interaction pattern is contained in a given task model.
92     * </p>
93     *
94     * @param taskModel
95     *            {@link ITaskModel}, which might contain the interaction pattern
96     * @return true, iff interaction pattern is contained
97     */
98    public boolean containedIn(ITaskModel taskModel) {
99        List<ITask> allConcernedTasks = filterAllConcernedTasksFrom(taskModel);
100        for (ITask concernedTask : allConcernedTasks) {
101            checkTask(concernedTask);
102            if (this.present)
103                break;
104        }
105        return this.present;
106    }
107
108    /**
109     *
110     * <p>
111     * Returns all tasks of the given task model matching the provided interaction pattern.
112     * </p>
113     *
114     * @param taskModel
115     *            {@link ITaskModel}, which might contain the interaction pattern
116     * @return all tasks matched
117     */
118    public Collection<ITask> matchingTasks(ITaskModel taskModel) {
119        List<ITask> allConcernedTasks = filterAllConcernedTasksFrom(taskModel);
120        for (Iterator<ITask> iterator = allConcernedTasks.iterator(); iterator.hasNext();) {
121            ITask concernedTask = iterator.next();
122            checkTask(concernedTask);
123            if (this.present)
124                this.present = false;
125            else
126                iterator.remove();
127        }
128        return allConcernedTasks;
129    }
130
131    /**
132     *
133     * <p>
134     * Checks a single {@link ITask} for the interaction pattern.
135     * </p>
136     *
137     * @param task
138     *            task, which might contain the interaction pattern
139     */
140    private void checkTask(ITask task) {
141        applyAllVisitors(task);
142        if (allVisitorsArePresent()) {
143            this.present = true;
144        }
145        else {
146            resetAllVisitors();
147        }
148    }
149
150    /**
151     *
152     * <p>
153     * Checks if a interaction pattern is contained in a given task.
154     * </p>
155     *
156     * @param task
157     *            task, which might contain the interaction pattern
158     * @return true, iff interaction pattern is contained
159     */
160    public boolean containedIn(ITask task) {
161        checkTask(task);
162        return this.present;
163    }
164
165    /**
166     *
167     * <p>
168     * Method applys all {@link InteractionPatternVisitor}s, to check single interaction pattern
169     * conditions.
170     * </p>
171     *
172     * @param task
173     *            task, which might contain the interaction pattern
174     */
175    private void applyAllVisitors(ITask task) {
176        Optional<InteractionPatternVisitor> previousVisitor = Optional.absent();
177        for (InteractionPatternVisitor visitor : patternVisitors) {
178            if (appliedOnSelectionNode(previousVisitor)) {
179                for (ITask selection : previousVisitor.get().getRetainedSelectionNodes()) {
180                    selection.accept(visitor);
181                }
182            }
183            else {
184                previousVisitor = Optional.of(visitor);
185                task.accept(visitor);
186            }
187        }
188    }
189
190    /**
191     *
192     * <p>
193     * Checks, if a {@link InteractionPatternVisitor} was applied on a {@link ISelection} task.
194     * </p>
195     *
196     * @param interactionPatternVisitor
197     *            {@link InteractionPatternVisitor}
198     * @return true, iff {@link InteractionPatternVisitor} was applied on {@link ISelection} task
199     */
200    private boolean appliedOnSelectionNode(Optional<InteractionPatternVisitor> interactionPatternVisitor)
201    {
202        return interactionPatternVisitor.isPresent() &&
203            interactionPatternVisitor.get().hasExcludedSelectionNodes();
204    }
205
206    /**
207     * <p>
208     * Filters given task model after root task of interaction pattern.
209     * </p>
210     *
211     * @param taskModel
212     *            {@link ITaskModel}
213     * @return all tasks of task model, which matches root task of interaction pattern
214     */
215    private List<ITask> filterAllConcernedTasksFrom(ITaskModel taskModel) {
216        return this.taskTreeFilter.filter(taskModel, this.rootTask).tasksMatchedFilter();
217    }
218
219    /**
220     * <p>
221     * Checks, if all interaction pattern condition are evaluated to true.
222     * </p>
223     *
224     * @return true, iff all interaction pattern condition are true
225     */
226    private boolean allVisitorsArePresent() {
227        Iterable<InteractionPatternVisitor> allPresent =
228            Iterables.filter(this.patternVisitors, new Predicate<InteractionPatternVisitor>() {
229
230                public boolean apply(InteractionPatternVisitor visitor) {
231                    return visitor.isPresent();
232                }
233
234            });
235        int cnt = Iterables.size(allPresent);
236        return cnt == this.patternVisitors.size();
237    }
238
239    /**
240     * <p>
241     * Resets all interaction pattern condition.
242     * </p>
243     *
244     */
245    private void resetAllVisitors() {
246        for (InteractionPatternVisitor visitor : this.patternVisitors) {
247            visitor.reset();
248        }
249
250    }
251
252}
Note: See TracBrowser for help on using the repository browser.