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
RevLine 
[1113]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
[1146]15package de.ugoe.cs.autoquest.tasktrees.taskequality;
[807]16
[1294]17import java.util.Collection;
18
[1061]19import de.ugoe.cs.autoquest.eventcore.IEventTarget;
[922]20import de.ugoe.cs.autoquest.eventcore.gui.IInteraction;
[1125]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;
[1043]28import de.ugoe.cs.autoquest.eventcore.gui.MouseClick;
[1056]29import de.ugoe.cs.autoquest.eventcore.gui.MouseDoubleClick;
[1043]30import de.ugoe.cs.autoquest.eventcore.gui.MouseDragAndDrop;
[1125]31import de.ugoe.cs.autoquest.eventcore.gui.Scroll;
[922]32import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
33import de.ugoe.cs.autoquest.eventcore.gui.ValueSelection;
[1061]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;
[1125]39import de.ugoe.cs.autoquest.eventcore.guimodel.IMenu;
[1061]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;
[1294]45import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
[1146]46import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
[1294]47import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
[807]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 */
[1146]63public class GUIEventTaskComparisonRule implements TaskComparisonRule {
[807]64   
[1125]65    /* (non-Javadoc)
[1294]66     * @see TaskComparisonRule#isApplicable(ITask, ITask)
[807]67     */
68    @Override
[1146]69    public boolean isApplicable(ITask task1, ITask task2) {
[1294]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;
[1125]87    }
88
89    /* (non-Javadoc)
[1294]90     * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask)
[1125]91     */
92    @Override
[1146]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));
[1125]96    }
97
98    /* (non-Javadoc)
[1294]99     * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask)
[1125]100     */
101    @Override
[1146]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));
[1125]105    }
106
107    /* (non-Javadoc)
[1294]108     * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask)
[1125]109     */
110    @Override
[1146]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));
[1125]114    }
115
116    /* (non-Javadoc)
[1294]117     * @see TaskComparisonRule#compare(ITask, ITask)
[1125]118     */
119    @Override
[1146]120    public TaskEquality compare(ITask task1, ITask task2) {
121        return getEquality(task1, task2, null);
[1125]122    }
123
[1294]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
[1125]171    /**
172     *
173     */
[1294]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();
[807]180       
[1294]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())) {
[1146]227            return TaskEquality.UNEQUAL;
[807]228        }
229       
[1294]230        IInteraction interaction1 = (IInteraction) eventTask1.getEvent().getType();
231        IInteraction interaction2 = (IInteraction) eventTask2.getEvent().getType();
[807]232       
[1125]233        return compareInteractions
[1294]234            (interaction1, interaction2, eventTask1.getEvent().getTarget(), requiredEqualityLevel);
[807]235    }
236
237    /**
238     * <p>
[1061]239     * compares two interactions. The method delegates to other, more specific compare method, e.g.,
[807]240     * {@link #compareTextInputs(TextInput, TextInput)} and
[1061]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.
[807]245     * </p>
[1154]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>
[807]252     *
[1154]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
[807]259     *
260     * @return as described
261     */
[1146]262    private TaskEquality compareInteractions(IInteraction interaction1,
[1061]263                                             IInteraction interaction2,
[1125]264                                             IEventTarget eventTarget,
[1146]265                                             TaskEquality equalityLevel)
[1061]266    {
[1146]267        TaskEquality level = equalityLevel;
[1125]268       
269        if (level == null) {
[1146]270            level = TaskEquality.LEXICALLY_EQUAL;
[1125]271        }
272       
[807]273        if (interaction1 == interaction2) {
[1146]274            return TaskEquality.LEXICALLY_EQUAL;
[807]275        }
[1125]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        }
[807]292        else if ((interaction1 instanceof TextInput) && (interaction2 instanceof TextInput)) {
[1125]293            return compareTextInputs
294                ((TextInput) interaction1, (TextInput) interaction2, level);
[807]295        }
296        else if ((interaction1 instanceof ValueSelection) &&
297                 (interaction2 instanceof ValueSelection))
298        {
299            return compareValueSelections
[1125]300                ((ValueSelection<?>) interaction1, (ValueSelection<?>) interaction2, level);
[807]301        }
302        else if (interaction1.equals(interaction2)) {
[1146]303            return TaskEquality.LEXICALLY_EQUAL;
[807]304        }
305        else {
[1146]306            return TaskEquality.UNEQUAL;
[807]307        }
308    }
309
310    /**
311     * <p>
[1154]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.
[807]315     * </p>
[1154]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>
[807]322     *
[1154]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
[807]328     */
[1146]329    private TaskEquality compareKeyInteractions(KeyInteraction interaction1,
[1125]330                                                KeyInteraction interaction2,
[1146]331                                                TaskEquality   equalityLevel)
[1125]332    {
333        if (((interaction1 instanceof KeyPressed) && (interaction2 instanceof KeyPressed)) ||
334            ((interaction1 instanceof KeyReleased) && (interaction2 instanceof KeyReleased)) ||
335            ((interaction1 instanceof KeyTyped) && (interaction2 instanceof KeyTyped)))
336        {
[1146]337            if ((equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) &&
[1125]338                (interaction1.getKey() == interaction2.getKey()))
339            {
[1146]340                return TaskEquality.LEXICALLY_EQUAL;
[807]341            }
342            else {
[1887]343                // pressing a key on the same target, e.g. a text field, usually has the same
344                // semantics
[1146]345                return TaskEquality.SEMANTICALLY_EQUAL;
[807]346            }
347        }
[1125]348       
[1146]349        return TaskEquality.UNEQUAL;
[807]350    }
[1125]351   
[807]352    /**
353     * <p>
[1125]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.
[807]356     * </p>
[1154]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>
[807]363     *
[1154]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
[807]367     *
368     * @return as described
369     */
[1146]370    private TaskEquality compareMouseDragAndDrops(MouseDragAndDrop interaction1,
[1125]371                                                  MouseDragAndDrop interaction2,
[1146]372                                                  TaskEquality     equalityLevel)
[807]373    {
[1125]374        if (interaction1.getButton() != interaction2.getButton()) {
[1146]375            return TaskEquality.UNEQUAL;
[1125]376        }
[807]377       
[1146]378        if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) {
[1125]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)) {
[1146]389                return TaskEquality.LEXICALLY_EQUAL;
[1125]390            }
[807]391        }
[1125]392       
[1887]393        // performing drag and drops on the same target usually have the same semantic meaning,
394        // i.e., the same function is called
[1146]395        return TaskEquality.SEMANTICALLY_EQUAL;
[807]396    }
397
[1043]398    /**
399     * <p>
[1125]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.
[1043]405     * </p>
[1154]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>
[1043]412     *
[1154]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
[1043]419     *
420     * @return as described
421     */
[1146]422    private TaskEquality compareMouseButtonInteractions(MouseButtonInteraction interaction1,
[1125]423                                                        MouseButtonInteraction interaction2,
424                                                        IEventTarget           eventTarget,
[1146]425                                                        TaskEquality           equalityLevel)
[1043]426    {
[1125]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()) {
[1146]436            return TaskEquality.UNEQUAL;
[1057]437        }
[1146]438        else if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL) &&
[1125]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        }
[1057]450       
[1125]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) {
[1146]462                return TaskEquality.LEXICALLY_EQUAL;
[1125]463            }
464            else {
[1887]465                // in most situations, the coordinates are not of interest. But if they are, then
466                // the event can be at most semantically equal
[1146]467                return TaskEquality.SEMANTICALLY_EQUAL;
[1125]468            }
[1061]469        }
470       
[1146]471        return TaskEquality.UNEQUAL;
[1043]472    }
473
474    /**
475     * <p>
[1887]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
[1056]478     * </p>
479     *
[1887]480     * @param interaction1  the first scroll interaction to compare
481     * @param interaction2  the second scroll interaction to compare
[1154]482     * @param equalityLevel the equality level to be checked for
[1056]483     *
484     * @return as described
485     */
[1146]486    private TaskEquality compareScrolls(Scroll       interaction1,
[1125]487                                        Scroll       interaction2,
[1146]488                                        TaskEquality equalityLevel)
[1056]489    {
[1887]490        if (equalityLevel.isAtLeast(TaskEquality.LEXICALLY_EQUAL)) {
[1125]491            int x1 = interaction1.getXPosition();
492            int x2 = interaction2.getXPosition();
493            int y1 = interaction1.getYPosition();
494            int y2 = interaction2.getYPosition();
[1057]495       
[1125]496            if ((x1 == x2) && (y1 == y2)) {
[1146]497                return TaskEquality.LEXICALLY_EQUAL;
[1125]498            }
[1061]499        }
500       
[1887]501        return TaskEquality.SYNTACTICALLY_EQUAL;
[1125]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>
[1154]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>
[1125]517     *
[1154]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
[1125]521     *
522     * @return as described
523     */
[1146]524    private TaskEquality compareTextInputs(TextInput    interaction1,
[1125]525                                           TextInput    interaction2,
[1146]526                                           TaskEquality equalityLevel)
[1125]527    {
528        switch (equalityLevel) {
529            case LEXICALLY_EQUAL:
530                if (interaction1.getTextInputEvents().equals(interaction2.getTextInputEvents())) {
[1146]531                    return TaskEquality.LEXICALLY_EQUAL;
[1125]532                }
533                // fall through
534            case SYNTACTICALLY_EQUAL:
535                if (interaction1.getEnteredText().equals(interaction2.getEnteredText())) {
[1146]536                    return TaskEquality.SYNTACTICALLY_EQUAL;
[1125]537                }
538                // fall through
539            case SEMANTICALLY_EQUAL:
[1146]540                return TaskEquality.SEMANTICALLY_EQUAL;
[1125]541            default:
[1146]542                return TaskEquality.UNEQUAL;
[1056]543        }
544    }
545
546    /**
547     * <p>
[1125]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).
[1043]551     * </p>
[1154]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>
[1043]558     *
[1154]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
[1043]562     *
563     * @return as described
564     */
[1146]565    private TaskEquality compareValueSelections(ValueSelection<?> interaction1,
[1125]566                                                ValueSelection<?> interaction2,
[1146]567                                                TaskEquality      equalityLevel)
[1043]568    {
[1146]569        if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) {
[1125]570            Object value1 = interaction1.getSelectedValue();
571            Object value2 = interaction2.getSelectedValue();
572       
573            if ((value1 == value2) || ((value1 != null) && (value1.equals(value2)))) {
[1146]574                return TaskEquality.LEXICALLY_EQUAL;
[1125]575            }
[1057]576        }
577       
[1146]578        return TaskEquality.SEMANTICALLY_EQUAL;
[1043]579    }
580
[1061]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) ||
[1125]601            (eventTarget instanceof IMenu) ||
[1061]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
[807]615}
Note: See TracBrowser for help on using the repository browser.