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

Last change on this file since 1918 was 1918, checked in by pharms, 9 years ago
  • extension with further smell detections
  • may not fully work. But Hudson is more happy because compile errors should be gone
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        UsabilitySmellIntensity severity = UsabilitySmellIntensity.getIntensity(ratio);
81
82        if (severity != null) {
83            Map<String, Object> parameters = new HashMap<String, Object>();
84
85            parameters.put("ratio", ratio / 10);
86            parameters.put("noOfUnused", unusedGUIElements.size());
87            parameters.put("noOfAll", allGUIElements.size());
88            parameters.put("unusedGuiElements", unusedGUIElements);
89           
90            results.addSmell
91                (severity, UsabilitySmellDescription.UNUSED_GUI_ELEMENTS, parameters);
92        }
93     }
94
95    /**
96     * <p>
97     * TODO: comment
98     * </p>
99     *
100     * @param taskModel
101     * @return
102     */
103    private GUIModel getGUIModel(ITaskModel taskModel) {
104        for (ITask task : taskModel.getTasks()) {
105            if (task instanceof IEventTask) {
106                for (ITaskInstance instance : task.getInstances()) {
107                    Event event = ((IEventTaskInstance) instance).getEvent();
108                   
109                    if (event.getTarget() instanceof IGUIElement) {
110                        return ((IGUIElement) event.getTarget()).getGUIModel();
111                    }
112                }
113            }
114        }
115       
116        return null;
117    }
118
119    /**
120     * <p>
121     * TODO: comment
122     * </p>
123     *
124     * @param taskModel
125     */
126    private Set<IGUIElement> getUsedGUIElements(ITaskModel taskModel) {
127        Set<IGUIElement> usedGUIElements = new HashSet<IGUIElement>();
128       
129        for (ITask task : taskModel.getTasks()) {
130            if (task instanceof IEventTask) {
131                for (ITaskInstance instance : task.getInstances()) {
132                    Event event = ((IEventTaskInstance) instance).getEvent();
133                   
134                    if (event.getTarget() instanceof IGUIElement) {
135                        usedGUIElements.add((IGUIElement) event.getTarget());
136                    }
137                }
138            }
139        }
140       
141        return usedGUIElements;
142    }
143   
144    /**
145     * <p>
146     * TODO: comment
147     * </p>
148     *
149     * @param taskModel
150     */
151    private Set<IGUIElement> getAllGUIElements(GUIModel guiModel) {
152        Set<IGUIElement> allGUIElements = new HashSet<IGUIElement>();
153       
154        if (guiModel != null) {
155            GUIModel.Traverser traverser = guiModel.getTraverser();
156
157            IGUIElement currentGUIElement = null;
158            do {
159                if (traverser.hasFirstChild()) {
160                    currentGUIElement = traverser.firstChild();
161                }
162                else if (traverser.hasNextSibling()) {
163                    currentGUIElement = traverser.nextSibling();
164                }
165                else {
166                    while (currentGUIElement != null) {
167                        currentGUIElement = traverser.parent();
168                        if (traverser.hasNextSibling()) {
169                            currentGUIElement = traverser.nextSibling();
170                            break;
171                        }
172                    }
173                }
174
175                if (isRelevant(currentGUIElement)) {
176                    allGUIElements.add(currentGUIElement);
177                }
178            }
179            while (currentGUIElement != null);
180        }
181       
182        return allGUIElements;
183    }
184   
185    /**
186     * <p>
187     * TODO: comment
188     * </p>
189     *
190     * @param taskModel
191     */
192    private List<IGUIElement> getUnusedGUIElements(Set<IGUIElement> usedGUIElements,
193                                                   Set<IGUIElement> allGUIElements)
194    {
195        List<IGUIElement> unusedGUIElements = new LinkedList<IGUIElement>();
196        for (IGUIElement currentGUIElement : allGUIElements) {
197            if (isRelevant(currentGUIElement) &&
198                !belongsToUsedGUIElements(currentGUIElement, usedGUIElements))
199            {
200                unusedGUIElements.add(currentGUIElement);
201            }
202        }
203       
204        return unusedGUIElements;
205    }
206
207    /**
208     * <p>
209     * TODO: comment
210     * </p>
211     *
212     * @param currentGUIElement
213     * @param usedGUIElements
214     * @return
215     */
216    private boolean belongsToUsedGUIElements(IGUIElement      relevantGUIElement,
217                                             Set<IGUIElement> usedGUIElements)
218    {
219        if (usedGUIElements.contains(relevantGUIElement)) {
220            return true;
221        }
222        else {
223            // in some cases, the events are recorded for the children of the relevant GUI elements
224            // therefore, check the children, as well.
225            List<IGUIElement> children =
226                relevantGUIElement.getGUIModel().getChildren(relevantGUIElement);
227           
228            if (children != null) {
229                for (IGUIElement child : children) {
230                    if (belongsToUsedGUIElements(child, usedGUIElements)) {
231                        return true;
232                    }
233                }
234            }
235        }
236       
237        return false;
238    }
239
240    /**
241     * <p>
242     * TODO: comment
243     * </p>
244     *
245     * @param currentGUIElement
246     * @return
247     */
248    private boolean isRelevant(IGUIElement currentGUIElement) {
249        if (currentGUIElement == null) {
250            return false;
251        }
252       
253        if ((currentGUIElement instanceof IButton) ||
254            (currentGUIElement instanceof ICheckBox) ||
255            (currentGUIElement instanceof IComboBox) ||
256            (currentGUIElement instanceof IListBox) ||
257            (currentGUIElement instanceof IMenuButton) ||
258            (currentGUIElement instanceof ITextArea) ||
259            (currentGUIElement instanceof ITextField))
260        {
261            return true;
262        }
263       
264        return false;
265    }
266}
Note: See TracBrowser for help on using the repository browser.