Author: rahul Date: Sun Jul 19 02:28:24 2009 New Revision: 795463 URL: http://svn.apache.org/viewvc?rev=795463&view=rev Log: JEXL-20 - Various checkstyle and Javadoc improvements. - Update a couple of checkstyle rules. Thanks to patch by Henri Biestro <hbiestro at gmail dot com>.
Modified: commons/proper/jexl/branches/2.0/src/conf/checkstyle.xml commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/AbstractExecutor.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/GetExecutor.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/util/introspection/MethodKeyTest.java Modified: commons/proper/jexl/branches/2.0/src/conf/checkstyle.xml URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/conf/checkstyle.xml?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/conf/checkstyle.xml (original) +++ commons/proper/jexl/branches/2.0/src/conf/checkstyle.xml Sun Jul 19 02:28:24 2009 @@ -57,7 +57,11 @@ <!-- Checks whether files end with a new line. --> <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile --> - <module name="NewlineAtEndOfFile"/> + <!-- JEXL-20: tried every combination on a Mac to no avail... + <module name="NewlineAtEndOfFile"> + <property name="lineSeparator" value="lf"/> + </module> + --> <!-- Checks that property files contain the same keys. --> <!-- See http://checkstyle.sf.net/config_misc.html#Translation --> @@ -70,7 +74,10 @@ <!-- Checks for Javadoc comments. --> <!-- See http://checkstyle.sf.net/config_javadoc.html --> - <module name="JavadocMethod"/> + <!-- JEXL-20: many of those by API choice --> + <module name="JavadocMethod"> + <property name="allowUndeclaredRTE" value="true"/> + </module> <module name="JavadocType"/> <module name="JavadocVariable"/> <module name="JavadocStyle"/> @@ -133,15 +140,16 @@ <!-- Checks for whitespace --> <!-- See http://checkstyle.sf.net/config_whitespace.html --> <module name="EmptyForIteratorPad"/> + <!-- <module name="GenericWhitespace"/> --> + <!-- JEXL-20: because the above is not yet supported through Maven plugin, disable others--> <!-- <module name="NoWhitespaceAfter"/> --> <!-- <module name="NoWhitespaceBefore"/> --> - <!-- <module name="GenericWhitespace"/> --> + <!-- <module name="WhitespaceAfter"/> --> + <!-- <module name="WhitespaceAround"/> --> <module name="OperatorWrap"/> <module name="ParenPad"/> <module name="TypecastParenPad"/> <module name="TabCharacter"/> - <!--<module name="WhitespaceAfter"/>--> - <!--<module name="WhitespaceAround"/>--> <!-- Modifier Checks --> @@ -161,8 +169,8 @@ <!-- Checks for common coding problems --> <!-- See http://checkstyle.sf.net/config_coding.html --> - <!-- JEXL: module name="AvoidInlineConditionals"/--> - <module name="DoubleCheckedLocking"/> <!-- MY FAVOURITE --> + <!-- JEXL: module name="AvoidInlineConditionals"/--> + <module name="DoubleCheckedLocking"/> <module name="EmptyStatement"/> <module name="EqualsHashCode"/> <module name="HiddenField"/> @@ -172,7 +180,8 @@ <property name="ignoreNumbers" value="-1, 0, 1, 2, 3"/> </module> <module name="MissingSwitchDefault"/> - <module name="RedundantThrows"/> + <!-- JEXL-20: used in introspection --> + <!--<module name="RedundantThrows"/>--> <module name="SimplifyBooleanExpression"/> <module name="SimplifyBooleanReturn"/> Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java Sun Jul 19 02:28:24 2009 @@ -1111,8 +1111,7 @@ } catch (Exception xany) { if (node == null) { throw new RuntimeException(xany); - } - else { + } else { throw new JexlException(node, "get object property error", xany); } } Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java Sun Jul 19 02:28:24 2009 @@ -170,6 +170,7 @@ /** * Checks whether this engine throws JexlException during evaluation. + * @return true if silent, false otherwise */ public boolean isSilent() { return this.silent; @@ -419,6 +420,7 @@ * <p> * If the JEXL engine is silent, errors will be logged through its logger as warning. * </p> + * @param context the evaluation context * @param bean the bean to set properties in * @param expr the property expression * @param value the value of the property @@ -530,8 +532,14 @@ int start = 0; int end = str.length(); if (end > 0) { - for (start = 0; start < end && str.charAt(start) == ' '; ++start); // trim front spaces - for (; end > 0 && str.charAt(end - 1) == ' '; --end); // trim ending spaces + // trim front spaces + while (start < end && str.charAt(start) == ' ') { + ++start; + } + // trim ending spaces + while (end > 0 && str.charAt(end - 1) == ' ') { + --end; + } return str.subSequence(start, end).toString(); } return ""; @@ -566,16 +574,19 @@ * instance fulfilling that pattern. */ @Deprecated + // CSOFF: StaticVariableName private static volatile JexlEngine DEFAULT = null; + // CSON: StaticVariableName /** * Retrieves a default JEXL engine. * @return the singleton */ + // CSOFF: DoubleCheckedLocking @Deprecated static JexlEngine getDefault() { - // java 5 allows the lazy singleton initialization - // using a double-check locking pattern + // java 5 memory model fixes the lazy singleton initialization + // using a double-check locking pattern using a volatile if (DEFAULT == null) { synchronized (JexlEngine.class) { if (DEFAULT == null) { @@ -585,4 +596,5 @@ } return DEFAULT; } + // CSON: DoubleCheckedLocking } \ No newline at end of file Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java Sun Jul 19 02:28:24 2009 @@ -26,12 +26,21 @@ protected Node mark; /** A marker to use in NPEs stating a null operand error. */ public static final String NULL_OPERAND = "jexl.null"; - /** {...@inheritdoc} */ + /** + * Creates a new JexlException. + * @param node the node causing the error + * @param msg the error message + */ public JexlException(Node node, String msg) { super(msg); mark = node; } - /** {...@inheritdoc} */ + /** + * Creates a new JexlException. + * @param node the node causing the error + * @param msg the error message + * @param cause the exception causing the error + */ public JexlException(Node node, String msg, Throwable cause) { super(msg, cause); mark = node; Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java Sun Jul 19 02:28:24 2009 @@ -122,19 +122,24 @@ * @see ExpressionBuilder */ private static enum ExpressionType { - CONSTANT(0), // constant count at index 0 - IMMEDIATE(1), // immediate count at index 1 - DEFERRED(2), // deferred count at index 2 - NESTED(2), // nested are counted as deferred thus count at index 2 - COMPOSITE(-1); // composite are not counted - /** the index in arrays of expression counters for composite expressions. */ + /** Constant expression, count index 0. */ + CONSTANT(0), + /** Immediate expression, count index 1. */ + IMMEDIATE(1), + /** Deferred expression, count index 2. */ + DEFERRED(2), + /** Nested (which are deferred) expressions, count index 2. */ + NESTED(2), + /** Composite expressions are not counted, index -1. */ + COMPOSITE(-1); + /** The index in arrays of expression counters for composite expressions. */ private final int index; /** * Creates an ExpressionType. - * @param index the index for this type in counters arrays. + * @param idx the index for this type in counters arrays. */ - ExpressionType(int index) { - this.index = index; + ExpressionType(int idx) { + this.index = idx; } } @@ -143,7 +148,9 @@ * Keeps count of sub-expressions by type. */ private static class ExpressionBuilder { + /** Per expression type counters. */ private final int[] counts; + /** The list of expressions. */ private final ArrayList<Expression> expressions; /** @@ -207,7 +214,11 @@ * The sole type of (runtime) exception the UnifiedJEXL can throw. */ public class Exception extends RuntimeException { - /** {...@inheritdoc} */ + /** + * Creates a UnifiedJEXL.Exception. + * @param msg the exception message + * @param cause the exception cause + */ public Exception(String msg, Throwable cause) { super(msg, cause); } @@ -217,13 +228,14 @@ * The abstract base class for all expressions, immediate '${...}' and deferred '#{...}'. */ public abstract class Expression { + /** The source of this expression ({...@see Expression#prepare}. */ protected final Expression source; /** * Creates an expression. - * @param source the source expression if any + * @param src the source expression if any */ - Expression(Expression source) { - this.source = source != null ? source : this; + Expression(Expression src) { + this.source = src != null ? src : this; } @Override @@ -252,6 +264,7 @@ /** * Adds this expression's string representation to a StringBuilder. + * @param strb the builder to fill */ abstract void asString(StringBuilder strb); @@ -338,21 +351,26 @@ /** A constant expression. */ private class ConstantExpression extends Expression { + /** The constant held by this expression. */ private final Object value; /** * Creates a constant expression. - * @param value the constant value + * <p> + * If the wrapped constant is a string, it is treated + * as a JEXL strings with respect to escaping. + * </p> + * @param val the constant value * @param source the source expression if any */ - ConstantExpression(Object value, Expression source) { + ConstantExpression(Object val, Expression source) { super(source); - if (value == null) { + if (val == null) { throw new NullPointerException("constant can not be null"); } - if (value instanceof String) { - value = StringParser.buildString((String) value, false); + if (val instanceof String) { + val = StringParser.buildString((String) val, false); } - this.value = value; + this.value = val; } @Override @@ -409,7 +427,9 @@ /** The base for Jexl based expressions. */ private abstract class JexlBasedExpression extends Expression { + /** The JEXL string for this expression. */ protected final CharSequence expr; + /** The JEXL node for this expression. */ protected final SimpleNode node; /** * Creates a JEXL interpretable expression. @@ -566,21 +586,21 @@ /** A composite expression: "... ${...} ... #{...} ...". */ private class CompositeExpression extends Expression { - // bit encoded (deferred count > 0) bit 1, (immediate count > 0) bit 0 + /** Bit encoded (deferred count > 0) bit 1, (immediate count > 0) bit 0. */ private final int meta; - // the list of expression resulting from parsing + /** The list of sub-expression resulting from parsing. */ private final Expression[] exprs; /** * Creates a composite expression. - * @param counts counters of expression per type - * @param exprs the sub-expressions - * @param source the source for this expresion if any - */ - CompositeExpression(int[] counts, ArrayList<Expression> exprs, Expression source) { - super(source); - this.exprs = exprs.toArray(new Expression[exprs.size()]); - this.meta = (counts[ExpressionType.DEFERRED.index] > 0 ? 2 : 0) | - (counts[ExpressionType.IMMEDIATE.index] > 0 ? 1 : 0); + * @param counter counters of expression per type + * @param list the sub-expressions + * @param src the source for this expresion if any + */ + CompositeExpression(int[] counters, ArrayList<Expression> list, Expression src) { + super(src); + this.exprs = list.toArray(new Expression[list.size()]); + this.meta = (counters[ExpressionType.DEFERRED.index] > 0 ? 2 : 0) + | (counters[ExpressionType.IMMEDIATE.index] > 0 ? 1 : 0); } @Override @@ -794,19 +814,24 @@ /** The different parsing states. */ private static enum ParseState { - CONST, // parsing a constant string - IMMEDIATE0, // seen $ - DEFERRED0, // seen # - IMMEDIATE1, // seen ${ - DEFERRED1, // seen #{ - ESCAPE // seen \ + /** Parsing a constant. */ + CONST, + /** Parsing after $ .*/ + IMMEDIATE0, + /** Parsing after # .*/ + DEFERRED0, + /** Parsing afer ${ . */ + IMMEDIATE1, + /** Parsing afer #{ . */ + DEFERRED1, + /** Parsing afer \ . */ + ESCAPE } /** * Parses a unified expression. - * @param expr the expression - * @param counts the expression type counters - * @return the list of expressions + * @param expr the string expression + * @return the expression instance * @throws Exception */ private Expression parseExpression(String expr) throws ParseException { Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/AbstractExecutor.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/AbstractExecutor.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/AbstractExecutor.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/AbstractExecutor.java Sun Jul 19 02:28:24 2009 @@ -16,16 +16,13 @@ */ package org.apache.commons.jexl.util; - - import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import org.apache.commons.logging.Log; /** * Abstract class that is used to execute an arbitrary - * method that is in introspected. This is the superclass + * method that is introspected. This is the superclass * for the GetExecutor and PropertyExecutor. * * @since 1.0 @@ -34,14 +31,21 @@ * @version $Id$ */ public abstract class AbstractExecutor { - /** The executor instance log. */ - protected Log rlog = null; - + /** Empty parameters list for method matching. */ + protected static final Object[] EMPTY_PARAMS = {}; /** * Method to be executed. */ - protected Method method = null; - + protected final Method method; + + /** + * Default and sole constructor. + * @param theMethod the method held by this executor + */ + protected AbstractExecutor(Method theMethod) { + method = theMethod; + } + /** * Execute method against context. * @@ -50,8 +54,11 @@ * @throws IllegalAccessException Method is inaccessible. * @throws InvocationTargetException Method body throws an exception. */ - public abstract Object execute(Object o) - throws IllegalAccessException, InvocationTargetException; + public Object execute(Object o) + throws IllegalAccessException, InvocationTargetException { + return method == null? null : method.invoke(o, (Object[]) null); + } + /** * Tell whether the executor is alive by looking @@ -59,16 +66,15 @@ * * @return boolean Whether the executor is alive. */ - public boolean isAlive() { + public final boolean isAlive() { return (method != null); } /** - * Get the method to be executed. - * + * Gets the method to be executed. * @return Method The method to be executed. */ - public Method getMethod() { + public final Method getMethod() { return method; } -} + } \ No newline at end of file Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java Sun Jul 19 02:28:24 2009 @@ -17,6 +17,9 @@ package org.apache.commons.jexl.util; +import java.lang.reflect.Method; +import org.apache.commons.jexl.util.introspection.Introspector; + import org.apache.commons.logging.Log; /** * Handles discovery and valuation of a @@ -32,73 +35,64 @@ * @author <a href="ge...@apache.org">Geir Magnusson Jr.</a> * @version $Id$ */ -public class BooleanPropertyExecutor extends PropertyExecutor { - +public class BooleanPropertyExecutor extends AbstractExecutor { + /** index of the first character of the property. */ + private static final int PROPERTY_START_INDEX = 2; /** * Constructor. * - * @param rlog The instance log. + * @param rlog The logger. * @param is The JEXL introspector. * @param clazz The class being analyzed. * @param property The boolean property. */ - public BooleanPropertyExecutor(Log rlog, - org.apache.commons.jexl.util.introspection.Introspector is, - Class<?> clazz, String property) { - super(rlog, is, clazz, property); + public BooleanPropertyExecutor(final Log rlog, Introspector is, Class<?> clazz, String property) { + super(discover(rlog, is, clazz, property)); } /** - * Locate the getter method for this boolean property. + * Finds the method for a BooleanPropertyExecutor. * + * @param rlog The logger. + * @param is The JEXL introspector. * @param clazz The class being analyzed. - * @param property Name of boolean property. + * @param property The boolean property. + * @return The method. */ - @Override - protected void discover(Class<?> clazz, String property) { + private static Method discover(final Log rlog, Introspector is, Class<?> clazz, String property) { + String mname = null; + Method m = null; try { char c; - /* - * now look for a boolean isFoo - */ - + // now look for a boolean isFoo StringBuilder sb = new StringBuilder("is"); sb.append(property); - methodUsed = sb.toString(); - method = introspector.getMethod(clazz, methodUsed, EMPTY_PARAMS); - - if (null == method) { - c = sb.charAt(2); - + mname = sb.toString(); + m = is.getMethod(clazz, mname, EMPTY_PARAMS); + if (null == m) { + //now the convenience, flip the 1st character + c = sb.charAt(PROPERTY_START_INDEX); if (Character.isLowerCase(c)) { - sb.setCharAt(2, Character.toUpperCase(c)); + sb.setCharAt(PROPERTY_START_INDEX, Character.toUpperCase(c)); } else { - sb.setCharAt(2, Character.toLowerCase(c)); + sb.setCharAt(PROPERTY_START_INDEX, Character.toLowerCase(c)); } - methodUsed = sb.toString(); - method = introspector.getMethod(clazz, methodUsed, EMPTY_PARAMS); + mname = sb.toString(); + m = is.getMethod(clazz, mname, EMPTY_PARAMS); } - if (method != null) { - /* - * now, this has to return a boolean - */ - - if (method.getReturnType() == Boolean.TYPE) { - return; - } - - method = null; + // now, this has to return a boolean + if (m != null && m.getReturnType() != Boolean.TYPE) { + m = null; } - /** - * pass through application level runtime exceptions - */ + // pass through application level runtime exceptions } catch (RuntimeException e) { throw e; } catch (Exception e) { rlog.error("PROGRAMMER ERROR : BooleanPropertyExector()", e); } + return m; } } \ No newline at end of file Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/GetExecutor.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/GetExecutor.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/GetExecutor.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/GetExecutor.java Sun Jul 19 02:28:24 2009 @@ -17,7 +17,7 @@ package org.apache.commons.jexl.util; -import java.lang.reflect.InvocationTargetException; +import org.apache.commons.jexl.util.introspection.Introspector; import org.apache.commons.logging.Log; @@ -38,34 +38,27 @@ * Container to hold the 'key' part of * get(key). */ - private final Object[] args = new Object[1]; - + private final Object[] args; + + /** + * Creates an arguments array. + * @param key the key to use as argument + * @return the arguments array + */ + private static Object[] makeArgs(String key) { + return new Object[]{key}; + } /** * Default constructor. * - * @param r The instance log. + * @param rlog The logger. * @param ispect The JEXL introspector. * @param c The class being examined. * @param key The key for the get(key) operation. */ - public GetExecutor(Log r, - org.apache.commons.jexl.util.introspection.Introspector ispect, - Class<?> c, String key) { - rlog = r; - args[0] = key; - method = ispect.getMethod(c, "get", args); - } - - /** - * {...@inheritdoc} - */ - public Object execute(Object o) - throws IllegalAccessException, InvocationTargetException { - if (method == null) { - return null; - } - - return method.invoke(o, args); + public GetExecutor(final Log rlog, Introspector ispect, Class<?> c, String key) { + super(ispect.getMethod(c, "get", makeArgs(key))); + args = makeArgs(key); } -} +} \ No newline at end of file Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java Sun Jul 19 02:28:24 2009 @@ -18,6 +18,7 @@ package org.apache.commons.jexl.util; import java.util.Map; +import java.lang.reflect.Method; import org.apache.commons.logging.Log; @@ -30,51 +31,56 @@ * @version $Id$ */ public class MapGetExecutor extends AbstractExecutor { + /** A one argument signature to find method. */ + private static final Class<?>[] OBJECT_PARM = new Class<?>[]{Object.class}; /** the property to get. */ private final String property; /** - * Create the instance. - * @param rlog the logger. + * Creates the instance. + * @param rlog The logger. * @param clazz the class to execute the get on. * @param aProperty the property or key to get. */ public MapGetExecutor(final Log rlog, final Class<?> clazz, final String aProperty) { - this.rlog = rlog; + super(aProperty != null? discover(rlog, clazz, aProperty) : null); this.property = aProperty; - discover(clazz); } /** - * Discover the method to call. - * @param clazz the class to find the method on. + * Finds the method for a MapGetExecutor. + * + * @param rlog The logger. + * @param clazz The class being analyzed. + * @param property The boolean property. + * @return The method. */ - protected void discover(final Class<?> clazz) { + private static Method discover(final Log rlog, final Class<?> clazz, final String property) { + Method m = null; Class<?>[] interfaces = clazz.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { if (interfaces[i].equals(Map.class)) { try { - if (property != null) { - method = Map.class.getMethod("get", new Class<?>[]{Object.class}); - } - /** - * pass through application level runtime exceptions - */ + m = Map.class.getMethod("get", OBJECT_PARM); + // pass through application level runtime exceptions } catch (RuntimeException e) { throw e; } catch (Exception e) { - rlog.error("While looking for get('" + property + "') method:", e); + rlog.error("While looking for get('" + property + "') method:", e); } break; } } + return m; } + /** * Get the property from the map. * @param o the map. * @return o.get(property) */ + @Override public Object execute(final Object o) { return ((Map<String,?>) o).get(property); } Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java Sun Jul 19 02:28:24 2009 @@ -16,8 +16,7 @@ */ package org.apache.commons.jexl.util; -import java.lang.reflect.InvocationTargetException; - +import java.lang.reflect.Method; import org.apache.commons.jexl.util.introspection.Introspector; import org.apache.commons.logging.Log; @@ -26,99 +25,62 @@ * @since 1.0 */ public class PropertyExecutor extends AbstractExecutor { - /* Empty param list. */ - protected static final Object[] EMPTY_PARAMS = {}; /** index of the first character of the property. */ private static final int PROPERTY_START_INDEX = 3; - /** The JEXL introspector used. */ - protected Introspector introspector = null; - - /** The method used. */ - protected String methodUsed = null; - /** * Constructor. * - * @param r The log for this property executor instance. - * @param ispctr The JEXL introspector. + * @param rlog The logger. + * @param is The JEXL introspector. * @param clazz The class being examined. * @param property The property being addressed. */ - public PropertyExecutor(Log r, Introspector ispctr, - Class<?> clazz, String property) { - rlog = r; - introspector = ispctr; - - discover(clazz, property); + public PropertyExecutor(final Log rlog, Introspector is, Class<?> clazz, String property) { + super(discover(rlog, is, clazz, property)); } + /** - * Locate the getter method for this property. + * Finds the method to create a PropertyExecutor. * - * @param clazz The class being analyzed. - * @param property Name of the property. + * @param rlog The logger. + * @param is The JEXL introspector. + * @param clazz The class being examined. + * @param property The property being addressed. + * @return The method. */ - protected void discover(Class<?> clazz, String property) { - /* - * this is gross and linear, but it keeps it straightforward. - */ - + private static Method discover(final Log rlog, Introspector is, Class<?> clazz, String property) { + // this is gross and linear, but it keeps it straightforward. + String mname = null; + Method m = null; try { - char c; - /* - * start with get<property> - * this leaves the property name - * as is... - */ + // start with get<property>, this leaves the property name as is... StringBuilder sb = new StringBuilder("get"); sb.append(property); - methodUsed = sb.toString(); + mname = sb.toString(); + m = is.getMethod(clazz, mname, EMPTY_PARAMS); + if (m == null) { + //now the convenience, flip the 1st character + char c = sb.charAt(PROPERTY_START_INDEX); + if (Character.isLowerCase(c)) { + sb.setCharAt(PROPERTY_START_INDEX, Character.toUpperCase(c)); + } else { + sb.setCharAt(PROPERTY_START_INDEX, Character.toLowerCase(c)); + } - method = introspector.getMethod(clazz, methodUsed, EMPTY_PARAMS); - - if (method != null) { - return; + mname = sb.toString(); + m = is.getMethod(clazz, mname, EMPTY_PARAMS); } - /* - * now the convenience, flip the 1st character - */ - - c = sb.charAt(PROPERTY_START_INDEX); - - if (Character.isLowerCase(c)) { - sb.setCharAt(PROPERTY_START_INDEX, Character.toUpperCase(c)); - } else { - sb.setCharAt(PROPERTY_START_INDEX, Character.toLowerCase(c)); - } - - methodUsed = sb.toString(); - method = introspector.getMethod(clazz, methodUsed, EMPTY_PARAMS); - - if (method != null) { - return; - } /** * pass through application level runtime exceptions */ } catch (RuntimeException e) { throw e; } catch (Exception e) { - rlog.error("PROGRAMMER ERROR : PropertyExector() : ", e); - } - } - - - /** - * {...@inheritdoc} - */ - public Object execute(Object o) - throws IllegalAccessException, InvocationTargetException { - if (method == null) { - return null; + rlog.error("PROGRAMMER ERROR : PropertyExecutor() : ", e); } - - return method.invoke(o, (Object[])null); + return m; } -} +} \ No newline at end of file Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java Sun Jul 19 02:28:24 2009 @@ -164,7 +164,7 @@ * </p> * @version $Id$ */ - static class MethodCache { + static final class MethodCache { /** * A method that returns itself used as a marker for cache miss, * allows the underlying cache map to be strongly typed. @@ -173,10 +173,10 @@ public static Method cacheMiss() { try { return MethodCache.class.getMethod("cacheMiss"); - } // this really cant make an error... - catch (Exception xio) { + } catch (Exception xio) { + // this really cant make an error... + return null; } - return null; } /** The cache miss marker method. */ private static final Method CACHE_MISS = cacheMiss(); @@ -203,20 +203,25 @@ * introspection for methods with primitive types will work * correctly. * </p> + * @param parm a may-be primitive type class + * @return the equivalent object class */ - static final Class<?> primitiveClass(Class<?> parm) { + static Class<?> primitiveClass(Class<?> parm) { // it is marginally faster to get from the map than call isPrimitive... //if (!parm.isPrimitive()) return parm; Class<?> prim = PRIMITIVE_TYPES.get(parm); return prim == null ? parm : prim; } /** + * The method cache. + * <p> * Cache of Methods, or CACHE_MISS, keyed by method * name and actual arguments used to find it. + * </p> */ private final Map<MethodKey, Method> cache = new HashMap<MethodKey, Method>(); /** - * Map of methods that are searchable according to method parameters to find a match + * Map of methods that are searchable according to method parameters to find a match. */ private final MethodMap methodMap = new MethodMap(); @@ -246,7 +251,7 @@ * Finds a Method using a MethodKey. * @param methodKey the method key * @return a method - * @throws org.apache.commons.jexl.util.introspection.MethodMap.AmbiguousException + * @throws MethodMap.AmbiguousException if method resolution is ambiguous */ Method get(final MethodKey methodKey) throws MethodMap.AmbiguousException { @@ -323,28 +328,29 @@ * (array of class). * Roughly 3x faster than string key to access the map & uses less memory. */ - static class MethodKey { + static final class MethodKey { /** The hash code. */ private final int hashCode; /** The method name. */ - final String method; + private final String method; /** The parameters. */ - final Class<?>[] params; + private final Class<?>[] params; /** A marker for empty parameter list. */ private static final Class<?>[] NOARGS = new Class<?>[0]; /** The hash code constants. */ private static final int HASH = 37; - /** Builds a MethodKey from a method. + /** Creates a MethodKey from a method. * Used to store information in the method map. + * @param aMethod the method to build the key from */ - MethodKey(Method method) { - this(method.getName(), method.getParameterTypes()); + MethodKey(Method aMethod) { + this(aMethod.getName(), aMethod.getParameterTypes()); } /** Creates a MethodKey from a method name and a set of arguments (objects). * Used to query the method map. - * @param method the method name + * @param aMethod the method name * @param args the arguments instances to match the method signature */ MethodKey(String aMethod, Object[] args) { @@ -352,7 +358,9 @@ this.method = aMethod; int hash = this.method.hashCode(); final int size; + // CSOFF: InnerAssignment if (args != null && (size = args.length) > 0) { + // CSON: InnerAssignment this.params = new Class<?>[size]; for (int p = 0; p < size; ++p) { // ctor(Object) : { @@ -371,7 +379,7 @@ /** Creates a MethodKey from a method name and a set of parameters (classes). * Used to store information in the method map. ( @see MethodKey#primitiveClass ) - * @param method the method name + * @param aMethod the method name * @param args the argument classes to match the method signature */ MethodKey(String aMethod, Class<?>[] args) { @@ -379,7 +387,9 @@ this.method = aMethod; int hash = this.method.hashCode(); final int size; + // CSOFF: InnerAssignment if (args != null && (size = args.length) > 0) { + // CSON: InnerAssignment this.params = new Class<?>[size]; for (int p = 0; p < size; ++p) { // ctor(Class): { @@ -394,6 +404,22 @@ this.hashCode = hash; } + /** + * Gets this key's method name. + * @return the method name + */ + String getMethod() { + return method; + } + + /** + * Gets this key's method parameter classes. + * @return the parameters + */ + Class<?>[] getParameters() { + return params; + } + @Override public int hashCode() { return hashCode; Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java Sun Jul 19 02:28:24 2009 @@ -89,24 +89,17 @@ */ @Override public Method getMethod(Class<?> c, String name, Object[] params) throws IllegalArgumentException { - /* - * just delegate to the base class - */ - + // just delegate to the base class try { return super.getMethod(c, name, params); - } - catch (MethodMap.AmbiguousException ae) { - /* - * whoops. Ambiguous. Make a nice log message and return null... - */ + } catch (MethodMap.AmbiguousException ae) { + // whoops. Ambiguous. Make a nice log message and return null... StringBuilder msg = new StringBuilder("Introspection Error : Ambiguous method invocation "); msg.append(name).append("( "); for (int i = 0; i < params.length; i++) { if (i > 0) { msg.append(", "); } - msg.append(null == params[i] ? "null" : params[i].getClass().getName()); } msg.append(") for class ").append(c.getName()); @@ -114,7 +107,6 @@ rlog.error(msg.toString()); } } - return null; } // CSON: RedundantThrows Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java Sun Jul 19 02:28:24 2009 @@ -122,6 +122,7 @@ /** * Gets the ClassMap for a given class. + * @param c the class * @return the class map */ private ClassMap getMap(Class<?> c) { Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java Sun Jul 19 02:28:24 2009 @@ -133,11 +133,11 @@ * @throws AmbiguousException if find is ambiguous */ Method find(ClassMap.MethodKey methodKey) throws AmbiguousException { - List<Method> methodList = get(methodKey.method); + List<Method> methodList = get(methodKey.getMethod()); if (methodList == null) { return null; } - return getMostSpecific(methodList, methodKey.params); + return getMostSpecific(methodList, methodKey.getParameters()); } // CSON: RedundantThrows Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java (original) +++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java Sun Jul 19 02:28:24 2009 @@ -36,7 +36,7 @@ /** Gets underlying introspector. * @return the introspector */ - public Introspector getIntrospector(); + Introspector getIntrospector(); /** * To support iteratives - #foreach(). Modified: commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/util/introspection/MethodKeyTest.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/util/introspection/MethodKeyTest.java?rev=795463&r1=795462&r2=795463&view=diff ============================================================================== --- commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/util/introspection/MethodKeyTest.java (original) +++ commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/util/introspection/MethodKeyTest.java Sun Jul 19 02:28:24 2009 @@ -143,7 +143,7 @@ public void testObjectKey() throws Exception { for(int k = 0; k < keyList.length; ++k) { ClassMap.MethodKey ctl = keyList[k]; - ClassMap.MethodKey key = makeKey(ctl.method, ctl.params); + ClassMap.MethodKey key = makeKey(ctl.getMethod(), ctl.getParameters()); String out = byKey.get(key); assertTrue(out != null); assertTrue(ctl.toString() + " != " + out, ctl.toString().equals(out)); @@ -154,7 +154,7 @@ public void testStringKey() throws Exception { for(int k = 0; k < keyList.length; ++k) { ClassMap.MethodKey ctl = keyList[k]; - String key = makeStringKey(ctl.method, ctl.params); + String key = makeStringKey(ctl.getMethod(), ctl.getParameters()); ClassMap.MethodKey out = byString.get(key); assertTrue(out != null); assertTrue(ctl.toString() + " != " + key, ctl.equals(out)); @@ -168,7 +168,7 @@ for(int l = 0; l < LOOP; ++l) for(int k = 0; k < keyList.length; ++k) { ClassMap.MethodKey ctl = keyList[k]; - ClassMap.MethodKey key = makeKey(ctl.method, ctl.params); + ClassMap.MethodKey key = makeKey(ctl.getMethod(), ctl.getParameters()); String out = byKey.get(key); assertTrue(out != null); } @@ -178,7 +178,7 @@ for(int l = 0; l < LOOP; ++l) for(int k = 0; k < keyList.length; ++k) { ClassMap.MethodKey ctl = keyList[k]; - String key = makeStringKey(ctl.method, ctl.params); + String key = makeStringKey(ctl.getMethod(), ctl.getParameters()); ClassMap.MethodKey out = byString.get(key); assertTrue(out != null); } @@ -215,4 +215,4 @@ } } } -} +} \ No newline at end of file