source: trunk/quest-plugin-jfc/src/main/java/de/ugoe/cs/quest/plugin/jfc/guimodel/JFCGUIElementSpec.java @ 849

Last change on this file since 849 was 849, checked in by sherbold, 12 years ago
File size: 10.0 KB
Line 
1
2package de.ugoe.cs.quest.plugin.jfc.guimodel;
3
4import java.util.ArrayList;
5import java.util.List;
6
7import org.apache.commons.collections15.CollectionUtils;
8
9import de.ugoe.cs.quest.eventcore.guimodel.IGUIElement;
10import de.ugoe.cs.quest.eventcore.guimodel.IGUIElementSpec;
11
12/**
13 * <p>
14 * Implements the specification of {@link IGUIElement} for {@link JFCGUIElement}s.
15 * </p>
16 *
17 * @version 1.0
18 * @author Patrick Harms
19 */
20public class JFCGUIElementSpec implements IGUIElementSpec {
21
22    /**
23     * <p>
24     * Id for object serialization.
25     * </p>
26     */
27    private static final long serialVersionUID = 1L;
28
29    /**
30     * <p>
31     * Current name of the GUI element
32     * </p>
33     */
34    private String name;
35
36    /**
37     * <p>
38     * Previous names of the GUI element as it may have changed over time.
39     * </p>
40     */
41    private List<String> formerNames = new ArrayList<String>();
42
43    /**
44     * <p>
45     * Type of the GUI element, i.e., its Java class.
46     * </p>
47     */
48    private String type = null;
49
50    /**
51     * <p>
52     * Icon associated with the GUI element.
53     * </p>
54     */
55    private String icon = null;
56
57    /**
58     * <p>
59     * Index of the GUI element in its parent element.
60     * </p>
61     */
62    private int index = -1;
63
64    /**
65     * <p>
66     * Hash code of the window element. Used as unique identifier during its existence.
67     * </p>
68     */
69    private int elementHash = -1;
70
71    /**
72     * <p>
73     * Previous hashes of the window as the window may have been destroyed and recreated.
74     * </p>
75     */
76    private List<Integer> formerElementHashes = new ArrayList<Integer>();
77
78    /*
79     * (non-Javadoc)
80     *
81     * @see
82     * de.ugoe.cs.quest.eventcore.guimodel.IGUIElementSpec#getSecificationSimilarity(IGUIElementSpec
83     * )
84     */
85    @Override
86    public boolean getSimilarity(IGUIElementSpec other) {
87        if (this == other) {
88            return true;
89        }
90
91        if (!(other instanceof JFCGUIElementSpec)) {
92            return false;
93        }
94
95        JFCGUIElementSpec otherSpec = (JFCGUIElementSpec) other;
96
97        if ((type != otherSpec.type) && ((type != null) && (!type.equals(otherSpec.type)))) {
98            return false;
99        }
100
101        if ((icon != otherSpec.icon) && ((icon != null) && (!icon.equals(otherSpec.icon)))) {
102            return false;
103        }
104
105        // up to now, we compared, if the basics match. Now lets compare the id, the name and the
106        // index. All may change. The name may be reset (e.g. the title of a frame using the
107        // asterisk in the case data was changed). The id may change if e.g. a dialog is closed
108        // and reopend, i.e. a new instance is created. The index may change, if later in a panel
109        // a new element is added or another one is removed. If the element hash or the name stay
110        // the same, then similarity is given. Therefore these are the first two comparisons
111
112        if (elementHash == otherSpec.elementHash) {
113            return true;
114        }
115
116        if ((name != null) && (name.equals(otherSpec.name))) {
117            return true;
118        }
119
120        if ((((name == null) && (otherSpec.name == null)) || (("".equals(name)) && (""
121            .equals(otherSpec.name)))) &&
122            (formerNames.size() == 0) &&
123            (otherSpec.formerNames.size() == 0))
124        {
125            return true;
126        }
127
128        // if the id and the name did not stay the same, then the name should be checked first.
129        // One of all known names of one of the specs must be equal to one of the known names of the
130        // respective other spec for similarity. Furthermore, if this is given, the index should
131        // have stayed the same.
132
133        if ((otherSpec.name != null) && formerNames.contains(otherSpec.name)) {
134            return index == otherSpec.index;
135        }
136
137        if ((name != null) && otherSpec.formerNames.contains(name)) {
138            return index == otherSpec.index;
139        }
140
141        if (CollectionUtils.containsAny(formerNames, otherSpec.formerNames)) {
142            return index == otherSpec.index;
143        }
144
145        // ok. Even the names do not match. This is usually a clear indication, that the elements
146        // are distinct. However, we check, if the former ids matched. This is very unlikely
147        // to happen. But it may occur, if a GUI element does not have a name or its name stays
148        // the empty string and if this GUI element is created, destroyed, and created again.
149        // Again we are restrictive and request the index to be equal as well.
150
151        if (formerElementHashes.contains(otherSpec.elementHash)) {
152            return index == otherSpec.index;
153        }
154
155        if (otherSpec.formerElementHashes.contains(elementHash)) {
156            return index == otherSpec.index;
157        }
158
159        if (CollectionUtils.containsAny(formerElementHashes, otherSpec.formerElementHashes)) {
160            return index == otherSpec.index;
161        }
162
163        // now we can be really sure, that the GUI elements differ
164
165        return false;
166    }
167
168    /*
169     * (non-Javadoc)
170     *
171     * @see de.ugoe.cs.quest.eventcore.guimodel.IGUIElementSpec#equals(IGUIElementSpec)
172     */
173    @Override
174    public boolean equals(Object other) {
175        if (this == other) {
176            return true;
177        }
178
179        if (!(other instanceof JFCGUIElementSpec)) {
180            return false;
181        }
182
183        JFCGUIElementSpec otherSpec = (JFCGUIElementSpec) other;
184
185        return ((name == otherSpec.name) || ((name != null) && (name.equals(otherSpec.name)))) &&
186            ((type == otherSpec.type) || ((type != null) && (type.equals(otherSpec.type)))) &&
187            ((icon == otherSpec.icon) || ((icon != null) && (icon.equals(otherSpec.icon)))) &&
188            (index == otherSpec.index) && (elementHash == otherSpec.elementHash);
189    }
190
191    /*
192     * (non-Javadoc)
193     *
194     * @see java.lang.Object#hashCode()
195     */
196    @Override
197    public int hashCode() {
198        return (name + type + icon + index + elementHash).hashCode();
199    }
200
201    /**
202     * <p>
203     * Returns the name of the specified GUI element.
204     * </p>
205     *
206     * @return the name
207     */
208    public String getName() {
209        StringBuffer names = new StringBuffer();
210
211        if (name != null) {
212            names.append('"');
213            names.append(name);
214            names.append('"');
215        }
216        else {
217            names.append("NOT_SET");
218        }
219
220        if (formerNames.size() > 0) {
221
222            names.append(" (aka ");
223
224            for (int i = 0; i < formerNames.size(); i++) {
225                if (i > 0) {
226                    names.append("/");
227                }
228
229                names.append('"');
230                names.append(formerNames.get(i));
231                names.append('"');
232            }
233
234            names.append(")");
235        }
236
237        return names.toString();
238    }
239
240    /**
241     * <p>
242     * Returns the title of the specified GUI element.
243     * </p>
244     *
245     * @return the title
246     */
247    public String getType() {
248        return type;
249    }
250
251    /**
252     * <p>
253     * Returns the icon associated with the specified GUI element.
254     * </p>
255     *
256     * @return the icon
257     */
258    public String getIcon() {
259        return icon;
260    }
261
262    /**
263     * <p>
264     * Returns the index of the specified GUI element in its parent element.
265     * </p>
266     *
267     * @return the index
268     */
269    public int getIndex() {
270        return index;
271    }
272
273    /**
274     * <p>
275     * Returns the object hash of the specified GUI element.
276     * </p>
277     *
278     * @return the elementHash
279     */
280    public int getElementHash() {
281        return elementHash;
282    }
283
284    /**
285     * <p>
286     * Sets the name of the specified GUI element.
287     * </p>
288     *
289     * @param newName
290     *            the name
291     */
292    public void setName(String newName) {
293        if ((this.name != null) && (!this.name.equals(newName)) &&
294            (!this.formerNames.contains(this.name)))
295        {
296            this.formerNames.add(this.name);
297        }
298
299        this.name = newName;
300    }
301
302    /**
303     * <p>
304     * Sets the type of the specified GUI element.
305     * </p>
306     *
307     * @param type
308     *            the type
309     */
310    public void setType(String type) {
311        this.type = type;
312    }
313
314    /**
315     * <p>
316     * Sets the icon associated with the specified GUI element.
317     * </p>
318     *
319     * @param icon
320     *            the icon
321     */
322    public void setIcon(String icon) {
323        this.icon = icon;
324    }
325
326    /**
327     * <p>
328     * Sets the index in its parent element of the specified GUI element.
329     * </p>
330     *
331     * @param index
332     *            the index
333     */
334    public void setIndex(int index) {
335        this.index = index;
336    }
337
338    /**
339     * <p>
340     * Sets the object hash of the specified GUI element.
341     * </p>
342     *
343     * @param newElementHash
344     *            the element hash
345     */
346    public void setElementHash(int newElementHash) {
347        if ((this.elementHash > -1) && !this.formerElementHashes.contains(this.elementHash)) {
348            this.formerElementHashes.add(this.elementHash);
349        }
350
351        this.elementHash = newElementHash;
352    }
353
354    /**
355     * <p>
356     * Updates the specification with another specification.
357     * </p>
358     *
359     * @param furtherSpec
360     *            specification used to update the current specification
361     */
362    void update(JFCGUIElementSpec other) {
363        if (other != this) {
364            for (int formerElementHash : other.formerElementHashes) {
365                setElementHash(formerElementHash);
366            }
367
368            if (elementHash != other.elementHash) {
369                elementHash = other.elementHash;
370            }
371
372            for (String formerName : other.formerNames) {
373                setName(formerName);
374            }
375
376            if ((name != other.name) && (name != null) && (!name.equals(other.name))) {
377                setName(other.name);
378            }
379        }
380    }
381
382    /*
383     * (non-Javadoc)
384     *
385     * @see java.lang.Object#toString()
386     */
387    public String toString() {
388        return "[" + getName() + ";\"" + type + "\";\"" + icon + "\";" + index + ";" + elementHash +
389            "]";
390    }
391
392}
Note: See TracBrowser for help on using the repository browser.