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

Last change on this file since 2042 was 2042, checked in by pharms, 9 years ago
  • finalized smell detection for phd thesis
File size: 9.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.ArrayList;
18import java.util.Collection;
19import java.util.HashMap;
20import java.util.HashSet;
21import java.util.LinkedList;
22import java.util.List;
23import java.util.Map;
24import java.util.Set;
25
26import de.ugoe.cs.autoquest.eventcore.IEventTarget;
27import de.ugoe.cs.autoquest.eventcore.gui.MouseClick;
28import de.ugoe.cs.autoquest.eventcore.gui.ValueSelection;
29import de.ugoe.cs.autoquest.eventcore.guimodel.ICheckBox;
30import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
31import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIView;
32import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
33import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
34import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
35import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
36import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
37import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
38import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
39
40/**
41 * TODO comment
42 *
43 * @version $Revision: $ $Date: 16.07.2012$
44 * @author 2012, last modified by $Author: pharms$
45 */
46public class CheckBoxMultipleSelectionRule 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        ValueChangeStatistics statistics = new ValueChangeStatistics();
56       
57        calculateStatistics(taskModel.getTasks(), statistics);
58
59        statistics.condenseCheckBoxGroups();
60       
61        UsabilityEvaluationResult results = new UsabilityEvaluationResult(taskModel);
62        analyzeStatistics(statistics, taskModel, results);
63
64        return results;
65    }
66
67    /**
68     *
69     */
70    private void analyzeStatistics(ValueChangeStatistics     statistics,
71                                   ITaskModel                taskModel,
72                                   UsabilityEvaluationResult results)
73    {
74        System.out.println("\n\n########################################\n");
75        final List<List<IEventTaskInstance>> actionInstancesInSameView = new LinkedList<>();
76       
77        for (IUserSession session : taskModel.getUserSessions()) {
78            for (ITaskInstance instance : session) {
79                final LinkedList<IEventTaskInstance> currentList = new LinkedList<>();
80               
81                instance.accept(new DefaultTaskInstanceTraversingVisitor() {
82                    @Override
83                    public void visit(IEventTaskInstance eventTaskInstance) {
84                        if (eventTaskInstance.getEvent().getTarget() instanceof IGUIElement) {
85                            IEventTarget target = eventTaskInstance.getEvent().getTarget();
86                            IGUIView currentView = ((IGUIElement) target).getView();
87                           
88                            IGUIView previousView = null;
89                            if (currentList.size() > 0) {
90                                target = currentList.getLast().getEvent().getTarget();
91                                previousView = ((IGUIElement) target).getView();
92                            }
93                           
94                            if ((previousView == currentView) ||
95                                ((previousView != null) && (previousView.equals(currentView))))
96                            {
97                                currentList.add(eventTaskInstance);
98                            }
99                            else {
100                                if (currentList.size() > 0) {
101                                    actionInstancesInSameView.add(new ArrayList<>(currentList));
102                                }
103                                currentList.clear();
104                                currentList.add(eventTaskInstance);
105                            }
106                        }
107                    }
108                });
109               
110                if (currentList.size() > 0) {
111                    actionInstancesInSameView.add(new ArrayList<>(currentList));
112                }
113            }
114        }
115
116       
117        Map<IGUIElement, List<IGUIElement>> checkBoxGroups = statistics.getCheckBoxGroups();
118       
119        for (Map.Entry<IGUIElement, List<IGUIElement>> group : checkBoxGroups.entrySet()) {
120            IGUIView currentView = group.getKey().getView();
121            int noOfEvents = 0;
122            int noOfGroupUsages = 0;
123            int noOfSingleCheckBoxUsages = 0;
124           
125            for (List<IEventTaskInstance> actionInstanceList : actionInstancesInSameView) {
126                IEventTarget target = actionInstanceList.get(0).getEvent().getTarget();
127                IGUIView viewOfList = ((IGUIElement) target).getView();
128               
129                if ((viewOfList == currentView) ||
130                    ((viewOfList != null) && (viewOfList.equals(currentView))))
131                {
132                    noOfGroupUsages++;
133                    boolean[] checkBoxUsages = new boolean[group.getValue().size()];
134                   
135                    for (IEventTaskInstance actionInstance : actionInstanceList) {
136                        int index = 0;
137                        for (IGUIElement checkBox : group.getValue()) {
138                            if ((("JFC".equals(actionInstance.getEvent().getTarget().getPlatform())) &&
139                                 (actionInstance.getEvent().getType() instanceof MouseClick) &&
140                                 (actionInstance.getEvent().getTarget().equals(checkBox))) ||
141                                ((actionInstance.getEvent().getType() instanceof ValueSelection<?>) &&
142                                 (actionInstance.getEvent().getTarget().equals(checkBox))))
143                            {
144                                checkBoxUsages[index] = !checkBoxUsages[index];
145                                noOfEvents++;
146                            }
147                            index++;
148                        }
149                    }
150                   
151                    int noOfCheckedBoxes = 0;
152                   
153                    for (int i = 0; i < checkBoxUsages.length; i++) {
154                        if (checkBoxUsages[i]) {
155                            noOfCheckedBoxes++;
156                        }
157                    }
158                   
159                    if (noOfCheckedBoxes == 1) {
160                        noOfSingleCheckBoxUsages++;
161                    }
162                }
163            }
164           
165            // get a value that is 1 if for one group usage there is on average one check box usage
166            // get a value of 0 if for one group usage there is on average two check box usages
167           
168            int ratio = noOfGroupUsages > 0 ? 1000 * noOfSingleCheckBoxUsages / noOfGroupUsages : 0;
169           
170            System.out.println(currentView + "  " + ratio + "  " + noOfGroupUsages + "  " +
171                               noOfSingleCheckBoxUsages);
172           
173            UsabilitySmellIntensity intensity = UsabilitySmellIntensity.getIntensity
174                (ratio, noOfEvents, -1);
175                   
176            if (intensity != null) {
177                Map<String, Object> parameters = new HashMap<String, Object>();
178                parameters.put("allUsages", noOfGroupUsages);
179                parameters.put("singleUsages", noOfSingleCheckBoxUsages);
180                parameters.put("ratio", 100 * noOfSingleCheckBoxUsages / noOfGroupUsages);
181                parameters.put("radioButtons", group.getValue());
182
183                results.addSmell
184                    (intensity, UsabilitySmellDescription.CHECK_BOX_SINGLE_SELECTION, parameters);
185            }
186        }
187    }
188
189    /**
190     *
191     */
192    private void calculateStatistics(Collection<ITask>     tasks,
193                                     ValueChangeStatistics statistics)
194    {
195        for (ITask task : tasks) {
196            if (task instanceof IEventTask) {
197                for (ITaskInstance taskInstance : task.getInstances()) {
198                    statistics.addValueChange((IEventTaskInstance) taskInstance);
199                }
200            }
201        }
202    }
203
204    /**
205     *
206     */
207    private static class ValueChangeStatistics {
208       
209        /** */
210        private Set<IGUIElement> checkBoxes = new HashSet<>();
211       
212        /** */
213        private Map<IGUIElement, List<IGUIElement>> checkBoxGroups = new HashMap<>();
214
215        /**
216         *
217         */
218        private void addValueChange(IEventTaskInstance instance) {
219            IGUIElement target = (IGUIElement) instance.getEvent().getTarget();
220           
221            if (target instanceof ICheckBox) {
222                checkBoxes.add(target);
223            }
224        }
225       
226        /**
227         *
228         */
229        private void condenseCheckBoxGroups() {
230            checkBoxGroups = RuleUtils.getGroups(checkBoxes, 3);
231        }
232
233        /**
234         *
235         */
236        private Map<IGUIElement, List<IGUIElement>> getCheckBoxGroups() {
237            return checkBoxGroups;
238        }
239
240    }
241
242}
Note: See TracBrowser for help on using the repository browser.