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