Author: markt
Date: Fri Feb 21 11:13:04 2014
New Revision: 1570529

URL: http://svn.apache.org/r1570529
Log:
Backport some more EL refactoring in preparation for the fix for 
https://issues.apache.org/bugzilla/show_bug.cgi?id=56147
Includes some re-ordering of methods to simplify diff against 8.0.x

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/javax/el/BeanELResolver.java
    tomcat/tc7.0.x/trunk/java/javax/el/Util.java

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1499513

Modified: tomcat/tc7.0.x/trunk/java/javax/el/BeanELResolver.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/javax/el/BeanELResolver.java?rev=1570529&r1=1570528&r2=1570529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/javax/el/BeanELResolver.java (original)
+++ tomcat/tc7.0.x/trunk/java/javax/el/BeanELResolver.java Fri Feb 21 11:13:04 
2014
@@ -22,10 +22,8 @@ import java.beans.FeatureDescriptor;
 import java.beans.IntrospectionException;
 import java.beans.Introspector;
 import java.beans.PropertyDescriptor;
-import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Arrays;
@@ -72,6 +70,20 @@ public class BeanELResolver extends ELRe
     }
 
     @Override
+    public Class<?> getType(ELContext context, Object base, Object property)
+            throws NullPointerException, PropertyNotFoundException, 
ELException {
+        if (context == null) {
+            throw new NullPointerException();
+        }
+        if (base == null || property == null) {
+            return null;
+        }
+
+        context.setPropertyResolved(true);
+        return this.property(context, base, property).getPropertyType();
+    }
+
+    @Override
     public Object getValue(ELContext context, Object base, Object property)
             throws NullPointerException, PropertyNotFoundException, 
ELException {
         if (context == null) {
@@ -104,20 +116,6 @@ public class BeanELResolver extends ELRe
     }
 
     @Override
-    public Class<?> getType(ELContext context, Object base, Object property)
-            throws NullPointerException, PropertyNotFoundException, 
ELException {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-        if (base == null || property == null) {
-            return null;
-        }
-
-        context.setPropertyResolved(true);
-        return this.property(context, base, property).getPropertyType();
-    }
-
-    @Override
     public void setValue(ELContext context, Object base, Object property,
             Object value) throws NullPointerException,
             PropertyNotFoundException, PropertyNotWritableException,
@@ -158,6 +156,48 @@ public class BeanELResolver extends ELRe
         }
     }
 
+    /**
+     * @since EL 2.2
+     */
+    @Override
+    public Object invoke(ELContext context, Object base, Object method,
+            Class<?>[] paramTypes, Object[] params) {
+        if (context == null) {
+            throw new NullPointerException();
+        }
+        if (base == null || method == null) {
+            return null;
+        }
+
+        ExpressionFactory factory = Util.getExpressionFactory();
+
+        String methodName = (String) factory.coerceToType(method, 
String.class);
+
+        // Find the matching method
+        Method matchingMethod =
+                Util.findMethod(base, methodName, paramTypes, params);
+
+        Object[] parameters = Util.buildParameters(
+                matchingMethod.getParameterTypes(), matchingMethod.isVarArgs(),
+                params);
+
+        Object result = null;
+        try {
+            result = matchingMethod.invoke(base, parameters);
+        } catch (IllegalArgumentException e) {
+            throw new ELException(e);
+        } catch (IllegalAccessException e) {
+            throw new ELException(e);
+        } catch (InvocationTargetException e) {
+            Throwable cause = e.getCause();
+            Util.handleThrowable(cause);
+            throw new ELException(cause);
+        }
+
+        context.setPropertyResolved(true);
+        return result;
+    }
+
     @Override
     public boolean isReadOnly(ELContext context, Object base, Object property)
             throws NullPointerException, PropertyNotFoundException, 
ELException {
@@ -267,7 +307,7 @@ public class BeanELResolver extends ELRe
 
         public boolean isReadOnly() {
             return this.write == null
-                && (null == (this.write = getMethod(this.owner, 
descriptor.getWriteMethod())));
+                && (null == (this.write = Util.getMethod(this.owner, 
descriptor.getWriteMethod())));
         }
 
         public Method getWriteMethod() {
@@ -280,7 +320,7 @@ public class BeanELResolver extends ELRe
 
         private Method write(ELContext ctx) {
             if (this.write == null) {
-                this.write = getMethod(this.owner, 
descriptor.getWriteMethod());
+                this.write = Util.getMethod(this.owner, 
descriptor.getWriteMethod());
                 if (this.write == null) {
                     throw new PropertyNotFoundException(Util.message(ctx,
                             "propertyNotWritable", new Object[] {
@@ -292,7 +332,7 @@ public class BeanELResolver extends ELRe
 
         private Method read(ELContext ctx) {
             if (this.read == null) {
-                this.read = getMethod(this.owner, descriptor.getReadMethod());
+                this.read = Util.getMethod(this.owner, 
descriptor.getReadMethod());
                 if (this.read == null) {
                     throw new PropertyNotFoundException(Util.message(ctx,
                             "propertyNotReadable", new Object[] {
@@ -317,38 +357,6 @@ public class BeanELResolver extends ELRe
         return props.get(ctx, prop);
     }
 
-    private static final Method getMethod(Class<?> type, Method m) {
-        if (m == null || Modifier.isPublic(type.getModifiers())) {
-            return m;
-        }
-        Class<?>[] inf = type.getInterfaces();
-        Method mp = null;
-        for (int i = 0; i < inf.length; i++) {
-            try {
-                mp = inf[i].getMethod(m.getName(), m.getParameterTypes());
-                mp = getMethod(mp.getDeclaringClass(), mp);
-                if (mp != null) {
-                    return mp;
-                }
-            } catch (NoSuchMethodException e) {
-                // Ignore
-            }
-        }
-        Class<?> sup = type.getSuperclass();
-        if (sup != null) {
-            try {
-                mp = sup.getMethod(m.getName(), m.getParameterTypes());
-                mp = getMethod(mp.getDeclaringClass(), mp);
-                if (mp != null) {
-                    return mp;
-                }
-            } catch (NoSuchMethodException e) {
-                // Ignore
-            }
-        }
-        return null;
-    }
-    
     private static final class ConcurrentCache<K,V> {
 
         private final int size;
@@ -385,112 +393,4 @@ public class BeanELResolver extends ELRe
         }
 
     }
-    
-    /**
-     * @since EL 2.2
-     */
-    @Override
-    public Object invoke(ELContext context, Object base, Object method,
-            Class<?>[] paramTypes, Object[] params) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-        if (base == null || method == null) {
-            return null;
-        }
-
-        ExpressionFactory factory = ExpressionFactory.newInstance();
-        
-        String methodName = (String) factory.coerceToType(method, 
String.class);
-        
-        // Find the matching method
-        Method matchingMethod = null;
-        Class<?> clazz = base.getClass();
-        if (paramTypes != null) {
-            try {
-                matchingMethod =
-                    getMethod(clazz, clazz.getMethod(methodName, paramTypes));
-            } catch (NoSuchMethodException e) {
-                throw new MethodNotFoundException(e);
-            }
-        } else {
-            int paramCount = 0;
-            if (params != null) {
-                paramCount = params.length;
-            }
-            Method[] methods = clazz.getMethods();
-            for (Method m : methods) {
-                if (methodName.equals(m.getName())) {
-                    if (m.getParameterTypes().length == paramCount) {
-                        // Same number of parameters - use the first match
-                        matchingMethod = getMethod(clazz, m);
-                        break;
-                    }
-                    if (m.isVarArgs()
-                            && paramCount > m.getParameterTypes().length - 2) {
-                        matchingMethod = getMethod(clazz, m);
-                    }
-                }
-            }
-            if (matchingMethod == null) {
-                throw new MethodNotFoundException(
-                        "Unable to find method [" + methodName + "] with ["
-                        + paramCount + "] parameters");
-            }
-        }
-
-        Class<?>[] parameterTypes = matchingMethod.getParameterTypes();
-        Object[] parameters = null;
-        if (parameterTypes.length > 0) {
-            parameters = new Object[parameterTypes.length];
-            @SuppressWarnings("null")  // params.length >= 
parameterTypes.length
-            int paramCount = params.length;
-            if (matchingMethod.isVarArgs()) {
-                int varArgIndex = parameterTypes.length - 1;
-                // First argCount-1 parameters are standard
-                for (int i = 0; (i < varArgIndex); i++) {
-                    parameters[i] = factory.coerceToType(params[i],
-                            parameterTypes[i]);
-                }
-                // Last parameter is the varargs
-                Class<?> varArgClass =
-                    parameterTypes[varArgIndex].getComponentType();
-                final Object varargs = Array.newInstance(
-                    varArgClass,
-                    (paramCount - varArgIndex));
-                for (int i = (varArgIndex); i < paramCount; i++) {
-                    Array.set(varargs, i - varArgIndex,
-                            factory.coerceToType(params[i], varArgClass));
-                }
-                parameters[varArgIndex] = varargs;
-            } else {
-                parameters = new Object[parameterTypes.length];
-                for (int i = 0; i < parameterTypes.length; i++) {
-                    parameters[i] = factory.coerceToType(params[i],
-                            parameterTypes[i]);
-                }
-            }
-        }
-        Object result = null;
-        try {
-            result = matchingMethod.invoke(base, parameters);
-        } catch (IllegalArgumentException e) {
-            throw new ELException(e);
-        } catch (IllegalAccessException e) {
-            throw new ELException(e);
-        } catch (InvocationTargetException e) {
-            Throwable cause = e.getCause();
-            if (cause instanceof ThreadDeath) {
-                throw (ThreadDeath) cause;
-            }
-            if (cause instanceof VirtualMachineError) {
-                throw (VirtualMachineError) cause;
-            }
-            throw new ELException(cause);
-        }
-        
-        context.setPropertyResolved(true);
-        return result;
-    }
-
 }

Modified: tomcat/tc7.0.x/trunk/java/javax/el/Util.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/javax/el/Util.java?rev=1570529&r1=1570528&r2=1570529&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/javax/el/Util.java (original)
+++ tomcat/tc7.0.x/trunk/java/javax/el/Util.java Fri Feb 21 11:13:04 2014
@@ -17,6 +17,10 @@
 package javax.el;
 
 import java.lang.ref.WeakReference;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.text.MessageFormat;
 import java.util.Locale;
 import java.util.MissingResourceException;
@@ -180,6 +184,83 @@ class Util {
         }
     }
 
+
+    static Method findMethod(Object base, String methodName,
+            Class<?>[] paramTypes, Object[] params) {
+
+        Method matchingMethod = null;
+
+        Class<?> clazz = base.getClass();
+        if (paramTypes != null) {
+            try {
+                matchingMethod =
+                    getMethod(clazz, clazz.getMethod(methodName, paramTypes));
+            } catch (NoSuchMethodException e) {
+                throw new MethodNotFoundException(e);
+            }
+        } else {
+            int paramCount = 0;
+            if (params != null) {
+                paramCount = params.length;
+            }
+            Method[] methods = clazz.getMethods();
+            for (Method m : methods) {
+                if (methodName.equals(m.getName())) {
+                    if (m.getParameterTypes().length == paramCount) {
+                        // Same number of parameters - use the first match
+                        matchingMethod = getMethod(clazz, m);
+                        break;
+                    }
+                    if (m.isVarArgs()
+                            && paramCount > m.getParameterTypes().length - 2) {
+                        matchingMethod = getMethod(clazz, m);
+                    }
+                }
+            }
+            if (matchingMethod == null) {
+                throw new MethodNotFoundException(
+                        "Unable to find method [" + methodName + "] with ["
+                        + paramCount + "] parameters");
+            }
+        }
+
+        return matchingMethod;
+    }
+
+
+    static Method getMethod(Class<?> type, Method m) {
+        if (m == null || Modifier.isPublic(type.getModifiers())) {
+            return m;
+        }
+        Class<?>[] inf = type.getInterfaces();
+        Method mp = null;
+        for (int i = 0; i < inf.length; i++) {
+            try {
+                mp = inf[i].getMethod(m.getName(), m.getParameterTypes());
+                mp = getMethod(mp.getDeclaringClass(), mp);
+                if (mp != null) {
+                    return mp;
+                }
+            } catch (NoSuchMethodException e) {
+                // Ignore
+            }
+        }
+        Class<?> sup = type.getSuperclass();
+        if (sup != null) {
+            try {
+                mp = sup.getMethod(m.getName(), m.getParameterTypes());
+                mp = getMethod(mp.getDeclaringClass(), mp);
+                if (mp != null) {
+                    return mp;
+                }
+            } catch (NoSuchMethodException e) {
+                // Ignore
+            }
+        }
+        return null;
+    }
+    
+    
     /*
      * This method duplicates code in org.apache.el.util.ReflectionUtil. When
      * making changes keep the code in sync.
@@ -216,4 +297,102 @@ class Util {
         }
         return targetClass.isAssignableFrom(src);
     }
+
+
+    static Constructor<?> findConstructor(Object base, Class<?>[] paramTypes,
+            Object[] params) {
+
+        Constructor<?> match = null;
+
+        Class<?> clazz = base.getClass();
+        if (paramTypes != null) {
+            try {
+                match = getConstructor(clazz, 
clazz.getConstructor(paramTypes));
+            } catch (NoSuchMethodException e) {
+                throw new MethodNotFoundException(e);
+            }
+        } else {
+            int paramCount = 0;
+            if (params != null) {
+                paramCount = params.length;
+            }
+            Constructor<?>[] constructors = clazz.getConstructors();
+            for (Constructor<?> c : constructors) {
+                if (c.getParameterTypes().length == paramCount) {
+                    // Same number of parameters - use the first match
+                    match = getConstructor(clazz, c);
+                    break;
+                }
+                if (c.isVarArgs()
+                        && paramCount > c.getParameterTypes().length - 2) {
+                    match = getConstructor(clazz, c);
+                }
+            }
+            if (match == null) {
+                throw new MethodNotFoundException(
+                        "Unable to find constructor with [" + paramCount +
+                        "] parameters");
+            }
+        }
+
+        return match;
+    }
+
+
+    static Constructor<?> getConstructor(Class<?> type, Constructor<?> c) {
+        if (c == null || Modifier.isPublic(type.getModifiers())) {
+            return c;
+        }
+        Constructor<?> cp = null;
+        Class<?> sup = type.getSuperclass();
+        if (sup != null) {
+            try {
+                cp = sup.getConstructor(c.getParameterTypes());
+                cp = getConstructor(cp.getDeclaringClass(), cp);
+                if (cp != null) {
+                    return cp;
+                }
+            } catch (NoSuchMethodException e) {
+                // Ignore
+            }
+        }
+        return null;
+    }
+
+
+    static Object[] buildParameters(Class<?>[] parameterTypes,
+            boolean isVarArgs,Object[] params) {
+        ExpressionFactory factory = getExpressionFactory();
+        Object[] parameters = null;
+        if (parameterTypes.length > 0) {
+            parameters = new Object[parameterTypes.length];
+            int paramCount = params.length;
+            if (isVarArgs) {
+                int varArgIndex = parameterTypes.length - 1;
+                // First argCount-1 parameters are standard
+                for (int i = 0; (i < varArgIndex); i++) {
+                    parameters[i] = factory.coerceToType(params[i],
+                            parameterTypes[i]);
+                }
+                // Last parameter is the varargs
+                Class<?> varArgClass =
+                    parameterTypes[varArgIndex].getComponentType();
+                final Object varargs = Array.newInstance(
+                    varArgClass,
+                    (paramCount - varArgIndex));
+                for (int i = (varArgIndex); i < paramCount; i++) {
+                    Array.set(varargs, i - varArgIndex,
+                            factory.coerceToType(params[i], varArgClass));
+                }
+                parameters[varArgIndex] = varargs;
+            } else {
+                parameters = new Object[parameterTypes.length];
+                for (int i = 0; i < parameterTypes.length; i++) {
+                    parameters[i] = factory.coerceToType(params[i],
+                            parameterTypes[i]);
+                }
+            }
+        }
+        return parameters;
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to