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.Set;
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 EventProducingSet<E> extends EventProducer implements EventListenerInterface, Set<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 set after add", "Size of the set",
42 new ObjectDescriptor("Size of the set after add", "Size of the set", Integer.class)));
43
44
45 public static final EventType OBJECT_REMOVED_EVENT =
46 new EventType("OBJECT_REMOVED_EVENT", new MetaData("Size of the set after remove", "Size of the set",
47 new ObjectDescriptor("Size of the set after remove", "Size of the set", Integer.class)));
48
49
50 public static final EventType OBJECT_CHANGED_EVENT =
51 new EventType("OBJECT_CHANGED_EVENT", new MetaData("Size of the set after change", "Size of the set",
52 new ObjectDescriptor("Size of the set after change", "Size of the set", Integer.class)));
53
54
55 private Set<E> parent = null;
56
57
58 private final IdProvider sourceIdProvider;
59
60
61
62
63
64
65 public EventProducingSet(final Set<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 EventProducingSet(final Set<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 boolean add(final E o)
130 {
131 boolean changed = this.parent.add(o);
132 if (changed)
133 {
134 this.fireEvent(OBJECT_ADDED_EVENT, this.parent.size());
135 }
136 else
137 {
138 this.fireEvent(OBJECT_CHANGED_EVENT, this.parent.size());
139 }
140 return changed;
141 }
142
143
144 @Override
145 public boolean addAll(final Collection<? extends E> c)
146 {
147 boolean changed = this.parent.addAll(c);
148 if (changed)
149 {
150 this.fireEvent(OBJECT_ADDED_EVENT, this.parent.size());
151 }
152 else
153 {
154 if (!c.isEmpty())
155 {
156 this.fireEvent(OBJECT_CHANGED_EVENT, this.parent.size());
157 }
158 }
159 return changed;
160 }
161
162
163 @Override
164 public boolean contains(final Object o)
165 {
166 return this.parent.contains(o);
167 }
168
169
170 @Override
171 public boolean containsAll(final Collection<?> c)
172 {
173 return this.parent.containsAll(c);
174 }
175
176
177 @Override
178 public EventProducingIterator<E> iterator()
179 {
180 EventProducingIterator<E> iterator = new EventProducingIterator<E>(this.parent.iterator(), this.sourceIdProvider);
181
182 iterator.addListener(this, EventProducingIterator.OBJECT_REMOVED_EVENT, ReferenceType.WEAK);
183 return iterator;
184 }
185
186
187 @Override
188 public void notify(final EventInterface event) throws RemoteException
189 {
190
191 if (event.getType().equals(EventProducingIterator.OBJECT_REMOVED_EVENT))
192 {
193 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
194 }
195 }
196
197
198 @Override
199 public boolean remove(final Object o)
200 {
201 boolean changed = this.parent.remove(o);
202 if (changed)
203 {
204 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
205 }
206 return changed;
207 }
208
209
210 @Override
211 public boolean removeAll(final Collection<?> c)
212 {
213 boolean changed = this.parent.removeAll(c);
214 if (changed)
215 {
216 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
217 }
218 return changed;
219 }
220
221
222 @Override
223 public boolean retainAll(final Collection<?> c)
224 {
225 boolean changed = this.parent.retainAll(c);
226 if (changed)
227 {
228 this.fireEvent(OBJECT_REMOVED_EVENT, this.parent.size());
229 }
230 return changed;
231 }
232
233
234 @Override
235 public Object[] toArray()
236 {
237 return this.parent.toArray();
238 }
239
240
241 @Override
242 public <T> T[] toArray(final T[] a)
243 {
244 return this.parent.toArray(a);
245 }
246 }