This is an automated email from the ASF dual-hosted git repository. remm pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push: new 4f5bdbc Add Graal ease of use for EL 4f5bdbc is described below commit 4f5bdbc95f1ad1152396c615aab65b2137d30c7f Author: remm <r...@apache.org> AuthorDate: Fri Sep 27 10:51:51 2019 +0200 Add Graal ease of use for EL Otherwise BeanELResolver uses BeanInfo (which is ok) and it needs manual reflection configuration. I prefer limiting the annoyances to a minimum wherever possible. --- java/org/apache/jasper/el/JasperELResolver.java | 110 +++++++++++++++++++++ .../apache/jasper/runtime/JspRuntimeLibrary.java | 2 +- webapps/docs/changelog.xml | 4 + 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/java/org/apache/jasper/el/JasperELResolver.java b/java/org/apache/jasper/el/JasperELResolver.java index 73d133e..99189807 100644 --- a/java/org/apache/jasper/el/JasperELResolver.java +++ b/java/org/apache/jasper/el/JasperELResolver.java @@ -17,6 +17,9 @@ package org.apache.jasper.el; +import java.beans.FeatureDescriptor; +import java.lang.reflect.Method; +import java.util.Iterator; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -34,6 +37,9 @@ import javax.el.StaticFieldELResolver; import javax.servlet.jsp.el.ImplicitObjectELResolver; import javax.servlet.jsp.el.ScopedAttributeELResolver; +import org.apache.jasper.runtime.ExceptionUtils; +import org.apache.jasper.runtime.JspRuntimeLibrary; + /** * Jasper-specific CompositeELResolver that optimizes certain functions to avoid * unnecessary resolver calls. @@ -61,6 +67,9 @@ public class JasperELResolver extends CompositeELResolver { add(new ResourceBundleELResolver()); add(new ListELResolver()); add(new ArrayELResolver()); + if (JspRuntimeLibrary.GRAAL) { + add(new GraalBeanELResolver()); + } add(new BeanELResolver()); add(new ScopedAttributeELResolver()); } @@ -103,6 +112,9 @@ public class JasperELResolver extends CompositeELResolver { // skip stream, static and collection-based resolvers (map, // resource, list, array) and bean start = index + 7; + if (JspRuntimeLibrary.GRAAL) { + start++; + } } else { // skip implicit resolver only start = 1; @@ -172,4 +184,102 @@ public class JasperELResolver extends CompositeELResolver { return obj.toString(); } } + + /** + * Extend ELResolver for Graal to avoid bean info use if possible, + * as BeanELResolver needs manual reflection configuration. + */ + private static class GraalBeanELResolver extends ELResolver { + + @Override + public Object getValue(ELContext context, Object base, + Object property) { + Object value = null; + Method method = getReadMethod(base.getClass(), property.toString()); + if (method != null) { + context.setPropertyResolved(base, property); + try { + value = method.invoke(base, (Object[]) null); + } catch (Exception ex) { + Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex); + ExceptionUtils.handleThrowable(thr); + } + } + return value; + } + + @Override + public void setValue(ELContext context, Object base, Object property, + Object value) { + Method method = getWriteMethod(base.getClass(), property.toString()); + if (method != null) { + context.setPropertyResolved(base, property); + try { + method.invoke(base, value); + } catch (Exception ex) { + Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex); + ExceptionUtils.handleThrowable(thr); + } + } + } + + @Override + public boolean isReadOnly(ELContext context, Object base, + Object property) { + Class<?> beanClass = base.getClass(); + String prop = property.toString(); + return (getReadMethod(beanClass, prop) != null) + && (getWriteMethod(beanClass, prop) != null); + } + + public static Method getReadMethod(Class<?> beanClass, String prop) { + Method result = null; + String setter = "get" + capitalize(prop); + Method methods[] = beanClass.getMethods(); + for (Method method : methods) { + if (setter.equals(method.getName())) { + return method; + } + } + return result; + } + + public static Method getWriteMethod(Class<?> beanClass, String prop) { + Method result = null; + String setter = "set" + capitalize(prop); + Method methods[] = beanClass.getMethods(); + for (Method method : methods) { + if (setter.equals(method.getName())) { + return method; + } + } + return result; + } + + public static String capitalize(String name) { + if (name == null || name.length() == 0) { + return name; + } + char chars[] = name.toCharArray(); + chars[0] = Character.toUpperCase(chars[0]); + return new String(chars); + } + + @Override + public Class<?> getType(ELContext context, Object base, + Object property) { + return null; + } + + @Override + public Iterator<FeatureDescriptor> getFeatureDescriptors( + ELContext context, Object base) { + return null; + } + + @Override + public Class<?> getCommonPropertyType(ELContext context, Object base) { + return null; + } + } } \ No newline at end of file diff --git a/java/org/apache/jasper/runtime/JspRuntimeLibrary.java b/java/org/apache/jasper/runtime/JspRuntimeLibrary.java index cc8416b..4770024 100644 --- a/java/org/apache/jasper/runtime/JspRuntimeLibrary.java +++ b/java/org/apache/jasper/runtime/JspRuntimeLibrary.java @@ -56,7 +56,7 @@ import org.apache.tomcat.InstanceManager; */ public class JspRuntimeLibrary { - private static final boolean GRAAL; + public static final boolean GRAAL; static { boolean result = false; diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 41d9f3f..89d8355 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -76,6 +76,10 @@ <update> Update to the Eclipse JDT compiler 4.13. (markt) </update> + <fix> + Add GraalVM specific ELResolver to avoid BeanInfo use in BeanElResolver + if possible, as it needs manual reflection configuration. (remm) + </fix> </changelog> </subsection> <subsection name="Web Socket"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org