Range.java
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/
package gov.nist.secauto.metaschema.core.metapath.cst;
import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
import gov.nist.secauto.metaschema.core.metapath.ISequence;
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
import gov.nist.secauto.metaschema.core.metapath.item.atomic.IIntegerItem;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import edu.umd.cs.findbugs.annotations.NonNull;
/**
* The CST node for a Metapath
* <a href="https://www.w3.org/TR/xpath-31/#doc-xpath31-RangeExpr">range
* expression</a>.
*/
public class Range
extends AbstractBinaryExpression<IExpression, IExpression> {
/**
* Construct a new range expression.
*
* @param start
* the expressions representing the start of the range
* @param end
* the expressions representing the end of the range
*
*/
public Range(@NonNull IExpression start, @NonNull IExpression end) {
super(start, end);
}
@Override
public Class<IIntegerItem> getBaseResultType() {
return IIntegerItem.class;
}
@Override
public ISequence<IIntegerItem> accept(DynamicContext dynamicContext, ISequence<?> focus) {
IAnyAtomicItem leftItem = getFirstDataItem(getLeft().accept(dynamicContext, focus), true);
IAnyAtomicItem rightItem = getFirstDataItem(getRight().accept(dynamicContext, focus), true);
IIntegerItem left = leftItem == null ? null : IIntegerItem.cast(leftItem);
IIntegerItem right = rightItem == null ? null : IIntegerItem.cast(rightItem);
ISequence<IIntegerItem> retval;
if (left == null || right == null || left.compareTo(right) > 0) {
retval = ISequence.empty();
} else {
BigInteger min = right.asInteger();
BigInteger max = right.asInteger();
List<IIntegerItem> range = new ArrayList<>(max.subtract(min).add(BigInteger.ONE).intValueExact());
for (BigInteger val = left.asInteger(); val.compareTo(max) <= 0; val = val.add(BigInteger.ONE)) {
range.add(IIntegerItem.valueOf(val));
}
retval = ISequence.ofCollection(range);
}
return retval;
}
@Override
public <RESULT, CONTEXT> RESULT accept(IExpressionVisitor<RESULT, CONTEXT> visitor, CONTEXT context) {
return visitor.visitRange(this, context);
}
}