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

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