1
2
3
4
5
6 package gov.nist.secauto.oscal.lib.profile.resolver;
7
8 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
9
10 import java.util.Collections;
11 import java.util.LinkedHashMap;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Objects;
15 import java.util.function.Function;
16 import java.util.stream.Collectors;
17 import java.util.stream.Stream;
18
19 import edu.umd.cs.findbugs.annotations.NonNull;
20 import edu.umd.cs.findbugs.annotations.Nullable;
21
22 public final class ModifyPhaseUtils {
23 private ModifyPhaseUtils() {
24
25 }
26
27 public static <T> Function<? super T, String> identityKey() {
28 return item -> Integer.toString(Objects.hashCode(item));
29 }
30
31 public static <T, R> Function<? super T, String> identifierKey(@NonNull Function<T, R> identifierFunction) {
32 return item -> {
33 R identifier = identifierFunction.apply(item);
34 String retval;
35 if (identifier == null) {
36 retval = Integer.toString(Objects.hashCode(item));
37 } else {
38 retval = identifier.toString();
39 }
40 return retval;
41 };
42 }
43
44 @SuppressWarnings("PMD.OnlyOneReturn")
45 public static <T> T mergeItem(@Nullable T original, @Nullable T additional) {
46 if (additional == null) {
47 return original;
48 }
49
50 return additional;
51 }
52
53 @SuppressWarnings("PMD.OnlyOneReturn")
54 public static <T> List<T> merge(@Nullable List<T> original, @Nullable List<T> additional,
55 Function<? super T, String> keyFunction) {
56 if (additional == null || additional.isEmpty()) {
57 return original;
58 }
59
60 if (original == null || original.isEmpty()) {
61 return additional;
62 }
63
64
65 List<T> reversed = Stream.concat(
66 CollectionUtil.listOrEmpty(original).stream(),
67 CollectionUtil.listOrEmpty(additional).stream())
68 .collect(Collectors.collectingAndThen(
69 Collectors.toList(),
70 l -> {
71 Collections.reverse(l);
72 return l;
73 }));
74
75
76 Map<String, List<T>> identityMap = reversed.stream()
77 .collect(Collectors.groupingBy(keyFunction, LinkedHashMap::new, Collectors.toList()));
78
79
80 return identityMap.values().stream()
81 .map(list -> list.stream().findFirst().get())
82 .collect(Collectors.collectingAndThen(
83 Collectors.toList(),
84 l -> {
85 Collections.reverse(l);
86 return l;
87 }));
88 }
89 }