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/java/de/ugoe/cs/autoquest/usability
Files:
2 added
8 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; 
Note: See TracChangeset for help on using the changeset viewer.