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 2011/11/16 17:33:02 UTC
svn commit: r1202769 - in /commons/proper/jexl/trunk/src:
main/java/org/apache/commons/jexl2/ test/java/org/apache/commons/jexl2/
Author: henrib
Date: Wed Nov 16 16:33:02 2011
New Revision: 1202769
URL: http://svn.apache.org/viewvc?rev=1202769&view=rev
Log:
Deduplication of error formatting code;
Commented $jexl variable and jexl: namespace;
Added test on UJEXL using writer directly
Modified:
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlContext.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlException.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/NamespaceResolver.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/UnifiedJEXL.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/UnifiedJEXLTest.java
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlContext.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlContext.java?rev=1202769&r1=1202768&r2=1202769&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlContext.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlContext.java Wed Nov 16 16:33:02 2011
@@ -18,7 +18,8 @@ package org.apache.commons.jexl2;
/**
* Manages variables which can be referenced in a JEXL expression.
- *
+ * <p>Note that JEXL may use '$jexl' and '$ujexl' variables for internal purpose; setting or getting those
+ * variables may lead to unexpected results unless specified otherwise.</p>
* @since 1.0
* @version $Id$
*/
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlException.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlException.java?rev=1202769&r1=1202768&r2=1202769&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlException.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlException.java Wed Nov 16 16:33:02 2011
@@ -37,7 +37,7 @@ public class JexlException extends Runti
private static final int MIN_EXCHARLOC = 5;
/** Maximum number of characters around exception location. */
private static final int MAX_EXCHARLOC = 10;
-
+
/**
* Creates a new JexlException.
* @param node the node causing the error
@@ -46,7 +46,7 @@ public class JexlException extends Runti
public JexlException(JexlNode node, String msg) {
super(msg);
mark = node;
- info = node != null? node.debugInfo() : null;
+ info = node != null ? node.debugInfo() : null;
}
@@ -59,9 +59,9 @@ public class JexlException extends Runti
public JexlException(JexlNode node, String msg, Throwable cause) {
super(msg, unwrap(cause));
mark = node;
- info = node != null? node.debugInfo() : null;
+ info = node != null ? node.debugInfo() : null;
}
-
+
/**
* Creates a new JexlException.
* @param dbg the debugging information associated
@@ -84,7 +84,7 @@ public class JexlException extends Runti
mark = null;
info = dbg;
}
-
+
/**
* Unwraps the cause of a throwable due to reflection.
* @param xthrow the throwable
@@ -95,11 +95,11 @@ public class JexlException extends Runti
return ((InvocationTargetException) xthrow).getTargetException();
} else if (xthrow instanceof UndeclaredThrowableException) {
return ((UndeclaredThrowableException) xthrow).getUndeclaredThrowable();
- } else{
+ } else {
return xthrow;
}
}
-
+
/**
* Accesses detailed message.
* @return the message
@@ -107,7 +107,30 @@ public class JexlException extends Runti
protected String detailedMessage() {
return super.getMessage();
}
-
+
+ /**
+ * Formats an error message from the parser.
+ * @param prefix the prefix to the message
+ * @param expr the expression in error
+ * @return the formatted message
+ */
+ protected String parserError(String prefix, String expr) {
+ int begin = info.debugInfo().getColumn();
+ int end = begin + MIN_EXCHARLOC;
+ begin -= MIN_EXCHARLOC;
+ if (begin < 0) {
+ end += MIN_EXCHARLOC;
+ begin = 0;
+ }
+ int length = expr.length();
+ if (length < MAX_EXCHARLOC) {
+ return prefix + " error in '" + expr + "'";
+ } else {
+ return prefix + " error near '... "
+ + expr.substring(begin, end > length ? length : end) + " ...'";
+ }
+ }
+
/**
* Thrown when tokenization fails.
*/
@@ -121,7 +144,7 @@ public class JexlException extends Runti
public Tokenization(JexlInfo node, CharSequence expr, TokenMgrError cause) {
super(merge(node, cause), expr.toString(), cause);
}
-
+
/**
* Merge the node info and the cause info to obtain best possible location.
* @param node the node
@@ -129,7 +152,7 @@ public class JexlException extends Runti
* @return the info to use
*/
private static DebugInfo merge(JexlInfo node, TokenMgrError cause) {
- DebugInfo dbgn = node != null? node.debugInfo() : null;
+ DebugInfo dbgn = node != null ? node.debugInfo() : null;
if (cause == null) {
return dbgn;
} else if (dbgn == null) {
@@ -138,33 +161,20 @@ public class JexlException extends Runti
return new DebugInfo(dbgn.getName(), cause.getLine(), cause.getColumn());
}
}
-
+
/**
* @return the expression
- */
+ */
public String getExpression() {
return super.detailedMessage();
}
-
+
@Override
protected String detailedMessage() {
- int begin = info.debugInfo().getColumn();
- int end = begin + MIN_EXCHARLOC;
- begin -= MIN_EXCHARLOC;
- if (begin < 0) {
- end += MIN_EXCHARLOC;
- begin = 0;
- }
- int length = getExpression().length();
- if (length < MAX_EXCHARLOC) {
- return "parsing error in '" + getExpression() + "'";
- } else {
- return "parsing error near '... "
- + getExpression().substring(begin, end > length? length : end) + " ...'";
- }
+ return parserError("tokenization", getExpression());
}
- }
-
+ }
+
/**
* Thrown when parsing fails.
*/
@@ -178,7 +188,7 @@ public class JexlException extends Runti
public Parsing(JexlInfo node, CharSequence expr, ParseException cause) {
super(merge(node, cause), expr.toString(), cause);
}
-
+
/**
* Merge the node info and the cause info to obtain best possible location.
* @param node the node
@@ -186,7 +196,7 @@ public class JexlException extends Runti
* @return the info to use
*/
private static DebugInfo merge(JexlInfo node, ParseException cause) {
- DebugInfo dbgn = node != null? node.debugInfo() : null;
+ DebugInfo dbgn = node != null ? node.debugInfo() : null;
if (cause == null) {
return dbgn;
} else if (dbgn == null) {
@@ -195,33 +205,20 @@ public class JexlException extends Runti
return new DebugInfo(dbgn.getName(), cause.getLine(), cause.getColumn());
}
}
-
+
/**
* @return the expression
- */
+ */
public String getExpression() {
return super.detailedMessage();
}
-
+
@Override
protected String detailedMessage() {
- int begin = info.debugInfo().getColumn();
- int end = begin + MIN_EXCHARLOC;
- begin -= MIN_EXCHARLOC;
- if (begin < 0) {
- end += MIN_EXCHARLOC;
- begin = 0;
- }
- int length = getExpression().length();
- if (length < MAX_EXCHARLOC) {
- return "parsing error in '" + getExpression() + "'";
- } else {
- return "parsing error near '... "
- + getExpression().substring(begin, end > length? length : end) + " ...'";
- }
+ return parserError("parsing", getExpression());
}
}
-
+
/**
* Thrown when a variable is unknown.
*/
@@ -234,20 +231,20 @@ public class JexlException extends Runti
public Variable(JexlNode node, String var) {
super(node, var);
}
-
+
/**
* @return the variable name
*/
public String getVariable() {
return super.detailedMessage();
}
-
+
@Override
protected String detailedMessage() {
return "undefined variable " + getVariable();
}
- }
-
+ }
+
/**
* Thrown when a property is unknown.
*/
@@ -260,20 +257,20 @@ public class JexlException extends Runti
public Property(JexlNode node, String var) {
super(node, var);
}
-
+
/**
* @return the property name
*/
public String getProperty() {
return super.detailedMessage();
}
-
+
@Override
protected String detailedMessage() {
return "inaccessible or unknown property " + getProperty();
}
- }
-
+ }
+
/**
* Thrown when a method or ctor is unknown, ambiguous or inaccessible.
*/
@@ -286,26 +283,27 @@ public class JexlException extends Runti
public Method(JexlNode node, String name) {
super(node, name);
}
-
+
/**
* @return the method name
- */
+ */
public String getMethod() {
return super.detailedMessage();
}
-
+
@Override
protected String detailedMessage() {
return "unknown, ambiguous or inaccessible method " + getMethod();
}
}
-
+
/**
* Thrown to return a value.
*/
- protected static class Return extends JexlException {
+ protected static class Return extends JexlException {
/** The returned value. */
private final Object result;
+
/**
* Creates a new instance of Return.
* @param node the return node
@@ -316,6 +314,7 @@ public class JexlException extends Runti
super(node, msg);
this.result = value;
}
+
/**
* @return the returned value
*/
@@ -323,7 +322,7 @@ public class JexlException extends Runti
return result;
}
}
-
+
/**
* Thrown to cancel a script execution.
*/
@@ -336,7 +335,7 @@ public class JexlException extends Runti
super(node, "execution cancelled", null);
}
}
-
+
/**
* Gets information about the cause of this error.
* <p>
@@ -358,7 +357,7 @@ public class JexlException extends Runti
}
return "";
}
-
+
/**
* Detailed info message about this error.
* Format is "debug![begin,end]: string \n msg" where:
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/NamespaceResolver.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/NamespaceResolver.java?rev=1202769&r1=1202768&r2=1202769&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/NamespaceResolver.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/NamespaceResolver.java Wed Nov 16 16:33:02 2011
@@ -24,6 +24,10 @@ package org.apache.commons.jexl2;
* the "math" namespace would be the proper object to expose functions like "log(...)", "sinus(...)", etc.
* </p>
* In expressions like "ns:function(...)", the resolver is called with resolveNamespace("ns").
+ * <p>
+ * JEXL itself reserves 'jexl' and 'ujexl' as namespaces for internal purpose; resolving those may lead to unexpected
+ * results.
+ * </p>
*/
public interface NamespaceResolver {
/**
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/UnifiedJEXL.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/UnifiedJEXL.java?rev=1202769&r1=1202768&r2=1202769&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/UnifiedJEXL.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/UnifiedJEXL.java Wed Nov 16 16:33:02 2011
@@ -1021,6 +1021,13 @@ public final class UnifiedJEXL {
* The value 169 is over fourty-two
* </pre></blockquote>
* <p>
+ * During evaluation, the template context exposes its writer as '$jexl' which is safe to use in this case.
+ * This allows writing directly through the writer without adding new-lines as in:
+ * <p><blockquote><pre>
+ * $$ for(var cell : cells) { $jexl.print(cell); $jexl.print(';') }
+ * </pre></blockquote>
+ * </p>
+ * <p>
* A template is expanded as one JEXL script and a list of UnifiedJEXL expressions; each UnifiedJEXL expression
* being replace in the script by a call to jexl:print(expr) (the expr is in fact the expr number in the template).
* This integration uses a specialized JexlContext (TemplateContext) that serves as a namespace (for jexl:)
@@ -1181,6 +1188,7 @@ public final class UnifiedJEXL {
/**
* The type of context to use during evaluation of templates.
+ * <p>This context exposes its writer as '$jexl' to the scripts.</p>
* <p>public for introspection purpose.</p>
*/
public final class TemplateContext implements JexlContext, NamespaceResolver {
@@ -1217,7 +1225,11 @@ public final class UnifiedJEXL {
/** {@inheritDoc} */
public Object get(String name) {
- return wrap.get(name);
+ if ("$jexl".equals(name)) {
+ return writer;
+ } else {
+ return wrap.get(name);
+ }
}
/** {@inheritDoc} */
@@ -1250,22 +1262,6 @@ public final class UnifiedJEXL {
public void include(Template template, Object... args) {
template.evaluate(wrap, writer, args);
}
-
- /**
- * Prints an expression result.
- * @param e the expression number
- */
- public void print(String cs) {
- Expression expr = UnifiedJEXL.this.parse(cs);
- if (expr.isDeferred()) {
- expr = expr.prepare(wrap);
- }
- if (expr instanceof CompositeExpression) {
- printComposite((CompositeExpression) expr);
- } else {
- doPrint(expr.evaluate(this));
- }
- }
/**
* Prints an expression result.
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/UnifiedJEXLTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/UnifiedJEXLTest.java?rev=1202769&r1=1202768&r2=1202769&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/UnifiedJEXLTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/UnifiedJEXLTest.java Wed Nov 16 16:33:02 2011
@@ -16,8 +16,10 @@
*/
package org.apache.commons.jexl2;
+import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
+import java.io.Writer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -393,4 +395,29 @@ public class UnifiedJEXLTest extends Jex
String dstr = t.asString();
assertNotNull(dstr);
}
+
+ public static class FrobozWriter extends PrintWriter {
+ public FrobozWriter(Writer w) {
+ super(w);
+ }
+
+ public void print(Froboz froboz) {
+ super.print("froboz{");
+ super.print(froboz.value);
+ super.print("}");
+ }
+
+ @Override
+ public String toString() {
+ return out.toString();
+ }
+ }
+
+ public void testWriter() throws Exception {
+ Froboz froboz = new Froboz(42);
+ Writer writer = new FrobozWriter(new StringWriter());
+ UnifiedJEXL.Template t = EL.createTemplate("$$", new StringReader("$$$jexl.print(froboz)"), "froboz");
+ t.evaluate(context, writer, froboz);
+ assertEquals("froboz{42}", writer.toString());
+ }
}