1
2
3
4
5
6 package dev.metaschema.core.metapath.item;
7
8 import dev.metaschema.core.metapath.DynamicContext;
9 import dev.metaschema.core.metapath.InvalidTreatTypeDynamicMetapathException;
10 import dev.metaschema.core.metapath.cst.path.Axis;
11 import dev.metaschema.core.metapath.item.node.IDocumentBasedNodeItem;
12 import dev.metaschema.core.metapath.item.node.IDocumentNodeItem;
13 import dev.metaschema.core.metapath.item.node.INodeItem;
14 import dev.metaschema.core.metapath.type.InvalidTypeMetapathException;
15 import dev.metaschema.core.metapath.type.TypeMetapathException;
16 import dev.metaschema.core.util.ObjectUtils;
17 import edu.umd.cs.findbugs.annotations.NonNull;
18 import edu.umd.cs.findbugs.annotations.Nullable;
19
20
21
22
23 public final class ItemUtils {
24
25 private ItemUtils() {
26
27 }
28
29
30
31
32
33
34
35
36
37
38
39
40
41 @NonNull
42 public static INodeItem checkItemIsNodeItem(
43 @NonNull DynamicContext dynamicContext,
44 @Nullable IItem item) {
45 return checkItemIsType(dynamicContext, item, INodeItem.class);
46 }
47
48
49
50
51
52
53
54
55
56
57
58
59 @NonNull
60 public static IDocumentBasedNodeItem checkItemIsDocumentNodeItem(
61 @NonNull DynamicContext dynamicContext,
62 @Nullable IItem item) {
63 return checkItemIsType(dynamicContext, item, IDocumentBasedNodeItem.class);
64 }
65
66 @NonNull
67 private static <T extends IItem> T checkItemIsType(
68 @NonNull DynamicContext dynamicContext,
69 @Nullable IItem item,
70 @NonNull Class<T> itemClass) {
71 if (itemClass.isInstance(item)) {
72 return ObjectUtils.notNull(itemClass.cast(item));
73 }
74 if (item == null) {
75 throw new TypeMetapathException(TypeMetapathException.NOT_A_NODE_ITEM_FOR_STEP, "Item is null.")
76 .registerEvaluationContext(dynamicContext);
77 }
78 throw new TypeMetapathException(
79 TypeMetapathException.NOT_A_NODE_ITEM_FOR_STEP,
80 String.format("The item of type '%s' is not of the type '%s'.",
81 item.getClass().getName(),
82 itemClass.getName()))
83 .registerEvaluationContext(dynamicContext);
84 }
85
86
87
88
89
90
91
92
93
94
95
96
97
98 @NonNull
99 public static ISequence<IDocumentBasedNodeItem> getDocumentNodeItems(
100 @NonNull DynamicContext dynamicContext,
101 @NonNull ISequence<?> items) {
102 return ISequence.of(ObjectUtils.notNull(items.stream()
103
104 .map(item -> checkItemIsNodeItem(dynamicContext, item))
105 .map(item -> Axis.ANCESTOR_OR_SELF.execute(ObjectUtils.notNull(item))
106 .findFirst().stream()
107 .filter(IDocumentBasedNodeItem.class::isInstance)
108 .map(firstItem -> checkItemIsDocumentNodeItem(dynamicContext, firstItem))
109 .findFirst().orElseThrow(() -> new InvalidTreatTypeDynamicMetapathException(
110 dynamicContext.getExecutionStack(),
111 String.format("The node '%s' is not the descendant of a document node.",
112 item.getMetapath()))))));
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 @SuppressWarnings("unchecked")
131 @NonNull
132 public static <TYPE> TYPE checkItemType(@NonNull IItem item, @NonNull Class<TYPE> clazz) {
133 if (clazz.isInstance(item)) {
134 return (TYPE) item;
135 }
136 throw new InvalidTypeMetapathException(
137 item,
138 String.format(
139 "The item of type '%s' is not the required type '%s'.",
140 item.getClass().getName(),
141 clazz.getName()));
142 }
143 }