source: branches/ralph/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java @ 1645

Last change on this file since 1645 was 1552, checked in by rkrimmel, 10 years ago

Test commit to my branch

  • Property svn:executable set to *
File size: 13.2 KB
RevLine 
[1113]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
[922]15package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
[439]16
17import java.util.ArrayList;
18import java.util.List;
[725]19import java.util.logging.Level;
[439]20
[987]21import de.ugoe.cs.autoquest.eventcore.guimodel.IDialog;
22import de.ugoe.cs.autoquest.eventcore.guimodel.IFrame;
23import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
[1146]24import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEquality;
25import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder;
26import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
27import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
28import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
[725]29import de.ugoe.cs.util.console.Console;
[439]30
31/**
[1146]32 * TODO update comment
33 *
[809]34 * <p>
35 * This class is responsible for applying temporal relationship rules on a task tree. Through this,
36 * a flat task tree is restructured to have more depth but to include more temporal relationships
[1146]37 * between tasks which are not only a major sequence. I.e. through the application of the
38 * rules iterations and selections of tasks are detected. Which kind of temporal relations
[1294]39 * between tasks are detected depends on the {@link ITaskInstanceScopeRule}s known to
[809]40 * this class.
41 * </p>
[1294]42 * <p>The class holds references to the appropriate {@link ITaskInstanceScopeRule}s and calls
43 * their {@link ITaskInstanceScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)}
[1146]44 * method for each task in the task tree it is needed for. The general behavior of this class is
[809]45 * the following:
46 * <ol>
47 *   <li>
48 *     An instance of this class is created using the constructor and calling the
49 *     {@link #init()} method afterwards
50 *   </li>
51 *   <li>
[1146]52 *     then the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)}
53 *     method is called for a so far unstructured task
[809]54 *   </li>
55 *   <li>
56 *     the class iterates its internal list of rules and calls their
[1294]57 *     {@link ITaskInstanceScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)}
[809]58 *     method.
59 *   </li>
60 *   <li>
61 *     the class evaluates the rule application result
62 *     <ul>
63 *       <li>
64 *         if a rule returns a rule application result that is null, the next rule is tried
65 *       </li>
66 *       <li>
67 *         if a rule returns that it would be feasible if more data was available and the rule
68 *         application shall not be finalized (see finalize parameter of the applyRules method)
69 *         the rule application is broken up
70 *       </li>
71 *       <li>
72 *         if a rule returns, that it was applied, the same rule is applied again until it returns
[1146]73 *         null or feasible. For each newly created parent task provided in the rule application
74 *         result, the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)}
[809]75 *         method is called.
76 *       </li>
77 *     </ul>
78 *   </li>
79 * </ol>
[1146]80 * Through this, all rules are tried to be applied at least once to the provided parent task and
81 * all parent tasks created during the rule application.
[809]82 * </p>
[439]83 *
[809]84 * @author Patrick Harms
[439]85 */
[557]86public class TemporalRelationshipRuleManager {
87   
[809]88    /**
89     * <p>
[1146]90     * the task factory to be used during rule application
[809]91     * </p>
92     */
[1146]93    private ITaskFactory taskFactory;
[439]94
[557]95    /**
[809]96     * <p>
[1146]97     * the task builder to be used during rule application
[809]98     * </p>
[557]99     */
[1146]100    private ITaskBuilder taskBuilder;
[1107]101
102    /**
103     * <p>
[1146]104     * the temporal relationship rules known to the manager that are executed on whole sessions.
[1107]105     * The rules are applied in the order they occur in this list.
106     * </p>
107     */
[1146]108    private ISessionScopeRule[] sessionScopeRules;
[1107]109
110    /**
111     * <p>
112     * the temporal relationship rules known to the manager that are executed on whole sub trees.
113     * The rules are applied in the order they occur in this list.
114     * </p>
115     */
[1294]116    private ITaskInstanceScopeRule[] taskScopeRules;
[1107]117
118    /**
119     * <p>
120     * initialize the manager
121     * </p>
122     *
[1146]123     * @param taskFactory             the task factory to be used for instantiating new task tree
124     *                                tasks during rule application
125     * @param taskBuilder             the task builder to be used for linking tasks
[1107]126     *                                with each other during rule application
127     */
[1189]128    public TemporalRelationshipRuleManager(ITaskFactory taskFactory, ITaskBuilder taskBuilder) {
[557]129        super();
[1146]130        this.taskFactory = taskFactory;
131        this.taskBuilder = taskBuilder;
[557]132    }
[439]133
[557]134    /**
[809]135     * <p>
136     * initialized the temporal relationship rule manager by instantiating the known rules and
[1146]137     * providing them with a reference to the task equality manager or other information they need.
[809]138     * </p>
[557]139     */
140    public void init() {
[987]141        List<Class<? extends IGUIElement>> frameFilter =
142            new ArrayList<Class<? extends IGUIElement>>();
143        frameFilter.add(IFrame.class);
144        frameFilter.add(IDialog.class);
[1107]145        //frameFilter.add(ICanvas.class);
[987]146
[1146]147        sessionScopeRules = new ISessionScopeRule[] {
[1552]148            new SequenceForTaskDetectionRuleAlignment
[1189]149                (TaskEquality.SEMANTICALLY_EQUAL, taskFactory, taskBuilder),
[1127]150            /*new DefaultTaskSequenceDetectionRule
[1189]151                (NodeEquality.SYNTACTICALLY_EQUAL, taskFactory, taskTreeBuilder),
[1107]152            new DefaultTaskSequenceDetectionRule
[1189]153                (NodeEquality.LEXICALLY_EQUAL, taskFactory, taskTreeBuilder),*/
[1127]154            /*new TreeScopeWrapperRule
155                (new DefaultIterationDetectionRule
[1189]156                    (NodeEquality.LEXICALLY_EQUAL, taskFactory, taskTreeBuilder)),
[1127]157            new TreeScopeWrapperRule
158                (new DefaultIterationDetectionRule
[1189]159                    (NodeEquality.SYNTACTICALLY_EQUAL, taskFactory, taskTreeBuilder)),
[1127]160            new TreeScopeWrapperRule
161                (new DefaultIterationDetectionRule
[1189]162                    (NodeEquality.SEMANTICALLY_EQUAL, taskFactory, taskTreeBuilder))*/
[1107]163        };
[805]164       
[1107]165        //treeScopeRules.add(new DefaultGuiElementSequenceDetectionRule(frameFilter));
166
[1294]167        taskScopeRules = new ITaskInstanceScopeRule[] {
[1146]168            //new SequenceOnGuiElementDetectionRule(taskFactory, taskTreeBuilder),
169            //new EventSequenceOnSameTargetDetectionRule(taskFactory, taskTreeBuilder),
[1189]170            //new TrackBarSelectionDetectionRule(taskFactory, taskBuilder),
[1146]171            //new DefaultGuiEventSequenceDetectionRule(taskFactory, taskTreeBuilder),
[1107]172        };
173
[557]174    }
[439]175
[557]176    /**
[809]177     * <p>
[1146]178     * applies the known rules to the provided sessions. For the creation of further tasks,
179     * the provided builder and task factory are utilized. The method expects, that no more data
[1107]180     * is available and, therefore, finalizes the rule application.
181     * </p>
182     *
[1146]183     * @param taskFactory  the task factory to be used for instantiating new tasks.
[1107]184     */
[1146]185    public void applyRules(List<IUserSession> sessions) {
186        applyRules(sessionScopeRules, sessions, "");
[1107]187    }
188
189    /**
190     * <p>
[1146]191     * applies the known rules to the provided parent task. For the creation of further tasks,
192     * the provided builder and task factory are utilized. If the finalize parameter is true, the
[809]193     * rule application is finalized as far as possible without waiting for further data. If it is
194     * false, the rule application is broken up at the first rule returning, that its application
[1146]195     * would be feasible. The method calls itself for each parent task created through the rule
196     * application. In this case, the finalize parameter is always true.
[809]197     * </p>
[557]198     *
[1146]199     * @param parent       the parent task to apply the rules on
[809]200     * @param finalize     used to indicate, if the rule application shall break up if a rule would
201     *                     be feasible if further data was available, or not.
[1146]202     * @param logIndent    simply used for logging purposes to indent the log messages depending
203     *                     on the recursion depth of calling this method.
[557]204     */
[1146]205    private int applyRules(ISessionScopeRule[] rules,
206                           List<IUserSession>  sessions,
207                           String              logIndent)
208    {
209        Console.traceln
210            (Level.FINER, logIndent + "applying rules for " + sessions.size() + " sessions");
211
212        int noOfRuleApplications = 0;
213
214        for (ISessionScopeRule rule : rules) {
215            RuleApplicationResult result;
216            do {
217                Console.traceln(Level.FINER, logIndent + "trying rule " + rule);
218                result = rule.apply(sessions);
219
220                if ((result != null) &&
221                    (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED))
222                {
223                    Console.traceln(Level.FINE, logIndent + "applied rule " + rule);
224                    noOfRuleApplications++;
225                   
226                    //dumpTask(parent, "");
227
228                    for (ITaskInstance newParent : result.getNewlyCreatedTaskInstances()) {
229                        noOfRuleApplications +=
230                            applyRules(taskScopeRules, newParent, logIndent + "  ");
231                    }
232                }
233            }
234            while ((result != null) &&
235                   (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED));
236
237        }
238
239        if (noOfRuleApplications <= 0) {
240            Console.traceln(Level.FINE, logIndent + "no rules applied --> no temporal " +
241                            "relationship generated");
242        }
243
244        return noOfRuleApplications;
[439]245    }
[557]246
247    /**
[809]248     * <p>
[1146]249     * applies the known rules to the provided parent task. For the creation of further tasks,
250     * the provided builder and task factory are utilized. If the finalize parameter is true, the
[809]251     * rule application is finalized as far as possible without waiting for further data. If it is
252     * false, the rule application is broken up at the first rule returning, that its application
[1146]253     * would be feasible. The method calls itself for each parent task created through the rule
[809]254     * application. In this case, the finalize parameter is always true.
255     * </p>
[557]256     *
[1146]257     * @param parent       the parent task to apply the rules on
[809]258     * @param finalize     used to indicate, if the rule application shall break up if a rule would
259     *                     be feasible if further data was available, or not.
[987]260     * @param logIndent    simply used for logging purposes to indent the log messages depending
[809]261     *                     on the recursion depth of calling this method.
[557]262     */
[1294]263    private int applyRules(ITaskInstanceScopeRule[] rules,
264                           ITaskInstance                taskInstance,
[1146]265                           String                       logIndent)
[439]266    {
[1294]267        Console.traceln(Level.FINER, logIndent + "applying rules on " + taskInstance);
[557]268
269        int noOfRuleApplications = 0;
270
[1294]271        for (ITaskInstanceScopeRule rule : rules) {
[557]272            RuleApplicationResult result;
273            do {
[1146]274                Console.traceln
[1294]275                    (Level.FINER, logIndent + "trying rule " + rule + " on " + taskInstance);
276                result = rule.apply(taskInstance);
[557]277
278                if ((result != null) &&
[1127]279                    (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED))
[557]280                {
[725]281                    Console.traceln
[1294]282                        (Level.FINE, logIndent + "applied rule " + rule + " on " + taskInstance);
[557]283                    noOfRuleApplications++;
[987]284                   
[1127]285                    //dumpTask(parent, "");
[557]286
[1146]287                    for (ITaskInstance newParent : result.getNewlyCreatedTaskInstances()) {
[557]288                        noOfRuleApplications +=
[1146]289                            applyRules(taskScopeRules, newParent, logIndent + "  ");
[557]290                    }
291                }
292            }
293            while ((result != null) &&
[1127]294                   (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED));
[557]295        }
296
297        if (noOfRuleApplications <= 0) {
[1127]298            Console.traceln(Level.FINE, logIndent + "no rules applied --> no temporal " +
[725]299                            "relationship generated");
[557]300        }
301
302        return noOfRuleApplications;
[439]303    }
[557]304
305    /**
[809]306     *
307     */
[1146]308    /*private void dumpTask(ITask task, String indent) {
[987]309        StringBuffer message = new StringBuffer();
310        message.append(indent);
311        message.append(task);
312        if (task.getDescription() != null) {
313            message.append('(');
314            message.append(task.getDescription());
315            message.append(')');
316        }
317       
318        Console.traceln(Level.FINER, message.toString());
319       
320        if ((task.getChildren() != null) && (task.getChildren().size() > 0)) {
[1146]321            for (ITask child : task.getChildren()) {
[987]322                dumpTask(child, indent + "  ");
323            }
324        }
[1131]325    }*/
[439]326
327}
Note: See TracBrowser for help on using the repository browser.