source: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEqualityRuleManager.java @ 1294

Last change on this file since 1294 was 1294, checked in by pharms, 11 years ago
  • rework of task model to move event instance stuff to task instances
  • introduction of sequence, selection, iteration and optional instances
  • Property svn:executable set to *
File size: 17.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.taskequality;
16
17import java.util.ArrayList;
18import java.util.List;
19
20import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
21import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
22
23/**
24 * <p>
25 * The task equality rule manager is capable of comparing tasks and task instances based on its
26 * internal list of comparison rules. These rules are asked for comparing the two provided tasks or
27 * task instance. If a rule returns a task equality other than null, this equality is returned.
28 * Otherwise the next rule is asked.
29 * </p>
30 *
31 * @author Patrick Harms
32 */
33public class TaskEqualityRuleManager {
34   
35    /**
36     * <p>
37     * the singleton instance of this class
38     * </p>
39     */
40    private static final TaskEqualityRuleManager instance = new TaskEqualityRuleManager();
41
42    /**
43     * <p>
44     * the rules that can be used for comparing tasks
45     * </p>
46     */
47    private List<TaskComparisonRule> mRuleIndex = null;
48
49    /**
50     * <p>
51     * initializes the task equality rule manager by filling the internal list of comparison rules.
52     * </p>
53     */
54    private TaskEqualityRuleManager() {
55        mRuleIndex = new ArrayList<TaskComparisonRule>();
56        mRuleIndex.add(new TaskIdentityRule());
57        mRuleIndex.add(new GUIEventTaskComparisonRule());
58        mRuleIndex.add(new EventTaskComparisonRule());
59        mRuleIndex.add(new IterationComparisonRule());
60        mRuleIndex.add(new SequenceComparisonRule());
61        mRuleIndex.add(new SelectionComparisonRule());
62        mRuleIndex.add(new TaskAndIterationComparisonRule());
63        mRuleIndex.add(new TaskAndSelectionComparisonRule());
64    }
65
66
67    /**
68     * <p>
69     * returns the singleton instance of this class
70     * </p>
71     *
72     * @return as described
73     */
74    public static TaskEqualityRuleManager getInstance() {
75        return instance;
76    }
77
78    /**
79     * <p>
80     * this method performs a comparison of the two provided tasks. It iterates its internal
81     * comparison rules. If the first rule returns a task equality other than null,
82     * this equality is returned. Otherwise the next rule is tried. If no rule returns an equality
83     * <code>NodeEquality.UNEQUAL</code> is returned.
84     * </p>
85     *
86     * @param task1 the first task to be compared
87     * @param task2 the second task to be compared
88     *
89     * @return as described
90     *
91     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
92     *                               manager before a call to this method.
93     */
94    public TaskEquality compare(ITask task1, ITask task2)
95        throws IllegalStateException
96    {
97        if (mRuleIndex == null) {
98            throw new IllegalStateException("not initialized");
99        }
100       
101        // LOG.info("checking for equality of " + task1 + " and " + task2);
102        TaskEquality taskEquality = null;
103
104        for (TaskComparisonRule rule : mRuleIndex) {
105            if (rule.isApplicable(task1, task2)) {
106                taskEquality = rule.compare(task1, task2);
107                if (taskEquality != null) {
108                    // LOG.warning("used rule " + rule + " for equality check");
109                    return taskEquality;
110                }
111            }
112        }
113
114        // LOG.warning("no rule could be applied --> handling tasks as unequal");
115
116        return TaskEquality.UNEQUAL;
117    }
118
119    /**
120     * <p>
121     * this method two tasks with respect to the fiven equality level and returns true, if this
122     * level is given.
123     * </p>
124     *
125     * @param task1         the first task to be compared
126     * @param task2         the second task to be compared
127     * @param equalityLevel the level of equality to be checked for
128     *
129     * @return as described
130     *
131     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
132     *                               manager before a call to this method.
133     */
134    public boolean areAtLeastEqual(ITask task1, ITask task2, TaskEquality equalityLevel) {
135        if (equalityLevel == null) {
136            throw new IllegalArgumentException("required equality level must not be null");
137        }
138       
139        switch (equalityLevel) {
140            case IDENTICAL:
141                return areIdentical(task1, task2);
142            case LEXICALLY_EQUAL:
143                return areLexicallyEqual(task1, task2);
144            case SYNTACTICALLY_EQUAL:
145                return areSyntacticallyEqual(task1, task2);
146            case SEMANTICALLY_EQUAL:
147                return areSemanticallyEqual(task1, task2);
148            case UNEQUAL:
149                return !areSemanticallyEqual(task1, task2);
150            default:
151                throw new IllegalArgumentException("unknown required equality: " + equalityLevel);
152        }
153    }
154
155    /**
156     * <p>
157     * this method checks if the two given tasks are identical. For this, it iterates its internal
158     * comparison rules. If the first rule returns true, than this method returns true as well.
159     * If no rule returns true, this method returns false.
160     * </p>
161     *
162     * @param task1 the first task to be compared
163     * @param task2 the second task to be compared
164     *
165     * @return as described
166     *
167     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
168     *                               manager before a call to this method.
169     */
170    public boolean areIdentical(ITask task1, ITask task2) {
171        if (mRuleIndex == null) {
172            throw new IllegalStateException("not initialized");
173        }
174       
175        for (TaskComparisonRule rule : mRuleIndex) {
176            if (rule.isApplicable(task1, task2) && rule.areLexicallyEqual(task1, task2)) {
177                 return true;
178            }
179        }
180
181        return false;
182    }
183
184    /**
185     * <p>
186     * this method checks if the two given tasks are lexically equal. For this, it iterates its
187     * internal comparison rules. If the first rule returns true, than this method returns true
188     * as well. If no rule returns true, this method returns false.
189     * </p>
190     *
191     * @param task1 the first task to be compared
192     * @param task2 the second task to be compared
193     *
194     * @return as described
195     *
196     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
197     *                               manager before a call to this method.
198     */
199    public boolean areLexicallyEqual(ITask task1, ITask task2) {
200        if (mRuleIndex == null) {
201            throw new IllegalStateException("not initialized");
202        }
203       
204        for (TaskComparisonRule rule : mRuleIndex) {
205            if (rule.isApplicable(task1, task2) && rule.areLexicallyEqual(task1, task2)) {
206                 return true;
207            }
208        }
209
210        return false;
211    }
212
213    /**
214     * <p>
215     * this method checks if the two given tasks are syntactically equal. For this, it iterates its
216     * internal comparison rules. If the first rule returns true, than this method returns true
217     * as well. If no rule returns true, this method returns false.
218     * </p>
219     *
220     * @param task1 the first task to be compared
221     * @param task2 the second task to be compared
222     *
223     * @return as described
224     *
225     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
226     *                               manager before a call to this method.
227     */
228    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
229        if (mRuleIndex == null) {
230            throw new IllegalStateException("not initialized");
231        }
232       
233        for (TaskComparisonRule rule : mRuleIndex) {
234            if (rule.isApplicable(task1, task2) && rule.areSyntacticallyEqual(task1, task2)) {
235                 return true;
236            }
237        }
238
239        return false;
240    }
241
242    /**
243     * <p>
244     * this method checks if the two given tasks are semantically equal. For this, it iterates its
245     * internal comparison rules. If the first rule returns true, than this method returns true
246     * as well. If no rule returns true, this method returns false.
247     * </p>
248     *
249     * @param task1 the first task to be compared
250     * @param task2 the second task to be compared
251     *
252     * @return as described
253     *
254     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
255     *                               manager before a call to this method.
256     */
257    public boolean areSemanticallyEqual(ITask task1, ITask task2) {
258        if (mRuleIndex == null) {
259            throw new IllegalStateException("not initialized");
260        }
261       
262        for (TaskComparisonRule rule : mRuleIndex) {
263            if (rule.isApplicable(task1, task2) && rule.areSemanticallyEqual(task1, task2)) {
264                 return true;
265            }
266        }
267
268        return false;
269    }
270
271    /**
272     * <p>
273     * this method performs a comparison of the two provided task instances. It iterates its
274     * internal comparison rules. If the first rule returns a task instance equality other than
275     * null, this equality is returned. Otherwise the next rule is tried. If no rule returns an
276     * equality <code>TaskEquality.UNEQUAL</code> is returned.
277     * </p>
278     *
279     * @param instance1 the first task instance to be compared
280     * @param instance2 the second task instance to be compared
281     *
282     * @return as described
283     *
284     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
285     *                               manager before a call to this method.
286     */
287    public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2)
288        throws IllegalStateException
289    {
290        if (mRuleIndex == null) {
291            throw new IllegalStateException("not initialized");
292        }
293       
294        // LOG.info("checking for equality of " + instance1 + " and " + instance2);
295        TaskEquality instanceEquality = null;
296
297        for (TaskComparisonRule rule : mRuleIndex) {
298            if (rule.isApplicable(instance1, instance2)) {
299                instanceEquality = rule.compare(instance1, instance2);
300                if (instanceEquality != null) {
301                    // LOG.warning("used rule " + rule + " for equality check");
302                    return instanceEquality;
303                }
304            }
305        }
306
307        // LOG.warning("no rule could be applied --> handling tasks as unequal");
308
309        return TaskEquality.UNEQUAL;
310    }
311
312    /**
313     * <p>
314     * this method compares two task instances with respect to the given equality level and returns
315     * true, if this level is given.
316     * </p>
317     *
318     * @param instance1     the first task instance to be compared
319     * @param instance2     the second task instance to be compared
320     * @param equalityLevel the level of equality to be checked for
321     *
322     * @return as described
323     *
324     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
325     *                               manager before a call to this method.
326     */
327    public boolean areAtLeastEqual(ITaskInstance        instance1,
328                                   ITaskInstance        instance2,
329                                   TaskEquality equalityLevel)
330    {
331        if (equalityLevel == null) {
332            throw new IllegalArgumentException("required equality level must not be null");
333        }
334       
335        switch (equalityLevel) {
336            case IDENTICAL:
337                return areIdentical(instance1, instance2);
338            case LEXICALLY_EQUAL:
339                return areLexicallyEqual(instance1, instance2);
340            case SYNTACTICALLY_EQUAL:
341                return areSyntacticallyEqual(instance1, instance2);
342            case SEMANTICALLY_EQUAL:
343                return areSemanticallyEqual(instance1, instance2);
344            case UNEQUAL:
345                return !areSemanticallyEqual(instance1, instance2);
346            default:
347                throw new IllegalArgumentException("unknown required equality: " + equalityLevel);
348        }
349    }
350
351    /**
352     * <p>
353     * this method checks if the two given task instances are identical. For this, it iterates its
354     * internal comparison rules. If the first rule returns true, than this method returns true
355     * as well. If no rule returns true, this method returns false.
356     * </p>
357     *
358     * @param instance1 the first task instance to be compared
359     * @param instance2 the second task instance to be compared
360     *
361     * @return as described
362     *
363     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
364     *                               manager before a call to this method.
365     */
366    public boolean areIdentical(ITaskInstance instance1, ITaskInstance instance2) {
367        if (mRuleIndex == null) {
368            throw new IllegalStateException("not initialized");
369        }
370       
371        for (TaskComparisonRule rule : mRuleIndex) {
372            if (rule.isApplicable(instance1, instance2) &&
373                rule.areLexicallyEqual(instance1, instance2))
374            {
375                return true;
376            }
377        }
378
379        return false;
380    }
381
382    /**
383     * <p>
384     * this method checks if the two given task instances are lexically equal. For this, it
385     * iterates its internal comparison rules. If the first rule returns true, than this method
386     * returns true, as well. If no rule returns true, this method returns false.
387     * </p>
388     *
389     * @param instance1 the first task instance to be compared
390     * @param instance2 the second task instance to be compared
391     *
392     * @return as described
393     *
394     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
395     *                               manager before a call to this method.
396     */
397    public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
398        if (mRuleIndex == null) {
399            throw new IllegalStateException("not initialized");
400        }
401       
402        for (TaskComparisonRule rule : mRuleIndex) {
403            if (rule.isApplicable(instance1, instance2) &&
404                rule.areLexicallyEqual(instance1, instance2))
405            {
406                return true;
407            }
408        }
409
410        return false;
411    }
412
413    /**
414     * <p>
415     * this method checks if the two given task instances are syntactically equal. For this, it
416     * iterates its internal comparison rules. If the first rule returns true, than this method
417     * returns true, as well. If no rule returns true, this method returns false.
418     * </p>
419     *
420     * @param instance1 the first task instance to be compared
421     * @param instance2 the second task instance to be compared
422     *
423     * @return as described
424     *
425     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
426     *                               manager before a call to this method.
427     */
428    public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
429        if (mRuleIndex == null) {
430            throw new IllegalStateException("not initialized");
431        }
432       
433        for (TaskComparisonRule rule : mRuleIndex) {
434            if (rule.isApplicable(instance1, instance2) &&
435                rule.areSyntacticallyEqual(instance1, instance2))
436            {
437                return true;
438            }
439        }
440
441        return false;
442    }
443
444    /**
445     * <p>
446     * this method checks if the two given task instances are semantically equal. For this, it
447     * iterates its internal comparison rules. If the first rule returns true, than this method
448     * returns true, as well. If no rule returns true, this method returns false.
449     * </p>
450     *
451     * @param instance1 the first task instance to be compared
452     * @param instance2 the second task instance to be compared
453     *
454     * @return as described
455     *
456     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
457     *                               manager before a call to this method.
458     */
459    public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
460        if (mRuleIndex == null) {
461            throw new IllegalStateException("not initialized");
462        }
463       
464        for (TaskComparisonRule rule : mRuleIndex) {
465            if (rule.isApplicable(instance1, instance2) &&
466                rule.areSemanticallyEqual(instance1, instance2))
467            {
468                 return true;
469            }
470        }
471
472        return false;
473    }
474
475}
Note: See TracBrowser for help on using the repository browser.