Changeset 1423 for trunk/autoquest-core-tasktrees
- Timestamp:
- 02/28/14 15:09:12 (11 years ago)
- Location:
- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInfo.java
r1287 r1423 19 19 /** 20 20 * <p> 21 * yet more or less unused, this class will in the future provide extended information about a22 * specific task, such as statistics about task occurrences, etc.21 * Provides extended information about a specific task, such as statistics about task occurrences, 22 * etc. It contains measures for different metrics determined for a task. 23 23 * </p> 24 24 * … … 38 38 /** 39 39 * <p> 40 * returns the number of times a task occurred40 * returns all available measures 41 41 * </p> 42 42 * 43 43 * @return as described 44 44 */ 45 public int getCount(); 45 public IMeasure[] getMeasures(); 46 47 /** 48 * <p> 49 * returns the value of the measure identified through the given metric 50 * </p> 51 * 52 * @param metric the metric for which the value is to be returned 53 * 54 * @return as described 55 */ 56 public int getMeasureValue(TaskMetric metric); 57 58 /** 59 * <p> 60 * returns the value of the measure identified through the given metric if the task is 61 * observed in the given context, i.e. parent task. The result is Integer.MIN_VALUE if there 62 * is no value for this measure in a context. 63 * </p> 64 * 65 * @param metric the metric for which the value is to be returned 66 * @param context the context for which the measure value is to be returned 67 * 68 * @return as described 69 */ 70 public int getMeasureValue(TaskMetric metric, ITask context); 71 72 /** 73 * <p> 74 * represents a measure for a specific metric 75 * </p> 76 * 77 * @author Patrick Harms 78 */ 79 public interface IMeasure { 80 81 /** 82 * <p> 83 * returns the metric of the measure 84 * </p> 85 * 86 * @return as described 87 */ 88 public TaskMetric getMetric(); 89 90 /** 91 * <p> 92 * returns the value of the measure 93 * </p> 94 * 95 * @return as described 96 */ 97 public int getValue(); 98 99 /** 100 * <p> 101 * returns the value of the measure if the task was observed in a specific context, i.e. 102 * parent task 103 * </p> 104 * 105 * @return as described 106 */ 107 public int getValue(ITask context); 108 109 } 46 110 47 111 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskModel.java
r1214 r1423 22 22 * <p> 23 23 * This class represents a complete task model. A task model within AutoQUEST is usually generated 24 * based on user session . Therefore, the task model consists of the user sessions, the models24 * based on user sessions. Therefore, the task model consists of the user sessions, the models 25 25 * of the identified tasks, as well as further information about the tasks (e.g. their 26 26 * occurrence count) for statistical processing. … … 63 63 /** 64 64 * <p> 65 * returns a list of all metrics calculated by this model for the tasks and stored in the 66 * respective task infos 67 * </p> 68 * 69 * @return as described 70 */ 71 public TaskMetric[] getAllMetrics(); 72 73 /** 74 * <p> 65 75 * creates a deep clone of the model including all tasks and user sessions. 66 76 * </p> … … 69 79 */ 70 80 public ITaskModel clone(); 81 71 82 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskInfo.java
r1287 r1423 15 15 package de.ugoe.cs.autoquest.tasktrees.treeimpl; 16 16 17 import java.util.ArrayList; 18 import java.util.HashMap; 19 17 20 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 18 21 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo; 22 import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskMetric; 19 23 20 24 /** … … 41 45 */ 42 46 private ITask task; 43 44 /** 45 * <p> 46 * the number of occurrences of thistask47 * </p> 48 */ 49 private int count;47 48 /** 49 * <p> 50 * all available measures for the task 51 * </p> 52 */ 53 private ArrayList<Measure> measures = new ArrayList<Measure>(); 50 54 51 55 /** … … 69 73 70 74 /* (non-Javadoc) 71 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getCount() 72 */ 73 @Override 74 public int getCount() { 75 return count; 75 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getMeasures() 76 */ 77 @Override 78 public IMeasure[] getMeasures() { 79 measures.trimToSize(); 80 return measures.toArray(new IMeasure[measures.size()]); 81 } 82 83 /* (non-Javadoc) 84 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getMeasureValue(java.lang.String) 85 */ 86 @Override 87 public int getMeasureValue(TaskMetric metric) { 88 Measure measure = getMeasure(metric); 89 90 if (measure == null) { 91 throw new IllegalArgumentException("unknown metric " + metric); 92 } 93 94 return measure.getValue(); 95 } 96 97 /* (non-Javadoc) 98 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo#getMeasureValue(java.lang.String, de.ugoe.cs.autoquest.tasktrees.treeifc.ITask) 99 */ 100 @Override 101 public int getMeasureValue(TaskMetric metric, ITask context) { 102 Measure measure = getMeasure(metric); 103 104 if (measure == null) { 105 throw new IllegalArgumentException("unknown metric " + metric); 106 } 107 108 return measure.getValue(context); 76 109 } 77 110 … … 86 119 /** 87 120 * <p> 88 * used to increase the counter of occurrences of this task by one 89 * </p> 90 */ 91 void increaseCount() { 92 count++; 93 } 121 * must be called to indicate that a new new measures for the provided metric are about to 122 * be calculated and added. 123 * </p> 124 * 125 * @param metric the metric for which measures are about to be provided 126 */ 127 void addMeasure(TaskMetric metric) { 128 Measure measure = getMeasure(metric); 129 130 if (measure != null) { 131 throw new IllegalArgumentException("measure for metric " + metric + " already exists."); 132 } 133 134 measure = new Measure(metric); 135 measures.add(measure); 136 } 137 138 /** 139 * <p> 140 * sets a specific value for a measure of a specific metric in the provided context of the task 141 * </p> 142 * 143 * @param metric the metric to which the value belongs 144 * @param context the context of the task in which the measure was recorded 145 * @param value the value of the measure 146 */ 147 void setCount(TaskMetric metric, ITask context, int value) { 148 Measure measure = getMeasure(metric); 149 150 if (measure == null) { 151 throw new IllegalArgumentException("unknown metric. Please create a measure " + 152 "for the metric before using it."); 153 } 154 155 measure.set(context, value); 156 } 157 158 /** 159 * <p> 160 * increases a specific value for a measure of a specific metric in the provided context of the 161 * task 162 * </p> 163 * 164 * @param metric the metric to which the value belongs 165 * @param context the context of the task in which the measure was recorded 166 * @param increment the increment to be added to the value of the measure 167 */ 168 void increaseCount(TaskMetric metric, ITask context, int increment) { 169 Measure measure = getMeasure(metric); 170 171 if (measure == null) { 172 throw new IllegalArgumentException("unknown metric. Please create a measure " + 173 "for the metric before using it."); 174 } 175 176 measure.increase(context, increment); 177 } 178 179 /** 180 * <p> 181 * convenience method to internally determine the measure for a specific metric 182 * </p> 183 */ 184 private Measure getMeasure(TaskMetric metric) { 185 for (Measure candidate : measures) { 186 if (candidate.getMetric().equals(metric)) { 187 return candidate; 188 } 189 } 190 191 return null; 192 } 193 194 /** 195 * <p> 196 * implementation for the measure interface of the task info interface. Does nothing fancy 197 * except implementing the interface 198 * </p> 199 * 200 * @author Patrick Harms 201 */ 202 private static class Measure implements IMeasure { 203 204 /** 205 * <p> 206 * the metric to which the measure belongs 207 * </p> 208 */ 209 private TaskMetric metric; 210 211 /** 212 * <p> 213 * the observed values for the difference contexts of the task 214 * </p> 215 */ 216 private HashMap<ITask, Integer> values; 217 218 /** 219 * <p> 220 * the context free value of the measure independent of the task context 221 * </p> 222 */ 223 private int contextFreeValue = 0; 224 225 /** 226 * <p> 227 * initializes the measure with a specific metric 228 * </p> 229 */ 230 private Measure(TaskMetric metric) { 231 super(); 232 this.metric = metric; 233 } 234 235 /* (non-Javadoc) 236 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo.IMeasure#getMetric() 237 */ 238 @Override 239 public TaskMetric getMetric() { 240 return metric; 241 } 242 243 /* (non-Javadoc) 244 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo.IMeasure#getValue() 245 */ 246 @Override 247 public int getValue() { 248 return contextFreeValue; 249 } 250 251 /* (non-Javadoc) 252 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo.IMeasure#getValue(de.ugoe.cs.autoquest.tasktrees.treeifc.ITask) 253 */ 254 @Override 255 public int getValue(ITask context) { 256 if ((context != null) && (values != null)) { 257 Integer currentValue = values.get(context); 258 259 if (currentValue != null) { 260 return currentValue; 261 } 262 } 263 264 return Integer.MIN_VALUE; 265 } 266 267 /** 268 * <p> 269 * sets the value of the measure context free as well as specific to the provided context 270 * </p> 271 */ 272 private void set(ITask context, int value) { 273 contextFreeValue = value; 274 275 if (context != null) { 276 if (values == null) { 277 values = new HashMap<ITask, Integer>(); 278 } 279 280 values.put(context, value); 281 } 282 } 283 284 /** 285 * <p> 286 * increases the value of the measure context free as well as specific to the provided 287 * context according to the provided increment 288 * </p> 289 */ 290 private void increase(ITask context, int increment) { 291 contextFreeValue += increment; 292 293 if (context != null) { 294 if (values == null) { 295 values = new HashMap<ITask, Integer>(); 296 } 297 298 Integer currentValue = values.get(context); 299 300 if (currentValue == null) { 301 currentValue = 0; 302 } 303 304 values.put(context, currentValue + increment); 305 } 306 } 307 308 } 309 94 310 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskModel.java
r1287 r1423 21 21 import java.util.Map; 22 22 23 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 24 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 25 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; 26 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance; 27 import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; 28 import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional; 29 import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance; 30 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; 31 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance; 32 import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship; 23 33 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 24 34 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; … … 27 37 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo; 28 38 import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; 39 import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskMetric; 29 40 30 41 /** 31 42 * <p> 32 43 * this is the default implementation of the interface {@link ITaskModel}. It 33 * does not do anything fancy except implementing the interface. 44 * does not do anything fancy except implementing the interface. It also calculates on 45 * initialisations the measures for diverse metrics of the task belonging to the model 34 46 * </p> 35 47 * … … 44 56 */ 45 57 private static final long serialVersionUID = 1L; 58 59 /** 60 * <p> 61 * all metrics calculated by this type of task model 62 * </p> 63 */ 64 private static final TaskMetric[] taskMetrics = new TaskMetric[] 65 { TaskMetric.COUNT, 66 TaskMetric.DEPTH, 67 TaskMetric.EVENT_COVERAGE, 68 TaskMetric.EVENT_COVERAGE_RATIO }; 46 69 47 70 /** … … 54 77 /** 55 78 * <p> 56 * the tasks contained in the user session belonging to the model as well as statistical infos 57 * about them 58 * </p> 59 */ 60 private Map<ITask, TaskInfo> taskMap = new HashMap<ITask, TaskInfo>(); 61 79 * index for effectively accessing the model and calculating statistics about it 80 * </p> 81 */ 82 private transient TaskModelIndex index = null; 83 62 84 /** 63 85 * <p> … … 73 95 74 96 this.userSessions = userSessions; 75 76 for (IUserSession session : this.userSessions) {77 for (ITaskInstance taskInstance : session) {78 addTasksToMap(taskInstance);79 }80 }81 97 } 82 98 … … 87 103 @Override 88 104 public List<IUserSession> getUserSessions() { 105 ensureInitialized(); 89 106 return Collections.unmodifiableList(userSessions); 90 107 } … … 96 113 @Override 97 114 public Collection<ITask> getTasks() { 98 return Collections.unmodifiableCollection(taskMap.keySet()); 115 ensureInitialized(); 116 return Collections.unmodifiableCollection(index.taskMap.keySet()); 99 117 } 100 118 … … 105 123 @Override 106 124 public ITaskInfo getTaskInfo(ITask task) { 107 return taskMap.get(task); 108 } 125 ensureInitialized(); 126 return index.taskMap.get(task); 127 } 128 129 /* (non-Javadoc) 130 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getAllMetrics() 131 */ 132 @Override 133 public TaskMetric[] getAllMetrics() { 134 return taskMetrics; 135 } 136 109 137 110 138 /* (non-Javadoc) … … 116 144 } 117 145 118 119 /** 120 * <p> 121 * internal convenience method to recursively add the tasks of a task instance and its 122 * children to the task model 123 * </p> 124 * 125 * @param taskInstance the task instance of which the tasks shall be added 126 */ 127 private void addTasksToMap(ITaskInstance taskInstance) { 128 addTaskToMap(taskInstance.getTask()); 129 130 if (taskInstance instanceof ITaskInstanceList) { 131 for (ITaskInstance child : (ITaskInstanceList) taskInstance) { 132 addTasksToMap(child); 133 } 134 } 135 } 136 137 138 /** 139 * <p> 140 * internal convenience method to build the task model during initialization 141 * </p> 142 */ 143 private void addTaskToMap(ITask task) { 144 TaskInfo taskInfo = taskMap.get(task); 145 146 if (taskInfo == null) { 147 taskInfo = new TaskInfo(task); 148 taskMap.put(task, taskInfo); 149 } 150 151 taskInfo.increaseCount(); 152 153 /*if (task instanceof IStructuringTemporalRelationship) { 154 for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) { 155 addTaskToMap(child); 156 } 157 } 158 else if (task instanceof IMarkingTemporalRelationship) { 159 addTaskToMap(((IMarkingTemporalRelationship) task).getMarkedTask()); 146 /** 147 * <p> 148 * internal convenience method that initializes the internal index and calculates all measures 149 * for metrics available for the tasks 150 * </p> 151 */ 152 private synchronized void ensureInitialized() { 153 if (index == null) { 154 index = new TaskModelIndex(); 155 156 for (IUserSession session : this.userSessions) { 157 for (ITaskInstance taskInstance : session) { 158 index.handleTaskInstance(taskInstance, null); 159 } 160 } 161 162 // count all events covered 163 int allEventsCovered = 0; 164 Collection<ITask> tasks = getTasks(); 165 for (ITask task : tasks) { 166 if (task instanceof IEventTask) { 167 allEventsCovered += task.getInstances().size(); 168 } 169 } 170 171 // add some further measures 172 for (ITask task : tasks) { 173 TaskInfo info = index.taskMap.get(task); 174 info.addMeasure(TaskMetric.EVENT_COVERAGE_RATIO); 175 176 int coveredEvents = info.getMeasureValue(TaskMetric.EVENT_COVERAGE); 177 178 if (allEventsCovered > 0) { 179 info.setCount(TaskMetric.EVENT_COVERAGE_RATIO, null, 180 ((coveredEvents * 1000) / allEventsCovered)); 181 } 182 } 183 184 //index.dumpToCSV(System.out); 185 /*try { 186 OutputStream stream = new FileOutputStream(new File("tasks.csv")); 187 index.dumpToCSV(new PrintStream(stream)); 188 stream.close(); 189 } 190 catch (FileNotFoundException e) { 191 e.printStackTrace(); 192 }*/ 193 } 194 195 } 196 197 /** 198 * <p> 199 * the index of task infos used internally. The index is created once and while that filled 200 * with task infos for each observed task containing all measures for metrics belonging 201 * to the tasks. 202 * </p> 203 * 204 * @author Patrick Harms 205 */ 206 private static class TaskModelIndex { 207 208 /** 209 * <p> 210 * the tasks contained in the user session belonging to the model as well as statistical 211 * infos about them 212 * </p> 213 */ 214 private Map<ITask, TaskInfo> taskMap = new HashMap<ITask, TaskInfo>(); 215 216 /** 217 * <p> 218 * called on initialization to fill the index with infos about the given task instance 219 * as well as to calculate the appropriate metrics 220 * </p> 221 */ 222 private int[] handleTaskInstance(ITaskInstance taskInstance, ITask context) { 223 int eventTaskInstancesCovered = 0; 224 int depth = 0; 225 226 if (taskInstance instanceof ITaskInstanceList) { 227 for (ITaskInstance child : (ITaskInstanceList) taskInstance) { 228 int[] measures = handleTaskInstance(child, taskInstance.getTask()); 229 eventTaskInstancesCovered += measures[0]; 230 depth = Math.max(depth, measures[1]); 231 } 232 233 if ((((ITaskInstanceList) taskInstance).size() == 0) && 234 (taskInstance instanceof IIterationInstance)) 235 { 236 // ensure also empty task infos for unselected variants 237 ensureTaskInfo(((IIteration) taskInstance.getTask()).getMarkedTask(), context); 238 } 239 } 240 else if (taskInstance instanceof ISelectionInstance) { 241 ITaskInstance child = ((ISelectionInstance) taskInstance).getChild(); 242 int[] measures = handleTaskInstance(child, taskInstance.getTask()); 243 eventTaskInstancesCovered += measures[0]; 244 depth = Math.max(depth, measures[1]); 245 246 // ensure also empty task infos for unselected variants 247 for (ITask otherChildTask : ((ISelection) taskInstance.getTask()).getChildren()) { 248 ensureTaskInfo(otherChildTask, context); 249 } 250 } 251 else if (taskInstance instanceof IOptionalInstance) { 252 ITaskInstance child = ((IOptionalInstance) taskInstance).getChild(); 253 if (child != null) { 254 int[] measures = handleTaskInstance(child, taskInstance.getTask()); 255 eventTaskInstancesCovered += measures[0]; 256 depth = Math.max(depth, measures[1]); 257 } 258 else { 259 // ensure also empty task infos for unselected variants 260 ensureTaskInfo(((IOptional) taskInstance.getTask()).getMarkedTask(), context); 261 } 262 } 263 else if (taskInstance instanceof IEventTaskInstance) { 264 eventTaskInstancesCovered = 1; 265 } 266 267 depth++; 268 269 ensureTaskInfo(taskInstance.getTask(), context, eventTaskInstancesCovered, depth); 270 271 return new int[] { eventTaskInstancesCovered, depth }; 272 } 273 274 /** 275 * <p> 276 * internal convenience method to build the task model during initialization 277 * </p> 278 */ 279 private void ensureTaskInfo(ITask task, ITask context) { 280 ensureTaskInfo(task, context, 0, 0); 281 282 if (task instanceof IStructuringTemporalRelationship) { 283 for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) { 284 ensureTaskInfo(child, task); 285 } 286 } 287 else if (task instanceof IMarkingTemporalRelationship) { 288 ensureTaskInfo(((IMarkingTemporalRelationship) task).getMarkedTask(), task); 289 } 290 291 } 292 293 /** 294 * <p> 295 * internal convenience method to build the task model during initialization. Adds a new 296 * task info object to the map for the provided task and fills it with measures. If there 297 * are already some task infos for the task, the contained measures are updated according 298 * to the parameters. 299 * </p> 300 */ 301 private void ensureTaskInfo(ITask task, 302 ITask context, 303 int eventTaskInstancesCovered, 304 int depth) 305 { 306 TaskInfo taskInfo = taskMap.get(task); 307 308 if (taskInfo == null) { 309 taskInfo = new TaskInfo(task); 310 taskInfo.addMeasure(TaskMetric.COUNT); 311 taskInfo.addMeasure(TaskMetric.EVENT_COVERAGE); 312 taskInfo.addMeasure(TaskMetric.DEPTH); 313 taskMap.put(task, taskInfo); 314 315 taskInfo.setCount(TaskMetric.DEPTH, null, getDepth(task)); 316 } 317 318 taskInfo.increaseCount(TaskMetric.COUNT, context, 1); 319 taskInfo.increaseCount(TaskMetric.EVENT_COVERAGE, context, eventTaskInstancesCovered); 320 321 taskInfo.setCount(TaskMetric.DEPTH, context, depth); 322 } 323 324 /** 325 * <p> 326 * internal convenience method to calculate the maximum depth of a task 327 * </p> 328 */ 329 private int getDepth(ITask task) { 330 if (task instanceof IMarkingTemporalRelationship) { 331 return getDepth(((IMarkingTemporalRelationship) task).getMarkedTask()) + 1; 332 } 333 else if (task instanceof IStructuringTemporalRelationship) { 334 int maxDepth = 0; 335 336 for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) { 337 maxDepth = Math.max(maxDepth, getDepth(child)); 338 } 339 340 return maxDepth + 1; 341 } 342 else { 343 // event tasks 344 return 1; 345 } 346 } 347 348 /** 349 * 350 */ 351 /*private void dumpToCSV(PrintStream out) { 352 out.println("taskid;depth;count;eventcoverage;eventcoverageratio"); 353 354 for (Map.Entry<ITask, TaskInfo> entry : taskMap.entrySet()) { 355 out.print(entry.getKey().getId()); 356 out.print(';'); 357 out.print(entry.getValue().getMeasureValue(TaskMetric.DEPTH)); 358 out.print(';'); 359 out.print(entry.getValue().getMeasureValue(TaskMetric.COUNT)); 360 out.print(';'); 361 out.print(entry.getValue().getMeasureValue(TaskMetric.EVENT_COVERAGE)); 362 out.print(';'); 363 out.print(entry.getValue().getMeasureValue(TaskMetric.EVENT_COVERAGE_RATIO)); 364 out.println(); 365 } 160 366 }*/ 161 } 367 368 } 369 162 370 163 371 }
Note: See TracChangeset
for help on using the changeset viewer.