You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2013/11/25 14:35:57 UTC
svn commit: r1545274 [2/3] - in /commons/proper/jexl/trunk/src:
main/java/org/apache/commons/jexl3/
main/java/org/apache/commons/jexl3/internal/
main/java/org/apache/commons/jexl3/internal/introspection/
main/java/org/apache/commons/jexl3/introspection...
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ListGetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ListGetExecutor.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ListGetExecutor.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ListGetExecutor.java Mon Nov 25 13:35:55 2013
@@ -35,34 +35,33 @@ public final class ListGetExecutor exten
/**
* Attempts to discover a ListGetExecutor.
- *
+ *
* @param is the introspector
* @param clazz the class to find the get method from
- * @param identifier the key to use as an argument to the get method
+ * @param index the index to use as an argument to the get method
* @return the executor if found, null otherwise
*/
- public static ListGetExecutor discover(Introspector is, Class<?> clazz, Object identifier) {
- java.lang.reflect.Method method = null;
- Integer index = toInteger(identifier);
+ public static ListGetExecutor discover(Introspector is, Class<?> clazz, Integer index) {
if (index != null) {
if (clazz.isArray()) {
- method = ARRAY_GET;
- } else if (List.class.isAssignableFrom(clazz)) {
- method = LIST_GET;
+ return new ListGetExecutor(clazz, ARRAY_GET, index);
+ }
+ if (List.class.isAssignableFrom(clazz)) {
+ return new ListGetExecutor(clazz, LIST_GET, index);
}
}
- return method == null ? null : new ListGetExecutor(clazz, method, index);
+ return null;
}
/**
* Creates an instance.
* @param clazz he class the get method applies to
* @param method the method held by this executor
- * @param identifier the property to get
+ * @param index the index to use as an argument to the get method
*/
- private ListGetExecutor(Class<?> clazz, java.lang.reflect.Method method, Integer identifier) {
+ private ListGetExecutor(Class<?> clazz, java.lang.reflect.Method method, Integer index) {
super(clazz, method);
- property = identifier;
+ property = index;
}
@Override
@@ -80,8 +79,8 @@ public final class ListGetExecutor exten
}
@Override
- public Object tryInvoke(final Object obj, Object key) {
- Integer index = toInteger(key);
+ public Object tryInvoke(final Object obj, Object identifier) {
+ Integer index = castInteger(identifier);
if (obj != null && method != null
&& objectClass.equals(obj.getClass())
&& index != null) {
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ListSetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ListSetExecutor.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ListSetExecutor.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ListSetExecutor.java Mon Nov 25 13:35:55 2013
@@ -35,7 +35,7 @@ public final class ListSetExecutor exten
/**
* Attempts to discover a ListSetExecutor.
- *
+ *
* @param is the introspector
* @param clazz the class to find the get method from
* @param identifier the key to use as an argument to the get method
@@ -43,8 +43,7 @@ public final class ListSetExecutor exten
* @return the executor if found, null otherwise
*/
public static ListSetExecutor discover(Introspector is, Class<?> clazz, Object identifier, Object value) {
- Integer index = toInteger(identifier);
- java.lang.reflect.Method method = null;
+ Integer index = castInteger(identifier);
if (index != null) {
if (clazz.isArray()) {
// we could verify if the call can be performed but it does not change
@@ -52,18 +51,19 @@ public final class ListSetExecutor exten
// Class<?> formal = clazz.getComponentType();
// Class<?> actual = value == null? Object.class : value.getClass();
// if (IntrospectionUtils.isMethodInvocationConvertible(formal, actual, false)) {
- method = ARRAY_SET;
+ return new ListSetExecutor(clazz, ARRAY_SET, index);
// }
- } else if (List.class.isAssignableFrom(clazz)) {
- method = LIST_SET;
+ }
+ if (List.class.isAssignableFrom(clazz)) {
+ return new ListSetExecutor(clazz, LIST_SET, index);
}
}
- return method == null ? null : new ListSetExecutor(clazz, method, index);
+ return null;
}
/**
* Creates an instance.
- *
+ *
* @param clazz the class the set method applies to
* @param method the method called through this executor
* @param key the key to use as 1st argument to the set method
@@ -92,7 +92,7 @@ public final class ListSetExecutor exten
@Override
public Object tryInvoke(final Object obj, Object key, Object value) {
- Integer index = toInteger(key);
+ Integer index = castInteger(key);
if (obj != null && method != null
&& objectClass.equals(obj.getClass())
&& index != null) {
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MapGetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MapGetExecutor.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MapGetExecutor.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MapGetExecutor.java Mon Nov 25 13:35:55 2013
@@ -32,7 +32,7 @@ public final class MapGetExecutor extend
/**
* Attempts to discover a MapGetExecutor.
- *
+ *
* @param is the introspector
* @param clazz the class to find the get method from
* @param identifier the key to use as an argument to the get method
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MapSetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MapSetExecutor.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MapSetExecutor.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MapSetExecutor.java Mon Nov 25 13:35:55 2013
@@ -31,7 +31,7 @@ public final class MapSetExecutor extend
/**
* Attempts to discover a MapSetExecutor.
- *
+ *
* @param is the introspector
* @param clazz the class to find the set method from
* @param identifier the key to use as an argument to the get method
@@ -45,7 +45,7 @@ public final class MapSetExecutor extend
return null;
}
}
-
+
/**
* Creates an instance.
* @param clazz the class the set method applies to
@@ -61,7 +61,7 @@ public final class MapSetExecutor extend
public Object getTargetProperty() {
return property;
}
-
+
@Override
public Object invoke(final Object obj, Object value) throws IllegalAccessException, InvocationTargetException {
@SuppressWarnings("unchecked") // ctor only allows Map instances - see discover() method
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodExecutor.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodExecutor.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodExecutor.java Mon Nov 25 13:35:55 2013
@@ -24,9 +24,10 @@ import java.lang.reflect.InvocationTarge
* @since 2.0
*/
public final class MethodExecutor extends AbstractExecutor.Method {
- /** Whether this method handles varargs. */
- private final boolean isVarArgs;
-
+ /** If this method is a vararg method, vaStart is the last argument index. */
+ private final int vaStart;
+ /** If this method is a vararg method, vaClass is the component type of the vararg array. */
+ private final Class<?> vaClass;
/**
* Discovers a {@link MethodExecutor}.
@@ -66,18 +67,24 @@ public final class MethodExecutor extend
*/
private MethodExecutor(Class<?> c, java.lang.reflect.Method m, MethodKey k) {
super(c, m, k);
- isVarArgs = method != null && isVarArgMethod(method);
+ int vastart = -1;
+ Class<?> vaclass = null;
+ if (method != null) {
+ Class<?>[] formal = method.getParameterTypes();
+ // if the last parameter is an array, the method is considered as vararg
+ if (formal != null && method.isVarArgs()) {
+ vastart = formal.length - 1;
+ vaclass = formal[vastart].getComponentType();
+ }
+ }
+ vaStart = vastart;
+ vaClass = vaclass;
}
@Override
public Object invoke(Object o, Object[] args) throws IllegalAccessException, InvocationTargetException {
- if (isVarArgs) {
- Class<?>[] formal = method.getParameterTypes();
- int index = formal.length - 1;
- Class<?> type = formal[index].getComponentType();
- if (args.length >= index) {
- args = handleVarArg(type, index, args);
- }
+ if (vaClass != null) {
+ args = handleVarArg(args);
}
if (method.getDeclaringClass() == ArrayListWrapper.class && o.getClass().isArray()) {
return method.invoke(new ArrayListWrapper(o), args);
@@ -111,62 +118,45 @@ public final class MethodExecutor extend
* @param index The index of the vararg in the method declaration
* (This will always be one less than the number of
* expected arguments.)
- * @param actual The actual parameters being passed to this method
+ * @param actual The actual arguments being passed to this method
* @return The actual parameters adjusted for the varargs in order
* to fit the method declaration.
*/
- private Object[] handleVarArg(Class<?> type, int index, Object[] actual) {
- final int size = actual.length - index;
+ @SuppressWarnings("SuspiciousSystemArraycopy")
+ private Object[] handleVarArg(Object[] actual) {
+ final Class<?> vaclass = vaClass;
+ final int vastart = vaStart;
+ // variable arguments count
+ final int varargc = actual.length - vastart;
// if no values are being passed into the vararg, size == 0
- if (size == 1) {
+ if (varargc == 1) {
// if one non-null value is being passed into the vararg,
// and that arg is not the sole argument and not an array of the expected type,
// make the last arg an array of the expected type
- if (actual[index] != null) {
- Class<?> aclazz = actual[index].getClass();
- if (!aclazz.isArray() || !type.isAssignableFrom(aclazz.getComponentType())) {
+ if (actual[vastart] != null) {
+ Class<?> aclazz = actual[vastart].getClass();
+ if (!aclazz.isArray() || !vaclass.isAssignableFrom(aclazz.getComponentType())) {
// create a 1-length array to hold and replace the last argument
- Object lastActual = Array.newInstance(type, 1);
- Array.set(lastActual, 0, actual[index]);
- actual[index] = lastActual;
+ Object lastActual = Array.newInstance(vaclass, 1);
+ Array.set(lastActual, 0, actual[vastart]);
+ actual[vastart] = lastActual;
}
}
// else, the vararg is null and used as is, considered as T[]
} else {
// if no or multiple values are being passed into the vararg,
// put them in an array of the expected type
- Object lastActual = Array.newInstance(type, size);
- for (int i = 0; i < size; i++) {
- Array.set(lastActual, i, actual[index + i]);
- }
-
+ Object varargs = Array.newInstance(vaclass, varargc);
+ System.arraycopy(actual, vastart, varargs, 0, varargc);
// put all arguments into a new actual array of the appropriate size
- Object[] newActual = new Object[index + 1];
- System.arraycopy(actual, 0, newActual, 0, index);
- newActual[index] = lastActual;
-
+ Object[] newActual = new Object[vastart + 1];
+ System.arraycopy(actual, 0, newActual, 0, vastart);
+ newActual[vastart] = varargs;
// replace the old actual array
actual = newActual;
}
return actual;
}
-
- /**
- * Determines if a method can accept a variable number of arguments.
- * @param m a the method to check
- * @return true if method is vararg, false otherwise
- */
- private static boolean isVarArgMethod(java.lang.reflect.Method m) {
- Class<?>[] formal = m.getParameterTypes();
- if (formal == null || formal.length == 0) {
- return false;
- } else {
- Class<?> last = formal[formal.length - 1];
- // if the last arg is an array, then
- // we consider this a varargs method
- return last.isArray();
- }
- }
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java Mon Nov 25 13:35:55 2013
@@ -49,7 +49,6 @@ public final class MethodKey {
private static final int PRIMITIVE_SIZE = 13;
/** The primitive type to class conversion map. */
private static final Map<Class<?>, Class<?>> PRIMITIVE_TYPES;
-
static {
PRIMITIVE_TYPES = new HashMap<Class<?>, Class<?>>(PRIMITIVE_SIZE);
PRIMITIVE_TYPES.put(Boolean.TYPE, Boolean.class);
@@ -78,7 +77,6 @@ public final class MethodKey {
Class<?> prim = PRIMITIVE_TYPES.get(parm);
return prim == null ? parm : prim;
}
-
/** The hash code. */
private final int hashCode;
/** The method name. */
@@ -93,7 +91,7 @@ public final class MethodKey {
/**
* Creates a key from a method name and a set of arguments.
* @param aMethod the method to generate the key from
- * @param args the intended method arguments
+ * @param args the intended method arguments
*/
public MethodKey(String aMethod, Object[] args) {
super();
@@ -136,7 +134,7 @@ public final class MethodKey {
/**
* Creates a key from a method name and a set of parameters.
* @param aMethod the method to generate the key from
- * @param args the intended method parameters
+ * @param args the intended method parameters
*/
MethodKey(String aMethod, Class<?>[] args) {
super();
@@ -257,9 +255,7 @@ public final class MethodKey {
* type or an object type of a primitive type that can be converted to
* the formal type.
*/
- public static boolean isInvocationConvertible(Class<?> formal,
- Class<?> actual,
- boolean possibleVarArg) {
+ public static boolean isInvocationConvertible(Class<?> formal, Class<?> actual, boolean possibleVarArg) {
/* if it's a null, it means the arg was null */
if (actual == null && !formal.isPrimitive()) {
return true;
@@ -270,6 +266,11 @@ public final class MethodKey {
return true;
}
+ /** Catch all... */
+ if (formal == Object.class) {
+ return true;
+ }
+
/* Check for boxing with widening primitive conversion. Note that
* actual parameters are never primitives. */
if (formal.isPrimitive()) {
@@ -315,8 +316,7 @@ public final class MethodKey {
if (actual != null && actual.isArray()) {
actual = actual.getComponentType();
}
- return isInvocationConvertible(formal.getComponentType(),
- actual, false);
+ return isInvocationConvertible(formal.getComponentType(), actual, false);
}
return false;
}
@@ -337,16 +337,14 @@ public final class MethodKey {
* or formal and actual are both primitive types and actual can be
* subject to widening conversion to formal.
*/
- public static boolean isStrictInvocationConvertible(Class<?> formal,
- Class<?> actual,
- boolean possibleVarArg) {
+ public static boolean isStrictInvocationConvertible(Class<?> formal, Class<?> actual, boolean possibleVarArg) {
/* we shouldn't get a null into, but if so */
if (actual == null && !formal.isPrimitive()) {
return true;
}
/* Check for identity or widening reference conversion */
- if (formal.isAssignableFrom(actual)) {
+ if (formal.isAssignableFrom(actual) && (formal.isArray() == actual.isArray())) {
return true;
}
@@ -382,8 +380,7 @@ public final class MethodKey {
if (actual != null && actual.isArray()) {
actual = actual.getComponentType();
}
- return isStrictInvocationConvertible(formal.getComponentType(),
- actual, false);
+ return isStrictInvocationConvertible(formal.getComponentType(), actual, false);
}
return false;
}
@@ -402,7 +399,7 @@ public final class MethodKey {
/**
* Simple distinguishable exception, used when
- * we run across ambiguous overloading. Caught
+ * we run across ambiguous overloading. Caught
* by the introspector.
*/
public static class AmbiguousException extends RuntimeException {
@@ -424,6 +421,8 @@ public final class MethodKey {
*/
protected abstract Class<?>[] getParameterTypes(T app);
+ protected abstract boolean isVarArgs(T app);
+
// CSOFF: RedundantThrows
/**
* Gets the most specific method that is applicable to actual argument types.<p>
@@ -580,7 +579,7 @@ public final class MethodKey {
/**
* Checks whether a parameter class is a primitive.
* @param c the parameter class
- * @param possibleVararg true if this is the last parameter which can tbe be a primitive array (vararg call)
+ * @param possibleVararg true if this is the last parameter which can be a primitive array (vararg call)
* @return true if primitive, false otherwise
*/
private boolean isPrimitive(Class<?> c, boolean possibleVarArg) {
@@ -610,7 +609,6 @@ public final class MethodKey {
if (isApplicable(method, classes)) {
list.add(method);
}
-
}
return list;
}
@@ -623,48 +621,62 @@ public final class MethodKey {
* @param classes arguments to method
* @return true if method is applicable to arguments
*/
- private boolean isApplicable(T method, Class<?>[] classes) {
- Class<?>[] methodArgs = getParameterTypes(method);
- // if samee number or args or
+ private boolean isApplicable(T method, Class<?>[] actuals) {
+ Class<?>[] formals = getParameterTypes(method);
+ // if same number or args or
// there's just one more methodArg than class arg
// and the last methodArg is an array, then treat it as a vararg
- if (methodArgs.length == classes.length
- || ((methodArgs.length == classes.length + 1) && methodArgs[methodArgs.length - 1].isArray())) {
+ if (formals.length == actuals.length) {
// this will properly match when the last methodArg
// is an array/varargs and the last class is the type of array
// (e.g. String when the method is expecting String...)
- for (int i = 0; i < classes.length; ++i) {
- if (!isConvertible(methodArgs[i], classes[i], false)) {
+ for (int i = 0; i < actuals.length; ++i) {
+ if (!isConvertible(formals[i], actuals[i], false)) {
// if we're on the last arg and the method expects an array
- if (i == classes.length - 1 && methodArgs[i].isArray()) {
+ if (i == actuals.length - 1 && formals[i].isArray()) {
// check to see if the last arg is convertible
// to the array's component type
- return isConvertible(methodArgs[i], classes[i], true);
+ return isConvertible(formals[i], actuals[i], true);
}
return false;
}
}
return true;
}
- // more arguments given than the method accepts; check for varargs
- if (methodArgs.length > 0 && classes.length > 0) {
- // check that the last methodArg is an array
- Class<?> lastarg = methodArgs[methodArgs.length - 1];
- if (!lastarg.isArray()) {
+
+ // number of formal and actual differ, method must be vararg
+ if (!isVarArgs(method)) {
+ return false;
+ }
+
+ // less arguments than method parameters: vararg is null
+ if (formals.length > actuals.length) {
+ // only one parameter, the last (ie vararg) can be missing
+ if (formals.length - actuals.length > 1) {
return false;
}
+ // check that all present args match up to the method parms
+ for (int i = 0; i < actuals.length; ++i) {
+ if (!isConvertible(formals[i], actuals[i], false)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ // more arguments given than the method accepts; check for varargs
+ if (formals.length > 0 && actuals.length > 0) {
// check that they all match up to the last method arg
- for (int i = 0; i < methodArgs.length - 1; ++i) {
- if (!isConvertible(methodArgs[i], classes[i], false)) {
+ for (int i = 0; i < formals.length - 1; ++i) {
+ if (!isConvertible(formals[i], actuals[i], false)) {
return false;
}
}
-
// check that all remaining arguments are convertible to the vararg type
- Class<?> vararg = lastarg.getComponentType();
- for (int i = methodArgs.length - 1; i < classes.length; ++i) {
- if (!isConvertible(vararg, classes[i], false)) {
+ // (last parm is an array since method is vararg)
+ Class<?> vararg = formals[formals.length - 1].getComponentType();
+ for (int i = formals.length - 1; i < actuals.length; ++i) {
+ if (!isConvertible(vararg, actuals[i], false)) {
return false;
}
}
@@ -697,7 +709,8 @@ public final class MethodKey {
* in the method declaration
* @return see isStrictMethodInvocationConvertible.
*/
- private boolean isStrictConvertible(Class<?> formal, Class<?> actual, boolean possibleVarArg) {
+ private boolean isStrictConvertible(Class<?> formal, Class<?> actual,
+ boolean possibleVarArg) {
// if we see Void.class, the argument was null
return isStrictInvocationConvertible(formal, actual.equals(Void.class) ? null : actual, possibleVarArg);
}
@@ -710,6 +723,10 @@ public final class MethodKey {
protected Class<?>[] getParameterTypes(Method app) {
return app.getParameterTypes();
}
+ @Override
+ public boolean isVarArgs(Method app) {
+ return app.isVarArgs();
+ }
};
/**
* The parameter matching service for constructors.
@@ -719,5 +736,9 @@ public final class MethodKey {
protected Class<?>[] getParameterTypes(Constructor<?> app) {
return app.getParameterTypes();
}
+ @Override
+ public boolean isVarArgs(Constructor<?> app) {
+ return app.isVarArgs();
+ }
};
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/PropertyGetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/PropertyGetExecutor.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/PropertyGetExecutor.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/PropertyGetExecutor.java Mon Nov 25 13:35:55 2013
@@ -27,11 +27,11 @@ public final class PropertyGetExecutor e
private static final Object[] EMPTY_PARAMS = {};
/** The property. */
private final String property;
-
+
/**
* Discovers a PropertyGetExecutor.
* <p>The method to be found should be named "get{P,p}property.</p>
- *
+ *
* @param is the introspector
* @param clazz the class to find the get method from
* @param property the property name to find
@@ -41,7 +41,7 @@ public final class PropertyGetExecutor e
java.lang.reflect.Method method = discoverGet(is, "get", clazz, property);
return method == null? null : new PropertyGetExecutor(clazz, method, property);
}
-
+
/**
* Creates an instance.
* @param clazz he class the get method applies to
@@ -57,7 +57,7 @@ public final class PropertyGetExecutor e
public Object getTargetProperty() {
return property;
}
-
+
@Override
public Object invoke(Object o)
throws IllegalAccessException, InvocationTargetException {
@@ -67,7 +67,7 @@ public final class PropertyGetExecutor e
@Override
public Object tryInvoke(Object o, Object identifier) {
if (o != null && method != null
- && property.equals(toString(identifier))
+ && property.equals(castString(identifier))
&& objectClass.equals(o.getClass())) {
try {
return method.invoke(o, (Object[]) null);
@@ -89,8 +89,11 @@ public final class PropertyGetExecutor e
* @return The {get,is}{p,P}roperty method if one exists, null otherwise.
*/
static java.lang.reflect.Method discoverGet(Introspector is, String which, Class<?> clazz, String property) {
+ if (property == null || property.isEmpty()) {
+ return null;
+ }
// this is gross and linear, but it keeps it straightforward.
- java.lang.reflect.Method method = null;
+ java.lang.reflect.Method method;
final int start = which.length(); // "get" or "is" so 3 or 2 for char case switch
// start with get<Property>
StringBuilder sb = new StringBuilder(which);
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/PropertySetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/PropertySetExecutor.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/PropertySetExecutor.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/PropertySetExecutor.java Mon Nov 25 13:35:55 2013
@@ -14,45 +14,48 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.commons.jexl3.internal.introspection;
+
+import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
/**
* Specialized executor to set a property in an object.
* @since 2.0
*/
-public final class PropertySetExecutor extends AbstractExecutor.Set {
+public class PropertySetExecutor extends AbstractExecutor.Set {
/** Index of the first character of the set{p,P}roperty. */
private static final int SET_START_INDEX = 3;
/** The property. */
- private final String property;
-
+ protected final String property;
+
/**
* Discovers a PropertySetExecutor.
* <p>The method to be found should be named "set{P,p}property.</p>
- *
- * @param is the introspector
- * @param clazz the class to find the get method from
+ *
+ * @param is the introspector
+ * @param clazz the class to find the get method from
* @param property the property name to find
- * @param arg the value to assign to the property
+ * @param arg the value to assign to the property
* @return the executor if found, null otherwise
*/
public static PropertySetExecutor discover(Introspector is, Class<?> clazz, String property, Object arg) {
+ if (property == null || property.isEmpty()) {
+ return null;
+ }
java.lang.reflect.Method method = discoverSet(is, clazz, property, arg);
- return method == null? null : new PropertySetExecutor(clazz, method, property);
+ return method != null? new PropertySetExecutor(clazz, method, property) : null;
}
-
+
/**
* Creates an instance.
- * @param clazz the class the set method applies to
+ * @param clazz the class the set method applies to
* @param method the method called through this executor
- * @param key the key to use as 1st argument to the set method
+ * @param key the key to use as 1st argument to the set method
*/
- private PropertySetExecutor(Class<?> clazz, java.lang.reflect.Method method, String key) {
+ protected PropertySetExecutor(Class<?> clazz, java.lang.reflect.Method method, String key) {
super(clazz, method);
property = key;
-
}
@Override
@@ -62,9 +65,17 @@ public final class PropertySetExecutor e
@Override
public Object invoke(Object o, Object arg) throws IllegalAccessException, InvocationTargetException {
- Object[] pargs = {arg};
if (method != null) {
- method.invoke(o, pargs);
+ // handle the empty array case
+ if (isEmptyArray(arg)) {
+ // if array is empty but its component type is different from the method first parameter component type,
+ // replace argument with a new empty array instance (of the method first parameter component type)
+ Class<?> componentType = method.getParameterTypes()[0].getComponentType();
+ if (componentType != null && !componentType.equals(arg.getClass().getComponentType())) {
+ arg = Array.newInstance(componentType, 0);
+ }
+ }
+ method.invoke(o, arg);
}
return arg;
}
@@ -73,11 +84,9 @@ public final class PropertySetExecutor e
public Object tryInvoke(Object o, Object identifier, Object arg) {
if (o != null && method != null
// ensure method name matches the property name
- && property.equals(toString(identifier))
+ && property.equals(castString(identifier))
// object class should be same as executor's method declaring class
- && objectClass.equals(o.getClass())
- // we are guaranteed the method has one parameter since it is a set(x)
- && (arg == null || method.getParameterTypes()[0].equals(arg.getClass()))) {
+ && objectClass.equals(o.getClass())) {
try {
return invoke(o, arg);
} catch (InvocationTargetException xinvoke) {
@@ -89,15 +98,24 @@ public final class PropertySetExecutor e
return TRY_FAILED;
}
+ /**
+ * Checks wether an argument is an empty array.
+ * @param arg the argument
+ * @return true if <code>arg</code> is an empty array
+ */
+ private static boolean isEmptyArray(Object arg) {
+ return (arg != null && arg.getClass().isArray() && Array.getLength(arg) == 0);
+ }
/**
* Discovers the method for a {@link PropertySet}.
- * <p>The method to be found should be named "set{P,p}property.</p>
- *
- * @param is the introspector
- * @param clazz the class to find the get method from
+ * <p>The method to be found should be named "set{P,p}property.
+ * As a special case, any empty array will try to find a valid array-setting non-ambiguous method.
+ *
+ * @param is the introspector
+ * @param clazz the class to find the get method from
* @param property the name of the property to set
- * @param arg the value to assign to the property
+ * @param arg the value to assign to the property
* @return the method if found, null otherwise
*/
private static java.lang.reflect.Method discoverSet(Introspector is, Class<?> clazz, String property, Object arg) {
@@ -113,8 +131,44 @@ public final class PropertySetExecutor e
if (method == null) {
sb.setCharAt(SET_START_INDEX, Character.toLowerCase(c));
method = is.getMethod(clazz, sb.toString(), params);
+ // uppercase nth char, try array
+ if (method == null && isEmptyArray(arg)) {
+ sb.setCharAt(SET_START_INDEX, Character.toUpperCase(c));
+ method = lookupSetEmptyArray(is, clazz, sb.toString());
+ // lowercase nth char
+ if (method == null) {
+ sb.setCharAt(SET_START_INDEX, Character.toLowerCase(c));
+ method = lookupSetEmptyArray(is, clazz, sb.toString());
+ }
+ }
}
return method;
}
-}
+ /**
+ * Finds an empty array property setter method by <code>methodName</code>.
+ * <p>This checks only one method with that name accepts an array as sole parameter.
+ * @param is the introspector
+ * @param clazz the class to find the get method from
+ * @param methodName the method name to find
+ * @return the sole method that accepts an array as parameter
+ */
+ private static java.lang.reflect.Method lookupSetEmptyArray(Introspector is, final Class<?> clazz, String methodName) {
+ java.lang.reflect.Method candidate = null;
+ java.lang.reflect.Method[] methods = is.getMethods(clazz, methodName);
+ if (methods != null) {
+ for (java.lang.reflect.Method method : methods) {
+ Class<?>[] paramTypes = method.getParameterTypes();
+ if (paramTypes.length == 1 && paramTypes[0].isArray()) {
+ if (candidate != null) {
+ // because the setter method is overloaded for different parameter type,
+ // return null here to report the ambiguity.
+ return null;
+ }
+ candidate = method;
+ }
+ }
+ }
+ return candidate;
+ }
+}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Uberspect.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Uberspect.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Uberspect.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Uberspect.java Mon Nov 25 13:35:55 2013
@@ -21,7 +21,7 @@ import org.apache.commons.jexl3.introspe
import org.apache.commons.jexl3.introspection.JexlPropertySet;
import org.apache.commons.jexl3.introspection.JexlUberspect;
-import org.apache.commons.logging.Log;
+import org.apache.log4j.Logger;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -47,7 +47,7 @@ public class Uberspect implements JexlUb
*/
public static final Object TRY_FAILED = AbstractExecutor.TRY_FAILED;
/** The logger to use for all warnings & errors. */
- protected final Log rlog;
+ protected final Logger rlog;
/** The introspector version. */
private final AtomicInteger version;
/** The soft reference to the introspector currently in use. */
@@ -59,7 +59,7 @@ public class Uberspect implements JexlUb
* Creates a new Uberspect.
* @param runtimeLogger the logger used for all logging needs
*/
- public Uberspect(Log runtimeLogger) {
+ public Uberspect(Logger runtimeLogger) {
rlog = runtimeLogger;
ref = new SoftReference<Introspector>(null);
loader = new SoftReference<ClassLoader>(getClass().getClassLoader());
@@ -120,7 +120,9 @@ public class Uberspect implements JexlUb
}
/**
- * Gets the field named by <code>key</code> for the class <code>c</code>.
+ * Gets the field named by
+ * <code>key</code> for the class
+ * <code>c</code>.
*
* @param c Class in which the field search is taking place
* @param key Name of the field being searched for
@@ -140,29 +142,33 @@ public class Uberspect implements JexlUb
}
/**
- * Gets the method defined by <code>name</code> and
- * <code>params</code> for the Class <code>c</code>.
+ * Gets the method defined by
+ * <code>name</code> and
+ * <code>params</code> for the Class
+ * <code>c</code>.
*
* @param c Class in which the method search is taking place
* @param name Name of the method being searched for
* @param params An array of Objects (not Classes) that describe the
- * the parameters
+ * the parameters
*
* @return a {@link java.lang.reflect.Method}
- * or null if no unambiguous method could be found through introspection.
+ * or null if no unambiguous method could be found through introspection.
*/
public final Method getMethod(Class<?> c, String name, Object[] params) {
return base().getMethod(c, new MethodKey(name, params));
}
/**
- * Gets the method defined by <code>key</code> and for the Class <code>c</code>.
+ * Gets the method defined by
+ * <code>key</code> and for the Class
+ * <code>c</code>.
*
* @param c Class in which the method search is taking place
* @param key MethodKey of the method being searched for
*
* @return a {@link java.lang.reflect.Method}
- * or null if no unambiguous method could be found through introspection.
+ * or null if no unambiguous method could be found through introspection.
*/
public final Method getMethod(Class<?> c, MethodKey key) {
return base().getMethod(c, key);
@@ -195,7 +201,7 @@ public class Uberspect implements JexlUb
@Override
public JexlPropertyGet getPropertyGet(Object obj, Object identifier) {
final Class<?> claz = obj.getClass();
- final String property = AbstractExecutor.toString(identifier);
+ final String property = AbstractExecutor.castString(identifier);
final Introspector is = base();
JexlPropertyGet executor;
// first try for a getFoo() type of property (also getfoo() )
@@ -216,32 +222,38 @@ public class Uberspect implements JexlUb
return executor;
}
// let's see if this is a list or array
- executor = ListGetExecutor.discover(is, claz, identifier);
- if (executor != null) {
- return executor;
- }
- // if that didn't work, look for get(foo)
- executor = DuckGetExecutor.discover(is, claz, identifier);
- if (executor != null) {
- return executor;
- }
- // last, look for get("foo") if we did not try yet
- if (property != null && !(identifier instanceof String)) {
- // if that didn't work, look for get("foo")
- executor = DuckGetExecutor.discover(is, claz, property);
+ Integer index = AbstractExecutor.castInteger(identifier);
+ if (index != null) {
+ executor = ListGetExecutor.discover(is, claz, index);
if (executor != null) {
return executor;
}
}
- // a field may be?
- executor = FieldGetExecutor.discover(is, claz, property);
+ // if that didn't work, look for get(foo)
+ executor = DuckGetExecutor.discover(is, claz, identifier);
if (executor != null) {
return executor;
}
- // or an indexed property?
- executor = IndexedType.discover(is, obj, property);
- if (executor != null) {
- return executor;
+ if (property != null) {
+ // look for get("foo") if we did not try yet (just above)
+ if (property != identifier) {
+ executor = DuckGetExecutor.discover(is, claz, property);
+ if (executor != null) {
+ return executor;
+ }
+ }
+ if (index == null) {
+ // a field may be? (can not be a number)
+ executor = FieldGetExecutor.discover(is, claz, property);
+ if (executor != null) {
+ return executor;
+ }
+ // or an indexed property?
+ executor = IndexedType.discover(is, obj, property);
+ if (executor != null) {
+ return executor;
+ }
+ }
}
return null;
}
@@ -249,7 +261,7 @@ public class Uberspect implements JexlUb
@Override
public JexlPropertySet getPropertySet(final Object obj, final Object identifier, Object arg) {
final Class<?> claz = obj.getClass();
- final String property = AbstractExecutor.toString(identifier);
+ final String property = AbstractExecutor.castString(identifier);
final Introspector is = base();
JexlPropertySet executor;
// first try for a setFoo() type of property (also setfoo() )
@@ -266,9 +278,12 @@ public class Uberspect implements JexlUb
}
// let's see if we can convert the identifier to an int,
// if obj is an array or a list, we can still do something
- executor = ListSetExecutor.discover(is, claz, identifier, arg);
- if (executor != null) {
- return executor;
+ Integer index = AbstractExecutor.castInteger(identifier);
+ if (index != null) {
+ executor = ListSetExecutor.discover(is, claz, identifier, arg);
+ if (executor != null) {
+ return executor;
+ }
}
// if that didn't work, look for set(foo)
executor = DuckSetExecutor.discover(is, claz, identifier, arg);
@@ -276,16 +291,20 @@ public class Uberspect implements JexlUb
return executor;
}
// last, look for set("foo") if we did not try yet
- if (property != null && !(identifier instanceof String)) {
- executor = DuckSetExecutor.discover(is, claz, property, arg);
- if (executor != null) {
- return executor;
+ if (property != null) {
+ if (property != identifier) {
+ executor = DuckSetExecutor.discover(is, claz, property, arg);
+ if (executor != null) {
+ return executor;
+ }
+ }
+ if (index == null) {
+ // a field may be?
+ executor = FieldSetExecutor.discover(is, claz, property, arg);
+ if (executor != null) {
+ return executor;
+ }
}
- }
- // a field may be?
- executor = FieldSetExecutor.discover(is, claz, property, arg);
- if (executor != null) {
- return executor;
}
return null;
}
@@ -328,4 +347,63 @@ public class Uberspect implements JexlUb
public JexlMethod getConstructor(Object ctorHandle, Object[] args) {
return ConstructorMethod.discover(base(), ctorHandle, args);
}
+ /**
+ * May be a way to extend/improve sandboxing by choosing actual method for resolution.
+ **
+ * public static enum GetResolver {
+ * PROPERTY {
+ * @Override
+ * public JexlPropertyGet resolve(Uberspect uberspect, Object obj, Object identifier) {
+ * return PropertyGetExecutor.discover(uberspect.base(), obj.getClass(), AbstractExecutor.toString(identifier));
+ * }
+ * },
+ * BOOLEAN {
+ * @Override
+ * public JexlPropertyGet resolve(Uberspect uberspect, Object obj, Object identifier) {
+ * return BooleanGetExecutor.discover(uberspect.base(), obj.getClass(), AbstractExecutor.toString(identifier));
+ * }
+ * },
+ * MAP {
+ * @Override
+ * public JexlPropertyGet resolve(Uberspect uberspect, Object obj, Object identifier) {
+ * return MapGetExecutor.discover(uberspect.base(), obj.getClass(), identifier);
+ * }
+ * },
+ * LIST {
+ * @Override
+ * public JexlPropertyGet resolve(Uberspect uberspect, Object obj, Object identifier) {
+ * return ListGetExecutor.discover(uberspect.base(), obj.getClass(), identifier);
+ * }
+ * },
+ * DUCK {
+ * @Override
+ * public JexlPropertyGet resolve(Uberspect uberspect, Object obj, Object identifier) {
+ * final Introspector is = uberspect.base();
+ * final Class<?> clazz = obj.getClass();
+ * JexlPropertyGet executor = DuckGetExecutor.discover(is, clazz, identifier);
+ * if (executor == null && identifier != null && !(identifier instanceof String)) {
+ * executor = DuckGetExecutor.discover(is, clazz, AbstractExecutor.toString(identifier));
+ * }
+ * return executor;
+ * }
+ * },
+ * FIELD {
+ * @Override
+ * public JexlPropertyGet resolve(Uberspect uberspect, Object obj, Object identifier) {
+ * return FieldGetExecutor.discover(uberspect.base(), obj.getClass(), AbstractExecutor.toString(identifier));
+ * }
+ * },
+ * INDEXED {
+ * @Override
+ * public JexlPropertyGet resolve(Uberspect uberspect, Object obj, Object identifier) {
+ * return IndexedType.discover(uberspect.base(), obj, AbstractExecutor.toString(identifier));
+ * }
+ * },
+ * ANY {};
+ * <p/>
+ * public JexlPropertyGet resolve(Uberspect uberspect, Object obj, Object identifier) {
+ * return uberspect.getPropertyGet(obj, identifier);
+ * }
+ * }
+ */
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlMethod.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlMethod.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlMethod.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlMethod.java Mon Nov 25 13:35:55 2013
@@ -23,7 +23,7 @@ package org.apache.commons.jexl3.introsp
* <code>
* ${foo.bar()}
* </code>
- *
+ *
* @since 1.0
*/
public interface JexlMethod {
@@ -51,7 +51,8 @@ public interface JexlMethod {
Object tryInvoke(String name, Object obj, Object[] params);
/**
- * Checks whether a tryInvoke failed or not.
+ * Checks whether a tryInvoke return value indicates a failure or not.
+ * <p>Usage is : <code>Object r = tryInvoke(...); if (tryFailed(r) {...} else {...}</code>
* @param rval the value returned by tryInvoke
* @return true if tryInvoke failed, false otherwise
*/
@@ -60,7 +61,7 @@ public interface JexlMethod {
/**
* Specifies if this JexlMethod is cacheable and able to be reused for this
* class of object it was returned for.
- *
+ *
* @return true if can be reused for this class, false if not
*/
boolean isCacheable();
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlPropertyGet.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlPropertyGet.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlPropertyGet.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlPropertyGet.java Mon Nov 25 13:35:55 2013
@@ -28,7 +28,7 @@ package org.apache.commons.jexl3.introsp
public interface JexlPropertyGet {
/**
* Method used to get the property value of an object.
- *
+ *
* @param obj the object to get the property value from.
* @return the property value.
* @throws Exception on any error.
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlPropertySet.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlPropertySet.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlPropertySet.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/introspection/JexlPropertySet.java Mon Nov 25 13:35:55 2013
@@ -28,7 +28,7 @@ package org.apache.commons.jexl3.introsp
public interface JexlPropertySet {
/**
* Method used to set the property value of an object.
- *
+ *
* @param obj Object on which the property setter will be called with the value
* @param arg value to be set
* @return the value returned from the set operation (impl specific)
@@ -53,11 +53,11 @@ public interface JexlPropertySet {
* @return true if tryInvoke failed, false otherwise
*/
boolean tryFailed(Object rval);
-
+
/**
* Specifies if this JexlPropertySet is cacheable and able to be reused for
* this class of object it was returned for.
- *
+ *
* @return true if can be reused for this class, false if not
*/
boolean isCacheable();
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTArrayLiteral.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTArrayLiteral.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTArrayLiteral.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTArrayLiteral.java Mon Nov 25 13:35:55 2013
@@ -41,8 +41,7 @@ public final class ASTArrayLiteral exten
return constant;
}
- /** {
- * @inheritDoc} */
+ /** {@inheritDoc} */
@Override
public void jjtClose() {
constant = true;
@@ -58,8 +57,7 @@ public final class ASTArrayLiteral exten
}
}
- /** {
- * @inheritDoc} */
+ /** {@inheritDoc} */
@Override
public Object jjtAccept(ParserVisitor visitor, Object data) {
return visitor.visit(this, data);
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTJexlLambda.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTJexlLambda.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTJexlLambda.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTJexlLambda.java Mon Nov 25 13:35:55 2013
@@ -19,7 +19,7 @@ package org.apache.commons.jexl3.parser;
import org.apache.commons.jexl3.internal.Scope;
/**
- * Enhanced script to allow parameters declaration.
+ * Lambda (function).
*/
public final class ASTJexlLambda extends ASTJexlScript {
ASTJexlLambda(int id) {
@@ -30,6 +30,10 @@ public final class ASTJexlLambda extends
super(p, id);
}
+ public boolean isTopLevel() {
+ return parent == null;
+ }
+
/**
* Creates an array of arguments by copying values up to the number of parameters.
* @param values the argument values
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTJexlScript.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTJexlScript.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTJexlScript.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTJexlScript.java Mon Nov 25 13:35:55 2013
@@ -33,6 +33,20 @@ public class ASTJexlScript extends JexlN
super(p, id);
}
+ /**
+ * Consider script with no parameters that return lambda as parametric-scripts.
+ * @return the script
+ */
+ public ASTJexlScript script() {
+ if (scope == null && children != null && children.length == 1 && children[0] instanceof ASTJexlLambda) {
+ ASTJexlLambda lambda = (ASTJexlLambda) children[0];
+ lambda.parent = null;
+ return lambda;
+ } else {
+ return this;
+ }
+ }
+
@Override
public Object jjtAccept(ParserVisitor visitor, Object data) {
return visitor.visit(this, data);
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTNumberLiteral.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTNumberLiteral.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTNumberLiteral.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTNumberLiteral.java Mon Nov 25 13:35:55 2013
@@ -38,25 +38,27 @@ public final class ASTNumberLiteral exte
@Override
public String toString() {
+ if (literal == null || clazz == null || Double.isNaN(literal.doubleValue())) {
+ return "NaN";
+ }
if (BigDecimal.class.equals(clazz)) {
return BIGDF.format(literal);
- } else {
- StringBuilder strb = new StringBuilder(literal.toString());
- if (clazz != null) {
- if (Float.class.equals(clazz)) {
- strb.append('f');
- } else if (Double.class.equals(clazz)) {
- strb.append('d');
- } else if (BigDecimal.class.equals(clazz)) {
- strb.append('b');
- } else if (BigInteger.class.equals(clazz)) {
- strb.append('h');
- } else if (Long.class.equals(clazz)) {
- strb.append('l');
- }
+ }
+ StringBuilder strb = new StringBuilder(literal.toString());
+ if (clazz != null) {
+ if (Float.class.equals(clazz)) {
+ strb.append('f');
+ } else if (Double.class.equals(clazz)) {
+ strb.append('d');
+ } else if (BigDecimal.class.equals(clazz)) {
+ strb.append('b');
+ } else if (BigInteger.class.equals(clazz)) {
+ strb.append('h');
+ } else if (Long.class.equals(clazz)) {
+ strb.append('l');
}
- return strb.toString();
}
+ return strb.toString();
}
@Override
@@ -136,7 +138,7 @@ public final class ASTNumberLiteral exte
void setReal(String s) {
Number result;
Class<?> rclass;
- if ("#NaN".equals(s)) {
+ if ("#NaN".equals(s) || "NaN".equals(s)) {
result = Double.NaN;
rclass = Double.class;
} else {
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTVar.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTVar.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTVar.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTVar.java Mon Nov 25 13:35:55 2013
@@ -27,7 +27,7 @@ public class ASTVar extends ASTIdentifie
public ASTVar(Parser p, int id) {
super(p, id);
}
-
+
@Override
public Object jjtAccept(ParserVisitor visitor, Object data) {
return visitor.visit(this, data);
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt Mon Nov 25 13:35:55 2013
@@ -38,7 +38,7 @@ import org.apache.commons.jexl3.internal
public final class Parser extends JexlParser
{
- public ASTJexlScript parse(JexlInfo info, String jexlSrc, Scope scope, boolean registers) {
+ public ASTJexlScript parse(JexlInfo info, String jexlSrc, Scope scope, boolean registers, boolean expr) {
try {
// If registers are allowed, the default parser state has to be REGISTERS.
if (registers || ALLOW_REGISTERS) {
@@ -48,7 +48,7 @@ public final class Parser extends JexlPa
source = jexlSrc;
ReInit(new java.io.StringReader(jexlSrc));
frame = scope;
- ASTJexlScript script = JexlScript(scope);
+ ASTJexlScript script = expr? JexlExpression(scope) : JexlScript(scope) ;
script.value = info;
return script;
} catch (TokenMgrError xtme) {
@@ -159,6 +159,10 @@ PARSER_END(Parser)
/***************************************
* Identifier & String tokens
***************************************/
+<*> TOKEN : /* NaN */
+{
+ < NAN_LITERAL : "NaN" >
+}
<*> TOKEN : /* IDENTIFIERS */
{
@@ -205,7 +209,19 @@ ASTJexlScript JexlScript(Scope frame) :
}
{
( Statement() )* <EOF>
- { return jjtThis;}
+ {
+ return jjtThis.script();
+ }
+}
+
+ASTJexlScript JexlExpression(Scope frame) #JexlScript : {
+ jjtThis.setScope(frame);
+}
+{
+ ( Expression() )? <EOF>
+ {
+ return jjtThis.script();
+ }
}
void Statement() #void : {}
@@ -452,6 +468,14 @@ void Literal() #void :
StringLiteral()
|
NullLiteral()
+|
+ NaNLiteral()
+}
+
+void NaNLiteral() #NumberLiteral :
+{}
+{
+ <NAN_LITERAL> { jjtThis.setReal("NaN"); }
}
void NullLiteral() : {}
@@ -535,6 +559,15 @@ void Arguments() #Arguments : {}
<LPAREN> (Expression() (<COMMA> Expression())* )? <RPAREN>
}
+void FunctionCallLookahead() #void : {}
+{
+ LOOKAHEAD(4) <IDENTIFIER> <COLON> <IDENTIFIER> <LPAREN>
+ |
+ LOOKAHEAD(2) <IDENTIFIER> <LPAREN>
+ |
+ LOOKAHEAD(2) <REGISTER> <LPAREN>
+}
+
void FunctionCall() #void : {}
{
LOOKAHEAD(2) Identifier() <COLON> Identifier() Arguments() #FunctionNode(3)
@@ -627,7 +660,7 @@ void PrimaryExpression() #void : {}
|
LOOKAHEAD( <NEW> ) Constructor()
|
- LOOKAHEAD(2) FunctionCall()
+ LOOKAHEAD( FunctionCallLookahead() ) FunctionCall()
|
Identifier(true)
|
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/StringParser.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/StringParser.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/StringParser.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/StringParser.java Mon Nov 25 13:35:55 2013
@@ -205,5 +205,5 @@ public class StringParser {
strb.append(delim);
return strb.toString();
}
-
+
}
\ No newline at end of file
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngine.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngine.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/scripting/JexlScriptEngine.java Mon Nov 25 13:35:55 2013
@@ -38,8 +38,8 @@ import org.apache.commons.jexl3.JexlCont
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlScript;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.log4j.Logger;
+import org.apache.log4j.LogManager;
/**
* Implements the Jexl ScriptEngine for JSF-223.
@@ -62,7 +62,7 @@ import org.apache.commons.logging.LogFac
*/
public class JexlScriptEngine extends AbstractScriptEngine implements Compilable {
/** The logger. */
- private static final Log LOG = LogFactory.getLog(JexlScriptEngine.class);
+ private static final Logger LOG = LogManager.getLogger(JexlScriptEngine.class);
/** The shared expression cache size. */
private static final int CACHE_SIZE = 512;
@@ -169,7 +169,7 @@ public class JexlScriptEngine extends Ab
* Gives access to the engine logger.
* @return the JexlScriptEngine logger
*/
- public Log getLogger() {
+ public Logger getLogger() {
return LOG;
}
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/scripting/Main.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/scripting/Main.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/scripting/Main.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/scripting/Main.java Mon Nov 25 13:35:55 2013
@@ -32,16 +32,16 @@ public class Main {
/**
* Test application for JexlScriptEngine (JSR-223 implementation).
- *
+ *
* If a single argument is present, it is treated as a filename of a JEXL
* script to be evaluated. Any exceptions terminate the application.
- *
+ *
* Otherwise, lines are read from standard input and evaluated.
* ScriptExceptions are logged, and do not cause the application to exit.
* This is done so that interactive testing is easier.
- *
+ *
* @param args (optional) filename to evaluate. Stored in the args variable.
- *
+ *
* @throws Exception if parsing or IO fail
*/
public static void main(String[] args) throws Exception {
Modified: commons/proper/jexl/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/site/xdoc/changes.xml?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/jexl/trunk/src/site/xdoc/changes.xml Mon Nov 25 13:35:55 2013
@@ -25,7 +25,55 @@
<author email="dev@commons.apache.org">Commons Developers</author>
</properties>
<body>
- <release version="3.0" date="2012-09-30">
+ <release version="3.0.1" date="unreleased">
+ <action dev="henrib" type="fix" >
+ Fixed issue in edge case method resolution wrt overload and varargs
+ </action>
+ <action dev="henrib" type="add" >
+ Switch logging to log4j 1.2
+ </action>
+ <action dev="henrib" type="fix" issue="JEXL-144" due-to="Woonsang Ko">
+ Empty array property setting fails
+ </action>
+ <action dev="henrib" type="fix" issue="JEXL-142" due-to="Juozas Baliuks">
+ Map expression issue with empty key
+ </action>
+ <action dev="henrib" type="fix" issue="JEXL-141" due-to="Harpreet Singh">
+ Suffix for Big Decimal and Big Integer Literal is incorrectly mentioned in Java docs
+ </action>
+ <action dev="henrib" type="fix" issue="JEXL-137">
+ Invalid script variable list for nested array/map access
+ </action>
+ <action dev="henrib" type="fix">
+ Fixed Engine.getVariables that was erroneously considering method calls as variable usage
+ </action>
+ <action dev="henrib" type="fix">
+ Fixed issue in ternary expression
+ (grammar was not precise enough to differentiate namespace:function calls vs ternary right hand side)
+ </action>
+ <action dev="henrib" type="add">
+ NaN is now a keyword equivalent to #NaN (deprecated): POTENTIAL SCRIPT BREAK!
+ </action>
+ <action dev="henrib" type="add">
+ Syntactically enforce that expressions do not contain statements: POTENTIAL EXPRESSION BREAK!
+ (ie an expression is not a script and can NOT use 'if','for'... and blocks)
+ </action>
+ <action dev="henrib" type="add">
+ Added syntactic shortcut to create parametric scripts (script source creates an anonymous function)
+ </action>
+ <action dev="henrib" type="fix">
+ Segregated JexlScript and JexlExpression further to avoid calling JexlExpression.evaluate on JexlScript
+ (instead of JexlScript.execute) which had the unexpected property of only evaluating the first statement
+ </action>
+ <action dev="henrib" type="fix">
+ Fix an edge case of ambiguous method matching (see http://apache-commons.680414.n4.nabble.com/jexl-mathod-within-namespace-not-found-if-parameter-is-int-tt4637888.html)
+ </action>
+ <action dev="henrib" type="fix">
+ Fix issue wrt isEmpty and method varargs (assignable types vs equal types)
+ (see http://apache-commons.680414.n4.nabble.com/jexl-empty-function-crashes-if-called-with-int-tt4637895.html)
+ </action>
+ </release>
+ <release version="3.0" date="unreleased">
<action dev="henrib" type="add" issue="JEXL-133" due-to="Alfred Reibenschuh">
String matching Operator short-hand inspired by CSS3
</action>
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ArithmeticTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ArithmeticTest.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ArithmeticTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ArithmeticTest.java Mon Nov 25 13:35:55 2013
@@ -352,9 +352,15 @@ public class ArithmeticTest extends Jexl
script = jexl.createScript("#NaN");
result = script.execute(null);
assertTrue(Double.isNaN((Double) result));
+ script = jexl.createScript("NaN");
+ result = script.execute(null);
+ assertTrue(Double.isNaN((Double) result));
script = jexl.createScript("double:isNaN(#NaN)");
result = script.execute(null);
assertTrue((Boolean) result);
+ script = jexl.createScript("double:isNaN(NaN)");
+ result = script.execute(null);
+ assertTrue((Boolean) result);
}
public static class EmptyTestContext extends MapContext implements JexlContext.NamespaceResolver {
@@ -405,4 +411,4 @@ public class ArithmeticTest extends Jexl
assertEquals("failed on " + stext, expected, result);
}
}
-}
+}
\ No newline at end of file
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ArrayLiteralTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ArrayLiteralTest.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ArrayLiteralTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ArrayLiteralTest.java Mon Nov 25 13:35:55 2013
@@ -27,7 +27,7 @@ public class ArrayLiteralTest extends Je
public ArrayLiteralTest() {
super("ArrayLiteralTest");
}
-
+
public void testLiteralWithStrings() throws Exception {
JexlExpression e = JEXL.createExpression( "[ 'foo' , 'bar' ]" );
JexlContext jc = new MapContext();
@@ -63,7 +63,7 @@ public class ArrayLiteralTest extends Je
"[ 10 , null , 10]",
"[ '10' , null ]",
"[ null, '10' , null ]"
- };
+ };
Object [][]checks = {
{null, new Integer(10)},
{new Integer(10), null},
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/BitwiseOperatorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/BitwiseOperatorTest.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/BitwiseOperatorTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/BitwiseOperatorTest.java Mon Nov 25 13:35:55 2013
@@ -38,7 +38,7 @@ public class BitwiseOperatorTest extends
public BitwiseOperatorTest(String name) {
super(name);
}
-
+
public void testAndWithTwoNulls() throws Exception {
asserter.assertExpression("null & null", new Long(0));
}
@@ -70,7 +70,7 @@ public class BitwiseOperatorTest extends
public void testComplementWithNull() throws Exception {
asserter.assertExpression("~null", new Long(-1));
}
-
+
public void testComplementSimple() throws Exception {
asserter.assertExpression("~128", new Long(-129));
}
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/BlockTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/BlockTest.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/BlockTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/BlockTest.java Mon Nov 25 13:35:55 2013
@@ -5,9 +5,9 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,7 +24,7 @@ public class BlockTest extends JexlTestC
/**
* Create the test
- *
+ *
* @param testName name of the test
*/
public BlockTest(String testName) {
@@ -32,46 +32,46 @@ public class BlockTest extends JexlTestC
}
public void testBlockSimple() throws Exception {
- JexlExpression e = JEXL.createExpression("if (true) { 'hello'; }");
+ JexlScript e = JEXL.createScript("if (true) { 'hello'; }");
JexlContext jc = new MapContext();
- Object o = e.evaluate(jc);
+ Object o = e.execute(jc);
assertEquals("Result is wrong", "hello", o);
}
public void testBlockExecutesAll() throws Exception {
- JexlExpression e = JEXL.createExpression("if (true) { x = 'Hello'; y = 'World';}");
+ JexlScript e = JEXL.createScript("if (true) { x = 'Hello'; y = 'World';}");
JexlContext jc = new MapContext();
- Object o = e.evaluate(jc);
+ Object o = e.execute(jc);
assertEquals("First result is wrong", "Hello", jc.get("x"));
assertEquals("Second result is wrong", "World", jc.get("y"));
assertEquals("Block result is wrong", "World", o);
}
public void testEmptyBlock() throws Exception {
- JexlExpression e = JEXL.createExpression("if (true) { }");
+ JexlScript e = JEXL.createScript("if (true) { }");
JexlContext jc = new MapContext();
- Object o = e.evaluate(jc);
+ Object o = e.execute(jc);
assertNull("Result is wrong", o);
}
public void testBlockLastExecuted01() throws Exception {
- JexlExpression e = JEXL.createExpression("if (true) { x = 1; } else { x = 2; }");
+ JexlScript e = JEXL.createScript("if (true) { x = 1; } else { x = 2; }");
JexlContext jc = new MapContext();
- Object o = e.evaluate(jc);
+ Object o = e.execute(jc);
assertEquals("Block result is wrong", new Integer(1), o);
}
public void testBlockLastExecuted02() throws Exception {
- JexlExpression e = JEXL.createExpression("if (false) { x = 1; } else { x = 2; }");
+ JexlScript e = JEXL.createScript("if (false) { x = 1; } else { x = 2; }");
JexlContext jc = new MapContext();
- Object o = e.evaluate(jc);
+ Object o = e.execute(jc);
assertEquals("Block result is wrong", new Integer(2), o);
}
public void testNestedBlock() throws Exception {
- JexlExpression e = JEXL.createExpression("if (true) { x = 'hello'; y = 'world';" + " if (true) { x; } y; }");
+ JexlScript e = JEXL.createScript("if (true) { x = 'hello'; y = 'world';" + " if (true) { x; } y; }");
JexlContext jc = new MapContext();
- Object o = e.evaluate(jc);
+ Object o = e.execute(jc);
assertEquals("Block result is wrong", "world", o);
}
}
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreator.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreator.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreator.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreator.java Mon Nov 25 13:35:55 2013
@@ -37,6 +37,9 @@ public class ClassCreator {
private String sourceName = null;
private ClassLoader loader = null;
public static final boolean canRun = comSunToolsJavacMain();
+
+ static final String GEN_PATH = "/org/apache/commons/jexl3/generated";
+ static final String GEN_CLASS = "org.apache.commons.jexl3.generated.";
/**
* Check if we can invoke Sun's java compiler.
* @return true if it is possible, false otherwise
@@ -69,17 +72,17 @@ public class ClassCreator {
seed = s;
className = "foo" + s;
sourceName = className + ".java";
- packageDir = new File(base, seed + "/org/apache/commons/jexl3/generated");
+ packageDir = new File(base, seed + GEN_PATH);
packageDir.mkdirs();
loader = null;
}
public String getClassName() {
- return "org.apache.commons.jexl3.generated." + className;
+ return GEN_CLASS + className;
}
public Class<?> getClassInstance() throws Exception {
- return getClassLoader().loadClass("org.apache.commons.jexl3.generated." + className);
+ return getClassLoader().loadClass(getClassName());
}
public ClassLoader getClassLoader() throws Exception {
@@ -128,7 +131,16 @@ public class ClassCreator {
if (javac == null) {
return null;
}
- Integer r = (Integer) jexl.invokeMethod(javac, "compile", source);
+ Integer r;
+ try {
+ r = (Integer) jexl.invokeMethod(javac, "compile", source);
+ if (r.intValue() >= 0) {
+ return getClassLoader().loadClass("org.apache.commons.jexl3.generated." + className);
+ }
+ } catch (JexlException xignore) {
+ // ignore
+ }
+ r = (Integer) jexl.invokeMethod(javac, "compile", (Object) new String[]{source});
if (r.intValue() >= 0) {
return getClassLoader().loadClass("org.apache.commons.jexl3.generated." + className);
}
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreatorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreatorTest.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreatorTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ClassCreatorTest.java Mon Nov 25 13:35:55 2013
@@ -24,14 +24,14 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.log4j.Logger;
+import org.apache.log4j.LogManager;
/**
* Basic check on automated class creation
*/
public class ClassCreatorTest extends JexlTestCase {
- static final Log logger = LogFactory.getLog(JexlTestCase.class);
+ static final Logger logger = LogManager.getLogger(JexlTestCase.class);
static final int LOOPS = 8;
private File base = null;
private JexlEngine jexl = null;
Added: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ContextNamespaceTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ContextNamespaceTest.java?rev=1545274&view=auto
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ContextNamespaceTest.java (added)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ContextNamespaceTest.java Mon Nov 25 13:35:55 2013
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl3;
+
+import org.apache.commons.jexl3.internal.Engine;
+/**
+ * Tests JexlContext (advanced) features.
+ */
+public class ContextNamespaceTest extends JexlTestCase {
+
+ public ContextNamespaceTest(String testName) {
+ super(testName);
+ }
+
+ /*
+ * Accesses the thread context and cast it.
+ */
+ public static class Taxes {
+ public double vat(double n) {
+ TaxesContext context = (TaxesContext) JexlEngine.getThreadContext();
+ return n * context.getVAT() / 100.;
+ }
+ }
+
+ /**
+ * A thread local context carrying a namespace and some inner constants.
+ */
+ public static class TaxesContext extends MapContext implements JexlContext.ThreadLocal, JexlContext.NamespaceResolver {
+ private final Taxes taxes = new Taxes();
+ private final double vat;
+ TaxesContext(double vat) {
+ this.vat = vat;
+ }
+ @Override
+ public Object resolveNamespace(String name) {
+ return "taxes".equals(name)? taxes : null;
+ }
+ public double getVAT() {
+ return vat;
+ }
+ }
+
+ public void testThreadedContext() throws Exception {
+ JexlEngine jexl = new Engine();
+ TaxesContext context = new TaxesContext(18.6);
+ String strs = "taxes:vat(1000)";
+ JexlScript staxes = jexl.createScript(strs);
+ Object result = staxes.execute(context);
+ assertEquals(186., result);
+ }
+
+}
Propchange: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ContextNamespaceTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/Foo.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/Foo.java?rev=1545274&r1=1545273&r2=1545274&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/Foo.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/Foo.java Mon Nov 25 13:35:55 2013
@@ -5,9 +5,9 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,11 +22,11 @@ import java.util.List;
/**
* A simple bean used for testing purposes
- *
+ *
* @since 1.0
*/
public class Foo {
-
+
private boolean beenModified = false;
private String property1 = "some value";
public Foo() {}
@@ -35,7 +35,7 @@ public class Foo {
return getCheeseList().iterator();
}
}
-
+
public String bar()
{
return JexlTest.METHOD_STRING;
@@ -115,7 +115,7 @@ public class Foo {
{
return 22;
}
-
+
public String getProperty1() {
return property1;
}