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