source: trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/HierarchicalEventTargetTree.java @ 2252

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