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

Last change on this file since 2132 was 2132, checked in by pharms, 8 years ago
  • added possibility to select the minimal amount of action instances a detected sequence must cover
  • Property svn:executable set to *
File size: 9.1 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.IUserSession;
[725]28import de.ugoe.cs.util.console.Console;
[439]29
30/**
[1146]31 * TODO update comment
32 *
[809]33 * <p>
34 * This class is responsible for applying temporal relationship rules on a task tree. Through this,
35 * a flat task tree is restructured to have more depth but to include more temporal relationships
[1146]36 * between tasks which are not only a major sequence. I.e. through the application of the
37 * rules iterations and selections of tasks are detected. Which kind of temporal relations
[1294]38 * between tasks are detected depends on the {@link ITaskInstanceScopeRule}s known to
[809]39 * this class.
40 * </p>
[1294]41 * <p>The class holds references to the appropriate {@link ITaskInstanceScopeRule}s and calls
42 * their {@link ITaskInstanceScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)}
[1146]43 * method for each task in the task tree it is needed for. The general behavior of this class is
[809]44 * the following:
45 * <ol>
46 *   <li>
47 *     An instance of this class is created using the constructor and calling the
48 *     {@link #init()} method afterwards
49 *   </li>
50 *   <li>
[1146]51 *     then the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)}
52 *     method is called for a so far unstructured task
[809]53 *   </li>
54 *   <li>
55 *     the class iterates its internal list of rules and calls their
[1294]56 *     {@link ITaskInstanceScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)}
[809]57 *     method.
58 *   </li>
59 *   <li>
60 *     the class evaluates the rule application result
61 *     <ul>
62 *       <li>
63 *         if a rule returns a rule application result that is null, the next rule is tried
64 *       </li>
65 *       <li>
66 *         if a rule returns that it would be feasible if more data was available and the rule
67 *         application shall not be finalized (see finalize parameter of the applyRules method)
68 *         the rule application is broken up
69 *       </li>
70 *       <li>
71 *         if a rule returns, that it was applied, the same rule is applied again until it returns
[1146]72 *         null or feasible. For each newly created parent task provided in the rule application
73 *         result, the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)}
[809]74 *         method is called.
75 *       </li>
76 *     </ul>
77 *   </li>
78 * </ol>
[1146]79 * Through this, all rules are tried to be applied at least once to the provided parent task and
80 * all parent tasks created during the rule application.
[809]81 * </p>
[439]82 *
[809]83 * @author Patrick Harms
[439]84 */
[557]85public class TemporalRelationshipRuleManager {
86   
[809]87    /**
88     * <p>
[1146]89     * the task factory to be used during rule application
[809]90     * </p>
91     */
[1146]92    private ITaskFactory taskFactory;
[439]93
[557]94    /**
[809]95     * <p>
[1146]96     * the task builder to be used during rule application
[809]97     * </p>
[557]98     */
[1146]99    private ITaskBuilder taskBuilder;
[1107]100
101    /**
102     * <p>
103     * initialize the manager
104     * </p>
105     *
[1146]106     * @param taskFactory             the task factory to be used for instantiating new task tree
107     *                                tasks during rule application
108     * @param taskBuilder             the task builder to be used for linking tasks
[1107]109     *                                with each other during rule application
110     */
[1189]111    public TemporalRelationshipRuleManager(ITaskFactory taskFactory, ITaskBuilder taskBuilder) {
[557]112        super();
[1146]113        this.taskFactory = taskFactory;
114        this.taskBuilder = taskBuilder;
[557]115    }
[439]116
[557]117    /**
[809]118     * <p>
119     * initialized the temporal relationship rule manager by instantiating the known rules and
[1146]120     * providing them with a reference to the task equality manager or other information they need.
[809]121     * </p>
[557]122     */
123    public void init() {
[987]124        List<Class<? extends IGUIElement>> frameFilter =
125            new ArrayList<Class<? extends IGUIElement>>();
126        frameFilter.add(IFrame.class);
127        frameFilter.add(IDialog.class);
[1107]128        //frameFilter.add(ICanvas.class);
[557]129    }
[439]130
[557]131    /**
[809]132     * <p>
[1889]133     * applies only the known rules for task detection, i.e., currently only the sequence for task
134     * detection rule
135     * </p>
136     *
137     * @param sessions  the sessions to be processed
138     */
[2132]139    public void applyTaskDetectionRule(List<IUserSession> sessions,
140                                       TaskEquality       minimalTaskEquality,
141                                       int                minimumSequenceCoverage)
142    {
[1889]143        ISessionScopeRule[] rules = new ISessionScopeRule[] {
[2132]144            new SequenceForTaskDetectionRule(minimalTaskEquality, taskFactory, taskBuilder,
145                                             minimumSequenceCoverage)
[1889]146        };
147       
148        applyRules(rules, sessions, "");
149    }
150
151    /**
152     * <p>
153     * applies only the known rules for task merging, i.e., currently only the condense similar task
154     * rule
155     * </p>
156     *
157     * @param sessions  the sessions to be processed
158     */
159    public void applyTaskMergingRule(List<IUserSession> sessions) {
160        ISessionScopeRule[] rules = new ISessionScopeRule[] {
161            new CondenseSimilarTasksRule
162                (TaskEquality.SEMANTICALLY_EQUAL, taskFactory, taskBuilder)
163        };
164       
165        applyRules(rules, sessions, "");
166    }
167
168    /**
169     * <p>
[1146]170     * applies the known rules to the provided parent task. For the creation of further tasks,
171     * the provided builder and task factory are utilized. If the finalize parameter is true, the
[809]172     * rule application is finalized as far as possible without waiting for further data. If it is
173     * false, the rule application is broken up at the first rule returning, that its application
[1146]174     * would be feasible. The method calls itself for each parent task created through the rule
175     * application. In this case, the finalize parameter is always true.
[809]176     * </p>
[557]177     *
[1146]178     * @param parent       the parent task to apply the rules on
[809]179     * @param finalize     used to indicate, if the rule application shall break up if a rule would
180     *                     be feasible if further data was available, or not.
[1146]181     * @param logIndent    simply used for logging purposes to indent the log messages depending
182     *                     on the recursion depth of calling this method.
[557]183     */
[1146]184    private int applyRules(ISessionScopeRule[] rules,
185                           List<IUserSession>  sessions,
186                           String              logIndent)
187    {
188        Console.traceln
189            (Level.FINER, logIndent + "applying rules for " + sessions.size() + " sessions");
190
191        int noOfRuleApplications = 0;
192
193        for (ISessionScopeRule rule : rules) {
194            RuleApplicationResult result;
195            do {
196                Console.traceln(Level.FINER, logIndent + "trying rule " + rule);
197                result = rule.apply(sessions);
198
199                if ((result != null) &&
200                    (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED))
201                {
202                    Console.traceln(Level.FINE, logIndent + "applied rule " + rule);
203                    noOfRuleApplications++;
204                   
205                    //dumpTask(parent, "");
206                }
207            }
208            while ((result != null) &&
209                   (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED));
210
211        }
212
213        if (noOfRuleApplications <= 0) {
214            Console.traceln(Level.FINE, logIndent + "no rules applied --> no temporal " +
215                            "relationship generated");
216        }
217
218        return noOfRuleApplications;
[439]219    }
[557]220
221    /**
[809]222     *
223     */
[1146]224    /*private void dumpTask(ITask task, String indent) {
[987]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)) {
[1146]237            for (ITask child : task.getChildren()) {
[987]238                dumpTask(child, indent + "  ");
239            }
240        }
[1131]241    }*/
[439]242
243}
Note: See TracBrowser for help on using the repository browser.