// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.tasktrees.temporalrelation; import java.util.List; import java.util.logging.Level; import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEquality; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory; import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; import de.ugoe.cs.util.console.Console; /** * TODO update comment * *

* This class is responsible for applying temporal relationship rules on a task tree. Through this, * a flat task tree is restructured to have more depth but to include more temporal relationships * between tasks which are not only a major sequence. I.e. through the application of the * rules iterations and selections of tasks are detected. Which kind of temporal relations * between tasks are detected depends on the {@link ITaskInstanceScopeRule}s known to * this class. *

*

The class holds references to the appropriate {@link ITaskInstanceScopeRule}s and calls * their {@link ITaskInstanceScopeRule#apply(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance)} * method for each task in the task tree it is needed for. The general behavior of this class is * the following: *

*
    *
  1. * An instance of this class is created using the constructor and calling the * {@link #init()} method afterwards *
  2. *
  3. * then the {@link #applyTaskDetectionRule(List, TaskEquality, int)} * method is called for a so far unstructured task *
  4. *
  5. * the class iterates its internal list of rules and calls their * {@link ITaskInstanceScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)} * method. *
  6. *
  7. * the class evaluates the rule application result * *
  8. *
*

* Through this, all rules are tried to be applied at least once to the provided parent task and * all parent tasks created during the rule application. *

* * @author Patrick Harms */ public class TemporalRelationshipRuleManager { /** *

* the task factory to be used during rule application *

*/ private ITaskFactory taskFactory; /** *

* the task builder to be used during rule application *

*/ private ITaskBuilder taskBuilder; /** *

* initialize the manager *

* * @param taskFactory the task factory to be used for instantiating new task tree * tasks during rule application * @param taskBuilder the task builder to be used for linking tasks * with each other during rule application */ public TemporalRelationshipRuleManager(ITaskFactory taskFactory, ITaskBuilder taskBuilder) { super(); this.taskFactory = taskFactory; this.taskBuilder = taskBuilder; } /** *

* applies only the known rules for task detection, i.e., currently only the sequence for task * detection rule *

* * @param sessions the sessions to be processed */ public void applyTaskDetectionRule(List sessions, TaskEquality minimalTaskEquality, int minimumSequenceCoverage) { ISessionScopeRule[] rules = new ISessionScopeRule[] { new SequenceForTaskDetectionRule(minimalTaskEquality, taskFactory, taskBuilder, minimumSequenceCoverage) }; applyRules(rules, sessions, ""); } /** *

* applies only the known rules for task merging, i.e., currently only the condense similar task * rule *

* * @param sessions the sessions to be processed */ public void applyTaskMergingRule(List sessions) { ISessionScopeRule[] rules = new ISessionScopeRule[] { new CondenseSimilarTasksRule (TaskEquality.SEMANTICALLY_EQUAL, taskFactory, taskBuilder) }; applyRules(rules, sessions, ""); } /** *

* applies the known rules to the provided parent task. For the creation of further tasks, * the provided builder and task factory are utilized. If the finalize parameter is true, the * rule application is finalized as far as possible without waiting for further data. If it is * false, the rule application is broken up at the first rule returning, that its application * would be feasible. The method calls itself for each parent task created through the rule * application. In this case, the finalize parameter is always true. *

* * @param parent the parent task to apply the rules on * @param finalize used to indicate, if the rule application shall break up if a rule would * be feasible if further data was available, or not. * @param logIndent simply used for logging purposes to indent the log messages depending * on the recursion depth of calling this method. */ private int applyRules(ISessionScopeRule[] rules, List sessions, String logIndent) { Console.traceln (Level.FINER, logIndent + "applying rules for " + sessions.size() + " sessions"); int noOfRuleApplications = 0; for (ISessionScopeRule rule : rules) { RuleApplicationResult result; do { Console.traceln(Level.FINER, logIndent + "trying rule " + rule); result = rule.apply(sessions); if ((result != null) && (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)) { Console.traceln(Level.FINE, logIndent + "applied rule " + rule); noOfRuleApplications++; //dumpTask(parent, ""); } } while ((result != null) && (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)); } if (noOfRuleApplications <= 0) { Console.traceln(Level.FINE, logIndent + "no rules applied --> no temporal " + "relationship generated"); } return noOfRuleApplications; } /** * */ /*private void dumpTask(ITask task, String indent) { StringBuffer message = new StringBuffer(); message.append(indent); message.append(task); if (task.getDescription() != null) { message.append('('); message.append(task.getDescription()); message.append(')'); } Console.traceln(Level.FINER, message.toString()); if ((task.getChildren() != null) && (task.getChildren().size() > 0)) { for (ITask child : task.getChildren()) { dumpTask(child, indent + " "); } } }*/ }