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

Last change on this file since 1493 was 1493, checked in by pharms, 10 years ago
  • state of the HCSE 2014 Paper. An appropriate tag will follow.
File size: 8.6 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.util.HashMap;
18import java.util.HashSet;
19import java.util.LinkedList;
20import java.util.List;
21import java.util.Map;
22import java.util.Set;
23
24import de.ugoe.cs.autoquest.eventcore.Event;
25import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel;
26import de.ugoe.cs.autoquest.eventcore.guimodel.IButton;
27import de.ugoe.cs.autoquest.eventcore.guimodel.ICheckBox;
28import de.ugoe.cs.autoquest.eventcore.guimodel.IComboBox;
29import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
30import de.ugoe.cs.autoquest.eventcore.guimodel.IListBox;
31import de.ugoe.cs.autoquest.eventcore.guimodel.IMenuButton;
32import de.ugoe.cs.autoquest.eventcore.guimodel.ITextArea;
33import de.ugoe.cs.autoquest.eventcore.guimodel.ITextField;
34import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
35import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
36import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
37import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
38import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
39
40/**
41 * TODO comment
42 *
43 * @version $Revision: $ $Date: 16.07.2012$
44 * @author 2012, last modified by $Author: pharms$
45 */
46public class UnusedGUIElementsRule implements UsabilityEvaluationRule {
47
48    /*
49     * (non-Javadoc)
50     *
51     * @see de.ugoe.cs.usability.UsabilityEvaluationRule#evaluate(TaskTree)
52     */
53    @Override
54    public UsabilityEvaluationResult evaluate(ITaskModel taskModel) {
55        UsabilityEvaluationResult results = new UsabilityEvaluationResult(taskModel);
56
57        GUIModel guiModel = getGUIModel(taskModel);
58        Set<IGUIElement> allGUIElements = getAllGUIElements(guiModel);
59        Set<IGUIElement> usedGUIElements = getUsedGUIElements(taskModel);
60        List<IGUIElement> unusedGUIElements = getUnusedGUIElements(usedGUIElements, allGUIElements);
61        handleUnusedGUIElements(unusedGUIElements, allGUIElements, results);
62
63        return results;
64    }
65
66    /**
67     * <p>
68     * TODO: comment
69     * </p>
70     *
71     * @param unusedGUIElements
72     * @param results
73     */
74    private void handleUnusedGUIElements(List<IGUIElement>         unusedGUIElements,
75                                         Set<IGUIElement>          allGUIElements,
76                                         UsabilityEvaluationResult results)
77    {
78        int ratio = 1000 * unusedGUIElements.size() / allGUIElements.size();
79       
80        UsabilityDefectSeverity severity =
81            UsabilityDefectSeverity.getSeverity(ratio, 200, 100, 50, 25);
82
83        if (severity != null) {
84            Map<String, Object> parameters = new HashMap<String, Object>();
85
86            parameters.put("ratio", ratio / 10);
87            parameters.put("noOfUnused", unusedGUIElements.size());
88            parameters.put("noOfAll", allGUIElements.size());
89            parameters.put("unusedGuiElements", unusedGUIElements);
90           
91            results.addDefect
92                (severity, UsabilityDefectDescription.UNUSED_GUI_ELEMENTS, parameters);
93        }
94     }
95
96    /**
97     * <p>
98     * TODO: comment
99     * </p>
100     *
101     * @param taskModel
102     * @return
103     */
104    private GUIModel getGUIModel(ITaskModel taskModel) {
105        for (ITask task : taskModel.getTasks()) {
106            if (task instanceof IEventTask) {
107                for (ITaskInstance instance : task.getInstances()) {
108                    Event event = ((IEventTaskInstance) instance).getEvent();
109                   
110                    if (event.getTarget() instanceof IGUIElement) {
111                        return ((IGUIElement) event.getTarget()).getGUIModel();
112                    }
113                }
114            }
115        }
116       
117        return null;
118    }
119
120    /**
121     * <p>
122     * TODO: comment
123     * </p>
124     *
125     * @param taskModel
126     */
127    private Set<IGUIElement> getUsedGUIElements(ITaskModel taskModel) {
128        Set<IGUIElement> usedGUIElements = new HashSet<IGUIElement>();
129       
130        for (ITask task : taskModel.getTasks()) {
131            if (task instanceof IEventTask) {
132                for (ITaskInstance instance : task.getInstances()) {
133                    Event event = ((IEventTaskInstance) instance).getEvent();
134                   
135                    if (event.getTarget() instanceof IGUIElement) {
136                        usedGUIElements.add((IGUIElement) event.getTarget());
137                    }
138                }
139            }
140        }
141       
142        return usedGUIElements;
143    }
144   
145    /**
146     * <p>
147     * TODO: comment
148     * </p>
149     *
150     * @param taskModel
151     */
152    private Set<IGUIElement> getAllGUIElements(GUIModel guiModel) {
153        Set<IGUIElement> allGUIElements = new HashSet<IGUIElement>();
154       
155        if (guiModel != null) {
156            GUIModel.Traverser traverser = guiModel.getTraverser();
157
158            IGUIElement currentGUIElement = null;
159            do {
160                if (traverser.hasFirstChild()) {
161                    currentGUIElement = traverser.firstChild();
162                }
163                else if (traverser.hasNextSibling()) {
164                    currentGUIElement = traverser.nextSibling();
165                }
166                else {
167                    while (currentGUIElement != null) {
168                        currentGUIElement = traverser.parent();
169                        if (traverser.hasNextSibling()) {
170                            currentGUIElement = traverser.nextSibling();
171                            break;
172                        }
173                    }
174                }
175
176                if (isRelevant(currentGUIElement)) {
177                    allGUIElements.add(currentGUIElement);
178                }
179            }
180            while (currentGUIElement != null);
181        }
182       
183        return allGUIElements;
184    }
185   
186    /**
187     * <p>
188     * TODO: comment
189     * </p>
190     *
191     * @param taskModel
192     */
193    private List<IGUIElement> getUnusedGUIElements(Set<IGUIElement> usedGUIElements,
194                                                   Set<IGUIElement> allGUIElements)
195    {
196        List<IGUIElement> unusedGUIElements = new LinkedList<IGUIElement>();
197        for (IGUIElement currentGUIElement : allGUIElements) {
198            if (isRelevant(currentGUIElement) &&
199                !belongsToUsedGUIElements(currentGUIElement, usedGUIElements))
200            {
201                unusedGUIElements.add(currentGUIElement);
202            }
203        }
204       
205        return unusedGUIElements;
206    }
207
208    /**
209     * <p>
210     * TODO: comment
211     * </p>
212     *
213     * @param currentGUIElement
214     * @param usedGUIElements
215     * @return
216     */
217    private boolean belongsToUsedGUIElements(IGUIElement      relevantGUIElement,
218                                             Set<IGUIElement> usedGUIElements)
219    {
220        if (usedGUIElements.contains(relevantGUIElement)) {
221            return true;
222        }
223        else {
224            // in some cases, the events are recorded for the children of the relevant GUI elements
225            // therefore, check the children, as well.
226            List<IGUIElement> children =
227                relevantGUIElement.getGUIModel().getChildren(relevantGUIElement);
228           
229            if (children != null) {
230                for (IGUIElement child : children) {
231                    if (belongsToUsedGUIElements(child, usedGUIElements)) {
232                        return true;
233                    }
234                }
235            }
236        }
237       
238        return false;
239    }
240
241    /**
242     * <p>
243     * TODO: comment
244     * </p>
245     *
246     * @param currentGUIElement
247     * @return
248     */
249    private boolean isRelevant(IGUIElement currentGUIElement) {
250        if (currentGUIElement == null) {
251            return false;
252        }
253       
254        if ((currentGUIElement instanceof IButton) ||
255            (currentGUIElement instanceof ICheckBox) ||
256            (currentGUIElement instanceof IComboBox) ||
257            (currentGUIElement instanceof IListBox) ||
258            (currentGUIElement instanceof IMenuButton) ||
259            (currentGUIElement instanceof ITextArea) ||
260            (currentGUIElement instanceof ITextField))
261        {
262            return true;
263        }
264       
265        return false;
266    }
267}
Note: See TracBrowser for help on using the repository browser.