1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat.license;
20
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.Optional;
25 import java.util.Set;
26 import java.util.SortedSet;
27 import java.util.TreeSet;
28 import java.util.function.Predicate;
29 import java.util.stream.Collectors;
30
31 import org.apache.commons.collections4.set.UnmodifiableSortedSet;
32 import org.apache.rat.ConfigurationException;
33 import org.apache.rat.analysis.IHeaderMatcher;
34 import org.apache.rat.analysis.IHeaders;
35 import org.apache.rat.utils.DefaultLog;
36 import org.apache.rat.utils.Log;
37 import org.apache.rat.utils.ReportingSet;
38
39
40
41
42
43 public class LicenseSetFactory {
44
45
46
47
48
49
50
51 public static ILicenseFamily familySearch(final String target, final SortedSet<ILicenseFamily> licenseFamilies) {
52 ILicenseFamily family = ILicenseFamily.builder().setLicenseFamilyCategory(target).setLicenseFamilyName("Searching family")
53 .build();
54 return familySearch(family, licenseFamilies);
55 }
56
57
58
59
60
61
62
63 public static ILicenseFamily familySearch(final ILicenseFamily target, final SortedSet<ILicenseFamily> licenseFamilies) {
64 SortedSet<ILicenseFamily> part = licenseFamilies.tailSet(target);
65 return (!part.isEmpty() && part.first().compareTo(target) == 0) ? part.first() : null;
66 }
67
68
69
70
71 public enum LicenseFilter {
72
73 ALL,
74
75 APPROVED,
76
77 NONE
78 }
79
80
81 private final ReportingSet<ILicenseFamily> families;
82
83 private final ReportingSet<ILicense> licenses;
84
85
86 private final SortedSet<String> approvedLicenseCategories;
87
88
89
90
91 private final SortedSet<String> removedLicenseCategories;
92
93
94
95
96 private final SortedSet<String> approvedLicenseIds;
97
98
99
100
101 private final SortedSet<String> removedLicenseIds;
102
103
104
105
106
107 public LicenseSetFactory() {
108 families = new ReportingSet<>(new TreeSet<ILicenseFamily>())
109 .setMsgFormat(s -> String.format("Duplicate LicenseFamily category: %s", s.getFamilyCategory()));
110 licenses = new ReportingSet<>(new TreeSet<ILicense>())
111 .setMsgFormat(s -> String.format("Duplicate License %s (%s) of type %s", s.getName(), s.getId(), s.getLicenseFamily().getFamilyCategory()));
112
113 approvedLicenseCategories = new TreeSet<>();
114 removedLicenseCategories = new TreeSet<>();
115 approvedLicenseIds = new TreeSet<>();
116 removedLicenseIds = new TreeSet<>();
117 }
118
119
120
121
122
123
124 public LicenseSetFactory(final SortedSet<ILicense> licenses) {
125 this();
126 this.licenses.addAll(licenses);
127 licenses.forEach(l -> families.addIfNotPresent(l.getLicenseFamily()));
128 }
129
130 public void validate() {
131 Log log = DefaultLog.getInstance();
132
133
134 if (getLicenses(LicenseFilter.ALL).isEmpty()) {
135 String msg = "At least one license must be defined";
136 log.error(msg);
137 throw new ConfigurationException(msg);
138 }
139
140
141 Set<String> exists = getLicenseFamilies(LicenseFilter.ALL)
142 .stream().map(ILicenseFamily::getFamilyCategory).collect(Collectors.toSet());
143 Set<String> approved = new HashSet<>(approvedLicenseCategories);
144 approved.removeIf(exists::contains);
145 approved.forEach(name -> log.warn(String.format("License category '%s' was approved but does not exist.", name)));
146
147
148 exists = getLicenses(LicenseFilter.ALL)
149 .stream().map(ILicense::getId).collect(Collectors.toSet());
150 approved = new HashSet<>(approvedLicenseIds);
151 approved.removeIf(exists::contains);
152 approved.forEach(name -> log.warn(String.format("License '%s' was approved but does not exist.", name)));
153 }
154
155 public void add(final LicenseSetFactory other) {
156 this.families.addAll(other.families);
157 this.licenses.addAll(other.licenses);
158 this.approvedLicenseCategories.addAll(other.approvedLicenseCategories);
159 this.removedLicenseCategories.addAll(other.removedLicenseCategories);
160 this.approvedLicenseIds.addAll(other.approvedLicenseIds);
161 this.removedLicenseIds.addAll(other.removedLicenseIds);
162 }
163
164
165
166
167
168
169 public void logFamilyCollisions(final Log.Level level) {
170 families.setLogLevel(level);
171 }
172
173
174
175
176
177 public void familyDuplicateOption(final ReportingSet.Options state) {
178 families.setDuplicateOption(state);
179 }
180
181
182
183
184
185 public void logLicenseCollisions(final Log.Level level) {
186 licenses.setLogLevel(level);
187 }
188
189
190
191
192
193 public void licenseDuplicateOption(final ReportingSet.Options state) {
194 licenses.setDuplicateOption(state);
195 }
196
197
198
199
200
201
202 private static SortedSet<ILicenseFamily> extractFamily(final Collection<ILicense> licenses) {
203 SortedSet<ILicenseFamily> result = new TreeSet<>();
204 licenses.stream().map(ILicense::getLicenseFamily).forEach(result::add);
205 return result;
206 }
207
208
209
210
211
212
213 public void addLicense(final ILicense license) {
214 if (license != null) {
215 this.licenses.add(license);
216 this.families.addIfNotPresent(license.getLicenseFamily());
217 }
218 }
219
220
221
222
223
224
225
226 public ILicense addLicense(final ILicense.Builder builder) {
227 if (builder != null) {
228 ILicense license = builder.setLicenseFamilies(families).build();
229 this.licenses.add(license);
230 return license;
231 }
232 return null;
233 }
234
235
236
237
238
239
240 public void addLicenses(final Collection<ILicense> licenses) {
241 this.licenses.addAll(licenses);
242 licenses.stream().map(ILicense::getLicenseFamily).forEach(families::add);
243 }
244
245
246
247
248
249
250 public void addFamily(final ILicenseFamily family) {
251 if (family != null) {
252 this.families.add(family);
253 }
254 }
255
256
257
258
259
260
261
262 public void addFamily(final ILicenseFamily.Builder builder) {
263 if (builder != null) {
264 this.families.add(builder.build());
265 }
266 }
267
268
269
270
271
272 public void approveLicenseCategory(final String familyCategory) {
273 approvedLicenseCategories.add(ILicenseFamily.makeCategory(familyCategory));
274 }
275
276
277
278
279
280 public void removeLicenseCategory(final String familyCategory) {
281 removedLicenseCategories.add(ILicenseFamily.makeCategory(familyCategory));
282 }
283
284
285
286
287
288 public void approveLicenseId(final String licenseId) {
289 approvedLicenseIds.add(licenseId);
290 }
291
292
293
294
295
296 public void removeLicenseId(final String licenseId) {
297 removedLicenseIds.add(licenseId);
298 }
299
300
301
302
303
304
305 private boolean isApprovedCategory(final ILicenseFamily family) {
306 return approvedLicenseCategories.contains(family.getFamilyCategory()) && !removedLicenseCategories.contains(family.getFamilyCategory());
307 }
308
309
310
311
312
313 public Predicate<ILicense> getApprovedLicensePredicate() {
314 return lic -> !removedLicenseIds.contains(lic.getId()) && (approvedLicenseIds.contains(lic.getId()) ||
315 isApprovedCategory(lic.getLicenseFamily()));
316 }
317
318
319
320
321
322
323 public UnmodifiableSortedSet<ILicense> getLicenses(final LicenseFilter filter) {
324 SortedSet<ILicense> result;
325 switch (filter) {
326 case ALL:
327 result = licenses;
328 break;
329 case APPROVED:
330 result = new TreeSet<>();
331 licenses.stream().filter(getApprovedLicensePredicate()).forEach(result::add);
332 break;
333 case NONE:
334 default:
335 result = Collections.emptySortedSet();
336 }
337 return (UnmodifiableSortedSet<ILicense>) UnmodifiableSortedSet.unmodifiableSortedSet(result);
338 }
339
340
341
342
343
344
345 public SortedSet<ILicenseFamily> getLicenseFamilies(final LicenseFilter filter) {
346 SortedSet<ILicenseFamily> result;
347 switch (filter) {
348 case ALL:
349 result = extractFamily(licenses);
350 result.addAll(families);
351 return result;
352 case APPROVED:
353 result = new TreeSet<>();
354 licenses.stream().map(ILicense::getLicenseFamily).filter(this::isApprovedCategory).forEach(result::add);
355 return result;
356 case NONE:
357 default:
358 return Collections.emptySortedSet();
359 }
360 }
361
362
363
364
365
366
367
368 public SortedSet<String> getLicenseCategories(final LicenseFilter filter) {
369 SortedSet<String> result = new TreeSet<>();
370 switch (filter) {
371 case ALL:
372 licenses.forEach(l -> result.add(l.getLicenseFamily().getFamilyCategory()));
373 families.forEach(f -> result.add(f.getFamilyCategory()));
374 result.addAll(approvedLicenseCategories);
375 result.addAll(removedLicenseCategories);
376 return result;
377 case APPROVED:
378 approvedLicenseCategories.stream().filter(s -> !removedLicenseCategories.contains(s)).forEach(result::add);
379 families.stream().filter(this::isApprovedCategory).forEach(f -> result.add(f.getFamilyCategory()));
380 return result;
381 case NONE:
382 default:
383 return Collections.emptySortedSet();
384 }
385 }
386
387
388
389
390
391
392
393 public SortedSet<String> getLicenseIds(final LicenseFilter filter) {
394 Predicate<ILicense> approved = l -> (isApprovedCategory(l.getLicenseFamily()) ||
395 approvedLicenseIds.contains(l.getId())) && !removedLicenseIds.contains(l.getId());
396 SortedSet<String> result = new TreeSet<>();
397 switch (filter) {
398 case ALL:
399 licenses.forEach(l -> result.add(l.getId()));
400 result.addAll(approvedLicenseCategories);
401 result.addAll(removedLicenseCategories);
402 result.addAll(approvedLicenseIds);
403 result.addAll(removedLicenseIds);
404 return result;
405 case APPROVED:
406 licenses.stream().filter(approved).forEach(l -> result.add(l.getId()));
407 families.stream().filter(this::isApprovedCategory).forEach(f -> result.add(f.getFamilyCategory()));
408 approvedLicenseIds.stream().filter(s -> !removedLicenseIds.contains(s)).forEach(result::add);
409 return result;
410 case NONE:
411 default:
412 return Collections.emptySortedSet();
413 }
414 }
415
416
417
418
419
420
421
422
423 public static Optional<ILicense> search(final String familyId, final String licenseId, final SortedSet<ILicense> licenses) {
424 ILicenseFamily searchFamily = ILicenseFamily.builder().setLicenseFamilyCategory(familyId)
425 .setLicenseFamilyName("searching proxy").build();
426 ILicense target = new ILicense() {
427 @Override
428 public String getId() {
429 return licenseId;
430 }
431
432 @Override
433 public void reset() {
434
435 }
436
437 @Override
438 public boolean matches(final IHeaders headers) {
439 return false;
440 }
441
442 @Override
443 public boolean equals(final Object o) {
444 return ILicense.equals(this, o);
445 }
446
447 @Override
448 public int hashCode() {
449 return ILicense.hash(this);
450 }
451
452 @Override
453 public ILicenseFamily getLicenseFamily() {
454 return searchFamily;
455 }
456
457 @Override
458 public String getNote() {
459 return null;
460 }
461
462 @Override
463 public String getName() {
464 return searchFamily.getFamilyName();
465 }
466
467 @Override
468 public IHeaderMatcher getMatcher() {
469 return null;
470 }
471
472 };
473 return search(target, licenses);
474 }
475
476
477
478
479
480
481
482
483
484 public static Optional<ILicense> search(final ILicense target, final SortedSet<ILicense> licenses) {
485 if (licenses == null) {
486 return Optional.empty();
487 }
488 SortedSet<ILicense> part = licenses.tailSet(target);
489 return Optional.ofNullable((!part.isEmpty() && part.first().compareTo(target) == 0) ? part.first() : null);
490 }
491 }