Author: grobmeier
Date: Sat Jun 13 17:45:23 2009
New Revision: 784442
URL: http://svn.apache.org/viewvc?rev=784442&view=rev
Log:
JEXL-55: Bean & ant-ish like assignment, Ternary operator, Exception handling
revisited,
ScriptFactory, ExpressionFactory refactored
Contributed by Henri Biestro
Added:
commons/proper/jexl/branches/2.0/maven-eclipse.xml
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Debugger.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/logging/
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/logging/LogManager.java
commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/AssignTest.java
commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/util/
commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/util/introspection/
commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/util/introspection/MethodKeyTest.java
Modified:
commons/proper/jexl/branches/2.0/build.xml
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Arithmetic.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Expression.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionFactory.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionImpl.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlArithmetic.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptFactory.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptImpl.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/JEXLNode.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/Parser.jjt
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/VisitorAdapter.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/Coercion.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/UberspectImpl.java
commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/BlockTest.java
commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/JexlTest.java
commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/ParseFailuresTest.java
commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/ScriptFactoryTest.java
commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/ScriptTest.java
Modified: commons/proper/jexl/branches/2.0/build.xml
URL:
http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/build.xml?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/build.xml (original)
+++ commons/proper/jexl/branches/2.0/build.xml Sat Jun 13 17:45:23 2009
@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!--build.xml generated by maven from project.xml version 1.1.1-SNAPSHOT
- on date August 12 2006, time 0018-->
-
<project default="jar" name="commons-jexl" basedir=".">
<property name="defaulttargetdir" value="target">
</property>
@@ -16,11 +13,15 @@
</property>
<property name="testreportdir" value="target/test-reports">
</property>
+ <property name="gensrcdir" value="target/generated-src">
+ </property>
<property name="distdir" value="dist">
</property>
<property name="javadocdir" value="dist/docs/api">
</property>
- <property name="final.name" value="commons-jexl-1.1.1-SNAPSHOT">
+ <property name="javaccdir" value="${libdir}">
+ </property>
+ <property name="final.name" value="commons-jexl-2.0-SNAPSHOT">
</property>
<path id="build.classpath">
<fileset dir="${libdir}">
@@ -36,10 +37,29 @@
</equals>
</condition>
<!--Test if JUNIT is present in ANT classpath-->
-
+<property name="Junit.present" value="true"/>
+<!--
<available property="Junit.present" classname="junit.framework.Test">
</available>
+ -->
</target>
+
+<target name="dojavacc" description="Generate the parser classes">
+ <mkdir dir="${gensrcdir}/org/apache/commons/jexl/parser">
+ </mkdir>
+ <jjtree
+ target="src/java/org/apache/commons/jexl/parser/Parser.jjt"
+ outputdirectory="${gensrcdir}/org/apache/commons/jexl/parser"
+ javacchome="${javaccdir}"
+ nodeusesparser="true">
+ </jjtree>
+ <javacc
+ target="${gensrcdir}/org/apache/commons/jexl/parser/Parser.jj"
+ outputdirectory="${gensrcdir}/org/apache/commons/jexl/parser"
+ javacchome="${javaccdir}">
+ </javacc>
+ </target>
+
<target name="compile" description="o Compile the code" depends="get-deps">
<mkdir dir="${classesdir}">
</mkdir>
@@ -47,6 +67,8 @@
<src>
<pathelement location="src/java">
</pathelement>
+ <pathelement location="${gensrcdir}">
+ </pathelement>
</src>
<classpath refid="build.classpath">
</classpath>
@@ -142,7 +164,7 @@
</tstamp>
<property name="copyright" value="Copyright &copy; The Apache
Software Foundation. All Rights Reserved.">
</property>
- <property name="title" value="Commons JEXL 1.1.1-SNAPSHOT API">
+ <property name="title" value="Commons JEXL 2.0-SNAPSHOT API">
</property>
<javadoc use="true" private="true" destdir="${javadocdir}" author="true"
version="true" sourcepath="src/java" packagenames="org.apache.commons.jexl.*">
<classpath>
@@ -160,6 +182,8 @@
</get>
<get dest="${libdir}/junit-3.8.1.jar" usetimestamp="true"
ignoreerrors="true"
src="http://www.ibiblio.org/maven/junit/jars/junit-3.8.1.jar">
</get>
+ <get dest="${libdir}/javacc.jar" usetimestamp="true" ignoreerrors="true"
src="http://www.ibiblio.org/maven/javacc/jars/javacc-4.0.jar">
+ </get>
</target>
<target name="install-maven">
<get dest="${user.home}/maven-install-latest.jar" usetimestamp="true"
src="${repo}/maven/maven-install-latest.jar">
Added: commons/proper/jexl/branches/2.0/maven-eclipse.xml
URL:
http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/maven-eclipse.xml?rev=784442&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/maven-eclipse.xml (added)
+++ commons/proper/jexl/branches/2.0/maven-eclipse.xml Sat Jun 13 17:45:23 2009
@@ -0,0 +1,8 @@
+<project default="copy-resources">
+ <target name="init"/>
+ <target name="copy-resources" depends="init">
+ <copy todir="target/classes/META-INF" filtering="false">
+ <fileset dir="." includes="NOTICE.txt|LICENSE.txt"/>
+ </copy>
+ </target>
+</project>
\ No newline at end of file
Modified:
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Arithmetic.java
URL:
http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Arithmetic.java?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
---
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Arithmetic.java
(original)
+++
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Arithmetic.java
Sat Jun 13 17:45:23 2009
@@ -1,67 +1,167 @@
-/*
- * 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;
-/**
- * Pluggable arithmetic operators.
- */
-interface Arithmetic {
-
- /**
- * Add two values together.
- *
- * @param left first value
- * @param right second value
- * @return left + right.
- */
- Object add(Object left, Object right);
-
- /**
- * Divide the left value by the right.
- *
- * @param left first value
- * @param right second value
- * @return left - right.
- */
- Object divide(Object left, Object right);
-
- /**
- * left value mod right.
- *
- * @param left first value
- * @param right second value
- * @return left mod right.
- */
- Object mod(Object left, Object right);
-
- /**
- * Multiply the left value by the right.
- *
- * @param left first value
- * @param right second value
- * @return left * right.
- */
- Object multiply(Object left, Object right);
-
- /**
- * Subtract the right value from the left.
- *
- * @param left first value
- * @param right second value
- * @return left + right.
- */
- Object subtract(Object left, Object right);
+/*
+ * 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;
+/**
+ * Pluggable arithmetic, coercion & comparison operators.
+ */
+public interface Arithmetic {
+
+ /**
+ * Add two values together.
+ *
+ * @param left first value
+ * @param right second value
+ * @return left + right.
+ */
+ Object add(Object left, Object right);
+
+ /**
+ * Divide the left value by the right.
+ *
+ * @param left first value
+ * @param right second value
+ * @return left - right.
+ */
+ Object divide(Object left, Object right);
+
+ /**
+ * left value mod right.
+ *
+ * @param left first value
+ * @param right second value
+ * @return left mod right.
+ */
+ Object mod(Object left, Object right);
+
+ /**
+ * Multiply the left value by the right.
+ *
+ * @param left first value
+ * @param right second value
+ * @return left * right.
+ */
+ Object multiply(Object left, Object right);
+
+ /**
+ * Subtract the right value from the left.
+ *
+ * @param left first value
+ * @param right second value
+ * @return left + right.
+ */
+ Object subtract(Object left, Object right);
+
+ /**
+ * Coerce an object into a boolean.
+ * @param arg the value to convert
+ * @return a boolean
+ */
+ boolean toBoolean(Object arg);
+
+ /**
+ * Coerce an object into an integer.
+ * @param arg the object to coerce
+ * @return an int
+ */
+ int toInteger(Object arg);
+
+ /**
+ * Coerce an object into a long.
+ * @param arg the object to coerce
+ * @return a long
+ */
+ long toLong(Object arg);
+
+ /**
+ * Coerce an object into a double.
+ * @param arg the object to coerce
+ * @return a double
+ */
+ double toDouble(Object arg);
+
+ /**
+ * Coerce an object into a big integer.
+ * @param arg the object to coerce
+ * @return a big integer
+ */
+ java.math.BigInteger toBigInteger(Object arg);
+
+ /**
+ * Coerce an object into a big decimal.
+ * @param arg the object to coerce
+ * @return a big decimal
+ */
+ java.math.BigDecimal toBigDecimal(Object arg);
+
+ /**
+ * Given a Number, return back the value using the smallest type the result
+ * will fit into. This works hand in hand with parameter 'widening' in java
+ * method calls, e.g. a call to substring(int,int) with an int and a long
+ * will fail, but a call to substring(int,int) with an int and a short will
+ * succeed.
+ *
+ * @param original the original number.
+ * @return a value of the smallest type the original number will fit into.
+ * @since 1.1
+ */
+ public Number narrow(Number original);
+
+ /**
+ * Test if left == right.
+ *
+ * @param left first value
+ * @param right second value
+ * @return test result.
+ */
+ boolean equals(Object left, Object right);
+
+ /**
+ * Test if left < right.
+ *
+ * @param left first value
+ * @param right second value
+ * @return test result.
+ */
+ boolean lessThan(Object left, Object right);
+
+ /**
+ * Test if left > right.
+ *
+ * @param left first value
+ * @param right second value
+ * @return test result.
+ */
+ boolean greaterThan(Object left, Object right);
+
+ /**
+ * Test if left <= right.
+ *
+ * @param left first value
+ * @param right second value
+ * @return test result.
+ */
+ boolean lessThanOrEqual(Object left, Object right);
+
+ /**
+ * Test if left >= right.
+ *
+ * @param left first value
+ * @param right second value
+ * @return test result.
+ */
+ boolean greaterThanOrEqual(Object left, Object right);
}
\ No newline at end of file
Added:
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Debugger.java
URL:
http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Debugger.java?rev=784442&view=auto
==============================================================================
---
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Debugger.java
(added)
+++
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Debugger.java
Sat Jun 13 17:45:23 2009
@@ -0,0 +1,517 @@
+/*
+ * 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;
+
+import org.apache.commons.jexl.parser.ASTAddNode;
+import org.apache.commons.jexl.parser.ASTAndNode;
+import org.apache.commons.jexl.parser.ASTArrayAccess;
+import org.apache.commons.jexl.parser.ASTAssignment;
+import org.apache.commons.jexl.parser.ASTBitwiseAndNode;
+import org.apache.commons.jexl.parser.ASTBitwiseComplNode;
+import org.apache.commons.jexl.parser.ASTBitwiseOrNode;
+import org.apache.commons.jexl.parser.ASTBitwiseXorNode;
+import org.apache.commons.jexl.parser.ASTBlock;
+import org.apache.commons.jexl.parser.ASTDivNode;
+import org.apache.commons.jexl.parser.ASTEQNode;
+import org.apache.commons.jexl.parser.ASTEmptyFunction;
+import org.apache.commons.jexl.parser.ASTExpression;
+import org.apache.commons.jexl.parser.ASTExpressionExpression;
+import org.apache.commons.jexl.parser.ASTFalseNode;
+import org.apache.commons.jexl.parser.ASTFloatLiteral;
+import org.apache.commons.jexl.parser.ASTForeachStatement;
+import org.apache.commons.jexl.parser.ASTGENode;
+import org.apache.commons.jexl.parser.ASTGTNode;
+import org.apache.commons.jexl.parser.ASTIdentifier;
+import org.apache.commons.jexl.parser.ASTIfStatement;
+import org.apache.commons.jexl.parser.ASTIntegerLiteral;
+import org.apache.commons.jexl.parser.ASTJexlScript;
+import org.apache.commons.jexl.parser.ASTLENode;
+import org.apache.commons.jexl.parser.ASTLTNode;
+import org.apache.commons.jexl.parser.ASTMapEntry;
+import org.apache.commons.jexl.parser.ASTMapLiteral;
+import org.apache.commons.jexl.parser.ASTMethod;
+import org.apache.commons.jexl.parser.ASTModNode;
+import org.apache.commons.jexl.parser.ASTMulNode;
+import org.apache.commons.jexl.parser.ASTNENode;
+import org.apache.commons.jexl.parser.ASTNotNode;
+import org.apache.commons.jexl.parser.ASTNullLiteral;
+import org.apache.commons.jexl.parser.ASTOrNode;
+import org.apache.commons.jexl.parser.ASTReference;
+import org.apache.commons.jexl.parser.ASTReferenceExpression;
+import org.apache.commons.jexl.parser.ASTSizeFunction;
+import org.apache.commons.jexl.parser.ASTSizeMethod;
+import org.apache.commons.jexl.parser.ASTStatementExpression;
+import org.apache.commons.jexl.parser.ASTStringLiteral;
+import org.apache.commons.jexl.parser.ASTSubtractNode;
+import org.apache.commons.jexl.parser.ASTTernaryNode;
+import org.apache.commons.jexl.parser.ASTTrueNode;
+import org.apache.commons.jexl.parser.ASTUnaryMinusNode;
+import org.apache.commons.jexl.parser.ASTWhileStatement;
+import org.apache.commons.jexl.parser.Node;
+import org.apache.commons.jexl.parser.SimpleNode;
+
+import org.apache.commons.jexl.parser.ParserVisitor;
+/**
+ * Helps pinpoint the cause of problems in expressions that fail during
evaluation.
+ * It rebuilds an expression string from the tree and the start/end offsets of
the cause
+ * in that string (TODO pretty print).
+ * This implies that exceptions during evaluation should allways carry the
node that's causing
+ * the error.
+ */
+public class Debugger implements ParserVisitor {
+ StringBuilder builder;
+ Node cause;
+ int start = 0;
+ int end = 0;
+
+ public Debugger() {
+ builder = new StringBuilder();
+ cause = null;
+ start = 0;
+ end = 0;
+ }
+
+ /**
+ * Seeks the location of an error cause (a node) in an expression.
+ * @return true if the cause was located, false otherwise
+ */
+ public boolean debug(Node cause) {
+ builder = new StringBuilder();
+ this.cause = cause;
+ // make arg cause become the root cause
+ Node root = cause;
+ while (root.jjtGetParent() != null) {
+ root = root.jjtGetParent();
+ }
+ start = 0;
+ end = 0;
+ root.jjtAccept(this, null);
+ return start > 0;
+ }
+
+ /**
+ * @return The rebuilt expression
+ */
+ public String data() {
+ return builder.toString();
+ }
+
+ /**
+ * @return The starting offset location of the cause in the expression
+ */
+ public int start() {
+ return start;
+ }
+ /**
+ * @return The end offset location of the cause in the expression
+ */
+ public int end() {
+ return end;
+ }
+
+ /**
+ * Checks if a child node is the cause to debug & adds its representation
to the rebuilt expression
+ */
+ private Object accept(Node node, Object data) {
+ if (node == cause) {
+ start = builder.length();
+ }
+ Object value = node.jjtAccept(this, data);
+ if (node == cause) {
+ end = builder.length();
+ }
+ return value;
+ }
+
+ /**
+ * Checks if a terminal node is the the cause to debug & adds its
representation to the rebuilt expression
+ */
+ private Object check(Node node, String image, Object data) {
+ if (node == cause) {
+ start = builder.length();
+ }
+ if (image != null) {
+ builder.append(image);
+ } else {
+ builder.append(node.toString());
+ }
+ if (node == cause) {
+ end = builder.length();
+ }
+ return data;
+ }
+
+ /**
+ * Checks if the children of a node using infix notation is the cause to
debug,
+ * adds their representation to the rebuilt expression
+ */
+ private Object infixChildren(Node node, String infix, Object data) {
+ int num = node.jjtGetNumChildren();
+ for (int i = 0; i < num; ++i) {
+ if (i > 0) {
+ builder.append(infix);
+ }
+ accept(node.jjtGetChild(i), data);
+ }
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTAddNode node, Object data) {
+ return infixChildren(node, " + ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTAndNode node, Object data) {
+ return infixChildren(node, " && ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTArrayAccess node, Object data) {
+ accept(node.jjtGetChild(0), data);
+ int num = node.jjtGetNumChildren();
+ for (int i = 1; i < num; ++i) {
+ builder.append("[");
+ accept(node.jjtGetChild(i), data);
+ builder.append("]");
+ }
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTAssignment node, Object data) {
+ return infixChildren(node, " = ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTBitwiseAndNode node, Object data) {
+ return infixChildren(node, " & ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTBitwiseComplNode node, Object data) {
+ builder.append("~");
+ return accept(node.jjtGetChild(0), data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTBitwiseOrNode node, Object data) {
+ return infixChildren(node, " | ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTBitwiseXorNode node, Object data) {
+ return infixChildren(node, " ^ ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTBlock node, Object data) {
+ builder.append("{ ");
+ int num = node.jjtGetNumChildren();
+ for (int i = 0; i < num; ++i) {
+ accept(node.jjtGetChild(0), data);
+ }
+ builder.append(" }");
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTDivNode node, Object data) {
+ return infixChildren(node, " / ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTEmptyFunction node, Object data) {
+ builder.append("empty(");
+ accept(node.jjtGetChild(0), data);
+ builder.append(")");
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTEQNode node, Object data) {
+ return infixChildren(node, " == ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTExpression node, Object data) {
+ int num = node.jjtGetNumChildren();
+ for (int i = 0; i < num; ++i) {
+ accept(node.jjtGetChild(i), data);
+ }
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTExpressionExpression node, Object data) {
+ int num = node.jjtGetNumChildren();
+ for (int i = 0; i < num; ++i) {
+ accept(node.jjtGetChild(i), data);
+ }
+ builder.append(";");
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTFalseNode node, Object data) {
+ return check(node, "false", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTFloatLiteral node, Object data) {
+ return check(node, node.image, data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTForeachStatement node, Object data) {
+ builder.append("foreach(");
+ accept(node.jjtGetChild(0), data);
+ builder.append(" in ");
+ accept(node.jjtGetChild(1), data);
+ builder.append(") ");
+ accept(node.jjtGetChild(2), data);
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTGENode node, Object data) {
+ return infixChildren(node, " >= ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTGTNode node, Object data) {
+ return infixChildren(node, " > ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTIdentifier node, Object data) {
+ return check(node, node.image, data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTIfStatement node, Object data) {
+ builder.append("if(");
+ accept(node.jjtGetChild(0), data);
+ builder.append(") ");
+ accept(node.jjtGetChild(1), data);
+ if (node.jjtGetNumChildren() > 2) {
+ builder.append(" else ");
+ accept(node.jjtGetChild(2), data);
+ }
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTIntegerLiteral node, Object data) {
+ return check(node, node.image, data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTJexlScript node, Object data) {
+ int num = node.jjtGetNumChildren();
+ for (int i = 0; i < num; ++i) {
+ accept(node.jjtGetChild(i), data);
+ }
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTLENode node, Object data) {
+ return infixChildren(node, " <= ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTLTNode node, Object data) {
+ return infixChildren(node, " < ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTMapEntry node, Object data) {
+ accept(node.jjtGetChild(0), data);
+ builder.append(" => ");
+ accept(node.jjtGetChild(1), data);
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTMapLiteral node, Object data) {
+ int num = node.jjtGetNumChildren();
+ builder.append("[");
+ accept(node.jjtGetChild(0), data);
+ for (int i = 1; i < num; ++i) {
+ builder.append(", ");
+ accept(node.jjtGetChild(i), data);
+ }
+ builder.append("]");
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTMethod node, Object data) {
+ int num = node.jjtGetNumChildren();
+ accept(node.jjtGetChild(0), data);
+ builder.append("(");
+ for (int i = 1; i < num; ++i) {
+ if (i > 1) {
+ builder.append(", ");
+ }
+ accept(node.jjtGetChild(i), data);
+ }
+ builder.append(")");
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTModNode node, Object data) {
+ return infixChildren(node, " % ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTMulNode node, Object data) {
+ return infixChildren(node, " * ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTNENode node, Object data) {
+ return infixChildren(node, " != ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTNotNode node, Object data) {
+ builder.append("!");
+ accept(node.jjtGetChild(0), data);
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTNullLiteral node, Object data) {
+ check(node, "null", data);
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTOrNode node, Object data) {
+ return infixChildren(node, " ||", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTReference node, Object data) {
+ int num = node.jjtGetNumChildren();
+ accept(node.jjtGetChild(0), data);
+ for (int i = 1; i < num; ++i) {
+ builder.append(".");
+ accept(node.jjtGetChild(i), data);
+ }
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTReferenceExpression node, Object data) {
+ int num = node.jjtGetNumChildren();
+ accept(node.jjtGetChild(0), data);
+ for (int i = 1; i < num; ++i) {
+ builder.append(".");
+ accept(node.jjtGetChild(i), data);
+ }
+ builder.append(";");
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTSizeFunction node, Object data) {
+ builder.append("size(");
+ accept(node.jjtGetChild(0), data);
+ builder.append(")");
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTSizeMethod node, Object data) {
+ check(node, "size()", data);
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTStatementExpression node, Object data) {
+ int num = node.jjtGetNumChildren();
+ for (int i = 0; i < num; ++i) {
+ accept(node.jjtGetChild(i), data);
+ if (i > 0) {
+ builder.append(";");
+ }
+ }
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTStringLiteral node, Object data) {
+ String img = node.image.replace("'", "\\'");
+ return check(node, "'" + img + "'", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTSubtractNode node, Object data) {
+ return infixChildren(node, " - ", data);
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTTernaryNode node, Object data) {
+ accept(node.jjtGetChild(0), data);
+ if (node.jjtGetNumChildren() > 2) {
+ builder.append("? ");
+ accept(node.jjtGetChild(1), data);
+ builder.append(" : ");
+ accept(node.jjtGetChild(2), data);
+ } else {
+ builder.append("?:");
+ accept(node.jjtGetChild(1), data);
+
+ }
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTTrueNode node, Object data) {
+ check(node, "true", data);
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTUnaryMinusNode node, Object data) {
+ builder.append("-");
+ accept(node.jjtGetChild(0), data);
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(ASTWhileStatement node, Object data) {
+ builder.append("while(");
+ accept(node.jjtGetChild(0), data);
+ builder.append(") ");
+ accept(node.jjtGetChild(1), data);
+ return data;
+ }
+
+ /** {...@inheritdoc} */
+ public Object visit(SimpleNode node, Object data) {
+ int num = node.jjtGetNumChildren();
+ for (int i = 0; i < num; ++i) {
+ accept(node.jjtGetChild(i), data);
+ }
+ return data;
+ }
+}
Modified:
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Expression.java
URL:
http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Expression.java?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
---
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Expression.java
(original)
+++
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Expression.java
Sat Jun 13 17:45:23 2009
@@ -52,4 +52,9 @@
*/
String getExpression();
+ /**
+ * Returns the JEXL expression by reconstructing it from the parsed tree.
+ * @return the JEXL expression
+ */
+ String dump();
}
Modified:
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionFactory.java
URL:
http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionFactory.java?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
---
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionFactory.java
(original)
+++
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionFactory.java
Sat Jun 13 17:45:23 2009
@@ -16,16 +16,7 @@
*/
package org.apache.commons.jexl;
-import java.io.StringReader;
-
import org.apache.commons.jexl.parser.ParseException;
-import org.apache.commons.jexl.parser.Parser;
-import org.apache.commons.jexl.parser.SimpleNode;
-import org.apache.commons.jexl.parser.TokenMgrError;
-import org.apache.commons.jexl.util.Introspector;
-import org.apache.commons.jexl.util.introspection.Uberspect;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
/**
* <p>
@@ -49,48 +40,11 @@
*/
public class ExpressionFactory {
/**
- * The Log to which all ExpressionFactory messages will be logged.
- */
- protected static final Log LOG =
- LogFactory.getLog("org.apache.commons.jexl.ExpressionFactory");
-
- /**
- * The singleton ExpressionFactory also holds a single instance of
- * {...@link Parser}.
- * When parsing expressions, ExpressionFactory synchronizes on Parser.
- */
- protected final Parser parser =
- new Parser(new StringReader(";")); //$NON-NLS-1$
-
- /**
- * ExpressionFactory is a singleton and this is the private
- * instance fulfilling that pattern.
- */
- protected static final ExpressionFactory EF = new ExpressionFactory();
-
- /**
* Private constructor, the single instance is always obtained
* with a call to getInstance().
*/
- private ExpressionFactory() {
- this(Introspector.getUberspect());
- }
+ private ExpressionFactory() {}
- /**
- * Creates an expression factory using the provided {...@link Uberspect}.
- * @param uberspect to allow different introspection behaviour
- */
- public ExpressionFactory(Uberspect uberspect) {
- parser.setUberspect(uberspect);
- }
-
- /**
- * Returns the single instance of ExpressionFactory.
- * @return the instance of ExpressionFactory.
- */
- public static ExpressionFactory getInstance() {
- return EF;
- }
/**
* Creates an Expression from a String containing valid
@@ -104,65 +58,7 @@
*/
public static Expression createExpression(String expression)
throws ParseException {
- return getInstance().createNewExpression(expression);
+ return JexlEngine.DEFAULT.createExpression(expression);
}
-
- /**
- * Creates a new Expression based on the expression string.
- *
- * @param expression valid Jexl expression
- * @return Expression
- * @throws ParseException for malformed Jexl expression
- */
- public Expression createNewExpression(final String expression) throws
ParseException {
-
- String expr = cleanExpression(expression);
-
- // Parse the Expression
- SimpleNode tree;
- synchronized (parser) {
- LOG.debug("Parsing expression: " + expr);
- try {
- tree = parser.parse(new StringReader(expr));
- } catch (TokenMgrError tme) {
- throw new ParseException(tme.getMessage());
- } catch (ParseException e) {
- throw e;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- if (tree.jjtGetNumChildren() > 1 && LOG.isWarnEnabled()) {
- LOG.warn("The JEXL Expression created will be a reference"
- + " to the first expression from the supplied script: \""
- + expression + "\" ");
- }
-
- // Must be a simple reference, expression, statement or if, otherwise
- // throw an exception.
- SimpleNode node = (SimpleNode) tree.jjtGetChild(0);
-
- Interpreter interpreter = new Interpreter(
- null,
- Introspector.getUberspect(),
- new JexlArithmetic());
- // TODO: remove this from the parser.
- // interpreter.setUberspect(parser.getUberspect());
- return new ExpressionImpl(expression, node, interpreter);
- }
-
- /**
- * Trims the expression and adds a semi-colon if missing.
- * @param expression to clean
- * @return trimmed expression ending in a semi-colon
- */
- private String cleanExpression(String expression) {
- String expr = expression.trim();
- if (!expr.endsWith(";")) {
- expr += ";";
- }
- return expr;
- }
}
Modified:
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionImpl.java
URL:
http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionImpl.java?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
---
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionImpl.java
(original)
+++
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionImpl.java
Sat Jun 13 17:45:23 2009
@@ -49,6 +49,9 @@
*/
protected SimpleNode node;
+ /** The engine for this expression. */
+ protected final JexlEngine jexl;
+
/** The interpreter of the expression. */
protected Interpreter interpreter;
@@ -59,17 +62,23 @@
* @param ref the parsed expression.
* @param interp the interpreter to evaluate the expression
*/
- ExpressionImpl(String expr, SimpleNode ref, Interpreter interp) {
+ ExpressionImpl(JexlEngine engine, String expr, SimpleNode ref) {
expression = expr;
node = ref;
- interpreter = interp;
+ jexl = engine;
}
/**
* {...@inheritdoc}
*/
public Object evaluate(JexlContext context) throws Exception {
- return interpreter.interpret(node, context);
+ Interpreter interpreter = jexl.createInterpreter(context);
+ return interpreter.interpret(node, jexl.isSilent());
+ }
+
+ public String dump() {
+ Debugger debug = new Debugger();
+ return debug.debug(node)? debug.toString() : "/*?*/";
}
/**