source: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/AbstractDefaultGUIElement.java @ 1433

Last change on this file since 1433 was 1433, checked in by pharms, 10 years ago
  • added support to retrieve the GUI model to which a GUI element belongs from the GUI element itself
  • Property svn:executable set to *
File size: 8.9 KB
RevLine 
[927]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.
[831]14
[922]15package de.ugoe.cs.autoquest.eventcore.guimodel;
[545]16
[609]17import java.util.LinkedList;
18import java.util.List;
19
[545]20/**
[831]21 * <p>
22 * Skeletal implementation for GUI elements.
23 * </p>
[545]24 *
[831]25 * @version 1.0
26 * @author Patrick Harms
[545]27 */
28public abstract class AbstractDefaultGUIElement implements IGUIElement {
[831]29
30    /**
31     * <p>
32     * Id for object serialization.
33     * </p>
34     */
[545]35    public static final long serialVersionUID = 1L;
36
[831]37    /**
38     * <p>
39     * Specification of the GUI element
40     * </p>
41     */
42    private final IGUIElementSpec specification;
[545]43
[831]44    /**
45     * <p>
46     * Reference to the parent element
47     * </p>
48     */
[1259]49    private IGUIElement parent;
[1010]50   
51    /**
52     * <p>
[1121]53     * List of other GUI elements being equal to this
54     * </p>
55     */
56    private List<AbstractDefaultGUIElement> equalGUIElements = null;
57   
58    /**
59     * <p>
[1010]60     * Boolean that indicates if a GUIElement was used during a session.
61     * </p>
62     */
[1385]63    private boolean usageObserved;
[603]64
[576]65    /**
66     * <p>
[1433]67     * the reference to the GUI model to which this GUI element belongs.
68     * </p>
69     */
70    private GUIModel guiModel;
71
72    /**
73     * <p>
[831]74     * Constructor. Creates a new AbstractDefaultGUIElement.
[576]75     * </p>
[831]76     *
[576]77     * @param specification
[831]78     *            specification of the created GUI element
79     * @param parent
80     *            parent of the created GUI element; null means the element is a top-level window
[565]81     */
[603]82    public AbstractDefaultGUIElement(IGUIElementSpec specification, IGUIElement parent) {
[576]83        this.specification = specification;
[1010]84        this.usageObserved = false;
[1259]85        setParent(parent);
[565]86    }
87
[545]88    /*
89     * (non-Javadoc)
90     *
[576]91     * @see de.ugoe.cs.tasktree.guimodel.GUIElement#getSpecification()
[545]92     */
93    @Override
[576]94    public IGUIElementSpec getSpecification() {
95        return specification;
[545]96    }
97
[831]98    /*
99     * (non-Javadoc)
100     *
[922]101     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getParent()
[603]102     */
103    @Override
104    public IGUIElement getParent() {
105        return parent;
106    }
107
[1433]108    /* (non-Javadoc)
109     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getGUIModel()
110     */
111    @Override
112    public GUIModel getGUIModel() {
113       return guiModel;
114    }
115
[831]116    /*
117     * (non-Javadoc)
118     *
[922]119     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#addEqualGUIElement(IGUIElement)
[609]120     */
121    @Override
[831]122    public void addEqualGUIElement(IGUIElement equalElement) {
[1121]123        if (!(equalElement instanceof AbstractDefaultGUIElement)) {
124            throw new IllegalArgumentException
125                ("this implementation can only handle other AbstractDefaultGUIElements");
126        }
127       
128        AbstractDefaultGUIElement other = (AbstractDefaultGUIElement) equalElement;
129       
130        synchronized (AbstractDefaultGUIElement.class) {
131            if (this.equalGUIElements == null) {
132                if (other.equalGUIElements == null) {
133                    this.equalGUIElements = new LinkedList<AbstractDefaultGUIElement>();
134                    this.equalGUIElements.add(this);
135                    this.equalGUIElements.add(other);
136                    other.equalGUIElements = this.equalGUIElements;
137                }
138                else {
139                    addIfNotContained(other.equalGUIElements, this);
140                    this.equalGUIElements = other.equalGUIElements;
141                }
142            }
143            else {
144                if (other.equalGUIElements == null) {
145                    addIfNotContained(this.equalGUIElements, other);
146                    other.equalGUIElements = this.equalGUIElements;
147                }
148                else if (this.equalGUIElements != other.equalGUIElements) {
149                    this.equalGUIElements.addAll(other.equalGUIElements);
150
151                    // we also have to set this new list for all other elements for which so
152                    // far list2 was registered
153                    for (AbstractDefaultGUIElement candidate : other.equalGUIElements) {
154                        candidate.equalGUIElements = this.equalGUIElements;
155                    }
156
157                    other.equalGUIElements = this.equalGUIElements;
158                }
159                // else
160                // in this case, both GUI elements should already be registered with the same
161                // lists.
162            }
163        }
[609]164    }
165
[545]166    /*
167     * (non-Javadoc)
168     *
[1051]169     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#isUsed()
170     */
171    @Override
172    public boolean isUsed() {
173        return usageObserved;
174    }
175
176    /*
177     * (non-Javadoc)
178     *
179     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#markUsed()
180     */
181    @Override
182    public void markUsed() {
183        this.usageObserved = true;
184    }
185
186    /*
187     * (non-Javadoc)
188     *
[576]189     * @see GUIElement#equals(GUIElement)
[545]190     */
[603]191    public final boolean equals(Object other) {
[609]192        // implement final, as GUI elements are all singletons and they equal only if they are the
193        // same object or if they are in the list of equal GUI elements
[1121]194        if (super.equals(other)) {
195            return true;
196        }
197        else if (other instanceof AbstractDefaultGUIElement) {
198            synchronized (AbstractDefaultGUIElement.class) {
199                if (equalGUIElements != null) {
200                    for (IGUIElement candidate : equalGUIElements) {
201                        if (candidate == other) {
202                            return true;
203                        }
204                    }
205                }
206            }
207        }
208
209        return false;
[545]210    }
211
[831]212    /*
213     * (non-Javadoc)
214     *
[603]215     * @see java.lang.Object#hashCode()
216     */
217    @Override
218    public final int hashCode() {
[609]219        // implement final, as GUI elements are all singletons and they equal only if they are the
220        // same object. If there are several GUI element objects that represent the same GUI element
221        // then they are stored in the list of equal elements. In this case, the hash code of the
222        // list is unique within the system
[1121]223        synchronized (AbstractDefaultGUIElement.class) {
224            if (this.equalGUIElements == null) {
225                this.equalGUIElements = new LinkedList<AbstractDefaultGUIElement>();
226                this.equalGUIElements.add(this);
227            }
228           
229            return System.identityHashCode(this.equalGUIElements);
230        }
[603]231    }
[1010]232   
[609]233    /**
234     * <p>
[1259]235     * updates the parent node of this node if required due to model restructuring
236     * </p>
237     */
238    void setParent(IGUIElement newParent) {
[1385]239        synchronized (AbstractDefaultGUIElement.class) {
240            // all equal GUI elements must have the same parent. Otherwise, they are not equal
241            // anymore and we would have discrepancies on the return value of getParent() on
242            // equal GUI elements.
243            this.parent = newParent;
244            if (equalGUIElements != null) {
245                for (AbstractDefaultGUIElement candidate : equalGUIElements) {
246                    candidate.parent = newParent;
247                }
248            }
249        }
[1433]250    }
[1385]251
[1433]252    /**
253     * <p>
254     * used to set the GUI model to which this GUI element belongs. Will be set automatically, if
255     * used in combination with {@link GUIModel};
256     * </p>
257     *
258     * @param guiModel
259     */
260    void setGUIModel(GUIModel guiModel) {
261        this.guiModel = guiModel;
[1259]262    }
263
264    /**
265     * <p>
[1121]266     * Adds an {@link AbstractDefaultGUIElement} as equal to a list of
267     * {@link AbstractDefaultGUIElement}s if and only if it is not already contained.
[609]268     * </p>
269     *
[1121]270     * @param equalElementsList
271     *            list of {@link AbstractDefaultGUIElement} to which the GUI element is added
272     * @param guiElement
273     *            GUI element to be added
[609]274     */
[1121]275    private void addIfNotContained(List<AbstractDefaultGUIElement> equalElementsList,
276                                   AbstractDefaultGUIElement       guiElement)
277    {
278        for (IGUIElement candidate : equalElementsList) {
279            if (candidate == guiElement) {
280                return;
[609]281            }
282        }
283
[1121]284        equalElementsList.add(guiElement);
[609]285    }
286
[545]287}
Note: See TracBrowser for help on using the repository browser.