1
2
3
4
5
6 package gov.nist.secauto.metaschema.core.metapath.item;
7
8 import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItem;
9 import gov.nist.secauto.metaschema.core.metapath.type.TypeMetapathException;
10
11 import java.util.Arrays;
12 import java.util.Objects;
13 import java.util.stream.Stream;
14
15 import edu.umd.cs.findbugs.annotations.NonNull;
16 import edu.umd.cs.findbugs.annotations.Nullable;
17
18
19
20
21 public final class ItemUtils {
22
23 private ItemUtils() {
24
25 }
26
27
28
29
30
31
32
33
34
35
36
37 @NonNull
38 public static INodeItem checkItemIsNodeItemForStep(@Nullable IItem item) {
39 if (item instanceof INodeItem) {
40 return (INodeItem) item;
41 }
42 if (item == null) {
43 throw new TypeMetapathException(TypeMetapathException.NOT_A_NODE_ITEM_FOR_STEP,
44 "Item is null.");
45 }
46 throw new TypeMetapathException(TypeMetapathException.NOT_A_NODE_ITEM_FOR_STEP,
47 String.format(
48 "The item of type '%s' is not a INodeItem.",
49 item.getClass().getName()));
50 }
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 @SuppressWarnings("unchecked")
68 @NonNull
69 public static <TYPE> TYPE checkItemType(@NonNull IItem item, @NonNull Class<TYPE> clazz) {
70 if (clazz.isInstance(item)) {
71 return (TYPE) item;
72 }
73 throw new TypeMetapathException(TypeMetapathException.INVALID_TYPE_ERROR,
74 String.format(
75 "The item of type '%s' is not the required type '%s'.",
76 item.getClass().getName(),
77 clazz.getName()));
78 }
79
80 public static <T> Stream<Class<? extends T>> interfacesFor(
81 @NonNull Class<? extends T> seed,
82 @NonNull Class<T> base) {
83 return ancestorsOrSelf(seed)
84 .flatMap(clazz -> Stream.ofNullable(asSubclassOrNull(clazz, base)))
85 .flatMap(clazz -> Stream.concat(
86 Stream.of(clazz),
87 Arrays.stream(seed.getInterfaces())
88 .flatMap(cls -> Stream.ofNullable(asSubclassOrNull(cls, base)))));
89 }
90
91 private static <T> Stream<Class<? super T>> ancestorsOrSelf(@NonNull Class<T> seed) {
92 return Stream.iterate(seed, Objects::nonNull, Class::getSuperclass);
93 }
94
95 @Nullable
96 private static <T> Class<? extends T> asSubclassOrNull(Class<?> clazz, Class<T> base) {
97 Class<? extends T> retval = null;
98 try {
99 retval = clazz.asSubclass(base);
100 } catch (@SuppressWarnings("unused") ClassCastException ex) {
101
102 }
103 return retval;
104 }
105 }