package org.exist.xquery.functions.array;
import org.exist.xquery.*;
import org.exist.xquery.util.ExpressionDumper;
import org.exist.xquery.value.Item;
import org.exist.xquery.value.Sequence;
import org.exist.xquery.value.Type;
import java.util.ArrayList;
import java.util.List;
/**
* A literal array constructor (XQuery 3.1)
*/
public class ArrayConstructor extends AbstractExpression {
public enum ConstructorType { SQUARE_ARRAY, CURLY_ARRAY }
private ConstructorType type;
private List<Expression> arguments = new ArrayList<Expression>();
public ArrayConstructor(XQueryContext context, ConstructorType type) {
super(context);
this.type = type;
}
public void addArgument(Expression expression) {
arguments.add(expression);
}
@Override
public void analyze(AnalyzeContextInfo contextInfo) throws XPathException {
contextInfo.setParent(this);
for (Expression expr: arguments) {
expr.analyze(contextInfo);
}
}
@Override
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
if (context.getXQueryVersion() < 31) {
throw new XPathException(this, ErrorCodes.EXXQDY0004, "arrays are only available in XQuery 3.1, but version declaration states " +
context.getXQueryVersion());
}
switch(type) {
case SQUARE_ARRAY:
final List<Sequence> items = new ArrayList<Sequence>(arguments.size());
for (Expression arg: arguments) {
final Sequence result = arg.eval(contextSequence, contextItem);
if (result != null) {
items.add(result);
}
}
return new ArrayType(context, items);
default:
final Sequence result = arguments.get(0).eval(contextSequence, contextItem);
return new ArrayType(context, result);
}
}
@Override
public int returnsType() {
return Type.ARRAY;
}
@Override
public void resetState(boolean postOptimization) {
super.resetState(postOptimization);
for (Expression expr: arguments) {
expr.resetState(postOptimization);
}
}
@Override
public void dump(ExpressionDumper dumper) {
dumper.display("array {");
dumper.display('}');
}
@Override
public void accept(ExpressionVisitor visitor) {
for (Expression expr: arguments) {
expr.accept(visitor);
}
}
}