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

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