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

Last change on this file since 1292 was 1292, checked in by adeicke, 11 years ago

Refactored filter mechanism.

  • 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.ISelection;
24import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
25import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
26import de.ugoe.cs.autoquest.usability.taskmodel.filter.ITaskModelFilter;
27import de.ugoe.cs.autoquest.usability.taskmodel.filter.TaskModelFilter;
28import de.ugoe.cs.autoquest.usability.taskmodel.filter.types.TaskTypeFilter;
29
30/**
31 * <p>
32 * A interaction pattern is a simple approach to describe the structure of usage behaviour.
33 * </p>
34 *
35 * @author Alexander Deicke
36 */
37public class InteractionPattern {
38
39    /**
40     * <p>
41     * {@link TaskModelFilterAccessor}, which is used to filter a task model after different {@link ITask}s
42     * </p>
43     */
44    private ITaskModelFilter taskTreeFilter = new TaskModelFilter();
45
46    /**
47     * <p>
48     * Type of root task. Determines the order in which sub task appear.
49     * </p>
50     */
51    private TaskTypeFilter rootTask;
52
53    /**
54     * <p>
55     * Helper objects, which decide whether or not a defined pattern condition holds.
56     * </p>
57     */
58    private List<InteractionPatternVisitor> patternVisitors;
59
60    /**
61     * <p>
62     * Flag, which indicates if the interaction pattern was found within a given task model.
63     * </p>
64     */
65    private boolean present = false;
66
67    /**
68     * <p>
69     * Constructor. Creates a new interaction pattern for a given root task and a collection of
70     * {@link InteractionPatternVisitor}s.
71     * </p>
72     *
73     * @param rootTask
74     *            Type of root task, which determines the order in which sub task appear.
75     * @param patternVisitors
76     *            {@link InteractionPatternVisitor}s, which decide whether or not a defined pattern
77     *            condition holds
78     */
79    public InteractionPattern(TaskTypeFilter rootTask,
80                              List<InteractionPatternVisitor> patternVisitors)
81    {
82        this.patternVisitors = patternVisitors;
83        this.rootTask = rootTask;
84    }
85
86    /**
87     *
88     * <p>
89     * Checks if a interaction pattern is contained in a given task model.
90     * </p>
91     *
92     * @param taskModel
93     *            {@link ITaskModel}, which might contain the interaction pattern
94     * @return true, iff interaction pattern is contained
95     */
96    public boolean containedIn(ITaskModel taskModel) {
97        List<ITask> allConcernedTasks = filterAllConcernedTasksFrom(taskModel);
98        for (ITask concernedTask : allConcernedTasks) {
99            checkTask(concernedTask);
100            if (this.present)
101                break;
102        }
103        return this.present;
104    }
105
106    /**
107     *
108     * <p>
109     * Checks a single {@link ITask} for the interaction pattern.
110     * </p>
111     *
112     * @param task
113     *            task, which might contain the interaction pattern
114     */
115    private void checkTask(ITask task) {
116        applyAllVisitors(task);
117        if (allVisitorsArePresent()) {
118            this.present = true;
119        }
120        else {
121            resetAllVisitors();
122        }
123    }
124
125    /**
126     *
127     * <p>
128     * Checks if a interaction pattern is contained in a given task.
129     * </p>
130     *
131     * @param task
132     *            task, which might contain the interaction pattern
133     * @return true, iff interaction pattern is contained
134     */
135    public boolean containedIn(ITask task) {
136        checkTask(task);
137        return this.present;
138    }
139
140    /**
141     *
142     * <p>
143     * Method applys all {@link InteractionPatternVisitor}s, to check single interaction pattern
144     * conditions.
145     * </p>
146     *
147     * @param task
148     *            task, which might contain the interaction pattern
149     */
150    private void applyAllVisitors(ITask task) {
151        Optional<InteractionPatternVisitor> previousVisitor = Optional.absent();
152        for (InteractionPatternVisitor visitor : patternVisitors) {
153            if (appliedOnSelectionNode(previousVisitor)) {
154                for (ITask selection : previousVisitor.get().getRetainedSelectionNodes()) {
155                    selection.accept(visitor);
156                }
157            }
158            else {
159                previousVisitor = Optional.of(visitor);
160                task.accept(visitor);
161            }
162        }
163    }
164
165    /**
166     *
167     * <p>
168     * Checks, if a {@link InteractionPatternVisitor} was applied on a {@link ISelection} task.
169     * </p>
170     *
171     * @param interactionPatternVisitor
172     *            {@link InteractionPatternVisitor}
173     * @return true, iff {@link InteractionPatternVisitor} was applied on {@link ISelection} task
174     */
175    private boolean appliedOnSelectionNode(Optional<InteractionPatternVisitor> interactionPatternVisitor)
176    {
177        return interactionPatternVisitor.isPresent() &&
178            interactionPatternVisitor.get().hasExcludedSelectionNodes();
179    }
180
181    /**
182     * <p>
183     * Filters given task model after root task of interaction pattern.
184     * </p>
185     *
186     * @param taskModel
187     *            {@link ITaskModel}
188     * @return all tasks of task model, which matches root task of interaction pattern
189     */
190    private List<ITask> filterAllConcernedTasksFrom(ITaskModel taskModel) {
191        return this.taskTreeFilter.filter(taskModel, this.rootTask).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.