Search in sources :

Example 1 with ELClass

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;
}
Also used : VariableMapper(jakarta.el.VariableMapper) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) ELClass(jakarta.el.ELClass) ValueExpression(jakarta.el.ValueExpression) ELClass(jakarta.el.ELClass) ELException(jakarta.el.ELException) LambdaExpression(jakarta.el.LambdaExpression) FunctionMapper(jakarta.el.FunctionMapper)

Example 2 with ELClass

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;
}
Also used : ELClass(jakarta.el.ELClass) ImportHandler(jakarta.el.ImportHandler)

Example 3 with ELClass

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));
}
Also used : ELClass(jakarta.el.ELClass) PropertyNotFoundException(jakarta.el.PropertyNotFoundException) VariableMapper(jakarta.el.VariableMapper) ValueExpression(jakarta.el.ValueExpression) ELException(jakarta.el.ELException)

Aggregations

ELClass (jakarta.el.ELClass)3 ELException (jakarta.el.ELException)2 ValueExpression (jakarta.el.ValueExpression)2 VariableMapper (jakarta.el.VariableMapper)2 FunctionMapper (jakarta.el.FunctionMapper)1 ImportHandler (jakarta.el.ImportHandler)1 LambdaExpression (jakarta.el.LambdaExpression)1 PropertyNotFoundException (jakarta.el.PropertyNotFoundException)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1