1 package org.djutils.event.util;
2
3 import java.io.Serializable;
4 import java.rmi.RemoteException;
5 import java.util.Collection;
6 import java.util.List;
7
8 import org.djutils.event.EventInterface;
9 import org.djutils.event.EventListenerInterface;
10 import org.djutils.event.EventProducer;
11 import org.djutils.event.EventType;
12 import org.djutils.event.IdProvider;
13 import org.djutils.event.ref.ReferenceType;
14 import org.djutils.exceptions.Throw;
15 import org.djutils.metadata.MetaData;
16 import org.djutils.metadata.ObjectDescriptor;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 public class EventProducingList<E> extends EventProducer implements EventListenerInterface, List<E>
35 {
36
37 private static final long serialVersionUID = 20191230L;
38
39
40 public static final EventType OBJECT_ADDED_EVENT =
41 new EventType("OBJECT_ADDED_EVENT", new MetaData("Size of the list after add", "Size of the list",
42 new ObjectDescriptor("Size of the list after add", "Size of the list", Integer.class)));
43
44
45 public static final EventType OBJECT_REMOVED_EVENT =
46 new EventType("OBJECT_REMOVED_EVENT", new MetaData("Size of the list after remove", "Size of the list",
47 new ObjectDescriptor("Size of the list after remove", "Size of the list", Integer.class)));
48
49
50 public static final EventType OBJECT_CHANGED_EVENT =
51 new EventType("OBJECT_CHANGED_EVENT", new MetaData("Size of the list after change", "Size of the list",
52 new ObjectDescriptor("Size of the list after change", "Size of the list", Integer.class)));
53
54
55 private List<E> parent = null;
56
57
58 private final IdProvider sourceIdProvider;
59
60
61
62
63
64
65 public EventProducingList(final List<E> parent, final Serializable sourceId)
66 {
67 this(parent, new IdProvider()
68 {
69
70 private static final long serialVersionUID = 20200119L;
71
72 @Override
73 public Serializable id()
74 {
75 return sourceId;
76 }
77 });
78 }
79
80
81
82
83
84
85
86 public EventProducingList(final List<E> parent, final IdProvider sourceIdProvider)
87 {
88 Throw.whenNull(parent, "parent cannot be null");
89 Throw.whenNull(sourceIdProvider, "sourceIdprovider cannot be null");
90 this.parent = parent;
91 this.sourceIdProvider = sourceIdProvider;
92 }
93
94
95 @Override
96 public Serializable getSourceId()
97 {
98 return this.sourceIdProvider.id();
99 }
100
101
102 @Override
103 public int size()
104 {
105 return this.parent.size();
106 }
107
108
109 @Override
110 public boolean isEmpty()
111 {
112 return this.parent.isEmpty();
113 }
114
115
116 @Override
117 public void clear()
118 {
119 int nr = this.parent.size();
120 this.parent.clear();
121 if (nr != this.parent.size())
122 {
123 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
124 }
125 }
126
127
128 @Override
129 public void add(final int index, final E element)
130 {
131 this.parent.add(index, element);
132 this.fireEvent(OBJECT_ADDED_EVENT, this.parent.size());
133 }
134
135
136 @Override
137 public boolean add(final E o)
138 {
139 boolean result = this.parent.add(o);
140 if (result)
141 {
142 this.fireEvent(OBJECT_ADDED_EVENT, this.parent.size());
143 }
144 return result;
145 }
146
147
148 @Override
149 public boolean addAll(final Collection<? extends E> c)
150 {
151 boolean result = this.parent.addAll(c);
152 if (result)
153 {
154 this.fireEvent(OBJECT_ADDED_EVENT, this.parent.size());
155 }
156 return result;
157 }
158
159
160 @Override
161 public boolean addAll(final int index, final Collection<? extends E> c)
162 {
163 boolean result = this.parent.addAll(index, c);
164 if (result)
165 {
166 this.fireEvent(OBJECT_ADDED_EVENT, this.parent.size());
167 }
168 return result;
169 }
170
171
172 @Override
173 public boolean contains(final Object o)
174 {
175 return this.parent.contains(o);
176 }
177
178
179 @Override
180 public boolean containsAll(final Collection<?> c)
181 {
182 return this.parent.containsAll(c);
183 }
184
185
186 @Override
187 public E get(final int index)
188 {
189 return this.parent.get(index);
190 }
191
192
193 @Override
194 public int indexOf(final Object o)
195 {
196 return this.parent.indexOf(o);
197 }
198
199
200 @Override
201 public EventProducingIterator<E> iterator()
202 {
203 EventProducingIterator<E> iterator = new EventProducingIterator<E>(this.parent.iterator(), this.sourceIdProvider);
204
205 iterator.addListener(this, EventProducingIterator.OBJECT_REMOVED_EVENT, ReferenceType.WEAK);
206 return iterator;
207 }
208
209
210 @Override
211 public EventProducingListIterator<E> listIterator()
212 {
213 return listIterator(0);
214 }
215
216
217 @Override
218 public EventProducingListIterator<E> listIterator(final int index)
219 {
220 EventProducingListIterator<E> iterator =
221 new EventProducingListIterator<E>(this.parent.listIterator(index), this.sourceIdProvider);
222
223 iterator.addListener(this, EventProducingIterator.OBJECT_REMOVED_EVENT, ReferenceType.WEAK);
224 iterator.addListener(this, EventProducingListIterator.OBJECT_ADDED_EVENT, ReferenceType.WEAK);
225 iterator.addListener(this, EventProducingListIterator.OBJECT_CHANGED_EVENT, ReferenceType.WEAK);
226 return iterator;
227 }
228
229
230 @Override
231 public void notify(final EventInterface event) throws RemoteException
232 {
233
234 if (event.getType().equals(EventProducingIterator.OBJECT_REMOVED_EVENT))
235 {
236 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
237 }
238 else if (event.getType().equals(EventProducingListIterator.OBJECT_ADDED_EVENT))
239 {
240 this.fireEvent(OBJECT_ADDED_EVENT, this.parent.size());
241 }
242 else if (event.getType().equals(EventProducingListIterator.OBJECT_CHANGED_EVENT))
243 {
244 this.fireEvent(OBJECT_CHANGED_EVENT, this.parent.size());
245 }
246 }
247
248
249 @Override
250 public int lastIndexOf(final Object o)
251 {
252 return this.parent.lastIndexOf(o);
253 }
254
255
256 @Override
257 public E remove(final int index)
258 {
259 E result = this.parent.remove(index);
260 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
261 return result;
262 }
263
264
265 @Override
266 public boolean remove(final Object o)
267 {
268 boolean result = this.parent.remove(o);
269 if (result)
270 {
271 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
272 }
273 return result;
274 }
275
276
277 @Override
278 public boolean removeAll(final Collection<?> c)
279 {
280 boolean result = this.parent.removeAll(c);
281 if (result)
282 {
283 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
284 }
285 return result;
286 }
287
288
289 @Override
290 public boolean retainAll(final Collection<?> c)
291 {
292 boolean result = this.parent.retainAll(c);
293 if (result)
294 {
295 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
296 }
297 return result;
298 }
299
300
301 @Override
302 public E set(final int index, final E element)
303 {
304 E result = this.parent.set(index, element);
305 this.fireEvent(OBJECT_CHANGED_EVENT, this.parent.size());
306 return result;
307 }
308
309
310 @Override
311 public List<E> subList(final int fromIndex, final int toIndex)
312 {
313 return this.parent.subList(fromIndex, toIndex);
314 }
315
316
317 @Override
318 public Object[] toArray()
319 {
320 return this.parent.toArray();
321 }
322
323
324 @Override
325 public <T> T[] toArray(final T[] a)
326 {
327 return this.parent.toArray(a);
328 }
329 }