Changeset 2162


Ignore:
Timestamp:
09/07/17 16:15:00 (7 years ago)
Author:
pharms
Message:
  • changes for first VR oriented usability evaluation
Location:
trunk/autoquest-core-usability/src/main
Files:
2 added
9 edited

Legend:

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

    r1959 r2162  
    1515package de.ugoe.cs.autoquest.usability; 
    1616 
    17 import java.text.DecimalFormat; 
    1817import java.util.ArrayList; 
    1918import java.util.HashMap; 
     
    2120import java.util.List; 
    2221import java.util.Map; 
     22import java.util.Set; 
    2323 
    2424import org.apache.commons.math3.stat.descriptive.SummaryStatistics; 
     
    2626import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 
    2727import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 
     28import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 
     29import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance; 
    2830import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 
    2931import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 
    3032import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; 
     33import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskTreeUtils; 
    3134 
    3235/** 
     
    4649    public UsabilityEvaluationResult evaluate(ITaskModel taskModel) { 
    4750        SummaryStatistics statistics = new SummaryStatistics(); 
    48         int allObserved = calculateStatistics(taskModel.getUserSessions(), statistics); 
     51        SummaryStatistics mpStatistics = new SummaryStatistics(); 
     52        int allObserved = calculateStatistics 
     53            (taskModel.getUserSessions(), TaskTreeUtils.getMostProminentTasks(taskModel), 
     54             statistics, mpStatistics); 
    4955 
    5056        UsabilityEvaluationResult results = new UsabilityEvaluationResult(taskModel); 
    51         analyzeStatistics(statistics, allObserved, results); 
     57        analyzeStatistics(statistics, false, allObserved, results); 
     58        analyzeStatistics(mpStatistics, true, allObserved, results); 
    5259 
    5360        return results; 
     
    5865     */ 
    5966    private void analyzeStatistics(SummaryStatistics         statistics, 
     67                                   boolean                   mostProminentSequencesOnly, 
    6068                                   int                       allObserved, 
    6169                                   UsabilityEvaluationResult results) 
     
    7583            if (intensity != null) { 
    7684                Map<String, Object> parameters = new HashMap<String, Object>(); 
    77                 parameters.put("ratio", new DecimalFormat("#.##").format(mean * 10)); 
     85                parameters.put("ratio", ((float) Math.round(mean * 100)) / 10); 
     86                 
     87                if (mostProminentSequencesOnly) { 
     88                    parameters.put("tasksType", "representative tasks"); 
     89                } 
     90                else { 
     91                    parameters.put("tasksType", "tasks"); 
     92                } 
    7893 
    7994                results.addSmell(intensity, UsabilitySmellDescription.COMMON_TASK_RATE, parameters); 
     
    87102     */ 
    88103    private int calculateStatistics(List<IUserSession>      sessions, 
    89                                     final SummaryStatistics statistics) 
     104                                    final Set<ISequence>    mostProminentTasks, 
     105                                    final SummaryStatistics statistics, 
     106                                    final SummaryStatistics mpStatistics) 
    90107    { 
    91108        final LinkedList<ITaskInstance> rootNodes = new LinkedList<>(); 
     109        final LinkedList<ITaskInstance> mpRootNodes = new LinkedList<>(); 
    92110        final List<IEventTaskInstance> leafNodes = new ArrayList<>(); 
    93111         
     
    96114        for (IUserSession session : sessions) { 
    97115            rootNodes.clear(); 
     116            mpRootNodes.clear(); 
    98117             
    99118            for (final ITaskInstance currentRoot : session) { 
    100119                currentRoot.accept(new DefaultTaskInstanceTraversingVisitor() { 
     120                    private ITaskInstance currentMpRoot = null; 
     121  
     122                    @Override 
     123                    public void visit(ISequenceInstance sequenceInstance) { 
     124                        boolean currentInstancesIsMpRoot = false; 
     125                        if (mostProminentTasks.contains(sequenceInstance.getSequence())) { 
     126                            if (currentMpRoot == null) { 
     127                                currentMpRoot = sequenceInstance; 
     128                                currentInstancesIsMpRoot = true; 
     129                            } 
     130                            // else already detected most prominent root task 
     131                        } 
     132                        super.visit(sequenceInstance); 
     133                         
     134                        if (currentInstancesIsMpRoot) { 
     135                            // if the current instance is also the root instance considering only 
     136                            // most prominent sequences, then reset the stored instance to null 
     137                            // after traversing this task 
     138                            currentMpRoot = null; 
     139                        } 
     140                    } 
     141 
    101142                    @Override 
    102143                    public void visit(IEventTaskInstance eventTaskInstance) { 
    103144                        rootNodes.add(currentRoot); 
     145                        mpRootNodes.add(currentMpRoot != null ? currentMpRoot : currentRoot); 
    104146                        leafNodes.add(eventTaskInstance); 
    105147 
     
    109151                            while (rootNodes.size() >= 10) { 
    110152                                rootNodes.removeFirst(); 
     153                            } 
     154                        } 
     155                         
     156                        if (mpRootNodes.size() >= 10) { 
     157                            mpStatistics.addValue(getTaskCoverageMeasure(mpRootNodes)); 
     158                             
     159                            while (mpRootNodes.size() >= 10) { 
     160                                mpRootNodes.removeFirst(); 
    111161                            } 
    112162                        } 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/RequiredInefficientActionsRule.java

    r1949 r2162  
    1717import java.util.Collection; 
    1818import java.util.HashMap; 
     19import java.util.LinkedList; 
     20import java.util.List; 
    1921import java.util.Map; 
    2022 
    2123import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; 
    2224 
    23 import de.ugoe.cs.autoquest.eventcore.Event; 
    24 import de.ugoe.cs.autoquest.eventcore.gui.Scroll; 
    2525import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 
     26import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskTraversingVisitor; 
     27import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 
    2628import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 
    2729import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 
     
    9092        for (ITask task : tasks) { 
    9193            if (task instanceof ISequence)  { 
    92                 double[] ratios = getRatiosOfInefficientActionsInInstances((ISequence) task); 
    93                  
    94                 for (int i = 0; i < ratios.length; i++) { 
    95                     if (ratios[i] > 0) { 
    96                         // there is at least on inefficient action 
    97                         inefficientActionRatios.put((ISequence) task, ratios); 
    98                         break; 
     94                if (countEfficientActions((ISequence) task) > 1) { 
     95                    double[] ratios = getRatiosOfInefficientActionsInInstances((ISequence) task); 
     96                     
     97                    for (int i = 0; i < ratios.length; i++) { 
     98                        if (ratios[i] > 0) { 
     99                            // there is at least on inefficient action 
     100                            inefficientActionRatios.put((ISequence) task, ratios); 
     101                            break; 
     102                        } 
    99103                    } 
    100104                } 
     
    103107         
    104108        return inefficientActionRatios; 
     109    } 
     110 
     111    /** 
     112     *  
     113     */ 
     114    private int countEfficientActions(ISequence task) { 
     115        final List<IEventTask> efficientActions = new LinkedList<>(); 
     116         
     117        task.accept(new DefaultTaskTraversingVisitor() { 
     118            @Override 
     119            public void visit(IEventTask eventTask) { 
     120                if (!ActionClassifier.isInefficient(eventTask)) { 
     121                    efficientActions.add(eventTask); 
     122                } 
     123            } 
     124        }); 
     125         
     126        return efficientActions.size(); 
    105127    } 
    106128 
     
    131153            @Override 
    132154            public void visit(IEventTaskInstance eventTaskInstance) { 
    133                 if (isInefficientAction(eventTaskInstance.getEvent())) { 
     155                if (ActionClassifier.isInefficient(eventTaskInstance.getEvent())) { 
    134156                    count[0]++; 
    135157                } 
     
    143165    } 
    144166 
    145     /** 
    146      * 
    147      */ 
    148     private boolean isInefficientAction(Event event) { 
    149         return (event.getType() instanceof Scroll); 
    150     } 
    151  
    152167} 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/TargetDistanceRule.java

    r1918 r2162  
    1919import java.util.List; 
    2020import java.util.Map; 
     21import java.util.regex.Matcher; 
     22import java.util.regex.Pattern; 
    2123 
    22 import de.ugoe.cs.autoquest.eventcore.IEventTarget; 
    23 import de.ugoe.cs.autoquest.eventcore.gui.Scroll; 
     24import de.ugoe.cs.autoquest.eventcore.Event; 
    2425import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; 
    2526import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 
     
    3738 */ 
    3839public class TargetDistanceRule implements UsabilityEvaluationRule { 
     40     
     41    /** pattern for parsing target position parameter values */ 
     42    private Pattern targetPositionPattern = Pattern.compile 
     43            ("\\(\\s*(-?\\d*(\\.\\d*)?),\\s*(-?\\d*(\\.\\d*)?),\\s*(-?\\d*(\\.\\d*)?)\\s*\\)"); 
    3944 
    4045    /* 
     
    7883     */ 
    7984    private int[] getTargetDistance(ITaskInstance instance) { 
    80         List<IEventTarget> eventTargets = new LinkedList<IEventTarget>(); 
    81         getEventTargets(instance, eventTargets); 
    82         int noOfGUIElements = eventTargets.size(); 
     85        List<Event> events = new LinkedList<Event>(); 
     86        getEvents(instance, events); 
     87        int noOfEvents = events.size(); 
    8388        int distance = 0; 
    8489         
    85         while (eventTargets.size() > 1) { 
    86             distance += getDistance(eventTargets.get(0), eventTargets.get(1)); 
    87             eventTargets.remove(0); 
     90        while (events.size() > 1) { 
     91            distance += getDistance(events.get(0), events.get(1)); 
     92            events.remove(0); 
    8893        } 
    8994         
    90         return new int[] { noOfGUIElements, distance }; 
     95        return new int[] { noOfEvents, distance }; 
    9196    } 
    9297 
     
    9499     * 
    95100     */ 
    96     private int getDistance(IEventTarget eventTarget1, IEventTarget eventTarget2) { 
    97         if ((eventTarget1 instanceof IGUIElement) && (eventTarget2 instanceof IGUIElement)) { 
    98             return (int) 
    99                 (1000 * (((IGUIElement) eventTarget1).getDistanceTo((IGUIElement) eventTarget2))); 
     101    private int getDistance(Event event1, Event event2) { 
     102        String location1 = event1.getParameter("targetPosition"); 
     103        String location2 = event2.getParameter("targetPosition"); 
     104         
     105        if ((location1 != null) && (location2 != null)) { 
     106            Matcher matcher1 = targetPositionPattern.matcher(location1); 
     107            Matcher matcher2 = targetPositionPattern.matcher(location2); 
     108            if (matcher1.matches() && matcher2.matches()) { 
     109                try { 
     110                    double x = 
     111                        Double.parseDouble(matcher2.group(1)) - Float.parseFloat(matcher1.group(1)); 
     112                     
     113                    double y = 
     114                        Double.parseDouble(matcher2.group(3)) - Float.parseFloat(matcher1.group(3)); 
     115                     
     116                    double z = 
     117                        Double.parseDouble(matcher2.group(5)) - Float.parseFloat(matcher1.group(5)); 
     118                     
     119                    return (int) (100 * Math.sqrt(x*x + y*y + z*z)); 
     120                } 
     121                catch (NumberFormatException e) { 
     122                    // ignore and just continue with other variants. 
     123                } 
     124            } 
    100125        } 
    101         else if (eventTarget1.equals(eventTarget2)) { 
     126         
     127        if ((event1.getTarget() instanceof IGUIElement) && 
     128            (event2.getTarget() instanceof IGUIElement)) 
     129        { 
     130            IGUIElement target1 = (IGUIElement) event1.getTarget(); 
     131            IGUIElement target2 = (IGUIElement) event2.getTarget(); 
     132            return (int) (1000 * target1.getDistanceTo(target2)); 
     133        } 
     134         
     135        if (event1.getTarget().equals(event2.getTarget())) { 
    102136            return 0; 
    103137        } 
    104         else { 
    105             return 1000; 
    106         } 
     138         
     139        return 1000; 
    107140    } 
    108141 
     
    110143     * 
    111144     */ 
    112     private void getEventTargets(ITaskInstance instance, final List<IEventTarget> eventTargets) { 
     145    private void getEvents(ITaskInstance instance, final List<Event> events) { 
    113146        instance.accept(new DefaultTaskInstanceTraversingVisitor() { 
    114147            @Override 
    115148            public void visit(IEventTaskInstance eventTaskInstance) { 
    116                 if (!(eventTaskInstance.getEvent().getType() instanceof Scroll)) { 
    117                     eventTargets.add(eventTaskInstance.getEvent().getTarget()); 
     149                if (!(ActionClassifier.isInefficient(eventTaskInstance.getEvent()))) { 
     150                    events.add(eventTaskInstance.getEvent()); 
    118151                } 
    119152            } 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationManager.java

    r2042 r2162  
    1717import java.util.ArrayList; 
    1818import java.util.HashMap; 
     19import java.util.HashSet; 
    1920import java.util.LinkedList; 
    2021import java.util.List; 
    2122import java.util.ListIterator; 
    2223import java.util.Map; 
     24import java.util.Set; 
    2325import java.util.logging.Level; 
    2426 
     27import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 
     28import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 
    2529import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; 
     30import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 
    2631import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship; 
    2732import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
     33import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 
    2834import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 
    2935import de.ugoe.cs.util.console.Console; 
     
    5864        rules.add(new TargetDistanceRule()); 
    5965        rules.add(new MissingFeedbackRule()); 
     66        rules.add(new TaskRetryRule()); 
    6067        rules.add(new DataEntryMethodChangeRule()); 
    6168        rules.add(new CommonTaskRateRule()); 
     
    7380     * 
    7481     */ 
    75     public UsabilityEvaluationResult evaluateUsability(ITaskModel taskModel, int maxCount) { 
     82    public UsabilityEvaluationResult evaluateUsability(ITaskModel taskModel, 
     83                                                       int        maxCount, 
     84                                                       boolean    onlyMostRepresentative) 
     85    { 
    7686        Console.traceln(Level.INFO, "evaluating usability of task model " + taskModel); 
    7787 
    7888        List<UsabilityEvaluationResult> interimResults = new ArrayList<UsabilityEvaluationResult>(); 
     89        Set<ITask> mostRepresentativeTasks = null; 
    7990 
    8091        for (UsabilityEvaluationRule rule : rules) { 
    8192            Console.traceln(Level.INFO, "\napplying rule " + rule.getClass().getSimpleName()); 
    82             UsabilityEvaluationResult result = rule.evaluate(taskModel); 
     93            UsabilityEvaluationResult ruleResult = rule.evaluate(taskModel); 
    8394 
    8495            Map<String, List<UsabilitySmell>> smellGroups = new HashMap<>(); 
    8596             
    86             for (UsabilitySmell smell : result.getAllSmells()) { 
     97            for (UsabilitySmell smell : ruleResult.getAllSmells()) { 
    8798                List<UsabilitySmell> smellGroup = smellGroups.get(smell.getBriefDescription()); 
    8899                 
     
    99110                                " usability smells of type \"" + smellGroup.getKey() + "\""); 
    100111                 
    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                  
     112                ruleResult = new UsabilityEvaluationResult(taskModel, smellGroup.getValue()); 
     113                 
     114                checkDuplicates(ruleResult); 
     115                 
     116                if ((onlyMostRepresentative) || (maxCount < ruleResult.getAllSmells().size())) { 
    109117                    LinkedList<UsabilitySmell> sortedSmells = new LinkedList<>(); 
    110118                     
    111                     for (UsabilitySmell smell : result.getAllSmells()) { 
     119                    if (onlyMostRepresentative) { 
     120                        Console.traceln(Level.INFO, "filtering for smells that refer to only most " + 
     121                                        "representative tasks."); 
     122                    } 
     123                     
     124                    for (UsabilitySmell smell : ruleResult.getAllSmells()) { 
     125                        if (onlyMostRepresentative && (smell.getSmellingTask() != null)) { 
     126                            if (mostRepresentativeTasks == null) { 
     127                                mostRepresentativeTasks = getMostRepresentativeSequences(taskModel); 
     128                            } 
     129                             
     130                            if (!mostRepresentativeTasks.contains(smell.getSmellingTask())) { 
     131                                continue; 
     132                            } 
     133                        } 
     134                         
    112135                        ListIterator<UsabilitySmell> iterator = sortedSmells.listIterator(); 
    113136 
     
    116139                        while (iterator.hasNext()) { 
    117140                            if (iterator.next().getIntensity().getEventCoverage() < 
    118                                     smell.getIntensity().getEventCoverage()) 
     141                                smell.getIntensity().getEventCoverage()) 
    119142                            { 
    120143                                iterator.previous(); 
     
    129152                        } 
    130153                     
     154                    } 
     155                     
     156                    if (maxCount < ruleResult.getAllSmells().size()) { 
     157                        Console.traceln(Level.INFO, "filtering for " + maxCount + 
     158                                " smells of same type with highest event coverage."); 
     159                         
    131160                        while (sortedSmells.size() > maxCount) { 
    132161                            sortedSmells.removeLast(); 
     
    134163                    } 
    135164                 
    136                     result = new UsabilityEvaluationResult(taskModel, sortedSmells); 
    137                     checkDuplicates(result); 
    138                 } 
    139              
    140                 interimResults.add(result); 
     165                    Console.traceln(Level.INFO, sortedSmells.size() + " remaining."); 
     166                    ruleResult = new UsabilityEvaluationResult(taskModel, sortedSmells); 
     167                    checkDuplicates(ruleResult); 
     168                } 
     169             
     170                interimResults.add(ruleResult); 
    141171            } 
    142172        } 
     
    147177 
    148178        return result; 
     179    } 
     180 
     181    /** 
     182     * <p> 
     183     * TODO: comment 
     184     * </p> 
     185     * 
     186     * @param taskModel 
     187     * @return 
     188     */ 
     189    private Set<ITask> getMostRepresentativeSequences(ITaskModel taskModel) { 
     190        Map<Integer, List<ISequence>> coverageCounts = new HashMap<>(); 
     191        Map<ISequence, Set<IEventTaskInstance>> coverages = new HashMap<>(); 
     192        int maxCoverage = 0; 
     193 
     194        for (ITask task : taskModel.getTasks()) { 
     195            if (task instanceof ISequence) { 
     196                final Set<IEventTaskInstance> coveredEvents = new HashSet<>(); 
     197 
     198                for (ITaskInstance instance : task.getInstances()) { 
     199                    instance.accept(new DefaultTaskInstanceTraversingVisitor() { 
     200                        @Override 
     201                        public void visit(IEventTaskInstance eventTaskInstance) { 
     202                            coveredEvents.add(eventTaskInstance); 
     203                        } 
     204                    }); 
     205                } 
     206 
     207                coverages.put((ISequence) task, coveredEvents); 
     208 
     209                List<ISequence> tasksWithSameCoverage = coverageCounts.get(coveredEvents.size()); 
     210 
     211                if (tasksWithSameCoverage == null) { 
     212                    tasksWithSameCoverage = new LinkedList<>(); 
     213                    coverageCounts.put(coveredEvents.size(), tasksWithSameCoverage); 
     214                } 
     215 
     216                tasksWithSameCoverage.add((ISequence) task); 
     217 
     218                maxCoverage = Math.max(maxCoverage, coveredEvents.size()); 
     219            } 
     220        } 
     221 
     222        Set<ITask> mostRepresentativeSequences = new HashSet<>(); 
     223 
     224        for (int i = maxCoverage; i > 0; i--) { 
     225            List<ISequence> sequencesWithSameCoverage = coverageCounts.get(i); 
     226 
     227            if (sequencesWithSameCoverage == null) { 
     228                continue; 
     229            } 
     230 
     231            for (ISequence sequence : sequencesWithSameCoverage) { 
     232                mostRepresentativeSequences.add(sequence); 
     233            } 
     234             
     235            if ((100 * mostRepresentativeSequences.size() / coverages.size()) > 20) { 
     236                break; 
     237            } 
     238        } 
     239 
     240        return mostRepresentativeSequences; 
    149241    } 
    150242 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationResult.java

    r2042 r2162  
    1515package de.ugoe.cs.autoquest.usability; 
    1616 
     17import java.io.Serializable; 
    1718import java.util.ArrayList; 
    1819import java.util.Collection; 
     
    2930 * @author 2012, last modified by $Author: pharms$ 
    3031 */ 
    31 public class UsabilityEvaluationResult { 
     32public class UsabilityEvaluationResult implements Serializable { 
    3233     
     34    /**  */ 
     35    private static final long serialVersionUID = 1L; 
     36 
    3337    /** */ 
    3438    private ITaskModel taskModel; 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilitySmell.java

    r1918 r2162  
    1515package de.ugoe.cs.autoquest.usability; 
    1616 
     17import java.io.Serializable; 
     18import java.util.Collections; 
     19import java.util.LinkedList; 
    1720import java.util.List; 
    1821import java.util.Map; 
     
    2629 * @author 2012, last modified by $Author: pharms$ 
    2730 */ 
    28 public class UsabilitySmell { 
     31public class UsabilitySmell implements Serializable { 
     32 
     33    /**  */ 
     34    private static final long serialVersionUID = 1L; 
    2935 
    3036    /** */ 
     
    3945    /** */ 
    4046    private Map<String, Object> descriptionParameters; 
     47     
     48    /** */ 
     49    private List<String> tags; 
     50     
     51    /** */ 
     52    private ManualLabel manualLabel = ManualLabel.UNCHECKED; 
    4153 
    4254    /** 
     
    124136 
    125137    /* 
     138     *  
    126139     */ 
    127140    public String getBriefDescription() { 
    128141        return description.getBriefDescription(); 
     142    } 
     143 
     144    /** 
     145     * 
     146     */ 
     147    public void addTag(String tag) { 
     148        if (this.tags == null) { 
     149            this.tags = new LinkedList<>(); 
     150        } 
     151         
     152        if (!this.tags.contains(tag)) { 
     153            this.tags.add(tag); 
     154        } 
     155    } 
     156 
     157    /** 
     158     * 
     159     */ 
     160    public void removeTag(String tag) { 
     161        if (this.tags != null) { 
     162            this.tags.remove(tag); 
     163        } 
     164    } 
     165 
     166    /** 
     167     * @param manualLabel the manualLabel to set 
     168     */ 
     169    public void setManualLabel(ManualLabel manualLabel) { 
     170        this.manualLabel = manualLabel; 
     171    } 
     172 
     173    /** 
     174     * @return the tags 
     175     */ 
     176    public List<String> getTags() { 
     177        if (tags != null) { 
     178            return Collections.unmodifiableList(tags); 
     179        } 
     180        else { 
     181            return Collections.emptyList(); 
     182        } 
     183    } 
     184 
     185    /** 
     186     * @return the manualLabel 
     187     */ 
     188    public ManualLabel getManualLabel() { 
     189        return manualLabel; 
    129190    } 
    130191 
     
    170231    } 
    171232 
     233    /** */ 
     234    public static enum ManualLabel { 
     235        UNCHECKED, TRUE_POSITIVE, FALSE_POSITIVE; 
     236    } 
    172237} 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilitySmellDescription.java

    r1918 r2162  
    1717import java.io.IOException; 
    1818import java.io.InputStream; 
     19import java.io.Serializable; 
    1920import java.util.ArrayList; 
    2021import java.util.Collection; 
     
    3233 * @author 2012, last modified by $Author: pharms$ 
    3334 */ 
    34 public enum UsabilitySmellDescription { 
     35public enum UsabilitySmellDescription implements Serializable { 
    3536     
    3637    INEFFICIENT_ACTIONS, 
     
    4344    HIGH_TARGET_DISTANCE, 
    4445    MISSING_FEEDBACK, 
     46    TASK_RETRIED, 
    4547    UNUSED_GUI_ELEMENTS, 
    4648    DATA_ENTRY_METHOD_CHANGE, 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilitySmellIntensity.java

    r1918 r2162  
    1515package de.ugoe.cs.autoquest.usability; 
    1616 
     17import java.io.Serializable; 
     18 
    1719import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
    1820import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo; 
     
    2628 * @author 2012, last modified by $Author: pharms$ 
    2729 */ 
    28 public class UsabilitySmellIntensity { 
     30public class UsabilitySmellIntensity implements Serializable { 
    2931     
     32    /**  */ 
     33    private static final long serialVersionUID = 1L; 
     34 
    3035    /** */ 
    3136    private int ratio; 
  • trunk/autoquest-core-usability/src/main/resources/smellDescriptions_en.xml

    r2042 r2162  
    180180  </smellDescription> 
    181181   
     182  <smellDescription smellId="TASK_RETRIED" briefText="task retried"> 
     183    <textFragment> 
     184      The task  
     185    </textFragment> 
     186    <parameterFragment parameterName="task" /> 
     187    <textFragment> 
     188      is often retried, i.e., repeated subsequently. On average, every 
     189    </textFragment> 
     190    <parameterFragment parameterName="repeatedInstanceRatio" /> 
     191    <textFragment> 
     192      th instance is followed by one or more repetitions of the task and the average repetition 
     193      ratio when a task is repeated is 
     194    </textFragment> 
     195    <parameterFragment parameterName="averageRepetitionRatio" /> 
     196    <textFragment> 
     197      additional repetitions. This can be task retries and may indicate, that the task is hard to 
     198      be performed. Hence, it should be eased up. This can be done by checking, why the task is 
     199      retried and then adapting the implementation so that the task can be finalized with its 
     200      initial execution. 
     201    </textFragment> 
     202  </smellDescription> 
     203   
    182204  <smellDescription smellId="UNUSED_GUI_ELEMENTS" briefText="unused GUI elements"> 
    183205    <textFragment> 
     
    266288    <parameterFragment parameterName="ratio" /> 
    267289    <textFragment> 
    268       different determined tasks. In the worst case, each action is its own task. In the best case, 
     290      different determined 
     291    </textFragment> 
     292    <parameterFragment parameterName="tasksType" /> 
     293    <textFragment> 
     294      . In the worst case, each action is its own task. In the best case, 
    269295      all actions are described by the same tasks. This indicates, that the users act relatively 
    270296      different as otherwise, all their actions would be described by only a few tasks. Hence, 
Note: See TracChangeset for help on using the changeset viewer.