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