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