Ignore:
Timestamp:
10/20/15 10:11:04 (9 years ago)
Author:
pharms
Message:
  • finalized smell detection for phd thesis
Location:
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/CheckBoxMultipleSelectionRule.java

    r1918 r2042  
    1515package de.ugoe.cs.autoquest.usability; 
    1616 
     17import java.util.ArrayList; 
    1718import java.util.Collection; 
    1819import java.util.HashMap; 
    1920import java.util.HashSet; 
     21import java.util.LinkedList; 
    2022import java.util.List; 
    2123import java.util.Map; 
    2224import java.util.Set; 
    2325 
     26import de.ugoe.cs.autoquest.eventcore.IEventTarget; 
     27import de.ugoe.cs.autoquest.eventcore.gui.MouseClick; 
     28import de.ugoe.cs.autoquest.eventcore.gui.ValueSelection; 
    2429import de.ugoe.cs.autoquest.eventcore.guimodel.ICheckBox; 
    2530import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; 
    26 import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskTraversingVisitor; 
     31import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIView; 
     32import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 
    2733import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 
    2834import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 
    29 import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; 
    30 import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship; 
    3135import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
    3236import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 
    3337import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 
    34 import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskMetric; 
     38import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; 
    3539 
    3640/** 
     
    6872                                   UsabilityEvaluationResult results) 
    6973    { 
     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         
    70117        Map<IGUIElement, List<IGUIElement>> checkBoxGroups = statistics.getCheckBoxGroups(); 
    71118         
    72         CHECK_NEXT_GROUP: 
    73         for (List<IGUIElement> group : checkBoxGroups.values()) { 
    74             Set<ITask> tasksUsingGroup = new HashSet<>(); 
    75              
    76             for (IGUIElement checkBox : group) { 
    77                 Set<ITask> tasksUsingCheckBox = getTasksUsingCheckBox(checkBox, taskModel); 
     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(); 
    78128                 
    79                 for (ITask taskUsingCheckBox : tasksUsingCheckBox) { 
    80                     if (tasksUsingGroup.contains(taskUsingCheckBox)) { 
    81                         continue CHECK_NEXT_GROUP; 
    82                     } 
    83                     else { 
    84                         tasksUsingGroup.add(taskUsingCheckBox); 
     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++; 
    85161                    } 
    86162                } 
    87163            } 
    88164             
    89             if (tasksUsingGroup.size() > 0) { 
    90                 int eventCoverage = 0; 
    91                 int allRecordedEvents = 0; 
    92                  
    93                 for (ITask task : tasksUsingGroup) { 
    94                     if (task instanceof IEventTask) { 
    95                         eventCoverage += 
    96                             taskModel.getTaskInfo(task).getMeasureValue(TaskMetric.EVENT_COVERAGE); 
    97                     } 
    98                 } 
    99                  
    100                 for (ITask task : taskModel.getTasks()) { 
    101                     if (task instanceof IEventTask) { 
    102                         allRecordedEvents += 
    103                             taskModel.getTaskInfo(task).getMeasureValue(TaskMetric.EVENT_COVERAGE); 
    104                     } 
    105                 } 
    106                  
    107                  
    108                 UsabilitySmellIntensity intensity = UsabilitySmellIntensity.getIntensity 
    109                     ((int) (1000 * eventCoverage / allRecordedEvents), eventCoverage, -1); 
    110                      
    111                 if (intensity != null) { 
    112                     Map<String, Object> parameters = new HashMap<String, Object>(); 
    113                     parameters.put("radioButtons", group); 
    114  
    115                     results.addSmell 
    116                         (intensity, UsabilitySmellDescription.CHECK_BOX_SINGLE_SELECTION, 
    117                          parameters); 
    118                 } 
    119             } 
    120         } 
    121     } 
    122  
    123     /** 
    124      *  
    125      */ 
    126     private Set<ITask> getTasksUsingCheckBox(final IGUIElement checkBox, ITaskModel taskModel) { 
    127         final Set<ITask> tasksUsingCheckBox = new HashSet<ITask>(); 
    128          
    129         for (ITask candidate : taskModel.getTasks()) { 
    130             candidate.accept(new DefaultTaskTraversingVisitor() { 
    131                 @Override 
    132                 public void visit(IEventTask eventTask) { 
    133                     if (!eventTask.getInstances().isEmpty()) { 
    134                         IEventTaskInstance instance = 
    135                             (IEventTaskInstance) eventTask.getInstances().iterator().next(); 
    136                          
    137                         if (checkBox.equals(instance.getEvent().getTarget())) { 
    138                             tasksUsingCheckBox.add(eventTask); 
    139                         } 
    140                     } 
    141                 } 
    142                  
    143                 @Override 
    144                 public void visit(IStructuringTemporalRelationship relationship) { 
    145                     if (tasksUsingCheckBox.contains(relationship)) { 
    146                         return; 
    147                     } 
    148                     else { 
    149                         for (ITask child : relationship.getChildren()) { 
    150                             if (tasksUsingCheckBox.contains(child)) { 
    151                                 tasksUsingCheckBox.add(relationship); 
    152                                 return; 
    153                             } 
    154                         } 
    155                          
    156                         super.visit(relationship); 
    157                          
    158                         for (ITask child : relationship.getChildren()) { 
    159                             if (tasksUsingCheckBox.contains(child)) { 
    160                                 tasksUsingCheckBox.add(relationship); 
    161                                 break; 
    162                             } 
    163                         } 
    164                     } 
    165                 } 
    166  
    167                 @Override 
    168                 public void visit(IMarkingTemporalRelationship relationship) { 
    169                     if (tasksUsingCheckBox.contains(relationship)) { 
    170                         return; 
    171                     } 
    172                     else { 
    173                         if (tasksUsingCheckBox.contains(relationship.getMarkedTask())) { 
    174                             tasksUsingCheckBox.add(relationship); 
    175                             return; 
    176                         } 
    177                          
    178                         super.visit(relationship); 
    179                          
    180                         if (tasksUsingCheckBox.contains(relationship.getMarkedTask())) { 
    181                             tasksUsingCheckBox.add(relationship); 
    182                             return; 
    183                         } 
    184                     } 
    185                 } 
    186             }); 
    187         } 
    188          
    189         return tasksUsingCheckBox; 
     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        } 
    190187    } 
    191188 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/DataEntryMethodChangeRule.java

    r1960 r2042  
    2929import de.ugoe.cs.autoquest.eventcore.gui.ValueSelection; 
    3030import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 
     31import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskTraversingVisitor; 
     32import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 
    3133import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 
    3234import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 
     
    98100                int ratio = getAverageDataEntryMethodChangeRatio((ISequence) task); 
    99101                 
    100                 if (ratio > 0) { 
     102                if ((ratio > 0) && (getLeafNodes(task) > 2)) { 
    101103                    methodChangeRatios.put(task, ratio); 
    102104                } 
     
    105107         
    106108        return methodChangeRatios; 
     109    } 
     110 
     111    /** 
     112     * 
     113     */ 
     114    private int getLeafNodes(ITask task) { 
     115        final int[] counter = new int[1]; 
     116         
     117        task.accept(new DefaultTaskTraversingVisitor() { 
     118            @Override 
     119            public void visit(IEventTask eventTask) { 
     120                counter[0]++; 
     121            } 
     122        }); 
     123         
     124        return counter[0]; 
    107125    } 
    108126 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/DefaultValueRule.java

    r1941 r2042  
    2929 
    3030import de.ugoe.cs.autoquest.eventcore.Event; 
     31import de.ugoe.cs.autoquest.eventcore.gui.MouseClick; 
    3132import de.ugoe.cs.autoquest.eventcore.gui.TextInput; 
    3233import de.ugoe.cs.autoquest.eventcore.gui.ValueSelection; 
    3334import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel; 
    3435import de.ugoe.cs.autoquest.eventcore.guimodel.ICheckBox; 
     36import de.ugoe.cs.autoquest.eventcore.guimodel.IComboBox; 
    3537import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; 
    3638import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec; 
     
    136138            maxObserved = Math.max(maxObserved, selectedValue.getValue()); 
    137139             
    138             if (mostOftenSelected.size() > 0) { 
    139                 ListIterator<Object> iterator = mostOftenSelected.listIterator(); 
    140                 while (iterator.hasNext()) { 
    141                     if (selectedValues.get(iterator.next()) < selectedValue.getValue()) { 
    142                         iterator.previous(); 
    143                         iterator.add(selectedValue.getKey()); 
    144                      
    145                         while (mostOftenSelected.size() > 5) { 
    146                             mostOftenSelected.removeLast(); 
    147                         } 
    148                      
    149                         break; 
    150                     } 
    151                 } 
    152             } 
    153             else { 
     140            boolean added = false; 
     141            ListIterator<Object> iterator = mostOftenSelected.listIterator(); 
     142            while (iterator.hasNext()) { 
     143                if (selectedValues.get(iterator.next()) < selectedValue.getValue()) { 
     144                    iterator.previous(); 
     145                    iterator.add(selectedValue.getKey()); 
     146                    added = true; 
     147                    break; 
     148                } 
     149            } 
     150             
     151            if (!added) { 
    154152                mostOftenSelected.add(selectedValue.getKey()); 
     153            } 
     154             
     155            while (mostOftenSelected.size() > 5) { 
     156                mostOftenSelected.removeLast(); 
    155157            } 
    156158        } 
     
    163165        } 
    164166         
    165         if ((expected.length == 1) || 
     167        if ((expected.length > 1) && 
    166168            (new ChiSquareTest().chiSquareTest(expected, observed, 0.05))) 
    167169        { 
     
    218220     */ 
    219221    private boolean isValueSelection(ITaskInstance instance) { 
    220         return (instance instanceof IEventTaskInstance) && 
    221             ((((IEventTaskInstance) instance).getEvent().getType() instanceof TextInput) || 
    222              (((IEventTaskInstance) instance).getEvent().getType() instanceof ValueSelection)); 
     222        if (instance instanceof IEventTaskInstance) { 
     223            Event event = ((IEventTaskInstance) instance).getEvent(); 
     224         
     225            if ((event.getType() instanceof TextInput) || 
     226                (event.getType() instanceof ValueSelection)) 
     227            { 
     228                return true; 
     229            } 
     230             
     231            if (("JFC".equals(event.getTarget().getPlatform())) && 
     232                (event.getTarget() instanceof ICheckBox) && 
     233                (event.getType() instanceof MouseClick)) 
     234            { 
     235                return true; 
     236            } 
     237        } 
     238         
     239        return false; 
    223240    } 
    224241 
     
    439456                        ((ValueSelection<?>) valueChange.getEvent().getType()).getSelectedValue(); 
    440457                     
    441                     if ((target instanceof IRadioButton) || (target instanceof ICheckBox)) { 
     458                    if ((target.target instanceof IRadioButton) || 
     459                        (target.target instanceof ICheckBox)) 
     460                    { 
    442461                        selectedValue = selectedValue + " (" + target + ")"; 
     462                    } 
     463                    else if (target.target instanceof IComboBox) { 
     464                        if (selectedValue == null) { 
     465                            // this may have happened due to the recording issue that selected 
     466                            // values of combo boxes are not logged correctly. In this case, 
     467                            // pretend to have the a random value selected 
     468                            selectedValue = "randomValueDueToRecordingBug_" + Math.random();  
     469                        } 
     470                    } 
     471                } 
     472                else if (valueChange.getEvent().getType() instanceof MouseClick) { 
     473                    if ((target.target instanceof IRadioButton) || 
     474                        (target.target instanceof ICheckBox)) 
     475                    { 
     476                        selectedValue = target.toString(); 
     477                    } 
     478                    else { 
     479                        throw new IllegalStateException("the implementation needs to be extended " + 
     480                                                        "to fully support clicks as value changes"); 
    443481                    } 
    444482                } 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/MisleadingClickCueRule.java

    r1918 r2042  
    2424import de.ugoe.cs.autoquest.eventcore.gui.MouseClick; 
    2525import de.ugoe.cs.autoquest.eventcore.gui.MouseDoubleClick; 
     26import de.ugoe.cs.autoquest.eventcore.guimodel.IButton; 
    2627import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; 
    2728import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIView; 
     
    6566                                   UsabilityEvaluationResult results) 
    6667    { 
    67         for (Map.Entry<IGUIView, Map<IGUIElement, Integer>> uselessClickCounter : 
     68        for (Map.Entry<IGUIElement, Map<IGUIView, Integer>> uselessClickCounter : 
    6869                statistics.getUselessClickCounters().entrySet()) 
    6970        { 
    70             for (Map.Entry<IGUIElement, Integer> counter : uselessClickCounter.getValue().entrySet()) 
    71             { 
    72                 int uselessClicks = counter.getValue(); 
    73                 int noOfViewDisplays = statistics.getViewOpenedCount(uselessClickCounter.getKey()); 
    74  
    75                 int ratio = Math.min(1000, 1000 * uselessClicks / noOfViewDisplays); 
    76  
    77                 UsabilitySmellIntensity intensity = 
    78                     UsabilitySmellIntensity.getIntensity(ratio, uselessClicks, -1); 
    79  
    80                 if (intensity != null) { 
    81                     Map<String, Object> parameters = new HashMap<String, Object>(); 
    82                     parameters.put("noOfViewDisplays", noOfViewDisplays); 
    83                     parameters.put("uselessClicks", uselessClicks); 
    84                     parameters.put("element", counter.getKey()); 
    85                     parameters.put("view", uselessClickCounter.getKey()); 
    86  
    87                     results.addSmell 
    88                         (intensity, UsabilitySmellDescription.MISLEADING_CLICK_CUE, parameters); 
    89                 } 
     71            int uselessClicks = 0; 
     72            int noOfViewDisplays = 0; 
     73             
     74            for (Map.Entry<IGUIView, Integer> counter : uselessClickCounter.getValue().entrySet()) { 
     75                uselessClicks += counter.getValue(); 
     76                noOfViewDisplays += statistics.getViewOpenedCount(counter.getKey()); 
     77            } 
     78 
     79            int ratio = Math.min(1000, 1000 * uselessClicks / noOfViewDisplays); 
     80 
     81            UsabilitySmellIntensity intensity = 
     82                UsabilitySmellIntensity.getIntensity(ratio, uselessClicks, -1); 
     83 
     84            if (intensity != null) { 
     85                Map<String, Object> parameters = new HashMap<String, Object>(); 
     86                parameters.put("noOfViewDisplays", noOfViewDisplays); 
     87                parameters.put("uselessClicks", uselessClicks); 
     88                parameters.put("element", uselessClickCounter.getKey()); 
     89 
     90                results.addSmell 
     91                    (intensity, UsabilitySmellDescription.MISLEADING_CLICK_CUE, parameters); 
    9092            } 
    9193        } 
     
    155157            (target instanceof IText)) 
    156158        { 
    157             return true; 
     159            // check if the parent is a button 
     160            IGUIElement parent = target; 
     161            while ((parent != null) && !(parent instanceof IButton)) { 
     162                parent = parent.getParent(); 
     163            } 
     164             
     165            return !(parent instanceof IButton); 
    158166        } 
    159167        else { 
     
    171179         
    172180        /** */ 
    173         private Map<IGUIView, Map<IGUIElement, Integer>> uselessClickCounters = new HashMap<>(); 
     181        private Map<IGUIElement, Map<IGUIView, Integer>> uselessClickCounters = new HashMap<>(); 
    174182 
    175183        /** 
     
    199207         */ 
    200208        private void addUselessClick(IEventTaskInstance eventTaskInstance) { 
    201             Map<IGUIElement, Integer> counterMap = uselessClickCounters.get 
    202                 (((IGUIElement) eventTaskInstance.getEvent().getTarget()).getView()); 
     209            IGUIElement target = (IGUIElement) eventTaskInstance.getEvent().getTarget(); 
     210             
     211            Map<IGUIView, Integer> counterMap = uselessClickCounters.get(target); 
    203212             
    204213            if (counterMap == null) { 
    205214                counterMap = new HashMap<>(); 
    206                 uselessClickCounters.put 
    207                     (((IGUIElement) eventTaskInstance.getEvent().getTarget()).getView(), counterMap); 
    208             } 
    209              
    210             Integer counter = counterMap.get(eventTaskInstance.getEvent().getTarget()); 
     215                uselessClickCounters.put(target, counterMap); 
     216            } 
     217             
     218            Integer counter = counterMap.get(target.getView()); 
    211219             
    212220            if (counter == null) { 
    213                 counterMap.put((IGUIElement) eventTaskInstance.getEvent().getTarget(), 1); 
     221                counterMap.put(target.getView(), 1); 
    214222            } 
    215223            else { 
    216                 counterMap.put((IGUIElement) eventTaskInstance.getEvent().getTarget(), counter + 1); 
    217             } 
    218         } 
    219  
    220         /** 
    221          * 
    222          */ 
    223         private Map<IGUIView, Map<IGUIElement, Integer>> getUselessClickCounters() { 
     224                counterMap.put(target.getView(), counter + 1); 
     225            } 
     226        } 
     227 
     228        /** 
     229         * 
     230         */ 
     231        private Map<IGUIElement, Map<IGUIView, Integer>> getUselessClickCounters() { 
    224232            return uselessClickCounters; 
    225233        } 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/MissingFeedbackRule.java

    r1918 r2042  
    195195         
    196196        if (clicksOnIdenticalButton != null) { 
     197            if (clicksOnIdenticalButton.size() > 1) { 
     198                //throw new IllegalStateException("not described in dissertation"); 
     199            } 
     200             
    197201            long cummulativeImpatience = 0; 
    198202             
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/TextInputStatisticsRule.java

    r1918 r2042  
    107107            int noOfUsagesOfTextField1 = statistics.getUsageCount(entry.textField1); 
    108108            int noOfUsagesOfTextField2 = statistics.getUsageCount(entry.textField2); 
    109             int noOfUsagesOfTextField1WithSameTextInTextField2 = entry.enteredTexts.size(); 
    110              
    111             int ratioTextField1 =  
    112                 1000 * noOfUsagesOfTextField1WithSameTextInTextField2 / noOfUsagesOfTextField1; 
    113              
    114             int ratioTextField2 = 
    115                 1000 * noOfUsagesOfTextField1WithSameTextInTextField2 / noOfUsagesOfTextField2; 
    116  
    117             createTextFieldEntryRepetitionSmell(ratioTextField1, entry.textField1, 
    118                                                  entry.textField2, results); 
    119              
    120             createTextFieldEntryRepetitionSmell(ratioTextField2, entry.textField2, 
    121                                                  entry.textField1, results); 
    122              
    123         } 
    124     } 
    125  
    126     /** 
    127      * 
    128      */ 
    129     private void createTextFieldEntryRepetitionSmell(int                       ratioOfEqualEntries, 
    130                                                       ITextField                textField1, 
    131                                                       ITextField                textField2, 
    132                                                       UsabilityEvaluationResult results) 
    133     { 
     109            int numberOfEqualEntries = entry.enteredTexts.size(); 
     110             
     111            createTextFieldEntryRepetitionSmell(noOfUsagesOfTextField1, numberOfEqualEntries, 
     112                                                entry.textField1, entry.textField2, results); 
     113             
     114            createTextFieldEntryRepetitionSmell(noOfUsagesOfTextField2, numberOfEqualEntries, 
     115                                                entry.textField2, entry.textField1, results); 
     116             
     117        } 
     118    } 
     119 
     120    /** 
     121     * 
     122     */ 
     123    private void createTextFieldEntryRepetitionSmell(int                       allEntries, 
     124                                                     int                       numberOfEqualEntries, 
     125                                                     ITextField                textField1, 
     126                                                     ITextField                textField2, 
     127                                                     UsabilityEvaluationResult results) 
     128    { 
     129        int ratio = 1000 * numberOfEqualEntries / allEntries; 
     130         
    134131        UsabilitySmellIntensity severity = 
    135             UsabilitySmellIntensity.getIntensity(ratioOfEqualEntries); 
     132            UsabilitySmellIntensity.getIntensity(ratio, allEntries, -1); 
    136133         
    137134        if (severity != null) { 
    138135            Map<String, Object> parameters = new HashMap<String, Object>(); 
    139             parameters.put("textRepetitionRatio", (ratioOfEqualEntries / 10)); 
     136            parameters.put("numberOfEqualEntries", numberOfEqualEntries); 
     137            parameters.put("numberOfAllEntries", allEntries); 
     138            parameters.put("textRepetitionRatio", (ratio / 10)); 
    140139            parameters.put("textField1", textField1); 
    141140            parameters.put("textField2", textField2); 
     
    169168            int ratio = 1000 * noLetterOrDigitCount / allCharactersCount; 
    170169 
    171             UsabilitySmellIntensity severity = UsabilitySmellIntensity.getIntensity(ratio); 
     170            UsabilitySmellIntensity severity = UsabilitySmellIntensity.getIntensity 
     171                (ratio, statistics.getAllInputsInto(textField).size(), -1); 
    172172 
    173173            if (severity != null) { 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UnusedGUIElementsRule.java

    r1918 r2042  
    1515package de.ugoe.cs.autoquest.usability; 
    1616 
     17import java.util.ArrayList; 
    1718import java.util.HashMap; 
    1819import java.util.HashSet; 
     
    2829import de.ugoe.cs.autoquest.eventcore.guimodel.IComboBox; 
    2930import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; 
     31import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIView; 
    3032import de.ugoe.cs.autoquest.eventcore.guimodel.IListBox; 
    3133import de.ugoe.cs.autoquest.eventcore.guimodel.IMenuButton; 
    3234import de.ugoe.cs.autoquest.eventcore.guimodel.ITextArea; 
    3335import de.ugoe.cs.autoquest.eventcore.guimodel.ITextField; 
     36import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 
    3437import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 
    3538import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 
     
    3740import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 
    3841import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 
     42import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; 
    3943 
    4044/** 
     
    5458    public UsabilityEvaluationResult evaluate(ITaskModel taskModel) { 
    5559        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); 
     60         
     61        Map<IGUIView, List<Set<IGUIElement>>> viewDisplays = 
     62            getViewDisplays(taskModel.getUserSessions()); 
     63         
     64        Map<IGUIView, Set<IGUIElement>> allGUIElements = getAllGUIElements(taskModel); 
     65         
     66        for (Map.Entry<IGUIView, List<Set<IGUIElement>>> viewDisplay : viewDisplays.entrySet()) { 
     67            handleUnusedGUIElements 
     68                (allGUIElements, viewDisplay.getKey(), viewDisplay.getValue(), results); 
     69        } 
    6270 
    6371        return results; 
     
    6573 
    6674    /** 
    67      * <p> 
    68      * TODO: comment 
    69      * </p> 
     75     * @param results  
    7076     * 
    71      * @param unusedGUIElements 
    72      * @param results 
    73      */ 
    74     private void handleUnusedGUIElements(List<IGUIElement>         unusedGUIElements, 
    75                                          Set<IGUIElement>          allGUIElements, 
    76                                          UsabilityEvaluationResult results) 
     77     */ 
     78    private void handleUnusedGUIElements(Map<IGUIView, Set<IGUIElement>> usedGUIElements, 
     79                                         IGUIView                        view, 
     80                                         List<Set<IGUIElement>>          viewUsages, 
     81                                         UsabilityEvaluationResult       results) 
    7782    { 
    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> 
     83        Set<IGUIElement> allElementsInView = usedGUIElements.get(view); 
     84         
     85        if (allElementsInView == null) { 
     86            return; 
     87        } 
     88         
     89        Map<Integer, List<IGUIElement>> usageCounters = new HashMap<>(); 
     90         
     91        for (IGUIElement relevantElement : allElementsInView) { 
     92            int usageCounter = 0; 
     93             
     94            for (Set<IGUIElement> viewUsage : viewUsages) { 
     95                if (viewUsage.contains(relevantElement)) { 
     96                    usageCounter++; 
     97                } 
     98            } 
     99             
     100            List<IGUIElement> elementsWithSameUsage = usageCounters.get(usageCounter); 
     101             
     102            if (elementsWithSameUsage == null) { 
     103                elementsWithSameUsage = new LinkedList<>(); 
     104                usageCounters.put(usageCounter, elementsWithSameUsage); 
     105            } 
     106             
     107            elementsWithSameUsage.add(relevantElement); 
     108        } 
     109         
     110        int cumulativeGuiElementUsage = 0; 
     111        for (Set<IGUIElement> viewUsage : viewUsages) { 
     112            cumulativeGuiElementUsage += viewUsage.size(); 
     113        } 
     114         
     115        List<IGUIElement> unusedElements = usageCounters.get(0); 
     116         
     117        if (unusedElements != null) { 
     118            int ratio = 1000 * unusedElements.size() / allElementsInView.size(); 
     119 
     120            UsabilitySmellIntensity severity = UsabilitySmellIntensity.getIntensity 
     121                (ratio, cumulativeGuiElementUsage, -1); 
     122 
     123            if (severity != null) { 
     124                Map<String, Object> parameters = new HashMap<String, Object>(); 
     125 
     126                parameters.put("ratio", ratio / 10); 
     127                parameters.put("allDisplays", viewUsages.size()); 
     128                parameters.put("view", view); 
     129                parameters.put("unusedGuiElements", unusedElements); 
     130                parameters.put("allGuiElements", allElementsInView.size()); 
     131 
     132                results.addSmell 
     133                    (severity, UsabilitySmellDescription.UNUSED_GUI_ELEMENTS, parameters); 
     134            } 
     135        } 
     136    } 
     137 
     138    /** 
    99139     * 
    100      * @param taskModel 
    101      * @return 
    102      */ 
    103     private GUIModel getGUIModel(ITaskModel taskModel) { 
     140     */ 
     141    private Map<IGUIView, Set<IGUIElement>> getAllGUIElements(ITaskModel taskModel) { 
     142        Map<IGUIView, Set<IGUIElement>> result = new HashMap<>(); 
     143         
    104144        for (ITask task : taskModel.getTasks()) { 
    105145            if (task instanceof IEventTask) { 
     
    107147                    Event event = ((IEventTaskInstance) instance).getEvent(); 
    108148                     
    109                     if (event.getTarget() instanceof IGUIElement) { 
    110                         return ((IGUIElement) event.getTarget()).getGUIModel(); 
     149                    if ((event.getTarget() instanceof IGUIElement) && 
     150                        (isRelevant((IGUIElement) event.getTarget()))) 
     151                    { 
     152                        IGUIView view = ((IGUIElement) event.getTarget()).getView(); 
     153                         
     154                        Set<IGUIElement> elements = result.get(view); 
     155                         
     156                        if (elements == null) { 
     157                            elements = new HashSet<>(); 
     158                            result.put(view, elements); 
     159                        } 
     160                         
     161                        elements.add((IGUIElement) event.getTarget()); 
    111162                    } 
    112163                } 
     
    114165        } 
    115166         
    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()); 
     167        // the problem is, that using the GUI model does not allow to find all in a specific view 
     168        // as the GUI model may return a merged element instead. But anyway, we can add those, which 
     169        // are in the GUI model and have the same view. 
     170         
     171        GUIModel model = result.values().iterator().next().iterator().next().getGUIModel(); 
     172         
     173        GUIModel.Traverser traverser = model.getTraverser(); 
     174 
     175        IGUIElement currentGUIElement = null; 
     176        do { 
     177            if (traverser.hasFirstChild()) { 
     178                currentGUIElement = traverser.firstChild(); 
     179            } 
     180            else if (traverser.hasNextSibling()) { 
     181                currentGUIElement = traverser.nextSibling(); 
     182            } 
     183            else { 
     184                while (currentGUIElement != null) { 
     185                    currentGUIElement = traverser.parent(); 
     186                    if (traverser.hasNextSibling()) { 
     187                        currentGUIElement = traverser.nextSibling(); 
     188                        break; 
    136189                    } 
    137190                } 
    138191            } 
    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; 
     192 
     193            if (isRelevant(currentGUIElement)) { 
     194                IGUIView view = currentGUIElement.getView(); 
     195                 
     196                Set<IGUIElement> elements = result.get(view); 
     197                 
     198                if (elements == null) { 
     199                    elements = new HashSet<>(); 
     200                    result.put(view, elements); 
     201                } 
     202                 
     203                elements.add(currentGUIElement); 
     204            } 
     205        } 
     206        while (currentGUIElement != null); 
     207         
     208        return result; 
     209    } 
     210 
     211    /** 
     212     *  
     213     */ 
     214    private Map<IGUIView, List<Set<IGUIElement>>> getViewDisplays(List<IUserSession> sessions) { 
     215        final IGUIView[] currentView = new IGUIView[1]; 
     216        final List<IEventTaskInstance> actionInstances = new ArrayList<>(); 
     217        final Map<IGUIView, List<Set<IGUIElement>>> result = new HashMap<>(); 
     218         
     219        for (IUserSession session : sessions) { 
     220            currentView[0] = null; 
     221            actionInstances.clear(); 
     222             
     223            for (final ITaskInstance currentRoot : session) { 
     224                currentRoot.accept(new DefaultTaskInstanceTraversingVisitor() { 
     225                    @Override 
     226                    public void visit(IEventTaskInstance eventTaskInstance) { 
     227                        if (eventTaskInstance.getEvent().getTarget() instanceof IGUIElement) { 
     228                            IGUIView view = 
     229                                ((IGUIElement) eventTaskInstance.getEvent().getTarget()).getView(); 
     230                             
     231                            if ((currentView[0] == null) && (view != null)) { 
     232                                currentView[0] = view; 
     233                                actionInstances.clear(); 
     234                            } 
     235                            else if ((currentView[0] != null) && (!currentView[0].equals(view))) { 
     236                                addRelevantTargets(currentView[0], actionInstances, result); 
     237                                 
     238                                currentView[0] = view; 
     239                                actionInstances.clear(); 
     240                            } 
     241                        } 
     242                         
     243                        if (eventTaskInstance.getEvent().getTarget() instanceof IGUIElement) { 
     244                            actionInstances.add(eventTaskInstance); 
    171245                        } 
    172246                    } 
    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> 
     247                }); 
     248            } 
     249             
     250            // add the used GUI elements of the last shown view in the session 
     251            if (currentView[0] != null) { 
     252                addRelevantTargets(currentView[0], actionInstances, result); 
     253            } 
     254        } 
     255         
     256        return result; 
     257    } 
     258 
     259    /** 
    189260     * 
    190      * @param taskModel 
    191      */ 
    192     private List<IGUIElement> getUnusedGUIElements(Set<IGUIElement> usedGUIElements, 
    193                                                    Set<IGUIElement> allGUIElements) 
     261     */ 
     262    private void addRelevantTargets(IGUIView                              view, 
     263                                    List<IEventTaskInstance>              actionInstances, 
     264                                    Map<IGUIView, List<Set<IGUIElement>>> result) 
    194265    { 
    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> 
     266        List<Set<IGUIElement>> usedGUIElements = result.get(view); 
     267         
     268        if (usedGUIElements == null) { 
     269            usedGUIElements = new LinkedList<>(); 
     270            result.put(view, usedGUIElements); 
     271        } 
     272         
     273        Set<IGUIElement> elementsInViewDisplay = new HashSet<>(); 
     274         
     275        for (IEventTaskInstance actionInstance : actionInstances) { 
     276            IGUIElement element = (IGUIElement) actionInstance.getEvent().getTarget(); 
     277             
     278            while (element != null) { 
     279                if (isRelevant(element)) { 
     280                    elementsInViewDisplay.add(element); 
     281                } 
     282                 
     283                element = element.getParent(); 
     284            } 
     285        } 
     286         
     287        usedGUIElements.add(elementsInViewDisplay); 
     288    } 
     289 
     290    /** 
    211291     * 
    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 
    247292     */ 
    248293    private boolean isRelevant(IGUIElement currentGUIElement) { 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationManager.java

    r1918 r2042  
    1616 
    1717import java.util.ArrayList; 
     18import java.util.HashMap; 
     19import java.util.LinkedList; 
    1820import java.util.List; 
     21import java.util.ListIterator; 
     22import java.util.Map; 
    1923import java.util.logging.Level; 
    2024 
     
    4852     */ 
    4953    private void init() { 
    50         rules.add(new TaskTreeTestRule()); 
    51 //        rules.add(new TextInputStatisticsRule()); 
    52 //        rules.add(new MissingFeedbackRule()); 
    53 //        rules.add(new EventCoverageRatioRule()); 
    54 //        rules.add(new TargetDistanceRule()); 
    55 //        rules.add(new RequiredInefficientActionsRule()); 
    56 //        rules.add(new DataEntryMethodChangeRule()); 
     54//        rules.add(new TaskTreeTestRule()); 
     55         
     56        rules.add(new EventCoverageRatioRule()); 
     57        rules.add(new RequiredInefficientActionsRule()); 
     58        rules.add(new TargetDistanceRule()); 
     59        rules.add(new MissingFeedbackRule()); 
     60        rules.add(new DataEntryMethodChangeRule()); 
     61        rules.add(new CommonTaskRateRule()); 
     62        rules.add(new TextInputStatisticsRule()); 
     63        rules.add(new CheckBoxMultipleSelectionRule()); 
     64        rules.add(new MisleadingClickCueRule()); 
     65        rules.add(new DefaultCursorPositioningRule()); 
    5766        rules.add(new DefaultValueRule()); 
    58 //        rules.add(new CheckBoxMultipleSelectionRule()); 
    59 //        rules.add(new CommonTaskRateRule()); 
    60 //        rules.add(new MisleadingClickCueRule()); 
    61 //        rules.add(new DefaultCursorPositioningRule()); 
    62 //        rules.add(new UnusedGUIElementsRule()); 
     67        rules.add(new UnusedGUIElementsRule()); 
     68         
    6369//        rules.add(new TaskCooccurrenceRule()); 
    6470    } 
     
    6773     * 
    6874     */ 
    69     public UsabilityEvaluationResult evaluateUsability(ITaskModel taskModel) { 
     75    public UsabilityEvaluationResult evaluateUsability(ITaskModel taskModel, int maxCount) { 
    7076        Console.traceln(Level.INFO, "evaluating usability of task model " + taskModel); 
    7177 
     
    7379 
    7480        for (UsabilityEvaluationRule rule : rules) { 
    75             Console.traceln(Level.INFO, "applying rule " + rule.getClass().getSimpleName()); 
     81            Console.traceln(Level.INFO, "\napplying rule " + rule.getClass().getSimpleName()); 
    7682            UsabilityEvaluationResult result = rule.evaluate(taskModel); 
    77             interimResults.add(result); 
    78             Console.traceln(Level.INFO, "the rule found " + result.getAllSmells().size() + 
    79                             " usability smells."); 
    80              
    81             List<ITask> referredTasks = new ArrayList<ITask>(); 
    82  
     83 
     84            Map<String, List<UsabilitySmell>> smellGroups = new HashMap<>(); 
     85             
    8386            for (UsabilitySmell smell : result.getAllSmells()) { 
    84                 if (smell.getSmellingTask() != null) { 
    85                     referredTasks.add(smell.getSmellingTask()); 
    86                 } 
    87             } 
    88                  
    89             int counter = 0; 
    90             for (int i = 0; i < referredTasks.size(); i++) { 
    91                 for (int j = 0; j < referredTasks.size(); j++) { 
    92                     if (isChildOf(referredTasks.get(i), referredTasks.get(j))) { 
    93                         counter++; 
    94                         break; 
     87                List<UsabilitySmell> smellGroup = smellGroups.get(smell.getBriefDescription()); 
     88                 
     89                if (smellGroup == null) { 
     90                    smellGroup = new LinkedList<>(); 
     91                    smellGroups.put(smell.getBriefDescription(), smellGroup); 
     92                } 
     93                 
     94                smellGroup.add(smell); 
     95            } 
     96             
     97            for (Map.Entry<String, List<UsabilitySmell>> smellGroup : smellGroups.entrySet()) { 
     98                Console.traceln(Level.INFO, "the rule found " + smellGroup.getValue().size() + 
     99                                " usability smells of type \"" + smellGroup.getKey() + "\""); 
     100                 
     101                result = new UsabilityEvaluationResult(taskModel, smellGroup.getValue()); 
     102                 
     103                checkDuplicates(result); 
     104                 
     105                if (maxCount < result.getAllSmells().size()) { 
     106                    Console.traceln(Level.INFO, "filtering for " + maxCount + 
     107                                    " smells of same type with highest event coverage."); 
     108                 
     109                    LinkedList<UsabilitySmell> sortedSmells = new LinkedList<>(); 
     110                     
     111                    for (UsabilitySmell smell : result.getAllSmells()) { 
     112                        ListIterator<UsabilitySmell> iterator = sortedSmells.listIterator(); 
     113 
     114                        boolean added = false; 
     115                         
     116                        while (iterator.hasNext()) { 
     117                            if (iterator.next().getIntensity().getEventCoverage() < 
     118                                    smell.getIntensity().getEventCoverage()) 
     119                            { 
     120                                iterator.previous(); 
     121                                iterator.add(smell); 
     122                                added = true; 
     123                                break; 
     124                            } 
     125                        } 
     126                     
     127                        if (!added) { 
     128                            sortedSmells.add(smell); 
     129                        } 
     130                     
     131                        while (sortedSmells.size() > maxCount) { 
     132                            sortedSmells.removeLast(); 
     133                        } 
    95134                    } 
    96                 } 
    97             } 
    98                  
    99             if (counter > 0) { 
    100                 Console.traceln(Level.INFO, counter + " of the findings are duplicates in " + 
    101                                 "that they refer to tasks whose parent tasks are also " + 
    102                                 "referred by the findings"); 
     135                 
     136                    result = new UsabilityEvaluationResult(taskModel, sortedSmells); 
     137                    checkDuplicates(result); 
     138                } 
     139             
     140                interimResults.add(result); 
    103141            } 
    104142        } 
     
    112150 
    113151    /** 
    114      * <p> 
    115      * TODO: comment 
    116      * </p> 
    117152     * 
    118      * @param iTask 
    119      * @param iTask2 
    120      * @return 
     153     */ 
     154    private void checkDuplicates(UsabilityEvaluationResult result) { 
     155        List<ITask> referredTasks = new ArrayList<ITask>(); 
     156 
     157        for (UsabilitySmell smell : result.getAllSmells()) { 
     158            if (smell.getSmellingTask() != null) { 
     159                referredTasks.add(smell.getSmellingTask()); 
     160            } 
     161        } 
     162             
     163        int counter = 0; 
     164        for (int i = 0; i < referredTasks.size(); i++) { 
     165            for (int j = 0; j < referredTasks.size(); j++) { 
     166                if (isChildOf(referredTasks.get(i), referredTasks.get(j))) { 
     167                    counter++; 
     168                    break; 
     169                } 
     170            } 
     171        } 
     172             
     173        if (counter > 0) { 
     174            Console.traceln(Level.INFO, counter + " of the findings are duplicates in " + 
     175                            "that they refer to tasks whose parent tasks are also " + 
     176                            "referred by the findings"); 
     177        } 
     178    } 
     179 
     180    /** 
     181     * 
    121182     */ 
    122183    private boolean isChildOf(final ITask potChild, ITask potParent) { 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationResult.java

    r1918 r2042  
    1616 
    1717import java.util.ArrayList; 
     18import java.util.Collection; 
    1819import java.util.List; 
    1920import java.util.Map; 
     
    4142    public UsabilityEvaluationResult(ITaskModel taskModel) { 
    4243        this.taskModel = taskModel; 
     44    } 
     45 
     46    /** 
     47     * 
     48     */ 
     49    public UsabilityEvaluationResult(ITaskModel                 taskModel, 
     50                                     Collection<UsabilitySmell> smells) 
     51    { 
     52        this.taskModel = taskModel; 
     53        for (UsabilitySmell smell : smells) { 
     54            this.smells.add(smell); 
     55        } 
    4356    } 
    4457 
Note: See TracChangeset for help on using the changeset viewer.