source: trunk/autoquest-plugin-android/src/main/java/de/ugoe/cs/autoquest/plugin/android/guimodel/ANDROIDGUIElementSpec.java @ 1869

Last change on this file since 1869 was 1869, checked in by funger, 9 years ago
  • clean up
  • comments improved
  • add name, implement getSimilartiy, correct equals and hashCode in ANDROIDGUIElementSpec
  • add get and set methods to ANDROIDGUIElement
  • Property svn:mime-type set to text/plain
File size: 8.8 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.plugin.android.guimodel;
16
17import java.util.List;
18
19import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec;
20
21/**
22 * <p>
23 * Implements the specification of {@link IGUIElement} for {@link ANDROIDGUIElement}s.
24 * </p>
25 *
26 * @version 1.0
27 * @author Florian Unger
28 */
29public class ANDROIDGUIElementSpec implements IGUIElementSpec {
30
31    /**
32     * <p>
33     * Default serial version UID
34     * </p>
35     */
36    private static final long serialVersionUID = 1L;
37
38    /*
39     * (non-Javadoc)
40     *
41     * @see de.ugoe.cs.autoquest.androidmonitor.AndroidmonitorLogFile#logComponent()
42     */
43    /**
44     * <p>
45     * Hash code of the GUI element. Used as unique identifier during parsing a log file. Note that
46     * it is possible that the hash code of an element changes over several log files even if they
47     * come from the same target.
48     * </p>
49     */
50    private int elementHash;
51
52    /**
53     * <p>
54     * Path to an element in an activity. e.g. a path of a button could look like
55     * MainActivity/DecorView/ActionBarOverlayLayout/FrameLayout/ RelativeLayout/Button
56     * </p>
57     */
58    private String path;
59
60    /*
61     * (non-Javadoc)
62     *
63     * @see http://developer.android.com/reference/android/view/View.html#getId()
64     */
65    /**
66     * <p>
67     * Id of the object as it is returned by view.getId().
68     * </p>
69     */
70    private int index;
71
72    /**
73     * <p>
74     * Current name of the GUI element
75     * </p>
76     */
77    private String name;
78
79    /**
80     * <p>
81     * The type of GUI element, i.e., the class of the android GUI element.
82     * </p>
83     */
84    private String type;
85
86    /**
87     * <p>
88     * Type hierarchy of the class itself.
89     * </p>
90     */
91    private List<String> typeHierarchy = null;
92   
93    /*
94     * (non-Javadoc)
95     *
96     * @see
97     * de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getSecificationSimilarity(IGUIElementSpec
98     * )
99     */
100    @Override
101    public boolean getSimilarity(IGUIElementSpec other) {
102        if (this == other) {
103            return true;
104        }
105
106        if (!(other instanceof ANDROIDGUIElementSpec)) {
107            return false;
108        }
109
110        ANDROIDGUIElementSpec otherSpec = (ANDROIDGUIElementSpec) other;
111
112        if (type == null ? otherSpec.type != null : !type.equals(otherSpec.type)) {
113            return false;
114        }
115
116        /*
117         * Up to now, we compared, if the basics match. Due to testing with different virtual
118         * devices it seems to be the case that the id of a view (named index here) keeps the same
119         * even on different devices even if the hashCode changes. Some of the GUI elements does not
120         * have an id (id is -1).
121         */
122
123        if (otherSpec.index > 1 && index == otherSpec.index) {
124            return true;
125        }
126
127        /*
128         * Two elements could also be similar if the path of the elements is equal and the name is
129         * set, equal and not equal to "image:" even if index <= 1. This comparison is not
130         * implemented up to know due to the reason that all recorded elements up to 2015/01 either
131         * have an index > 1 or no name to be compared.
132         *
133         * In all other cases up to know it is not clear if two elements are similar.
134         *
135         * Not working:
136         *
137         * - Position of the elements: Due to the reason that there are a lot of different displays
138         * on the android market and the in the most cases the layout depends on the display size
139         * (different resolutions) similar elements have different positions.
140         */
141
142        return false;
143    }
144   
145
146    /*
147     * (non-Javadoc)
148     *
149     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getType()
150     */
151    @Override
152    public String getType() {
153        return type;
154    }
155
156    /*
157     * (non-Javadoc)
158     *
159     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getTypeHierarchy ()
160     */
161    @Override
162    public String[] getTypeHierarchy() {
163        if (typeHierarchy == null) {
164            return new String[]
165                { (getType()) };
166        }
167        else
168            return typeHierarchy.toArray(new String[typeHierarchy.size()]);
169    }
170   
171    /**
172     * <p>
173     * Returns the object hash of the specified GUI element.
174     * </p>
175     *
176     * @return the elementHash
177     */
178    public int getElementHash() {
179        return elementHash;
180    }
181
182    /**
183     * <p>
184     * Returns the path associated with the specified GUI element.
185     * </p>
186     *
187     * @return the path to an element
188     */
189    public String getPath() {
190        return path;
191    }
192
193    /**
194     * <p>
195     * Returns the GUI element identifier.
196     * </p>
197     *
198     * @return identifier of the GUI element
199     */
200    public int getIndex() {
201        return index;
202    }
203
204    /**
205     * <p>
206     * Returns the name of the specified GUI element. Displayed text in the application or image
207     * name.
208     * </p>
209     *
210     * @return text or image of the GUI element.
211     */
212    public String getName() {       
213        if (name == null || name.trim().length() == 0) {
214            return "NOT_SET";
215        }
216        return name;
217    }
218
219    /**
220     * <p>
221     * Sets the GUI element identifier.
222     * </p>
223     *
224     * @param indentifier
225     */
226    public void setIndex(int index) {
227        this.index = index;
228    }
229
230    /**
231     * Set the hash code associated with the GUI element.
232     *
233     * @param hash
234     *            the hash of an element object
235     */
236    public void setElementHash(int hash) {
237        this.elementHash = hash;
238    }
239
240    /**
241     * Set the path associated with the specified GUI element.
242     *
243     * @param path
244     *            the path to an element
245     */
246    public void setPath(String path) {
247        this.path = path;
248    }
249
250    /**
251     * <p>
252     * Sets the type of the specified GUI element.
253     * </p>
254     *
255     * @param type
256     *            the type
257     */
258    public void setType(String type) {
259        this.type = type;
260    }
261
262    /**
263     * <p>
264     * Sets the name of the specified GUI element. Displayed text in the application or image name.
265     * </p>
266     *
267     * @param name
268     *            the name
269     */
270    public void setName(String name) {
271        this.name = name;
272    }
273
274    /**
275     * <p>
276     * Sets the type hierarchy of the specified GUI element.
277     *
278     * @param typeHierarchy
279     *            </p>
280     */
281    public void setTypeHierarchy(List<String> typeHierarchy) {
282        this.typeHierarchy = typeHierarchy;
283    }
284   
285    /*
286     * (non-Javadoc)
287     *
288     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#equals(IGUIElementSpec)
289     */
290    @Override
291    public boolean equals(Object other) {
292        if (this == other) {
293            return true;
294        }
295
296        if (!(other instanceof ANDROIDGUIElementSpec)) {
297            return false;
298        }
299
300        ANDROIDGUIElementSpec otherSpec = (ANDROIDGUIElementSpec) other;
301
302        return (elementHash == otherSpec.elementHash) &&
303            (path == null ? otherSpec.path == null : path.equals(otherSpec.path)) &&
304            (index == otherSpec.index) &&
305            (name == null ? otherSpec.name == null : name.equals(otherSpec.name)) &&
306            (type == null ? otherSpec.type == null : type.equals(otherSpec.type));
307    }
308   
309    /*
310     * (non-Javadoc)
311     *
312     * @see java.lang.Object#hashCode()
313     */
314    @Override
315    public int hashCode() {
316     // 17 due to the reason that this is a prime number.
317        int result = 17;
318        /*
319         * 31 due to the reason that a lot of VM's could optimize this multiplication by a shift.
320         * Source: Effective Java, Joshua Bloch, 2008, p.48
321         */
322        result = 31 * result + elementHash;
323        result = 31 * result + path.hashCode();
324        result = 31 * result + index;
325        result = 31 * result + getName().hashCode();
326        result = 31 * result + type.hashCode();     
327        return result;
328    }
329   
330
331}
Note: See TracBrowser for help on using the repository browser.