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

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

Used Eclipse code cleanup

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