source: trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/RequiredScrollRule.java @ 1335

Last change on this file since 1335 was 1335, checked in by pharms, 10 years ago
  • corrected and extended usability evaluations
  • checking now more text field specific for required input formats and word repetitions
  • checking also for required scrolls
File size: 6.8 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;
16
17import java.text.DecimalFormat;
18import java.util.Collection;
19import java.util.HashMap;
20import java.util.Map;
21
22import de.ugoe.cs.autoquest.eventcore.IEventType;
23import de.ugoe.cs.autoquest.eventcore.gui.Scroll;
24import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
25import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance;
26import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance;
27import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
28import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
29import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance;
30import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
31import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
32import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
33
34/**
35 * TODO comment
36 *
37 * @version $Revision: $ $Date: 16.07.2012$
38 * @author 2012, last modified by $Author: pharms$
39 */
40public class RequiredScrollRule implements UsabilityEvaluationRule {
41
42    /*
43     * (non-Javadoc)
44     *
45     * @see de.ugoe.cs.usability.UsabilityEvaluationRule#evaluate(TaskTree)
46     */
47    @Override
48    public UsabilityEvaluationResult evaluate(ITaskModel taskModel) {
49        Map<ITask, Integer> smellingTasks = getTasksStartingWithScroll(taskModel.getTasks());
50
51        UsabilityEvaluationResult results = new UsabilityEvaluationResult();
52        analyzeTasksStartingWithScroll(smellingTasks, results);
53
54        return results;
55    }
56
57    /**
58     *
59     */
60    private void analyzeTasksStartingWithScroll(Map<ITask, Integer>       smellingTasks,
61                                                UsabilityEvaluationResult results)
62    {
63
64        for (Map.Entry<ITask, Integer> entry : smellingTasks.entrySet()) {
65            float ratio = entry.getValue() / (float) entry.getKey().getInstances().size();
66
67            UsabilityDefectSeverity severity = null;
68            if (ratio > 0.9) {
69                severity = UsabilityDefectSeverity.HIGH;
70            }
71            else if (ratio > 0.6) {
72                severity = UsabilityDefectSeverity.MEDIUM;
73            }
74            else if (ratio > 0.4) {
75                severity = UsabilityDefectSeverity.LOW;
76            }
77            else if (ratio > 0.2) {
78                severity = UsabilityDefectSeverity.INFO;
79            }
80
81            if (severity != null) {
82                Map<String, String> parameters = new HashMap<String, String>();
83                parameters.put("task", entry.getKey().toString());
84                parameters.put("scrollRatio", DecimalFormat.getInstance().format(ratio * 100));
85
86                results.addDefect(severity, UsabilityDefectDescription.SCROLL_REQUIRED, parameters);
87            }
88        }
89    }
90
91    /**
92     *
93     */
94    private Map<ITask, Integer> getTasksStartingWithScroll(Collection<ITask> tasks) {
95        Map<ITask, Integer> scrollCounts = new HashMap<ITask, Integer>();
96       
97        for (ITask task : tasks) {
98            // only sequences are important for required scrolls
99            if (task instanceof ISequence) {
100                int count = countInstancesStartingWithScroll(task);
101                if (count > 0) {
102                    scrollCounts.put(task, count);
103                }
104            }
105        }
106       
107        return scrollCounts;
108    }
109
110    /**
111     *
112     */
113    private int countInstancesStartingWithScroll(ITask task) {
114        Collection<ITaskInstance> instances = task.getInstances();
115       
116        int counter = 0;
117        for (ITaskInstance instance : instances) {
118            if (startsWithScroll(instance)) {
119                counter++;
120            }
121        }
122       
123        return counter;
124    }
125
126    /**
127     *
128     */
129    private boolean startsWithScroll(ITaskInstance instance) {
130        if (instance instanceof ISequenceInstance) {
131            ITaskInstance firstChild = ((ISequenceInstance) instance).size() > 1 ?
132                ((ISequenceInstance) instance).get(0) : null;
133
134            if (firstChild == null) {
135                throw new IllegalArgumentException
136                    ("instance of a sequence must have at least two children");
137            }
138
139            if (startsWithScroll(firstChild)) {
140                return true;
141            }
142        }
143        else if (instance instanceof ISelectionInstance) {
144            ITaskInstance child = ((ISelectionInstance) instance).getChild();
145           
146            if (child != null) {
147                return startsWithScroll(child);
148            }
149            else {
150                throw new IllegalArgumentException("instance of a selection must have a child");
151            }
152        }
153        else if (instance instanceof IIterationInstance) {
154            ITaskInstance firstChild = ((IIterationInstance) instance).size() > 0 ?
155                ((IIterationInstance) instance).get(0) : null;
156
157            if (firstChild == null) {
158                throw new IllegalArgumentException
159                    ("instance of an iteration must have at least one child");
160            }
161
162            if (startsWithScroll(firstChild)) {
163                return true;
164            }
165        }
166        else if (instance instanceof IOptionalInstance) {
167            ITaskInstance child = ((IOptionalInstance) instance).getChild();
168           
169            if (child != null) {
170                return startsWithScroll(child);
171            }
172        }
173        else if (isScroll(instance)) {
174            return true;
175        }
176       
177        return false;
178    }
179
180    /**
181     * @param firstChild
182     * @return
183     */
184    private boolean isScroll(ITaskInstance instance) {
185        ITaskInstance instanceToCheck = instance;
186       
187        if (instanceToCheck instanceof IIterationInstance) {
188            instanceToCheck = ((IIterationInstance) instanceToCheck).size() > 0 ?
189                ((IIterationInstance) instanceToCheck).get(0) : null;
190
191            if (instanceToCheck == null) {
192                throw new IllegalArgumentException
193                    ("instance of an iteration must have at least one child");
194            }
195        }
196       
197        if (instanceToCheck instanceof IEventTaskInstance) {
198            IEventType type = ((IEventTaskInstance) instanceToCheck).getEvent().getType();
199           
200            return (type instanceof Scroll);
201        }
202       
203        return false;
204    }
205
206}
Note: See TracBrowser for help on using the repository browser.