source: branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SelectionComparisonRule.java

Last change on this file was 1734, checked in by rkrimmel, 10 years ago

Added automatically created javadoc, still needs to be commented properly though

  • Property svn:executable set to *
File size: 12.9 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.List;
18
19import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
20import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
21import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
22import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
23
24// TODO: Auto-generated Javadoc
25/**
26 * <p>
27 * this task comparison rule is capable of comparing selections. If both
28 * selections do not have children, they are treated as lexically equal. If they
29 * have children, each child of both selections is compared to each child of the
30 * respective other selection. The resulting equality is the most concrete one
31 * of all these comparisons. I.e. if all children are at least lexically equal,
32 * then the selections are lexically equal. If all children are at least
33 * syntactically equal, then the selections are syntactically equal. If all
34 * children are at least semantically equal, then the selections are
35 * semantically equal. If only one of the selections has children, then the
36 * selections are unequal. The comparison is broken up, if only a specific
37 * equality is checked for and this equality is ensured.
38 * </p>
39 *
40 * @author 2012, last modified by $Author: patrick$
41 * @version $Revision: $ $Date: 19.02.2012$
42 */
43public class SelectionComparisonRule implements TaskComparisonRule {
44
45        /*
46         * (non-Javadoc)
47         *
48         * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask)
49         */
50        @Override
51        public boolean areLexicallyEqual(ITask task1, ITask task2) {
52                final TaskEquality equality = getEquality(task1, task2,
53                                TaskEquality.LEXICALLY_EQUAL);
54                return (equality != null)
55                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
56        }
57
58        /*
59         * (non-Javadoc)
60         *
61         * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance)
62         */
63        @Override
64        public boolean areLexicallyEqual(ITaskInstance instance1,
65                        ITaskInstance instance2) {
66                final TaskEquality equality = getEquality(instance1, instance2,
67                                TaskEquality.LEXICALLY_EQUAL);
68                return (equality != null)
69                                && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
70        }
71
72        /*
73         * (non-Javadoc)
74         *
75         * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask)
76         */
77        @Override
78        public boolean areSemanticallyEqual(ITask task1, ITask task2) {
79                final TaskEquality equality = getEquality(task1, task2,
80                                TaskEquality.SEMANTICALLY_EQUAL);
81                return (equality != null)
82                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
83        }
84
85        /*
86         * (non-Javadoc)
87         *
88         * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance,
89         * ITaskInstance)
90         */
91        @Override
92        public boolean areSemanticallyEqual(ITaskInstance instance1,
93                        ITaskInstance instance2) {
94                final TaskEquality equality = getEquality(instance1, instance2,
95                                TaskEquality.SEMANTICALLY_EQUAL);
96                return (equality != null)
97                                && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
98        }
99
100        /*
101         * (non-Javadoc)
102         *
103         * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask)
104         */
105        @Override
106        public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
107                final TaskEquality equality = getEquality(task1, task2,
108                                TaskEquality.SYNTACTICALLY_EQUAL);
109                return (equality != null)
110                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
111        }
112
113        /*
114         * (non-Javadoc)
115         *
116         * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance,
117         * ITaskInstance)
118         */
119        @Override
120        public boolean areSyntacticallyEqual(ITaskInstance instance1,
121                        ITaskInstance instance2) {
122                final TaskEquality equality = getEquality(instance1, instance2,
123                                TaskEquality.SYNTACTICALLY_EQUAL);
124                return (equality != null)
125                                && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
126        }
127
128        /**
129         * <p>
130         * used to to call the task equality rule manager for the comparison of the
131         * two provided children. If no required equality level is provided, than
132         * the most concrete equality is returned. Otherwise, the required equality
133         * is returned as long as the children are equal on that level.
134         * </p>
135         *
136         * @param child1
137         *            the first task to be compared
138         * @param child2
139         *            the second task to be compared
140         * @param requiredEqualityLevel
141         *            the equality level to be checked for
142         *
143         * @return the determined equality
144         */
145        private TaskEquality callRuleManager(ITask child1, ITask child2,
146                        TaskEquality requiredEqualityLevel) {
147                if (requiredEqualityLevel == null) {
148                        return TaskEqualityRuleManager.getInstance()
149                                        .compare(child1, child2);
150                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual(
151                                child1, child2, requiredEqualityLevel)) {
152                        return requiredEqualityLevel;
153                } else {
154                        return TaskEquality.UNEQUAL;
155                }
156        }
157
158        /**
159         * <p>
160         * used to to call the task equality rule manager for the comparison of the
161         * two provided children. If no required equality level is provided, than
162         * the most concrete equality is returned. Otherwise, the required equality
163         * is returned as long as the children are equal on that level.
164         * </p>
165         *
166         * @param taskInstance1
167         *            the first task instance to be compared
168         * @param taskInstance2
169         *            the second task instance to be compared
170         * @param requiredEqualityLevel
171         *            the equality level to be checked for
172         *
173         * @return the determined equality
174         */
175        private TaskEquality callRuleManager(ITaskInstance taskInstance1,
176                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) {
177                if (requiredEqualityLevel == null) {
178                        return TaskEqualityRuleManager.getInstance().compare(taskInstance1,
179                                        taskInstance2);
180                } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual(
181                                taskInstance1, taskInstance2, requiredEqualityLevel)) {
182                        return requiredEqualityLevel;
183                } else {
184                        return TaskEquality.UNEQUAL;
185                }
186        }
187
188        /**
189         * <p>
190         * ensures for the two given lists, that for at least one task in the first
191         * list there is a task in the second list being on the given level equal to
192         * the task in the first list.
193         * </p>
194         *
195         * @param children1
196         *            the first list to be compared
197         * @param children2
198         *            the second list to be compared
199         * @param requiredEqualityLevel
200         *            the equality level to be checked for
201         *
202         * @return true if there is a task in the first list that has an equal task
203         *         in the second list when considering the given equality level,
204         *         false else.
205         */
206        private boolean checkEqualityLevel(List<ITask> children1,
207                        List<ITask> children2, TaskEquality requiredEqualityLevel) {
208                TaskEquality currentEquality;
209                for (final ITask child1 : children1) {
210                        for (final ITask child2 : children2) {
211                                currentEquality = callRuleManager(child1, child2,
212                                                requiredEqualityLevel);
213                                if ((currentEquality != null)
214                                                && (currentEquality.isAtLeast(requiredEqualityLevel))) {
215                                        // we found at least one equal child with sufficient
216                                        // equality in the
217                                        // second list. So be can break up for this child.
218                                        return true;
219                                }
220                        }
221                }
222
223                return false;
224        }
225
226        /*
227         * (non-Javadoc)
228         *
229         * @see TaskComparisonRule#compare(ITask, ITask)
230         */
231        @Override
232        public TaskEquality compare(ITask task1, ITask task2) {
233                return getEquality(task1, task2, null);
234        }
235
236        /*
237         * (non-Javadoc)
238         *
239         * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance)
240         */
241        @Override
242        public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) {
243                return getEquality(instance1, instance2, null);
244        }
245
246        /**
247         * <p>
248         * compares two selections with each other checking for the provided
249         * required level of equality. If this level is ensured, the method
250         * immediately returns. The more concrete the required equality level, the
251         * more checks this method performs.
252         * </p>
253         *
254         * @param task1
255         *            the first task to be compared
256         * @param task2
257         *            the second task to be compared
258         * @param requiredEqualityLevel
259         *            the equality level to be checked for
260         *
261         * @return the determined equality.
262         */
263        private TaskEquality getEquality(ITask task1, ITask task2,
264                        TaskEquality requiredEqualityLevel) {
265                final List<ITask> children1 = ((ISelection) task1).getChildren();
266                final List<ITask> children2 = ((ISelection) task2).getChildren();
267
268                // if both selections do not have children, they are lexically equal. If
269                // only one of them
270                // has children, they are unequal.
271                if ((children1.size() == 0) && (children2.size() == 0)) {
272                        return TaskEquality.LEXICALLY_EQUAL;
273                } else if ((children1.size() == 0) || (children2.size() == 0)) {
274                        return TaskEquality.UNEQUAL;
275                }
276
277                if (requiredEqualityLevel == null) {
278                        // calculate the common equality level for all children of both
279                        // selections.
280                        // do it in both directions to ensure commutative comparison
281                        return getMostConcreteEqualityLevel(children1, children2);
282                } else {
283                        // we are searching for a specific equality
284                        if (checkEqualityLevel(children1, children2, requiredEqualityLevel)) {
285                                return requiredEqualityLevel;
286                        } else {
287                                return TaskEquality.UNEQUAL;
288                        }
289                }
290        }
291
292        /**
293         * <p>
294         * compares two selection instances with each other checking for the
295         * provided required level of equality. If this level is ensured, the method
296         * immediately returns. The more concrete the required equality level, the
297         * more checks this method performs.
298         * </p>
299         *
300         * @param taskInstance1
301         *            the first task instance to be compared
302         * @param taskInstance2
303         *            the second task instance to be compared
304         * @param requiredEqualityLevel
305         *            the equality level to be checked for
306         *
307         * @return the determined equality.
308         */
309        private TaskEquality getEquality(ITaskInstance taskInstance1,
310                        ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) {
311                final ITaskInstance child1 = ((ISelectionInstance) taskInstance1)
312                                .getChild();
313                final ITaskInstance child2 = ((ISelectionInstance) taskInstance2)
314                                .getChild();
315
316                // if both selections do not have children, they are lexically equal. If
317                // only one of them
318                // has children, they are unequal.
319                if ((child1 == null) && (child2 == null)) {
320                        return TaskEquality.LEXICALLY_EQUAL;
321                } else if ((child1 == null) || (child2 == null)) {
322                        return TaskEquality.UNEQUAL;
323                }
324
325                final TaskEquality equality = callRuleManager(child1, child2,
326                                requiredEqualityLevel);
327
328                if (equality == TaskEquality.IDENTICAL) {
329                        // two different selection instances can be at most lexically equal
330                        // even if their
331                        // children are identical
332                        return TaskEquality.LEXICALLY_EQUAL;
333                } else {
334                        return equality;
335                }
336        }
337
338        /**
339         * <p>
340         * determines the most concrete equality level for all tasks in the first
341         * list compared to all tasks in the second list. It is sufficient, if there
342         * is one task in one list for which there exist an equal task in the other
343         * list.
344         * </p>
345         *
346         * @param children1
347         *            the first list to be compared
348         * @param children2
349         *            the second list to be compared
350         *
351         * @return the most concrete task equality identified for all tasks in the
352         *         first list with respect to the second list
353         */
354        private TaskEquality getMostConcreteEqualityLevel(List<ITask> children1,
355                        List<ITask> children2) {
356                TaskEquality childEquality;
357                TaskEquality currentEquality;
358                for (final ITask child1 : children1) {
359                        childEquality = null;
360                        for (final ITask child2 : children2) {
361                                currentEquality = callRuleManager(child1, child2, null);
362                                if ((currentEquality != null)
363                                                && (currentEquality != TaskEquality.UNEQUAL)) {
364                                        if (childEquality == null) {
365                                                childEquality = currentEquality;
366                                        } else {
367                                                childEquality = childEquality
368                                                                .getCommonDenominator(currentEquality);
369                                        }
370
371                                        if (childEquality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)) {
372                                                // as we calculate the most concrete equality, we can
373                                                // break up here
374                                                return TaskEquality.LEXICALLY_EQUAL;
375                                        }
376                                }
377                        }
378                }
379
380                // as the comparison should be commutative, we do not need to check, if
381                // in list 2 there is
382                // a child equal to one in list 1
383                return TaskEquality.UNEQUAL;
384        }
385
386        /*
387         * (non-Javadoc)
388         *
389         * @see TaskComparisonRule#isApplicable(ITask, ITask)
390         */
391        @Override
392        public boolean isApplicable(ITask task1, ITask task2) {
393                return (task1 instanceof ISelection) && (task2 instanceof ISelection);
394        }
395
396        /*
397         * (non-Javadoc)
398         *
399         * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance)
400         */
401        @Override
402        public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) {
403                return isApplicable(instance1.getTask(), instance2.getTask());
404        }
405}
Note: See TracBrowser for help on using the repository browser.