1 package cz.cuni.amis.pogamut.sposh.elements;
2
3 import java.awt.datatransfer.DataFlavor;
4 import java.beans.PropertyChangeEvent;
5 import java.util.*;
6
7
8
9
10
11
12
13
14 public abstract class PoshElement<T extends PoshElement, PARENT extends PoshElement> {
15
16
17
18
19
20 private PARENT parent;
21
22
23
24 private final Set<PoshElementListener<T>> elementListeners = new HashSet<PoshElementListener<T>>();
25 private final Set<PoshElementListener<T>> elementListenersUm = Collections.unmodifiableSet(elementListeners);
26
27
28
29
30
31
32
33 public final Set<PoshElementListener<T>> getElementListeners() {
34 return elementListenersUm;
35 }
36
37
38
39
40
41
42
43
44 public final synchronized boolean addElementListener(PoshElementListener<T> listener) {
45 return elementListeners.add(listener);
46 }
47
48
49
50
51
52
53
54
55 public final synchronized boolean removeElementListener(PoshElementListener<T> listener) {
56 return elementListeners.remove(listener);
57 }
58
59
60
61
62
63
64
65
66 protected final synchronized void firePropertyChange(String name, Object o, Object n) {
67 PoshElementListener[] listeners = elementListenersUm.toArray(new PoshElementListener[0]);
68 for (PoshElementListener listener : listeners) {
69 listener.propertyChange(new PropertyChangeEvent(this, name, o, n));
70 }
71 }
72
73
74
75
76
77
78
79 public abstract DataFlavor getDataFlavor();
80
81
82
83
84
85
86 public abstract LapType getType();
87
88
89
90
91
92
93
94 public abstract List<? extends PoshElement> getChildDataNodes();
95
96
97
98
99
100
101
102 protected final synchronized void emitChildNode(PoshElement emitedChild) {
103
104 PoshElementListener<T>[] listenersArray = elementListenersUm.toArray(new PoshElementListener[]{});
105 for (PoshElementListener<T> listener : listenersArray) {
106 listener.childElementAdded((T) this, emitedChild);
107 }
108 }
109
110
111
112
113
114
115
116 protected final synchronized void emitChildMove(PoshElement childNode, int oldIndex, int newIndex) {
117 PoshElementListener[] listenersArray = elementListenersUm.toArray(new PoshElementListener[]{});
118
119 for (PoshElementListener<T> listener : listenersArray) {
120 listener.childElementMoved((T) this, childNode, oldIndex, newIndex);
121 }
122 }
123
124
125
126
127
128 protected final synchronized void emitChildDeleted(PoshElement child, int removedChildPosition) {
129 PoshElementListener[] listenersArray = elementListenersUm.toArray(new PoshElementListener[]{});
130
131 for (PoshElementListener<T> listener : listenersArray) {
132 listener.childElementRemoved((T) this, child, removedChildPosition);
133 }
134 }
135
136
137
138
139
140
141
142 protected void setParent(PARENT parent) {
143 this.parent = parent;
144 }
145
146
147
148
149
150
151 public PARENT getParent() {
152 return this.parent;
153 }
154
155
156
157
158
159
160 public final PoshPlan getRootNode() {
161 PoshElement cur = this;
162 while (cur.getParent() != null) {
163 cur = cur.getParent();
164 }
165 if (cur instanceof PoshPlan) {
166 return (PoshPlan) cur;
167 }
168 return null;
169 }
170
171
172
173
174
175
176
177 public abstract boolean moveChild(int newIndex, PoshElement child);
178
179
180
181
182
183
184
185
186
187 protected final boolean isChildOfParent() {
188 if (parent != null) {
189 return parent.getChildDataNodes().contains(this);
190 }
191 return false;
192 }
193
194
195
196
197
198
199
200
201 public final List<? extends PoshElement> getChildren(LapType selectType) {
202 List<PoshElement> selectedChildren = new LinkedList<PoshElement>();
203 for (PoshElement node : this.getChildDataNodes()) {
204 if (node.getType() == selectType) {
205 selectedChildren.add(node);
206 }
207 }
208 return selectedChildren;
209 }
210
211
212
213
214
215 public final int getChildId(PoshElement child) {
216 assert child.getParent() == this;
217 List<? extends PoshElement> sameTypeChildren = getChildren(child.getType());
218 return sameTypeChildren.indexOf(child);
219 }
220
221
222
223
224
225 public final int getId() {
226 return parent.getChildId(this);
227 }
228 }