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

Last change on this file since 1217 was 1217, checked in by adeicke, 11 years ago
  • Added proper formating and JavaDoc?.
  • Several renaming refactorings.
  • Property svn:mime-type set to text/plain
File size: 7.1 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.List;
18
19import com.google.common.base.Optional;
20import com.google.common.base.Predicate;
21import com.google.common.collect.Iterables;
22
23import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
24import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
25import de.ugoe.cs.autoquest.usability.taskmodel.filter.IterativeDFSFilterStrategy;
26import de.ugoe.cs.autoquest.usability.taskmodel.filter.types.TaskModelFilter;
27import de.ugoe.cs.autoquest.usability.taskmodel.filter.types.TaskTypeFilter;
28
29/**
30 * <p>
31 * A interaction pattern is a simple approach to describe the structure of usage behaviour.
32 * </p>
33 *
34 * @author Alexander Deicke
35 */
36public class InteractionPattern {
37
38    /**
39     * <p>
40     * {@link TaskModelFilter}, which is used to filter a task model after different {@link ITask}s
41     * </p>
42     */
43    private TaskModelFilter taskTreeFilter = new TaskModelFilter(new IterativeDFSFilterStrategy());
44
45    /**
46     * <p>
47     * Type of root task. Determines the order in which sub task appear.
48     * </p>
49     */
50    private TaskTypeFilter rootTask;
51
52    /**
53     * <p>
54     * Helper objects, which decide whether or not a defined pattern condition holds.
55     * </p>
56     */
57    private List<InteractionPatternVisitor> patternVisitors;
58
59    /**
60     * <p>
61     * Flag, which indicates if the interaction pattern was found within a given task model.
62     * </p>
63     */
64    private boolean present = false;
65
66    /**
67     * <p>
68     * Constructor. Creates a new interaction pattern for a given root task and a collection of
69     * {@link InteractionPatternVisitor}s.
70     * </p>
71     *
72     * @param rootTask
73     *            Type of root task, which determines the order in which sub task appear.
74     * @param patternVisitors
75     *            {@link InteractionPatternVisitor}s, which decide whether or not a defined pattern
76     *            condition holds
77     */
78    public InteractionPattern(TaskTypeFilter rootTask,
79                              List<InteractionPatternVisitor> patternVisitors)
80    {
81        this.patternVisitors = patternVisitors;
82        this.rootTask = rootTask;
83    }
84
85    /**
86     *
87     * <p>
88     * Checks if a interaction pattern is contained in a given task model.
89     * </p>
90     *
91     * @param taskModel
92     *            {@link ITaskModel}, which might contain the interaction pattern
93     * @return true, iff interaction pattern is contained
94     */
95    public boolean containedIn(ITaskModel taskModel) {
96        List<ITask> allConcernedTasks = filterAllConcernedTasksFrom(taskModel);
97        for (ITask concernedTask : allConcernedTasks) {
98            checkTask(concernedTask);
99            if (this.present)
100                break;
101        }
102        return this.present;
103    }
104
105    /**
106     *
107     * <p>
108     * Checks a single {@link ITask} for the interaction pattern.
109     * </p>
110     *
111     * @param task
112     *            task, which might contain the interaction pattern
113     */
114    private void checkTask(ITask task) {
115        applyAllVisitors(task);
116        if (allVisitorsArePresent()) {
117            this.present = true;
118        }
119        else {
120            resetAllVisitors();
121        }
122    }
123
124    /**
125     *
126     * <p>
127     * Checks if a interaction pattern is contained in a given task.
128     * </p>
129     *
130     * @param task
131     *            task, which might contain the interaction pattern
132     * @return true, iff interaction pattern is contained
133     */
134    public boolean containedIn(ITask task) {
135        checkTask(task);
136        return this.present;
137    }
138
139    /**
140     *
141     * <p>
142     * Method applys all {@link InteractionPatternVisitor}s, to check single interaction pattern
143     * conditions.
144     * </p>
145     *
146     * @param task
147     *            task, which might contain the interaction pattern
148     */
149    private void applyAllVisitors(ITask task) {
150        Optional<InteractionPatternVisitor> previousVisitor = Optional.absent();
151        for (InteractionPatternVisitor visitor : patternVisitors) {
152            if (appliedOnSelectionNode(previousVisitor)) {
153                for (ITask selection : previousVisitor.get().getRetainedSelectionNodes()) {
154                    selection.accept(visitor);
155                }
156            }
157            else {
158                previousVisitor = Optional.of(visitor);
159                task.accept(visitor);
160            }
161        }
162    }
163
164    /**
165     *
166     * <p>
167     * Checks, if a {@link InteractionPatternVisitor} was applied on a {@link ISelection} task.
168     * </p>
169     *
170     * @param interactionPatternVisitor
171     *            {@link InteractionPatternVisitor}
172     * @return true, iff {@link InteractionPatternVisitor} was applied on {@link ISelection} task
173     */
174    private boolean appliedOnSelectionNode(Optional<InteractionPatternVisitor> interactionPatternVisitor)
175    {
176        return interactionPatternVisitor.isPresent() &&
177            interactionPatternVisitor.get().hasExcludedSelectionNodes();
178    }
179
180    /**
181     * <p>
182     * Filters given task model after root task of interaction pattern.
183     * </p>
184     *
185     * @param taskModel
186     *            {@link ITaskModel}
187     * @return all tasks of task model, which matches root task of interaction pattern
188     */
189    private List<ITask> filterAllConcernedTasksFrom(ITaskModel taskModel) {
190        return this.taskTreeFilter.filterByNodeType(this.rootTask).from(taskModel)
191            .tasksMatchedFilter();
192    }
193
194    /**
195     * <p>
196     * Checks, if all interaction pattern condition are evaluated to true.
197     * </p>
198     *
199     * @return true, iff all interaction pattern condition are true
200     */
201    private boolean allVisitorsArePresent() {
202        Iterable<InteractionPatternVisitor> allPresent =
203            Iterables.filter(this.patternVisitors, new Predicate<InteractionPatternVisitor>() {
204
205                public boolean apply(InteractionPatternVisitor visitor) {
206                    return visitor.isPresent();
207                }
208
209            });
210        return Iterables.size(allPresent) == this.patternVisitors.size();
211    }
212
213    /**
214     * <p>
215     * Resets all interaction pattern condition.
216     * </p>
217     *
218     */
219    private void resetAllVisitors() {
220        for (InteractionPatternVisitor visitor : this.patternVisitors) {
221            visitor.reset();
222        }
223
224    }
225
226}
Note: See TracBrowser for help on using the repository browser.