Ignore:
Timestamp:
02/21/13 18:39:13 (11 years ago)
Author:
pharms
Message:
  • changed rules to be testable on their own
  • added first version for a task detection rule
  • refactored rules to have a simpler interface
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiEventSequenceDetectionRule.java

    r987 r1107  
    11package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 
     2 
     3import java.util.Stack; 
    24 
    35import de.ugoe.cs.autoquest.eventcore.gui.IInteraction; 
     
    1820 * @author 2012, last modified by $Author: patrick$ 
    1921 */ 
    20 public class DefaultGuiEventSequenceDetectionRule implements TemporalRelationshipRule { 
     22class DefaultGuiEventSequenceDetectionRule implements TemporalRelationshipRule { 
    2123 
     24    /** 
     25     * <p> 
     26     * the task tree node factory to be used for creating substructures for the temporal 
     27     * relationships identified during rule 
     28     * </p> 
     29     */ 
     30    private ITaskTreeNodeFactory taskTreeNodeFactory; 
     31    /** 
     32     * <p> 
     33     * the task tree builder to be used for creating substructures for the temporal relationships 
     34     * identified during rule application 
     35     * </p> 
     36     */ 
     37    private ITaskTreeBuilder taskTreeBuilder; 
     38     
     39    /** 
     40     * <p> 
     41     * instantiates the rule with a task tree node factory and builder to be used during rule 
     42     * application. 
     43     * </p> 
     44     *  
     45     * @param taskTreeNodeFactory the task tree node factory to be used for creating substructures 
     46     *                            for the temporal relationships identified during rule 
     47     *                            application 
     48     * @param taskTreeBuilder     the task tree builder to be used for creating substructures for 
     49     *                            the temporal relationships identified during rule application 
     50     */ 
     51    DefaultGuiEventSequenceDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory, 
     52                                         ITaskTreeBuilder     taskTreeBuilder) 
     53    { 
     54        this.taskTreeNodeFactory = taskTreeNodeFactory; 
     55        this.taskTreeBuilder = taskTreeBuilder; 
     56    } 
     57     
    2258    /* 
    2359     * (non-Javadoc) 
    2460     *  
    2561     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode, 
    26      * TaskTreeBuilder, TaskTreeNodeFactory) 
     62     * boolean) 
    2763     */ 
    2864    @Override 
    29     public RuleApplicationResult apply(ITaskTreeNode        parent, 
    30                                        ITaskTreeBuilder     builder, 
    31                                        ITaskTreeNodeFactory nodeFactory, 
    32                                        boolean              finalize) 
    33     { 
     65    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) { 
    3466        if (!(parent instanceof ISequence)) { 
    3567            return null; 
     
    3769 
    3870        RuleApplicationResult result = new RuleApplicationResult(); 
    39         int sequenceStartingIndex = -1; 
     71        Stack<Integer> sequenceStartingIndex = new Stack<Integer>(); 
    4072 
    4173        int index = 0; 
     
    4779            { 
    4880                IInteraction eventType = (IInteraction) ((IEventTask) child).getEventType(); 
    49                  
    50                 if (eventType.finishesLogicalSequence() && (sequenceStartingIndex > -1)) 
    51                 { 
    52                     // There are several situations in which this implementation may cause infinite 
    53                     // loops. This is because the rule manager will reapply rules until 
    54                     // no rule is applied anymore. A sequence identified in a first iteration will 
    55                     // be identified as a sequence also in a second iteration. As an example 
    56                     // many sequences start with an interaction starting that sequence and end 
    57                     // with an interaction ending that sequence. This will be reidentified as 
    58                     // further subsequence. It must therefore be assured, that a sequence, that 
    59                     // was once identified is not reidentified in a further application of the rule. 
    60                     // For this, the implementation performs a kind of dry run. It creates a list of 
    61                     // children that would belong to an identified sequence. Only if this list is 
    62                     // not a reidentification then a new sequence is created and added to the 
    63                     // parent. If it is a reidentification can be identified, if the list of 
    64                     // children will contain all children of the parent, or if the list of children 
    65                     // only consists of one sequence. Further, an identified sequence must at least 
    66                     // have one child. 
    67                     if (((sequenceStartingIndex != 0) || 
    68                          (index != (parent.getChildren().size() - 1))) && 
    69                         (((index - sequenceStartingIndex) > 0) || 
    70                           (((index - sequenceStartingIndex) == 0) && 
    71                            (!eventType.startsLogicalSequence())))) 
    72                     { 
    73                         boolean allNewChildrenAreSequences = true; 
    7481 
    75                         for (int j = sequenceStartingIndex; 
    76                              ((allNewChildrenAreSequences) && (j < index)); j++) 
    77                         { 
    78                             allNewChildrenAreSequences &= 
    79                                 (parent.getChildren().get(j) instanceof ISequence); 
    80                         } 
    81  
    82                         if (!allNewChildrenAreSequences) { 
    83                             ISequence sequence = nodeFactory.createNewSequence(); 
    84  
    85                             for (int j = sequenceStartingIndex; j < index; j++) { 
    86                                 builder.addChild 
    87                                     (sequence, parent.getChildren().get(sequenceStartingIndex)); 
    88                                 builder.removeChild((ISequence) parent, sequenceStartingIndex); 
    89                             } 
    90  
    91                             if (!eventType.startsLogicalSequence()) { 
    92                                 builder.addChild 
    93                                     (sequence, parent.getChildren().get(sequenceStartingIndex)); 
    94                                 builder.removeChild((ISequence) parent, sequenceStartingIndex); 
    95                             } 
    96  
    97                             builder.addChild((ISequence) parent, sequenceStartingIndex, sequence); 
    98  
    99                             result.addNewlyCreatedParentNode(sequence); 
    100                              
    101                             builder.setDescription 
    102                                 (sequence, "logical sequence started by the first event"); 
    103                              
    104                             result.setRuleApplicationStatus 
    105                                 (RuleApplicationStatus.RULE_APPLICATION_FINISHED); 
    106                             return result; 
    107                         } 
    108                     } 
     82                if (eventType.finishesLogicalSequence() && (sequenceStartingIndex.size() > 0)) { 
     83                    index = handleLogicalSequence(sequenceStartingIndex, index, parent, result); 
    10984                } 
    11085 
    11186                if (eventType.startsLogicalSequence()) { 
    112                     sequenceStartingIndex = index; 
     87                    sequenceStartingIndex.push(index); 
    11388                } 
    11489            } 
     
    11792        } 
    11893 
    119         if (sequenceStartingIndex >= 0) { 
    120             result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE); 
     94        if (sequenceStartingIndex.size() > 0) { 
     95            if (!finalize) { 
     96                result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE); 
     97            } 
     98            else { 
     99                ITaskTreeNode lastChild = parent.getChildren().get(parent.getChildren().size() - 1); 
     100                 
     101                if (lastChild instanceof IEventTask) { 
     102                    handleLogicalSequence 
     103                        (sequenceStartingIndex, parent.getChildren().size() - 1, parent, result); 
     104                } 
     105            } 
    121106        } 
    122107 
     
    124109    } 
    125110 
     111    /** 
     112     * <p> 
     113     * TODO: comment 
     114     * </p> 
     115     * 
     116     */ 
     117    private int handleLogicalSequence(Stack<Integer>        sequenceStartingIndex, 
     118                                      int                   index, 
     119                                      ITaskTreeNode         parent, 
     120                                      RuleApplicationResult result) 
     121    { 
     122        int newIndex = index; 
     123        IInteraction eventType = 
     124            (IInteraction) ((IEventTask) parent.getChildren().get(index)).getEventType(); 
     125 
     126        // There are several situations in which this implementation may cause infinite 
     127        // loops. This is because the rule manager will reapply rules until 
     128        // no rule is applied anymore. A sequence identified in a first iteration will 
     129        // be identified as a sequence also in a second iteration. As an example 
     130        // many sequences start with an interaction starting that sequence and end 
     131        // with an interaction ending that sequence. This will be reidentified as 
     132        // further subsequence. It must therefore be assured, that a sequence, that 
     133        // was once identified is not reidentified in a further application of the rule. 
     134        // For this, the implementation performs a kind of dry run. It creates a list of 
     135        // children that would belong to an identified sequence. Only if this list is 
     136        // not a reidentification then a new sequence is created and added to the 
     137        // parent. If it is a reidentification can be identified, if the list of 
     138        // children will contain all children of the parent, or if the list of children 
     139        // only consists of one sequence. Further, an identified sequence must at least 
     140        // have one child. 
     141         
     142        boolean allChildrenBelongToSubSequence = 
     143            (sequenceStartingIndex.peek() == 0) && (index == (parent.getChildren().size() - 1)); 
     144         
     145        boolean atLeastOneChildToCondense = index - sequenceStartingIndex.peek() > 0; 
     146         
     147        if (!allChildrenBelongToSubSequence && atLeastOneChildToCondense) { 
     148            int startIndex = sequenceStartingIndex.pop(); 
     149            ISequence sequence = taskTreeNodeFactory.createNewSequence(); 
     150 
     151            for (int j = startIndex; j < index; j++) { 
     152                taskTreeBuilder.addChild(sequence, parent.getChildren().get(startIndex)); 
     153                taskTreeBuilder.removeChild((ISequence) parent, startIndex); 
     154            } 
     155 
     156            if (!eventType.startsLogicalSequence()) { 
     157                taskTreeBuilder.addChild(sequence, parent.getChildren().get(startIndex)); 
     158                taskTreeBuilder.removeChild((ISequence) parent, startIndex); 
     159                newIndex = startIndex; 
     160            } 
     161            else { 
     162                newIndex = startIndex + 1; 
     163            } 
     164 
     165            taskTreeBuilder.addChild((ISequence) parent, startIndex, sequence); 
     166 
     167            result.addNewlyCreatedParentNode(sequence); 
     168                 
     169            taskTreeBuilder.setDescription(sequence, "logical sequence started by the first event"); 
     170                 
     171            result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED); 
     172        } 
     173         
     174        return newIndex; 
     175    } 
     176 
    126177} 
Note: See TracChangeset for help on using the changeset viewer.