1 package org.djutils.event.util;
2
3 import java.io.Serializable;
4 import java.rmi.RemoteException;
5 import java.util.Collection;
6
7 import org.djutils.event.EventInterface;
8 import org.djutils.event.EventListenerInterface;
9 import org.djutils.event.EventProducer;
10 import org.djutils.event.EventType;
11 import org.djutils.event.IdProvider;
12 import org.djutils.event.ref.ReferenceType;
13 import org.djutils.exceptions.Throw;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 public class EventProducingCollection<T> extends EventProducer implements EventListenerInterface, Collection<T>
32 {
33
34 private static final long serialVersionUID = 20191230L;
35
36
37 public static final EventType>EventType OBJECT_ADDED_EVENT = new EventType("OBJECT_ADDED_EVENT");
38
39
40 public static final EventTypeventType OBJECT_REMOVED_EVENT = new EventType("OBJECT_REMOVED_EVENT");
41
42
43 public static final EventTypeventType OBJECT_CHANGED_EVENT = new EventType("OBJECT_CHANGED_EVENT");
44
45
46 private Collection<T> parent = null;
47
48
49 private final IdProvider sourceIdProvider;
50
51
52
53
54
55
56 public EventProducingCollection(final Collection<T> parent, final Serializable sourceId)
57 {
58 this(parent, new IdProvider()
59 {
60
61 private static final long serialVersionUID = 20200119L;
62
63 @Override
64 public Serializable id()
65 {
66 return sourceId;
67 }
68 });
69 }
70
71
72
73
74
75
76
77 public EventProducingCollection(final Collection<T> parent, final IdProvider sourceIdProvider)
78 {
79 Throw.whenNull(parent, "parent cannot be null");
80 Throw.whenNull(sourceIdProvider, "sourceIdprovider cannot be null");
81 this.parent = parent;
82 this.sourceIdProvider = sourceIdProvider;
83 }
84
85
86 @Override
87 public Serializable getSourceId()
88 {
89 return this.sourceIdProvider.id();
90 }
91
92
93 @Override
94 public int size()
95 {
96 return this.parent.size();
97 }
98
99
100 @Override
101 public boolean isEmpty()
102 {
103 return this.parent.isEmpty();
104 }
105
106
107 @Override
108 public void clear()
109 {
110 int nr = this.parent.size();
111 this.parent.clear();
112 if (nr != this.parent.size())
113 {
114 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
115 }
116 }
117
118
119 @Override
120 public boolean add(final T o)
121 {
122 boolean changed = this.parent.add(o);
123 if (changed)
124 {
125 this.fireEvent(OBJECT_ADDED_EVENT, this.parent.size());
126 }
127 else
128 {
129 this.fireEvent(OBJECT_CHANGED_EVENT, this.parent.size());
130 }
131 return changed;
132 }
133
134
135 @Override
136 public boolean addAll(final Collection<? extends T> c)
137 {
138 boolean changed = this.parent.addAll(c);
139 if (changed)
140 {
141 this.fireEvent(OBJECT_ADDED_EVENT, this.parent.size());
142 }
143 else
144 {
145 if (!c.isEmpty())
146 {
147 this.fireEvent(OBJECT_CHANGED_EVENT, this.parent.size());
148 }
149 }
150 return changed;
151 }
152
153
154 @Override
155 public boolean contains(final Object o)
156 {
157 return this.parent.contains(o);
158 }
159
160
161 @Override
162 public boolean containsAll(final Collection<?> c)
163 {
164 return this.parent.containsAll(c);
165 }
166
167
168 @Override
169 public EventProducingIterator<T> iterator()
170 {
171 EventProducingIterator<T> iterator = new EventProducingIterator<T>(this.parent.iterator(), this.sourceIdProvider);
172
173 iterator.addListener(this, EventProducingIterator.OBJECT_REMOVED_EVENT, ReferenceType.WEAK);
174 return iterator;
175 }
176
177
178 @Override
179 public void notify(final EventInterface event) throws RemoteException
180 {
181
182 if (event.getType().equals(EventProducingIterator.OBJECT_REMOVED_EVENT))
183 {
184 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
185 }
186 }
187
188
189 @Override
190 public boolean remove(final Object o)
191 {
192 boolean changed = this.parent.remove(o);
193 if (changed)
194 {
195 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
196 }
197 return changed;
198 }
199
200
201 @Override
202 public boolean removeAll(final Collection<?> c)
203 {
204 boolean changed = this.parent.removeAll(c);
205 if (changed)
206 {
207 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
208 }
209 return changed;
210 }
211
212
213 @Override
214 public boolean retainAll(final Collection<?> c)
215 {
216 boolean changed = this.parent.retainAll(c);
217 if (changed)
218 {
219 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
220 }
221 return changed;
222 }
223
224
225 @Override
226 public Object[] toArray()
227 {
228 return this.parent.toArray();
229 }
230
231
232 @Override
233 public <E> E[] toArray(final E[] a)
234 {
235 return this.parent.toArray(a);
236 }
237 }