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

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