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