use of jakarta.el.LambdaExpression in project tomcat by apache.
the class AstFunction method getValue.
@Override
public Object getValue(EvaluationContext ctx) throws ELException {
FunctionMapper fnMapper = ctx.getFunctionMapper();
// quickly validate again for this request
if (fnMapper == null) {
throw new ELException(MessageFactory.get("error.fnMapper.null"));
}
Method m = fnMapper.resolveFunction(this.prefix, this.localName);
if (m == null && this.prefix.length() == 0) {
// TODO: Do we need to think about precedence of the various ways
// a lambda expression may be obtained from something that
// the parser thinks is a function?
Object obj = null;
if (ctx.isLambdaArgument(this.localName)) {
obj = ctx.getLambdaArgument(this.localName);
}
if (obj == null) {
VariableMapper varMapper = ctx.getVariableMapper();
if (varMapper != null) {
obj = varMapper.resolveVariable(this.localName);
if (obj instanceof ValueExpression) {
// See if this returns a LambdaExpression
obj = ((ValueExpression) obj).getValue(ctx);
}
}
}
if (obj == null) {
obj = ctx.getELResolver().getValue(ctx, null, this.localName);
}
if (obj instanceof LambdaExpression) {
// Build arguments
int i = 0;
while (obj instanceof LambdaExpression && i < jjtGetNumChildren()) {
Node args = jjtGetChild(i);
obj = ((LambdaExpression) obj).invoke(((AstMethodParameters) args).getParameters(ctx));
i++;
}
if (i < jjtGetNumChildren()) {
// there were too many sets of parameters
throw new ELException(MessageFactory.get("error.lambda.tooManyMethodParameterSets"));
}
return obj;
}
// Call to a constructor or a static method
obj = ctx.getImportHandler().resolveClass(this.localName);
if (obj != null) {
return ctx.getELResolver().invoke(ctx, new ELClass((Class<?>) obj), "<init>", null, ((AstMethodParameters) this.children[0]).getParameters(ctx));
}
obj = ctx.getImportHandler().resolveStatic(this.localName);
if (obj != null) {
return ctx.getELResolver().invoke(ctx, new ELClass((Class<?>) obj), this.localName, null, ((AstMethodParameters) this.children[0]).getParameters(ctx));
}
}
if (m == null) {
throw new ELException(MessageFactory.get("error.fnMapper.method", this.getOutputName()));
}
// single set of method parameters
if (this.jjtGetNumChildren() != 1) {
throw new ELException(MessageFactory.get("error.function.tooManyMethodParameterSets", getOutputName()));
}
Node parameters = jjtGetChild(0);
Class<?>[] paramTypes = m.getParameterTypes();
Object[] params = null;
Object result = null;
int inputParameterCount = parameters.jjtGetNumChildren();
int methodParameterCount = paramTypes.length;
if (inputParameterCount == 0 && methodParameterCount == 1 && m.isVarArgs()) {
params = new Object[] { null };
} else if (inputParameterCount > 0) {
params = new Object[methodParameterCount];
try {
for (int i = 0; i < methodParameterCount; i++) {
if (m.isVarArgs() && i == methodParameterCount - 1) {
if (inputParameterCount < methodParameterCount) {
params[i] = new Object[] { null };
} else if (inputParameterCount == methodParameterCount && paramTypes[i].isArray()) {
params[i] = parameters.jjtGetChild(i).getValue(ctx);
} else {
Object[] varargs = new Object[inputParameterCount - methodParameterCount + 1];
Class<?> target = paramTypes[i].getComponentType();
for (int j = i; j < inputParameterCount; j++) {
varargs[j - i] = parameters.jjtGetChild(j).getValue(ctx);
varargs[j - i] = ELSupport.coerceToType(ctx, varargs[j - i], target);
}
params[i] = varargs;
}
} else {
params[i] = parameters.jjtGetChild(i).getValue(ctx);
}
params[i] = ELSupport.coerceToType(ctx, params[i], paramTypes[i]);
}
} catch (ELException ele) {
throw new ELException(MessageFactory.get("error.function", this.getOutputName()), ele);
}
}
try {
result = m.invoke(null, params);
} catch (IllegalAccessException iae) {
throw new ELException(MessageFactory.get("error.function", this.getOutputName()), iae);
} catch (InvocationTargetException ite) {
Throwable cause = ite.getCause();
if (cause instanceof ThreadDeath) {
throw (ThreadDeath) cause;
}
if (cause instanceof VirtualMachineError) {
throw (VirtualMachineError) cause;
}
throw new ELException(MessageFactory.get("error.function", this.getOutputName()), cause);
}
return result;
}
use of jakarta.el.LambdaExpression in project tomcat by apache.
the class AstValue method getValue.
@Override
public Object getValue(EvaluationContext ctx) throws ELException {
Object base = this.children[0].getValue(ctx);
int propCount = this.jjtGetNumChildren();
int i = 1;
Object suffix = null;
ELResolver resolver = ctx.getELResolver();
while (base != null && i < propCount) {
suffix = this.children[i].getValue(ctx);
if (i + 1 < propCount && (this.children[i + 1] instanceof AstMethodParameters)) {
AstMethodParameters mps = (AstMethodParameters) this.children[i + 1];
if (base instanceof Optional && "orElseGet".equals(suffix) && mps.jjtGetNumChildren() == 1) {
Node paramFoOptional = mps.jjtGetChild(0);
if (!(paramFoOptional instanceof AstLambdaExpression || paramFoOptional instanceof LambdaExpression)) {
throw new ELException(MessageFactory.get("stream.optional.paramNotLambda", suffix));
}
}
// This is a method
Object[] paramValues = mps.getParameters(ctx);
base = resolver.invoke(ctx, base, suffix, getTypesFromValues(paramValues), paramValues);
i += 2;
} else {
// This is a property
if (suffix == null) {
return null;
}
ctx.setPropertyResolved(false);
base = resolver.getValue(ctx, base, suffix);
i++;
}
}
if (!ctx.isPropertyResolved()) {
throw new PropertyNotFoundException(MessageFactory.get("error.resolver.unhandled", base, suffix));
}
return base;
}
use of jakarta.el.LambdaExpression in project tomcat by apache.
the class ELSupport method coerceToType.
public static final <T> T coerceToType(final ELContext ctx, final Object obj, final Class<T> type) throws ELException {
if (ctx != null) {
boolean originalIsPropertyResolved = ctx.isPropertyResolved();
try {
T result = ctx.getELResolver().convertToType(ctx, obj, type);
if (ctx.isPropertyResolved()) {
return result;
}
} finally {
ctx.setPropertyResolved(originalIsPropertyResolved);
}
}
if (type == null || Object.class.equals(type) || (obj != null && type.isAssignableFrom(obj.getClass()))) {
@SuppressWarnings("unchecked") T result = (T) obj;
return result;
}
if (!COERCE_TO_ZERO) {
if (obj == null && !type.isPrimitive() && !String.class.isAssignableFrom(type)) {
return null;
}
}
if (String.class.equals(type)) {
@SuppressWarnings("unchecked") T result = (T) coerceToString(ctx, obj);
return result;
}
if (ELArithmetic.isNumberType(type)) {
@SuppressWarnings("unchecked") T result = (T) coerceToNumber(ctx, obj, type);
return result;
}
if (Character.class.equals(type) || Character.TYPE == type) {
@SuppressWarnings("unchecked") T result = (T) coerceToCharacter(ctx, obj);
return result;
}
if (Boolean.class.equals(type) || Boolean.TYPE == type) {
@SuppressWarnings("unchecked") T result = (T) coerceToBoolean(ctx, obj, Boolean.TYPE == type);
return result;
}
if (type.isEnum()) {
@SuppressWarnings("unchecked") T result = (T) coerceToEnum(ctx, obj, type);
return result;
}
// new to spec
if (obj == null) {
return null;
}
if (obj instanceof String) {
String str = (String) obj;
PropertyEditor editor = PropertyEditorManager.findEditor(type);
if (editor == null) {
if (str.isEmpty()) {
return null;
}
throw new ELException(MessageFactory.get("error.convert", obj, obj.getClass(), type));
} else {
try {
editor.setAsText(str);
@SuppressWarnings("unchecked") T result = (T) editor.getValue();
return result;
} catch (RuntimeException e) {
if (str.isEmpty()) {
return null;
}
throw new ELException(MessageFactory.get("error.convert", obj, obj.getClass(), type), e);
}
}
}
// for an empty map. The parser will always parse {} as an empty set.
if (obj instanceof Set && type == Map.class && ((Set<?>) obj).isEmpty()) {
@SuppressWarnings("unchecked") T result = (T) Collections.EMPTY_MAP;
return result;
}
// Handle arrays
if (type.isArray() && obj.getClass().isArray()) {
@SuppressWarnings("unchecked") T result = (T) coerceToArray(ctx, obj, type);
return result;
}
if (obj instanceof LambdaExpression && isFunctionalInterface(type)) {
T result = coerceToFunctionalInterface(ctx, (LambdaExpression) obj, type);
return result;
}
throw new ELException(MessageFactory.get("error.convert", obj, obj.getClass(), type));
}
use of jakarta.el.LambdaExpression in project tomcat by apache.
the class AstLambdaExpression method getValue.
@Override
public Object getValue(EvaluationContext ctx) throws ELException {
// Correct evaluation requires knowledge of the whole set of nested
// expressions, not just the current expression
NestedState state = getNestedState();
// Check that there are not more sets of parameters than there are
// nested expressions.
int methodParameterSetCount = jjtGetNumChildren() - 2;
if (methodParameterSetCount > state.getNestingCount()) {
throw new ELException(MessageFactory.get("error.lambda.tooManyMethodParameterSets"));
}
// First child is always parameters even if there aren't any
AstLambdaParameters formalParametersNode = (AstLambdaParameters) children[0];
Node[] formalParamNodes = formalParametersNode.children;
// Second child is a value expression
ValueExpressionImpl ve = new ValueExpressionImpl("", children[1], ctx.getFunctionMapper(), ctx.getVariableMapper(), null);
// Build a LambdaExpression
List<String> formalParameters = new ArrayList<>();
if (formalParamNodes != null) {
for (Node formalParamNode : formalParamNodes) {
formalParameters.add(formalParamNode.getImage());
}
}
LambdaExpression le = new LambdaExpression(formalParameters, ve);
le.setELContext(ctx);
if (jjtGetNumChildren() == 2) {
// in the nesting declare parameters
if (state.getHasFormalParameters()) {
return le;
} else {
return le.invoke(ctx, (Object[]) null);
}
}
/*
* This is a (possibly nested) lambda expression with one or more sets
* of parameters provided.
*
* If there are more nested expressions than sets of parameters this may
* return a LambdaExpression.
*
* If there are more sets of parameters than nested expressions an
* ELException will have been thrown by the check at the start of this
* method.
*/
// Always have to invoke the outer-most expression
int methodParameterIndex = 2;
Object result = le.invoke(((AstMethodParameters) children[methodParameterIndex]).getParameters(ctx));
methodParameterIndex++;
while (result instanceof LambdaExpression && methodParameterIndex < jjtGetNumChildren()) {
result = ((LambdaExpression) result).invoke(((AstMethodParameters) children[methodParameterIndex]).getParameters(ctx));
methodParameterIndex++;
}
return result;
}
use of jakarta.el.LambdaExpression in project tomcat by apache.
the class Stream method sorted.
public Stream sorted(final LambdaExpression le) {
Iterator<Object> downStream = new OpIterator() {
private Iterator<Object> sorted = null;
@Override
protected void findNext() {
if (sorted == null) {
sort(le);
}
if (sorted.hasNext()) {
next = sorted.next();
foundNext = true;
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private final void sort(LambdaExpression le) {
List list = new ArrayList<>();
Comparator<Object> c = new LambdaExpressionComparator(le);
while (iterator.hasNext()) {
list.add(iterator.next());
}
list.sort(c);
sorted = list.iterator();
}
};
return new Stream(downStream);
}
Aggregations