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