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 2012/07/05 09:08:07 UTC
svn commit: r1357476 [1/2] - 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/parser/ site/...
Author: henrib
Date: Thu Jul 5 07:08:06 2012
New Revision: 1357476
URL: http://svn.apache.org/viewvc?rev=1357476&view=rev
Log:
Added range operator (x .. y) and supporting class (IntegerRange);
Added startsWith/endsWith (=^ and =$) operators;
Added #NaN to grammar;
Added charset support in JexlEngine & builder options;
Rafactored code for map and array literals (MapBuilder/ArrayBuilder), allow override in JexlArithmetic to customize behavior;
Updated constant JexlNode determination;
Updated exception handling during parsing, more precise message and info;
Moved ReadonlyContext to test dir;
Moved some tests from 'issues' to arithmetic;
Updated doc and changes;
Added:
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/ArrayBuilder.java (with props)
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/IntegerRange.java (with props)
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/MapBuilder.java (with props)
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ArithmeticOperatorTest.java
- copied, changed from r1338871, commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/BitwiseOperatorTest.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ReadonlyContext.java
- copied, changed from r1338871, commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/ReadonlyContext.java
Removed:
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/ReadonlyContext.java
Modified:
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlEngine.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlException.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Closure.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Engine.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Script.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ArrayListWrapper.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/SandboxUberspect.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/package.html
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTArrayLiteral.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTMapLiteral.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTNumberLiteral.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTStringLiteral.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java
commons/proper/jexl/trunk/src/site/xdoc/changes.xml
commons/proper/jexl/trunk/src/site/xdoc/reference/syntax.xml
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ArithmeticTest.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/JexlEvalContext.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/JexlTest.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/internal/Util.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/parser/ParserTest.java
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java Thu Jul 5 07:08:06 2012
@@ -16,8 +16,6 @@
*/
package org.apache.commons.jexl3;
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
@@ -110,6 +108,82 @@ public class JexlArithmetic {
}
/**
+ * Helper interface used when creating an array literal.
+ * <p>The default implementation creates an array and attempts to type it strictly.
+ * <ul>
+ * <li>If all objects are of the same type, the array returned will be an array of that same type</li>
+ * <li>If all objects are Numbers, the array returned will be an array of Numbers</li>
+ * <li>If all objects are convertible to a primitive type, the array returned will be an array
+ * of the primitive type</li>
+ * </ul>
+ * </p>
+ */
+ public interface ArrayBuilder {
+ /**
+ * Adds a literal to the array.
+ * @param value the item to add
+ */
+ void add(Object value);
+
+ /**
+ * Creates the actual "array" instance.
+ * @return the array
+ */
+ Object create();
+ }
+
+ /**
+ * Called by the interpreter when evaluating a literal array.
+ * @param size the number of elements in the array
+ * @return the array builder
+ */
+ public ArrayBuilder arrayBuilder(int size) {
+ return new org.apache.commons.jexl3.internal.ArrayBuilder(size);
+ }
+
+ /**
+ * Helper interface used when creating a map literal.
+ * <p>The default implementation creates a java.util.HashMap.</p>
+ */
+ public interface MapBuilder {
+ /**
+ * Adds a new entry to the map.
+ * @param key the map entry key
+ * @param value the map entry value
+ */
+ void put(Object key, Object value);
+
+ /**
+ * Creates the actual "map" instance.
+ * @return the map
+ */
+ Object create();
+ }
+
+ /**
+ * Called by the interpreter when evaluating a literal map.
+ * @param size the number of elements in the map
+ * @return the map builder
+ */
+ public MapBuilder mapBuilder(int size) {
+ return new org.apache.commons.jexl3.internal.MapBuilder(size);
+ }
+
+ /**
+ * Creates a literal range.
+ * <p>The default implementation only accepts integers.</p>
+ * @param from the included lower bound value (null if none)
+ * @param to the included upper bound value (null if none)
+ * @return the range as an iterable
+ * @throws ArithmeticException as an option if creation fails
+ */
+ public Iterable<?> createRange(Object from, Object to) throws ArithmeticException {
+ final int ifrom = toInteger(from);
+ final int ito = toInteger(to);
+ return new org.apache.commons.jexl3.internal.IntegerRange(ifrom, ito);
+ }
+
+ /**
* Checks whether this JexlArithmetic instance
* strictly considers null as an error when used as operand unexpectedly.
* @return true if strict, false if lenient
@@ -365,96 +439,22 @@ public class JexlArithmetic {
}
/**
- * Given an array of objects, attempt to type it more strictly.
- * <p>This is a placeholder for derivation that calls the static typeArray method.</p>
- * @param untyped an untyped array
- * @return the original array if the attempt to strictly type the array fails, a typed array otherwise
- */
- public Object narrowArrayType(Object[] untyped) {
- return typeArray(untyped);
- }
-
- /**
- * Given an array of objects, attempt to type it more strictly.
- * <ul>
- * <li>If all objects are of the same type, the array returned will be an array of that same type</li>
- * <li>If all objects are Numbers, the array returned will be an array of Numbers</li>
- * <li>If all objects are convertible to a primitive type, the array returned will be an array
- * of the primitive type</li>
- * </ul>
- * @param untyped an untyped array
- * @return the original array if the attempt to strictly type the array fails, a typed array otherwise
- */
- public static Object typeArray(Object[] untyped) {
- final int size = untyped.length;
- Class<?> commonClass = null;
- if (size > 0) {
- boolean isNumber = true;
- // for all children after first...
- for (int u = 0; u < size && !Object.class.equals(commonClass); ++u) {
- if (untyped[u] != null) {
- Class<?> eclass = untyped[u].getClass();
- // base common class on first non-null entry
- if (commonClass == null) {
- commonClass = eclass;
- isNumber &= Number.class.isAssignableFrom(commonClass);
- } else if (!commonClass.equals(eclass)) {
- // if both are numbers...
- if (isNumber && Number.class.isAssignableFrom(eclass)) {
- commonClass = Number.class;
- } else {
- // attempt to find valid superclass
- do {
- eclass = eclass.getSuperclass();
- if (eclass == null) {
- commonClass = Object.class;
- break;
- }
- } while (!commonClass.isAssignableFrom(eclass));
- }
- }
- } else {
- isNumber = false;
- }
- }
- // convert array to the common class if not Object.class
- if (commonClass != null && !Object.class.equals(commonClass)) {
- // if the commonClass has an equivalent primitive type, get it
- if (isNumber) {
- try {
- final Field type = commonClass.getField("TYPE");
- commonClass = (Class<?>) type.get(null);
- } catch (Exception xany) {
- // ignore
- }
- }
- // allocate and fill up the typed array
- Object typed = Array.newInstance(commonClass, size);
- for (int i = 0; i < size; ++i) {
- Array.set(typed, i, untyped[i]);
- }
- return typed;
- }
- }
- return untyped;
- }
-
- /**
* Replace all numbers in an arguments array with the smallest type that will fit.
* @param args the argument array
* @return true if some arguments were narrowed and args array is modified,
- * false if no narrowing occured and args array has not been modified
+ * false if no narrowing occured and args array has not been modified
*/
public boolean narrowArguments(Object[] args) {
boolean narrowed = false;
for (int a = 0; a < args.length; ++a) {
Object arg = args[a];
if (arg instanceof Number) {
- Object narg = narrow((Number) arg);
- if (narg != arg) {
+ Number narg = (Number) arg;
+ Number narrow = narrow(narg);
+ if (!narg.equals(narrow)) {
narrowed = true;
}
- args[a] = narg;
+ args[a] = narrow;
}
}
return narrowed;
@@ -519,7 +519,7 @@ public class JexlArithmetic {
BigDecimal r = toBigDecimal(right);
if (BigDecimal.ZERO.equals(r)) {
throw new ArithmeticException("/");
- }
+ }
BigDecimal result = l.divide(r, getMathContext());
return narrowBigDecimal(left, right, result);
}
@@ -537,7 +537,7 @@ public class JexlArithmetic {
BigInteger r = toBigInteger(right);
if (BigInteger.ZERO.equals(r)) {
throw new ArithmeticException("/");
- }
+ }
BigInteger result = l.divide(r);
return narrowBigInteger(left, right, result);
}
@@ -559,7 +559,7 @@ public class JexlArithmetic {
BigDecimal r = toBigDecimal(right);
if (BigDecimal.ZERO.equals(r)) {
throw new ArithmeticException("%");
- }
+ }
BigDecimal remainder = l.remainder(r, getMathContext());
return narrowBigDecimal(left, right, remainder);
}
@@ -578,7 +578,7 @@ public class JexlArithmetic {
BigInteger result = l.mod(r);
if (BigInteger.ZERO.equals(r)) {
throw new ArithmeticException("%");
- }
+ }
return narrowBigInteger(left, right, result);
}
@@ -1022,7 +1022,7 @@ public class JexlArithmetic {
return new BigInteger(val.toString());
} else if (val instanceof String) {
String string = (String) val;
- if ("".equals(string.trim())) {
+ if ("".equals(string)) {
return BigInteger.ZERO;
} else {
return new BigInteger(string);
@@ -1052,7 +1052,7 @@ public class JexlArithmetic {
controlNullOperand();
return BigDecimal.ZERO;
} else if (val instanceof String) {
- String string = ((String) val).trim();
+ String string = (String) val;
if ("".equals(string)) {
return BigDecimal.ZERO;
}
@@ -1094,7 +1094,7 @@ public class JexlArithmetic {
} else if (val instanceof Boolean) {
return ((Boolean) val).booleanValue() ? 1. : 0.;
} else if (val instanceof String) {
- String string = ((String) val).trim();
+ String string = (String) val;
if ("".equals(string)) {
return Double.NaN;
} else {
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java Thu Jul 5 07:08:06 2012
@@ -16,6 +16,7 @@
*/
package org.apache.commons.jexl3;
+import java.nio.charset.Charset;
import org.apache.commons.jexl3.internal.Engine;
import java.util.Map;
import org.apache.commons.jexl3.introspection.JexlUberspect;
@@ -99,6 +100,10 @@ public class JexlBuilder {
*/
protected int cacheThreshold = CACHE_THRESHOLD;
/**
+ * The charset.
+ */
+ protected Charset charset = Charset.defaultCharset();
+ /**
* The class loader.
*/
protected ClassLoader loader = null;
@@ -179,6 +184,21 @@ public class JexlBuilder {
}
/**
+ * Sets the charset to use.
+ * @param arg the charset
+ * @return this builder
+ */
+ public JexlBuilder loader(Charset arg) {
+ this.charset = arg;
+ return this;
+ }
+
+ /** @return the charset */
+ public Charset charset() {
+ return charset;
+ }
+
+ /**
* Sets whether the engine will throw JexlException during evaluation when an error is triggered.
* @param flag true means no JexlException will occur, false allows them
* @return this builder
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlEngine.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlEngine.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlEngine.java Thu Jul 5 07:08:06 2012
@@ -20,11 +20,12 @@ import org.apache.commons.jexl3.introspe
import java.io.BufferedReader;
import java.io.File;
-import java.io.FileReader;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.MathContext;
import java.net.URL;
+import java.nio.charset.Charset;
/**
* Creates and evaluates JexlExpression and JexlScript objects.
@@ -49,6 +50,11 @@ public abstract class JexlEngine {
*/
public interface Options {
/**
+ * The charset used for parsing.
+ * @return the charset
+ */
+ Charset getCharset();
+ /**
* Sets whether the engine will throw a {@link JexlException} when an error is encountered during evaluation.
* @return true if silent, false otherwise
*/
@@ -114,6 +120,12 @@ public abstract class JexlEngine {
private static final int JXLT_CACHE_SIZE = 256;
/**
+ * Gets the charset used for parsing.
+ * @return the charset
+ */
+ public abstract Charset getCharset();
+
+ /**
* Gets this engine underlying {@link JexlUberspect}.
* @return the uberspect
*/
@@ -473,7 +485,7 @@ public abstract class JexlEngine {
}
BufferedReader reader = null;
try {
- reader = new BufferedReader(new FileReader(file));
+ reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), getCharset()));
return toString(reader);
} catch (IOException xio) {
throw new JexlException(createInfo(file.toString(), 1, 1), "could not read source File", xio);
@@ -482,7 +494,7 @@ public abstract class JexlEngine {
try {
reader.close();
} catch (IOException xignore) {
- // cant to much
+ // cant do much
}
}
}
@@ -499,7 +511,7 @@ public abstract class JexlEngine {
}
BufferedReader reader = null;
try {
- reader = new BufferedReader(new InputStreamReader(url.openStream()));
+ reader = new BufferedReader(new InputStreamReader(url.openStream(), getCharset()));
return toString(reader);
} catch (IOException xio) {
throw new JexlException(createInfo(url.toString(), 1, 1), "could not read source URL", xio);
@@ -508,7 +520,7 @@ public abstract class JexlEngine {
try {
reader.close();
} catch (IOException xignore) {
- // cant to much
+ // cant do much
}
}
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlException.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlException.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlException.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlException.java Thu Jul 5 07:08:06 2012
@@ -73,7 +73,7 @@ public class JexlException extends Runti
* @param cause the exception causing the error
*/
public JexlException(JexlInfo jinfo, String msg, Throwable cause) {
- super(msg, unwrap(cause));
+ super(msg != null ? msg : "", unwrap(cause));
mark = null;
info = jinfo;
}
@@ -213,7 +213,7 @@ public class JexlException extends Runti
*/
public static class Parsing extends JexlException {
/**
- * Creates a new Variable exception instance.
+ * Creates a new Parsing exception instance.
* @param info the location information
* @param cause the javacc cause
*/
@@ -222,7 +222,7 @@ public class JexlException extends Runti
}
/**
- * Creates a new Variable exception instance.
+ * Creates a new Parsing exception instance.
* @param info the location information
* @param msg the message
*/
@@ -244,6 +244,46 @@ public class JexlException extends Runti
}
/**
+ * Thrown when parsing fails due to an ambiguous statement.
+ * @since 3.0
+ */
+ public static class Ambiguous extends Parsing {
+ /**
+ * Creates a new Ambiguous statement exception instance.
+ * @param info the location information
+ * @param expr the source expression line
+ */
+ public Ambiguous(JexlInfo info, String expr) {
+ super(info, expr);
+ }
+
+ @Override
+ protected String detailedMessage() {
+ return parserError("ambiguous statement", getDetail());
+ }
+ }
+
+ /**
+ * Thrown when parsing fails due to an invalid assigment.
+ * @since 3.0
+ */
+ public static class Assignment extends Parsing {
+ /**
+ * Creates a new Assignment statement exception instance.
+ * @param info the location information
+ * @param expr the source expression line
+ */
+ public Assignment(JexlInfo info, String expr) {
+ super(info, expr);
+ }
+
+ @Override
+ protected String detailedMessage() {
+ return parserError("assignement", getDetail());
+ }
+ }
+
+ /**
* Thrown when a variable is unknown.
* @since 3.0
*/
Added: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/ArrayBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/ArrayBuilder.java?rev=1357476&view=auto
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/ArrayBuilder.java (added)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/ArrayBuilder.java Thu Jul 5 07:08:06 2012
@@ -0,0 +1,107 @@
+/*
+ * 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.internal;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import org.apache.commons.jexl3.JexlArithmetic;
+
+/**
+ * Helper class to create typed arrays.
+ */
+public class ArrayBuilder implements JexlArithmetic.ArrayBuilder {
+ /** The intended class array. */
+ private Class<?> commonClass = null;
+ /** Whether the array stores numbers. */
+ private boolean isNumber = true;
+ /** The untyped list of items being added. */
+ private final Object[] untyped;
+ /** Number of added items. */
+ private int added = 0;
+
+ /**
+ * Creates a new builder.
+ * @param size the exact array size
+ */
+ public ArrayBuilder(int size) {
+ untyped = new Object[size];
+ }
+
+ @Override
+ public void add(Object value) {
+ // for all children after first...
+ if (!Object.class.equals(commonClass)) {
+ if (value == null) {
+ isNumber = false;
+ } else {
+ Class<?> eclass = value.getClass();
+ // base common class on first non-null entry
+ if (commonClass == null) {
+ commonClass = eclass;
+ isNumber &= Number.class.isAssignableFrom(commonClass);
+ } else if (!commonClass.equals(eclass)) {
+ // if both are numbers...
+ if (isNumber && Number.class.isAssignableFrom(eclass)) {
+ commonClass = Number.class;
+ } else {
+ // attempt to find valid superclass
+ do {
+ eclass = eclass.getSuperclass();
+ if (eclass == null) {
+ commonClass = Object.class;
+ break;
+ }
+ } while (!commonClass.isAssignableFrom(eclass));
+ }
+ }
+ }
+ }
+ if (added >= untyped.length) {
+ throw new IllegalArgumentException("add() over size");
+ }
+ untyped[added++] = value;
+ }
+
+ @Override
+ public Object create() {
+ if (untyped != null) {
+ int size = untyped.length;
+ // convert untyped array to the common class if not Object.class
+ if (commonClass != null && !Object.class.equals(commonClass)) {
+ // if the commonClass is a number, it has an equivalent primitive type, get it
+ if (isNumber) {
+ try {
+ final Field type = commonClass.getField("TYPE");
+ commonClass = (Class<?>) type.get(null);
+ } catch (Exception xany) {
+ // ignore
+ }
+ }
+ // allocate and fill up the typed array
+ Object typed = Array.newInstance(commonClass, size);
+ for (int i = 0; i < size; ++i) {
+ Array.set(typed, i, untyped[i]);
+ }
+ return typed;
+ } else {
+ return untyped;
+ }
+ } else {
+ return new Object[0];
+ }
+ }
+}
Propchange: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/ArrayBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Closure.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Closure.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Closure.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Closure.java Thu Jul 5 07:08:06 2012
@@ -46,7 +46,7 @@ public class Closure extends Script {
@Override
public String getParsedText() {
Debugger debug = new Debugger();
- boolean d = debug.debug(script);
+ debug.debug(script);
return debug.toString();
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Debugger.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Debugger.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Debugger.java Thu Jul 5 07:08:06 2012
@@ -54,10 +54,13 @@ import org.apache.commons.jexl3.parser.A
import org.apache.commons.jexl3.parser.ASTMulNode;
import org.apache.commons.jexl3.parser.ASTNENode;
import org.apache.commons.jexl3.parser.ASTNRNode;
+import org.apache.commons.jexl3.parser.ASTEWNode;
+import org.apache.commons.jexl3.parser.ASTSWNode;
import org.apache.commons.jexl3.parser.ASTNotNode;
import org.apache.commons.jexl3.parser.ASTNullLiteral;
import org.apache.commons.jexl3.parser.ASTNumberLiteral;
import org.apache.commons.jexl3.parser.ASTOrNode;
+import org.apache.commons.jexl3.parser.ASTRangeNode;
import org.apache.commons.jexl3.parser.ASTReference;
import org.apache.commons.jexl3.parser.ASTReferenceExpression;
import org.apache.commons.jexl3.parser.ASTReturnStatement;
@@ -377,6 +380,11 @@ public final class Debugger extends Pars
}
@Override
+ protected Object visit(ASTRangeNode node, Object data) {
+ return infixChildren(node, " .. ", false, data);
+ }
+
+ @Override
protected Object visit(ASTAssignment node, Object data) {
return infixChildren(node, " = ", false, data);
}
@@ -452,6 +460,16 @@ public final class Debugger extends Pars
}
@Override
+ protected Object visit(ASTSWNode node, Object data) {
+ return infixChildren(node, " =^ ", false, data);
+ }
+
+ @Override
+ protected Object visit(ASTEWNode node, Object data) {
+ return infixChildren(node, " =$ ", false, data);
+ }
+
+ @Override
protected Object visit(ASTFalseNode node, Object data) {
return check(node, "false", data);
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Engine.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Engine.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Engine.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Engine.java Thu Jul 5 07:08:06 2012
@@ -41,8 +41,6 @@ import org.apache.commons.jexl3.parser.P
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import java.io.Reader;
-
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
@@ -53,6 +51,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.lang.ref.SoftReference;
+import java.nio.charset.Charset;
/**
* A JexlEngine implementation.
@@ -118,6 +117,11 @@ public class Engine extends JexlEngine {
*/
protected final int cacheThreshold;
/**
+ * The default charset.
+ */
+ protected final Charset charset;
+
+ /**
* The default cache load factor.
*/
private static final float LOAD_FACTOR = 0.75f;
@@ -153,6 +157,7 @@ public class Engine extends JexlEngine {
this.arithmetic = conf.arithmetic() == null ? new JexlArithmetic(this.strict) : conf.arithmetic();
this.cache = conf.cache() <= 0 ? null : new SoftCache<String, ASTJexlScript>(conf.cache());
this.cacheThreshold = conf.cacheThreshold();
+ this.charset = conf.charset();
}
/**
@@ -192,7 +197,7 @@ public class Engine extends JexlEngine {
}
@Override
- public final boolean isStrict() {
+ public boolean isStrict() {
return strict;
}
@@ -202,6 +207,11 @@ public class Engine extends JexlEngine {
}
@Override
+ public Charset getCharset() {
+ return charset;
+ }
+
+ @Override
public TemplateEngine createJxltEngine(int cacheSize, char immediate, char deferred) {
return new TemplateEngine(this, cacheSize, immediate, deferred);
}
@@ -618,8 +628,7 @@ public class Engine extends JexlEngine {
}
}
}
- Reader reader = new StringReader(expr);
- script = parser.parse(info, reader, scope, registers);
+ script = parser.parse(info, expr, scope, registers);
if (cached) {
cache.put(expr, script);
}
Added: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/IntegerRange.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/IntegerRange.java?rev=1357476&view=auto
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/IntegerRange.java (added)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/IntegerRange.java Thu Jul 5 07:08:06 2012
@@ -0,0 +1,87 @@
+/*
+ * 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.internal;
+
+import java.util.Iterator;
+
+/**
+ * A range of integers.
+ */
+public class IntegerRange implements Iterable<Integer> {
+ /** The lower boundary. */
+ private final int low;
+ /** The upper boundary. */
+ private final int high;
+
+ /**
+ * Creates a new range.
+ * @param from the lower inclusive boundary
+ * @param to the higher inclusive boundary
+ */
+ public IntegerRange(int from, int to) {
+ low = from;
+ high = to;
+ }
+
+ @Override
+ public Iterator<Integer> iterator() {
+ return new IntegerIterator(low, high);
+ }
+}
+
+/**
+ * An iterator on an integer range.
+ */
+class IntegerIterator implements Iterator<Integer> {
+ /** The lower boundary. */
+ private final int low;
+ /** The upper boundary. */
+ private final int high;
+ /** The current value. */
+ private int cursor;
+ /**
+ * Creates a iterator on the range.
+ * @param l low boundary
+ * @param h high boundary
+ */
+ public IntegerIterator(int l, int h) {
+ low = l;
+ high = h;
+ cursor = low;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return cursor <= high;
+ }
+
+ @Override
+ public Integer next() {
+ if (cursor <= high) {
+ int next = cursor;
+ cursor += 1;
+ return Integer.valueOf(next);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+}
Propchange: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/IntegerRange.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java Thu Jul 5 07:08:06 2012
@@ -40,6 +40,7 @@ import org.apache.commons.jexl3.parser.A
import org.apache.commons.jexl3.parser.ASTDivNode;
import org.apache.commons.jexl3.parser.ASTEQNode;
import org.apache.commons.jexl3.parser.ASTERNode;
+import org.apache.commons.jexl3.parser.ASTEWNode;
import org.apache.commons.jexl3.parser.ASTEmptyFunction;
import org.apache.commons.jexl3.parser.ASTEmptyMethod;
import org.apache.commons.jexl3.parser.ASTFalseNode;
@@ -72,6 +73,8 @@ import org.apache.commons.jexl3.parser.A
import org.apache.commons.jexl3.parser.ASTSizeMethod;
import org.apache.commons.jexl3.parser.ASTStringLiteral;
import org.apache.commons.jexl3.parser.ASTSubNode;
+import org.apache.commons.jexl3.parser.ASTSWNode;
+import org.apache.commons.jexl3.parser.ASTRangeNode;
import org.apache.commons.jexl3.parser.ASTTernaryNode;
import org.apache.commons.jexl3.parser.ASTTrueNode;
import org.apache.commons.jexl3.parser.ASTUnaryMinusNode;
@@ -322,17 +325,17 @@ public class Interpreter extends ParserV
@Override
protected Object visit(ASTArrayLiteral node, Object data) {
- Object literal = node.getLiteral();
- if (literal == null) {
- int childCount = node.jjtGetNumChildren();
- Object[] array = new Object[childCount];
+ int childCount = node.jjtGetNumChildren();
+ JexlArithmetic.ArrayBuilder ab = arithmetic.arrayBuilder(childCount);
+ if (ab != null) {
for (int i = 0; i < childCount; i++) {
Object entry = node.jjtGetChild(i).jjtAccept(this, data);
- array[i] = entry;
+ ab.add(entry);
}
- literal = arithmetic.narrowArrayType(array);
+ return ab.create();
+ } else {
+ return null;
}
- return literal;
}
@Override
@@ -500,10 +503,87 @@ public class Interpreter extends ParserV
}
@Override
- protected Object visit(ASTERNode node, Object data) {
+ protected Object visit(ASTSWNode node, Object data) {
Object left = node.jjtGetChild(0).jjtAccept(this, data);
Object right = node.jjtGetChild(1).jjtAccept(this, data);
try {
+ if (left == null || right == null) {
+ return false;
+ }
+ if (left instanceof String) {
+ return ((String) left).startsWith(arithmetic.toString(right));
+ } else {
+ // try a startsWith method (duck type)
+ try {
+ Object[] argv = {right};
+ JexlMethod vm = uberspect.getMethod(left, "startsWith", argv);
+ if (vm != null) {
+ return arithmetic.toBoolean(vm.invoke(left, argv)) ? Boolean.TRUE : Boolean.FALSE;
+ } else if (arithmetic.narrowArguments(argv)) {
+ vm = uberspect.getMethod(left, "startsWith", argv);
+ if (vm != null) {
+ return arithmetic.toBoolean(vm.invoke(left, argv)) ? Boolean.TRUE : Boolean.FALSE;
+ }
+ }
+ } catch (InvocationTargetException e) {
+ throw new JexlException(node, "=^ invocation error", e.getCause());
+ } catch (Exception e) {
+ throw new JexlException(node, "=^ error", e);
+ }
+ }
+ // defaults to equal
+ return arithmetic.equals(left, right) ? Boolean.TRUE : Boolean.FALSE;
+ } catch (ArithmeticException xrt) {
+ throw new JexlException(node, "=^ error", xrt);
+ }
+ }
+
+ @Override
+ protected Object visit(ASTEWNode node, Object data) {
+ Object left = node.jjtGetChild(0).jjtAccept(this, data);
+ Object right = node.jjtGetChild(1).jjtAccept(this, data);
+ try {
+ if (left == null || right == null) {
+ return false;
+ }
+ if (left instanceof String) {
+ return ((String) left).endsWith(arithmetic.toString(right));
+ } else {
+ // try a endsWith method (duck type)
+ try {
+ Object[] argv = {right};
+ JexlMethod vm = uberspect.getMethod(left, "endsWith", argv);
+ if (vm != null) {
+ return arithmetic.toBoolean(vm.invoke(left, argv)) ? Boolean.TRUE : Boolean.FALSE;
+ } else if (arithmetic.narrowArguments(argv)) {
+ vm = uberspect.getMethod(left, "endsWith", argv);
+ if (vm != null) {
+ return arithmetic.toBoolean(vm.invoke(left, argv)) ? Boolean.TRUE : Boolean.FALSE;
+ }
+ }
+ } catch (InvocationTargetException e) {
+ throw new JexlException(node, "=$ invocation error", e.getCause());
+ } catch (Exception e) {
+ throw new JexlException(node, "=$ error", e);
+ }
+ // defaults to equal
+ return arithmetic.equals(left, right) ? Boolean.TRUE : Boolean.FALSE;
+ }
+ } catch (ArithmeticException xrt) {
+ throw new JexlException(node, "=$ error", xrt);
+ }
+ }
+
+ /**
+ * The 'match'/'in' operator implementation.
+ * @param node the node
+ * @param op the calling operator, =~ or !=
+ * @param left the left operand
+ * @param right the right operand
+ * @return true if left matches right, false otherwise
+ */
+ protected Object matches(JexlNode node, String op, Object left, Object right) {
+ try {
// use arithmetic / pattern matching ?
if (right instanceof java.util.regex.Pattern || right instanceof String) {
return arithmetic.matches(left, right) ? Boolean.TRUE : Boolean.FALSE;
@@ -534,9 +614,9 @@ public class Interpreter extends ParserV
}
}
} catch (InvocationTargetException e) {
- throw new JexlException(node, "=~ invocation error", e.getCause());
+ throw new JexlException(node, op +" invocation error", e.getCause());
} catch (Exception e) {
- throw new JexlException(node, "=~ error", e);
+ throw new JexlException(node, op + " error", e);
}
// try iterative comparison
Iterator<?> it = uberspect.getIterator(right);
@@ -552,11 +632,26 @@ public class Interpreter extends ParserV
// defaults to equal
return arithmetic.equals(left, right) ? Boolean.TRUE : Boolean.FALSE;
} catch (ArithmeticException xrt) {
- throw new JexlException(node, "=~ error", xrt);
+ throw new JexlException(node, op + " error", xrt);
}
}
@Override
+ protected Object visit(ASTERNode node, Object data) {
+ Object left = node.jjtGetChild(0).jjtAccept(this, data);
+ Object right = node.jjtGetChild(1).jjtAccept(this, data);
+ return matches(node, "=~", left, right);
+ }
+
+ @Override
+ protected Object visit(ASTNRNode node, Object data) {
+ Object left = node.jjtGetChild(0).jjtAccept(this, data);
+ Object right = node.jjtGetChild(1).jjtAccept(this, data);
+ Object result = matches(node, "!~", left, right);
+ return arithmetic.toBoolean(result) ? Boolean.FALSE : Boolean.TRUE;
+ }
+
+ @Override
protected Object visit(ASTIfStatement node, Object data) {
int n = 0;
try {
@@ -621,14 +716,28 @@ public class Interpreter extends ParserV
@Override
protected Object visit(ASTMapLiteral node, Object data) {
int childCount = node.jjtGetNumChildren();
- Map<Object, Object> map = new HashMap<Object, Object>();
-
- for (int i = 0; i < childCount; i++) {
- Object[] entry = (Object[]) (node.jjtGetChild(i)).jjtAccept(this, data);
- map.put(entry[0], entry[1]);
+ JexlArithmetic.MapBuilder mb = arithmetic.mapBuilder(childCount);
+ if (mb != null) {
+ for (int i = 0; i < childCount; i++) {
+ Object[] entry = (Object[]) (node.jjtGetChild(i)).jjtAccept(this, data);
+ mb.put(entry[0], entry[1]);
+ }
+ return mb.create();
+ } else {
+ return null;
}
+ }
- return map;
+ @Override
+ protected Object visit(ASTRangeNode node, Object data) {
+ Object left = node.jjtGetChild(0).jjtAccept(this, data);
+ Object right = node.jjtGetChild(1).jjtAccept(this, data);
+ try {
+ return arithmetic.createRange(left, right);
+ } catch (ArithmeticException xrt) {
+ JexlNode xnode = findNullOperand(xrt, node, left, right);
+ throw new JexlException(xnode, ".. error", xrt);
+ }
}
@Override
@@ -671,62 +780,6 @@ public class Interpreter extends ParserV
}
@Override
- protected Object visit(ASTNRNode node, Object data) {
- Object left = node.jjtGetChild(0).jjtAccept(this, data);
- Object right = node.jjtGetChild(1).jjtAccept(this, data);
- try {
- if (right instanceof java.util.regex.Pattern || right instanceof String) {
- // use arithmetic / pattern matching
- return arithmetic.matches(left, right) ? Boolean.FALSE : Boolean.TRUE;
- }
- // try contains on collection
- if (right instanceof Set<?>) {
- return ((Set<?>) right).contains(left) ? Boolean.FALSE : Boolean.TRUE;
- }
- // try contains on map key
- if (right instanceof Map<?, ?>) {
- return ((Map<?, ?>) right).containsKey(left) ? Boolean.FALSE : Boolean.TRUE;
- }
- // try contains on collection
- if (right instanceof Collection<?>) {
- return ((Collection<?>) right).contains(left) ? Boolean.FALSE : Boolean.TRUE;
- }
- // try a contains method (duck type set)
- try {
- Object[] argv = {left};
- JexlMethod vm = uberspect.getMethod(right, "contains", argv);
- if (vm != null) {
- return arithmetic.toBoolean(vm.invoke(right, argv)) ? Boolean.FALSE : Boolean.TRUE;
- } else if (arithmetic.narrowArguments(argv)) {
- vm = uberspect.getMethod(right, "contains", argv);
- if (vm != null) {
- return arithmetic.toBoolean(vm.invoke(right, argv)) ? Boolean.FALSE : Boolean.TRUE;
- }
- }
- } catch (InvocationTargetException e) {
- throw new JexlException(node, "!~ invocation error", e.getCause());
- } catch (Exception e) {
- throw new JexlException(node, "!~ error", e);
- }
- // try iterative comparison
- Iterator<?> it = uberspect.getIterator(right);//, node.jjtGetChild(1));
- if (it != null) {
- while (it.hasNext()) {
- Object next = it.next();
- if (next == left || (next != null && next.equals(left))) {
- return Boolean.FALSE;
- }
- }
- return Boolean.TRUE;
- }
- // defaults to not equal
- return arithmetic.equals(left, right) ? Boolean.FALSE : Boolean.TRUE;
- } catch (ArithmeticException xrt) {
- throw new JexlException(node, "!~ error", xrt);
- }
- }
-
- @Override
protected Object visit(ASTNotNode node, Object data) {
Object val = node.jjtGetChild(0).jjtAccept(this, data);
return arithmetic.toBoolean(val) ? Boolean.FALSE : Boolean.TRUE;
Added: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/MapBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/MapBuilder.java?rev=1357476&view=auto
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/MapBuilder.java (added)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/MapBuilder.java Thu Jul 5 07:08:06 2012
@@ -0,0 +1,48 @@
+/*
+ * 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.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.jexl3.JexlArithmetic;
+
+/**
+ * Helper class to create map literals.
+ */
+public class MapBuilder implements JexlArithmetic.MapBuilder {
+ /** The map being created. */
+ private final Map<Object, Object> map;
+
+ /**
+ * Creates a new builder.
+ * @param size the expected map size
+ */
+ public MapBuilder(int size) {
+ map = new HashMap<Object, Object>(size);
+ }
+
+ @Override
+ public void put(Object key, Object value) {
+ map.put(key, value);
+ }
+
+ @Override
+ public Object create() {
+ return map;
+ }
+
+}
Propchange: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/MapBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Script.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Script.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Script.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Script.java Thu Jul 5 07:08:06 2012
@@ -103,7 +103,7 @@ public class Script implements JexlScrip
@Override
public String getParsedText() {
Debugger debug = new Debugger();
- boolean d = debug.debug(script);
+ debug.debug(script);
return debug.toString();
}
@@ -112,7 +112,7 @@ public class Script implements JexlScrip
CharSequence src = source;
if (src == null) {
Debugger debug = new Debugger();
- boolean d = debug.debug(script);
+ debug.debug(script);
src = debug.toString();
}
return src == null ? "/*no source*/" : src.toString();
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ArrayListWrapper.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ArrayListWrapper.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ArrayListWrapper.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ArrayListWrapper.java Thu Jul 5 07:08:06 2012
@@ -22,6 +22,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
+import java.util.RandomAccess;
/**
* A class that wraps an array within an AbstractList.
@@ -30,7 +31,7 @@ import java.util.ListIterator;
* for any method is thus always ArrayListWrapper.
* </p>
*/
-public class ArrayListWrapper extends AbstractList<Object> {
+public class ArrayListWrapper extends AbstractList<Object> implements RandomAccess {
/** the array to wrap. */
private final Object array;
@@ -115,7 +116,7 @@ public class ArrayListWrapper extends Ab
public boolean contains(Object o) {
return indexOf(o) != -1;
}
-
+
@Override
public boolean isEmpty() {
return super.isEmpty();
@@ -125,7 +126,7 @@ public class ArrayListWrapper extends Ab
public Iterator<Object> iterator() {
return super.iterator();
}
-
+
@Override
public boolean containsAll(Collection<?> c) {
return super.containsAll(c);
@@ -150,7 +151,7 @@ public class ArrayListWrapper extends Ab
public List<Object> subList(int fromIndex, int toIndex) {
return super.subList(fromIndex, toIndex);
}
-
+
@Override
public boolean add(Object o) {
throw new UnsupportedOperationException("Not supported.");
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/SandboxUberspect.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/SandboxUberspect.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/SandboxUberspect.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/SandboxUberspect.java Thu Jul 5 07:08:06 2012
@@ -29,9 +29,9 @@ import org.apache.commons.jexl3.introspe
*/
public final class SandboxUberspect implements JexlUberspect {
/** The base uberspect. */
- protected final JexlUberspect uberspect;
+ private final JexlUberspect uberspect;
/** The sandbox. */
- protected final JexlSandbox sandbox;
+ private final JexlSandbox sandbox;
/**
* A constructor for JexlSandbox uberspect.
@@ -127,7 +127,7 @@ public final class SandboxUberspect impl
return null;
}
-
+
/**
* {@inheritDoc}
*/
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/package.html
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/package.html?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/package.html (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/package.html Thu Jul 5 07:08:06 2012
@@ -311,7 +311,8 @@
<h3><a name="dynamic_configuration">Dynamic Configuration</a></h3>
<p>
- Those configuration options can be overriden during evaluation by implementing a {@link org.apache.commons.jexl3.JexlContext}
+ Those configuration options can be overriden during evaluation by implementing a
+ {@link org.apache.commons.jexl3.JexlContext}
that also implements {@link org.apache.commons.jexl3.JexlEngine$Options} to carry evaluation options.
An example of such a class exists in the test package.
</p>
@@ -346,12 +347,16 @@
<p>
{@link org.apache.commons.jexl3.JexlArithmetic}
is the class to derive if you need to change how operators behave or add types upon which they
- operate. For example, this would
- be the case if you wanted '+' to operate on arrays; you'd need to derive JexlArithmetic and
- implement your own version of Add.
- Note however that you can not change the operator precedence.
-
+ operate.
+ For example, this would be the case if you wanted '+' to operate on arrays; you'd need to derive
+ JexlArithmetic and implement your own version of Add.
+
+ There are 3 entry points that allow customizing the type of objects created for respectively
+ array literals {@link org.apache.commons.jexl3.JexlArithmetic#arrayBuilder},
+ map literals {@link org.apache.commons.jexl3.JexlArithmetic#mapBuilder}
+ and range objects {@link org.apache.commons.jexl3.JexlArithmetic#createRange}.
+ Note however that you can <em>not</em> change the operator precedence.
</p>
<h2><a name="extension">Extending JEXL</a></h2>
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=1357476&r1=1357475&r2=1357476&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 Thu Jul 5 07:08:06 2012
@@ -16,12 +16,9 @@
*/
package org.apache.commons.jexl3.parser;
-import org.apache.commons.jexl3.JexlArithmetic;
import org.apache.commons.jexl3.internal.Debugger;
-public final class ASTArrayLiteral extends JexlNode implements JexlNode.Literal<Object> {
- /** The type literal value. */
- private Object array = null;
+public final class ASTArrayLiteral extends JexlNode {
/** Whether this array is constant or not. */
private boolean constant = false;
@@ -40,31 +37,29 @@ public final class ASTArrayLiteral exten
}
@Override
- public Object getLiteral() {
- return array;
+ protected boolean isConstant(boolean literal) {
+ return constant;
}
- /** {@inheritDoc} */
+ /** {
+ * @inheritDoc} */
@Override
public void jjtClose() {
- if (children == null || children.length == 0) {
- array = new Object[0];
- constant = true;
- } else {
- constant = isConstant();
- if (constant) {
- Object[] cc = new Object[children.length];
- for(int c = 0; c < children.length; ++c) {
- cc[c] = ((JexlNode.Literal<?>) children[c]).getLiteral();
+ constant = true;
+ if (children != null) {
+ for (int c = 0; c < children.length && constant; ++c) {
+ JexlNode child = children[c];
+ if (child instanceof ASTReference) {
+ constant = child.isConstant(true);
+ } else if (!child.isConstant()) {
+ constant = false;
}
- array = JexlArithmetic.typeArray(cc);
- } else {
- array = null;
}
}
}
- /** {@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/ASTMapLiteral.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTMapLiteral.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTMapLiteral.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTMapLiteral.java Thu Jul 5 07:08:06 2012
@@ -16,13 +16,9 @@
*/
package org.apache.commons.jexl3.parser;
-import java.util.Collections;
-import java.util.Map;
import org.apache.commons.jexl3.internal.Debugger;
-public final class ASTMapLiteral extends JexlNode implements JexlNode.Literal<Object> {
- /** The type literal value. */
- private Map<?,?> map = null;
+public final class ASTMapLiteral extends JexlNode {
/** Whether this array is constant or not. */
private boolean constant = false;
@@ -34,7 +30,6 @@ public final class ASTMapLiteral extends
super(p, id);
}
-
@Override
public String toString() {
Debugger dbg = new Debugger();
@@ -42,21 +37,23 @@ public final class ASTMapLiteral extends
}
@Override
- public Map<?,?> getLiteral() {
- return map;
+ protected boolean isConstant(boolean literal) {
+ return constant;
}
- /**
- * Sets the literal value only if the descendants of this node compose a constant.
- * @param literal the literal array value
- * @throws IllegalArgumentException if literal is not an array or null
- */
- void setLiteral(Object literal) {
- if (constant) {
- if (!(literal instanceof Map<?,?>)) {
- throw new IllegalArgumentException(literal.getClass() + " is not a map");
+ /** {@inheritDoc} */
+ @Override
+ public void jjtClose() {
+ constant = true;
+ if (children != null) {
+ for (int c = 0; c < children.length && constant; ++c) {
+ JexlNode child = children[c];
+ if (child instanceof ASTMapEntry) {
+ constant = child.isConstant(true);
+ } else if (!child.isConstant()) {
+ constant = false;
+ }
}
- this.map = (Map<?,?>) literal;
}
}
@@ -66,14 +63,4 @@ public final class ASTMapLiteral extends
return visitor.visit(this, data);
}
- /** {@inheritDoc} */
- @Override
- public void jjtClose() {
- if (children == null || children.length == 0) {
- map = Collections.EMPTY_MAP;
- constant = true;
- } else {
- constant = isConstant();
- }
- }
}
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=1357476&r1=1357475&r2=1357476&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 Thu Jul 5 07:08:06 2012
@@ -18,8 +18,9 @@ package org.apache.commons.jexl3.parser;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.text.DecimalFormat;
-public final class ASTNumberLiteral extends JexlNode implements JexlNode.Literal<Number> {
+public final class ASTNumberLiteral extends JexlNode implements JexlNode.Constant<Number> {
/** The type literal value. */
private Number literal = null;
/** The expected class. */
@@ -33,23 +34,29 @@ public final class ASTNumberLiteral exte
super(p, id);
}
+ static final DecimalFormat BIGDF = new DecimalFormat("0.0b");
+
@Override
public String toString() {
- 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');
+ 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');
+ }
}
+ return strb.toString();
}
- return strb.toString();
}
@Override
@@ -57,7 +64,6 @@ public final class ASTNumberLiteral exte
return literal;
}
- /** {@inheritDoc} */
@Override
protected boolean isConstant(boolean literal) {
return true;
@@ -127,43 +133,47 @@ public final class ASTNumberLiteral exte
* Originally from OGNL.
* @param s the real as string
*/
- void setReal(String s) {
+ void setReal(String s) {
Number result;
Class<?> rclass;
- final int last = s.length() - 1;
- switch (s.charAt(last)) {
- case 'b':
- case 'B': {
- rclass = BigDecimal.class;
- result = new BigDecimal(s.substring(0, last));
- break;
- }
- case 'f':
- case 'F': {
- rclass = Float.class;
- result = Float.valueOf(s.substring(0, last));
- break;
- }
- case 'd':
- case 'D':
- rclass = Double.class;
- result = Double.valueOf(s.substring(0, last));
- break;
- default: {
- rclass = Double.class;
- try {
- result = Double.valueOf(s);
- } catch (NumberFormatException take3) {
- result = new BigDecimal(s);
+ if ("#NaN".equals(s)) {
+ result = Double.NaN;
+ rclass = Double.class;
+ } else {
+ final int last = s.length() - 1;
+ switch (s.charAt(last)) {
+ case 'b':
+ case 'B': {
+ rclass = BigDecimal.class;
+ result = new BigDecimal(s.substring(0, last));
+ break;
+ }
+ case 'f':
+ case 'F': {
+ rclass = Float.class;
+ result = Float.valueOf(s.substring(0, last));
+ break;
+ }
+ case 'd':
+ case 'D':
+ rclass = Double.class;
+ result = Double.valueOf(s.substring(0, last));
+ break;
+ default: {
+ rclass = Double.class;
+ try {
+ result = Double.valueOf(s);
+ } catch (NumberFormatException take3) {
+ result = new BigDecimal(s);
+ }
+ break;
}
- break;
}
}
literal = result;
clazz = rclass;
}
- /** {@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/ASTStringLiteral.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTStringLiteral.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTStringLiteral.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ASTStringLiteral.java Thu Jul 5 07:08:06 2012
@@ -16,7 +16,7 @@
*/
package org.apache.commons.jexl3.parser;
-public final class ASTStringLiteral extends JexlNode implements JexlNode.Literal<String> {
+public final class ASTStringLiteral extends JexlNode implements JexlNode.Constant<String> {
ASTStringLiteral(int id) {
super(id);
@@ -46,7 +46,7 @@ public final class ASTStringLiteral exte
protected boolean isConstant(boolean literal) {
return true;
}
-
+
void setLiteral(String literal) {
value = literal;
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java Thu Jul 5 07:08:06 2012
@@ -16,6 +16,7 @@
*/
package org.apache.commons.jexl3.parser;
+import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.JexlInfo;
import org.apache.commons.jexl3.introspection.JexlMethod;
import org.apache.commons.jexl3.introspection.JexlPropertyGet;
@@ -28,11 +29,10 @@ import org.apache.commons.jexl3.introspe
*/
public abstract class JexlNode extends SimpleNode {
/**
- * A marker interface for literals.
- *
+ * A marker interface for constants.
* @param <T> the literal type
*/
- public interface Literal<T> {
+ public interface Constant<T> {
T getLiteral();
}
@@ -84,8 +84,8 @@ public abstract class JexlNode extends S
*
* @return true if constant, false otherwise
*/
- public final boolean isConstant() {
- return isConstant(this instanceof JexlNode.Literal<?>);
+ public boolean isConstant() {
+ return isConstant(this instanceof JexlNode.Constant<?>);
}
protected boolean isConstant(boolean literal) {
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java Thu Jul 5 07:08:06 2012
@@ -16,6 +16,9 @@
*/
package org.apache.commons.jexl3.parser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.JexlInfo;
import org.apache.commons.jexl3.internal.Scope;
@@ -26,6 +29,10 @@ import java.util.Stack;
* The base class for parsing, manages the parameter/local variable frame.
*/
public abstract class JexlParser extends StringParser {
+ /** Whether the parser will allow user-named registers (aka #0 syntax). */
+ protected boolean ALLOW_REGISTERS = false;
+ /** The source being processed. */
+ protected String source = null;
/**
* The map of named registers aka script parameters.
* <p>Each parameter is associated to a register and is materialized
@@ -34,6 +41,14 @@ public abstract class JexlParser extends
protected Scope frame = null;
protected Stack<Scope> frames = new Stack<Scope>();
+
+ /**
+ * Internal, for debug purpose only.
+ */
+ public void allowRegisters(boolean registers) {
+ ALLOW_REGISTERS = registers;
+ }
+
/**
* Sets the frame to use by this parser.
* <p> This is used to allow parameters to be declared before parsing. </p>
@@ -77,7 +92,7 @@ public abstract class JexlParser extends
/**
* Checks whether an identifier is a local variable or argument, ie a symbol, stored in a register.
* @param identifier the identifier
- * @param image the identifier image
+ * @param image the identifier image
* @return the image
*/
public String checkVariable(ASTIdentifier identifier, String image) {
@@ -94,7 +109,7 @@ public abstract class JexlParser extends
* Declares a local variable.
* <p> This method creates an new entry in the symbol map. </p>
* @param identifier the identifier used to declare
- * @param image the variable name
+ * @param image the variable name
*/
public void declareVariable(ASTVar identifier, String image) {
if (frame == null) {
@@ -150,27 +165,48 @@ public abstract class JexlParser extends
script.setScope(frame);
}
popFrame();
- } else if (node instanceof ASTAmbiguous && node.jjtGetNumChildren() > 0) {
- final JexlInfo dbgInfo;
- Token tok = this.getToken(0);
- if (tok != null) {
- dbgInfo = new JexlInfo(tok.image, tok.beginLine, tok.beginColumn);
- } else {
- dbgInfo = node.jexlInfo();
- }
- throw new JexlException.Parsing(dbgInfo, "Ambiguous statement, missing ';' between expressions");
+ } else if (node instanceof ASTAmbiguous) {
+ throwParsingException(JexlException.Ambiguous.class, node);
} else if (node instanceof ASTAssignment) {
JexlNode lv = node.jjtGetChild(0);
if (!lv.isLeftValue()) {
- final JexlInfo dbgInfo;
- Token tok = this.getToken(0);
- if (tok != null) {
- dbgInfo = new JexlInfo(tok.image, tok.beginLine, tok.beginColumn);
- } else {
- dbgInfo = node.jexlInfo();
+ throwParsingException(JexlException.Assignment.class, lv);
+ }
+ }
+ }
+
+ /**
+ * Throws a parsing exception.
+ * @param xclazz the class of exception
+ * @param node the node that provoqued it
+ */
+ private void throwParsingException(Class<? extends JexlException> xclazz, JexlNode node) {
+ final JexlInfo dbgInfo;
+ Token tok = this.getToken(0);
+ if (tok != null) {
+ dbgInfo = new JexlInfo(tok.image, tok.beginLine, tok.beginColumn);
+ } else {
+ dbgInfo = node.jexlInfo();
+ }
+ String msg = null;
+ try {
+ if (source != null) {
+ BufferedReader reader = new BufferedReader(new StringReader(source));
+ for (int l = 0; l < dbgInfo.getLine(); ++l) {
+ msg = reader.readLine();
}
- throw new JexlException.Parsing(dbgInfo, "Invalid assignment expression");
+ } else {
+ msg = "";
}
+ } catch (IOException xio) {
+ // ignore
+ }
+ if (JexlException.Ambiguous.class.equals(xclazz)) {
+ throw new JexlException.Ambiguous(dbgInfo, msg);
+ }
+ if (JexlException.Assignment.class.equals(xclazz)) {
+ throw new JexlException.Assignment(dbgInfo, msg);
}
+ throw new JexlException.Parsing(dbgInfo, msg);
}
}
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=1357476&r1=1357475&r2=1357476&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 Thu Jul 5 07:08:06 2012
@@ -38,16 +38,15 @@ import org.apache.commons.jexl3.internal
public final class Parser extends JexlParser
{
- private boolean ALLOW_REGISTERS = false;
-
- public ASTJexlScript parse(JexlInfo info, Reader reader, Scope scope, boolean registers) {
+ public ASTJexlScript parse(JexlInfo info, String jexlSrc, Scope scope, boolean registers) {
try {
// If registers are allowed, the default parser state has to be REGISTERS.
if (registers || ALLOW_REGISTERS) {
token_source.defaultLexState = REGISTERS;
}
// lets do the 'Unique Init' in here to be safe - it's a pain to remember
- ReInit(reader);
+ source = jexlSrc;
+ ReInit(new java.io.StringReader(jexlSrc));
frame = scope;
ASTJexlScript script = JexlScript(scope);
script.value = info;
@@ -57,18 +56,11 @@ public final class Parser extends JexlPa
} catch (ParseException xparse) {
throw new JexlException.Parsing(info, xparse).clean();
} finally {
+ source = null;
frame = null;
token_source.defaultLexState = DEFAULT;
}
}
-
- /**
- * Internal, for debug purpose only.
- */
- public void allowRegisters(boolean registers) {
- ALLOW_REGISTERS = registers;
- }
-
}
PARSER_END(Parser)
@@ -139,6 +131,8 @@ PARSER_END(Parser)
| < ne : "!=" | "ne" >
| < req : "=~" >
| < rne : "!~" >
+ | < sw : "=^" >
+ | < ew : "=$" >
| < gt : ">" | "gt" >
| < ge : ">=" | "ge" >
| < lt : "<" | "lt" >
@@ -157,6 +151,7 @@ PARSER_END(Parser)
| < and : "&" >
| < or : "|" >
| < xor : "^" >
+ | < range : ".." >
}
/***************************************
@@ -184,7 +179,10 @@ PARSER_END(Parser)
(["l","L","h","H"])?
>
|
- < FLOAT_LITERAL: (<DIGIT>)+ "." (<DIGIT>)+ ((["e","E"])(["+","-"])?(<DIGIT>)+)? (["d","D","f","F","b","B"])? >
+ < FLOAT_LITERAL:
+ "#NaN"
+ |
+ (<DIGIT>)+ "." (<DIGIT>)+ ((["e","E"])(["+","-"])?(<DIGIT>)+)? (["d","D","f","F","b","B"])? >
}
<*> TOKEN :
@@ -338,8 +336,10 @@ void EqualityExpression() #void : {}
RelationalExpression()
(
<eq> RelationalExpression() #EQNode(2)
-|
+ |
<ne> RelationalExpression() #NENode(2)
+ |
+ <range> RelationalExpression() #RangeNode(2) // range
)?
}
@@ -358,6 +358,10 @@ void RelationalExpression() #void : {}
<req> AdditiveExpression() #ERNode(2) // equals regexp
|
<rne> AdditiveExpression() #NRNode(2) // not equals regexp
+ |
+ <sw> AdditiveExpression() #SWNode(2) // starts with
+ |
+ <ew> AdditiveExpression() #EWNode(2) // ends with
)?
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java Thu Jul 5 07:08:06 2012
@@ -85,6 +85,10 @@ public abstract class ParserVisitor {
protected abstract Object visit(ASTNRNode node, Object data);
+ protected abstract Object visit(ASTSWNode node, Object data);
+
+ protected abstract Object visit(ASTEWNode node, Object data);
+
protected abstract Object visit(ASTAddNode node, Object data);
protected abstract Object visit(ASTSubNode node, Object data);
@@ -115,6 +119,8 @@ public abstract class ParserVisitor {
protected abstract Object visit(ASTArrayLiteral node, Object data);
+ protected abstract Object visit(ASTRangeNode node, Object data);
+
protected abstract Object visit(ASTMapLiteral node, Object data);
protected abstract Object visit(ASTMapEntry node, Object data);
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=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/jexl/trunk/src/site/xdoc/changes.xml Thu Jul 5 07:08:06 2012
@@ -2,22 +2,22 @@
<!--
/*
- * 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.
- */
- -->
+* 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.
+*/
+-->
<document>
<properties>
@@ -25,7 +25,13 @@
<author email="dev@commons.apache.org">Commons Developers</author>
</properties>
<body>
- <release version="3.0" date="2012-06-01">
+ <release version="3.0" date="2012-07-30">
+ <action dev="henrib" type="add" issue="JEXL-131" due-to="Alfred Reibenschuh">
+ String matching Operator short-hand inspired by CSS3
+ </action>
+ <action dev="henrib" type="add" >
+ Range operator
+ </action>
<action dev="henrib" type="add" issue="JEXL-128" due-to="Matteo Trotta">
ObjectContext should implement NamespaceResolver
</action>
@@ -39,7 +45,10 @@
Move JEXL from org.apache.comms.jexl2 to org.apache.commons.jexl3
</action>
</release>
- <release version="2.1.2" date="2012-05-30">
+ <release version="2.1.2" date="2012-07-30">
+ <action dev="henrib" type="fix" issue="JEXL-134" due-to="Manoj Mokashi">
+ Issue with evaluation of concat of variables : \r + \n gives 0
+ </action>
<action dev="henrib" type="fix" issue="JEXL-131" due-to="Clay Bruce">
UnifiedJexl parsing may fail with NPE
</action>
Modified: commons/proper/jexl/trunk/src/site/xdoc/reference/syntax.xml
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/site/xdoc/reference/syntax.xml?rev=1357476&r1=1357475&r2=1357476&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/site/xdoc/reference/syntax.xml (original)
+++ commons/proper/jexl/trunk/src/site/xdoc/reference/syntax.xml Thu Jul 5 07:08:06 2012
@@ -327,7 +327,7 @@
Those variables values are bound in the function environment at definition time.</p>
<code>var t = 20; var s = function(x, y) {x + y + t}; t = 54; s(15, 7)</code>
The function closure hoists 't' when defined; the result of the evaluation will
- lead to <code>15 +7 + 20 = 42</code>.
+ lead to <code>15 +7 + 20 = 42</code>.
</td>
</tr>
</table>
@@ -485,12 +485,40 @@
For example
<code>"abcdef" !~ "abc.*</code> returns <code>false</code>.
It also checks whether any collection, set or map (on keys) does not contain a value; in that case, it behaves
- as "not in" operator. Note that it also applies to arrays as well as "duck-typed" collection, ie classes exposing a "contains"
- method.
+ as "not in" operator.
<code> "a" !~ ["a","b","c","d","e",f"]</code> returns <code>true</code>.
+ Note that through duck-typing, user classes exposing a public 'contains' method will allow their instances
+ to behave has right-hand-size operands of this operator.
+ </td>
+ </tr>
+ <tr>
+ <td>Starts With<code>=^</code></td>
+ <td>
+ The syntactically CSS3 inspired <code>=^</code> operator is a short-hand for the 'startsWith' method.
+ For example,
+ <code> "abcdef" ^= "abc" </code> returns <code>true</code>.
+ Note that through duck-typing, user classes exposing a public 'startsWith' method will allow their instances
+ to behave has left-hand-size operands of this operator.
</td>
</tr>
<tr>
+ <td>Ends With<code>=$</code></td>
+ <td>The syntactically CSS3 inspired <code>=$</code> operator is a short-hand for the 'endsWith' method.
+ For example,
+ <code> "abcdef" $= "def" </code> returns <code>true</code>.
+ Note that through duck-typing, user classes exposing an 'endsWith' method will allow their instances
+ to behave has left-hand-size operands of this operator.
+ </td>
+ </tr>
+ <tr>
+ <td>Range<code>..</code></td>
+ <td>
+ This operator creates a 'range' of values (in the form of a java iterable).
+ For example,
+ <code>for(var x: 1 .. 3) {}</code> will loop 3 times with the value of 'x' being 1, 2 and 3.
+ </td>
+ </tr>
+ <tr>
<td>Addition</td>
<td>
The usual <code>+</code> operator is used.
@@ -579,7 +607,7 @@
<td>
Loop through items of an Array, Collection, Map, Iterator or Enumeration, e.g.
<source>for(item : list) {
- x = x + item;
+ x = x + item;
}</source>
Where <code>item</code> and <code>list</code> are variables.
The JEXL 1.1 syntax using <code>foreach(item in list)</code> is now <strong>deprecated</strong>.
@@ -590,7 +618,7 @@
<td>
Loop until a condition is satisfied, e.g.
<source>while (x lt 10) {
- x = x + 2;
+ x = x + 2;
}</source>
</td>
</tr>