source: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiEventSequenceDetectionRule.java @ 1117

Last change on this file since 1117 was 1117, checked in by pharms, 11 years ago
  • added toString methods
  • Property svn:executable set to *
File size: 8.1 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
16
17import java.util.Stack;
18
19import de.ugoe.cs.autoquest.eventcore.gui.IInteraction;
20import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
21import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
22import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
23import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
24import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
25
26/**
27 * This rule generates sequences of events depending on the event types, more concrete, the
28 * {@link IInteraction}s and the return values of their {@link IInteraction#startsLogicalSequence()}
29 * and {@link IInteraction#finishesLogicalSequence()}. If a new logical sequence is started by
30 * an interaction, then a real sequence is instantiated. The sequence is finished, if an
31 * interaction finishes a logical sequence. Examples include keyboard focus changes.
32 *
33 * @version $Revision: $ $Date: 18.03.2012$
34 * @author 2012, last modified by $Author: patrick$
35 */
36class DefaultGuiEventSequenceDetectionRule implements TemporalRelationshipRule {
37
38    /**
39     * <p>
40     * the task tree node factory to be used for creating substructures for the temporal
41     * relationships identified during rule
42     * </p>
43     */
44    private ITaskTreeNodeFactory taskTreeNodeFactory;
45    /**
46     * <p>
47     * the task tree builder to be used for creating substructures for the temporal relationships
48     * identified during rule application
49     * </p>
50     */
51    private ITaskTreeBuilder taskTreeBuilder;
52   
53    /**
54     * <p>
55     * instantiates the rule with a task tree node factory and builder to be used during rule
56     * application.
57     * </p>
58     *
59     * @param taskTreeNodeFactory the task tree node factory to be used for creating substructures
60     *                            for the temporal relationships identified during rule
61     *                            application
62     * @param taskTreeBuilder     the task tree builder to be used for creating substructures for
63     *                            the temporal relationships identified during rule application
64     */
65    DefaultGuiEventSequenceDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory,
66                                         ITaskTreeBuilder     taskTreeBuilder)
67    {
68        this.taskTreeNodeFactory = taskTreeNodeFactory;
69        this.taskTreeBuilder = taskTreeBuilder;
70    }
71   
72    /* (non-Javadoc)
73     * @see java.lang.Object#toString()
74     */
75    @Override
76    public String toString() {
77        return "DefaultGuiEventSequenceDetectionRule";
78    }
79
80    /*
81     * (non-Javadoc)
82     *
83     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
84     * boolean)
85     */
86    @Override
87    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) {
88        if (!(parent instanceof ISequence)) {
89            return null;
90        }
91
92        RuleApplicationResult result = new RuleApplicationResult();
93        Stack<Integer> sequenceStartingIndex = new Stack<Integer>();
94
95        int index = 0;
96        while (index < parent.getChildren().size()) {
97            ITaskTreeNode child = parent.getChildren().get(index);
98
99            if ((child instanceof IEventTask) &&
100                (((IEventTask) child).getEventType() instanceof IInteraction))
101            {
102                IInteraction eventType = (IInteraction) ((IEventTask) child).getEventType();
103
104                if (eventType.finishesLogicalSequence() && (sequenceStartingIndex.size() > 0)) {
105                    index = handleLogicalSequence(sequenceStartingIndex, index, parent, result);
106                }
107
108                if (eventType.startsLogicalSequence()) {
109                    sequenceStartingIndex.push(index);
110                }
111            }
112
113            index++;
114        }
115
116        if (sequenceStartingIndex.size() > 0) {
117            if (!finalize) {
118                result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
119            }
120            else {
121                ITaskTreeNode lastChild = parent.getChildren().get(parent.getChildren().size() - 1);
122               
123                if (lastChild instanceof IEventTask) {
124                    handleLogicalSequence
125                        (sequenceStartingIndex, parent.getChildren().size() - 1, parent, result);
126                }
127            }
128        }
129
130        return result;
131    }
132
133    /**
134     * <p>
135     * TODO: comment
136     * </p>
137     *
138     */
139    private int handleLogicalSequence(Stack<Integer>        sequenceStartingIndex,
140                                      int                   index,
141                                      ITaskTreeNode         parent,
142                                      RuleApplicationResult result)
143    {
144        int newIndex = index;
145        IInteraction eventType =
146            (IInteraction) ((IEventTask) parent.getChildren().get(index)).getEventType();
147
148        // There are several situations in which this implementation may cause infinite
149        // loops. This is because the rule manager will reapply rules until
150        // no rule is applied anymore. A sequence identified in a first iteration will
151        // be identified as a sequence also in a second iteration. As an example
152        // many sequences start with an interaction starting that sequence and end
153        // with an interaction ending that sequence. This will be reidentified as
154        // further subsequence. It must therefore be assured, that a sequence, that
155        // was once identified is not reidentified in a further application of the rule.
156        // For this, the implementation performs a kind of dry run. It creates a list of
157        // children that would belong to an identified sequence. Only if this list is
158        // not a reidentification then a new sequence is created and added to the
159        // parent. If it is a reidentification can be identified, if the list of
160        // children will contain all children of the parent, or if the list of children
161        // only consists of one sequence. Further, an identified sequence must at least
162        // have one child.
163       
164        boolean allChildrenBelongToSubSequence =
165            (sequenceStartingIndex.peek() == 0) && (index == (parent.getChildren().size() - 1));
166       
167        boolean atLeastOneChildToCondense = index - sequenceStartingIndex.peek() > 0;
168       
169        if (!allChildrenBelongToSubSequence && atLeastOneChildToCondense) {
170            int startIndex = sequenceStartingIndex.pop();
171            ISequence sequence = taskTreeNodeFactory.createNewSequence();
172
173            for (int j = startIndex; j < index; j++) {
174                taskTreeBuilder.addChild(sequence, parent.getChildren().get(startIndex));
175                taskTreeBuilder.removeChild((ISequence) parent, startIndex);
176            }
177
178            if (!eventType.startsLogicalSequence()) {
179                taskTreeBuilder.addChild(sequence, parent.getChildren().get(startIndex));
180                taskTreeBuilder.removeChild((ISequence) parent, startIndex);
181                newIndex = startIndex;
182            }
183            else {
184                newIndex = startIndex + 1;
185            }
186
187            taskTreeBuilder.addChild((ISequence) parent, startIndex, sequence);
188
189            result.addNewlyCreatedParentNode(sequence);
190               
191            taskTreeBuilder.setDescription(sequence, "logical sequence started by the first event");
192               
193            result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
194        }
195       
196        return newIndex;
197    }
198
199}
Note: See TracBrowser for help on using the repository browser.