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

Last change on this file since 1891 was 1887, checked in by pharms, 9 years ago
  • extended and corrected task comparison
File size: 26.7 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.tasktrees.taskequality;
16
17import java.util.Collection;
18
19import de.ugoe.cs.autoquest.eventcore.IEventTarget;
20import de.ugoe.cs.autoquest.eventcore.gui.IInteraction;
21import de.ugoe.cs.autoquest.eventcore.gui.KeyInteraction;
22import de.ugoe.cs.autoquest.eventcore.gui.KeyPressed;
23import de.ugoe.cs.autoquest.eventcore.gui.KeyReleased;
24import de.ugoe.cs.autoquest.eventcore.gui.KeyTyped;
25import de.ugoe.cs.autoquest.eventcore.gui.MouseButtonDown;
26import de.ugoe.cs.autoquest.eventcore.gui.MouseButtonInteraction;
27import de.ugoe.cs.autoquest.eventcore.gui.MouseButtonUp;
28import de.ugoe.cs.autoquest.eventcore.gui.MouseClick;
29import de.ugoe.cs.autoquest.eventcore.gui.MouseDoubleClick;
30import de.ugoe.cs.autoquest.eventcore.gui.MouseDragAndDrop;
31import de.ugoe.cs.autoquest.eventcore.gui.Scroll;
32import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
33import de.ugoe.cs.autoquest.eventcore.gui.ValueSelection;
34import de.ugoe.cs.autoquest.eventcore.guimodel.IButton;
35import de.ugoe.cs.autoquest.eventcore.guimodel.ICheckBox;
36import de.ugoe.cs.autoquest.eventcore.guimodel.IComboBox;
37import de.ugoe.cs.autoquest.eventcore.guimodel.IImage;
38import de.ugoe.cs.autoquest.eventcore.guimodel.IListBox;
39import de.ugoe.cs.autoquest.eventcore.guimodel.IMenu;
40import de.ugoe.cs.autoquest.eventcore.guimodel.IMenuButton;
41import de.ugoe.cs.autoquest.eventcore.guimodel.IRadioButton;
42import de.ugoe.cs.autoquest.eventcore.guimodel.IShape;
43import de.ugoe.cs.autoquest.eventcore.guimodel.IText;
44import de.ugoe.cs.autoquest.eventcore.guimodel.IToolTip;
45import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
46import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
47import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
48
49/**
50 * <p>
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.
59 * </p>
60 *
61 * @author Patrick Harms
62 */
63public 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                // pressing a key on the same target, e.g. a text field, usually has the same
344                // semantics
345                return TaskEquality.SEMANTICALLY_EQUAL;
346            }
347        }
348       
349        return TaskEquality.UNEQUAL;
350    }
351   
352    /**
353     * <p>
354     * compares two mouse drag and drops. If both drag and drops have the same start and end
355     * coordinates, they are lexically equal. Otherwise, they are semantically equal.
356     * </p>
357     * <p>
358     * The provided equality level can be used to restrict the quality check to the given level.
359     * This is done for optimization purposes. The returned equality level is as concrete as
360     * the provided one. It may be more concrete if there is no difference regarding the
361     * comparison on the levels.
362     * </p>
363     *
364     * @param interaction1  the first mouse drag and drop to compare
365     * @param interaction2  the second mouse drag and drop to compare
366     * @param equalityLevel the equality level to be checked for
367     *
368     * @return as described
369     */
370    private TaskEquality compareMouseDragAndDrops(MouseDragAndDrop interaction1,
371                                                  MouseDragAndDrop interaction2,
372                                                  TaskEquality     equalityLevel)
373    {
374        if (interaction1.getButton() != interaction2.getButton()) {
375            return TaskEquality.UNEQUAL;
376        }
377       
378        if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) {
379            int x1 = interaction1.getX();
380            int x1Start = interaction1.getXStart();
381            int x2 = interaction2.getX();
382            int x2Start = interaction2.getXStart();
383            int y1 = interaction1.getY();
384            int y1Start = interaction1.getYStart();
385            int y2 = interaction2.getY();
386            int y2Start = interaction2.getYStart();
387       
388            if ((x1Start == x2Start) && (x1 == x2) && (y1Start == y2Start) && (y1 == y2)) {
389                return TaskEquality.LEXICALLY_EQUAL;
390            }
391        }
392       
393        // performing drag and drops on the same target usually have the same semantic meaning,
394        // i.e., the same function is called
395        return TaskEquality.SEMANTICALLY_EQUAL;
396    }
397
398    /**
399     * <p>
400     * compares two mouse button interactions such as clicks, mouse button down, or double clicks.
401     * If both interactions have the same coordinates, they are lexically equal. Otherwise, they
402     * are semantically equal. Mouse clicks for which the coordinates make no lexical difference
403     * (see {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated as
404     * lexically equal.
405     * </p>
406     * <p>
407     * The provided equality level can be used to restrict the quality check to the given level.
408     * This is done for optimization purposes. The returned equality level is as concrete as
409     * the provided one. It may be more concrete if there is no difference regarding the
410     * comparison on the levels.
411     * </p>
412     *
413     * @param interaction1  the first mouse button interaction to compare
414     * @param interaction2  the second mouse button interaction to compare
415     * @param eventTarget   the event target on which the interactions happened (used within
416     *                      special comparisons like mouse clicks on buttons, where the coordinates
417     *                      can be ignored)
418     * @param equalityLevel the equality level to be checked for
419     *
420     * @return as described
421     */
422    private TaskEquality compareMouseButtonInteractions(MouseButtonInteraction interaction1,
423                                                        MouseButtonInteraction interaction2,
424                                                        IEventTarget           eventTarget,
425                                                        TaskEquality           equalityLevel)
426    {
427        boolean coordinatesMatch = true;
428       
429        if ((interaction1 instanceof MouseDragAndDrop) &&
430            (interaction2 instanceof MouseDragAndDrop))
431        {
432            return compareMouseDragAndDrops
433                ((MouseDragAndDrop) interaction1, (MouseDragAndDrop) interaction2, equalityLevel);
434        }
435        else if (interaction1.getButton() != interaction2.getButton()) {
436            return TaskEquality.UNEQUAL;
437        }
438        else if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL) &&
439                 clickCoordinatesMakeLexicalDifference(eventTarget))
440        {
441            int x1 = interaction1.getX();
442            int x2 = interaction2.getX();
443            int y1 = interaction1.getY();
444            int y2 = interaction2.getY();
445
446            if ((x1 != x2) || (y1 != y2)) {
447                coordinatesMatch = false;
448            }
449        }
450       
451        // up to now, they can be equal. Now check the types. Do it as last action as these
452        // checks take the most time and should, therefore, only be done latest
453        if (((interaction1 instanceof MouseClick) && (interaction2 instanceof MouseClick)) ||
454            ((interaction1 instanceof MouseDoubleClick) &&
455             (interaction2 instanceof MouseDoubleClick)) ||
456            ((interaction1 instanceof MouseButtonDown) &&
457             (interaction2 instanceof MouseButtonDown)) ||
458            ((interaction1 instanceof MouseButtonUp) &&
459             (interaction2 instanceof MouseButtonUp)))
460        {
461            if (coordinatesMatch) {
462                return TaskEquality.LEXICALLY_EQUAL;
463            }
464            else {
465                // in most situations, the coordinates are not of interest. But if they are, then
466                // the event can be at most semantically equal
467                return TaskEquality.SEMANTICALLY_EQUAL;
468            }
469        }
470       
471        return TaskEquality.UNEQUAL;
472    }
473
474    /**
475     * <p>
476     * compares two scrolls and considers them as lexically equal if they have the same coordinates.
477     * Otherwise, they are syntactically equal as the happen on the same target
478     * </p>
479     *
480     * @param interaction1  the first scroll interaction to compare
481     * @param interaction2  the second scroll interaction to compare
482     * @param equalityLevel the equality level to be checked for
483     *
484     * @return as described
485     */
486    private TaskEquality compareScrolls(Scroll       interaction1,
487                                        Scroll       interaction2,
488                                        TaskEquality equalityLevel)
489    {
490        if (equalityLevel.isAtLeast(TaskEquality.LEXICALLY_EQUAL)) {
491            int x1 = interaction1.getXPosition();
492            int x2 = interaction2.getXPosition();
493            int y1 = interaction1.getYPosition();
494            int y2 = interaction2.getYPosition();
495       
496            if ((x1 == x2) && (y1 == y2)) {
497                return TaskEquality.LEXICALLY_EQUAL;
498            }
499        }
500       
501        return TaskEquality.SYNTACTICALLY_EQUAL;
502    }
503
504    /**
505     * <p>
506     * compares two text inputs. If both text inputs have the same entered text and text input
507     * events, they are lexically equal. If they only have the same entered text, they are
508     * syntactically equal. If they are only both text inputs, they are semantically equal.
509     * (the equality of the event targets is checked beforehand).
510     * </p>
511     * <p>
512     * The provided equality level can be used to restrict the quality check to the given level.
513     * This is done for optimization purposes. The returned equality level is as concrete as
514     * the provided one. It may be more concrete if there is no difference regarding the
515     * comparison on the levels.
516     * </p>
517     *
518     * @param interaction1  the first text input to compare
519     * @param interaction2  the second text input to compare
520     * @param equalityLevel the equality level to be checked for
521     *
522     * @return as described
523     */
524    private TaskEquality compareTextInputs(TextInput    interaction1,
525                                           TextInput    interaction2,
526                                           TaskEquality equalityLevel)
527    {
528        switch (equalityLevel) {
529            case LEXICALLY_EQUAL:
530                if (interaction1.getTextInputEvents().equals(interaction2.getTextInputEvents())) {
531                    return TaskEquality.LEXICALLY_EQUAL;
532                }
533                // fall through
534            case SYNTACTICALLY_EQUAL:
535                if (interaction1.getEnteredText().equals(interaction2.getEnteredText())) {
536                    return TaskEquality.SYNTACTICALLY_EQUAL;
537                }
538                // fall through
539            case SEMANTICALLY_EQUAL:
540                return TaskEquality.SEMANTICALLY_EQUAL;
541            default:
542                return TaskEquality.UNEQUAL;
543        }
544    }
545
546    /**
547     * <p>
548     * compares two value selections. If both value selections have the same selected value, they
549     * are syntactically equal, otherwise they are semantically equal.
550     * (the equality of the event targets is checked beforehand).
551     * </p>
552     * <p>
553     * The provided equality level can be used to restrict the quality check to the given level.
554     * This is done for optimization purposes. The returned equality level is as concrete as
555     * the provided one. It may be more concrete if there is no difference regarding the
556     * comparison on the levels.
557     * </p>
558     *
559     * @param interaction1  the first value selection to compare
560     * @param interaction2  the second value selection to compare
561     * @param equalityLevel the equality level to be checked for
562     *
563     * @return as described
564     */
565    private TaskEquality compareValueSelections(ValueSelection<?> interaction1,
566                                                ValueSelection<?> interaction2,
567                                                TaskEquality      equalityLevel)
568    {
569        if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) {
570            Object value1 = interaction1.getSelectedValue();
571            Object value2 = interaction2.getSelectedValue();
572       
573            if ((value1 == value2) || ((value1 != null) && (value1.equals(value2)))) {
574                return TaskEquality.LEXICALLY_EQUAL;
575            }
576        }
577       
578        return TaskEquality.SEMANTICALLY_EQUAL;
579    }
580
581    /**
582     * <p>
583     * Checks, if the coordinates of a click or double click on the provided event target makes
584     * a lexical difference. Mouse clicks and double clicks on buttons, check boxes,
585     * combo boxes, images, list boxes, menu buttons, radio buttons, shapes, uneditable text,
586     * and tool tips have no lexical difference as long as they happen on the same event target.
587     * The concrete coordinates are not relevant.
588     * </p>
589     *
590     * @param eventTarget the event target on which the interaction occurred
591     *
592     * @return if the coordinates are important to be considered for clicks and double clicks,
593     *         false else
594     */
595    private boolean clickCoordinatesMakeLexicalDifference(IEventTarget eventTarget) {
596        if ((eventTarget instanceof IButton) ||
597            (eventTarget instanceof ICheckBox) ||
598            (eventTarget instanceof IComboBox) ||
599            (eventTarget instanceof IImage) ||
600            (eventTarget instanceof IListBox) ||
601            (eventTarget instanceof IMenu) ||
602            (eventTarget instanceof IMenuButton) ||
603            (eventTarget instanceof IRadioButton) ||
604            (eventTarget instanceof IShape) ||
605            (eventTarget instanceof IText) ||
606            (eventTarget instanceof IToolTip))
607        {
608            return false;
609        }
610        else {
611            return true;
612        }
613    }
614
615}
Note: See TracBrowser for help on using the repository browser.