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

Last change on this file since 1121 was 1121, checked in by pharms, 11 years ago
  • changed implementation for equality management so that GUI elements as well as their equality relationships are serializable
  • Property svn:executable set to *
File size: 7.6 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     */
49    private final 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     */
63    boolean usageObserved;
[603]64
[576]65    /**
66     * <p>
[831]67     * Constructor. Creates a new AbstractDefaultGUIElement.
[576]68     * </p>
[831]69     *
[576]70     * @param specification
[831]71     *            specification of the created GUI element
72     * @param parent
73     *            parent of the created GUI element; null means the element is a top-level window
[565]74     */
[603]75    public AbstractDefaultGUIElement(IGUIElementSpec specification, IGUIElement parent) {
[576]76        this.specification = specification;
[603]77        this.parent = parent;
[1010]78        this.usageObserved = false;
[565]79    }
80
[545]81    /*
82     * (non-Javadoc)
83     *
[576]84     * @see de.ugoe.cs.tasktree.guimodel.GUIElement#getSpecification()
[545]85     */
86    @Override
[576]87    public IGUIElementSpec getSpecification() {
88        return specification;
[545]89    }
90
[831]91    /*
92     * (non-Javadoc)
93     *
[922]94     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getParent()
[603]95     */
96    @Override
97    public IGUIElement getParent() {
98        return parent;
99    }
100
[831]101    /*
102     * (non-Javadoc)
103     *
[922]104     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#addEqualGUIElement(IGUIElement)
[609]105     */
106    @Override
[831]107    public void addEqualGUIElement(IGUIElement equalElement) {
[1121]108        if (!(equalElement instanceof AbstractDefaultGUIElement)) {
109            throw new IllegalArgumentException
110                ("this implementation can only handle other AbstractDefaultGUIElements");
111        }
112       
113        AbstractDefaultGUIElement other = (AbstractDefaultGUIElement) equalElement;
114       
115        synchronized (AbstractDefaultGUIElement.class) {
116            if (this.equalGUIElements == null) {
117                if (other.equalGUIElements == null) {
118                    this.equalGUIElements = new LinkedList<AbstractDefaultGUIElement>();
119                    this.equalGUIElements.add(this);
120                    this.equalGUIElements.add(other);
121                    other.equalGUIElements = this.equalGUIElements;
122                }
123                else {
124                    addIfNotContained(other.equalGUIElements, this);
125                    this.equalGUIElements = other.equalGUIElements;
126                }
127            }
128            else {
129                if (other.equalGUIElements == null) {
130                    addIfNotContained(this.equalGUIElements, other);
131                    other.equalGUIElements = this.equalGUIElements;
132                }
133                else if (this.equalGUIElements != other.equalGUIElements) {
134                    this.equalGUIElements.addAll(other.equalGUIElements);
135
136                    // we also have to set this new list for all other elements for which so
137                    // far list2 was registered
138                    for (AbstractDefaultGUIElement candidate : other.equalGUIElements) {
139                        candidate.equalGUIElements = this.equalGUIElements;
140                    }
141
142                    other.equalGUIElements = this.equalGUIElements;
143                }
144                // else
145                // in this case, both GUI elements should already be registered with the same
146                // lists.
147            }
148        }
[609]149    }
150
[545]151    /*
152     * (non-Javadoc)
153     *
[1051]154     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#isUsed()
155     */
156    @Override
157    public boolean isUsed() {
158        return usageObserved;
159    }
160
161    /*
162     * (non-Javadoc)
163     *
164     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#markUsed()
165     */
166    @Override
167    public void markUsed() {
168        this.usageObserved = true;
169    }
170
171    /*
172     * (non-Javadoc)
173     *
[576]174     * @see GUIElement#equals(GUIElement)
[545]175     */
[603]176    public final boolean equals(Object other) {
[609]177        // implement final, as GUI elements are all singletons and they equal only if they are the
178        // same object or if they are in the list of equal GUI elements
[1121]179        if (super.equals(other)) {
180            return true;
181        }
182        else if (other instanceof AbstractDefaultGUIElement) {
183            synchronized (AbstractDefaultGUIElement.class) {
184                if (equalGUIElements != null) {
185                    for (IGUIElement candidate : equalGUIElements) {
186                        if (candidate == other) {
187                            return true;
188                        }
189                    }
190                }
191            }
192        }
193
194        return false;
[545]195    }
196
[831]197    /*
198     * (non-Javadoc)
199     *
[603]200     * @see java.lang.Object#hashCode()
201     */
202    @Override
203    public final int hashCode() {
[609]204        // implement final, as GUI elements are all singletons and they equal only if they are the
205        // same object. If there are several GUI element objects that represent the same GUI element
206        // then they are stored in the list of equal elements. In this case, the hash code of the
207        // list is unique within the system
[1121]208        synchronized (AbstractDefaultGUIElement.class) {
209            if (this.equalGUIElements == null) {
210                this.equalGUIElements = new LinkedList<AbstractDefaultGUIElement>();
211                this.equalGUIElements.add(this);
212            }
213           
214            return System.identityHashCode(this.equalGUIElements);
215        }
[603]216    }
[1010]217   
[609]218    /**
219     * <p>
[1121]220     * Adds an {@link AbstractDefaultGUIElement} as equal to a list of
221     * {@link AbstractDefaultGUIElement}s if and only if it is not already contained.
[609]222     * </p>
223     *
[1121]224     * @param equalElementsList
225     *            list of {@link AbstractDefaultGUIElement} to which the GUI element is added
226     * @param guiElement
227     *            GUI element to be added
[609]228     */
[1121]229    private void addIfNotContained(List<AbstractDefaultGUIElement> equalElementsList,
230                                   AbstractDefaultGUIElement       guiElement)
231    {
232        for (IGUIElement candidate : equalElementsList) {
233            if (candidate == guiElement) {
234                return;
[609]235            }
236        }
237
[1121]238        equalElementsList.add(guiElement);
[609]239    }
240
[545]241}
Note: See TracBrowser for help on using the repository browser.