source: trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/DefaultValueRule.java

Last change on this file was 2243, checked in by pharms, 7 years ago
  • solved some findbugs issues
File size: 27.1 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.usability;
16
17import java.util.ArrayList;
18import java.util.Collection;
19import java.util.HashMap;
20import java.util.HashSet;
21import java.util.Iterator;
22import java.util.LinkedList;
23import java.util.List;
24import java.util.ListIterator;
25import java.util.Map;
26import java.util.Set;
27
28import org.apache.commons.math3.stat.inference.ChiSquareTest;
29
30import de.ugoe.cs.autoquest.eventcore.Event;
31import de.ugoe.cs.autoquest.eventcore.IEventTargetSpec;
32import de.ugoe.cs.autoquest.eventcore.IHierarchicalEventTarget;
33import de.ugoe.cs.autoquest.eventcore.IHierarchicalEventTargetModel;
34import de.ugoe.cs.autoquest.eventcore.gui.MouseClick;
35import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
36import de.ugoe.cs.autoquest.eventcore.gui.ValueSelection;
37import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel;
38import de.ugoe.cs.autoquest.eventcore.guimodel.ICheckBox;
39import de.ugoe.cs.autoquest.eventcore.guimodel.IComboBox;
40import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
41import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec;
42import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIView;
43import de.ugoe.cs.autoquest.eventcore.guimodel.IRadioButton;
44import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
45import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
46import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
47import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
48import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
49import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
50import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
51
52/**
53 * TODO comment
54 *
55 * @version $Revision: $ $Date: 16.07.2012$
56 * @author 2012, last modified by $Author: pharms$
57 */
58public class DefaultValueRule implements UsabilityEvaluationRule {
59   
60    /** */
61    private static String DEFAULT_VALUE = "DEFAULT_VALUE";
62   
63    /*
64     * (non-Javadoc)
65     *
66     * @see de.ugoe.cs.usability.UsabilityEvaluationRule#evaluate(TaskTree)
67     */
68    @Override
69    public UsabilityEvaluationResult evaluate(ITaskModel taskModel) {
70        System.out.println("determining value selection targets");
71        Set<ValueSelectionTarget> targets = getValueSelectionTargets(taskModel.getTasks());
72        System.out.println("found " + targets.size() + " targets");
73       
74        System.out.println("grouping radio buttons and check boxes targets");
75        condenseRadioButtonAndCheckBoxGroups(targets);
76        System.out.println(targets.size() + " remaining");
77       
78        System.out.println("calculating statistics");
79        ValueChangeStatistics statistics = new ValueChangeStatistics(targets);
80        calculateStatistics(taskModel.getUserSessions(), statistics);
81
82        System.out.println("analyzing statistics");
83        UsabilityEvaluationResult results = new UsabilityEvaluationResult(taskModel);
84        analyzeStatistics(statistics, results);
85
86        return results;
87    }
88
89    /**
90     *
91     */
92    private void analyzeStatistics(ValueChangeStatistics     statistics,
93                                   UsabilityEvaluationResult results)
94    {
95        System.out.println
96            ("determined " + statistics.getViewsWithValueSelections().size() + " views");
97       
98        // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TEST IMPLEMENTATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
99        int valueSelectionTargetCounter = 0;
100       
101        for (IGUIView view : statistics.getViewsWithValueSelections()) {
102            valueSelectionTargetCounter += statistics.getValueSelectionTargetsInView(view).size();
103        }
104       
105        if (valueSelectionTargetCounter != statistics.selectedValues.size()) {
106            throw new IllegalStateException("this should not happen");
107        }
108        // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TEST IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
109       
110        for (IGUIView view : statistics.getViewsWithValueSelections()) {
111            //System.out.println("view " + view + " has " +
112            //                   statistics.getValueSelectionTargetsInView(view) +
113            //                   " value selection targets");
114            for (ValueSelectionTarget target : statistics.getValueSelectionTargetsInView(view)) {
115                analyzeStatistics
116                    (view, target, statistics.getStatisticsForValueSelectionTarget(target), results);
117            }
118        }
119    }
120
121    /**
122     *
123     */
124    private void analyzeStatistics(IGUIView                  view,
125                                   ValueSelectionTarget      target,
126                                   Map<Object, Integer>      selectedValues,
127                                   UsabilityEvaluationResult results)
128    {
129        //System.out.println("  analyzing selected values for " + target);
130        long[] observed = new long[selectedValues.size()];
131        long allObserved = 0;
132        long maxObserved = 0;
133        LinkedList<Object> mostOftenSelected = new LinkedList<>();
134       
135        int i = 0;
136        for (Map.Entry<Object, Integer> selectedValue : selectedValues.entrySet()) {
137            //System.out.println("    " + selectedValue.getValue() + " \t " + selectedValue.getKey());
138           
139            observed[i++] = selectedValue.getValue();
140            allObserved += selectedValue.getValue();
141            maxObserved = Math.max(maxObserved, selectedValue.getValue());
142           
143            boolean added = false;
144            ListIterator<Object> iterator = mostOftenSelected.listIterator();
145            while (iterator.hasNext()) {
146                if (selectedValues.get(iterator.next()) < selectedValue.getValue()) {
147                    iterator.previous();
148                    iterator.add(selectedValue.getKey());
149                    added = true;
150                    break;
151                }
152            }
153           
154            if (!added) {
155                mostOftenSelected.add(selectedValue.getKey());
156            }
157           
158            while (mostOftenSelected.size() > 5) {
159                mostOftenSelected.removeLast();
160            }
161        }
162       
163        double[] expected = new double[observed.length];
164        double expectedFrequency = ((double) allObserved) / expected.length;
165       
166        for (i = 0; i < expected.length; i++) {
167            expected[i] = expectedFrequency;
168        }
169       
170        if ((expected.length > 1) &&
171            (new ChiSquareTest().chiSquareTest(expected, observed, 0.05)))
172        {
173            // values are not equally distributed.
174           
175            // if the default value is most often selected, everything is fine. If not, smell is
176            // detected
177            if (!DEFAULT_VALUE.equals(mostOftenSelected.get(0))) {
178                UsabilitySmellIntensity intensity = UsabilitySmellIntensity.getIntensity
179                    ((int) (1000 * maxObserved / allObserved), (int) allObserved, -1);
180               
181                if (intensity != null) {
182                    List<String> mostOftenSelectedValues =
183                        new ArrayList<>(mostOftenSelected.size());
184               
185                    for (Object oftenSelected : mostOftenSelected) {
186                        mostOftenSelectedValues.add
187                            (oftenSelected + " (" +
188                             (100.0 * selectedValues.get(oftenSelected) / allObserved) + "%)");
189                    }
190               
191                    Map<String, Object> parameters = new HashMap<String, Object>();
192                    parameters.put("view", view);
193                    parameters.put("guiElement", target);
194                    parameters.put("selectedValues", mostOftenSelectedValues);
195
196                    results.addSmell(intensity, UsabilitySmellDescription.GOOD_DEFAULTS, parameters);
197                }
198            }
199        }
200    }
201
202    /**
203     *
204     */
205    private Set<ValueSelectionTarget> getValueSelectionTargets(Collection<ITask> tasks) {
206        Set<ValueSelectionTarget> result = new HashSet<>();
207       
208        for (ITask task : tasks) {
209            if (task instanceof IEventTask) {
210                for (ITaskInstance instance : task.getInstances()) {
211                    if (isValueSelection(instance)) {
212                        result.add(newValueSelectionTarget(instance));
213                    }
214                }
215            }
216        }
217       
218        return result;
219    }
220
221    /**
222     *
223     */
224    private boolean isValueSelection(ITaskInstance instance) {
225        if (instance instanceof IEventTaskInstance) {
226            Event event = ((IEventTaskInstance) instance).getEvent();
227       
228            if ((event.getType() instanceof TextInput) ||
229                (event.getType() instanceof ValueSelection))
230            {
231                return true;
232            }
233           
234            if (("JFC".equals(event.getTarget().getPlatform())) &&
235                (event.getTarget() instanceof ICheckBox) &&
236                (event.getType() instanceof MouseClick))
237            {
238                return true;
239            }
240        }
241       
242        return false;
243    }
244
245    /**
246     *
247     */
248    private static ValueSelectionTarget newValueSelectionTarget(ITaskInstance instance) {
249        Event event = ((IEventTaskInstance) instance).getEvent();
250        return new ValueSelectionTarget((IGUIElement) event.getTarget());
251    }
252   
253    /**
254     *
255     */
256    private void condenseRadioButtonAndCheckBoxGroups(Set<ValueSelectionTarget> targets) {
257        // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TEST IMPLEMENTATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
258        Set<IGUIView> viewsBefore = new HashSet<IGUIView>();
259       
260        for (ValueSelectionTarget target : targets) {
261            viewsBefore.add(target.getView());
262        }
263        // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TEST IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
264       
265        condenseGuiElementGroups(targets, IRadioButton.class);
266        condenseGuiElementGroups(targets, ICheckBox.class);
267       
268        // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TEST IMPLEMENTATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
269        Set<IGUIView> viewsAfter = new HashSet<IGUIView>();
270       
271        for (ValueSelectionTarget target : targets) {
272            viewsAfter.add(target.getView());
273        }
274       
275        if (viewsBefore.size() != viewsAfter.size()) {
276            throw new IllegalStateException("this should not happen");
277        }
278       
279        for (IGUIView view : viewsBefore) {
280            if (!viewsAfter.contains(view)) {
281                throw new IllegalStateException("this should not happen too");
282            }
283        }
284        // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TEST IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
285    }
286   
287    /**
288     *
289     */
290    private void condenseGuiElementGroups(Set<ValueSelectionTarget> targets, Class<?> type) {
291        Map<IGUIView, List<IGUIElement>> guiElementsInViews = new HashMap<>();
292       
293        // determine the targets under consideration
294        for (ValueSelectionTarget target : targets) {
295            if (type.isInstance(target.getTarget())) {
296                List<IGUIElement> guiElementsInView = guiElementsInViews.get(target.getView());
297
298                if (guiElementsInView == null) {
299                    guiElementsInView = new LinkedList<IGUIElement>();
300                    guiElementsInViews.put(target.getView(), guiElementsInView);
301                }
302               
303                guiElementsInView.add(target);
304            }
305        }
306
307        for (Map.Entry<IGUIView, List<IGUIElement>> guiElements :
308                 guiElementsInViews.entrySet())
309        {
310            Map<IGUIElement, List<IGUIElement>> groups =
311                RuleUtils.getGroups(guiElements.getValue(), 3);
312
313            for (Map.Entry<IGUIElement, List<IGUIElement>> group : groups.entrySet()) {
314                //System.out.println("replacing");
315
316                // it is important to provide the correct view here, as the view of group.getKey()
317                // for HTML stuff may not be correct due to GUI model condensing
318                ValueSelectionTargetGroup valueSelectionTargetGroup =
319                    new ValueSelectionTargetGroup(group.getKey(), guiElements.getKey());
320               
321                for (IGUIElement toBeMerged : group.getValue()) {
322                    //System.out.println(targets.size() + "  " + toBeMerged.getView() + "  " +
323                    //                   toBeMerged);
324                   
325                    valueSelectionTargetGroup.addTargetToGroup(toBeMerged);
326                    targets.remove(toBeMerged);
327                }
328               
329                //System.out.println("with " + valueSelectionTargetGroup.getView() + "  " +
330                //                   valueSelectionTargetGroup);
331                targets.add(valueSelectionTargetGroup);
332            }
333        }
334    }
335
336    /**
337     *
338     */
339    private void calculateStatistics(List<IUserSession>          sessions,
340                                     final ValueChangeStatistics statistics)
341    {
342        final IGUIView[] currentView = new IGUIView[1];
343        final List<IEventTaskInstance> valueChangesInViewDisplay = new ArrayList<>();
344       
345        for (IUserSession session : sessions) {
346            currentView[0] = null;
347            valueChangesInViewDisplay.clear();
348           
349            for (final ITaskInstance currentRoot : session) {
350                currentRoot.accept(new DefaultTaskInstanceTraversingVisitor() {
351                    @Override
352                    public void visit(IEventTaskInstance eventTaskInstance) {
353                        if (eventTaskInstance.getEvent().getTarget() instanceof IGUIElement) {
354                            IGUIView view =
355                                ((IGUIElement) eventTaskInstance.getEvent().getTarget()).getView();
356                           
357                            if ((currentView[0] == null) && (view != null)) {
358                                currentView[0] = view;
359                                valueChangesInViewDisplay.clear();
360                            }
361                            else if ((currentView[0] != null) && (!currentView[0].equals(view))) {
362                                statistics.addValueChangesInViewDisplay
363                                    (currentView[0], valueChangesInViewDisplay);
364                               
365                                currentView[0] = view;
366                                valueChangesInViewDisplay.clear();
367                            }
368                        }
369                       
370                        if (isValueSelection(eventTaskInstance)) {
371                            valueChangesInViewDisplay.add(eventTaskInstance);
372                        }
373                    }
374                });
375            }
376           
377            // add the selected values of the last shown view in the session
378            if (currentView[0] != null) {
379                statistics.addValueChangesInViewDisplay(currentView[0], valueChangesInViewDisplay);
380            }
381        }
382    }
383
384    /**
385     *
386     */
387    private static class ValueChangeStatistics {
388       
389        /** */
390        private Map<ValueSelectionTarget, ValueSelectionTarget> targetReplacements =
391            new HashMap<>();
392       
393        /** */
394        private Map<IGUIView, List<ValueSelectionTarget>> valueSelectionTargetsInView =
395            new HashMap<>();
396       
397        /** */
398        private Map<ValueSelectionTarget, Map<Object, Integer>> selectedValues = new HashMap<>();
399
400        /**
401         *
402         */
403        public ValueChangeStatistics(Set<ValueSelectionTarget> targets) {
404            for (ValueSelectionTarget target : targets) {
405                if (target instanceof ValueSelectionTargetGroup) {
406                    for (IGUIElement groupElement : (ValueSelectionTargetGroup) target) {
407                        targetReplacements.put((ValueSelectionTarget) groupElement, target);
408                    }
409                }
410                else {
411                    targetReplacements.put((ValueSelectionTarget) target, target);
412                }
413               
414                List<ValueSelectionTarget> targetsInView =
415                    valueSelectionTargetsInView.get(target.getView());
416               
417                if (targetsInView == null) {
418                    targetsInView = new LinkedList<ValueSelectionTarget>();
419                    valueSelectionTargetsInView.put(target.getView(), targetsInView);
420                }
421               
422                targetsInView.add((ValueSelectionTarget) target);
423            }
424        }
425
426        /**
427         *
428         */
429        private void addValueChangesInViewDisplay(IGUIView                 view,
430                                                  List<IEventTaskInstance> valueChanges)
431        {
432            if (!valueSelectionTargetsInView.containsKey(view)) {
433                if (!valueChanges.isEmpty()) {
434                    throw new IllegalStateException("this should not happen, as we already " +
435                                                    "recorded the views with possible value " +
436                                                    "changes at this point");
437                }
438               
439                // view does not contain value changes --> return
440                return;
441            }
442           
443            //System.out.println
444            //    ("handling " + valueChanges.size() + " value changes on view " + view);
445       
446            Map<ValueSelectionTarget, Object> lastSelectedValues = new HashMap<>();
447           
448            // determine the last selected value for each of the value selection targets that were
449            // actively selected by the user
450            for (IEventTaskInstance valueChange : valueChanges) {
451                ValueSelectionTarget target = newValueSelectionTarget(valueChange);
452                Object selectedValue;
453               
454                if (valueChange.getEvent().getType() instanceof TextInput) {
455                    selectedValue = ((TextInput) valueChange.getEvent().getType()).getEnteredText();
456                }
457                else if (valueChange.getEvent().getType() instanceof ValueSelection) {
458                    selectedValue =
459                        ((ValueSelection<?>) valueChange.getEvent().getType()).getSelectedValue();
460                   
461                    if ((target.target instanceof IRadioButton) ||
462                        (target.target instanceof ICheckBox))
463                    {
464                        selectedValue = selectedValue + " (" + target + ")";
465                    }
466                    else if (target.target instanceof IComboBox) {
467                        if (selectedValue == null) {
468                            // this may have happened due to the recording issue that selected
469                            // values of combo boxes are not logged correctly. In this case,
470                            // pretend to have the a random value selected
471                            selectedValue = "randomValueDueToRecordingBug_" + Math.random();
472                        }
473                    }
474                }
475                else if (valueChange.getEvent().getType() instanceof MouseClick) {
476                    if ((target.target instanceof IRadioButton) ||
477                        (target.target instanceof ICheckBox))
478                    {
479                        selectedValue = target.toString();
480                    }
481                    else {
482                        throw new IllegalStateException("the implementation needs to be extended " +
483                                                        "to fully support clicks as value changes");
484                    }
485                }
486                else {
487                    throw new IllegalStateException("the implementation needs to be extended to " +
488                                                    "handle further value change types");
489                }
490               
491                target = targetReplacements.get(target);
492                lastSelectedValues.put(target, selectedValue);
493            }
494           
495            // add the default value selection for the unchanged value selection targets
496            for (ValueSelectionTarget target : valueSelectionTargetsInView.get(view)) {
497                if (!lastSelectedValues.containsKey(target)) {
498                    lastSelectedValues.put(target, DEFAULT_VALUE);
499                }
500            }
501           
502            // and now store the statistics
503            for (Map.Entry<ValueSelectionTarget, Object> selectedValue :
504                     lastSelectedValues.entrySet())
505            {
506                Map<Object, Integer> statistics = selectedValues.get(selectedValue.getKey());
507               
508                if (statistics == null) {
509                    statistics = new HashMap<>();
510                    selectedValues.put(selectedValue.getKey(), statistics);
511                }
512               
513                Integer counter = statistics.get(selectedValue.getValue());
514               
515                if (counter == null) {
516                    statistics.put(selectedValue.getValue(), 1);
517                }
518                else {
519                    statistics.put(selectedValue.getValue(), counter + 1);
520                }
521            }
522        }
523
524        /**
525         *
526         */
527        private Collection<IGUIView> getViewsWithValueSelections() {
528            return valueSelectionTargetsInView.keySet();
529        }
530
531        /**
532         *
533         */
534        private Collection<ValueSelectionTarget> getValueSelectionTargetsInView(IGUIView view) {
535            return valueSelectionTargetsInView.get(view);
536        }
537
538        /**
539         *
540         */
541        private Map<Object, Integer> getStatisticsForValueSelectionTarget
542            (ValueSelectionTarget target)
543        {
544            return selectedValues.get(target);
545        }
546    }
547
548    /**
549     *
550     */
551    private static class ValueSelectionTarget implements IGUIElement {
552
553        /**  */
554        private static final long serialVersionUID = 1L;
555
556        /** */
557        private IGUIView view;
558       
559        /** */
560        private IGUIElement target;
561       
562        /**
563         *
564         */
565        private ValueSelectionTarget(IGUIElement target) {
566            this.view = target.getView();
567            this.target = target;
568        }
569       
570        /**
571         *
572         */
573        private ValueSelectionTarget(IGUIElement target, IGUIView view) {
574            this.view = view;
575            this.target = target;
576        }
577
578        /**
579         *
580         */
581        public IGUIElementSpec getSpecification() {
582            return target.getSpecification();
583        }
584
585        /**
586         *
587         */
588        public String getPlatform() {
589            return target.getPlatform();
590        }
591
592        /**
593         *
594         */
595        public IGUIElement getParent() {
596            return target.getParent();
597        }
598
599        /**
600         *
601         */
602        public String getStringIdentifier() {
603            return target.getStringIdentifier();
604        }
605
606        /**
607         *
608         */
609        public GUIModel getGUIModel() {
610            return target.getGUIModel();
611        }
612
613        /**
614         *
615         */
616        public IHierarchicalEventTargetModel<?> getEventTargetModel() {
617            return target.getEventTargetModel();
618        }
619
620        /**
621         *
622         */
623        public boolean isUsed() {
624            return target.isUsed();
625        }
626
627        /**
628         *
629         */
630        public void markUsed() {
631            target.markUsed();
632        }
633
634        /**
635         *
636         */
637        public boolean equals(Object obj) {
638            if (this == obj) {
639                return true;
640            }
641            else if (obj instanceof ValueSelectionTarget) {
642                ValueSelectionTarget other = (ValueSelectionTarget) obj;
643                return ((this.view == null) ? other.view == null : other.view.equals(this.view) &&
644                        other.target.equals(this.target));
645            }
646           
647            return false;
648        }
649
650        /**
651         *
652         */
653        public int hashCode() {
654            if (view != null) {
655                return view.hashCode();
656            }
657            else {
658                return 0;
659            }
660        }
661
662        /**
663         *
664         */
665        public void updateSpecification(IEventTargetSpec furtherSpec) {
666            target.updateSpecification(furtherSpec);
667        }
668
669        /**
670         *
671         */
672        public void addEqualEventTarget(IHierarchicalEventTarget equalElement) {
673            target.addEqualEventTarget(equalElement);
674        }
675
676        /**
677         *
678         */
679        public double getDistanceTo(IGUIElement otherElement) {
680            return target.getDistanceTo(otherElement);
681        }
682
683        /* (non-Javadoc)
684         * @see java.lang.Object#toString()
685         */
686        @Override
687        public String toString() {
688            return target.toString();
689        }
690
691        /**
692         *
693         */
694        public IGUIView getView() {
695            return view;
696        }
697
698        /**
699         *
700         */
701        private IGUIElement getTarget() {
702            return target;
703        }
704
705    }
706
707    /**
708     *
709     */
710    private static class ValueSelectionTargetGroup extends ValueSelectionTarget
711        implements Iterable<IGUIElement>
712    {
713
714        /**  */
715        private static final long serialVersionUID = 1L;
716       
717        /** */
718        private List<IGUIElement> groupedTargets = new LinkedList<>();
719       
720        /**
721         *
722         */
723        private ValueSelectionTargetGroup(IGUIElement target, IGUIView view) {
724            super(target, view);
725        }
726
727        /**
728         *
729         */
730        private void addTargetToGroup(IGUIElement target) {
731            groupedTargets.add(target);
732        }
733
734        /* (non-Javadoc)
735         * @see java.lang.Iterable#iterator()
736         */
737        @Override
738        public Iterator<IGUIElement> iterator() {
739            return groupedTargets.iterator();
740        }
741
742        /* (non-Javadoc)
743         * @see java.lang.Object#toString()
744         */
745        @Override
746        public String toString() {
747            return "group(" + groupedTargets.size() + " targets, view " + super.getView() + ")";
748        }
749
750        /* (non-Javadoc)
751         * @see de.ugoe.cs.autoquest.usability.DefaultValueRule.ValueSelectionTarget#equals(java.lang.Object)
752         */
753        @Override
754        public boolean equals(Object obj) {
755            // Use parent implementation as the parent class will point to the parent GUI Element representing this group
756            return super.equals(obj);
757        }
758
759        /* (non-Javadoc)
760         * @see de.ugoe.cs.autoquest.usability.DefaultValueRule.ValueSelectionTarget#hashCode()
761         */
762        @Override
763        public int hashCode() {
764            // Use parent implementation as the parent class will point to the parent GUI Element representing this group
765            return super.hashCode();
766        }
767    }
768}
Note: See TracBrowser for help on using the repository browser.