use of jakarta.el.ELClass 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.ELClass in project tomcat by apache.
the class ImportELResolver method getValue.
@Override
public Object getValue(ELContext context, Object base, Object property) {
Objects.requireNonNull(context);
Object result = null;
if (base == null) {
if (property != null) {
boolean resolveClass = true;
// Performance short-cut available when running on Tomcat
if (AST_IDENTIFIER_KEY != null) {
// Tomcat will set this key to Boolean.TRUE if the
// identifier is a stand-alone identifier (i.e.
// identifier) rather than part of an AstValue (i.e.
// identifier.something). Imports do not need to be
// checked if this is a stand-alone identifier
Boolean value = (Boolean) context.getContext(AST_IDENTIFIER_KEY);
if (value != null && value.booleanValue()) {
resolveClass = false;
}
}
ImportHandler importHandler = context.getImportHandler();
if (importHandler != null) {
String key = property.toString();
Class<?> clazz = null;
if (resolveClass) {
clazz = importHandler.resolveClass(key);
if (clazz != null) {
result = new ELClass(clazz);
}
}
if (result == null) {
// This might be the name of an imported static field
clazz = importHandler.resolveStatic(key);
if (clazz != null) {
try {
result = clazz.getField(key).get(null);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
// Most (all?) of these should have been
// prevented by the checks when the import
// was defined.
}
}
}
}
}
}
if (result != null) {
context.setPropertyResolved(base, property);
}
return result;
}
use of jakarta.el.ELClass in project tomcat by apache.
the class AstIdentifier method getValue.
@Override
public Object getValue(EvaluationContext ctx) throws ELException {
// Lambda parameters
if (ctx.isLambdaArgument(this.image)) {
return ctx.getLambdaArgument(this.image);
}
// Variable mapper
VariableMapper varMapper = ctx.getVariableMapper();
if (varMapper != null) {
ValueExpression expr = varMapper.resolveVariable(this.image);
if (expr != null) {
return expr.getValue(ctx.getELContext());
}
}
// EL Resolvers
ctx.setPropertyResolved(false);
Object result;
/* Putting the Boolean into the ELContext is part of a performance
* optimisation for ScopedAttributeELResolver. When looking up "foo",
* the resolver can't differentiate between ${ foo } and ${ foo.bar }.
* This is important because the expensive class lookup only needs to
* be performed in the later case. This flag tells the resolver if the
* lookup can be skipped.
*/
if (parent instanceof AstValue) {
ctx.putContext(this.getClass(), Boolean.FALSE);
} else {
ctx.putContext(this.getClass(), Boolean.TRUE);
}
try {
result = ctx.getELResolver().getValue(ctx, null, this.image);
} finally {
// Always reset the flag to false so the optimisation is not applied
// inappropriately
ctx.putContext(this.getClass(), Boolean.FALSE);
}
if (ctx.isPropertyResolved()) {
return result;
}
// Import
result = ctx.getImportHandler().resolveClass(this.image);
if (result != null) {
return new ELClass((Class<?>) result);
}
result = ctx.getImportHandler().resolveStatic(this.image);
if (result != null) {
try {
return ((Class<?>) result).getField(this.image).get(null);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
throw new ELException(e);
}
}
throw new PropertyNotFoundException(MessageFactory.get("error.resolver.unhandled.null", this.image));
}
Aggregations