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