Changeset 987 for trunk/autoquest-core-tasktrees/src
- Timestamp:
- 11/15/12 11:31:11 (12 years ago)
- Location:
- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation
- Files:
-
- 3 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiElementSequenceDetectionRule.java
r972 r987 12 12 13 13 /** 14 * This rule generates sequences depending on a GUI model. All actions occurring on the same GUI15 * element are put together in a sequence. All sequences and actions within a common panel are also16 * put together to a sequence. Through this, an event sequence gets a logical structure and shows,17 * which interactions that happen together also happen in the same GUI context.14 * This rule structures the task tree based on GUI elements of the GUI model. The rule can 15 * be provided with a filter for considered GUI elements. It generates sub sequences for any 16 * GUI element in the hierarchy matching the filter so that each sequence represents all 17 * interactions in a certain GUI element. 18 18 * 19 19 * @version $Revision: $ $Date: 18.03.2012$ … … 21 21 */ 22 22 public class DefaultGuiElementSequenceDetectionRule implements TemporalRelationshipRule { 23 24 /** 25 * <p> 26 * the GUI element filter to be applied or null if none is specified. 27 * </p> 28 */ 29 private List<Class<? extends IGUIElement>> guiElementFilter; 30 31 /** 32 * <p> 33 * instantiates the rule without a GUI element filter 34 * </p> 35 */ 36 DefaultGuiElementSequenceDetectionRule() { 37 this.guiElementFilter = null; 38 } 39 40 /** 41 * <p> 42 * instantiates the rule with a GUI element filter. Only those types given in the filter will 43 * be considered during the rule application. For all other types, no subsequences will be 44 * created. 45 * </p> 46 * 47 * @param guiElementFilter the GUI element filter to be applied 48 */ 49 DefaultGuiElementSequenceDetectionRule(List<Class<? extends IGUIElement>> guiElementFilter) { 50 this.guiElementFilter = guiElementFilter; 51 } 23 52 24 53 /* … … 39 68 40 69 RuleApplicationResult result = new RuleApplicationResult(); 41 42 IGUIElement lastGuiElement = null; 70 List<List<IGUIElement>> hierarchies = new ArrayList<List<IGUIElement>>(); 71 72 // collect information about the GUI hierarchy 73 int maxHierarchyDepth = 0; 74 IGUIElement guiElement; 75 List<IGUIElement> guiElements = new ArrayList<IGUIElement>(); 76 List<IGUIElement> hierarchy; 77 78 for (ITaskTreeNode child : parent.getChildren()) { 79 guiElement = getGuiElement(child); 80 guiElements.add(guiElement); 81 hierarchy = getGuiElementHierarchy(guiElement); 82 hierarchies.add(hierarchy); 83 if (hierarchy != null) { 84 maxHierarchyDepth = Math.max(maxHierarchyDepth, hierarchy.size()); 85 } 86 } 87 88 IGUIElement commonDenominator = getCommonDenominator(guiElements); 89 hierarchy = getGuiElementHierarchy(commonDenominator); 90 int initialHierarchyLevel = hierarchy != null ? hierarchy.size() : 0; 91 92 // now generate sub sequences for the different GUI elements. Start at the hierarchy 93 // level of the children of the common denominator to ensure, that different children are 94 // found. If this level is already the maximum hierarchy depth, we do not need to condense 95 // anything. 96 97 RuleApplicationStatus status; 98 if (initialHierarchyLevel < maxHierarchyDepth) { 99 status = generateSubSequences(parent, hierarchies, initialHierarchyLevel, finalize, 100 builder, nodeFactory, result); 101 } 102 else { 103 status = RuleApplicationStatus.RULE_NOT_APPLIED; 104 } 105 106 result.setRuleApplicationStatus(status); 107 108 return result; 109 } 110 111 /** 112 * <p> 113 * generates subsequences for all groups of children of the provided parent, that operate 114 * in different GUI elements at the provided hierarchy level. It will not generate a sub 115 * sequence for the last elements, if the rule application shall not finalize. 116 * </p> 117 * 118 * @param parent the parent node of which the children shall be grouped 119 * @param hierarchies the GUI hierarchies for the children of the parent 120 * @param hierarchyLevel the current hierarchy level to be considered 121 * @param maxHierarchyDepth the maximum hierarchy depth that may apply in this application 122 * @param finalize true, if the application shall be finalized, false else 123 * @param builder the builder to use for generating the tree structure 124 * @param nodeFactory the node factory to use for generating the tree structure 125 * @param result the result of the rule application to add newly created parent 126 * nodes to 127 * 128 * @return RULE_APPLICATION_FINISHED, if at least one subsequence was generated, 129 * RULE_APPLICATION_FEASIBLE, if the application shall not be finalized but some 130 * children could be condensed if further data was available, and RULE_NOT_APPLIED, 131 * if no subsequence was created and none is can be created, because no further 132 * data is expected 133 */ 134 private RuleApplicationStatus generateSubSequences(ITaskTreeNode parent, 135 List<List<IGUIElement>> hierarchies, 136 int hierarchyLevel, 137 boolean finalize, 138 ITaskTreeBuilder builder, 139 ITaskTreeNodeFactory nodeFactory, 140 RuleApplicationResult result) 141 { 142 IGUIElement currentParent = null; 143 List<IGUIElement> hierarchy; 144 int startingIndex = -1; 145 146 RuleApplicationStatus status = RuleApplicationStatus.RULE_NOT_APPLIED; 147 boolean subsequenceHasStarted = false; 148 boolean exceedingGuiHierarchyDepth = false; 149 boolean nextGuiElementDiffers = false; 150 151 currentParent = null; 152 startingIndex = -1; 153 43 154 int index = 0; 44 155 while (index < parent.getChildren().size()) { 45 ITaskTreeNode child = parent.getChildren().get(index); 46 IGUIElement currentGuiElement = getGUIElement(child); 47 if ((index > 0) && (!lastGuiElement.equals(currentGuiElement))) { 48 ReducableCommonDenominator commonDenominator = 49 getNextReducableCommonDenominator(parent, index - 1); 50 51 if (commonDenominator != null) { 52 // condense only if not all children would be condensed or if we can be sure, 53 // that there will be no further child that should be included in the condensed 54 // sequence 55 if ((commonDenominator.noOfTasks < parent.getChildren().size()) && 56 (!isOnGuiElementPath(commonDenominator.commonGuiElement, currentGuiElement))) 57 { 58 condenseTasksToSequence(parent, index, commonDenominator.noOfTasks, 59 builder, nodeFactory, result); 60 61 result.setRuleApplicationStatus 62 (RuleApplicationStatus.RULE_APPLICATION_FINISHED); 63 return result; 64 } 65 else { 66 // the common denominator is on the parent path of the next GUI element. 67 // Therefore, the current sequences is not finished yet. So break up. 68 result.setRuleApplicationStatus 69 (RuleApplicationStatus.RULE_APPLICATION_FEASIBLE); 70 } 71 } 72 } 73 74 lastGuiElement = currentGuiElement; 156 hierarchy = hierarchies.get(index); 157 158 exceedingGuiHierarchyDepth = hierarchyLevel >= hierarchy.size(); 159 nextGuiElementDiffers = 160 subsequenceHasStarted && 161 (exceedingGuiHierarchyDepth || !currentParent.equals(hierarchy.get(hierarchyLevel))); 162 163 164 if (!subsequenceHasStarted && !exceedingGuiHierarchyDepth) { 165 currentParent = hierarchy.get(hierarchyLevel); 166 startingIndex = index; 167 subsequenceHasStarted = true; 168 } 169 else if (nextGuiElementDiffers) { 170 status = condenseSequence(parent, hierarchies, hierarchyLevel, startingIndex, 171 index - 1, builder, nodeFactory, result); 172 173 if (status != null) { 174 index = startingIndex + 1; 175 } 176 177 if (!exceedingGuiHierarchyDepth) { 178 currentParent = hierarchy.get(hierarchyLevel); 179 startingIndex = index; 180 subsequenceHasStarted = true; 181 } 182 else { 183 currentParent = null; 184 startingIndex = -1; 185 subsequenceHasStarted = false; 186 } 187 } 188 75 189 index++; 76 190 } 77 191 78 ReducableCommonDenominator commonDenominator = 79 getNextReducableCommonDenominator(parent, parent.getChildren().size() - 1); 80 81 if ((commonDenominator != null) && 82 (commonDenominator.noOfTasks < parent.getChildren().size())) 83 { 84 if (finalize) { 85 condenseTasksToSequence 86 (parent, index, commonDenominator.noOfTasks, builder, nodeFactory, result); 192 if (finalize) { 193 if (subsequenceHasStarted) { 194 status = condenseSequence 195 (parent, hierarchies, hierarchyLevel, startingIndex, 196 parent.getChildren().size() - 1, builder, nodeFactory, result); 197 } 198 else if (status != RuleApplicationStatus.RULE_APPLICATION_FINISHED) { 199 status = RuleApplicationStatus.RULE_NOT_APPLIED; 200 } 201 } 202 else { 203 if ((currentParent != null) && 204 (status != RuleApplicationStatus.RULE_APPLICATION_FINISHED)) 205 { 206 status = RuleApplicationStatus.RULE_APPLICATION_FEASIBLE; 207 } 208 } 209 210 return status; 211 } 212 213 /** 214 * <p> 215 * condenses a specified group of children on the provided parent to a subsequences and 216 * calls {@link #generateSubSequences(ITaskTreeNode, List, int, boolean, ITaskTreeBuilder, ITaskTreeNodeFactory, RuleApplicationResult)} 217 * for the newly created subsequence. The method does not condense subgroups consisting of 218 * only one child which is already a sequence. 219 * </p> 220 * 221 * @param parent the parent task of which children shall be condensed 222 * @param hierarchies the GUI element hierarchies of the children of the parent 223 * @param hierarchyLevel the currently considered GUI element hierarchy level 224 * @param startIndex the index of the first child belonging to the subgroup 225 * @param endIndex the index of the last child belonging to the subgroup 226 * @param builder the builder to use for generating the tree structure 227 * @param nodeFactory the node factory to use for generating the tree structure 228 * @param result the result of the rule application to add newly created parent nodes to 229 * 230 * @return RULE_APPLICATION_FINISHED, if at the subsequence was generated and RULE_NOT_APPLIED, 231 * if no subsequence was created, because only one child belonged to the group which 232 * was already a sequence 233 */ 234 private RuleApplicationStatus condenseSequence(ITaskTreeNode parent, 235 List<List<IGUIElement>> hierarchies, 236 int hierarchyLevel, 237 int startIndex, 238 int endIndex, 239 ITaskTreeBuilder builder, 240 ITaskTreeNodeFactory nodeFactory, 241 RuleApplicationResult result) 242 { 243 boolean onlyASingleChildToReduce = (endIndex - startIndex) == 0; 244 boolean singleChildIsSequence = onlyASingleChildToReduce && 245 parent.getChildren().get(startIndex) instanceof ISequence; 246 247 if (!onlyASingleChildToReduce || !singleChildIsSequence) { 248 ISequence sequence = nodeFactory.createNewSequence(); 249 250 List<List<IGUIElement>> subHierarchies = new ArrayList<List<IGUIElement>>(); 251 List<IGUIElement> newHierarchy = 252 hierarchies.get(startIndex).subList(0, hierarchyLevel + 1); 253 builder.setDescription(sequence, "interactions on " + 254 newHierarchy.get(newHierarchy.size() - 1).getStringIdentifier()); 255 256 for (int i = startIndex; i <= endIndex; i++) { 257 builder.addChild(sequence, parent.getChildren().get(startIndex)); 258 builder.removeChild((ISequence) parent, startIndex); 87 259 88 result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED); 89 90 return result; 91 } 92 else { 93 result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE); 94 } 95 } 96 97 return result; 98 } 99 100 /** 101 * <p> 102 * TODO: comment 103 * </p> 104 * 105 * @param guiElement 106 * @param detectedTasks 107 * @param parent 108 * @param index 109 * @param builder 110 * @param nodeFactory 111 * @return 112 */ 113 private void condenseTasksToSequence(ITaskTreeNode parent, 114 int parentIndex, 115 int noOfTasks, 116 ITaskTreeBuilder builder, 117 ITaskTreeNodeFactory nodeFactory, 118 RuleApplicationResult result) 119 { 120 ISequence newSequence = nodeFactory.createNewSequence(); 121 for (int i = 0; i < noOfTasks; i++) { 122 builder.addChild(newSequence, parent.getChildren().get(parentIndex - noOfTasks)); 123 // remove exactly the same number of children from the parent. 124 builder.removeChild((ISequence) parent, parentIndex - noOfTasks); 125 } 126 127 builder.addChild((ISequence) parent, parentIndex - noOfTasks, newSequence); 128 result.addNewlyCreatedParentNode(newSequence); 129 } 130 131 /** 132 * <p> 133 * TODO: comment 134 * </p> 135 * 136 * @param detectedTasks 137 * @return 138 */ 139 private ReducableCommonDenominator getNextReducableCommonDenominator(ITaskTreeNode parent, 140 int childIndex) 141 { 142 ReducableCommonDenominator commonDenominator = null; 143 144 // a common denominator can only exist for at least two task tree nodes 145 if (childIndex > 0) { 146 // start with the last one 147 int pos = childIndex; 148 149 commonDenominator = new ReducableCommonDenominator(); 150 151 // check for further predecessors, if they match the same common denominator 152 IGUIElement currentCommonDenominator = null; 153 do { 154 if (--pos < 0) { 155 currentCommonDenominator = null; 156 } 157 else { 158 currentCommonDenominator = getCommonDenominator 159 (getGUIElement(parent.getChildren().get(pos)), 160 getGUIElement(parent.getChildren().get(pos + 1))); 161 } 162 163 if (commonDenominator.commonGuiElement == null) { 164 commonDenominator.commonGuiElement = currentCommonDenominator; 165 } 166 } 167 while ((commonDenominator.commonGuiElement != null) && 168 (commonDenominator.commonGuiElement.equals(currentCommonDenominator))); 169 170 if (commonDenominator.commonGuiElement != null) { 171 // pos points to the last element, that has not the same common denominator. 172 // This one must be subtracted from the task number as well 173 commonDenominator.noOfTasks = childIndex - pos; 174 } 175 else { 176 commonDenominator = null; 177 } 178 } 179 180 return commonDenominator; 181 } 182 183 /** 184 * <p> 185 * TODO: comment 186 * </p> 187 * 188 * @param child 189 * @return 190 */ 191 private IGUIElement getGUIElement(ITaskTreeNode node) { 192 List<IGUIElement> terminalGUIElements = new ArrayList<IGUIElement>(); 193 getTerminalGUIElements(node, terminalGUIElements); 194 return getCommonDenominator(terminalGUIElements); 195 } 196 197 /** 198 * <p> 199 * TODO: comment 200 * </p> 201 * 202 * @param detectedTaskGroups 203 * @return 204 */ 205 /*private IGUIElement getCommonDenominator(Stack<Task> detectedTasks, int start) { 206 List<IGUIElement> allGUIElements = new ArrayList<IGUIElement>(); 207 208 for (int i = start; i < detectedTasks.size(); i++) { 209 allGUIElements.add(detectedTasks.get(i).commonGuiElement); 210 } 211 212 return getCommonDenominator(allGUIElements); 213 }*/ 214 215 /** 216 * <p> 217 * TODO: comment 218 * </p> 219 * 220 * @param child 221 * @return 222 */ 223 private IGUIElement getCommonDenominator(IGUIElement guiElement1, IGUIElement guiElement2) { 224 List<IGUIElement> allGUIElements = new ArrayList<IGUIElement>(); 225 allGUIElements.add(guiElement1); 226 allGUIElements.add(guiElement2); 227 return getCommonDenominator(allGUIElements); 228 } 229 230 /** 231 * <p> 232 * TODO: comment 233 * </p> 234 * 235 * @param child 236 * @return 260 subHierarchies.add(hierarchies.remove(startIndex)); 261 } 262 263 builder.addChild((ISequence) parent, startIndex, sequence); 264 265 hierarchies.add(startIndex, newHierarchy); 266 267 generateSubSequences 268 (sequence, subHierarchies, hierarchyLevel + 1, true, builder, nodeFactory, result); 269 270 result.addNewlyCreatedParentNode(sequence); 271 272 return RuleApplicationStatus.RULE_APPLICATION_FINISHED; 273 } 274 else { 275 return null; 276 } 277 278 } 279 280 /** 281 * <p> 282 * return a common denominator for the provided list of GUI elements, i.e. a GUI element, that 283 * is part of the parent GUI hiearchy of all GUI elements in the list. If there is no common 284 * denominator, the method returns null. 285 * </p> 237 286 */ 238 287 private IGUIElement getCommonDenominator(List<IGUIElement> guiElements) { … … 245 294 IGUIElement guiElement = guiElements.get(0); 246 295 while (guiElement != null) { 247 commonDenominatorPath.add(0, guiElement); 296 if (guiElementMatchesConsideredTypes(guiElement)) { 297 commonDenominatorPath.add(0, guiElement); 298 } 248 299 guiElement = guiElement.getParent(); 300 } 301 302 if (commonDenominatorPath.size() == 0) { 303 return null; 249 304 } 250 305 … … 257 312 guiElement = guiElements.get(i); 258 313 while (guiElement != null) { 259 currentPath.add(0, guiElement); 314 if (guiElementMatchesConsideredTypes(guiElement)) { 315 currentPath.add(0, guiElement); 316 } 260 317 guiElement = guiElement.getParent(); 261 318 } … … 285 342 /** 286 343 * <p> 287 * TODO: comment 288 * </p> 289 * 290 * @param child 291 * @return 292 */ 293 private void getTerminalGUIElements(ITaskTreeNode node, List<IGUIElement> terminalGUIElements) { 344 * returns the GUI element on which all interactions of the provided task takes place. If 345 * the task is a simple event task its target is returned. If the task is a parent task 346 * of several children, the common denominator of the GUI elements of all its children is 347 * returned. The method returns null, if there is no common GUI element for all events 348 * represented by the provided task. 349 * </p> 350 */ 351 private IGUIElement getGuiElement(ITaskTreeNode node) { 352 if (node != null) { 353 List<IGUIElement> terminalGuiElements = new ArrayList<IGUIElement>(); 354 getTerminalGuiElements(node, terminalGuiElements); 355 return getCommonDenominator(terminalGuiElements); 356 } 357 else { 358 return null; 359 } 360 } 361 362 /** 363 * <p> 364 * recursive method calling itself to determine all terminal GUI elements of the provided 365 * task. The terminal GUI elements are stored in the provided list. 366 * </p> 367 */ 368 private void getTerminalGuiElements(ITaskTreeNode node, List<IGUIElement> terminalGuiElements) { 294 369 if (node instanceof IEventTask) { 295 370 if (((IEventTask) node).getEventTarget() instanceof IGUIElement) { 296 terminalGUIElements.add((IGUIElement) ((IEventTask) node).getEventTarget()); 371 IGUIElement terminalGuiElement = (IGUIElement) ((IEventTask) node).getEventTarget(); 372 terminalGuiElement = 373 searchHierarchyForGuiElementWithConsideredType(terminalGuiElement); 374 375 if (terminalGuiElement != null) { 376 terminalGuiElements.add(terminalGuiElement); 377 } 297 378 } 298 379 } 299 380 else { 300 381 for (ITaskTreeNode child : node.getChildren()) { 301 getTerminalGUIElements(child, terminalGUIElements); 302 } 303 } 304 } 305 306 /** 307 * <p> 308 * TODO: comment 309 * </p> 310 * 311 * @param currentCommonDenominator 312 * @param guiElement 313 * @return 314 */ 315 private boolean isOnGuiElementPath(IGUIElement potentialPathElement, IGUIElement child) { 316 IGUIElement guiElement = child; 317 318 while (guiElement != null) { 319 if (guiElement.equals(potentialPathElement)) { 320 return true; 321 } 322 guiElement = guiElement.getParent(); 323 } 324 325 return false; 326 } 327 328 /** 329 * 330 */ 331 private static class ReducableCommonDenominator { 332 333 /** the GUI element being the common denominator */ 334 private IGUIElement commonGuiElement; 335 336 /** the number of tasks that match the common denominator */ 337 private int noOfTasks; 338 339 /* (non-Javadoc) 340 * @see java.lang.Object#toString() 341 */ 342 @Override 343 public String toString() { 344 return noOfTasks + " tasks on " + commonGuiElement; 345 } 346 347 } 382 getTerminalGuiElements(child, terminalGuiElements); 383 } 384 } 385 } 386 387 /** 388 * <p> 389 * returns a list of GUI elements that represents the whole GUI element hierarchy of the 390 * provided GUI element. The method considers the GUI element filter applied by this rule. 391 * </p> 392 */ 393 private List<IGUIElement> getGuiElementHierarchy(IGUIElement guiElement) { 394 IGUIElement element = guiElement; 395 396 if (!guiElementMatchesConsideredTypes(element)) { 397 element = searchHierarchyForGuiElementWithConsideredType(element); 398 } 399 400 List<IGUIElement> hierarchy = new ArrayList<IGUIElement>(); 401 402 while (element != null) { 403 hierarchy.add(0, element); 404 element = searchHierarchyForGuiElementWithConsideredType(element.getParent()); 405 } 406 407 if (hierarchy.size() > 0) { 408 return hierarchy; 409 } 410 else { 411 return null; 412 } 413 } 414 415 /** 416 * <p> 417 * returns for a given GUI element the next GUI element in the upper GUI element hierarchy 418 * that matches the GUI element filter of the rule. If the provided GUI element already 419 * matches the filter, it is returned directly. 420 * </p> 421 */ 422 private IGUIElement searchHierarchyForGuiElementWithConsideredType(IGUIElement guiElement) { 423 IGUIElement returnValue = guiElement; 424 425 while ((returnValue != null) && !guiElementMatchesConsideredTypes(returnValue)) { 426 returnValue = returnValue.getParent(); 427 } 428 429 return returnValue; 430 } 431 432 /** 433 * <p> 434 * checks if the provided GUI element matches the GUI element filter applied by the rule. 435 * </p> 436 */ 437 private boolean guiElementMatchesConsideredTypes(IGUIElement guiElement) { 438 if (guiElementFilter == null) { 439 return true; 440 } 441 else { 442 for (Class<? extends IGUIElement> clazz : guiElementFilter) { 443 if (clazz.isInstance(guiElement)) { 444 return true; 445 } 446 } 447 448 return false; 449 } 450 } 451 348 452 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiElementSequenceDetectionRuleBad.java
r972 r987 12 12 13 13 /** 14 * This rule generates sequences depending on a GUI model. All actions occurring on the same GUI 15 * element are put together in a sequence. All sequences and actions within a common panel are also 16 * put together to a sequence. Through this, an event sequence gets a logical structure and shows, 17 * which interactions that happen together also happen in the same GUI context. 14 * TODO: comment or delete 18 15 * 19 16 * @version $Revision: $ $Date: 18.03.2012$ 20 17 * @author 2012, last modified by $Author: patrick$ 21 18 */ 22 public class DefaultGuiElementSequenceDetectionRule implements TemporalRelationshipRule { 19 public class DefaultGuiElementSequenceDetectionRuleBad implements TemporalRelationshipRule { 20 21 /** 22 * 23 */ 24 private List<Class<? extends IGUIElement>> guiElementFilter; 25 26 /** 27 * 28 */ 29 DefaultGuiElementSequenceDetectionRuleBad() { 30 this.guiElementFilter = null; 31 } 32 33 /** 34 * 35 */ 36 DefaultGuiElementSequenceDetectionRuleBad(List<Class<? extends IGUIElement>> guiElementFilter) { 37 this.guiElementFilter = guiElementFilter; 38 } 23 39 24 40 /* … … 38 54 } 39 55 56 List<ITaskTreeNode> children = parent.getChildren(); 40 57 RuleApplicationResult result = new RuleApplicationResult(); 41 58 42 59 IGUIElement lastGuiElement = null; 43 60 int index = 0; 44 while (index < parent.getChildren().size()) {45 ITaskTreeNode child = parent.getChildren().get(index);46 IGUIElement currentGuiElement = getG UIElement(child);47 if ((index > 0) && (! lastGuiElement.equals(currentGuiElement))) {61 while (index <= children.size()) { 62 ITaskTreeNode child = index < children.size() ? children.get(index) : null; 63 IGUIElement currentGuiElement = getGuiElement(child); 64 if ((index > 0) && (!guiElementsEqual(lastGuiElement, currentGuiElement))) { 48 65 ReducableCommonDenominator commonDenominator = 49 66 getNextReducableCommonDenominator(parent, index - 1); 50 51 if (commonDenominator != null) { 52 // condense only if not all children would be condensed or if we can be sure, 53 // that there will be no further child that should be included in the condensed 54 // sequence 55 if ((commonDenominator.noOfTasks < parent.getChildren().size()) && 56 (!isOnGuiElementPath(commonDenominator.commonGuiElement, currentGuiElement))) 57 { 58 condenseTasksToSequence(parent, index, commonDenominator.noOfTasks, 59 builder, nodeFactory, result); 60 61 result.setRuleApplicationStatus 62 (RuleApplicationStatus.RULE_APPLICATION_FINISHED); 63 return result; 64 } 65 else { 66 // the common denominator is on the parent path of the next GUI element. 67 // Therefore, the current sequences is not finished yet. So break up. 68 result.setRuleApplicationStatus 69 (RuleApplicationStatus.RULE_APPLICATION_FEASIBLE); 70 } 71 } 67 68 RuleApplicationStatus status = handleCommonDenominator 69 (commonDenominator, parent, index, lastGuiElement, currentGuiElement, builder, 70 nodeFactory, finalize, result); 71 72 if (status != null) { 73 result.setRuleApplicationStatus(status); 74 return result; 75 } 76 // else go on 72 77 } 73 78 … … 76 81 } 77 82 78 ReducableCommonDenominator commonDenominator =79 getNextReducableCommonDenominator(parent, parent.getChildren().size() - 1);80 81 if ((commonDenominator != null) &&82 (commonDenominator.noOfTasks < parent.getChildren().size()))83 {84 if (finalize) {85 condenseTasksToSequence86 (parent, index, commonDenominator.noOfTasks, builder, nodeFactory, result);87 88 result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);89 90 return result;91 }92 else {93 result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);94 }95 }96 97 83 return result; 98 84 } 99 85 100 86 /** 101 * <p> 102 * TODO: comment 103 * </p> 104 * 105 * @param guiElement 106 * @param detectedTasks 107 * @param parent 108 * @param index 109 * @param builder 110 * @param nodeFactory 111 * @return 112 */ 113 private void condenseTasksToSequence(ITaskTreeNode parent, 114 int parentIndex, 115 int noOfTasks, 116 ITaskTreeBuilder builder, 117 ITaskTreeNodeFactory nodeFactory, 118 RuleApplicationResult result) 119 { 120 ISequence newSequence = nodeFactory.createNewSequence(); 121 for (int i = 0; i < noOfTasks; i++) { 122 builder.addChild(newSequence, parent.getChildren().get(parentIndex - noOfTasks)); 123 // remove exactly the same number of children from the parent. 124 builder.removeChild((ISequence) parent, parentIndex - noOfTasks); 125 } 126 127 builder.addChild((ISequence) parent, parentIndex - noOfTasks, newSequence); 128 result.addNewlyCreatedParentNode(newSequence); 129 } 130 131 /** 132 * <p> 133 * TODO: comment 134 * </p> 135 * 136 * @param detectedTasks 137 * @return 87 * 138 88 */ 139 89 private ReducableCommonDenominator getNextReducableCommonDenominator(ITaskTreeNode parent, … … 157 107 else { 158 108 currentCommonDenominator = getCommonDenominator 159 (getG UIElement(parent.getChildren().get(pos)),160 getG UIElement(parent.getChildren().get(pos + 1)));109 (getGuiElement(parent.getChildren().get(pos)), 110 getGuiElement(parent.getChildren().get(pos + 1))); 161 111 } 162 112 … … 182 132 183 133 /** 184 * <p> 185 * TODO: comment 186 * </p> 187 * 188 * @param child 189 * @return 190 */ 191 private IGUIElement getGUIElement(ITaskTreeNode node) { 192 List<IGUIElement> terminalGUIElements = new ArrayList<IGUIElement>(); 193 getTerminalGUIElements(node, terminalGUIElements); 194 return getCommonDenominator(terminalGUIElements); 195 } 196 197 /** 198 * <p> 199 * TODO: comment 200 * </p> 201 * 202 * @param detectedTaskGroups 203 * @return 204 */ 205 /*private IGUIElement getCommonDenominator(Stack<Task> detectedTasks, int start) { 206 List<IGUIElement> allGUIElements = new ArrayList<IGUIElement>(); 207 208 for (int i = start; i < detectedTasks.size(); i++) { 209 allGUIElements.add(detectedTasks.get(i).commonGuiElement); 210 } 211 212 return getCommonDenominator(allGUIElements); 213 }*/ 214 215 /** 216 * <p> 217 * TODO: comment 218 * </p> 219 * 220 * @param child 221 * @return 222 */ 223 private IGUIElement getCommonDenominator(IGUIElement guiElement1, IGUIElement guiElement2) { 224 List<IGUIElement> allGUIElements = new ArrayList<IGUIElement>(); 225 allGUIElements.add(guiElement1); 226 allGUIElements.add(guiElement2); 227 return getCommonDenominator(allGUIElements); 228 } 229 230 /** 231 * <p> 232 * TODO: comment 233 * </p> 234 * 235 * @param child 236 * @return 134 * 135 */ 136 private RuleApplicationStatus handleCommonDenominator(ReducableCommonDenominator commonDenominator, 137 ITaskTreeNode parent, 138 int currentIndex, 139 IGUIElement lastGuiElement, 140 IGUIElement currentGuiElement, 141 ITaskTreeBuilder builder, 142 ITaskTreeNodeFactory nodeFactory, 143 boolean finalize, 144 RuleApplicationResult result) 145 { 146 List<ITaskTreeNode> children = parent.getChildren(); 147 148 boolean sequenceHasOnlyOneChild = children.size() == 1; 149 boolean reachedEndOfSequence = currentIndex == children.size(); 150 boolean haveCommonDenominator = commonDenominator != null; 151 boolean allChildrenShareDenominator = 152 haveCommonDenominator && commonDenominator.noOfTasks == children.size(); 153 boolean nextChildSharesDenominator = 154 haveCommonDenominator && !reachedEndOfSequence && 155 isOnGuiElementPath(commonDenominator.commonGuiElement, currentGuiElement); 156 157 IGUIElement denominatorOfPreviousAndCurrentChild = 158 !reachedEndOfSequence ? getCommonDenominator(lastGuiElement, currentGuiElement) : null; 159 160 boolean previousAndCurrentChildHaveDenominator = 161 denominatorOfPreviousAndCurrentChild != null; 162 163 if (haveCommonDenominator) { 164 if (!reachedEndOfSequence) { 165 if (nextChildSharesDenominator) { 166 // the last child, although matching the identified common denominator, may 167 // stand on its own because it is even deeper in the hierarchy, than the 168 // common denominator as well as the common denominator with the next child. 169 // So there need to appropriate subsequences to distinguish the child from 170 // the hierarchy of the next one. 171 if (isOnGuiElementPath(denominatorOfPreviousAndCurrentChild, lastGuiElement)) { 172 return condenseChildToSequencesRepresentingHierarchy 173 (parent, lastGuiElement, denominatorOfPreviousAndCurrentChild, 174 currentIndex - 1, builder, nodeFactory, result); 175 } 176 else { 177 // go on 178 return null; 179 } 180 } 181 else { 182 condenseTasksToSequencesRepresentingHierarchy 183 (commonDenominator.commonGuiElement, currentGuiElement, parent, 184 currentIndex, commonDenominator.noOfTasks, builder, nodeFactory, result); 185 186 return RuleApplicationStatus.RULE_APPLICATION_FINISHED; 187 } 188 } 189 else { 190 // end of sequence is reached and denominator is found 191 if (!allChildrenShareDenominator) { 192 condenseTasksToSequencesRepresentingHierarchy 193 (commonDenominator.commonGuiElement, currentGuiElement, parent, 194 currentIndex, commonDenominator.noOfTasks, builder, nodeFactory, result); 195 196 return RuleApplicationStatus.RULE_APPLICATION_FINISHED; 197 } 198 else { 199 // all children share denominator 200 if (finalize) { 201 if (ensureSequencesRepresentingHierarchy 202 (parent, commonDenominator.commonGuiElement, 203 builder, nodeFactory, result)) 204 { 205 return RuleApplicationStatus.RULE_APPLICATION_FINISHED; 206 } 207 else { 208 return condenseChildToSequencesRepresentingHierarchy 209 (parent, lastGuiElement, getGuiElement(parent), currentIndex - 1, 210 builder, nodeFactory, result); 211 } 212 } 213 else { 214 return RuleApplicationStatus.RULE_APPLICATION_FEASIBLE; 215 } 216 } 217 } 218 } 219 else { 220 // no common denominator found 221 if (!reachedEndOfSequence) { 222 if (previousAndCurrentChildHaveDenominator) { 223 // go on 224 return null; 225 } 226 else { 227 return condenseChildToSequencesRepresentingHierarchy 228 (parent, lastGuiElement, getGuiElement(parent), currentIndex - 1, 229 builder, nodeFactory, result); 230 } 231 } 232 else { 233 // last child has its own GUI hierarchy 234 if (sequenceHasOnlyOneChild) { 235 if (finalize) { 236 if (ensureSequencesRepresentingHierarchy 237 (parent, lastGuiElement, builder, nodeFactory, result)) 238 { 239 return RuleApplicationStatus.RULE_APPLICATION_FINISHED; 240 } 241 else { 242 return RuleApplicationStatus.RULE_NOT_APPLIED; 243 } 244 } 245 else { 246 return RuleApplicationStatus.RULE_APPLICATION_FEASIBLE; 247 } 248 } 249 else { 250 if (finalize) { 251 return condenseChildToSequencesRepresentingHierarchy 252 (parent, lastGuiElement, getGuiElement(parent), currentIndex - 1, 253 builder, nodeFactory, result); 254 } 255 else { 256 return RuleApplicationStatus.RULE_APPLICATION_FEASIBLE; 257 } 258 } 259 } 260 } 261 } 262 263 /** 264 * 237 265 */ 238 266 private IGUIElement getCommonDenominator(List<IGUIElement> guiElements) { … … 245 273 IGUIElement guiElement = guiElements.get(0); 246 274 while (guiElement != null) { 247 commonDenominatorPath.add(0, guiElement); 275 if (guiElementMatchesConsideredTypes(guiElement)) { 276 commonDenominatorPath.add(0, guiElement); 277 } 248 278 guiElement = guiElement.getParent(); 279 } 280 281 if (commonDenominatorPath.size() == 0) { 282 return null; 249 283 } 250 284 … … 257 291 guiElement = guiElements.get(i); 258 292 while (guiElement != null) { 259 currentPath.add(0, guiElement); 293 if (guiElementMatchesConsideredTypes(guiElement)) { 294 currentPath.add(0, guiElement); 295 } 260 296 guiElement = guiElement.getParent(); 261 297 } … … 284 320 285 321 /** 322 * 323 */ 324 private IGUIElement getCommonDenominator(IGUIElement guiElement1, IGUIElement guiElement2) { 325 if ((guiElement1 == null) || (guiElement2 == null)) { 326 return null; 327 } 328 329 List<IGUIElement> allGuiElements = new ArrayList<IGUIElement>(); 330 allGuiElements.add(guiElement1); 331 allGuiElements.add(guiElement2); 332 return getCommonDenominator(allGuiElements); 333 } 334 335 /** 336 * 337 */ 338 private void condenseTasksToSequencesRepresentingHierarchy(IGUIElement lastGuiElement, 339 IGUIElement currentGuiElement, 340 ITaskTreeNode parent, 341 int parentIndex, 342 int noOfTasks, 343 ITaskTreeBuilder builder, 344 ITaskTreeNodeFactory nodeFactory, 345 RuleApplicationResult result) 346 { 347 List<IGUIElement> lastHierarchy = getGuiElementHierarchy(lastGuiElement); 348 List<IGUIElement> currentHierarchy = getGuiElementHierarchy(currentGuiElement); 349 int index = parentIndex; 350 351 ITaskTreeNode generatedSequence = parent; 352 353 for (int i = 0; i < lastHierarchy.size(); i++) { 354 // add sequence for each element in the previous hierarchy, that does not occur in the 355 // current hierarchy 356 if ((currentHierarchy == null) || (i >= currentHierarchy.size()) || 357 (!currentHierarchy.get(i).equals(lastHierarchy.get(i)))) 358 { 359 condenseTasksToSequence(generatedSequence, lastHierarchy.get(i), index, 360 noOfTasks, builder, nodeFactory, result); 361 362 // only in the first iteration, we condense tasks in the parent. Afterwards, 363 // we always condense all tasks in the created sequence to a new subsequence. 364 // Therefore, adapt all indexes appropriately 365 generatedSequence = generatedSequence.getChildren().get(index - noOfTasks); 366 index = noOfTasks; 367 } 368 } 369 } 370 371 /** 372 * 373 */ 374 private boolean ensureSequencesRepresentingHierarchy(ITaskTreeNode parent, 375 IGUIElement elementToRepresent, 376 ITaskTreeBuilder builder, 377 ITaskTreeNodeFactory nodeFactory, 378 RuleApplicationResult result) 379 { 380 boolean applied = false; 381 IGUIElement currentlyConsideredElement = elementToRepresent; 382 IGUIElement elementRepresentedByParent = getGuiElement(parent); 383 384 while ((currentlyConsideredElement != null) && 385 (!currentlyConsideredElement.equals(elementRepresentedByParent))) 386 { 387 condenseTasksToSequence(parent, currentlyConsideredElement, parent.getChildren().size(), 388 parent.getChildren().size(), builder, nodeFactory, result); 389 applied = true; 390 currentlyConsideredElement = currentlyConsideredElement.getParent(); 391 } 392 393 if (currentlyConsideredElement != null) { 394 applied |= updateDescription(parent, currentlyConsideredElement, builder); 395 } 396 397 return applied; 398 } 399 400 /** 401 * 402 */ 403 private RuleApplicationStatus condenseChildToSequencesRepresentingHierarchy(ITaskTreeNode parent, 404 IGUIElement childGuiElement, 405 IGUIElement parentGuiElement, 406 int childIndex, 407 ITaskTreeBuilder builder, 408 ITaskTreeNodeFactory nodeFactory, 409 RuleApplicationResult result) 410 { 411 ITaskTreeNode child = parent.getChildren().get(childIndex); 412 boolean childIsSequence = child instanceof ISequence; 413 boolean childHasGuiElement = childGuiElement != null; 414 415 if (childIsSequence) { 416 if (childHasGuiElement) { 417 if (updateDescription(child, childGuiElement, builder)) { 418 return RuleApplicationStatus.RULE_APPLICATION_FINISHED; 419 } 420 } 421 } 422 else { 423 boolean applied = false; 424 IGUIElement currentlyConsideredElement = childGuiElement; 425 426 while ((currentlyConsideredElement != null) && 427 (!currentlyConsideredElement.equals(parentGuiElement))) 428 { 429 condenseTasksToSequence(parent, currentlyConsideredElement, childIndex + 1, 1, 430 builder, nodeFactory, result); 431 applied = true; 432 currentlyConsideredElement = currentlyConsideredElement.getParent(); 433 } 434 435 if (currentlyConsideredElement != null) { 436 IGUIElement parentCommonDenominator = getGuiElement(parent); 437 if (currentlyConsideredElement.equals(parentCommonDenominator)) { 438 applied |= updateDescription(parent, currentlyConsideredElement, builder); 439 } 440 } 441 442 if (applied) { 443 return RuleApplicationStatus.RULE_APPLICATION_FINISHED; 444 } 445 } 446 447 return null; 448 } 449 450 /** 286 451 * <p> 287 * TODO: comment 452 * condensed a subsequence of the children of the provided parent to a sequence. The 453 * subsequence in the list of children defined by the index of the succeeding child 454 * (parentIndex) and the number of tasks to be condensed (noOfTasks). 288 455 * </p> 289 456 * 290 * @param child 291 * @return 292 */ 293 private void getTerminalGUIElements(ITaskTreeNode node, List<IGUIElement> terminalGUIElements) { 457 * @param parent the parent node whose children are to be condensed 458 * @param target the GUI element in which all condensed interactions take place 459 * @param parentIndex the index of the child in the parent, which follows the children 460 * to be condensed 461 * @param noOfTasks the number of children to be condensed 462 * @param builder the builder to create the new subsequence 463 * @param nodeFactory the node factory to instantiate the new subsequence 464 * @param result the result of the rule application to store newly created parent nodes 465 */ 466 private void condenseTasksToSequence(ITaskTreeNode parent, 467 IGUIElement target, 468 int parentIndex, 469 int noOfTasks, 470 ITaskTreeBuilder builder, 471 ITaskTreeNodeFactory nodeFactory, 472 RuleApplicationResult result) 473 { 474 ISequence newSequence = nodeFactory.createNewSequence(); 475 updateDescription(newSequence, target, builder); 476 477 for (int i = 0; i < noOfTasks; i++) { 478 builder.addChild(newSequence, parent.getChildren().get(parentIndex - noOfTasks)); 479 // remove exactly the same number of children from the parent. 480 builder.removeChild((ISequence) parent, parentIndex - noOfTasks); 481 } 482 483 builder.addChild((ISequence) parent, parentIndex - noOfTasks, newSequence); 484 result.addNewlyCreatedParentNode(newSequence); 485 } 486 487 /** 488 * 489 */ 490 private boolean updateDescription(ITaskTreeNode node, 491 IGUIElement commonGuiElement, 492 ITaskTreeBuilder builder) 493 { 494 String newDescription = "interactions on " + commonGuiElement.getStringIdentifier(); 495 496 String currentDescription = node.getDescription(); 497 498 if ((currentDescription == null) || (currentDescription.indexOf(newDescription) == -1)) { 499 if ((currentDescription != null) && (!"".equals(currentDescription))) { 500 newDescription = currentDescription + "; " + newDescription; 501 } 502 503 builder.setDescription(node, newDescription); 504 return true; 505 } 506 else { 507 return false; 508 } 509 } 510 511 /** 512 * 513 */ 514 private IGUIElement getGuiElement(ITaskTreeNode node) { 515 if (node != null) { 516 List<IGUIElement> terminalGuiElements = new ArrayList<IGUIElement>(); 517 getTerminalGuiElements(node, terminalGuiElements); 518 return getCommonDenominator(terminalGuiElements); 519 } 520 else { 521 return null; 522 } 523 } 524 525 /** 526 * 527 */ 528 private void getTerminalGuiElements(ITaskTreeNode node, List<IGUIElement> terminalGuiElements) { 294 529 if (node instanceof IEventTask) { 295 530 if (((IEventTask) node).getEventTarget() instanceof IGUIElement) { 296 terminalGUIElements.add((IGUIElement) ((IEventTask) node).getEventTarget()); 531 IGUIElement terminalGuiElement = (IGUIElement) ((IEventTask) node).getEventTarget(); 532 terminalGuiElement = 533 searchHierarchyForGuiElementWithConsideredType(terminalGuiElement); 534 535 if (terminalGuiElement != null) { 536 terminalGuiElements.add(terminalGuiElement); 537 } 297 538 } 298 539 } 299 540 else { 300 541 for (ITaskTreeNode child : node.getChildren()) { 301 getTerminalGUIElements(child, terminalGUIElements); 302 } 303 } 304 } 305 306 /** 307 * <p> 308 * TODO: comment 309 * </p> 310 * 311 * @param currentCommonDenominator 312 * @param guiElement 313 * @return 542 getTerminalGuiElements(child, terminalGuiElements); 543 } 544 } 545 } 546 547 /** 548 * 549 */ 550 private List<IGUIElement> getGuiElementHierarchy(IGUIElement guiElement) { 551 IGUIElement element = guiElement; 552 553 if (!guiElementMatchesConsideredTypes(element)) { 554 element = searchHierarchyForGuiElementWithConsideredType(element); 555 } 556 557 List<IGUIElement> hierarchy = new ArrayList<IGUIElement>(); 558 559 while (element != null) { 560 hierarchy.add(0, element); 561 element = searchHierarchyForGuiElementWithConsideredType(element.getParent()); 562 } 563 564 if (hierarchy.size() > 0) { 565 return hierarchy; 566 } 567 else { 568 return null; 569 } 570 } 571 572 /** 573 * 574 */ 575 private IGUIElement searchHierarchyForGuiElementWithConsideredType(IGUIElement guiElement) { 576 IGUIElement returnValue = guiElement; 577 578 while ((returnValue != null) && !guiElementMatchesConsideredTypes(returnValue)) { 579 returnValue = returnValue.getParent(); 580 } 581 582 return returnValue; 583 } 584 585 /** 586 * 587 */ 588 private boolean guiElementsEqual(IGUIElement guiElement1, IGUIElement guiElement2) { 589 if (guiElement1 == null) { 590 return guiElement2 == null; 591 } 592 else { 593 return guiElement1.equals(guiElement2); 594 } 595 } 596 597 /** 598 * 314 599 */ 315 600 private boolean isOnGuiElementPath(IGUIElement potentialPathElement, IGUIElement child) { … … 329 614 * 330 615 */ 331 private static class ReducableCommonDenominator { 616 private boolean guiElementMatchesConsideredTypes(IGUIElement guiElement) { 617 if (guiElementFilter == null) { 618 return true; 619 } 620 else { 621 for (Class<? extends IGUIElement> clazz : guiElementFilter) { 622 if (clazz.isInstance(guiElement)) { 623 return true; 624 } 625 } 626 627 return false; 628 } 629 } 630 631 /** 632 * 633 */ 634 static class ReducableCommonDenominator { 332 635 333 636 /** the GUI element being the common denominator */ 334 privateIGUIElement commonGuiElement;637 IGUIElement commonGuiElement; 335 638 336 639 /** the number of tasks that match the common denominator */ 337 privateint noOfTasks;640 int noOfTasks; 338 641 339 642 /* (non-Javadoc) -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiEventSequenceDetectionRule.java
r972 r987 98 98 99 99 result.addNewlyCreatedParentNode(sequence); 100 101 builder.setDescription 102 (sequence, "logical sequence started by the first event"); 103 100 104 result.setRuleApplicationStatus 101 105 (RuleApplicationStatus.RULE_APPLICATION_FINISHED); -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java
r922 r987 5 5 import java.util.logging.Level; 6 6 7 import de.ugoe.cs.autoquest.eventcore.guimodel.IDialog; 8 import de.ugoe.cs.autoquest.eventcore.guimodel.IFrame; 9 import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; 7 10 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality; 8 11 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager; … … 100 103 */ 101 104 public void init() { 105 List<Class<? extends IGUIElement>> frameFilter = 106 new ArrayList<Class<? extends IGUIElement>>(); 107 frameFilter.add(IFrame.class); 108 frameFilter.add(IDialog.class); 109 110 rules.add(new DefaultGuiElementSequenceDetectionRule(frameFilter)); 102 111 rules.add(new DefaultGuiElementSequenceDetectionRule()); 103 112 rules.add(new DefaultEventTargetSequenceDetectionRule()); 104 113 rules.add(new TrackBarSelectionDetectionRule(nodeEqualityRuleManager)); 105 rules.add(new DefaultGuiEventSequenceDetectionRule());114 //rules.add(new DefaultGuiEventSequenceDetectionRule()); 106 115 107 116 rules.add(new DefaultIterationDetectionRule … … 153 162 * @param finalize used to indicate, if the rule application shall break up if a rule would 154 163 * be feasible if further data was available, or not. 155 * @param logIndent simply used for loggin purposes to indent the log messages depending164 * @param logIndent simply used for logging purposes to indent the log messages depending 156 165 * on the recursion depth of calling this method. 157 166 */ … … 169 178 RuleApplicationResult result; 170 179 do { 171 // LOG.info(logIndent + "trying to applyrule " + rule + " on " + parent);180 Console.traceln(Level.FINER, logIndent + "trying rule " + rule + " on " + parent); 172 181 result = rule.apply(parent, builder, nodeFactory, finalize); 173 182 … … 179 188 (Level.FINE, logIndent + "applied rule " + rule + " on " + parent); 180 189 noOfRuleApplications++; 190 191 dumpTask(parent, ""); 181 192 182 193 for (ITaskTreeNode newParent : result.getNewlyCreatedParentNodes()) { … … 211 222 * 212 223 */ 213 /* 214 * private void dumpTask(TaskTreeNode task, String indent) { System.err.print(indent); 215 * System.err.print(task); System.err.println(" "); 216 * 217 * if ((task.getChildren() != null) && (task.getChildren().size() > 0)) { for (TaskTreeNode 218 * child : task.getChildren()) { dumpTask(child, indent + " "); } } } 219 */ 224 private void dumpTask(ITaskTreeNode task, String indent) { 225 StringBuffer message = new StringBuffer(); 226 message.append(indent); 227 message.append(task); 228 if (task.getDescription() != null) { 229 message.append('('); 230 message.append(task.getDescription()); 231 message.append(')'); 232 } 233 234 Console.traceln(Level.FINER, message.toString()); 235 236 if ((task.getChildren() != null) && (task.getChildren().size() > 0)) { 237 for (ITaskTreeNode child : task.getChildren()) { 238 dumpTask(child, indent + " "); 239 } 240 } 241 } 220 242 221 243 }
Note: See TracChangeset
for help on using the changeset viewer.