use of org.structr.core.function.QueryFunction in project structr by structr.
the class SliceExpression method evaluate.
@Override
public Object evaluate(final ActionContext ctx, final GraphObject entity) throws FrameworkException, UnlicensedException {
if (listExpression == null || startExpression == null || endExpression == null) {
return ERROR_MESSAGE_SLICE;
}
// evaluate start and end bounds
final Object startObject = startExpression.evaluate(ctx, entity);
final Object endObject = endExpression.evaluate(ctx, entity);
if (startObject == null) {
throw new FrameworkException(422, "Error in slice(): invalid start of range: null");
}
if (endObject == null) {
throw new FrameworkException(422, "Error in slice(): invalid end of range: null");
}
final Integer start = toNumber(startObject);
Integer end = toNumber(endObject);
boolean valid = true;
// null => number format parsing error or invalid source data
if (start == null || end == null) {
return null;
}
// check bounds BEFORE evaluating list expression
if (start < 0) {
valid = false;
logger.warn("Error in slice(): start index must be >= 0.");
}
if (end < 0) {
valid = false;
logger.warn("Error in slice(): end index must be > 0.");
}
if (start >= end) {
valid = false;
logger.warn("Error in slice(): start index must be < end index.");
}
if (valid) {
if (listExpression instanceof QueryFunction) {
final QueryFunction queryFunction = (QueryFunction) listExpression;
queryFunction.setRangeStart(start);
queryFunction.setRangeEnd(end);
return listExpression.evaluate(ctx, entity);
} else if (listExpression instanceof FunctionExpression && ((FunctionExpression) listExpression).getFunction() instanceof QueryFunction) {
final QueryFunction queryFunction = (QueryFunction) ((FunctionExpression) listExpression).getFunction();
queryFunction.setRangeStart(start);
queryFunction.setRangeEnd(end);
return listExpression.evaluate(ctx, entity);
} else {
final Object src = listExpression.evaluate(ctx, entity);
List list = null;
// handle list argument
if (src instanceof List) {
list = (List) src;
// handle array argument
} else if (isArray(src)) {
list = toList((Object[]) src);
// handle collection argument
} else if (src != null) {
list = new LinkedList((Collection) src);
} else {
return null;
}
if (start > list.size()) {
valid = false;
logger.warn("Error in slice(): start index is out of range.");
}
if (end > list.size()) {
end = list.size();
}
if (valid) {
return list.subList(start, end);
}
}
}
return null;
}
Aggregations