Changeset 1733 for branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality
- Timestamp:
- 09/05/14 19:33:12 (10 years ago)
- Location:
- branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/EventTaskComparisonRule.java
r1294 r1733 24 24 /** 25 25 * <p> 26 * This rule identifies two tasks as lexically equal, if they are both event tasks and27 * if their respective event types and targets equal.26 * This rule identifies two tasks as lexically equal, if they are both event 27 * tasks and if their respective event types and targets equal. 28 28 * </p> 29 29 * … … 31 31 */ 32 32 public class EventTaskComparisonRule implements TaskComparisonRule { 33 34 /* (non-Javadoc)35 * @see TaskComparisonRule#isApplicable(ITask, ITask)36 */37 @Override38 public boolean isApplicable(ITask task1, ITask task2) {39 return (task1 instanceof IEventTask) && (task2 instanceof IEventTask);40 }41 33 42 /* (non-Javadoc) 43 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 44 */ 45 @Override 46 public boolean areLexicallyEqual(ITask task1, ITask task2) { 47 Collection<ITaskInstance> taskInstances1 = task1.getInstances(); 48 Collection<ITaskInstance> taskInstances2 = task2.getInstances(); 49 50 for (ITaskInstance instance1 : taskInstances1) { 51 boolean found = false; 52 53 for (ITaskInstance instance2 : taskInstances2) { 54 if (areLexicallyEqual(instance1, instance2)) { 55 found = true; 56 break; 57 } 58 } 59 60 if (!found) { 61 return false; 62 } 63 } 64 65 return true; 66 } 34 /* 35 * (non-Javadoc) 36 * 37 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 38 */ 39 @Override 40 public boolean areLexicallyEqual(ITask task1, ITask task2) { 41 final Collection<ITaskInstance> taskInstances1 = task1.getInstances(); 42 final Collection<ITaskInstance> taskInstances2 = task2.getInstances(); 67 43 68 /* (non-Javadoc) 69 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 70 */ 71 @Override 72 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 73 return areLexicallyEqual(task1, task2); 74 } 44 for (final ITaskInstance instance1 : taskInstances1) { 45 boolean found = false; 75 46 76 /* (non-Javadoc) 77 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 78 */ 79 @Override 80 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 81 return areLexicallyEqual(task1, task2); 82 } 47 for (final ITaskInstance instance2 : taskInstances2) { 48 if (areLexicallyEqual(instance1, instance2)) { 49 found = true; 50 break; 51 } 52 } 83 53 84 /* (non-Javadoc) 85 * @see TaskComparisonRule#compare(ITask, ITask) 86 */ 87 @Override 88 public TaskEquality compare(ITask task1, ITask task2) { 89 if (areLexicallyEqual(task1, task2)) { 90 return TaskEquality.LEXICALLY_EQUAL; 91 } 92 else { 93 return TaskEquality.UNEQUAL; 94 } 95 } 54 if (!found) { 55 return false; 56 } 57 } 96 58 97 98 /* (non-Javadoc) 99 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 100 */ 101 @Override 102 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 103 return 104 (instance1 instanceof IEventTaskInstance) && (instance2 instanceof IEventTaskInstance); 105 } 59 return true; 60 } 106 61 107 /* (non-Javadoc) 108 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 109 */ 110 @Override 111 public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 112 IEventTaskInstance eventTask1 = (IEventTaskInstance) instance1; 113 IEventTaskInstance eventTask2 = (IEventTaskInstance) instance2; 114 115 return (eventTask1.getEvent().getType().equals(eventTask2.getEvent().getType()) && 116 eventTask1.getEvent().getTarget().equals(eventTask2.getEvent().getTarget())); 117 } 62 /* 63 * (non-Javadoc) 64 * 65 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 66 */ 67 @Override 68 public boolean areLexicallyEqual(ITaskInstance instance1, 69 ITaskInstance instance2) { 70 final IEventTaskInstance eventTask1 = (IEventTaskInstance) instance1; 71 final IEventTaskInstance eventTask2 = (IEventTaskInstance) instance2; 118 72 119 /* (non-Javadoc) 120 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 121 */ 122 @Override 123 public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 124 return areLexicallyEqual(instance1, instance2); 125 } 73 return (eventTask1.getEvent().getType() 74 .equals(eventTask2.getEvent().getType()) && eventTask1 75 .getEvent().getTarget() 76 .equals(eventTask2.getEvent().getTarget())); 77 } 126 78 127 /* (non-Javadoc) 128 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 129 */ 130 @Override 131 public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 132 return areLexicallyEqual(instance1, instance2); 133 } 79 /* 80 * (non-Javadoc) 81 * 82 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 83 */ 84 @Override 85 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 86 return areLexicallyEqual(task1, task2); 87 } 134 88 135 /* (non-Javadoc) 136 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 137 */ 138 @Override 139 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 140 if (areLexicallyEqual(instance1, instance2)) { 141 return TaskEquality.LEXICALLY_EQUAL; 142 } 143 else { 144 return TaskEquality.UNEQUAL; 145 } 146 } 89 /* 90 * (non-Javadoc) 91 * 92 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 93 * ITaskInstance) 94 */ 95 @Override 96 public boolean areSemanticallyEqual(ITaskInstance instance1, 97 ITaskInstance instance2) { 98 return areLexicallyEqual(instance1, instance2); 99 } 100 101 /* 102 * (non-Javadoc) 103 * 104 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 105 */ 106 @Override 107 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 108 return areLexicallyEqual(task1, task2); 109 } 110 111 /* 112 * (non-Javadoc) 113 * 114 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 115 * ITaskInstance) 116 */ 117 @Override 118 public boolean areSyntacticallyEqual(ITaskInstance instance1, 119 ITaskInstance instance2) { 120 return areLexicallyEqual(instance1, instance2); 121 } 122 123 /* 124 * (non-Javadoc) 125 * 126 * @see TaskComparisonRule#compare(ITask, ITask) 127 */ 128 @Override 129 public TaskEquality compare(ITask task1, ITask task2) { 130 if (areLexicallyEqual(task1, task2)) { 131 return TaskEquality.LEXICALLY_EQUAL; 132 } else { 133 return TaskEquality.UNEQUAL; 134 } 135 } 136 137 /* 138 * (non-Javadoc) 139 * 140 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 141 */ 142 @Override 143 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 144 if (areLexicallyEqual(instance1, instance2)) { 145 return TaskEquality.LEXICALLY_EQUAL; 146 } else { 147 return TaskEquality.UNEQUAL; 148 } 149 } 150 151 /* 152 * (non-Javadoc) 153 * 154 * @see TaskComparisonRule#isApplicable(ITask, ITask) 155 */ 156 @Override 157 public boolean isApplicable(ITask task1, ITask task2) { 158 return (task1 instanceof IEventTask) && (task2 instanceof IEventTask); 159 } 160 161 /* 162 * (non-Javadoc) 163 * 164 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 165 */ 166 @Override 167 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 168 return (instance1 instanceof IEventTaskInstance) 169 && (instance2 instanceof IEventTaskInstance); 170 } 147 171 148 172 } -
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/GUIEventTaskComparisonRule.java
r1294 r1733 50 50 * <p> 51 51 * This rule compares GUI event tasks (i.e. it is more concrete, than the 52 * {@link EventTaskComparisonRule}). Two GUI event tasks are only equal if their event type and 53 * target are equal. The returned equality is even more fine-grained for events whose type is 54 * {@link TextInput} and {@link ValueSelection}. For text inputs, lexical equality is returned if 55 * the same text is entered using the same key interactions. Syntactical equality is returned if 56 * the same text is entered using different key interactions. Semantical equality is returned if 57 * different text is entered, but into the same event target. Value selections are syntactically 58 * equal, if the same value is selected. Otherwise they are semantically equal. 52 * {@link EventTaskComparisonRule}). Two GUI event tasks are only equal if their 53 * event type and target are equal. The returned equality is even more 54 * fine-grained for events whose type is {@link TextInput} and 55 * {@link ValueSelection}. For text inputs, lexical equality is returned if the 56 * same text is entered using the same key interactions. Syntactical equality is 57 * returned if the same text is entered using different key interactions. 58 * Semantical equality is returned if different text is entered, but into the 59 * same event target. Value selections are syntactically equal, if the same 60 * value is selected. Otherwise they are semantically equal. 59 61 * </p> 60 62 * … … 62 64 */ 63 65 public class GUIEventTaskComparisonRule implements TaskComparisonRule { 64 65 /* (non-Javadoc) 66 * @see TaskComparisonRule#isApplicable(ITask, ITask) 67 */ 68 @Override 69 public boolean isApplicable(ITask task1, ITask task2) { 70 for (ITaskInstance instance : task1.getInstances()) { 71 if ((!(instance instanceof IEventTaskInstance)) || 72 (!(((IEventTaskInstance) instance).getEvent().getType() instanceof IInteraction))) 73 { 74 return false; 75 } 76 } 77 78 for (ITaskInstance instance : task2.getInstances()) { 79 if ((!(instance instanceof IEventTaskInstance)) || 80 (!(((IEventTaskInstance) instance).getEvent().getType() instanceof IInteraction))) 81 { 82 return false; 83 } 84 } 85 86 return true; 87 } 88 89 /* (non-Javadoc) 90 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 91 */ 92 @Override 93 public boolean areLexicallyEqual(ITask task1, ITask task2) { 94 TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL); 95 return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 96 } 97 98 /* (non-Javadoc) 99 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 100 */ 101 @Override 102 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 103 TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL); 104 return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 105 } 106 107 /* (non-Javadoc) 108 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 109 */ 110 @Override 111 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 112 TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL); 113 return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 114 } 115 116 /* (non-Javadoc) 117 * @see TaskComparisonRule#compare(ITask, ITask) 118 */ 119 @Override 120 public TaskEquality compare(ITask task1, ITask task2) { 121 return getEquality(task1, task2, null); 122 } 123 124 /* (non-Javadoc) 125 * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#isApplicable(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 126 */ 127 @Override 128 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 129 return 130 (instance1 instanceof IEventTaskInstance) && 131 (instance2 instanceof IEventTaskInstance) && 132 (((IEventTaskInstance) instance1).getEvent().getType() instanceof IInteraction) && 133 (((IEventTaskInstance) instance1).getEvent().getType() instanceof IInteraction); 134 } 135 136 /* (non-Javadoc) 137 * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#areLexicallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 138 */ 139 @Override 140 public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 141 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL); 142 return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 143 } 144 145 /* (non-Javadoc) 146 * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#areSyntacticallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 147 */ 148 @Override 149 public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 150 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL); 151 return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 152 } 153 154 /* (non-Javadoc) 155 * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#areSemanticallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 156 */ 157 @Override 158 public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 159 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL); 160 return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 161 } 162 163 /* (non-Javadoc) 164 * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#compare(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 165 */ 166 @Override 167 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 168 return getEquality(instance1, instance2, null); 169 } 170 171 /** 172 * 173 */ 174 private TaskEquality getEquality(ITask task1, 175 ITask task2, 176 TaskEquality requiredEqualityLevel) 177 { 178 Collection<ITaskInstance> taskInstances1 = task1.getInstances(); 179 Collection<ITaskInstance> taskInstances2 = task2.getInstances(); 180 181 TaskEquality checkedEquality = 182 requiredEqualityLevel != null ? requiredEqualityLevel : TaskEquality.SEMANTICALLY_EQUAL; 183 184 TaskEquality commonDenominator = TaskEquality.LEXICALLY_EQUAL; 185 186 for (ITaskInstance instance1 : taskInstances1) { 187 TaskEquality mostConcreteEquality = null; 188 189 for (ITaskInstance instance2 : taskInstances2) { 190 TaskEquality equality = getEquality(instance1, instance2, requiredEqualityLevel); 191 192 if ((equality != null) && ((mostConcreteEquality == null) || 193 (equality.isAtLeast(mostConcreteEquality)))) 194 { 195 mostConcreteEquality = equality; 196 197 if (((requiredEqualityLevel != null) && 198 (mostConcreteEquality.isAtLeast(requiredEqualityLevel))) || 199 (mostConcreteEquality.isAtLeast(TaskEquality.LEXICALLY_EQUAL))) 200 { 201 break; 202 } 203 } 204 } 205 206 commonDenominator = commonDenominator.getCommonDenominator(mostConcreteEquality); 207 208 if (!commonDenominator.isAtLeast(checkedEquality)) { 209 return TaskEquality.UNEQUAL; 210 } 211 } 212 213 return commonDenominator; 214 } 215 216 /** 217 * 218 */ 219 private TaskEquality getEquality(ITaskInstance instance1, 220 ITaskInstance instance2, 221 TaskEquality requiredEqualityLevel) 222 { 223 IEventTaskInstance eventTask1 = (IEventTaskInstance) instance1; 224 IEventTaskInstance eventTask2 = (IEventTaskInstance) instance2; 225 226 if (!eventTask1.getEvent().getTarget().equals(eventTask2.getEvent().getTarget())) { 227 return TaskEquality.UNEQUAL; 228 } 229 230 IInteraction interaction1 = (IInteraction) eventTask1.getEvent().getType(); 231 IInteraction interaction2 = (IInteraction) eventTask2.getEvent().getType(); 232 233 return compareInteractions 234 (interaction1, interaction2, eventTask1.getEvent().getTarget(), requiredEqualityLevel); 235 } 236 237 /** 238 * <p> 239 * compares two interactions. The method delegates to other, more specific compare method, e.g., 240 * {@link #compareTextInputs(TextInput, TextInput)} and 241 * {@link #compareValueSelections(ValueSelection, ValueSelection)}, if any exist for the 242 * concrete interaction types. Otherwise it uses the equals method of the interactions for 243 * comparison. In this case, if the interactions equals method returns true, this method 244 * returns lexical equality. 245 * </p> 246 * <p> 247 * The provided equality level can be used to restrict the quality check to the given level. 248 * This is done for optimization purposes. The returned equality level can be at most as 249 * concrete as the provided one. If the provided one is null, it is expected to be lexical 250 * equality. 251 * </p> 252 * 253 * @param interaction1 the first interaction to compare 254 * @param interaction2 the second interaction to compare 255 * @param eventTarget the event target on which the interactions happened (used within 256 * special comparisons like mouse clicks on buttons, where the coordinates 257 * can be ignored) 258 * @param equalityLevel the equality level to be checked for 259 * 260 * @return as described 261 */ 262 private TaskEquality compareInteractions(IInteraction interaction1, 263 IInteraction interaction2, 264 IEventTarget eventTarget, 265 TaskEquality equalityLevel) 266 { 267 TaskEquality level = equalityLevel; 268 269 if (level == null) { 270 level = TaskEquality.LEXICALLY_EQUAL; 271 } 272 273 if (interaction1 == interaction2) { 274 return TaskEquality.LEXICALLY_EQUAL; 275 } 276 else if ((interaction1 instanceof KeyInteraction) && 277 (interaction2 instanceof KeyInteraction)) 278 { 279 return compareKeyInteractions 280 ((KeyInteraction) interaction1, (KeyInteraction) interaction2, level); 281 } 282 else if ((interaction1 instanceof MouseButtonInteraction) && 283 (interaction2 instanceof MouseButtonInteraction)) 284 { 285 return compareMouseButtonInteractions 286 ((MouseButtonInteraction) interaction1, (MouseButtonInteraction) interaction2, 287 eventTarget, level); 288 } 289 else if ((interaction1 instanceof Scroll) && (interaction2 instanceof Scroll)) { 290 return compareScrolls((Scroll) interaction1, (Scroll) interaction2, level); 291 } 292 else if ((interaction1 instanceof TextInput) && (interaction2 instanceof TextInput)) { 293 return compareTextInputs 294 ((TextInput) interaction1, (TextInput) interaction2, level); 295 } 296 else if ((interaction1 instanceof ValueSelection) && 297 (interaction2 instanceof ValueSelection)) 298 { 299 return compareValueSelections 300 ((ValueSelection<?>) interaction1, (ValueSelection<?>) interaction2, level); 301 } 302 else if (interaction1.equals(interaction2)) { 303 return TaskEquality.LEXICALLY_EQUAL; 304 } 305 else { 306 return TaskEquality.UNEQUAL; 307 } 308 } 309 310 /** 311 * <p> 312 * compares two key interactions. If both are of the same type and if both have the 313 * same key, they are lexically equal. If both are only of the same type, they are 314 * semantically equal. Otherwise, they are unequal. 315 * </p> 316 * <p> 317 * The provided equality level can be used to restrict the quality check to the given level. 318 * This is done for optimization purposes. The returned equality level is as concrete as 319 * the provided one. It may be more concrete if there is no difference regarding the 320 * comparison on the levels. 321 * </p> 322 * 323 * @param interaction1 the first key interaction 324 * @param interaction2 the second key interaction 325 * @param equalityLevel the equality level to be checked for 326 * 327 * @return as described 328 */ 329 private TaskEquality compareKeyInteractions(KeyInteraction interaction1, 330 KeyInteraction interaction2, 331 TaskEquality equalityLevel) 332 { 333 if (((interaction1 instanceof KeyPressed) && (interaction2 instanceof KeyPressed)) || 334 ((interaction1 instanceof KeyReleased) && (interaction2 instanceof KeyReleased)) || 335 ((interaction1 instanceof KeyTyped) && (interaction2 instanceof KeyTyped))) 336 { 337 if ((equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) && 338 (interaction1.getKey() == interaction2.getKey())) 339 { 340 return TaskEquality.LEXICALLY_EQUAL; 341 } 342 else { 343 return TaskEquality.SEMANTICALLY_EQUAL; 344 } 345 } 346 347 return TaskEquality.UNEQUAL; 348 } 349 350 /** 351 * <p> 352 * compares two mouse drag and drops. If both drag and drops have the same start and end 353 * coordinates, they are lexically equal. Otherwise, they are semantically equal. 354 * </p> 355 * <p> 356 * The provided equality level can be used to restrict the quality check to the given level. 357 * This is done for optimization purposes. The returned equality level is as concrete as 358 * the provided one. It may be more concrete if there is no difference regarding the 359 * comparison on the levels. 360 * </p> 361 * 362 * @param interaction1 the first mouse drag and drop to compare 363 * @param interaction2 the second mouse drag and drop to compare 364 * @param equalityLevel the equality level to be checked for 365 * 366 * @return as described 367 */ 368 private TaskEquality compareMouseDragAndDrops(MouseDragAndDrop interaction1, 369 MouseDragAndDrop interaction2, 370 TaskEquality equalityLevel) 371 { 372 if (interaction1.getButton() != interaction2.getButton()) { 373 return TaskEquality.UNEQUAL; 374 } 375 376 if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 377 int x1 = interaction1.getX(); 378 int x1Start = interaction1.getXStart(); 379 int x2 = interaction2.getX(); 380 int x2Start = interaction2.getXStart(); 381 int y1 = interaction1.getY(); 382 int y1Start = interaction1.getYStart(); 383 int y2 = interaction2.getY(); 384 int y2Start = interaction2.getYStart(); 385 386 if ((x1Start == x2Start) && (x1 == x2) && (y1Start == y2Start) && (y1 == y2)) { 387 return TaskEquality.LEXICALLY_EQUAL; 388 } 389 } 390 391 return TaskEquality.SEMANTICALLY_EQUAL; 392 } 393 394 /** 395 * <p> 396 * compares two mouse button interactions such as clicks, mouse button down, or double clicks. 397 * If both interactions have the same coordinates, they are lexically equal. Otherwise, they 398 * are semantically equal. Mouse clicks for which the coordinates make no lexical difference 399 * (see {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated as 400 * lexically equal. 401 * </p> 402 * <p> 403 * The provided equality level can be used to restrict the quality check to the given level. 404 * This is done for optimization purposes. The returned equality level is as concrete as 405 * the provided one. It may be more concrete if there is no difference regarding the 406 * comparison on the levels. 407 * </p> 408 * 409 * @param interaction1 the first mouse button interaction to compare 410 * @param interaction2 the second mouse button interaction to compare 411 * @param eventTarget the event target on which the interactions happened (used within 412 * special comparisons like mouse clicks on buttons, where the coordinates 413 * can be ignored) 414 * @param equalityLevel the equality level to be checked for 415 * 416 * @return as described 417 */ 418 private TaskEquality compareMouseButtonInteractions(MouseButtonInteraction interaction1, 419 MouseButtonInteraction interaction2, 420 IEventTarget eventTarget, 421 TaskEquality equalityLevel) 422 { 423 boolean coordinatesMatch = true; 424 425 if ((interaction1 instanceof MouseDragAndDrop) && 426 (interaction2 instanceof MouseDragAndDrop)) 427 { 428 return compareMouseDragAndDrops 429 ((MouseDragAndDrop) interaction1, (MouseDragAndDrop) interaction2, equalityLevel); 430 } 431 else if (interaction1.getButton() != interaction2.getButton()) { 432 return TaskEquality.UNEQUAL; 433 } 434 else if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL) && 435 clickCoordinatesMakeLexicalDifference(eventTarget)) 436 { 437 int x1 = interaction1.getX(); 438 int x2 = interaction2.getX(); 439 int y1 = interaction1.getY(); 440 int y2 = interaction2.getY(); 441 442 if ((x1 != x2) || (y1 != y2)) { 443 coordinatesMatch = false; 444 } 445 } 446 447 // up to now, they can be equal. Now check the types. Do it as last action as these 448 // checks take the most time and should, therefore, only be done latest 449 if (((interaction1 instanceof MouseClick) && (interaction2 instanceof MouseClick)) || 450 ((interaction1 instanceof MouseDoubleClick) && 451 (interaction2 instanceof MouseDoubleClick)) || 452 ((interaction1 instanceof MouseButtonDown) && 453 (interaction2 instanceof MouseButtonDown)) || 454 ((interaction1 instanceof MouseButtonUp) && 455 (interaction2 instanceof MouseButtonUp))) 456 { 457 if (coordinatesMatch) { 458 return TaskEquality.LEXICALLY_EQUAL; 459 } 460 else { 461 return TaskEquality.SEMANTICALLY_EQUAL; 462 } 463 } 464 465 return TaskEquality.UNEQUAL; 466 } 467 468 /** 469 * <p> 470 * compares two mouse button interactions such as clicks, mouse button down, or double clicks. 471 * If both interactions have the same coordinates, they are lexically equal. Otherwise, they 472 * are semantically equal. Mouse clicks for which the coordinates make no lexical difference 473 * (see {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated as 474 * lexically equal. 475 * </p> 476 * <p> 477 * The provided equality level can be used to restrict the quality check to the given level. 478 * This is done for optimization purposes. The returned equality level is as concrete as 479 * the provided one. It may be more concrete if there is no difference regarding the 480 * comparison on the levels. 481 * </p> 482 * 483 * @param interaction1 the first mouse button interaction to compare 484 * @param interaction2 the second mouse button interaction to compare 485 * @param eventTarget the event target on which the interactions happened (used within 486 * special comparisons like mouse clicks on buttons, where the coordinates 487 * can be ignored) 488 * @param equalityLevel the equality level to be checked for 489 * 490 * @return as described 491 */ 492 private TaskEquality compareScrolls(Scroll interaction1, 493 Scroll interaction2, 494 TaskEquality equalityLevel) 495 { 496 if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 497 int x1 = interaction1.getXPosition(); 498 int x2 = interaction2.getXPosition(); 499 int y1 = interaction1.getYPosition(); 500 int y2 = interaction2.getYPosition(); 501 502 if ((x1 == x2) && (y1 == y2)) { 503 return TaskEquality.LEXICALLY_EQUAL; 504 } 505 } 506 507 return TaskEquality.SEMANTICALLY_EQUAL; 508 } 509 510 /** 511 * <p> 512 * compares two text inputs. If both text inputs have the same entered text and text input 513 * events, they are lexically equal. If they only have the same entered text, they are 514 * syntactically equal. If they are only both text inputs, they are semantically equal. 515 * (the equality of the event targets is checked beforehand). 516 * </p> 517 * <p> 518 * The provided equality level can be used to restrict the quality check to the given level. 519 * This is done for optimization purposes. The returned equality level is as concrete as 520 * the provided one. It may be more concrete if there is no difference regarding the 521 * comparison on the levels. 522 * </p> 523 * 524 * @param interaction1 the first text input to compare 525 * @param interaction2 the second text input to compare 526 * @param equalityLevel the equality level to be checked for 527 * 528 * @return as described 529 */ 530 private TaskEquality compareTextInputs(TextInput interaction1, 531 TextInput interaction2, 532 TaskEquality equalityLevel) 533 { 534 switch (equalityLevel) { 535 case LEXICALLY_EQUAL: 536 if (interaction1.getTextInputEvents().equals(interaction2.getTextInputEvents())) { 537 return TaskEquality.LEXICALLY_EQUAL; 538 } 539 // fall through 540 case SYNTACTICALLY_EQUAL: 541 if (interaction1.getEnteredText().equals(interaction2.getEnteredText())) { 542 return TaskEquality.SYNTACTICALLY_EQUAL; 543 } 544 // fall through 545 case SEMANTICALLY_EQUAL: 546 return TaskEquality.SEMANTICALLY_EQUAL; 547 default: 548 return TaskEquality.UNEQUAL; 549 } 550 } 551 552 /** 553 * <p> 554 * compares two value selections. If both value selections have the same selected value, they 555 * are syntactically equal, otherwise they are semantically equal. 556 * (the equality of the event targets is checked beforehand). 557 * </p> 558 * <p> 559 * The provided equality level can be used to restrict the quality check to the given level. 560 * This is done for optimization purposes. The returned equality level is as concrete as 561 * the provided one. It may be more concrete if there is no difference regarding the 562 * comparison on the levels. 563 * </p> 564 * 565 * @param interaction1 the first value selection to compare 566 * @param interaction2 the second value selection to compare 567 * @param equalityLevel the equality level to be checked for 568 * 569 * @return as described 570 */ 571 private TaskEquality compareValueSelections(ValueSelection<?> interaction1, 572 ValueSelection<?> interaction2, 573 TaskEquality equalityLevel) 574 { 575 if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 576 Object value1 = interaction1.getSelectedValue(); 577 Object value2 = interaction2.getSelectedValue(); 578 579 if ((value1 == value2) || ((value1 != null) && (value1.equals(value2)))) { 580 return TaskEquality.LEXICALLY_EQUAL; 581 } 582 } 583 584 return TaskEquality.SEMANTICALLY_EQUAL; 585 } 586 587 /** 588 * <p> 589 * Checks, if the coordinates of a click or double click on the provided event target makes 590 * a lexical difference. Mouse clicks and double clicks on buttons, check boxes, 591 * combo boxes, images, list boxes, menu buttons, radio buttons, shapes, uneditable text, 592 * and tool tips have no lexical difference as long as they happen on the same event target. 593 * The concrete coordinates are not relevant. 594 * </p> 595 * 596 * @param eventTarget the event target on which the interaction occurred 597 * 598 * @return if the coordinates are important to be considered for clicks and double clicks, 599 * false else 600 */ 601 private boolean clickCoordinatesMakeLexicalDifference(IEventTarget eventTarget) { 602 if ((eventTarget instanceof IButton) || 603 (eventTarget instanceof ICheckBox) || 604 (eventTarget instanceof IComboBox) || 605 (eventTarget instanceof IImage) || 606 (eventTarget instanceof IListBox) || 607 (eventTarget instanceof IMenu) || 608 (eventTarget instanceof IMenuButton) || 609 (eventTarget instanceof IRadioButton) || 610 (eventTarget instanceof IShape) || 611 (eventTarget instanceof IText) || 612 (eventTarget instanceof IToolTip)) 613 { 614 return false; 615 } 616 else { 617 return true; 618 } 619 } 66 67 /* 68 * (non-Javadoc) 69 * 70 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 71 */ 72 @Override 73 public boolean areLexicallyEqual(ITask task1, ITask task2) { 74 final TaskEquality equality = getEquality(task1, task2, 75 TaskEquality.LEXICALLY_EQUAL); 76 return (equality != null) 77 && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 78 } 79 80 /* 81 * (non-Javadoc) 82 * 83 * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule# 84 * areLexicallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, 85 * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 86 */ 87 @Override 88 public boolean areLexicallyEqual(ITaskInstance instance1, 89 ITaskInstance instance2) { 90 final TaskEquality equality = getEquality(instance1, instance2, 91 TaskEquality.LEXICALLY_EQUAL); 92 return (equality != null) 93 && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 94 } 95 96 /* 97 * (non-Javadoc) 98 * 99 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 100 */ 101 @Override 102 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 103 final TaskEquality equality = getEquality(task1, task2, 104 TaskEquality.SEMANTICALLY_EQUAL); 105 return (equality != null) 106 && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 107 } 108 109 /* 110 * (non-Javadoc) 111 * 112 * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule# 113 * areSemanticallyEqual 114 * (de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, 115 * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 116 */ 117 @Override 118 public boolean areSemanticallyEqual(ITaskInstance instance1, 119 ITaskInstance instance2) { 120 final TaskEquality equality = getEquality(instance1, instance2, 121 TaskEquality.SEMANTICALLY_EQUAL); 122 return (equality != null) 123 && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 124 } 125 126 /* 127 * (non-Javadoc) 128 * 129 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 130 */ 131 @Override 132 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 133 final TaskEquality equality = getEquality(task1, task2, 134 TaskEquality.SYNTACTICALLY_EQUAL); 135 return (equality != null) 136 && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 137 } 138 139 /* 140 * (non-Javadoc) 141 * 142 * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule# 143 * areSyntacticallyEqual 144 * (de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, 145 * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 146 */ 147 @Override 148 public boolean areSyntacticallyEqual(ITaskInstance instance1, 149 ITaskInstance instance2) { 150 final TaskEquality equality = getEquality(instance1, instance2, 151 TaskEquality.SYNTACTICALLY_EQUAL); 152 return (equality != null) 153 && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 154 } 155 156 /** 157 * <p> 158 * Checks, if the coordinates of a click or double click on the provided 159 * event target makes a lexical difference. Mouse clicks and double clicks 160 * on buttons, check boxes, combo boxes, images, list boxes, menu buttons, 161 * radio buttons, shapes, uneditable text, and tool tips have no lexical 162 * difference as long as they happen on the same event target. The concrete 163 * coordinates are not relevant. 164 * </p> 165 * 166 * @param eventTarget 167 * the event target on which the interaction occurred 168 * 169 * @return if the coordinates are important to be considered for clicks and 170 * double clicks, false else 171 */ 172 private boolean clickCoordinatesMakeLexicalDifference( 173 IEventTarget eventTarget) { 174 if ((eventTarget instanceof IButton) 175 || (eventTarget instanceof ICheckBox) 176 || (eventTarget instanceof IComboBox) 177 || (eventTarget instanceof IImage) 178 || (eventTarget instanceof IListBox) 179 || (eventTarget instanceof IMenu) 180 || (eventTarget instanceof IMenuButton) 181 || (eventTarget instanceof IRadioButton) 182 || (eventTarget instanceof IShape) 183 || (eventTarget instanceof IText) 184 || (eventTarget instanceof IToolTip)) { 185 return false; 186 } else { 187 return true; 188 } 189 } 190 191 /* 192 * (non-Javadoc) 193 * 194 * @see TaskComparisonRule#compare(ITask, ITask) 195 */ 196 @Override 197 public TaskEquality compare(ITask task1, ITask task2) { 198 return getEquality(task1, task2, null); 199 } 200 201 /* 202 * (non-Javadoc) 203 * 204 * @see 205 * de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#compare 206 * (de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, 207 * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 208 */ 209 @Override 210 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 211 return getEquality(instance1, instance2, null); 212 } 213 214 /** 215 * <p> 216 * compares two interactions. The method delegates to other, more specific 217 * compare method, e.g., {@link #compareTextInputs(TextInput, TextInput)} 218 * and {@link #compareValueSelections(ValueSelection, ValueSelection)}, if 219 * any exist for the concrete interaction types. Otherwise it uses the 220 * equals method of the interactions for comparison. In this case, if the 221 * interactions equals method returns true, this method returns lexical 222 * equality. 223 * </p> 224 * <p> 225 * The provided equality level can be used to restrict the quality check to 226 * the given level. This is done for optimization purposes. The returned 227 * equality level can be at most as concrete as the provided one. If the 228 * provided one is null, it is expected to be lexical equality. 229 * </p> 230 * 231 * @param interaction1 232 * the first interaction to compare 233 * @param interaction2 234 * the second interaction to compare 235 * @param eventTarget 236 * the event target on which the interactions happened (used 237 * within special comparisons like mouse clicks on buttons, where 238 * the coordinates can be ignored) 239 * @param equalityLevel 240 * the equality level to be checked for 241 * 242 * @return as described 243 */ 244 private TaskEquality compareInteractions(IInteraction interaction1, 245 IInteraction interaction2, IEventTarget eventTarget, 246 TaskEquality equalityLevel) { 247 TaskEquality level = equalityLevel; 248 249 if (level == null) { 250 level = TaskEquality.LEXICALLY_EQUAL; 251 } 252 253 if (interaction1 == interaction2) { 254 return TaskEquality.LEXICALLY_EQUAL; 255 } else if ((interaction1 instanceof KeyInteraction) 256 && (interaction2 instanceof KeyInteraction)) { 257 return compareKeyInteractions((KeyInteraction) interaction1, 258 (KeyInteraction) interaction2, level); 259 } else if ((interaction1 instanceof MouseButtonInteraction) 260 && (interaction2 instanceof MouseButtonInteraction)) { 261 return compareMouseButtonInteractions( 262 (MouseButtonInteraction) interaction1, 263 (MouseButtonInteraction) interaction2, eventTarget, level); 264 } else if ((interaction1 instanceof Scroll) 265 && (interaction2 instanceof Scroll)) { 266 return compareScrolls((Scroll) interaction1, (Scroll) interaction2, 267 level); 268 } else if ((interaction1 instanceof TextInput) 269 && (interaction2 instanceof TextInput)) { 270 return compareTextInputs((TextInput) interaction1, 271 (TextInput) interaction2, level); 272 } else if ((interaction1 instanceof ValueSelection) 273 && (interaction2 instanceof ValueSelection)) { 274 return compareValueSelections((ValueSelection<?>) interaction1, 275 (ValueSelection<?>) interaction2, level); 276 } else if (interaction1.equals(interaction2)) { 277 return TaskEquality.LEXICALLY_EQUAL; 278 } else { 279 return TaskEquality.UNEQUAL; 280 } 281 } 282 283 /** 284 * <p> 285 * compares two key interactions. If both are of the same type and if both 286 * have the same key, they are lexically equal. If both are only of the same 287 * type, they are semantically equal. Otherwise, they are unequal. 288 * </p> 289 * <p> 290 * The provided equality level can be used to restrict the quality check to 291 * the given level. This is done for optimization purposes. The returned 292 * equality level is as concrete as the provided one. It may be more 293 * concrete if there is no difference regarding the comparison on the 294 * levels. 295 * </p> 296 * 297 * @param interaction1 298 * the first key interaction 299 * @param interaction2 300 * the second key interaction 301 * @param equalityLevel 302 * the equality level to be checked for 303 * 304 * @return as described 305 */ 306 private TaskEquality compareKeyInteractions(KeyInteraction interaction1, 307 KeyInteraction interaction2, TaskEquality equalityLevel) { 308 if (((interaction1 instanceof KeyPressed) && (interaction2 instanceof KeyPressed)) 309 || ((interaction1 instanceof KeyReleased) && (interaction2 instanceof KeyReleased)) 310 || ((interaction1 instanceof KeyTyped) && (interaction2 instanceof KeyTyped))) { 311 if ((equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) 312 && (interaction1.getKey() == interaction2.getKey())) { 313 return TaskEquality.LEXICALLY_EQUAL; 314 } else { 315 return TaskEquality.SEMANTICALLY_EQUAL; 316 } 317 } 318 319 return TaskEquality.UNEQUAL; 320 } 321 322 /** 323 * <p> 324 * compares two mouse button interactions such as clicks, mouse button down, 325 * or double clicks. If both interactions have the same coordinates, they 326 * are lexically equal. Otherwise, they are semantically equal. Mouse clicks 327 * for which the coordinates make no lexical difference (see 328 * {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated 329 * as lexically equal. 330 * </p> 331 * <p> 332 * The provided equality level can be used to restrict the quality check to 333 * the given level. This is done for optimization purposes. The returned 334 * equality level is as concrete as the provided one. It may be more 335 * concrete if there is no difference regarding the comparison on the 336 * levels. 337 * </p> 338 * 339 * @param interaction1 340 * the first mouse button interaction to compare 341 * @param interaction2 342 * the second mouse button interaction to compare 343 * @param eventTarget 344 * the event target on which the interactions happened (used 345 * within special comparisons like mouse clicks on buttons, where 346 * the coordinates can be ignored) 347 * @param equalityLevel 348 * the equality level to be checked for 349 * 350 * @return as described 351 */ 352 private TaskEquality compareMouseButtonInteractions( 353 MouseButtonInteraction interaction1, 354 MouseButtonInteraction interaction2, IEventTarget eventTarget, 355 TaskEquality equalityLevel) { 356 boolean coordinatesMatch = true; 357 358 if ((interaction1 instanceof MouseDragAndDrop) 359 && (interaction2 instanceof MouseDragAndDrop)) { 360 return compareMouseDragAndDrops((MouseDragAndDrop) interaction1, 361 (MouseDragAndDrop) interaction2, equalityLevel); 362 } else if (interaction1.getButton() != interaction2.getButton()) { 363 return TaskEquality.UNEQUAL; 364 } else if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL) 365 && clickCoordinatesMakeLexicalDifference(eventTarget)) { 366 final int x1 = interaction1.getX(); 367 final int x2 = interaction2.getX(); 368 final int y1 = interaction1.getY(); 369 final int y2 = interaction2.getY(); 370 371 if ((x1 != x2) || (y1 != y2)) { 372 coordinatesMatch = false; 373 } 374 } 375 376 // up to now, they can be equal. Now check the types. Do it as last 377 // action as these 378 // checks take the most time and should, therefore, only be done latest 379 if (((interaction1 instanceof MouseClick) && (interaction2 instanceof MouseClick)) 380 || ((interaction1 instanceof MouseDoubleClick) && (interaction2 instanceof MouseDoubleClick)) 381 || ((interaction1 instanceof MouseButtonDown) && (interaction2 instanceof MouseButtonDown)) 382 || ((interaction1 instanceof MouseButtonUp) && (interaction2 instanceof MouseButtonUp))) { 383 if (coordinatesMatch) { 384 return TaskEquality.LEXICALLY_EQUAL; 385 } else { 386 return TaskEquality.SEMANTICALLY_EQUAL; 387 } 388 } 389 390 return TaskEquality.UNEQUAL; 391 } 392 393 /** 394 * <p> 395 * compares two mouse drag and drops. If both drag and drops have the same 396 * start and end coordinates, they are lexically equal. Otherwise, they are 397 * semantically equal. 398 * </p> 399 * <p> 400 * The provided equality level can be used to restrict the quality check to 401 * the given level. This is done for optimization purposes. The returned 402 * equality level is as concrete as the provided one. It may be more 403 * concrete if there is no difference regarding the comparison on the 404 * levels. 405 * </p> 406 * 407 * @param interaction1 408 * the first mouse drag and drop to compare 409 * @param interaction2 410 * the second mouse drag and drop to compare 411 * @param equalityLevel 412 * the equality level to be checked for 413 * 414 * @return as described 415 */ 416 private TaskEquality compareMouseDragAndDrops( 417 MouseDragAndDrop interaction1, MouseDragAndDrop interaction2, 418 TaskEquality equalityLevel) { 419 if (interaction1.getButton() != interaction2.getButton()) { 420 return TaskEquality.UNEQUAL; 421 } 422 423 if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 424 final int x1 = interaction1.getX(); 425 final int x1Start = interaction1.getXStart(); 426 final int x2 = interaction2.getX(); 427 final int x2Start = interaction2.getXStart(); 428 final int y1 = interaction1.getY(); 429 final int y1Start = interaction1.getYStart(); 430 final int y2 = interaction2.getY(); 431 final int y2Start = interaction2.getYStart(); 432 433 if ((x1Start == x2Start) && (x1 == x2) && (y1Start == y2Start) 434 && (y1 == y2)) { 435 return TaskEquality.LEXICALLY_EQUAL; 436 } 437 } 438 439 return TaskEquality.SEMANTICALLY_EQUAL; 440 } 441 442 /** 443 * <p> 444 * compares two mouse button interactions such as clicks, mouse button down, 445 * or double clicks. If both interactions have the same coordinates, they 446 * are lexically equal. Otherwise, they are semantically equal. Mouse clicks 447 * for which the coordinates make no lexical difference (see 448 * {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated 449 * as lexically equal. 450 * </p> 451 * <p> 452 * The provided equality level can be used to restrict the quality check to 453 * the given level. This is done for optimization purposes. The returned 454 * equality level is as concrete as the provided one. It may be more 455 * concrete if there is no difference regarding the comparison on the 456 * levels. 457 * </p> 458 * 459 * @param interaction1 460 * the first mouse button interaction to compare 461 * @param interaction2 462 * the second mouse button interaction to compare 463 * @param eventTarget 464 * the event target on which the interactions happened (used 465 * within special comparisons like mouse clicks on buttons, where 466 * the coordinates can be ignored) 467 * @param equalityLevel 468 * the equality level to be checked for 469 * 470 * @return as described 471 */ 472 private TaskEquality compareScrolls(Scroll interaction1, 473 Scroll interaction2, TaskEquality equalityLevel) { 474 if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 475 final int x1 = interaction1.getXPosition(); 476 final int x2 = interaction2.getXPosition(); 477 final int y1 = interaction1.getYPosition(); 478 final int y2 = interaction2.getYPosition(); 479 480 if ((x1 == x2) && (y1 == y2)) { 481 return TaskEquality.LEXICALLY_EQUAL; 482 } 483 } 484 485 return TaskEquality.SEMANTICALLY_EQUAL; 486 } 487 488 /** 489 * <p> 490 * compares two text inputs. If both text inputs have the same entered text 491 * and text input events, they are lexically equal. If they only have the 492 * same entered text, they are syntactically equal. If they are only both 493 * text inputs, they are semantically equal. (the equality of the event 494 * targets is checked beforehand). 495 * </p> 496 * <p> 497 * The provided equality level can be used to restrict the quality check to 498 * the given level. This is done for optimization purposes. The returned 499 * equality level is as concrete as the provided one. It may be more 500 * concrete if there is no difference regarding the comparison on the 501 * levels. 502 * </p> 503 * 504 * @param interaction1 505 * the first text input to compare 506 * @param interaction2 507 * the second text input to compare 508 * @param equalityLevel 509 * the equality level to be checked for 510 * 511 * @return as described 512 */ 513 private TaskEquality compareTextInputs(TextInput interaction1, 514 TextInput interaction2, TaskEquality equalityLevel) { 515 switch (equalityLevel) { 516 case LEXICALLY_EQUAL: 517 if (interaction1.getTextInputEvents().equals( 518 interaction2.getTextInputEvents())) { 519 return TaskEquality.LEXICALLY_EQUAL; 520 } 521 // fall through 522 case SYNTACTICALLY_EQUAL: 523 if (interaction1.getEnteredText().equals( 524 interaction2.getEnteredText())) { 525 return TaskEquality.SYNTACTICALLY_EQUAL; 526 } 527 // fall through 528 case SEMANTICALLY_EQUAL: 529 return TaskEquality.SEMANTICALLY_EQUAL; 530 default: 531 return TaskEquality.UNEQUAL; 532 } 533 } 534 535 /** 536 * <p> 537 * compares two value selections. If both value selections have the same 538 * selected value, they are syntactically equal, otherwise they are 539 * semantically equal. (the equality of the event targets is checked 540 * beforehand). 541 * </p> 542 * <p> 543 * The provided equality level can be used to restrict the quality check to 544 * the given level. This is done for optimization purposes. The returned 545 * equality level is as concrete as the provided one. It may be more 546 * concrete if there is no difference regarding the comparison on the 547 * levels. 548 * </p> 549 * 550 * @param interaction1 551 * the first value selection to compare 552 * @param interaction2 553 * the second value selection to compare 554 * @param equalityLevel 555 * the equality level to be checked for 556 * 557 * @return as described 558 */ 559 private TaskEquality compareValueSelections(ValueSelection<?> interaction1, 560 ValueSelection<?> interaction2, TaskEquality equalityLevel) { 561 if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) { 562 final Object value1 = interaction1.getSelectedValue(); 563 final Object value2 = interaction2.getSelectedValue(); 564 565 if ((value1 == value2) 566 || ((value1 != null) && (value1.equals(value2)))) { 567 return TaskEquality.LEXICALLY_EQUAL; 568 } 569 } 570 571 return TaskEquality.SEMANTICALLY_EQUAL; 572 } 573 574 /** 575 * 576 */ 577 private TaskEquality getEquality(ITask task1, ITask task2, 578 TaskEquality requiredEqualityLevel) { 579 final Collection<ITaskInstance> taskInstances1 = task1.getInstances(); 580 final Collection<ITaskInstance> taskInstances2 = task2.getInstances(); 581 582 final TaskEquality checkedEquality = requiredEqualityLevel != null ? requiredEqualityLevel 583 : TaskEquality.SEMANTICALLY_EQUAL; 584 585 TaskEquality commonDenominator = TaskEquality.LEXICALLY_EQUAL; 586 587 for (final ITaskInstance instance1 : taskInstances1) { 588 TaskEquality mostConcreteEquality = null; 589 590 for (final ITaskInstance instance2 : taskInstances2) { 591 final TaskEquality equality = getEquality(instance1, instance2, 592 requiredEqualityLevel); 593 594 if ((equality != null) 595 && ((mostConcreteEquality == null) || (equality 596 .isAtLeast(mostConcreteEquality)))) { 597 mostConcreteEquality = equality; 598 599 if (((requiredEqualityLevel != null) && (mostConcreteEquality 600 .isAtLeast(requiredEqualityLevel))) 601 || (mostConcreteEquality 602 .isAtLeast(TaskEquality.LEXICALLY_EQUAL))) { 603 break; 604 } 605 } 606 } 607 608 commonDenominator = commonDenominator 609 .getCommonDenominator(mostConcreteEquality); 610 611 if (!commonDenominator.isAtLeast(checkedEquality)) { 612 return TaskEquality.UNEQUAL; 613 } 614 } 615 616 return commonDenominator; 617 } 618 619 /** 620 * 621 */ 622 private TaskEquality getEquality(ITaskInstance instance1, 623 ITaskInstance instance2, TaskEquality requiredEqualityLevel) { 624 final IEventTaskInstance eventTask1 = (IEventTaskInstance) instance1; 625 final IEventTaskInstance eventTask2 = (IEventTaskInstance) instance2; 626 627 if (!eventTask1.getEvent().getTarget() 628 .equals(eventTask2.getEvent().getTarget())) { 629 return TaskEquality.UNEQUAL; 630 } 631 632 final IInteraction interaction1 = (IInteraction) eventTask1.getEvent() 633 .getType(); 634 final IInteraction interaction2 = (IInteraction) eventTask2.getEvent() 635 .getType(); 636 637 return compareInteractions(interaction1, interaction2, eventTask1 638 .getEvent().getTarget(), requiredEqualityLevel); 639 } 640 641 /* 642 * (non-Javadoc) 643 * 644 * @see TaskComparisonRule#isApplicable(ITask, ITask) 645 */ 646 @Override 647 public boolean isApplicable(ITask task1, ITask task2) { 648 for (final ITaskInstance instance : task1.getInstances()) { 649 if ((!(instance instanceof IEventTaskInstance)) 650 || (!(((IEventTaskInstance) instance).getEvent().getType() instanceof IInteraction))) { 651 return false; 652 } 653 } 654 655 for (final ITaskInstance instance : task2.getInstances()) { 656 if ((!(instance instanceof IEventTaskInstance)) 657 || (!(((IEventTaskInstance) instance).getEvent().getType() instanceof IInteraction))) { 658 return false; 659 } 660 } 661 662 return true; 663 } 664 665 /* 666 * (non-Javadoc) 667 * 668 * @see 669 * de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#isApplicable 670 * (de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, 671 * de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance) 672 */ 673 @Override 674 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 675 return (instance1 instanceof IEventTaskInstance) 676 && (instance2 instanceof IEventTaskInstance) 677 && (((IEventTaskInstance) instance1).getEvent().getType() instanceof IInteraction) 678 && (((IEventTaskInstance) instance1).getEvent().getType() instanceof IInteraction); 679 } 620 680 621 681 } -
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/IterationComparisonRule.java
r1294 r1733 23 23 /** 24 24 * <p> 25 * This class is capable of comparing Iterations. Iterations equal at distinct levels 26 * in distinct situations. The following table shows the results of the comparison for the 27 * specific situations (the parameters are commutative). In any other situation, the comparison 28 * returns <code>NodeEquality.UNEQUAL</code>: 25 * This class is capable of comparing Iterations. Iterations equal at distinct 26 * levels in distinct situations. The following table shows the results of the 27 * comparison for the specific situations (the parameters are commutative). In 28 * any other situation, the comparison returns <code>NodeEquality.UNEQUAL</code> 29 * : 29 30 * </p> 30 31 * 31 32 * <table border="1"> 32 * <tr> 33 * <th>iteration 1</th> 34 * <th>iteration 2</th> 35 * <th>comparison result</th> 36 * </tr> 37 * <tr> 38 * <td>any iteration</td> 39 * <td>any iteration with a child that is lexically equal to the child of iteration 1</td> 40 * <td><code>NodeEquality.LEXICALLY_EQUAL</code></td> 41 * </tr> 42 * <tr> 43 * <td>any iteration</td> 44 * <td>any iteration with a child that is syntactically equal to the child of iteration 1</td> 45 * <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 46 * </tr> 47 * <tr> 48 * <td>any iteration</td> 49 * <td>any iteration with a child that is semantically equal to the child of iteration 1</td> 50 * <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 51 * </tr> 52 * <tr> 53 * <td>an iteration with a selection of syntactically equal children</td> 54 * <td>an iteration with a child that is syntactically equal to the children of the child 55 * selection of iteration 1</td> 56 * <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 57 * </tr> 58 * <tr> 59 * <td>an iteration with a selection of syntactically equal children</td> 60 * <td>an iteration with a selection of syntactically equal children that are all syntactically 61 * equal to the selection of children of iteration 1</td> 62 * <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 63 * </tr> 64 * <tr> 65 * <td>an iteration with a selection of semantically equal children</td> 66 * <td>an iteration with a child that is semantically equal to the children of the child 67 * selection of iteration 1</td> 68 * <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 69 * </tr> 70 * <tr> 71 * <td>an iteration with a selection of semantically equal children</td> 72 * <td>an iteration with a selection of semantically equal children that are all semantically 73 * equal to the selection of children of iteration 1</td> 74 * <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 75 * </tr> 33 * <tr> 34 * <th>iteration 1</th> 35 * <th>iteration 2</th> 36 * <th>comparison result</th> 37 * </tr> 38 * <tr> 39 * <td>any iteration</td> 40 * <td>any iteration with a child that is lexically equal to the child of 41 * iteration 1</td> 42 * <td><code>NodeEquality.LEXICALLY_EQUAL</code></td> 43 * </tr> 44 * <tr> 45 * <td>any iteration</td> 46 * <td>any iteration with a child that is syntactically equal to the child of 47 * iteration 1</td> 48 * <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 49 * </tr> 50 * <tr> 51 * <td>any iteration</td> 52 * <td>any iteration with a child that is semantically equal to the child of 53 * iteration 1</td> 54 * <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 55 * </tr> 56 * <tr> 57 * <td>an iteration with a selection of syntactically equal children</td> 58 * <td>an iteration with a child that is syntactically equal to the children of 59 * the child selection of iteration 1</td> 60 * <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 61 * </tr> 62 * <tr> 63 * <td>an iteration with a selection of syntactically equal children</td> 64 * <td>an iteration with a selection of syntactically equal children that are 65 * all syntactically equal to the selection of children of iteration 1</td> 66 * <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td> 67 * </tr> 68 * <tr> 69 * <td>an iteration with a selection of semantically equal children</td> 70 * <td>an iteration with a child that is semantically equal to the children of 71 * the child selection of iteration 1</td> 72 * <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 73 * </tr> 74 * <tr> 75 * <td>an iteration with a selection of semantically equal children</td> 76 * <td>an iteration with a selection of semantically equal children that are all 77 * semantically equal to the selection of children of iteration 1</td> 78 * <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td> 79 * </tr> 76 80 * </table> 77 81 * … … 80 84 */ 81 85 public class IterationComparisonRule implements TaskComparisonRule { 82 83 /* (non-Javadoc) 84 * @see TaskComparisonRule#isApplicable(ITask, ITask) 85 */ 86 @Override 87 public boolean isApplicable(ITask task1, ITask task2) { 88 return (task1 instanceof IIteration) && (task2 instanceof IIteration); 89 } 90 91 /* (non-Javadoc) 92 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 93 */ 94 @Override 95 public boolean areLexicallyEqual(ITask task1, ITask task2) { 96 ITask child1 = ((IIteration) task1).getMarkedTask(); 97 ITask child2 = ((IIteration) task2).getMarkedTask(); 98 99 if (child1 != null) { 100 if (child2 == null) { 101 return false; 102 } 103 else { 104 // iterations may have 3 different structures. 105 // 1. they have one child, which is the iterated one 106 // 2. they have a sequence of children, which is iterated 107 // 3. they have a selection of different iterated variants (usually the variants 108 // are semantically equal) 109 // ignore the type of the children but check them for equality. 110 111 return getNodeEquality(child1, child2).isAtLeast(TaskEquality.LEXICALLY_EQUAL); 112 } 113 } 114 else if (child2 == null) { 115 return true; 116 } 117 118 return false; 119 } 120 121 /* (non-Javadoc) 122 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 123 */ 124 @Override 125 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 126 return areLexicallyEqual(task1, task2); 127 } 128 129 /* (non-Javadoc) 130 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 131 */ 132 @Override 133 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 134 return compare(task1, task2).isAtLeast(TaskEquality.SEMANTICALLY_EQUAL); 135 } 136 137 /* (non-Javadoc) 138 * @see TaskComparisonRule#compare(ITask, ITask) 139 */ 140 @Override 141 public TaskEquality compare(ITask task1, ITask task2) { 142 ITask child1 = ((IIteration) task1).getMarkedTask(); 143 ITask child2 = ((IIteration) task2).getMarkedTask(); 144 145 // if both iterations do not have children, they are equal although this doesn't make sense 146 if ((child1 == null) && (child2 == null)) { 147 return TaskEquality.LEXICALLY_EQUAL; 148 } 149 else if ((child1 == null) || (child2 == null)) { 150 return TaskEquality.UNEQUAL; 151 } 152 153 // iterations may have 3 different structures. 154 // 1. they have one child, which is the iterated one 155 // 2. they have a sequence of children, which is iterated 156 // 3. they have a selection of different iterated variants (usually the variants are 157 // semantically equal) 158 // 159 // the permutations of the three variants in combination must be checked 160 161 // check if both tasks are the same variants of iterations and if their children are equal. 162 // This condition matches, if both iterations are the same variants of iteration. I.e. three 163 // combinations of the permutation are handled herewith. 164 TaskEquality taskEquality = getNodeEquality(child1, child2); 165 166 if (taskEquality != null) { 167 return taskEquality; 168 } 169 170 // compare one iteration with a single task as a child and another one with a selection of 171 // semantically equal tasks 172 return selectionChildrenSemanticallyEqualNode(child1, child2); 173 174 // all other combinations (i.e. sequence with single child and sequence with selection) 175 // can not match 176 } 177 178 /* (non-Javadoc) 179 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 180 */ 181 @Override 182 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 183 return isApplicable(instance1.getTask(), instance2.getTask()); 184 } 185 186 /* (non-Javadoc) 187 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 188 */ 189 @Override 190 public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 191 IIterationInstance iteration1 = (IIterationInstance) instance1; 192 IIterationInstance iteration2 = (IIterationInstance) instance2; 193 194 // if both sequences do not have children, they are equal although this doesn't make sense 195 if ((iteration1.size() == 0) && (iteration2.size() == 0)) { 196 return true; 197 } 198 199 if (iteration1.size() != iteration2.size()) { 200 return false; 201 } 202 203 for (int i = 0; i < iteration1.size(); i++) { 204 ITaskInstance child1 = iteration1.get(i); 205 ITaskInstance child2 = iteration2.get(i); 206 207 TaskEquality taskEquality = 208 callRuleManager(child1, child2, TaskEquality.LEXICALLY_EQUAL); 209 210 if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) { 211 return false; 212 } 213 } 214 215 return true; 216 } 217 218 /* (non-Javadoc) 219 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 220 */ 221 @Override 222 public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 223 return areLexicallyEqual(instance1, instance2); 224 } 225 226 /* (non-Javadoc) 227 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 228 */ 229 @Override 230 public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 231 return areLexicallyEqual(instance1, instance2); 232 } 233 234 /* (non-Javadoc) 235 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 236 */ 237 @Override 238 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 239 if (areLexicallyEqual(instance1, instance2)) { 240 return TaskEquality.LEXICALLY_EQUAL; 241 } 242 else { 243 return TaskEquality.UNEQUAL; 244 } 245 } 246 247 /** 248 * <p> 249 * compares two tasks with each other by calling the rule manager. If the rule manager returns 250 * identity, then the returned equality is set to lexically equal. The reason is, that 251 * the children of the iterations are compared and that therefore the distinct iterations 252 * can be at most lexically equal. 253 * </p> 254 * 255 * @param child1 the first task to be compared 256 * @param child2 the second task to be compared 257 * 258 * @return the determined equality being at most lexical equality. 259 */ 260 private TaskEquality getNodeEquality(ITask child1, ITask child2) { 261 TaskEquality taskEquality = callRuleManager(child1, child2, null); 262 263 if (taskEquality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)) { 264 // prevent, that identical is returned, because the iterations itself are not identical 265 // although the iterated tasks are 266 if (taskEquality == TaskEquality.IDENTICAL) { 267 return TaskEquality.LEXICALLY_EQUAL; 268 } 269 else { 270 return taskEquality; 271 } 272 } 273 274 return TaskEquality.UNEQUAL; 275 } 276 277 /** 278 * <p> 279 * compares two tasks. One of them must be a selection, the other one can be any task. 280 * The method returns a task equality that is not <code>NodeEquality.UNEQUAL</code> 281 * if the other task is at least semantically equal to the children of the selection. It 282 * returns more concrete equalities, if the equality between the other task and the children 283 * of the selection is more concrete. 284 * </p> 285 * 286 * @param task1 the first task to compare 287 * @param task2 the second task to compare 288 * 289 * @return as described 290 */ 291 private TaskEquality selectionChildrenSemanticallyEqualNode(ITask task1, ITask task2) { 292 ISelection selection = null; 293 ITask task = null; 294 if (task1 instanceof ISelection) { 295 selection = (ISelection) task1; 296 task = task2; 297 } 298 else if (task2 instanceof ISelection) { 299 selection = (ISelection) task2; 300 task = task1; 301 } 302 else { 303 return TaskEquality.UNEQUAL; 304 } 305 306 // Iterations, where one has a selection and the other one not can at most be syntactically 307 // equal but not identical 308 TaskEquality commonDenominatorForAllComparisons = TaskEquality.SYNTACTICALLY_EQUAL; 309 310 for (ITask child : selection.getChildren()) { 311 TaskEquality taskEquality = 312 callRuleManager(task, child, commonDenominatorForAllComparisons); 313 314 if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) { 315 return TaskEquality.UNEQUAL; 316 } 317 318 commonDenominatorForAllComparisons = 319 commonDenominatorForAllComparisons.getCommonDenominator(taskEquality); 320 } 321 322 return commonDenominatorForAllComparisons; 323 } 324 325 /** 326 * <p> 327 * used to to call the task equality rule manager for the comparison of the two provided 328 * children. If no required equality level is provided, than the most concrete equality is 329 * returned. Otherwise, the required equality is returned as long as the children are equal 330 * on that level. 331 * </p> 332 * 333 * @param child1 the first task to be compared 334 * @param child2 the second task to be compared 335 * @param requiredEqualityLevel the equality level to be checked for 336 * 337 * @return the determined equality 338 */ 339 private TaskEquality callRuleManager(ITask child1, 340 ITask child2, 341 TaskEquality requiredEqualityLevel) 342 { 343 if (requiredEqualityLevel == null) { 344 return TaskEqualityRuleManager.getInstance().compare(child1, child2); 345 } 346 else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 347 (child1, child2, requiredEqualityLevel)) 348 { 349 return requiredEqualityLevel; 350 } 351 else { 352 return TaskEquality.UNEQUAL; 353 } 354 } 355 356 /** 357 * <p> 358 * used to to call the task equality rule manager for the comparison of the two provided 359 * children. If no required equality level is provided, than the most concrete equality is 360 * returned. Otherwise, the required equality is returned as long as the children are equal 361 * on that level. 362 * </p> 363 * 364 * @param taskInstance1 the first task instance to be compared 365 * @param taskInstance2 the second task instance to be compared 366 * @param requiredEqualityLevel the equality level to be checked for 367 * 368 * @return the determined equality 369 */ 370 private TaskEquality callRuleManager(ITaskInstance taskInstance1, 371 ITaskInstance taskInstance2, 372 TaskEquality requiredEqualityLevel) 373 { 374 if (requiredEqualityLevel == null) { 375 return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2); 376 } 377 else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 378 (taskInstance1, taskInstance2, requiredEqualityLevel)) 379 { 380 return requiredEqualityLevel; 381 } 382 else { 383 return TaskEquality.UNEQUAL; 384 } 385 } 86 87 /* 88 * (non-Javadoc) 89 * 90 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 91 */ 92 @Override 93 public boolean areLexicallyEqual(ITask task1, ITask task2) { 94 final ITask child1 = ((IIteration) task1).getMarkedTask(); 95 final ITask child2 = ((IIteration) task2).getMarkedTask(); 96 97 if (child1 != null) { 98 if (child2 == null) { 99 return false; 100 } else { 101 // iterations may have 3 different structures. 102 // 1. they have one child, which is the iterated one 103 // 2. they have a sequence of children, which is iterated 104 // 3. they have a selection of different iterated variants 105 // (usually the variants 106 // are semantically equal) 107 // ignore the type of the children but check them for equality. 108 109 return getNodeEquality(child1, child2).isAtLeast( 110 TaskEquality.LEXICALLY_EQUAL); 111 } 112 } else if (child2 == null) { 113 return true; 114 } 115 116 return false; 117 } 118 119 /* 120 * (non-Javadoc) 121 * 122 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 123 */ 124 @Override 125 public boolean areLexicallyEqual(ITaskInstance instance1, 126 ITaskInstance instance2) { 127 final IIterationInstance iteration1 = (IIterationInstance) instance1; 128 final IIterationInstance iteration2 = (IIterationInstance) instance2; 129 130 // if both sequences do not have children, they are equal although this 131 // doesn't make sense 132 if ((iteration1.size() == 0) && (iteration2.size() == 0)) { 133 return true; 134 } 135 136 if (iteration1.size() != iteration2.size()) { 137 return false; 138 } 139 140 for (int i = 0; i < iteration1.size(); i++) { 141 final ITaskInstance child1 = iteration1.get(i); 142 final ITaskInstance child2 = iteration2.get(i); 143 144 final TaskEquality taskEquality = callRuleManager(child1, child2, 145 TaskEquality.LEXICALLY_EQUAL); 146 147 if ((taskEquality == null) 148 || (taskEquality == TaskEquality.UNEQUAL)) { 149 return false; 150 } 151 } 152 153 return true; 154 } 155 156 /* 157 * (non-Javadoc) 158 * 159 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 160 */ 161 @Override 162 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 163 return compare(task1, task2).isAtLeast(TaskEquality.SEMANTICALLY_EQUAL); 164 } 165 166 /* 167 * (non-Javadoc) 168 * 169 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 170 * ITaskInstance) 171 */ 172 @Override 173 public boolean areSemanticallyEqual(ITaskInstance instance1, 174 ITaskInstance instance2) { 175 return areLexicallyEqual(instance1, instance2); 176 } 177 178 /* 179 * (non-Javadoc) 180 * 181 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 182 */ 183 @Override 184 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 185 return areLexicallyEqual(task1, task2); 186 } 187 188 /* 189 * (non-Javadoc) 190 * 191 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 192 * ITaskInstance) 193 */ 194 @Override 195 public boolean areSyntacticallyEqual(ITaskInstance instance1, 196 ITaskInstance instance2) { 197 return areLexicallyEqual(instance1, instance2); 198 } 199 200 /** 201 * <p> 202 * used to to call the task equality rule manager for the comparison of the 203 * two provided children. If no required equality level is provided, than 204 * the most concrete equality is returned. Otherwise, the required equality 205 * is returned as long as the children are equal on that level. 206 * </p> 207 * 208 * @param child1 209 * the first task to be compared 210 * @param child2 211 * the second task to be compared 212 * @param requiredEqualityLevel 213 * the equality level to be checked for 214 * 215 * @return the determined equality 216 */ 217 private TaskEquality callRuleManager(ITask child1, ITask child2, 218 TaskEquality requiredEqualityLevel) { 219 if (requiredEqualityLevel == null) { 220 return TaskEqualityRuleManager.getInstance() 221 .compare(child1, child2); 222 } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 223 child1, child2, requiredEqualityLevel)) { 224 return requiredEqualityLevel; 225 } else { 226 return TaskEquality.UNEQUAL; 227 } 228 } 229 230 /** 231 * <p> 232 * used to to call the task equality rule manager for the comparison of the 233 * two provided children. If no required equality level is provided, than 234 * the most concrete equality is returned. Otherwise, the required equality 235 * is returned as long as the children are equal on that level. 236 * </p> 237 * 238 * @param taskInstance1 239 * the first task instance to be compared 240 * @param taskInstance2 241 * the second task instance to be compared 242 * @param requiredEqualityLevel 243 * the equality level to be checked for 244 * 245 * @return the determined equality 246 */ 247 private TaskEquality callRuleManager(ITaskInstance taskInstance1, 248 ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 249 if (requiredEqualityLevel == null) { 250 return TaskEqualityRuleManager.getInstance().compare(taskInstance1, 251 taskInstance2); 252 } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 253 taskInstance1, taskInstance2, requiredEqualityLevel)) { 254 return requiredEqualityLevel; 255 } else { 256 return TaskEquality.UNEQUAL; 257 } 258 } 259 260 /* 261 * (non-Javadoc) 262 * 263 * @see TaskComparisonRule#compare(ITask, ITask) 264 */ 265 @Override 266 public TaskEquality compare(ITask task1, ITask task2) { 267 final ITask child1 = ((IIteration) task1).getMarkedTask(); 268 final ITask child2 = ((IIteration) task2).getMarkedTask(); 269 270 // if both iterations do not have children, they are equal although this 271 // doesn't make sense 272 if ((child1 == null) && (child2 == null)) { 273 return TaskEquality.LEXICALLY_EQUAL; 274 } else if ((child1 == null) || (child2 == null)) { 275 return TaskEquality.UNEQUAL; 276 } 277 278 // iterations may have 3 different structures. 279 // 1. they have one child, which is the iterated one 280 // 2. they have a sequence of children, which is iterated 281 // 3. they have a selection of different iterated variants (usually the 282 // variants are 283 // semantically equal) 284 // 285 // the permutations of the three variants in combination must be checked 286 287 // check if both tasks are the same variants of iterations and if their 288 // children are equal. 289 // This condition matches, if both iterations are the same variants of 290 // iteration. I.e. three 291 // combinations of the permutation are handled herewith. 292 final TaskEquality taskEquality = getNodeEquality(child1, child2); 293 294 if (taskEquality != null) { 295 return taskEquality; 296 } 297 298 // compare one iteration with a single task as a child and another one 299 // with a selection of 300 // semantically equal tasks 301 return selectionChildrenSemanticallyEqualNode(child1, child2); 302 303 // all other combinations (i.e. sequence with single child and sequence 304 // with selection) 305 // can not match 306 } 307 308 /* 309 * (non-Javadoc) 310 * 311 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 312 */ 313 @Override 314 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 315 if (areLexicallyEqual(instance1, instance2)) { 316 return TaskEquality.LEXICALLY_EQUAL; 317 } else { 318 return TaskEquality.UNEQUAL; 319 } 320 } 321 322 /** 323 * <p> 324 * compares two tasks with each other by calling the rule manager. If the 325 * rule manager returns identity, then the returned equality is set to 326 * lexically equal. The reason is, that the children of the iterations are 327 * compared and that therefore the distinct iterations can be at most 328 * lexically equal. 329 * </p> 330 * 331 * @param child1 332 * the first task to be compared 333 * @param child2 334 * the second task to be compared 335 * 336 * @return the determined equality being at most lexical equality. 337 */ 338 private TaskEquality getNodeEquality(ITask child1, ITask child2) { 339 final TaskEquality taskEquality = callRuleManager(child1, child2, null); 340 341 if (taskEquality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)) { 342 // prevent, that identical is returned, because the iterations 343 // itself are not identical 344 // although the iterated tasks are 345 if (taskEquality == TaskEquality.IDENTICAL) { 346 return TaskEquality.LEXICALLY_EQUAL; 347 } else { 348 return taskEquality; 349 } 350 } 351 352 return TaskEquality.UNEQUAL; 353 } 354 355 /* 356 * (non-Javadoc) 357 * 358 * @see TaskComparisonRule#isApplicable(ITask, ITask) 359 */ 360 @Override 361 public boolean isApplicable(ITask task1, ITask task2) { 362 return (task1 instanceof IIteration) && (task2 instanceof IIteration); 363 } 364 365 /* 366 * (non-Javadoc) 367 * 368 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 369 */ 370 @Override 371 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 372 return isApplicable(instance1.getTask(), instance2.getTask()); 373 } 374 375 /** 376 * <p> 377 * compares two tasks. One of them must be a selection, the other one can be 378 * any task. The method returns a task equality that is not 379 * <code>NodeEquality.UNEQUAL</code> if the other task is at least 380 * semantically equal to the children of the selection. It returns more 381 * concrete equalities, if the equality between the other task and the 382 * children of the selection is more concrete. 383 * </p> 384 * 385 * @param task1 386 * the first task to compare 387 * @param task2 388 * the second task to compare 389 * 390 * @return as described 391 */ 392 private TaskEquality selectionChildrenSemanticallyEqualNode(ITask task1, 393 ITask task2) { 394 ISelection selection = null; 395 ITask task = null; 396 if (task1 instanceof ISelection) { 397 selection = (ISelection) task1; 398 task = task2; 399 } else if (task2 instanceof ISelection) { 400 selection = (ISelection) task2; 401 task = task1; 402 } else { 403 return TaskEquality.UNEQUAL; 404 } 405 406 // Iterations, where one has a selection and the other one not can at 407 // most be syntactically 408 // equal but not identical 409 TaskEquality commonDenominatorForAllComparisons = TaskEquality.SYNTACTICALLY_EQUAL; 410 411 for (final ITask child : selection.getChildren()) { 412 final TaskEquality taskEquality = callRuleManager(task, child, 413 commonDenominatorForAllComparisons); 414 415 if ((taskEquality == null) 416 || (taskEquality == TaskEquality.UNEQUAL)) { 417 return TaskEquality.UNEQUAL; 418 } 419 420 commonDenominatorForAllComparisons = commonDenominatorForAllComparisons 421 .getCommonDenominator(taskEquality); 422 } 423 424 return commonDenominatorForAllComparisons; 425 } 386 426 } -
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SelectionComparisonRule.java
r1294 r1733 24 24 /** 25 25 * <p> 26 * this task comparison rule is capable of comparing selections. If both selections do not have 27 * children, they are treated as lexically equal. If they have children, each child of both 28 * selections is compared to each child of the respective other selection. The resulting equality 29 * is the most concrete one of all these comparisons. I.e. if all children are at least lexically 30 * equal, then the selections are lexically equal. If all children are at least syntactically 31 * equal, then the selections are syntactically equal. If all children are at least semantically 32 * equal, then the selections are semantically equal. If only one of the selections has children, 33 * then the selections are unequal. The comparison is broken up, if only a specific equality is 34 * checked for and this equality is ensured. 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. 35 37 * </p> 36 38 * … … 40 42 public class SelectionComparisonRule implements TaskComparisonRule { 41 43 42 /* (non-Javadoc) 43 * @see TaskComparisonRule#isApplicable(ITask, ITask) 44 */ 45 @Override 46 public boolean isApplicable(ITask task1, ITask task2) { 47 return (task1 instanceof ISelection) && (task2 instanceof ISelection); 48 } 49 50 /* (non-Javadoc) 51 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 52 */ 53 @Override 54 public boolean areLexicallyEqual(ITask task1, ITask task2) { 55 TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL); 56 return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 57 } 58 59 /* (non-Javadoc) 60 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 61 */ 62 @Override 63 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 64 TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL); 65 return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 66 } 67 68 /* (non-Javadoc) 69 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 70 */ 71 @Override 72 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 73 TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL); 74 return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 75 } 76 77 /* (non-Javadoc) 78 * @see TaskComparisonRule#compare(ITask, ITask) 79 */ 80 @Override 81 public TaskEquality compare(ITask task1, ITask task2) { 82 return getEquality(task1, task2, null); 83 } 84 85 /* (non-Javadoc) 86 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 87 */ 88 @Override 89 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 90 return isApplicable(instance1.getTask(), instance2.getTask()); 91 } 92 93 /* (non-Javadoc) 94 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 95 */ 96 @Override 97 public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 98 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL); 99 return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 100 } 101 102 /* (non-Javadoc) 103 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 104 */ 105 @Override 106 public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 107 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL); 108 return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 109 } 110 111 /* (non-Javadoc) 112 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 113 */ 114 @Override 115 public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 116 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL); 117 return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 118 } 119 120 /* (non-Javadoc) 121 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 122 */ 123 @Override 124 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 125 return getEquality(instance1, instance2, null); 126 } 127 128 /** 129 * <p> 130 * compares two selections with each other checking for the provided required level of 131 * equality. If this level is ensured, the method immediately returns. The more concrete 132 * the required equality level, the more checks this method performs. 133 * </p> 134 * 135 * @param task1 the first task to be compared 136 * @param task2 the second task to be compared 137 * @param requiredEqualityLevel the equality level to be checked for 138 * 139 * @return the determined equality. 140 */ 141 private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) { 142 List<ITask> children1 = ((ISelection) task1).getChildren(); 143 List<ITask> children2 = ((ISelection) task2).getChildren(); 144 145 // if both selections do not have children, they are lexically equal. If only one of them 146 // has children, they are unequal. 147 if ((children1.size() == 0) && (children2.size() == 0)) { 148 return TaskEquality.LEXICALLY_EQUAL; 149 } 150 else if ((children1.size() == 0) || (children2.size() == 0)) { 151 return TaskEquality.UNEQUAL; 152 } 153 154 if (requiredEqualityLevel == null) { 155 // calculate the common equality level for all children of both selections. 156 // do it in both directions to ensure commutative comparison 157 return getMostConcreteEqualityLevel(children1, children2); 158 } 159 else { 160 // we are searching for a specific equality 161 if (checkEqualityLevel(children1, children2, requiredEqualityLevel)) { 162 return requiredEqualityLevel; 163 } 164 else { 165 return TaskEquality.UNEQUAL; 166 } 167 } 168 } 169 170 /** 171 * <p> 172 * determines the most concrete equality level for all tasks in the first list compared to all 173 * tasks in the second list. It is sufficient, if there is one task in one list for which there 174 * exist an equal task in the other list. 175 * </p> 176 * 177 * @param children1 the first list to be compared 178 * @param children2 the second list to be compared 179 * 180 * @return the most concrete task equality identified for all tasks in the first list with 181 * respect to the second list 182 */ 183 private TaskEquality getMostConcreteEqualityLevel(List<ITask> children1, List<ITask> children2) 184 { 185 TaskEquality childEquality; 186 TaskEquality currentEquality; 187 for (ITask child1 : children1) { 188 childEquality = null; 189 for (ITask child2 : children2) { 190 currentEquality = callRuleManager(child1, child2, null); 191 if ((currentEquality != null) && (currentEquality != TaskEquality.UNEQUAL)) { 192 if (childEquality == null) { 193 childEquality = currentEquality; 194 } 195 else { 196 childEquality = childEquality.getCommonDenominator(currentEquality); 197 } 198 199 if (childEquality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)) { 200 // as we calculate the most concrete equality, we can break up here 201 return TaskEquality.LEXICALLY_EQUAL; 202 } 203 } 204 } 205 } 206 207 // as the comparison should be commutative, we do not need to check, if in list 2 there is 208 // a child equal to one in list 1 209 return TaskEquality.UNEQUAL; 210 } 211 212 /** 213 * <p> 214 * ensures for the two given lists, that for at least one task in the first list there is a task 215 * in the second list being on the given level equal to the task in the first list. 216 * </p> 217 * 218 * @param children1 the first list to be compared 219 * @param children2 the second list to be compared 220 * @param requiredEqualityLevel the equality level to be checked for 221 * 222 * @return true if there is a task in the first list that has an equal task in the second list 223 * when considering the given equality level, false else. 224 */ 225 private boolean checkEqualityLevel(List<ITask> children1, 226 List<ITask> children2, 227 TaskEquality requiredEqualityLevel) 228 { 229 TaskEquality currentEquality; 230 for (ITask child1 : children1) { 231 for (ITask child2 : children2) { 232 currentEquality = callRuleManager(child1, child2, requiredEqualityLevel); 233 if ((currentEquality != null) && (currentEquality.isAtLeast(requiredEqualityLevel))) 234 { 235 // we found at least one equal child with sufficient equality in the 236 // second list. So be can break up for this child. 237 return true; 238 } 239 } 240 } 241 242 return false; 243 } 244 245 /** 246 * <p> 247 * used to to call the task equality rule manager for the comparison of the two provided 248 * children. If no required equality level is provided, than the most concrete equality is 249 * returned. Otherwise, the required equality is returned as long as the children are equal 250 * on that level. 251 * </p> 252 * 253 * @param child1 the first task to be compared 254 * @param child2 the second task to be compared 255 * @param requiredEqualityLevel the equality level to be checked for 256 * 257 * @return the determined equality 258 */ 259 private TaskEquality callRuleManager(ITask child1, 260 ITask child2, 261 TaskEquality requiredEqualityLevel) 262 { 263 if (requiredEqualityLevel == null) { 264 return TaskEqualityRuleManager.getInstance().compare(child1, child2); 265 } 266 else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 267 (child1, child2, requiredEqualityLevel)) 268 { 269 return requiredEqualityLevel; 270 } 271 else { 272 return TaskEquality.UNEQUAL; 273 } 274 } 275 276 /** 277 * <p> 278 * compares two selection instances with each other checking for the provided required level of 279 * equality. If this level is ensured, the method immediately returns. The more concrete 280 * the required equality level, the more checks this method performs. 281 * </p> 282 * 283 * @param taskInstance1 the first task instance to be compared 284 * @param taskInstance2 the second task instance to be compared 285 * @param requiredEqualityLevel the equality level to be checked for 286 * 287 * @return the determined equality. 288 */ 289 private TaskEquality getEquality(ITaskInstance taskInstance1, 290 ITaskInstance taskInstance2, 291 TaskEquality requiredEqualityLevel) 292 { 293 ITaskInstance child1 = ((ISelectionInstance) taskInstance1).getChild(); 294 ITaskInstance child2 = ((ISelectionInstance) taskInstance2).getChild(); 295 296 // if both selections do not have children, they are lexically equal. If only one of them 297 // has children, they are unequal. 298 if ((child1 == null) && (child2 == null)) { 299 return TaskEquality.LEXICALLY_EQUAL; 300 } 301 else if ((child1 == null) || (child2 == null)) { 302 return TaskEquality.UNEQUAL; 303 } 304 305 TaskEquality equality = callRuleManager(child1, child2, requiredEqualityLevel); 306 307 if (equality == TaskEquality.IDENTICAL) { 308 // two different selection instances can be at most lexically equal even if their 309 // children are identical 310 return TaskEquality.LEXICALLY_EQUAL; 311 } 312 else { 313 return equality; 314 } 315 } 316 317 /** 318 * <p> 319 * used to to call the task equality rule manager for the comparison of the two provided 320 * children. If no required equality level is provided, than the most concrete equality is 321 * returned. Otherwise, the required equality is returned as long as the children are equal 322 * on that level. 323 * </p> 324 * 325 * @param taskInstance1 the first task instance to be compared 326 * @param taskInstance2 the second task instance to be compared 327 * @param requiredEqualityLevel the equality level to be checked for 328 * 329 * @return the determined equality 330 */ 331 private TaskEquality callRuleManager(ITaskInstance taskInstance1, 332 ITaskInstance taskInstance2, 333 TaskEquality requiredEqualityLevel) 334 { 335 if (requiredEqualityLevel == null) { 336 return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2); 337 } 338 else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 339 (taskInstance1, taskInstance2, requiredEqualityLevel)) 340 { 341 return requiredEqualityLevel; 342 } 343 else { 344 return TaskEquality.UNEQUAL; 345 } 346 } 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 } 347 404 } -
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SequenceComparisonRule.java
r1294 r1733 24 24 /** 25 25 * <p> 26 * This rule is capable of comparing sequences. If both sequences do not have children, they are27 * treated as lexically equal. Sequences are lexically equal, if they have the same number and28 * order of lexically equal children. The rule can not decide, if two sequences are syntactically29 * or semantically equal.26 * This rule is capable of comparing sequences. If both sequences do not have 27 * children, they are treated as lexically equal. Sequences are lexically equal, 28 * if they have the same number and order of lexically equal children. The rule 29 * can not decide, if two sequences are syntactically or semantically equal. 30 30 * </p> 31 31 * … … 35 35 public class SequenceComparisonRule implements TaskComparisonRule { 36 36 37 /* (non-Javadoc) 38 * @see TaskComparisonRule#isApplicable(ITask, ITask) 39 */ 40 @Override 41 public boolean isApplicable(ITask task1, ITask task2) { 42 return (task1 instanceof ISequence) && (task2 instanceof ISequence); 43 } 44 45 /* (non-Javadoc) 46 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 47 */ 48 @Override 49 public boolean areLexicallyEqual(ITask task1, ITask task2) { 50 TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL); 51 return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 52 } 53 54 /* (non-Javadoc) 55 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 56 */ 57 @Override 58 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 59 TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL); 60 return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 61 } 62 63 /* (non-Javadoc) 64 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 65 */ 66 @Override 67 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 68 TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL); 69 return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 70 } 71 72 /* (non-Javadoc) 73 * @see TaskComparisonRule#compare(ITask, ITask) 74 */ 75 @Override 76 public TaskEquality compare(ITask task1, ITask task2) { 77 return getEquality(task1, task2, null); 78 } 79 80 /* (non-Javadoc) 81 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 82 */ 83 @Override 84 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 85 return isApplicable(instance1.getTask(), instance2.getTask()); 86 } 87 88 /* (non-Javadoc) 89 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 90 */ 91 @Override 92 public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 93 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL); 94 return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 95 } 96 97 /* (non-Javadoc) 98 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 99 */ 100 @Override 101 public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 102 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL); 103 return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 104 } 105 106 /* (non-Javadoc) 107 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 108 */ 109 @Override 110 public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 111 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL); 112 return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 113 } 114 115 /* (non-Javadoc) 116 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 117 */ 118 @Override 119 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 120 return getEquality(instance1, instance2, null); 121 } 122 123 /** 124 * <p> 125 * compares two sequences with each other checking for the provided required level of 126 * equality. If this level is ensured, the method immediately returns. The more concrete 127 * the required equality level, the more checks this method performs. 128 * </p> 129 * 130 * @param task1 the first task to be compared 131 * @param task2 the second task to be compared 132 * @param requiredEqualityLevel the equality level to be checked for 133 * 134 * @return the determined equality. 135 */ 136 private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) { 137 List<ITask> children1 = ((ISequence) task1).getChildren(); 138 List<ITask> children2 = ((ISequence) task2).getChildren(); 139 140 // if both sequences do not have children, they are equal although this doesn't make sense 141 if ((children1.size() == 0) && (children2.size() == 0)) { 142 return TaskEquality.LEXICALLY_EQUAL; 143 } 144 145 if (children1.size() != children2.size()) { 146 return TaskEquality.UNEQUAL; 147 } 148 149 TaskEquality resultingEquality = TaskEquality.LEXICALLY_EQUAL; 150 for (int i = 0; i < children1.size(); i++) { 151 ITask child1 = children1.get(i); 152 ITask child2 = children2.get(i); 153 154 TaskEquality taskEquality = callRuleManager(child1, child2, requiredEqualityLevel); 155 156 if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) { 157 return TaskEquality.UNEQUAL; 158 } 159 160 resultingEquality = resultingEquality.getCommonDenominator(taskEquality); 161 } 162 163 return resultingEquality; 164 } 165 166 /** 167 * <p> 168 * used to to call the task equality rule manager for the comparison of the two provided 169 * children. If no required equality level is provided, than the most concrete equality is 170 * returned. Otherwise, the required equality is returned as long as the children are equal 171 * on that level. 172 * </p> 173 * 174 * @param child1 the first task to be compared 175 * @param child2 the second task to be compared 176 * @param requiredEqualityLevel the equality level to be checked for 177 * 178 * @return the determined equality 179 */ 180 private TaskEquality callRuleManager(ITask child1, 181 ITask child2, 182 TaskEquality requiredEqualityLevel) 183 { 184 if (requiredEqualityLevel == null) { 185 return TaskEqualityRuleManager.getInstance().compare(child1, child2); 186 } 187 else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 188 (child1, child2, requiredEqualityLevel)) 189 { 190 return requiredEqualityLevel; 191 } 192 else { 193 return TaskEquality.UNEQUAL; 194 } 195 } 196 197 /** 198 * <p> 199 * compares two sequence instances with each other checking for the provided required level of 200 * equality. If this level is ensured, the method immediately returns. The more concrete 201 * the required equality level, the more checks this method performs. 202 * </p> 203 * 204 * @param taskInstance1 the first task instance to be compared 205 * @param taskInstance2 the second task instance to be compared 206 * @param requiredEqualityLevel the equality level to be checked for 207 * 208 * @return the determined equality. 209 */ 210 private TaskEquality getEquality(ITaskInstance taskInstance1, 211 ITaskInstance taskInstance2, 212 TaskEquality requiredEqualityLevel) 213 { 214 ISequenceInstance sequence1 = (ISequenceInstance) taskInstance1; 215 ISequenceInstance sequence2 = (ISequenceInstance) taskInstance2; 216 217 // if both sequences do not have children, they are equal although this doesn't make sense 218 if ((sequence1.size() == 0) && (sequence2.size() == 0)) { 219 return TaskEquality.LEXICALLY_EQUAL; 220 } 221 222 if (sequence1.size() != sequence2.size()) { 223 return TaskEquality.UNEQUAL; 224 } 225 226 TaskEquality resultingEquality = TaskEquality.LEXICALLY_EQUAL; 227 for (int i = 0; i < sequence1.size(); i++) { 228 ITaskInstance child1 = sequence1.get(i); 229 ITaskInstance child2 = sequence2.get(i); 230 231 TaskEquality taskEquality = callRuleManager(child1, child2, requiredEqualityLevel); 232 233 if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) { 234 return TaskEquality.UNEQUAL; 235 } 236 237 resultingEquality = resultingEquality.getCommonDenominator(taskEquality); 238 } 239 240 return resultingEquality; 241 } 242 243 /** 244 * <p> 245 * used to to call the task equality rule manager for the comparison of the two provided 246 * children. If no required equality level is provided, than the most concrete equality is 247 * returned. Otherwise, the required equality is returned as long as the children are equal 248 * on that level. 249 * </p> 250 * 251 * @param taskInstance1 the first task instance to be compared 252 * @param taskInstance2 the second task instance to be compared 253 * @param requiredEqualityLevel the equality level to be checked for 254 * 255 * @return the determined equality 256 */ 257 private TaskEquality callRuleManager(ITaskInstance taskInstance1, 258 ITaskInstance taskInstance2, 259 TaskEquality requiredEqualityLevel) 260 { 261 if (requiredEqualityLevel == null) { 262 return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2); 263 } 264 else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 265 (taskInstance1, taskInstance2, requiredEqualityLevel)) 266 { 267 return requiredEqualityLevel; 268 } 269 else { 270 return TaskEquality.UNEQUAL; 271 } 272 } 37 /* 38 * (non-Javadoc) 39 * 40 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 41 */ 42 @Override 43 public boolean areLexicallyEqual(ITask task1, ITask task2) { 44 final TaskEquality equality = getEquality(task1, task2, 45 TaskEquality.LEXICALLY_EQUAL); 46 return (equality != null) 47 && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 48 } 49 50 /* 51 * (non-Javadoc) 52 * 53 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 54 */ 55 @Override 56 public boolean areLexicallyEqual(ITaskInstance instance1, 57 ITaskInstance instance2) { 58 final TaskEquality equality = getEquality(instance1, instance2, 59 TaskEquality.LEXICALLY_EQUAL); 60 return (equality != null) 61 && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 62 } 63 64 /* 65 * (non-Javadoc) 66 * 67 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 68 */ 69 @Override 70 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 71 final TaskEquality equality = getEquality(task1, task2, 72 TaskEquality.SEMANTICALLY_EQUAL); 73 return (equality != null) 74 && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 75 } 76 77 /* 78 * (non-Javadoc) 79 * 80 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 81 * ITaskInstance) 82 */ 83 @Override 84 public boolean areSemanticallyEqual(ITaskInstance instance1, 85 ITaskInstance instance2) { 86 final TaskEquality equality = getEquality(instance1, instance2, 87 TaskEquality.SEMANTICALLY_EQUAL); 88 return (equality != null) 89 && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 90 } 91 92 /* 93 * (non-Javadoc) 94 * 95 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 96 */ 97 @Override 98 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 99 final TaskEquality equality = getEquality(task1, task2, 100 TaskEquality.SYNTACTICALLY_EQUAL); 101 return (equality != null) 102 && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 103 } 104 105 /* 106 * (non-Javadoc) 107 * 108 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 109 * ITaskInstance) 110 */ 111 @Override 112 public boolean areSyntacticallyEqual(ITaskInstance instance1, 113 ITaskInstance instance2) { 114 final TaskEquality equality = getEquality(instance1, instance2, 115 TaskEquality.SYNTACTICALLY_EQUAL); 116 return (equality != null) 117 && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 118 } 119 120 /** 121 * <p> 122 * used to to call the task equality rule manager for the comparison of the 123 * two provided children. If no required equality level is provided, than 124 * the most concrete equality is returned. Otherwise, the required equality 125 * is returned as long as the children are equal on that level. 126 * </p> 127 * 128 * @param child1 129 * the first task to be compared 130 * @param child2 131 * the second task to be compared 132 * @param requiredEqualityLevel 133 * the equality level to be checked for 134 * 135 * @return the determined equality 136 */ 137 private TaskEquality callRuleManager(ITask child1, ITask child2, 138 TaskEquality requiredEqualityLevel) { 139 if (requiredEqualityLevel == null) { 140 return TaskEqualityRuleManager.getInstance() 141 .compare(child1, child2); 142 } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 143 child1, child2, requiredEqualityLevel)) { 144 return requiredEqualityLevel; 145 } else { 146 return TaskEquality.UNEQUAL; 147 } 148 } 149 150 /** 151 * <p> 152 * used to to call the task equality rule manager for the comparison of the 153 * two provided children. If no required equality level is provided, than 154 * the most concrete equality is returned. Otherwise, the required equality 155 * is returned as long as the children are equal on that level. 156 * </p> 157 * 158 * @param taskInstance1 159 * the first task instance to be compared 160 * @param taskInstance2 161 * the second task instance to be compared 162 * @param requiredEqualityLevel 163 * the equality level to be checked for 164 * 165 * @return the determined equality 166 */ 167 private TaskEquality callRuleManager(ITaskInstance taskInstance1, 168 ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 169 if (requiredEqualityLevel == null) { 170 return TaskEqualityRuleManager.getInstance().compare(taskInstance1, 171 taskInstance2); 172 } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 173 taskInstance1, taskInstance2, requiredEqualityLevel)) { 174 return requiredEqualityLevel; 175 } else { 176 return TaskEquality.UNEQUAL; 177 } 178 } 179 180 /* 181 * (non-Javadoc) 182 * 183 * @see TaskComparisonRule#compare(ITask, ITask) 184 */ 185 @Override 186 public TaskEquality compare(ITask task1, ITask task2) { 187 return getEquality(task1, task2, null); 188 } 189 190 /* 191 * (non-Javadoc) 192 * 193 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 194 */ 195 @Override 196 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 197 return getEquality(instance1, instance2, null); 198 } 199 200 /** 201 * <p> 202 * compares two sequences with each other checking for the provided required 203 * level of equality. If this level is ensured, the method immediately 204 * returns. The more concrete the required equality level, the more checks 205 * this method performs. 206 * </p> 207 * 208 * @param task1 209 * the first task to be compared 210 * @param task2 211 * the second task to be compared 212 * @param requiredEqualityLevel 213 * the equality level to be checked for 214 * 215 * @return the determined equality. 216 */ 217 private TaskEquality getEquality(ITask task1, ITask task2, 218 TaskEquality requiredEqualityLevel) { 219 final List<ITask> children1 = ((ISequence) task1).getChildren(); 220 final List<ITask> children2 = ((ISequence) task2).getChildren(); 221 222 // if both sequences do not have children, they are equal although this 223 // doesn't make sense 224 if ((children1.size() == 0) && (children2.size() == 0)) { 225 return TaskEquality.LEXICALLY_EQUAL; 226 } 227 228 if (children1.size() != children2.size()) { 229 return TaskEquality.UNEQUAL; 230 } 231 232 TaskEquality resultingEquality = TaskEquality.LEXICALLY_EQUAL; 233 for (int i = 0; i < children1.size(); i++) { 234 final ITask child1 = children1.get(i); 235 final ITask child2 = children2.get(i); 236 237 final TaskEquality taskEquality = callRuleManager(child1, child2, 238 requiredEqualityLevel); 239 240 if ((taskEquality == null) 241 || (taskEquality == TaskEquality.UNEQUAL)) { 242 return TaskEquality.UNEQUAL; 243 } 244 245 resultingEquality = resultingEquality 246 .getCommonDenominator(taskEquality); 247 } 248 249 return resultingEquality; 250 } 251 252 /** 253 * <p> 254 * compares two sequence instances with each other checking for the provided 255 * required level of equality. If this level is ensured, the method 256 * immediately returns. The more concrete the required equality level, the 257 * more checks this method performs. 258 * </p> 259 * 260 * @param taskInstance1 261 * the first task instance to be compared 262 * @param taskInstance2 263 * the second task instance to be compared 264 * @param requiredEqualityLevel 265 * the equality level to be checked for 266 * 267 * @return the determined equality. 268 */ 269 private TaskEquality getEquality(ITaskInstance taskInstance1, 270 ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 271 final ISequenceInstance sequence1 = (ISequenceInstance) taskInstance1; 272 final ISequenceInstance sequence2 = (ISequenceInstance) taskInstance2; 273 274 // if both sequences do not have children, they are equal although this 275 // doesn't make sense 276 if ((sequence1.size() == 0) && (sequence2.size() == 0)) { 277 return TaskEquality.LEXICALLY_EQUAL; 278 } 279 280 if (sequence1.size() != sequence2.size()) { 281 return TaskEquality.UNEQUAL; 282 } 283 284 TaskEquality resultingEquality = TaskEquality.LEXICALLY_EQUAL; 285 for (int i = 0; i < sequence1.size(); i++) { 286 final ITaskInstance child1 = sequence1.get(i); 287 final ITaskInstance child2 = sequence2.get(i); 288 289 final TaskEquality taskEquality = callRuleManager(child1, child2, 290 requiredEqualityLevel); 291 292 if ((taskEquality == null) 293 || (taskEquality == TaskEquality.UNEQUAL)) { 294 return TaskEquality.UNEQUAL; 295 } 296 297 resultingEquality = resultingEquality 298 .getCommonDenominator(taskEquality); 299 } 300 301 return resultingEquality; 302 } 303 304 /* 305 * (non-Javadoc) 306 * 307 * @see TaskComparisonRule#isApplicable(ITask, ITask) 308 */ 309 @Override 310 public boolean isApplicable(ITask task1, ITask task2) { 311 return (task1 instanceof ISequence) && (task2 instanceof ISequence); 312 } 313 314 /* 315 * (non-Javadoc) 316 * 317 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 318 */ 319 @Override 320 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 321 return isApplicable(instance1.getTask(), instance2.getTask()); 322 } 273 323 } -
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndIterationComparisonRule.java
r1294 r1733 23 23 * <p> 24 24 * This class is capable of comparing any task which is not an iteration with an 25 * iteration. This is needed, because iterations may iterate exactly that task. In this 26 * case, the iteration would be equal to that task if it was executed exactly once. The rule 27 * returns lexically equal, it the child of the iteration is lexically equal to the task 28 * or if the child of the iteration is a selection and this selections contains a lexically equal 29 * task. The same applies for syntactical and semantical equality. 25 * iteration. This is needed, because iterations may iterate exactly that task. 26 * In this case, the iteration would be equal to that task if it was executed 27 * exactly once. The rule returns lexically equal, it the child of the iteration 28 * is lexically equal to the task or if the child of the iteration is a 29 * selection and this selections contains a lexically equal task. The same 30 * applies for syntactical and semantical equality. 30 31 * </p> 31 32 * 32 33 * @author Patrick Harms 33 34 */ 34 35 public class TaskAndIterationComparisonRule implements TaskComparisonRule { 35 36 /* (non-Javadoc) 37 * @see TaskComparisonRule#isApplicable(ITask, ITask) 38 */ 39 @Override 40 public boolean isApplicable(ITask task1, ITask task2) { 41 return ((task1 instanceof IIteration) && (!(task2 instanceof IIteration))) || 42 ((task2 instanceof IIteration) && (!(task1 instanceof IIteration))); 43 } 44 45 /* (non-Javadoc) 46 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 47 */ 48 @Override 49 public boolean areLexicallyEqual(ITask task1, ITask task2) { 50 TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL); 51 return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 52 } 53 54 /* (non-Javadoc) 55 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 56 */ 57 @Override 58 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 59 TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL); 60 return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 61 } 62 63 /* (non-Javadoc) 64 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 65 */ 66 @Override 67 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 68 TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL); 69 return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 70 } 71 72 /* (non-Javadoc) 73 * @see TaskComparisonRule#compare(ITask, ITask) 74 */ 75 @Override 76 public TaskEquality compare(ITask task1, ITask task2) { 77 return getEquality(task1, task2, null); 78 } 79 80 /* (non-Javadoc) 81 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 82 */ 83 @Override 84 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 85 return isApplicable(instance1.getTask(), instance2.getTask()); 86 } 87 88 /* (non-Javadoc) 89 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 90 */ 91 @Override 92 public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 93 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL); 94 return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 95 } 96 97 /* (non-Javadoc) 98 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 99 */ 100 @Override 101 public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 102 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL); 103 return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 104 } 105 106 /* (non-Javadoc) 107 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 108 */ 109 @Override 110 public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 111 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL); 112 return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 113 } 114 115 /* (non-Javadoc) 116 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 117 */ 118 @Override 119 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 120 return getEquality(instance1, instance2, null); 121 } 122 123 /** 124 * <p> 125 * compares two tasks with each other checking for the provided required level of 126 * equality. One of the tasks must be an iteration, the other one not. If this is not the 127 * case, the method returns null. The returned equality level is at most lexical equality 128 * as the iteration can not be identical to something not being an iteration. 129 * </p> 130 * 131 * @param task1 the first task to be compared 132 * @param task2 the second task to be compared 133 * @param requiredEqualityLevel the equality level to be checked for 134 * 135 * @return the determined equality. 136 */ 137 private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) { 138 IIteration iteration = null; 139 ITask task = null; 140 141 if (task1 instanceof IIteration) { 142 if (task2 instanceof IIteration) { 143 // the rule is not responsible for two iterations 144 return null; 145 } 146 147 iteration = (IIteration) task1; 148 task = task2; 149 } 150 else if (task2 instanceof IIteration) { 151 if (task1 instanceof IIteration) { 152 // the rule is not responsible for two iterations 153 return null; 154 } 155 156 iteration = (IIteration) task2; 157 task = task1; 158 } 159 else { 160 return null; 161 } 162 163 ITask child = iteration.getMarkedTask(); 164 165 // now, that we found the iteration and the task, lets compare the child of the iteration 166 // with the task. 167 if (child == null) { 168 return null; 169 } 170 171 TaskEquality taskEquality = callRuleManager(child, task, requiredEqualityLevel); 172 173 // although the subtask may be identical to the task, we can not return identical, as 174 // the iteration is not identical to the task, but at most lexically equal 175 if (taskEquality == TaskEquality.IDENTICAL) { 176 return TaskEquality.LEXICALLY_EQUAL; 177 } 178 else { 179 return taskEquality; 180 } 181 182 } 183 184 /** 185 * <p> 186 * used to to call the task equality rule manager for the comparison of the two provided 187 * children. If no required equality level is provided, than the most concrete equality is 188 * returned. Otherwise, the required equality is returned as long as the children are equal 189 * on that level. 190 * </p> 191 * 192 * @param child1 the first task to be compared 193 * @param child2 the second task to be compared 194 * @param requiredEqualityLevel the equality level to be checked for 195 * 196 * @return the determined equality 197 */ 198 private TaskEquality callRuleManager(ITask child1, 199 ITask child2, 200 TaskEquality requiredEqualityLevel) 201 { 202 if (requiredEqualityLevel == null) { 203 return TaskEqualityRuleManager.getInstance().compare(child1, child2); 204 } 205 else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 206 (child1, child2, requiredEqualityLevel)) 207 { 208 return requiredEqualityLevel; 209 } 210 else { 211 return TaskEquality.UNEQUAL; 212 } 213 } 214 215 /** 216 * <p> 217 * compares two task instances with each other checking for the provided required level of 218 * equality. One of the task instances must be a iteration, the other one not. If this is not 219 * the case, the method returns null. The returned equality level is at most lexical equality 220 * as the iteration can not be identical to something not being a iteration. 221 * </p> 222 * 223 * @param taskInstance1 the first task instance to be compared 224 * @param taskInstance2 the second task instance to be compared 225 * @param requiredEqualityLevel the equality level to be checked for 226 * 227 * @return the determined equality. 228 */ 229 private TaskEquality getEquality(ITaskInstance taskInstance1, 230 ITaskInstance taskInstance2, 231 TaskEquality requiredEqualityLevel) 232 { 233 IIterationInstance iteration = null; 234 ITaskInstance task = null; 235 236 if (taskInstance1 instanceof IIterationInstance) { 237 if (taskInstance2 instanceof IIterationInstance) { 238 // the rule is not responsible for two iterations 239 return null; 240 } 241 242 iteration = (IIterationInstance) taskInstance1; 243 task = taskInstance2; 244 } 245 else if (taskInstance2 instanceof IIterationInstance) { 246 if (taskInstance1 instanceof IIterationInstance) { 247 // the rule is not responsible for two iterations 248 return null; 249 } 250 251 iteration = (IIterationInstance) taskInstance2; 252 task = taskInstance1; 253 } 254 else { 255 return null; 256 } 257 258 // now, that we found the iteration and the task, lets compare the children of the iteration 259 // with the task. 260 261 if (iteration.size() < 1) { 262 return null; 263 } 264 265 TaskEquality mostConcreteNodeEquality = null; 266 267 for (ITaskInstance child : iteration) { 268 TaskEquality taskEquality = callRuleManager(child, task, requiredEqualityLevel); 269 270 if (taskEquality != TaskEquality.UNEQUAL) { 271 if (mostConcreteNodeEquality == null) { 272 mostConcreteNodeEquality = taskEquality; 273 } 274 else if (mostConcreteNodeEquality.isAtLeast(taskEquality)) { 275 mostConcreteNodeEquality = taskEquality; 276 277 } 278 279 if ((requiredEqualityLevel != null) && 280 (mostConcreteNodeEquality.isAtLeast(requiredEqualityLevel))) 281 { 282 // if we found one child of the selection that is as equal as required, then 283 // we can consider the selection to be sufficiently equal to the other task. 284 // So we break up checking further children. 285 break; 286 } 287 } 288 } 289 290 // although the subtask may be identical to the task, we can not return identical, as 291 // the selection is not identical to the task, but at most lexically equal 292 if (mostConcreteNodeEquality == TaskEquality.IDENTICAL) { 293 return TaskEquality.LEXICALLY_EQUAL; 294 } 295 else { 296 return mostConcreteNodeEquality; 297 } 298 299 } 300 301 /** 302 * <p> 303 * used to to call the task equality rule manager for the comparison of the two provided 304 * children. If no required equality level is provided, than the most concrete equality is 305 * returned. Otherwise, the required equality is returned as long as the children are equal 306 * on that level. 307 * </p> 308 * 309 * @param taskInstance1 the first task instance to be compared 310 * @param taskInstance2 the second task instance to be compared 311 * @param requiredEqualityLevel the equality level to be checked for 312 * 313 * @return the determined equality 314 */ 315 private TaskEquality callRuleManager(ITaskInstance taskInstance1, 316 ITaskInstance taskInstance2, 317 TaskEquality requiredEqualityLevel) 318 { 319 if (requiredEqualityLevel == null) { 320 return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2); 321 } 322 else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 323 (taskInstance1, taskInstance2, requiredEqualityLevel)) 324 { 325 return requiredEqualityLevel; 326 } 327 else { 328 return TaskEquality.UNEQUAL; 329 } 330 } 36 37 /* 38 * (non-Javadoc) 39 * 40 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 41 */ 42 @Override 43 public boolean areLexicallyEqual(ITask task1, ITask task2) { 44 final TaskEquality equality = getEquality(task1, task2, 45 TaskEquality.LEXICALLY_EQUAL); 46 return (equality != null) 47 && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 48 } 49 50 /* 51 * (non-Javadoc) 52 * 53 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 54 */ 55 @Override 56 public boolean areLexicallyEqual(ITaskInstance instance1, 57 ITaskInstance instance2) { 58 final TaskEquality equality = getEquality(instance1, instance2, 59 TaskEquality.LEXICALLY_EQUAL); 60 return (equality != null) 61 && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 62 } 63 64 /* 65 * (non-Javadoc) 66 * 67 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 68 */ 69 @Override 70 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 71 final TaskEquality equality = getEquality(task1, task2, 72 TaskEquality.SEMANTICALLY_EQUAL); 73 return (equality != null) 74 && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 75 } 76 77 /* 78 * (non-Javadoc) 79 * 80 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 81 * ITaskInstance) 82 */ 83 @Override 84 public boolean areSemanticallyEqual(ITaskInstance instance1, 85 ITaskInstance instance2) { 86 final TaskEquality equality = getEquality(instance1, instance2, 87 TaskEquality.SEMANTICALLY_EQUAL); 88 return (equality != null) 89 && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 90 } 91 92 /* 93 * (non-Javadoc) 94 * 95 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 96 */ 97 @Override 98 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 99 final TaskEquality equality = getEquality(task1, task2, 100 TaskEquality.SYNTACTICALLY_EQUAL); 101 return (equality != null) 102 && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 103 } 104 105 /* 106 * (non-Javadoc) 107 * 108 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 109 * ITaskInstance) 110 */ 111 @Override 112 public boolean areSyntacticallyEqual(ITaskInstance instance1, 113 ITaskInstance instance2) { 114 final TaskEquality equality = getEquality(instance1, instance2, 115 TaskEquality.SYNTACTICALLY_EQUAL); 116 return (equality != null) 117 && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 118 } 119 120 /** 121 * <p> 122 * used to to call the task equality rule manager for the comparison of the 123 * two provided children. If no required equality level is provided, than 124 * the most concrete equality is returned. Otherwise, the required equality 125 * is returned as long as the children are equal on that level. 126 * </p> 127 * 128 * @param child1 129 * the first task to be compared 130 * @param child2 131 * the second task to be compared 132 * @param requiredEqualityLevel 133 * the equality level to be checked for 134 * 135 * @return the determined equality 136 */ 137 private TaskEquality callRuleManager(ITask child1, ITask child2, 138 TaskEquality requiredEqualityLevel) { 139 if (requiredEqualityLevel == null) { 140 return TaskEqualityRuleManager.getInstance() 141 .compare(child1, child2); 142 } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 143 child1, child2, requiredEqualityLevel)) { 144 return requiredEqualityLevel; 145 } else { 146 return TaskEquality.UNEQUAL; 147 } 148 } 149 150 /** 151 * <p> 152 * used to to call the task equality rule manager for the comparison of the 153 * two provided children. If no required equality level is provided, than 154 * the most concrete equality is returned. Otherwise, the required equality 155 * is returned as long as the children are equal on that level. 156 * </p> 157 * 158 * @param taskInstance1 159 * the first task instance to be compared 160 * @param taskInstance2 161 * the second task instance to be compared 162 * @param requiredEqualityLevel 163 * the equality level to be checked for 164 * 165 * @return the determined equality 166 */ 167 private TaskEquality callRuleManager(ITaskInstance taskInstance1, 168 ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 169 if (requiredEqualityLevel == null) { 170 return TaskEqualityRuleManager.getInstance().compare(taskInstance1, 171 taskInstance2); 172 } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 173 taskInstance1, taskInstance2, requiredEqualityLevel)) { 174 return requiredEqualityLevel; 175 } else { 176 return TaskEquality.UNEQUAL; 177 } 178 } 179 180 /* 181 * (non-Javadoc) 182 * 183 * @see TaskComparisonRule#compare(ITask, ITask) 184 */ 185 @Override 186 public TaskEquality compare(ITask task1, ITask task2) { 187 return getEquality(task1, task2, null); 188 } 189 190 /* 191 * (non-Javadoc) 192 * 193 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 194 */ 195 @Override 196 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 197 return getEquality(instance1, instance2, null); 198 } 199 200 /** 201 * <p> 202 * compares two tasks with each other checking for the provided required 203 * level of equality. One of the tasks must be an iteration, the other one 204 * not. If this is not the case, the method returns null. The returned 205 * equality level is at most lexical equality as the iteration can not be 206 * identical to something not being an iteration. 207 * </p> 208 * 209 * @param task1 210 * the first task to be compared 211 * @param task2 212 * the second task to be compared 213 * @param requiredEqualityLevel 214 * the equality level to be checked for 215 * 216 * @return the determined equality. 217 */ 218 private TaskEquality getEquality(ITask task1, ITask task2, 219 TaskEquality requiredEqualityLevel) { 220 IIteration iteration = null; 221 ITask task = null; 222 223 if (task1 instanceof IIteration) { 224 if (task2 instanceof IIteration) { 225 // the rule is not responsible for two iterations 226 return null; 227 } 228 229 iteration = (IIteration) task1; 230 task = task2; 231 } else if (task2 instanceof IIteration) { 232 if (task1 instanceof IIteration) { 233 // the rule is not responsible for two iterations 234 return null; 235 } 236 237 iteration = (IIteration) task2; 238 task = task1; 239 } else { 240 return null; 241 } 242 243 final ITask child = iteration.getMarkedTask(); 244 245 // now, that we found the iteration and the task, lets compare the child 246 // of the iteration 247 // with the task. 248 if (child == null) { 249 return null; 250 } 251 252 final TaskEquality taskEquality = callRuleManager(child, task, 253 requiredEqualityLevel); 254 255 // although the subtask may be identical to the task, we can not return 256 // identical, as 257 // the iteration is not identical to the task, but at most lexically 258 // equal 259 if (taskEquality == TaskEquality.IDENTICAL) { 260 return TaskEquality.LEXICALLY_EQUAL; 261 } else { 262 return taskEquality; 263 } 264 265 } 266 267 /** 268 * <p> 269 * compares two task instances with each other checking for the provided 270 * required level of equality. One of the task instances must be a 271 * iteration, the other one not. If this is not the case, the method returns 272 * null. The returned equality level is at most lexical equality as the 273 * iteration can not be identical to something not being a iteration. 274 * </p> 275 * 276 * @param taskInstance1 277 * the first task instance to be compared 278 * @param taskInstance2 279 * the second task instance to be compared 280 * @param requiredEqualityLevel 281 * the equality level to be checked for 282 * 283 * @return the determined equality. 284 */ 285 private TaskEquality getEquality(ITaskInstance taskInstance1, 286 ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 287 IIterationInstance iteration = null; 288 ITaskInstance task = null; 289 290 if (taskInstance1 instanceof IIterationInstance) { 291 if (taskInstance2 instanceof IIterationInstance) { 292 // the rule is not responsible for two iterations 293 return null; 294 } 295 296 iteration = (IIterationInstance) taskInstance1; 297 task = taskInstance2; 298 } else if (taskInstance2 instanceof IIterationInstance) { 299 if (taskInstance1 instanceof IIterationInstance) { 300 // the rule is not responsible for two iterations 301 return null; 302 } 303 304 iteration = (IIterationInstance) taskInstance2; 305 task = taskInstance1; 306 } else { 307 return null; 308 } 309 310 // now, that we found the iteration and the task, lets compare the 311 // children of the iteration 312 // with the task. 313 314 if (iteration.size() < 1) { 315 return null; 316 } 317 318 TaskEquality mostConcreteNodeEquality = null; 319 320 for (final ITaskInstance child : iteration) { 321 final TaskEquality taskEquality = callRuleManager(child, task, 322 requiredEqualityLevel); 323 324 if (taskEquality != TaskEquality.UNEQUAL) { 325 if (mostConcreteNodeEquality == null) { 326 mostConcreteNodeEquality = taskEquality; 327 } else if (mostConcreteNodeEquality.isAtLeast(taskEquality)) { 328 mostConcreteNodeEquality = taskEquality; 329 330 } 331 332 if ((requiredEqualityLevel != null) 333 && (mostConcreteNodeEquality 334 .isAtLeast(requiredEqualityLevel))) { 335 // if we found one child of the selection that is as equal 336 // as required, then 337 // we can consider the selection to be sufficiently equal to 338 // the other task. 339 // So we break up checking further children. 340 break; 341 } 342 } 343 } 344 345 // although the subtask may be identical to the task, we can not return 346 // identical, as 347 // the selection is not identical to the task, but at most lexically 348 // equal 349 if (mostConcreteNodeEquality == TaskEquality.IDENTICAL) { 350 return TaskEquality.LEXICALLY_EQUAL; 351 } else { 352 return mostConcreteNodeEquality; 353 } 354 355 } 356 357 /* 358 * (non-Javadoc) 359 * 360 * @see TaskComparisonRule#isApplicable(ITask, ITask) 361 */ 362 @Override 363 public boolean isApplicable(ITask task1, ITask task2) { 364 return ((task1 instanceof IIteration) && (!(task2 instanceof IIteration))) 365 || ((task2 instanceof IIteration) && (!(task1 instanceof IIteration))); 366 } 367 368 /* 369 * (non-Javadoc) 370 * 371 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 372 */ 373 @Override 374 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 375 return isApplicable(instance1.getTask(), instance2.getTask()); 376 } 331 377 } -
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndSelectionComparisonRule.java
r1294 r1733 25 25 * <p> 26 26 * This class is capable of comparing any task which is not a selection with a 27 * selection. This is needed, because selections may contain exactly that task. Therefore, if 28 * this task is selected out of a selection the selection is equal to the task itself. 29 * The rule returns lexically equal, if the selection contains a lexically equal task. The same 30 * applies for syntactical and semantical equality. 27 * selection. This is needed, because selections may contain exactly that task. 28 * Therefore, if this task is selected out of a selection the selection is equal 29 * to the task itself. The rule returns lexically equal, if the selection 30 * contains a lexically equal task. The same applies for syntactical and 31 * semantical equality. 31 32 * </p> 32 33 * 33 34 * @author Patrick Harms 34 35 */ 35 36 public class TaskAndSelectionComparisonRule implements TaskComparisonRule { 36 37 /* (non-Javadoc) 38 * @see TaskComparisonRule#isApplicable(ITask, ITask) 39 */ 40 @Override 41 public boolean isApplicable(ITask task1, ITask task2) { 42 return ((task1 instanceof ISelection) && (!(task2 instanceof ISelection))) || 43 ((task2 instanceof ISelection) && (!(task1 instanceof ISelection))); 44 } 45 46 /* (non-Javadoc) 47 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 48 */ 49 @Override 50 public boolean areLexicallyEqual(ITask task1, ITask task2) { 51 TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL); 52 return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 53 } 54 55 /* (non-Javadoc) 56 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 57 */ 58 @Override 59 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 60 TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL); 61 return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 62 } 63 64 /* (non-Javadoc) 65 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 66 */ 67 @Override 68 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 69 TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL); 70 return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 71 } 72 73 /* (non-Javadoc) 74 * @see TaskComparisonRule#compare(ITask, ITask) 75 */ 76 @Override 77 public TaskEquality compare(ITask task1, ITask task2) { 78 return getEquality(task1, task2, null); 79 } 80 81 /* (non-Javadoc) 82 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 83 */ 84 @Override 85 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 86 return isApplicable(instance1.getTask(), instance2.getTask()); 87 } 88 89 /* (non-Javadoc) 90 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 91 */ 92 @Override 93 public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 94 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL); 95 return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 96 } 97 98 /* (non-Javadoc) 99 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 100 */ 101 @Override 102 public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 103 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL); 104 return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 105 } 106 107 /* (non-Javadoc) 108 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 109 */ 110 @Override 111 public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 112 TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL); 113 return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 114 } 115 116 /* (non-Javadoc) 117 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 118 */ 119 @Override 120 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 121 return getEquality(instance1, instance2, null); 122 } 123 124 /** 125 * <p> 126 * compares two tasks with each other checking for the provided required level of 127 * equality. One of the tasks must be a selection, the other one not. If this is not the 128 * case, the method returns null. The returned equality level is at most lexical equality 129 * as the selection can not be identical to something not being a selection. 130 * </p> 131 * 132 * @param task1 the first task to be compared 133 * @param task2 the second task to be compared 134 * @param requiredEqualityLevel the equality level to be checked for 135 * 136 * @return the determined equality. 137 */ 138 private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) { 139 ISelection selection = null; 140 ITask task = null; 141 142 if (task1 instanceof ISelection) { 143 if (task2 instanceof ISelection) { 144 // the rule is not responsible for two selections 145 return null; 146 } 147 148 selection = (ISelection) task1; 149 task = task2; 150 } 151 else if (task2 instanceof ISelection) { 152 if (task1 instanceof ISelection) { 153 // the rule is not responsible for two selections 154 return null; 155 } 156 157 selection = (ISelection) task2; 158 task = task1; 159 } 160 else { 161 return null; 162 } 163 164 // now, that we found the selection and the task, lets compare the children of the selection 165 // with the task. 166 List<ITask> children = selection.getChildren(); 167 168 if (children.size() < 1) { 169 return null; 170 } 171 172 TaskEquality mostConcreteNodeEquality = null; 173 174 for (ITask child : children) { 175 TaskEquality taskEquality = callRuleManager(child, task, requiredEqualityLevel); 176 177 if (taskEquality != TaskEquality.UNEQUAL) { 178 if (mostConcreteNodeEquality == null) { 179 mostConcreteNodeEquality = taskEquality; 180 } 181 else if (mostConcreteNodeEquality.isAtLeast(taskEquality)) { 182 mostConcreteNodeEquality = taskEquality; 183 184 } 185 186 if ((requiredEqualityLevel != null) && 187 (mostConcreteNodeEquality.isAtLeast(requiredEqualityLevel))) 188 { 189 // if we found one child of the selection that is as equal as required, then 190 // we can consider the selection to be sufficiently equal to the other task. 191 // So we break up checking further children. 192 break; 193 } 194 } 195 } 196 197 // although the subtask may be identical to the task, we can not return identical, as 198 // the selection is not identical to the task, but at most lexically equal 199 if (mostConcreteNodeEquality == TaskEquality.IDENTICAL) { 200 return TaskEquality.LEXICALLY_EQUAL; 201 } 202 else { 203 return mostConcreteNodeEquality; 204 } 205 206 } 207 208 /** 209 * <p> 210 * used to to call the task equality rule manager for the comparison of the two provided 211 * children. If no required equality level is provided, than the most concrete equality is 212 * returned. Otherwise, the required equality is returned as long as the children are equal 213 * on that level. 214 * </p> 215 * 216 * @param child1 the first task to be compared 217 * @param child2 the second task to be compared 218 * @param requiredEqualityLevel the equality level to be checked for 219 * 220 * @return the determined equality 221 */ 222 private TaskEquality callRuleManager(ITask child1, 223 ITask child2, 224 TaskEquality requiredEqualityLevel) 225 { 226 if (requiredEqualityLevel == null) { 227 return TaskEqualityRuleManager.getInstance().compare(child1, child2); 228 } 229 else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 230 (child1, child2, requiredEqualityLevel)) 231 { 232 return requiredEqualityLevel; 233 } 234 else { 235 return TaskEquality.UNEQUAL; 236 } 237 } 238 239 /** 240 * <p> 241 * compares two task instances with each other checking for the provided required level of 242 * equality. One of the task instances must be a selection, the other one not. If this is not 243 * the case, the method returns null. The returned equality level is at most lexical equality 244 * as the selection can not be identical to something not being a selection. 245 * </p> 246 * 247 * @param taskInstance1 the first task instance to be compared 248 * @param taskInstance2 the second task instance to be compared 249 * @param requiredEqualityLevel the equality level to be checked for 250 * 251 * @return the determined equality. 252 */ 253 private TaskEquality getEquality(ITaskInstance taskInstance1, 254 ITaskInstance taskInstance2, 255 TaskEquality requiredEqualityLevel) 256 { 257 ISelectionInstance selection = null; 258 ITaskInstance task = null; 259 260 if (taskInstance1 instanceof ISelectionInstance) { 261 if (taskInstance2 instanceof ISelectionInstance) { 262 // the rule is not responsible for two selections 263 return null; 264 } 265 266 selection = (ISelectionInstance) taskInstance1; 267 task = taskInstance2; 268 } 269 else if (taskInstance2 instanceof ISelectionInstance) { 270 if (taskInstance1 instanceof ISelectionInstance) { 271 // the rule is not responsible for two selections 272 return null; 273 } 274 275 selection = (ISelectionInstance) taskInstance2; 276 task = taskInstance1; 277 } 278 else { 279 return null; 280 } 281 282 // now, that we found the selection and the task, lets compare the child of the selection 283 // with the task. 284 ITaskInstance child = selection.getChild(); 285 286 if (child == null) { 287 return null; 288 } 289 290 TaskEquality taskEquality = callRuleManager(child, task, requiredEqualityLevel); 291 292 // although the subtask may be identical to the task, we can not return identical, as 293 // the selection is not identical to the task, but at most lexically equal 294 if (taskEquality == TaskEquality.IDENTICAL) { 295 return TaskEquality.LEXICALLY_EQUAL; 296 } 297 else { 298 return taskEquality; 299 } 300 301 } 302 303 /** 304 * <p> 305 * used to to call the task equality rule manager for the comparison of the two provided 306 * children. If no required equality level is provided, than the most concrete equality is 307 * returned. Otherwise, the required equality is returned as long as the children are equal 308 * on that level. 309 * </p> 310 * 311 * @param taskInstance1 the first task instance to be compared 312 * @param taskInstance2 the second task instance to be compared 313 * @param requiredEqualityLevel the equality level to be checked for 314 * 315 * @return the determined equality 316 */ 317 private TaskEquality callRuleManager(ITaskInstance taskInstance1, 318 ITaskInstance taskInstance2, 319 TaskEquality requiredEqualityLevel) 320 { 321 if (requiredEqualityLevel == null) { 322 return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2); 323 } 324 else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual 325 (taskInstance1, taskInstance2, requiredEqualityLevel)) 326 { 327 return requiredEqualityLevel; 328 } 329 else { 330 return TaskEquality.UNEQUAL; 331 } 332 } 37 38 /* 39 * (non-Javadoc) 40 * 41 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 42 */ 43 @Override 44 public boolean areLexicallyEqual(ITask task1, ITask task2) { 45 final TaskEquality equality = getEquality(task1, task2, 46 TaskEquality.LEXICALLY_EQUAL); 47 return (equality != null) 48 && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 49 } 50 51 /* 52 * (non-Javadoc) 53 * 54 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 55 */ 56 @Override 57 public boolean areLexicallyEqual(ITaskInstance instance1, 58 ITaskInstance instance2) { 59 final TaskEquality equality = getEquality(instance1, instance2, 60 TaskEquality.LEXICALLY_EQUAL); 61 return (equality != null) 62 && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)); 63 } 64 65 /* 66 * (non-Javadoc) 67 * 68 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 69 */ 70 @Override 71 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 72 final TaskEquality equality = getEquality(task1, task2, 73 TaskEquality.SEMANTICALLY_EQUAL); 74 return (equality != null) 75 && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 76 } 77 78 /* 79 * (non-Javadoc) 80 * 81 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 82 * ITaskInstance) 83 */ 84 @Override 85 public boolean areSemanticallyEqual(ITaskInstance instance1, 86 ITaskInstance instance2) { 87 final TaskEquality equality = getEquality(instance1, instance2, 88 TaskEquality.SEMANTICALLY_EQUAL); 89 return (equality != null) 90 && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)); 91 } 92 93 /* 94 * (non-Javadoc) 95 * 96 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 97 */ 98 @Override 99 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 100 final TaskEquality equality = getEquality(task1, task2, 101 TaskEquality.SYNTACTICALLY_EQUAL); 102 return (equality != null) 103 && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 104 } 105 106 /* 107 * (non-Javadoc) 108 * 109 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 110 * ITaskInstance) 111 */ 112 @Override 113 public boolean areSyntacticallyEqual(ITaskInstance instance1, 114 ITaskInstance instance2) { 115 final TaskEquality equality = getEquality(instance1, instance2, 116 TaskEquality.SYNTACTICALLY_EQUAL); 117 return (equality != null) 118 && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)); 119 } 120 121 /** 122 * <p> 123 * used to to call the task equality rule manager for the comparison of the 124 * two provided children. If no required equality level is provided, than 125 * the most concrete equality is returned. Otherwise, the required equality 126 * is returned as long as the children are equal on that level. 127 * </p> 128 * 129 * @param child1 130 * the first task to be compared 131 * @param child2 132 * the second task to be compared 133 * @param requiredEqualityLevel 134 * the equality level to be checked for 135 * 136 * @return the determined equality 137 */ 138 private TaskEquality callRuleManager(ITask child1, ITask child2, 139 TaskEquality requiredEqualityLevel) { 140 if (requiredEqualityLevel == null) { 141 return TaskEqualityRuleManager.getInstance() 142 .compare(child1, child2); 143 } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 144 child1, child2, requiredEqualityLevel)) { 145 return requiredEqualityLevel; 146 } else { 147 return TaskEquality.UNEQUAL; 148 } 149 } 150 151 /** 152 * <p> 153 * used to to call the task equality rule manager for the comparison of the 154 * two provided children. If no required equality level is provided, than 155 * the most concrete equality is returned. Otherwise, the required equality 156 * is returned as long as the children are equal on that level. 157 * </p> 158 * 159 * @param taskInstance1 160 * the first task instance to be compared 161 * @param taskInstance2 162 * the second task instance to be compared 163 * @param requiredEqualityLevel 164 * the equality level to be checked for 165 * 166 * @return the determined equality 167 */ 168 private TaskEquality callRuleManager(ITaskInstance taskInstance1, 169 ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 170 if (requiredEqualityLevel == null) { 171 return TaskEqualityRuleManager.getInstance().compare(taskInstance1, 172 taskInstance2); 173 } else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual( 174 taskInstance1, taskInstance2, requiredEqualityLevel)) { 175 return requiredEqualityLevel; 176 } else { 177 return TaskEquality.UNEQUAL; 178 } 179 } 180 181 /* 182 * (non-Javadoc) 183 * 184 * @see TaskComparisonRule#compare(ITask, ITask) 185 */ 186 @Override 187 public TaskEquality compare(ITask task1, ITask task2) { 188 return getEquality(task1, task2, null); 189 } 190 191 /* 192 * (non-Javadoc) 193 * 194 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 195 */ 196 @Override 197 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 198 return getEquality(instance1, instance2, null); 199 } 200 201 /** 202 * <p> 203 * compares two tasks with each other checking for the provided required 204 * level of equality. One of the tasks must be a selection, the other one 205 * not. If this is not the case, the method returns null. The returned 206 * equality level is at most lexical equality as the selection can not be 207 * identical to something not being a selection. 208 * </p> 209 * 210 * @param task1 211 * the first task to be compared 212 * @param task2 213 * the second task to be compared 214 * @param requiredEqualityLevel 215 * the equality level to be checked for 216 * 217 * @return the determined equality. 218 */ 219 private TaskEquality getEquality(ITask task1, ITask task2, 220 TaskEquality requiredEqualityLevel) { 221 ISelection selection = null; 222 ITask task = null; 223 224 if (task1 instanceof ISelection) { 225 if (task2 instanceof ISelection) { 226 // the rule is not responsible for two selections 227 return null; 228 } 229 230 selection = (ISelection) task1; 231 task = task2; 232 } else if (task2 instanceof ISelection) { 233 if (task1 instanceof ISelection) { 234 // the rule is not responsible for two selections 235 return null; 236 } 237 238 selection = (ISelection) task2; 239 task = task1; 240 } else { 241 return null; 242 } 243 244 // now, that we found the selection and the task, lets compare the 245 // children of the selection 246 // with the task. 247 final List<ITask> children = selection.getChildren(); 248 249 if (children.size() < 1) { 250 return null; 251 } 252 253 TaskEquality mostConcreteNodeEquality = null; 254 255 for (final ITask child : children) { 256 final TaskEquality taskEquality = callRuleManager(child, task, 257 requiredEqualityLevel); 258 259 if (taskEquality != TaskEquality.UNEQUAL) { 260 if (mostConcreteNodeEquality == null) { 261 mostConcreteNodeEquality = taskEquality; 262 } else if (mostConcreteNodeEquality.isAtLeast(taskEquality)) { 263 mostConcreteNodeEquality = taskEquality; 264 265 } 266 267 if ((requiredEqualityLevel != null) 268 && (mostConcreteNodeEquality 269 .isAtLeast(requiredEqualityLevel))) { 270 // if we found one child of the selection that is as equal 271 // as required, then 272 // we can consider the selection to be sufficiently equal to 273 // the other task. 274 // So we break up checking further children. 275 break; 276 } 277 } 278 } 279 280 // although the subtask may be identical to the task, we can not return 281 // identical, as 282 // the selection is not identical to the task, but at most lexically 283 // equal 284 if (mostConcreteNodeEquality == TaskEquality.IDENTICAL) { 285 return TaskEquality.LEXICALLY_EQUAL; 286 } else { 287 return mostConcreteNodeEquality; 288 } 289 290 } 291 292 /** 293 * <p> 294 * compares two task instances with each other checking for the provided 295 * required level of equality. One of the task instances must be a 296 * selection, the other one not. If this is not the case, the method returns 297 * null. The returned equality level is at most lexical equality as the 298 * selection can not be identical to something not being a selection. 299 * </p> 300 * 301 * @param taskInstance1 302 * the first task instance to be compared 303 * @param taskInstance2 304 * the second task instance to be compared 305 * @param requiredEqualityLevel 306 * the equality level to be checked for 307 * 308 * @return the determined equality. 309 */ 310 private TaskEquality getEquality(ITaskInstance taskInstance1, 311 ITaskInstance taskInstance2, TaskEquality requiredEqualityLevel) { 312 ISelectionInstance selection = null; 313 ITaskInstance task = null; 314 315 if (taskInstance1 instanceof ISelectionInstance) { 316 if (taskInstance2 instanceof ISelectionInstance) { 317 // the rule is not responsible for two selections 318 return null; 319 } 320 321 selection = (ISelectionInstance) taskInstance1; 322 task = taskInstance2; 323 } else if (taskInstance2 instanceof ISelectionInstance) { 324 if (taskInstance1 instanceof ISelectionInstance) { 325 // the rule is not responsible for two selections 326 return null; 327 } 328 329 selection = (ISelectionInstance) taskInstance2; 330 task = taskInstance1; 331 } else { 332 return null; 333 } 334 335 // now, that we found the selection and the task, lets compare the child 336 // of the selection 337 // with the task. 338 final ITaskInstance child = selection.getChild(); 339 340 if (child == null) { 341 return null; 342 } 343 344 final TaskEquality taskEquality = callRuleManager(child, task, 345 requiredEqualityLevel); 346 347 // although the subtask may be identical to the task, we can not return 348 // identical, as 349 // the selection is not identical to the task, but at most lexically 350 // equal 351 if (taskEquality == TaskEquality.IDENTICAL) { 352 return TaskEquality.LEXICALLY_EQUAL; 353 } else { 354 return taskEquality; 355 } 356 357 } 358 359 /* 360 * (non-Javadoc) 361 * 362 * @see TaskComparisonRule#isApplicable(ITask, ITask) 363 */ 364 @Override 365 public boolean isApplicable(ITask task1, ITask task2) { 366 return ((task1 instanceof ISelection) && (!(task2 instanceof ISelection))) 367 || ((task2 instanceof ISelection) && (!(task1 instanceof ISelection))); 368 } 369 370 /* 371 * (non-Javadoc) 372 * 373 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 374 */ 375 @Override 376 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 377 return isApplicable(instance1.getTask(), instance2.getTask()); 378 } 333 379 } -
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskComparisonRule.java
r1294 r1733 20 20 /** 21 21 * <p> 22 * A task comparison rule is used by the {@link TaskEqualityRuleManager} to compare tasks and 23 * task instances with each other. It provides several methods to be called for a comparison. 22 * A task comparison rule is used by the {@link TaskEqualityRuleManager} to 23 * compare tasks and task instances with each other. It provides several methods 24 * to be called for a comparison. 24 25 * </p> 25 26 * … … 29 30 public interface TaskComparisonRule { 30 31 31 /** 32 * <p> 33 * checks if the rule is applicable for comparing the two provided tasks 34 * </p> 35 * 36 * @param task1 the first task to compare 37 * @param task2 the second task to compare 38 * 39 * @return true, if the rule is applicable, false else 40 */ 41 public boolean isApplicable(ITask task1, ITask task2); 32 /** 33 * <p> 34 * checks, if the provided tasks are lexically equal 35 * </p> 36 * 37 * @param task1 38 * the first task to compare 39 * @param task2 40 * the second task to compare 41 * 42 * @return true, if the tasks are equal, false else 43 */ 44 public boolean areLexicallyEqual(ITask task1, ITask task2); 42 45 43 /** 44 * <p> 45 * checks, if the provided tasks are lexically equal 46 * </p> 47 * 48 * @param task1 the first task to compare 49 * @param task2 the second task to compare 50 * 51 * @return true, if the tasks are equal, false else 52 */ 53 public boolean areLexicallyEqual(ITask task1, ITask task2); 46 /** 47 * <p> 48 * checks, if the provided task instances are lexically equal 49 * </p> 50 * 51 * @param instance1 52 * the first task instance to compare 53 * @param instance2 54 * the second task instance to compare 55 * 56 * @return true, if the tasks are equal, false else 57 */ 58 public boolean areLexicallyEqual(ITaskInstance instance1, 59 ITaskInstance instance2); 54 60 55 /** 56 * <p> 57 * checks, if the provided tasks are syntactically equal 58 * </p> 59 * 60 * @param task1 the first task to compare 61 * @param task2 the second task to compare 62 * 63 * @return true, if the tasks are equal, false else 64 */ 65 public boolean areSyntacticallyEqual(ITask task1, ITask task2); 61 /** 62 * <p> 63 * checks, if the provided tasks are semantically equal 64 * </p> 65 * 66 * @param task1 67 * the first task to compare 68 * @param task2 69 * the second task to compare 70 * 71 * @return true, if the tasks are equal, false else 72 */ 73 public boolean areSemanticallyEqual(ITask task1, ITask task2); 66 74 67 /** 68 * <p> 69 * checks, if the provided tasks are semantically equal 70 * </p> 71 * 72 * @param task1 the first task to compare 73 * @param task2 the second task to compare 74 * 75 * @return true, if the tasks are equal, false else 76 */ 77 public boolean areSemanticallyEqual(ITask task1, ITask task2); 75 /** 76 * <p> 77 * checks, if the provided task instances are semantically equal 78 * </p> 79 * 80 * @param instance1 81 * the first task instance to compare 82 * @param instance2 83 * the second task instance to compare 84 * 85 * @return true, if the tasks are equal, false else 86 */ 87 public boolean areSemanticallyEqual(ITaskInstance instance1, 88 ITaskInstance instance2); 78 89 79 80 81 * compares two tasks with each other. The result of the method is either a task equality or 82 * null. If it is null, it means, that the rule is not able to correctly compare the two given 83 * tasks 84 * </p> 85 * 86 * @param task1 the first task to compare 87 * @param task2the second task to compare88 89 * @return as described 90 91 public TaskEquality compare(ITask task1, ITask task2);90 /** 91 * <p> 92 * checks, if the provided tasks are syntactically equal 93 * </p> 94 * 95 * @param task1 96 * the first task to compare 97 * @param task2 98 * the second task to compare 99 * 100 * @return true, if the tasks are equal, false else 101 */ 102 public boolean areSyntacticallyEqual(ITask task1, ITask task2); 92 103 93 /** 94 * <p> 95 * checks if the rule is applicable for comparing the two provided task instances 96 * </p> 97 * 98 * @param instance1 the first task instance to compare 99 * @param instance2 the second task instance to compare 100 * 101 * @return true, if the rule is applicable, false else 102 */ 103 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2); 104 /** 105 * <p> 106 * checks, if the provided task instances are syntactically equal 107 * </p> 108 * 109 * @param instance1 110 * the first task instance to compare 111 * @param instance2 112 * the second task instance to compare 113 * 114 * @return true, if the tasks are equal, false else 115 */ 116 public boolean areSyntacticallyEqual(ITaskInstance instance1, 117 ITaskInstance instance2); 104 118 105 /** 106 * <p> 107 * checks, if the provided task instances are lexically equal 108 * </p> 109 * 110 * @param instance1 the first task instance to compare 111 * @param instance2 the second task instance to compare 112 * 113 * @return true, if the tasks are equal, false else 114 */ 115 public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2); 119 /** 120 * <p> 121 * compares two tasks with each other. The result of the method is either a 122 * task equality or null. If it is null, it means, that the rule is not able 123 * to correctly compare the two given tasks 124 * </p> 125 * 126 * @param task1 127 * the first task to compare 128 * @param task2 129 * the second task to compare 130 * 131 * @return as described 132 */ 133 public TaskEquality compare(ITask task1, ITask task2); 116 134 117 /** 118 * <p> 119 * checks, if the provided task instances are syntactically equal 120 * </p> 121 * 122 * @param instance1 the first task instance to compare 123 * @param instance2 the second task instance to compare 124 * 125 * @return true, if the tasks are equal, false else 126 */ 127 public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2); 135 /** 136 * <p> 137 * compares two task instances with each other. The result of the method is 138 * either a task instance equality or null. If it is null, it means, that 139 * the rule is not able to correctly compare the two given task instances 140 * </p> 141 * 142 * @param instance1 143 * the first task instance to compare 144 * @param instance2 145 * the second task instance to compare 146 * 147 * @return as described 148 */ 149 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2); 128 150 129 /** 130 * <p> 131 * checks, if the provided task instances are semantically equal 132 * </p> 133 * 134 * @param instance1 the first task instance to compare 135 * @param instance2 the second task instance to compare 136 * 137 * @return true, if the tasks are equal, false else 138 */ 139 public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2); 151 /** 152 * <p> 153 * checks if the rule is applicable for comparing the two provided tasks 154 * </p> 155 * 156 * @param task1 157 * the first task to compare 158 * @param task2 159 * the second task to compare 160 * 161 * @return true, if the rule is applicable, false else 162 */ 163 public boolean isApplicable(ITask task1, ITask task2); 140 164 141 /** 142 * <p> 143 * compares two task instances with each other. The result of the method is either a task 144 * instance equality or null. If it is null, it means, that the rule is not able to correctly 145 * compare the two given task instances 146 * </p> 147 * 148 * @param instance1 the first task instance to compare 149 * @param instance2 the second task instance to compare 150 * 151 * @return as described 152 */ 153 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2); 165 /** 166 * <p> 167 * checks if the rule is applicable for comparing the two provided task 168 * instances 169 * </p> 170 * 171 * @param instance1 172 * the first task instance to compare 173 * @param instance2 174 * the second task instance to compare 175 * 176 * @return true, if the rule is applicable, false else 177 */ 178 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2); 154 179 155 180 } -
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEquality.java
r1156 r1733 17 17 /** 18 18 * <p> 19 * A task equality denotes, how equal two tasks are. There are different equality levels 20 * which are similar to the usual design levels of GUI design. These levels are 19 * A task equality denotes, how equal two tasks are. There are different 20 * equality levels which are similar to the usual design levels of GUI design. 21 * These levels are 21 22 * <ul> 22 * <li>conceptual design: defines the concepts to be edited using a GUI</li> 23 * <li>semantical design: defines the possible functions for editing the concepts</li> 24 * <li>syntactical design: defines, which steps are needed to execute the functions</li> 25 * <li>lexical design: defines on the key stroke level, how the steps for executing a function 26 * can be performed</li> 23 * <li>conceptual design: defines the concepts to be edited using a GUI</li> 24 * <li>semantical design: defines the possible functions for editing the 25 * concepts</li> 26 * <li>syntactical design: defines, which steps are needed to execute the 27 * functions</li> 28 * <li>lexical design: defines on the key stroke level, how the steps for 29 * executing a function can be performed</li> 27 30 * </ul> 28 * It is not possible to compare two tasks conceptually. But the other design levels can be29 * identified and compared.31 * It is not possible to compare two tasks conceptually. But the other design 32 * levels can be identified and compared. 30 33 * </p> 31 34 * <p> 32 * Tasks can be identical. This is the case if in the java virtual machine, their comparison 33 * using the <code>==</code> operator or the equals method return true. 35 * Tasks can be identical. This is the case if in the java virtual machine, 36 * their comparison using the <code>==</code> operator or the equals method 37 * return true. 34 38 * </p> 35 39 * <p> 36 * Tasks are lexically equal, if they represent the same events on a key stroke level to be 37 * carried out to execute the task. Identical tasks are also syntactically equal. 40 * Tasks are lexically equal, if they represent the same events on a key stroke 41 * level to be carried out to execute the task. Identical tasks are also 42 * syntactically equal. 38 43 * </p> 39 44 * <p> 40 * Nodes are syntactically equal, if they differ in their events on key stroke level, but the 41 * syntactical result is the same. For example, entering the text "hello" into a text field can 42 * be done by entering the letters in their correct order, but also by copying the text into the 43 * text field. The syntactical result is the same: The text "hello" was entered. But the tasks 44 * lexically differ because the events on key stroke level are different. On the other hand, 45 * lexically equal tasks are also syntactically equal. 45 * Nodes are syntactically equal, if they differ in their events on key stroke 46 * level, but the syntactical result is the same. For example, entering the text 47 * "hello" into a text field can be done by entering the letters in their 48 * correct order, but also by copying the text into the text field. The 49 * syntactical result is the same: The text "hello" was entered. But the tasks 50 * lexically differ because the events on key stroke level are different. On the 51 * other hand, lexically equal tasks are also syntactically equal. 46 52 * </p> 47 53 * <p> 48 * Tasks are semantically equal, if they execute the same function for editing the concepts. An 49 * example are a click on a button and a short cut, both executing the same function. These tasks 50 * are syntactically and, therefore, also lexically different, but semantically equal. 51 * Syntactically equal tasks are always also semantically equal. 54 * Tasks are semantically equal, if they execute the same function for editing 55 * the concepts. An example are a click on a button and a short cut, both 56 * executing the same function. These tasks are syntactically and, therefore, 57 * also lexically different, but semantically equal. Syntactically equal tasks 58 * are always also semantically equal. 52 59 * </p> 53 60 * … … 56 63 */ 57 64 public enum TaskEquality { 58 IDENTICAL, 59 LEXICALLY_EQUAL, 60 SYNTACTICALLY_EQUAL, 61 SEMANTICALLY_EQUAL, 62 UNEQUAL; 65 IDENTICAL, LEXICALLY_EQUAL, SYNTACTICALLY_EQUAL, SEMANTICALLY_EQUAL, UNEQUAL; 63 66 64 /** 65 * <p> 66 * Checks for the current task equality, if it is at least identical to the 67 * provided one or even more concrete. As an example, the task equality identical also 68 * indicates, that the tasks are e.g. lexically, syntactically and semantically equal. 69 * Therefore, the method called on <code>IDENTICAL</code> with <code>SEMANTICALLY_EQUAL</code> 70 * as parameter will return true. If this method is called on <code>SYNTACTICALLY_EQUAL</code> 71 * with the parameter <code>IDENTICAL</code> instead, it returns false; 72 * </p> 73 * 74 * @param taskEquality the task equality to compare with. 75 * 76 * @return as described 77 */ 78 public boolean isAtLeast(TaskEquality taskEquality) 79 { 80 switch (taskEquality) { 81 case IDENTICAL: 82 return 83 (this == IDENTICAL); 84 case LEXICALLY_EQUAL: 85 return 86 (this == IDENTICAL) || 87 (this == LEXICALLY_EQUAL); 88 case SYNTACTICALLY_EQUAL: 89 return 90 (this == IDENTICAL) || 91 (this == LEXICALLY_EQUAL) || 92 (this == SYNTACTICALLY_EQUAL); 93 case SEMANTICALLY_EQUAL: 94 return 95 (this == IDENTICAL) || 96 (this == LEXICALLY_EQUAL) || 97 (this == SYNTACTICALLY_EQUAL) || 98 (this == SEMANTICALLY_EQUAL); 99 case UNEQUAL: 100 return 101 (this == UNEQUAL); 102 default : 103 return false; 104 } 105 } 67 /** 68 * <p> 69 * returns the common denominator of this task equality and the provided 70 * one. I.e. if one equality is e.g. syntactical and the other one only 71 * semantical, then semantical is returned. 72 * </p> 73 * 74 * @param otherEquality 75 * the equality, to compare this with 76 * 77 * @return as described 78 */ 79 public TaskEquality getCommonDenominator(TaskEquality otherEquality) { 80 if (this.isAtLeast(otherEquality)) { 81 return otherEquality; 82 } else if (otherEquality.isAtLeast(this)) { 83 return this; 84 } else { 85 return TaskEquality.UNEQUAL; 86 } 87 } 106 88 107 /** 108 * <p> 109 * returns the common denominator of this task equality and the provided one. I.e. if one 110 * equality is e.g. syntactical and the other one only semantical, then semantical is returned. 111 * </p> 112 * 113 * @param otherEquality the equality, to compare this with 114 * 115 * @return as described 116 */ 117 public TaskEquality getCommonDenominator(TaskEquality otherEquality) { 118 if (this.isAtLeast(otherEquality)) { 119 return otherEquality; 120 } 121 else if (otherEquality.isAtLeast(this)) { 122 return this; 123 } 124 else { 125 return TaskEquality.UNEQUAL; 126 } 127 } 89 /** 90 * <p> 91 * Checks for the current task equality, if it is at least identical to the 92 * provided one or even more concrete. As an example, the task equality 93 * identical also indicates, that the tasks are e.g. lexically, 94 * syntactically and semantically equal. Therefore, the method called on 95 * <code>IDENTICAL</code> with <code>SEMANTICALLY_EQUAL</code> as parameter 96 * will return true. If this method is called on 97 * <code>SYNTACTICALLY_EQUAL</code> with the parameter 98 * <code>IDENTICAL</code> instead, it returns false; 99 * </p> 100 * 101 * @param taskEquality 102 * the task equality to compare with. 103 * 104 * @return as described 105 */ 106 public boolean isAtLeast(TaskEquality taskEquality) { 107 switch (taskEquality) { 108 case IDENTICAL: 109 return (this == IDENTICAL); 110 case LEXICALLY_EQUAL: 111 return (this == IDENTICAL) || (this == LEXICALLY_EQUAL); 112 case SYNTACTICALLY_EQUAL: 113 return (this == IDENTICAL) || (this == LEXICALLY_EQUAL) 114 || (this == SYNTACTICALLY_EQUAL); 115 case SEMANTICALLY_EQUAL: 116 return (this == IDENTICAL) || (this == LEXICALLY_EQUAL) 117 || (this == SYNTACTICALLY_EQUAL) 118 || (this == SEMANTICALLY_EQUAL); 119 case UNEQUAL: 120 return (this == UNEQUAL); 121 default: 122 return false; 123 } 124 } 128 125 } -
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEqualityRuleManager.java
r1294 r1733 23 23 /** 24 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. 25 * The task equality rule manager is capable of comparing tasks and task 26 * instances based on its internal list of comparison rules. These rules are 27 * asked for comparing the two provided tasks or task instance. If a rule 28 * returns a task equality other than null, this equality is returned. Otherwise 29 * the next rule is asked. 29 30 * </p> 30 31 * … … 32 33 */ 33 34 public 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 } 35 36 /** 37 * <p> 38 * returns the singleton instance of this class 39 * </p> 40 * 41 * @return as described 42 */ 43 public static TaskEqualityRuleManager getInstance() { 44 return instance; 45 } 46 47 /** 48 * <p> 49 * the singleton instance of this class 50 * </p> 51 */ 52 private static final TaskEqualityRuleManager instance = new TaskEqualityRuleManager(); 53 54 /** 55 * <p> 56 * the rules that can be used for comparing tasks 57 * </p> 58 */ 59 private List<TaskComparisonRule> mRuleIndex = null; 60 61 /** 62 * <p> 63 * initializes the task equality rule manager by filling the internal list 64 * of comparison rules. 65 * </p> 66 */ 67 private TaskEqualityRuleManager() { 68 mRuleIndex = new ArrayList<TaskComparisonRule>(); 69 mRuleIndex.add(new TaskIdentityRule()); 70 mRuleIndex.add(new GUIEventTaskComparisonRule()); 71 mRuleIndex.add(new EventTaskComparisonRule()); 72 mRuleIndex.add(new IterationComparisonRule()); 73 mRuleIndex.add(new SequenceComparisonRule()); 74 mRuleIndex.add(new SelectionComparisonRule()); 75 mRuleIndex.add(new TaskAndIterationComparisonRule()); 76 mRuleIndex.add(new TaskAndSelectionComparisonRule()); 77 } 78 79 /** 80 * <p> 81 * this method two tasks with respect to the fiven equality level and 82 * returns true, if this level is given. 83 * </p> 84 * 85 * @param task1 86 * the first task to be compared 87 * @param task2 88 * the second task to be compared 89 * @param equalityLevel 90 * the level of equality to be checked for 91 * 92 * @return as described 93 * 94 * @throws IllegalStateException 95 * in the case, the {@link #init()} method was not called on the 96 * manager before a call to this method. 97 */ 98 public boolean areAtLeastEqual(ITask task1, ITask task2, 99 TaskEquality equalityLevel) { 100 if (equalityLevel == null) { 101 throw new IllegalArgumentException( 102 "required equality level must not be null"); 103 } 104 105 switch (equalityLevel) { 106 case IDENTICAL: 107 return areIdentical(task1, task2); 108 case LEXICALLY_EQUAL: 109 return areLexicallyEqual(task1, task2); 110 case SYNTACTICALLY_EQUAL: 111 return areSyntacticallyEqual(task1, task2); 112 case SEMANTICALLY_EQUAL: 113 return areSemanticallyEqual(task1, task2); 114 case UNEQUAL: 115 return !areSemanticallyEqual(task1, task2); 116 default: 117 throw new IllegalArgumentException("unknown required equality: " 118 + equalityLevel); 119 } 120 } 121 122 /** 123 * <p> 124 * this method compares two task instances with respect to the given 125 * equality level and returns true, if this level is given. 126 * </p> 127 * 128 * @param instance1 129 * the first task instance to be compared 130 * @param instance2 131 * the second task instance to be compared 132 * @param equalityLevel 133 * the level of equality to be checked for 134 * 135 * @return as described 136 * 137 * @throws IllegalStateException 138 * in the case, the {@link #init()} method was not called on the 139 * manager before a call to this method. 140 */ 141 public boolean areAtLeastEqual(ITaskInstance instance1, 142 ITaskInstance instance2, TaskEquality equalityLevel) { 143 if (equalityLevel == null) { 144 throw new IllegalArgumentException( 145 "required equality level must not be null"); 146 } 147 148 switch (equalityLevel) { 149 case IDENTICAL: 150 return areIdentical(instance1, instance2); 151 case LEXICALLY_EQUAL: 152 return areLexicallyEqual(instance1, instance2); 153 case SYNTACTICALLY_EQUAL: 154 return areSyntacticallyEqual(instance1, instance2); 155 case SEMANTICALLY_EQUAL: 156 return areSemanticallyEqual(instance1, instance2); 157 case UNEQUAL: 158 return !areSemanticallyEqual(instance1, instance2); 159 default: 160 throw new IllegalArgumentException("unknown required equality: " 161 + equalityLevel); 162 } 163 } 164 165 /** 166 * <p> 167 * this method checks if the two given tasks are identical. For this, it 168 * iterates its internal comparison rules. If the first rule returns true, 169 * than this method returns true as well. If no rule returns true, this 170 * method returns false. 171 * </p> 172 * 173 * @param task1 174 * the first task to be compared 175 * @param task2 176 * the second task to be compared 177 * 178 * @return as described 179 * 180 * @throws IllegalStateException 181 * in the case, the {@link #init()} method was not called on the 182 * manager before a call to this method. 183 */ 184 public boolean areIdentical(ITask task1, ITask task2) { 185 if (mRuleIndex == null) { 186 throw new IllegalStateException("not initialized"); 187 } 188 189 for (final TaskComparisonRule rule : mRuleIndex) { 190 if (rule.isApplicable(task1, task2) 191 && rule.areLexicallyEqual(task1, task2)) { 192 return true; 193 } 194 } 195 196 return false; 197 } 198 199 /** 200 * <p> 201 * this method checks if the two given task instances are identical. For 202 * this, it iterates its internal comparison rules. If the first rule 203 * returns true, than this method returns true as well. If no rule returns 204 * true, this method returns false. 205 * </p> 206 * 207 * @param instance1 208 * the first task instance to be compared 209 * @param instance2 210 * the second task instance to be compared 211 * 212 * @return as described 213 * 214 * @throws IllegalStateException 215 * in the case, the {@link #init()} method was not called on the 216 * manager before a call to this method. 217 */ 218 public boolean areIdentical(ITaskInstance instance1, ITaskInstance instance2) { 219 if (mRuleIndex == null) { 220 throw new IllegalStateException("not initialized"); 221 } 222 223 for (final TaskComparisonRule rule : mRuleIndex) { 224 if (rule.isApplicable(instance1, instance2) 225 && rule.areLexicallyEqual(instance1, instance2)) { 226 return true; 227 } 228 } 229 230 return false; 231 } 232 233 /** 234 * <p> 235 * this method checks if the two given tasks are lexically equal. For this, 236 * it iterates its internal comparison rules. If the first rule returns 237 * true, than this method returns true as well. If no rule returns true, 238 * this method returns false. 239 * </p> 240 * 241 * @param task1 242 * the first task to be compared 243 * @param task2 244 * the second task to be compared 245 * 246 * @return as described 247 * 248 * @throws IllegalStateException 249 * in the case, the {@link #init()} method was not called on the 250 * manager before a call to this method. 251 */ 252 public boolean areLexicallyEqual(ITask task1, ITask task2) { 253 if (mRuleIndex == null) { 254 throw new IllegalStateException("not initialized"); 255 } 256 257 for (final TaskComparisonRule rule : mRuleIndex) { 258 if (rule.isApplicable(task1, task2) 259 && rule.areLexicallyEqual(task1, task2)) { 260 return true; 261 } 262 } 263 264 return false; 265 } 266 267 /** 268 * <p> 269 * this method checks if the two given task instances are lexically equal. 270 * For this, it iterates its internal comparison rules. If the first rule 271 * returns true, than this method returns true, as well. If no rule returns 272 * true, this method returns false. 273 * </p> 274 * 275 * @param instance1 276 * the first task instance to be compared 277 * @param instance2 278 * the second task instance to be compared 279 * 280 * @return as described 281 * 282 * @throws IllegalStateException 283 * in the case, the {@link #init()} method was not called on the 284 * manager before a call to this method. 285 */ 286 public boolean areLexicallyEqual(ITaskInstance instance1, 287 ITaskInstance instance2) { 288 if (mRuleIndex == null) { 289 throw new IllegalStateException("not initialized"); 290 } 291 292 for (final TaskComparisonRule rule : mRuleIndex) { 293 if (rule.isApplicable(instance1, instance2) 294 && rule.areLexicallyEqual(instance1, instance2)) { 295 return true; 296 } 297 } 298 299 return false; 300 } 301 302 /** 303 * <p> 304 * this method checks if the two given tasks are semantically equal. For 305 * this, it iterates its internal comparison rules. If the first rule 306 * returns true, than this method returns true as well. If no rule returns 307 * true, this method returns false. 308 * </p> 309 * 310 * @param task1 311 * the first task to be compared 312 * @param task2 313 * the second task to be compared 314 * 315 * @return as described 316 * 317 * @throws IllegalStateException 318 * in the case, the {@link #init()} method was not called on the 319 * manager before a call to this method. 320 */ 321 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 322 if (mRuleIndex == null) { 323 throw new IllegalStateException("not initialized"); 324 } 325 326 for (final TaskComparisonRule rule : mRuleIndex) { 327 if (rule.isApplicable(task1, task2) 328 && rule.areSemanticallyEqual(task1, task2)) { 329 return true; 330 } 331 } 332 333 return false; 334 } 335 336 /** 337 * <p> 338 * this method checks if the two given task instances are semantically 339 * equal. For this, it iterates its internal comparison rules. If the first 340 * rule returns true, than this method returns true, as well. If no rule 341 * returns true, this method returns false. 342 * </p> 343 * 344 * @param instance1 345 * the first task instance to be compared 346 * @param instance2 347 * the second task instance to be compared 348 * 349 * @return as described 350 * 351 * @throws IllegalStateException 352 * in the case, the {@link #init()} method was not called on the 353 * manager before a call to this method. 354 */ 355 public boolean areSemanticallyEqual(ITaskInstance instance1, 356 ITaskInstance instance2) { 357 if (mRuleIndex == null) { 358 throw new IllegalStateException("not initialized"); 359 } 360 361 for (final TaskComparisonRule rule : mRuleIndex) { 362 if (rule.isApplicable(instance1, instance2) 363 && rule.areSemanticallyEqual(instance1, instance2)) { 364 return true; 365 } 366 } 367 368 return false; 369 } 370 371 /** 372 * <p> 373 * this method checks if the two given tasks are syntactically equal. For 374 * this, it iterates its internal comparison rules. If the first rule 375 * returns true, than this method returns true as well. If no rule returns 376 * true, this method returns false. 377 * </p> 378 * 379 * @param task1 380 * the first task to be compared 381 * @param task2 382 * the second task to be compared 383 * 384 * @return as described 385 * 386 * @throws IllegalStateException 387 * in the case, the {@link #init()} method was not called on the 388 * manager before a call to this method. 389 */ 390 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 391 if (mRuleIndex == null) { 392 throw new IllegalStateException("not initialized"); 393 } 394 395 for (final TaskComparisonRule rule : mRuleIndex) { 396 if (rule.isApplicable(task1, task2) 397 && rule.areSyntacticallyEqual(task1, task2)) { 398 return true; 399 } 400 } 401 402 return false; 403 } 404 405 /** 406 * <p> 407 * this method checks if the two given task instances are syntactically 408 * equal. For this, it iterates its internal comparison rules. If the first 409 * rule returns true, than this method returns true, as well. If no rule 410 * returns true, this method returns false. 411 * </p> 412 * 413 * @param instance1 414 * the first task instance to be compared 415 * @param instance2 416 * the second task instance to be compared 417 * 418 * @return as described 419 * 420 * @throws IllegalStateException 421 * in the case, the {@link #init()} method was not called on the 422 * manager before a call to this method. 423 */ 424 public boolean areSyntacticallyEqual(ITaskInstance instance1, 425 ITaskInstance instance2) { 426 if (mRuleIndex == null) { 427 throw new IllegalStateException("not initialized"); 428 } 429 430 for (final TaskComparisonRule rule : mRuleIndex) { 431 if (rule.isApplicable(instance1, instance2) 432 && rule.areSyntacticallyEqual(instance1, instance2)) { 433 return true; 434 } 435 } 436 437 return false; 438 } 439 440 /** 441 * <p> 442 * this method performs a comparison of the two provided tasks. It iterates 443 * its internal comparison rules. If the first rule returns a task equality 444 * other than null, this equality is returned. Otherwise the next rule is 445 * tried. If no rule returns an equality <code>NodeEquality.UNEQUAL</code> 446 * is returned. 447 * </p> 448 * 449 * @param task1 450 * the first task to be compared 451 * @param task2 452 * the second task to be compared 453 * 454 * @return as described 455 * 456 * @throws IllegalStateException 457 * in the case, the {@link #init()} method was not called on the 458 * manager before a call to this method. 459 */ 460 public TaskEquality compare(ITask task1, ITask task2) 461 throws IllegalStateException { 462 if (mRuleIndex == null) { 463 throw new IllegalStateException("not initialized"); 464 } 465 466 // LOG.info("checking for equality of " + task1 + " and " + task2); 467 TaskEquality taskEquality = null; 468 469 for (final TaskComparisonRule rule : mRuleIndex) { 470 if (rule.isApplicable(task1, task2)) { 471 taskEquality = rule.compare(task1, task2); 472 if (taskEquality != null) { 473 // LOG.warning("used rule " + rule + " for equality check"); 474 return taskEquality; 475 } 476 } 477 } 478 479 // LOG.warning("no rule could be applied --> handling tasks as unequal"); 480 481 return TaskEquality.UNEQUAL; 482 } 483 484 /** 485 * <p> 486 * this method performs a comparison of the two provided task instances. It 487 * iterates its internal comparison rules. If the first rule returns a task 488 * instance equality other than null, this equality is returned. Otherwise 489 * the next rule is tried. If no rule returns an equality 490 * <code>TaskEquality.UNEQUAL</code> is returned. 491 * </p> 492 * 493 * @param instance1 494 * the first task instance to be compared 495 * @param instance2 496 * the second task instance to be compared 497 * 498 * @return as described 499 * 500 * @throws IllegalStateException 501 * in the case, the {@link #init()} method was not called on the 502 * manager before a call to this method. 503 */ 504 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) 505 throws IllegalStateException { 506 if (mRuleIndex == null) { 507 throw new IllegalStateException("not initialized"); 508 } 509 510 // LOG.info("checking for equality of " + instance1 + " and " + 511 // instance2); 512 TaskEquality instanceEquality = null; 513 514 for (final TaskComparisonRule rule : mRuleIndex) { 515 if (rule.isApplicable(instance1, instance2)) { 516 instanceEquality = rule.compare(instance1, instance2); 517 if (instanceEquality != null) { 518 // LOG.warning("used rule " + rule + " for equality check"); 519 return instanceEquality; 520 } 521 } 522 } 523 524 // LOG.warning("no rule could be applied --> handling tasks as unequal"); 525 526 return TaskEquality.UNEQUAL; 527 } 474 528 475 529 } -
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskIdentityRule.java
r1294 r1733 20 20 /** 21 21 * <p> 22 * This comparison rule returns <code>TaskEquality.IDENTICAL</code> if the comparison of the two23 * tasks using the <code>==</code> operator returns true. Else it returns null to denote, that24 * it can not compare the tasks.22 * This comparison rule returns <code>TaskEquality.IDENTICAL</code> if the 23 * comparison of the two tasks using the <code>==</code> operator returns true. 24 * Else it returns null to denote, that it can not compare the tasks. 25 25 * </p> 26 26 * … … 30 30 public class TaskIdentityRule implements TaskComparisonRule { 31 31 32 /* (non-Javadoc) 33 * @see TaskComparisonRule#isApplicable(ITask, ITask) 34 */ 35 @Override 36 public boolean isApplicable(ITask task1, ITask task2) { 37 return (task1 == task2); 38 } 32 /* 33 * (non-Javadoc) 34 * 35 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 36 */ 37 @Override 38 public boolean areLexicallyEqual(ITask task1, ITask task2) { 39 return (task1 == task2); 40 } 39 41 40 /* (non-Javadoc) 41 * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask) 42 */ 43 @Override 44 public boolean areLexicallyEqual(ITask task1, ITask task2) { 45 return (task1 == task2); 46 } 42 /* 43 * (non-Javadoc) 44 * 45 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 46 */ 47 @Override 48 public boolean areLexicallyEqual(ITaskInstance instance1, 49 ITaskInstance instance2) { 50 return (instance1.getTask() == instance2.getTask()); 51 } 47 52 48 /* (non-Javadoc) 49 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 50 */ 51 @Override 52 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 53 return (task1 == task2); 54 } 53 /* 54 * (non-Javadoc) 55 * 56 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 57 */ 58 @Override 59 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 60 return (task1 == task2); 61 } 55 62 56 /* (non-Javadoc) 57 * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask) 58 */ 59 @Override 60 public boolean areSemanticallyEqual(ITask task1, ITask task2) { 61 return (task1 == task2); 62 } 63 /* 64 * (non-Javadoc) 65 * 66 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, 67 * ITaskInstance) 68 */ 69 @Override 70 public boolean areSemanticallyEqual(ITaskInstance instance1, 71 ITaskInstance instance2) { 72 return (instance1.getTask() == instance2.getTask()); 73 } 63 74 64 /* (non-Javadoc) 65 * @see TaskComparisonRule#compare(ITask, ITask) 66 */ 67 @Override 68 public TaskEquality compare(ITask task1, ITask task2) { 69 if (isApplicable(task1, task2)) { 70 return TaskEquality.IDENTICAL; 71 } 72 else { 73 return null; 74 } 75 } 75 /* 76 * (non-Javadoc) 77 * 78 * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask) 79 */ 80 @Override 81 public boolean areSyntacticallyEqual(ITask task1, ITask task2) { 82 return (task1 == task2); 83 } 76 84 77 /* (non-Javadoc) 78 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 79 */ 80 @Override 81 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 82 return (instance1.getTask() == instance2.getTask()); 83 } 85 /* 86 * (non-Javadoc) 87 * 88 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, 89 * ITaskInstance) 90 */ 91 @Override 92 public boolean areSyntacticallyEqual(ITaskInstance instance1, 93 ITaskInstance instance2) { 94 return (instance1.getTask() == instance2.getTask()); 95 } 84 96 85 /* (non-Javadoc) 86 * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance) 87 */ 88 @Override 89 public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 90 return (instance1.getTask() == instance2.getTask()); 91 } 97 /* 98 * (non-Javadoc) 99 * 100 * @see TaskComparisonRule#compare(ITask, ITask) 101 */ 102 @Override 103 public TaskEquality compare(ITask task1, ITask task2) { 104 if (isApplicable(task1, task2)) { 105 return TaskEquality.IDENTICAL; 106 } else { 107 return null; 108 } 109 } 92 110 93 /* (non-Javadoc) 94 * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance) 95 */ 96 @Override 97 public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 98 return (instance1.getTask() == instance2.getTask()); 99 } 111 /* 112 * (non-Javadoc) 113 * 114 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 115 */ 116 @Override 117 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 118 if (isApplicable(instance1, instance2)) { 119 return TaskEquality.IDENTICAL; 120 } else { 121 return null; 122 } 123 } 100 124 101 /* (non-Javadoc) 102 * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance) 103 */ 104 @Override 105 public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) { 106 return (instance1.getTask() == instance2.getTask()); 107 } 125 /* 126 * (non-Javadoc) 127 * 128 * @see TaskComparisonRule#isApplicable(ITask, ITask) 129 */ 130 @Override 131 public boolean isApplicable(ITask task1, ITask task2) { 132 return (task1 == task2); 133 } 108 134 109 /* (non-Javadoc) 110 * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance) 111 */ 112 @Override 113 public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) { 114 if (isApplicable(instance1, instance2)) { 115 return TaskEquality.IDENTICAL; 116 } 117 else { 118 return null; 119 } 120 } 135 /* 136 * (non-Javadoc) 137 * 138 * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance) 139 */ 140 @Override 141 public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) { 142 return (instance1.getTask() == instance2.getTask()); 143 } 121 144 122 145 }
Note: See TracChangeset
for help on using the changeset viewer.