You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ra...@apache.org on 2009/07/17 20:41:00 UTC
svn commit: r795190 - in /commons/proper/jexl/branches/2.0/src:
java/org/apache/commons/jexl/ java/org/apache/commons/jexl/parser/
java/org/apache/commons/jexl/util/ test/org/apache/commons/jexl/
Author: rahul
Date: Fri Jul 17 18:40:59 2009
New Revision: 795190
URL: http://svn.apache.org/viewvc?rev=795190&view=rev
Log:
UnifiedJEXL improvements:
- Better names for inner classes
- More test coverage, and some fixes
- Factor String parsing utilities in new class (StringParser)
Slightly modified version of patch thanks to Henri Biestro <hbiestro at gmail dot com>.
JEXL-58
Added:
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/StringParser.java (with props)
Modified:
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/Parser.jjt
commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/UnifiedJEXLTest.java
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java?rev=795190&r1=795189&r2=795190&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java Fri Jul 17 18:40:59 2009
@@ -21,6 +21,7 @@
import java.util.ArrayList;
import org.apache.commons.jexl.parser.SimpleNode;
import org.apache.commons.jexl.parser.ParseException;
+import org.apache.commons.jexl.util.StringParser;
/**
* An evaluator similar to the unified EL evaluator used in JSP/JSF based on JEXL.
@@ -173,7 +174,7 @@
// if only one sub-expr, no need to create a composite
return (expressions.size() == 1)?
expressions.get(0) :
- el.new Composite(counts, expressions, source);
+ el.new CompositeExpression(counts, expressions, source);
}
}
@@ -199,21 +200,41 @@
* The abstract base class for all expressions, immediate '${...}' and deferred '#{...}'.
*/
public abstract class Expression {
- final Expression source;
+ protected final Expression source;
Expression(Expression source) {
this.source = source != null ? source : this;
}
+ @Override
+ public String toString() {
+ StringBuilder strb = new StringBuilder();
+ if (source != this) {
+ strb.append(source.toString());
+ strb.append(" /*= ");
+ }
+ asString(strb);
+ if (source != this) {
+ strb.append(" */");
+ }
+ return strb.toString();
+ }
/**
- * Generate the string corresponding to this expression.
+ * Generates this expression's string representation.
* @return the string representation
*/
public String asString() {
- return toString();
+ StringBuilder strb = new StringBuilder();
+ asString(strb);
+ return strb.toString();
}
/**
+ * Adds this expression's string representation to a StringBuilder.
+ */
+ abstract void asString(StringBuilder strb);
+
+ /**
* When the expression is dependant upon immediate and deferred sub-expressions,
* evaluates the immediate sub-expressions with the context passed as parameter
* and returns this expression deferred form.
@@ -294,49 +315,50 @@
/** A constant expression. */
- private class Constant extends Expression {
+ private class ConstantExpression extends Expression {
private final Object value;
- Constant(Object value, Expression source) {
+ ConstantExpression(Object value, Expression source) {
super(source);
if (value == null) {
throw new NullPointerException("constant can not be null");
}
+ if (value instanceof String) {
+ value = StringParser.buildString((String) value, false);
+ }
this.value = value;
}
+ @Override
+ public String asString() {
+ StringBuilder strb = new StringBuilder();
+ strb.append('"');
+ asString(strb);
+ strb.append('"');
+ return strb.toString();
+ }
+
+ @Override
ExpressionType getType() {
return ExpressionType.CONSTANT;
}
@Override
- public String toString() {
+ void asString(StringBuilder strb) {
String str = value.toString();
if (value instanceof String || value instanceof CharSequence) {
- StringBuilder strb = new StringBuilder(str.length() + 2);
- if (source != this) {
- strb.append(source.toString());
- strb.append(" /*= ");
- }
- strb.append('"');
for (int i = 0, size = str.length(); i < size; ++i) {
char c = str.charAt(i);
if (c == '"')
strb.append('\\');
+ else if (c == '\\')
+ strb.append("\\\\");
strb.append(c);
}
- strb.append('"');
- if (source != this) {
- strb.append(" */");
- }
- return strb.toString();
}
- return str;
- }
-
- @Override
- public String asString() {
- return value.toString();
+ else {
+ strb.append(str);
+ }
}
@Override
@@ -363,11 +385,11 @@
/** The base for Jexl based expressions. */
- abstract private class JexlBased extends Expression {
+ abstract private class JexlBasedExpression extends Expression {
protected final CharSequence expr;
protected final SimpleNode node;
- JexlBased(CharSequence expr, SimpleNode node, Expression source) {
+ JexlBasedExpression(CharSequence expr, SimpleNode node, Expression source) {
super(source);
this.expr = expr;
this.node = node;
@@ -391,8 +413,11 @@
}
@Override
- public String asString() {
- return expr.toString();
+ public void asString(StringBuilder strb) {
+ strb.append(isImmediate()? '$' : '#');
+ strb.append("{");
+ strb.append(expr);
+ strb.append("}");
}
@Override
@@ -418,8 +443,8 @@
}
/** An immediate expression: ${jexl}. */
- private class Immediate extends JexlBased {
- Immediate(CharSequence expr, SimpleNode node, Expression source) {
+ private class ImmediateExpression extends JexlBasedExpression {
+ ImmediateExpression(CharSequence expr, SimpleNode node, Expression source) {
super(expr, node, source);
}
@@ -435,8 +460,8 @@
}
/** An immediate expression: ${jexl}. */
- private class Deferred extends JexlBased {
- Deferred(CharSequence expr, SimpleNode node, Expression source) {
+ private class DeferredExpression extends JexlBasedExpression {
+ DeferredExpression(CharSequence expr, SimpleNode node, Expression source) {
super(expr, node, source);
}
@@ -456,8 +481,8 @@
* #{...${jexl}...}
* Note that the deferred syntax is JEXL's, not UnifiedJEXL.
*/
- private class Nested extends Deferred {
- Nested(CharSequence expr, SimpleNode node, Expression source) {
+ private class NestedExpression extends DeferredExpression {
+ NestedExpression(CharSequence expr, SimpleNode node, Expression source) {
super(expr, node, source);
if (this.source != this) {
throw new IllegalArgumentException("Nested expression can not have a source");
@@ -483,7 +508,7 @@
public Expression prepare(Interpreter interpreter) throws ParseException {
String value = interpreter.interpret(node).toString();
SimpleNode dnode = toNode(value);
- return new Deferred(value, dnode, this);
+ return new DeferredExpression(value, dnode, this);
}
@Override
@@ -494,13 +519,13 @@
/** A composite expression: "... ${...} ... #{...} ...". */
- private class Composite extends Expression {
+ private class CompositeExpression extends Expression {
// bit encoded (deferred count > 0) bit 1, (immediate count > 0) bit 0
final int meta;
// the list of expression resulting from parsing
final Expression[] exprs;
- Composite(int[] counts, ArrayList<Expression> exprs, Expression source) {
+ CompositeExpression(int[] counts, ArrayList<Expression> exprs, Expression source) {
super(source);
this.exprs = exprs.toArray(new Expression[exprs.size()]);
this.meta = (counts[ExpressionType.DEFERRED.index] > 0? 2 : 0) |
@@ -518,32 +543,14 @@
@Override
public boolean isImmediate() {
// immediate if no deferred
- return (meta & 2) != 0;
- }
-
- @Override
- public String toString() {
- StringBuilder strb = new StringBuilder();
- if (source != this) {
- strb.append(source.toString());
- strb.append(" /*= ");
- }
- for (Expression e : exprs) {
- strb.append(e.toString());
- }
- if (source != this) {
- strb.append(" */ ");
- }
- return strb.toString();
+ return (meta & 2) == 0;
}
@Override
- public String asString() {
- StringBuilder strb = new StringBuilder();
+ void asString(StringBuilder strb) {
for (Expression e : exprs) {
- strb.append(e.asString());
+ e.asString(strb);
}
- return strb.toString();
}
@Override
@@ -565,10 +572,10 @@
for(int e = 0; e < size; ++e) {
Expression expr = exprs[e];
Expression prepared = expr.prepare(interpreter);
- if (evalImmediate && prepared instanceof Immediate) {
+ if (evalImmediate && prepared instanceof ImmediateExpression) {
// evaluate immediate as constant
Object value = prepared.evaluate(interpreter);
- prepared = value == null? null : new Constant(value, prepared);
+ prepared = value == null? null : new ConstantExpression(value, prepared);
}
// add it if not null
if (prepared != null) {
@@ -789,7 +796,7 @@
state = ParseState.IMMEDIATE1;
// if chars in buffer, create constant
if (strb.length() > 0) {
- Expression cexpr = new Constant(strb.toString(), null);
+ Expression cexpr = new ConstantExpression(strb.toString(), null);
builder.add(cexpr);
strb.delete(0, Integer.MAX_VALUE);
}
@@ -806,7 +813,7 @@
state = ParseState.DEFERRED1;
// if chars in buffer, create constant
if (strb.length() > 0) {
- Expression cexpr = new Constant(strb.toString(), null);
+ Expression cexpr = new ConstantExpression(strb.toString(), null);
builder.add(cexpr);
strb.delete(0, Integer.MAX_VALUE);
}
@@ -822,7 +829,7 @@
if (c == '}') {
// materialize the immediate expr
//Expression iexpr = createExpression(ExpressionType.IMMEDIATE, strb, null);
- Expression iexpr = new Immediate(strb.toString(), toNode(strb), null);
+ Expression iexpr = new ImmediateExpression(strb.toString(), toNode(strb), null);
builder.add(iexpr);
strb.delete(0, Integer.MAX_VALUE);
state = ParseState.CONST;
@@ -836,7 +843,7 @@
// skip inner strings (for '}')
if (c == '"' || c == '\'') {
strb.append(c);
- i = readDeferredString(strb, expr, i + 1, c);
+ i = StringParser.readString(strb, expr, i + 1, c);
continue;
}
// nested immediate in deferred; need to balance count of '{' & '}'
@@ -856,8 +863,8 @@
} else {
// materialize the nested/deferred expr
Expression dexpr = nested?
- new Nested(expr.substring(inested, i+1), toNode(strb), null) :
- new Deferred(strb.toString(), toNode(strb), null);
+ new NestedExpression(expr.substring(inested, i+1), toNode(strb), null) :
+ new DeferredExpression(strb.toString(), toNode(strb), null);
builder.add(dexpr);
strb.delete(0, Integer.MAX_VALUE);
nested = false;
@@ -883,42 +890,12 @@
}
// we should be in that state
if (state != ParseState.CONST)
- throw new IllegalStateException("malformed expression: " + expr);
+ throw new ParseException("malformed expression: " + expr);
// if any chars were buffered, add them as a constant
if (strb.length() > 0) {
- Expression cexpr = new Constant(strb.toString(), null);
+ Expression cexpr = new ConstantExpression(strb.toString(), null);
builder.add(cexpr);
}
return builder.build(this, null);
}
-
- /**
- * Read the remainder of a string till a given separator,
- * handles escaping through '\' syntax.
- * @param strb the destination buffer to copy characters into
- * @param str the origin
- * @param index the offset into the origin
- * @param sep the separator, single or double quote, marking end of string
- * @return the offset in origin
- */
- static private int readDeferredString(StringBuilder strb, String str, int index, char sep) {
- boolean escape = false;
- for(;index < str.length();++index) {
- char c = str.charAt(index);
- if (escape) {
- strb.append(c);
- escape = false;
- continue;
- }
- if (c == '\\') {
- escape = true;
- continue;
- }
- strb.append(c);
- if (c == sep) {
- break;
- }
- }
- return index;
- }
}
\ No newline at end of file
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/Parser.jjt
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/Parser.jjt?rev=795190&r1=795189&r2=795190&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/Parser.jjt (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/Parser.jjt Fri Jul 17 18:40:59 2009
@@ -43,7 +43,7 @@
import org.apache.commons.jexl.util.introspection.Uberspect;
-public class Parser
+public class Parser extends StringParser
{
public SimpleNode parse(Reader reader)
@@ -349,7 +349,7 @@
{
(
t=<STRING_LITERAL>
- { jjtThis.image = t.image.substring(1, t.image.length() -1); }
+ { jjtThis.image = Parser.buildString(t.image, true); }
)
}
@@ -484,8 +484,8 @@
TOKEN :
{
<STRING_LITERAL :
- ("\"" ( ~["\"","\n","\r"] )* "\"" )
+ ("\"" ( ~["\"","\n","\r"] | "\\" ["n","t","b","r","f","\\","\""] )* "\"" )
|
- ("\'" ( ~["\'","\n","\r"] )* "\'" )
+ ("\'" ( ~["\'","\n","\r"] | "\\" ["n","t","b","r","f","\\","\'"])* "\'" )
>
}
\ No newline at end of file
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/StringParser.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/StringParser.java?rev=795190&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/StringParser.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/StringParser.java Fri Jul 17 18:40:59 2009
@@ -0,0 +1,84 @@
+/*
+ * 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.jexl.util;
+
+/**
+ * Common constant strings utilities.
+ */
+public class StringParser {
+ /**
+ * Builds a string, handles escaping through '\' syntax.
+ * @param str the string to build from
+ * @param eatsep whether the separator, the first character, should be considered
+ * @return the built string
+ */
+ public static String buildString(CharSequence str, boolean eatsep) {
+ StringBuilder strb = new StringBuilder(str.length());
+ char sep = eatsep ? str.charAt(0) : 0;
+ int end = str.length() - (eatsep ? 1 : 0);
+ int begin = (eatsep ? 1 : 0);
+ read(strb, str, begin, end, sep);
+ return strb.toString();
+ }
+
+ /**
+ * Read the remainder of a string till a given separator,
+ * handles escaping through '\' syntax.
+ * @param strb the destination buffer to copy characters into
+ * @param str the origin
+ * @param index the offset into the origin
+ * @param sep the separator, single or double quote, marking end of string
+ * @return the offset in origin
+ */
+ public static int readString(StringBuilder strb, CharSequence str, int index, char sep) {
+ return read(strb, str, index, str.length(), sep);
+ }
+
+ /**
+ * Read the remainder of a string till a given separator,
+ * handles escaping through '\' syntax.
+ * @param strb the destination buffer to copy characters into
+ * @param str the origin
+ * @param begin the relative offset in str to begin reading
+ * @param end the relative offset in str to end reading
+ * @param sep the separator, single or double quote, marking end of string
+ * @return the last character offset handled in origin
+ */
+ private static int read(StringBuilder strb, CharSequence str, int begin, int end, char sep) {
+ boolean escape = false;
+ int index = begin;
+ for (; index < end; ++index) {
+ char c = str.charAt(index);
+ if (escape) {
+ strb.append(c);
+ if (c == '\\')
+ strb.append('\\');
+ escape = false;
+ continue;
+ }
+ if (c == '\\') {
+ escape = true;
+ continue;
+ }
+ strb.append(c);
+ if (c == sep) {
+ break;
+ }
+ }
+ return index;
+ }
+}
\ No newline at end of file
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/StringParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/StringParser.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/UnifiedJEXLTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/UnifiedJEXLTest.java?rev=795190&r1=795189&r2=795190&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/UnifiedJEXLTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/UnifiedJEXLTest.java Fri Jul 17 18:40:59 2009
@@ -15,7 +15,9 @@
* limitations under the License.
*/
package org.apache.commons.jexl;
-
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import junit.framework.TestCase;
/**
* Test cases for the UnifiedEL.
@@ -28,10 +30,16 @@
JEXL.setCache(128);
}
static UnifiedJEXL EL = new UnifiedJEXL(JEXL);
-
+ static Log LOG = LogFactory.getLog(UnifiedJEXL.class);
+ JexlContext context = null;
+ Map<String,Object> vars =null;
+
+ @Override
public void setUp() throws Exception {
// ensure jul logging is only error
java.util.logging.Logger.getLogger(JexlEngine.class.getName()).setLevel(java.util.logging.Level.SEVERE);
+ context = JexlHelper.createContext();
+ vars = context.getVars();
}
public static class Froboz {
@@ -80,79 +88,154 @@
public void testAssign() throws Exception {
UnifiedJEXL.Expression assign = EL.parse("${froboz.value = 10}");
UnifiedJEXL.Expression check = EL.parse("${froboz.value}");
- JexlContext jc = JexlHelper.createContext();
- Object o = assign.evaluate(jc);
+ Object o = assign.evaluate(context);
assertEquals("Result is not 10", new Integer(10), o);
- o = check.evaluate(jc);
+ o = check.evaluate(context);
assertEquals("Result is not 10", new Integer(10), o);
}
- public void testDear() throws Exception {
- UnifiedJEXL.Expression assign = EL.parse("Dear ${p} ${name};");
- JexlContext jc = JexlHelper.createContext();
- jc.getVars().put("p", "Mr");
- jc.getVars().put("name", "Doe");
- Object o = assign.evaluate(jc);
+ public void testComposite() throws Exception {
+ UnifiedJEXL.Expression expr = EL.parse("Dear ${p} ${name};");
+ vars.put("p", "Mr");
+ vars.put("name", "Doe");
+ assertTrue("expression should be immediate", expr.isImmediate());
+ Object o = expr.evaluate(context);
assertEquals("Dear Mr Doe;", o);
- jc.getVars().put("p", "Ms");
- jc.getVars().put("name", "Jones");
- o = assign.evaluate(jc);
+ vars.put("p", "Ms");
+ vars.put("name", "Jones");
+ o = expr.evaluate(context);
assertEquals("Dear Ms Jones;", o);
}
- public void testDear2Phase() throws Exception {
- UnifiedJEXL.Expression assign = EL.parse("Dear #{p} ${name};");
- JexlContext jc = JexlHelper.createContext();
- jc.getVars().put("name", "Doe");
- UnifiedJEXL.Expression phase1 = assign.prepare(jc);
- jc.getVars().put("p", "Mr");
- jc.getVars().put("name", "Should not be used in 2nd phase");
- Object o = phase1.evaluate(jc);
+ public void testPrepareEvaluate() throws Exception {
+ UnifiedJEXL.Expression expr = EL.parse("Dear #{p} ${name};");
+ assertTrue("expression should be deferred", expr.isDeferred());
+ vars.put("name", "Doe");
+ UnifiedJEXL.Expression phase1 = expr.prepare(context);
+ String as = phase1.asString();
+ assertEquals("Dear #{p} Doe;", as);
+ vars.put("p", "Mr");
+ vars.put("name", "Should not be used in 2nd phase");
+ Object o = phase1.evaluate(context);
assertEquals("Dear Mr Doe;", o);
}
public void testNested() throws Exception {
UnifiedJEXL.Expression expr = EL.parse("#{${hi}+'.world'}");
- JexlContext jc = JexlHelper.createContext();
- jc.getVars().put("hi", "hello");
- jc.getVars().put("hello.world", "Hello World!");
- Object o = expr.evaluate(jc);
+ vars.put("hi", "hello");
+ vars.put("hello.world", "Hello World!");
+ Object o = expr.evaluate(context);
+ assertTrue("source should not be expression", expr.getSource() != expr.prepare(context));
+ assertTrue("expression should be deferred", expr.isDeferred());
assertEquals("Hello World!", o);
}
public void testImmediate() throws Exception {
+ JexlContext none = null;
UnifiedJEXL.Expression expr = EL.parse("${'Hello ' + 'World!'}");
- JexlContext jc = null;
- Object o = expr.evaluate(jc);
+ assertTrue("prepare should return same expression", expr.prepare(none) == expr);
+ Object o = expr.evaluate(none);
+ assertTrue("expression should be immediate", expr.isImmediate());
+ assertEquals("Hello World!", o);
+ }
+
+ public void testConstant() throws Exception {
+ JexlContext none = null;
+ UnifiedJEXL.Expression expr = EL.parse("Hello World!");
+ assertTrue("prepare should return same expression", expr.prepare(none) == expr);
+ Object o = expr.evaluate(none);
+ assertTrue("expression should be immediate", expr.isImmediate());
assertEquals("Hello World!", o);
}
public void testDeferred() throws Exception {
+ JexlContext none = null;
UnifiedJEXL.Expression expr = EL.parse("#{'world'}");
- JexlContext jc = null;
- Object o = expr.evaluate(jc);
+ assertTrue("prepare should return same expression", expr.prepare(none) == expr);
+ Object o = expr.evaluate(none);
+ assertTrue("expression should be deferred", expr.isDeferred());
assertEquals("world", o);
}
+
+ public void testEscape() throws Exception {
+ UnifiedJEXL.Expression expr = EL.parse("#\\{'world'\\}");
+ JexlContext none = null;
+ Object o = expr.evaluate(none);
+ assertEquals("#{'world'}", o);
+ }
+
+ public void testEscapeString() throws Exception {
+ UnifiedJEXL.Expression expr = EL.parse("\\\"${'world\\'s finest'}\\\"");
+ JexlContext none = null;
+ Object o = expr.evaluate(none);
+ assertEquals("\"world's finest\"", o);
+ }
+
+ public void testMalformed() throws Exception {
+ try {
+ UnifiedJEXL.Expression expr = EL.parse("${'world'");
+ JexlContext none = null;
+ Object o = expr.evaluate(none);
+ fail("should be malformed");
+ }
+ catch(UnifiedJEXL.Exception xjexl) {
+ // expected
+ String xmsg = xjexl.getMessage();
+ LOG.warn(xmsg);
+ }
+ }
+
+ public void testMalformedNested() throws Exception {
+ try {
+ UnifiedJEXL.Expression expr = EL.parse("#{${hi} world}");
+ JexlContext none = null;
+ Object o = expr.evaluate(none);
+ fail("should be malformed");
+ }
+ catch(UnifiedJEXL.Exception xjexl) {
+ // expected
+ String xmsg = xjexl.getMessage();
+ LOG.warn(xmsg);
+ }
+ }
+
+ public void testBadContextNested() throws Exception {
+ try {
+ UnifiedJEXL.Expression expr = EL.parse("#{${hi}+'.world'}");
+ JexlContext none = null;
+ Object o = expr.evaluate(none);
+ fail("should be malformed");
+ }
+ catch(UnifiedJEXL.Exception xjexl) {
+ // expected
+ String xmsg = xjexl.getMessage();
+ LOG.warn(xmsg);
+ }
+ }
public void testCharAtBug() throws Exception {
- JexlContext jc = JexlHelper.createContext();
-
- jc.getVars().put("foo", "abcdef");
+ vars.put("foo", "abcdef");
UnifiedJEXL.Expression expr = EL.parse("${foo.substring(2,4)/*comment*/}");
- Object o = expr.evaluate(jc);
+ Object o = expr.evaluate(context);
assertEquals("cd", o);
- jc.getVars().put("bar", "foo");
- EL.getEngine().setSilent(true);
- expr = EL.parse("#{${bar}+'.charAt(-2)'}");
- expr = expr.prepare(jc);
- o = expr.evaluate(jc);
- assertEquals(null, o);
+ vars.put("bar", "foo");
+ try {
+ JEXL.setSilent(true);
+ expr = EL.parse("#{${bar}+'.charAt(-2)'}");
+ expr = expr.prepare(context);
+ o = expr.evaluate(context);
+ assertEquals(null, o);
+ }
+ finally {
+ JEXL.setSilent(false);
+ }
}
-
+
public static void main(String[] args) throws Exception {
- //new UnifiedELTest("debug").testClassHash();
- new UnifiedJEXLTest("debug").testAssign();
+ UnifiedJEXLTest test = new UnifiedJEXLTest("debug");
+ test.setUp();
+ test.testBadContextNested();
}
}
\ No newline at end of file