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

Last change on this file since 714 was 714, checked in by pharms, 12 years ago

improved comparison of GUI elements

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