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

Last change on this file since 1026 was 1026, checked in by fglaser, 12 years ago
  • GUIElementTree is now generic to allow different id types in the internal handling of GUI elements. This became necessary during the development of HTMLLogParser.
  • Property svn:mime-type set to text/plain
File size: 8.2 KB
Line 
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.
14
15package de.ugoe.cs.autoquest.eventcore.guimodel;
16
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.List;
20import java.util.Map;
21
22import de.ugoe.cs.autoquest.eventcore.guimodel.GUIElementFactory;
23import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel;
24import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModelException;
25import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementFactory;
26
27/**
28 * <p>
29 * This class provides the interfaces for GUI element trees.
30 * </p>
31 * <p>
32 * The GUIElementTree represents the hierarchical structure of the GUI elements "as it is" currently during
33 * a session. It may change during the session due to creation and destruction of GUI elements. The parameter
34 * T represents the id type of the GUI elements that are handled internally.
35 * </p>
36 *
37 * @author Fabian Glaser
38 * @author Steffen Herbold
39 * @version 1.0
40 */
41public class GUIElementTree<T> {
42    /**
43     * <p>
44     * Map of all GUI elements that are part of the tree for efficient searching. The keys of the
45     * map are the ids of the GUI elements.
46     * </p>
47     */
48    private Map<T, IGUIElement> guiElements;
49
50    /**
51     * <p>
52     * Map of all GUI element specifications that are part of the tree for efficient searching. The
53     * keys of the map are the ids of the GUI elements.
54     * </p>
55     */
56    private Map<T, IGUIElementSpec> guiElementSpecs;
57
58    /**
59     * <p>
60     * Map of all children of GUI elements that are part of the tree. The keys of the map are the
61     * ids of the parent GUI elements.
62     * </p>
63     */
64    private Map<T, List<T>> childRelations;
65
66    /**
67     * <p>
68     * Map of all parents of GUI elements that are part of the tree. The keys of the map are the
69     * ids of the child GUI elements.
70     * </p>
71     */
72    private Map<T, T> parentRelations;
73
74    /**
75     * <p>
76     * the internally created GUI model
77     * </p>
78     */
79    private GUIModel guiModel;
80
81    /**
82     * <p>
83     * the GUI element factory used in the model
84     * </p>
85     */
86    private IGUIElementFactory guiElementFactory = GUIElementFactory.getInstance();
87
88 
89
90    /**
91     * <p>
92     * Creates a new GUIElementTree.
93     * </p>
94     */
95    public GUIElementTree() {
96        guiElementSpecs = new HashMap<T, IGUIElementSpec>();
97        childRelations = new HashMap<T, List<T>>();
98        parentRelations = new HashMap<T, T>();
99        guiElements = new HashMap<T, IGUIElement>();
100        guiModel = new GUIModel();
101    }
102   
103    /**
104     * <p>
105     * Creates a GUIElementTree with an already existing guiModel
106     * @param guiModel
107     * </p>
108     */
109    public GUIElementTree(GUIModel guiModel){
110        guiElementSpecs = new HashMap<T, IGUIElementSpec>();
111        childRelations = new HashMap<T, List<T>>();
112        parentRelations = new HashMap<T, T>();
113        guiElements = new HashMap<T, IGUIElement>();
114        this.guiModel = guiModel;
115    }
116
117    /**
118     * <p>
119     * Adds a new GUI element to the tree.
120     * </p>
121     *
122     * @param guiElementID
123     *            id of the GUI element to be created
124     * @param parentID
125     *            id of the parent GUI element
126     * @param guiElementSpec
127     *                    the GUI element specification
128     */
129    public void add(T guiElementID,
130                                T parentID,
131                    IGUIElementSpec guiElementSpec)
132    {
133        IGUIElement guiElement = guiElements.get(guiElementID);
134       
135        if (guiElement == null) {
136                IGUIElementSpec parent = guiElementSpecs.get(parentID);
137            if (parent != null) {
138                List<T> otherChildren = childRelations.get(parentID);
139
140                if (otherChildren == null) {
141                    otherChildren = new ArrayList<T>();
142                    childRelations.put(parentID, otherChildren);
143                }
144
145                otherChildren.add(guiElementID);
146
147                parentRelations.put(guiElementID, parentID);
148            }
149            guiElementSpecs.put(guiElementID, guiElementSpec);
150           
151            List<IGUIElementSpec> guiElementPath = new ArrayList<IGUIElementSpec>();
152
153            T currentElementID = guiElementID;
154            while (guiElementSpec != null) {
155                guiElementPath.add(0, guiElementSpec);
156                currentElementID = parentRelations.get(currentElementID);
157                guiElementSpec = guiElementSpecs.get(currentElementID);
158            }
159
160            try {
161                guiElement = guiModel.integratePath(guiElementPath, guiElementFactory);
162            }
163            catch (GUIModelException e) {
164                throw new RuntimeException("could not instantiate GUI element with id " + guiElementID, e);
165            }
166            guiElements.put(guiElementID, guiElement);
167        }
168    }
169
170    /**
171     * <p>
172     * Searches the tree for a GUI element with the specified id and returns its
173     * {@link IGUIElement} .
174     * </p>
175     *
176     * @param id
177     *            id that is looked for
178     * @return {@link IGUIElementSpec} of the GUI element with the given id if found, null otherwise
179     */
180    public IGUIElement find(T id) {
181        return guiElements.get(id);
182    }
183
184    /**
185     * <p>
186     * Removes a GUI element (defined by its id) from the tree. All children of the GUI element will be
187     * removed recursively.
188     * </p>
189     *
190     * @param id
191     *            id of the GUI element to be removed
192     * @return number of GUI elements that were removed
193     */
194    public int remove(T id) {
195        int removedCounter = 0;
196        IGUIElementSpec node = guiElementSpecs.remove(id);
197
198        if (node != null) {
199                removedCounter++;
200            List<T> nodesToBeRemoved = childRelations.remove(id);
201
202            // remove all children and sub-children, if any
203            if (nodesToBeRemoved != null) {
204                for (int i = 0; i < nodesToBeRemoved.size(); i++) {
205                    T nodeToBeRemoved = nodesToBeRemoved.get(i);
206                    List<T> children =
207                        childRelations.remove(nodeToBeRemoved);
208
209                    if (children != null) {
210                        nodesToBeRemoved.addAll(children);
211                    }
212
213                    guiElementSpecs.remove(nodeToBeRemoved);
214                    parentRelations.remove(nodeToBeRemoved);
215                    removedCounter++;
216                }
217            }
218
219            /* the node may be a child node of a parent. So search for it in the child relations
220            of the parent and remove it */
221            T parent = parentRelations.remove(id);
222            if (parent != null) {
223                List<T> children = childRelations.get(parent);
224
225                if (children != null) {
226                    for (int i = 0; i < children.size(); i++) {
227                        if (children.get(i) == id) {
228                            children.remove(i);
229                            break;
230                        }
231                    }
232
233                    if (children.size() <= 0) {
234                        childRelations.remove(parent);
235                    }
236                }
237            }
238        }
239        return removedCounter;
240    }
241
242    /**
243     * @return the guiModel
244     */
245    public GUIModel getGUIModel() {
246        return guiModel;
247    }
248
249    /**
250     * <p>
251     * Returns the number of nodes contained in the JFCComponentTree.
252     * </p>
253     *
254     * @return number of nodes
255     */
256    public int size() {
257        return guiElementSpecs.size();
258    }
259
260}
Note: See TracBrowser for help on using the repository browser.