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 @Override
65 public int size()
66 {
67 return this.wrappedCollection.size();
68 }
69
70 @Override
71 public boolean isEmpty()
72 {
73 return this.wrappedCollection.isEmpty();
74 }
75
76 @Override
77 public void clear()
78 {
79 int nr = this.wrappedCollection.size();
80 this.wrappedCollection.clear();
81 if (nr != this.wrappedCollection.size())
82 {
83 fireEvent(OBJECT_REMOVED_EVENT, this.wrappedCollection.size());
84 }
85 }
86
87 @Override
88 public boolean add(final T o)
89 {
90 boolean changed = this.wrappedCollection.add(o);
91 if (changed)
92 {
93 fireEvent(OBJECT_ADDED_EVENT, this.wrappedCollection.size());
94 }
95 else
96 {
97 fireEvent(OBJECT_CHANGED_EVENT, this.wrappedCollection.size());
98 }
99 return changed;
100 }
101
102 @Override
103 public boolean addAll(final Collection<? extends T> c)
104 {
105 boolean changed = this.wrappedCollection.addAll(c);
106 if (changed)
107 {
108 fireEvent(OBJECT_ADDED_EVENT, this.wrappedCollection.size());
109 }
110 else
111 {
112 if (!c.isEmpty())
113 {
114 fireEvent(OBJECT_CHANGED_EVENT, this.wrappedCollection.size());
115 }
116 }
117 return changed;
118 }
119
120 @Override
121 public boolean contains(final Object o)
122 {
123 return this.wrappedCollection.contains(o);
124 }
125
126 @Override
127 public boolean containsAll(final Collection<?> c)
128 {
129 return this.wrappedCollection.containsAll(c);
130 }
131
132 @Override
133 public EventProducingIterator<T> iterator()
134 {
135 EventProducingIterator<T> iterator = new EventProducingIterator<T>(this.wrappedCollection.iterator());
136
137 iterator.addListener(this, EventProducingIterator.OBJECT_REMOVED_EVENT, ReferenceType.WEAK);
138 return iterator;
139 }
140
141 @Override
142 public void notify(final Event event) throws RemoteException
143 {
144
145 if (event.getType().equals(EventProducingIterator.OBJECT_REMOVED_EVENT))
146 {
147 fireEvent(OBJECT_REMOVED_EVENT, this.wrappedCollection.size());
148 }
149 }
150
151 @Override
152 public boolean remove(final Object o)
153 {
154 boolean changed = this.wrappedCollection.remove(o);
155 if (changed)
156 {
157 fireEvent(OBJECT_REMOVED_EVENT, this.wrappedCollection.size());
158 }
159 return changed;
160 }
161
162 @Override
163 public boolean removeAll(final Collection<?> c)
164 {
165 boolean changed = this.wrappedCollection.removeAll(c);
166 if (changed)
167 {
168 fireEvent(OBJECT_REMOVED_EVENT, this.wrappedCollection.size());
169 }
170 return changed;
171 }
172
173 @Override
174 public boolean retainAll(final Collection<?> c)
175 {
176 boolean changed = this.wrappedCollection.retainAll(c);
177 if (changed)
178 {
179 fireEvent(OBJECT_REMOVED_EVENT, this.wrappedCollection.size());
180 }
181 return changed;
182 }
183
184 @Override
185 public Object[] toArray()
186 {
187 return this.wrappedCollection.toArray();
188 }
189
190 @Override
191 public <E> E[] toArray(final E[] a)
192 {
193 return this.wrappedCollection.toArray(a);
194 }
195
196 }