1
2
3
4
5
6 package dev.metaschema.core.metapath.cst.items;
7
8 import java.math.BigInteger;
9 import java.util.ArrayList;
10 import java.util.List;
11
12 import dev.metaschema.core.metapath.DynamicContext;
13 import dev.metaschema.core.metapath.IExpression;
14 import dev.metaschema.core.metapath.cst.AbstractBinaryExpression;
15 import dev.metaschema.core.metapath.cst.IExpressionVisitor;
16 import dev.metaschema.core.metapath.item.ISequence;
17 import dev.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
18 import dev.metaschema.core.metapath.item.atomic.IIntegerItem;
19 import edu.umd.cs.findbugs.annotations.NonNull;
20
21
22
23
24
25
26 public class Range
27 extends AbstractBinaryExpression<IExpression, IExpression> {
28
29
30
31
32
33
34
35
36
37
38
39
40 public Range(
41 @NonNull String text,
42 @NonNull IExpression start,
43 @NonNull IExpression end) {
44 super(text, start, end);
45 }
46
47 @Override
48 public Class<IIntegerItem> getBaseResultType() {
49 return IIntegerItem.class;
50 }
51
52 @Override
53 protected ISequence<?> evaluate(DynamicContext dynamicContext, ISequence<?> focus) {
54 IAnyAtomicItem leftItem = ISequence.of(getLeft().accept(dynamicContext, focus).atomize()).getFirstItem(true);
55 IAnyAtomicItem rightItem = ISequence.of(getRight().accept(dynamicContext, focus).atomize()).getFirstItem(true);
56
57 IIntegerItem left = leftItem == null ? null : IIntegerItem.cast(leftItem);
58 IIntegerItem right = rightItem == null ? null : IIntegerItem.cast(rightItem);
59
60 ISequence<IIntegerItem> retval;
61 if (left == null || right == null || left.compareTo(right) > 0) {
62 retval = ISequence.empty();
63 } else {
64
65 BigInteger min = left.asInteger();
66 BigInteger max = right.asInteger();
67
68 List<IIntegerItem> range = new ArrayList<>(max.subtract(min).add(BigInteger.ONE).intValueExact());
69 for (BigInteger val = left.asInteger(); val.compareTo(max) <= 0; val = val.add(BigInteger.ONE)) {
70 range.add(IIntegerItem.valueOf(val));
71 }
72
73 retval = ISequence.ofCollection(range);
74 }
75 return retval;
76 }
77
78 @Override
79 public <RESULT, CONTEXT> RESULT accept(IExpressionVisitor<RESULT, CONTEXT> visitor, CONTEXT context) {
80 return visitor.visitRange(this, context);
81 }
82 }