1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat.utils;
20
21 import java.util.Collection;
22 import java.util.Comparator;
23 import java.util.Iterator;
24 import java.util.SortedSet;
25 import java.util.Spliterator;
26 import java.util.function.Consumer;
27 import java.util.function.Function;
28 import java.util.function.Predicate;
29 import java.util.stream.Stream;
30
31
32
33
34
35 public class ReportingSet<T> implements SortedSet<T> {
36
37 private final SortedSet<T> delegate;
38
39 private Options duplicateOption = Options.IGNORE;
40
41 private Log.Level duplicateLogLevel = Log.Level.WARN;
42
43 private Function<T, String> duplicateFmt = t -> String.format("Duplicate %s detected %s", t.getClass(), t);
44
45 public enum Options { OVERWRITE, IGNORE, FAIL }
46
47
48
49
50
51 public ReportingSet(final SortedSet<T> delegate) {
52 this.delegate = delegate;
53 }
54
55
56
57
58
59
60 public ReportingSet<T> setMsgFormat(final Function<T, String> msgFmt) {
61 duplicateFmt = msgFmt;
62 return this;
63 }
64
65
66
67
68
69
70
71 public ReportingSet<T> setDuplicateOption(final Options state) {
72 this.duplicateOption = state;
73 return this;
74 }
75
76
77
78
79
80
81
82 public ReportingSet<T> setLogLevel(final Log.Level level) {
83 this.duplicateLogLevel = level;
84 return this;
85 }
86
87 private ReportingSet<T> sameConfig(final SortedSet<T> delegate) {
88 ReportingSet<T> result = delegate instanceof ReportingSet ? (ReportingSet<T>) delegate : new ReportingSet<>(delegate);
89 return result.setDuplicateOption(this.duplicateOption).setLogLevel(this.duplicateLogLevel);
90 }
91
92
93
94
95
96
97 public boolean addIfNotPresent(final T e) {
98 return add(false, e);
99 }
100
101 @Override
102 public boolean add(final T e) {
103 return add(true, e);
104 }
105
106
107
108
109
110
111
112 private boolean add(final boolean reportDup, final T e) {
113 if (delegate.contains(e)) {
114 String msg = String.format("%s", ReportingSet.this.duplicateFmt.apply(e));
115 if (reportDup) {
116 msg = String.format("%s (action: %s)", msg, duplicateOption);
117 DefaultLog.getInstance().log(duplicateLogLevel, msg);
118 }
119 switch (duplicateOption) {
120 case FAIL:
121 throw new IllegalArgumentException(msg);
122 case IGNORE:
123 return false;
124 case OVERWRITE:
125 delegate.remove(e);
126 return delegate.add(e);
127 }
128 }
129 return delegate.add(e);
130 }
131
132 @Override
133 public boolean addAll(final Collection<? extends T> c) {
134 boolean updated = false;
135 for (T e : c) {
136 updated |= add(e);
137 }
138 return updated;
139 }
140
141 public boolean addAllIfNotPresent(final Collection<? extends T> c) {
142 boolean updated = false;
143 for (T e : c) {
144 updated |= addIfNotPresent(e);
145 }
146 return updated;
147 }
148
149 @Override
150 public void clear() {
151 delegate.clear();
152 }
153
154 @Override
155 public Comparator<? super T> comparator() {
156 return delegate.comparator();
157 }
158
159 @Override
160 public boolean contains(final Object o) {
161 return delegate.contains(o);
162 }
163
164 @Override
165 public boolean containsAll(final Collection<?> c) {
166 return delegate.containsAll(c);
167 }
168
169 @Override
170 public boolean equals(final Object o) {
171 return delegate.equals(o);
172 }
173
174 @Override
175 public T first() {
176 return delegate.first();
177 }
178
179 @Override
180 public void forEach(final Consumer<? super T> action) {
181 delegate.forEach(action);
182 }
183
184 @Override
185 public int hashCode() {
186 return delegate.hashCode();
187 }
188
189 @Override
190 public ReportingSet<T> headSet(final T toElement) {
191 return sameConfig(delegate.headSet(toElement));
192 }
193
194 @Override
195 public boolean isEmpty() {
196 return delegate.isEmpty();
197 }
198
199 @Override
200 public Iterator<T> iterator() {
201 return delegate.iterator();
202 }
203
204 @Override
205 public T last() {
206 return delegate.last();
207 }
208
209 @Override
210 public Stream<T> parallelStream() {
211 return delegate.parallelStream();
212 }
213
214 @Override
215 public boolean remove(final Object o) {
216 return delegate.remove(o);
217 }
218
219 @Override
220 public boolean removeAll(final Collection<?> c) {
221 return delegate.removeAll(c);
222 }
223
224 @Override
225 public boolean removeIf(final Predicate<? super T> filter) {
226 return delegate.removeIf(filter);
227 }
228
229 @Override
230 public boolean retainAll(final Collection<?> c) {
231 return delegate.retainAll(c);
232 }
233
234 @Override
235 public int size() {
236 return delegate.size();
237 }
238
239 @Override
240 public Spliterator<T> spliterator() {
241 return delegate.spliterator();
242 }
243
244 @Override
245 public Stream<T> stream() {
246 return delegate.stream();
247 }
248
249 @Override
250 public ReportingSet<T> subSet(final T fromElement, final T toElement) {
251 return sameConfig(delegate.subSet(fromElement, toElement));
252 }
253
254 @Override
255 public ReportingSet<T> tailSet(final T fromElement) {
256 return sameConfig(delegate.tailSet(fromElement));
257 }
258
259 @Override
260 public Object[] toArray() {
261 return delegate.toArray();
262 }
263
264 @Override
265 public <T> T[] toArray(final T[] a) {
266 return delegate.toArray(a);
267 }
268 }