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.function.FunctionUtils;
10 import gov.nist.secauto.metaschema.core.metapath.function.IArgument;
11 import gov.nist.secauto.metaschema.core.metapath.item.ICollectionValue;
12 import gov.nist.secauto.metaschema.core.metapath.item.ISequence;
13 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IIntegerItem;
14 import gov.nist.secauto.metaschema.core.metapath.item.function.IArrayItem;
15 import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
16 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
17
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Objects;
21 import java.util.stream.Collectors;
22
23 import edu.umd.cs.findbugs.annotations.NonNull;
24
25
26
27
28
29
30
31
32 public abstract class AbstractArrayItem<ITEM extends ICollectionValue>
33 extends ImmutableCollections.AbstractImmutableDelegatedList<ITEM>
34 implements IArrayItem<ITEM>, IFeatureCollectionFunctionItem {
35 @NonNull
36 private static final IEnhancedQName QNAME = IEnhancedQName.of("array");
37 @NonNull
38 private static final List<IArgument> ARGUMENTS = ObjectUtils.notNull(List.of(
39 IArgument.builder().name("position").type(IIntegerItem.type()).one().build()));
40
41 @NonNull
42 private static final IArrayItem<?> EMPTY = new ArrayItemN<>();
43
44
45
46
47
48
49
50
51 @SuppressWarnings("unchecked")
52 @NonNull
53 public static <T extends ICollectionValue> IArrayItem<T> empty() {
54 return (IArrayItem<T>) EMPTY;
55 }
56
57 @Override
58 public IEnhancedQName getQName() {
59 return QNAME;
60 }
61
62 @Override
63 public List<IArgument> getArguments() {
64 return ARGUMENTS;
65 }
66
67 @Override
68 public ISequence<?> execute(List<? extends ISequence<?>> arguments, DynamicContext dynamicContext,
69 ISequence<?> focus) {
70 ISequence<? extends IIntegerItem> arg = FunctionUtils.asType(
71 ObjectUtils.notNull(arguments.get(0)));
72
73 IIntegerItem position = arg.getFirstItem(true);
74 if (position == null) {
75 return ISequence.empty();
76 }
77
78 int index = position.toIntValueExact() - 1;
79 ICollectionValue result = getValue().get(index);
80 return result.toSequence();
81 }
82
83 @Override
84 public int hashCode() {
85 return Objects.hash(getValue());
86 }
87
88 @Override
89 public boolean equals(Object other) {
90 return other == this
91 || other instanceof IArrayItem && getValue().equals(((IArrayItem<?>) other).getValue());
92 }
93
94 @SuppressWarnings("PMD.OnlyOneReturn")
95 @Override
96 public boolean deepEquals(ICollectionValue other, DynamicContext dynamicContext) {
97 if (!(other instanceof IArrayItem)) {
98 return false;
99 }
100
101 IArrayItem<?> otherArray = (IArrayItem<?>) other;
102 if (size() != otherArray.size()) {
103 return false;
104 }
105
106 Iterator<? extends ICollectionValue> thisIterator = iterator();
107 Iterator<? extends ICollectionValue> otherIterator = otherArray.iterator();
108 boolean retval = true;
109 while (thisIterator.hasNext() && otherIterator.hasNext()) {
110 ICollectionValue i1 = thisIterator.next();
111 ICollectionValue i2 = otherIterator.next();
112 if (!i1.deepEquals(i2, dynamicContext)) {
113 retval = false;
114 break;
115 }
116 }
117 return retval;
118 }
119
120 @Override
121 public String toSignature() {
122 return ObjectUtils.notNull(stream()
123 .map(ICollectionValue::toSignature)
124 .collect(Collectors.joining(",", "[", "]")));
125 }
126
127 @Override
128 public String toString() {
129 return toSignature();
130 }
131 }