1
2
3
4
5
6 package gov.nist.secauto.metaschema.core.metapath.impl;
7
8 import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
9 import gov.nist.secauto.metaschema.core.metapath.ICollectionValue;
10 import gov.nist.secauto.metaschema.core.metapath.ISequence;
11 import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils;
12 import gov.nist.secauto.metaschema.core.metapath.function.IArgument;
13 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
14 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IIntegerItem;
15 import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayItem;
16 import gov.nist.secauto.metaschema.core.metapath.type.ISequenceType;
17 import gov.nist.secauto.metaschema.core.metapath.type.Occurrence;
18 import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
19 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
20
21 import java.util.EnumSet;
22 import java.util.List;
23 import java.util.Objects;
24 import java.util.Set;
25 import java.util.stream.Collectors;
26
27 import edu.umd.cs.findbugs.annotations.NonNull;
28
29
30
31
32
33
34
35
36 public abstract class AbstractArrayItem<ITEM extends ICollectionValue>
37 extends ImmutableCollections.AbstractImmutableDelegatedList<ITEM>
38 implements IArrayItem<ITEM> {
39 @NonNull
40 private static final IEnhancedQName QNAME = IEnhancedQName.of("array");
41 @NonNull
42 private static final Set<FunctionProperty> PROPERTIES = ObjectUtils.notNull(
43 EnumSet.of(FunctionProperty.DETERMINISTIC));
44 @NonNull
45 private static final List<IArgument> ARGUMENTS = ObjectUtils.notNull(List.of(
46 IArgument.builder().name("position").type(IIntegerItem.type()).one().build()));
47 @NonNull
48 private static final ISequenceType RESULT = ISequenceType.of(
49 IAnyAtomicItem.type(), Occurrence.ZERO_OR_ONE);
50
51 @NonNull
52 private static final IArrayItem<?> EMPTY = new ArrayItemN<>();
53
54
55
56
57
58
59
60
61 @SuppressWarnings("unchecked")
62 @NonNull
63 public static <T extends ICollectionValue> IArrayItem<T> empty() {
64 return (IArrayItem<T>) EMPTY;
65 }
66
67 @Override
68 public boolean isDeterministic() {
69 return true;
70 }
71
72 @Override
73 public boolean isContextDepenent() {
74 return false;
75 }
76
77 @Override
78 public boolean isFocusDepenent() {
79 return false;
80 }
81
82 @Override
83 public IEnhancedQName getQName() {
84 return QNAME;
85 }
86
87 @Override
88 public Set<FunctionProperty> getProperties() {
89 return PROPERTIES;
90 }
91
92 @Override
93 public List<IArgument> getArguments() {
94 return ARGUMENTS;
95 }
96
97 @Override
98 public int arity() {
99 return 1;
100 }
101
102 @Override
103 public boolean isArityUnbounded() {
104 return false;
105 }
106
107 @Override
108 public ISequenceType getResult() {
109 return RESULT;
110 }
111
112 @Override
113 public ISequence<?> execute(List<? extends ISequence<?>> arguments, DynamicContext dynamicContext,
114 ISequence<?> focus) {
115 ISequence<? extends IIntegerItem> arg = FunctionUtils.asType(
116 ObjectUtils.notNull(arguments.get(0)));
117
118 IIntegerItem position = arg.getFirstItem(true);
119 if (position == null) {
120 return ISequence.empty();
121 }
122
123 int index = position.asInteger().intValueExact() - 1;
124 ICollectionValue result = getValue().get(index);
125 return result.toSequence();
126 }
127
128 @Override
129 public int hashCode() {
130 return Objects.hash(getValue());
131 }
132
133 @Override
134 public boolean equals(Object other) {
135 return other == this
136 || other instanceof IArrayItem && getValue().equals(((IArrayItem<?>) other).getValue());
137 }
138
139 @Override
140 public String toSignature() {
141 return ObjectUtils.notNull(stream()
142 .map(ICollectionValue::toSignature)
143 .collect(Collectors.joining(",", "[", "]")));
144 }
145
146 @Override
147 public String toString() {
148 return toSignature();
149 }
150 }