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

Reply via email to