KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jexl > ExpressionFactory


1 /*
2  * Copyright 2002-2006 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.jexl;
17
18 import java.io.StringReader JavaDoc;
19
20 import org.apache.commons.jexl.parser.ASTExpressionExpression;
21 import org.apache.commons.jexl.parser.ASTForeachStatement;
22 import org.apache.commons.jexl.parser.ASTIfStatement;
23 import org.apache.commons.jexl.parser.ASTReferenceExpression;
24 import org.apache.commons.jexl.parser.ASTStatementExpression;
25 import org.apache.commons.jexl.parser.ASTWhileStatement;
26 import org.apache.commons.jexl.parser.Parser;
27 import org.apache.commons.jexl.parser.SimpleNode;
28 import org.apache.commons.jexl.parser.TokenMgrError;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 /**
33  * <p>
34  * Creates Expression objects. To create a JEXL Expression object, pass
35  * valid JEXL syntax to the static createExpression() method:
36  * </p>
37  *
38  * <pre>
39  * String jexl = "array[1]";
40  * Expression expression = ExpressionFactory.createExpression( jexl );
41  * </pre>
42  *
43  * <p>
44  * When an {@link Expression} object is created, the JEXL syntax is
45  * parsed and verified. If the supplied expression is neither an
46  * expression nor a reference, an exception is thrown from createException().
47  * </p>
48  * @since 1.0
49  * @author <a HREF="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
50  * @version $Id: ExpressionFactory.java 429169 2006-08-06 11:36:29 -0700 (Sun, 06 Aug 2006) rahul $
51  */

52 public class ExpressionFactory {
53     /**
54      * The Log to which all ExpressionFactory messages will be logged.
55      */

56     protected static Log log =
57         LogFactory.getLog("org.apache.commons.jexl.ExpressionFactory");
58
59     /**
60      * The singleton ExpressionFactory also holds a single instance of
61      * {@link Parser}.
62      * When parsing expressions, ExpressionFactory synchronizes on Parser.
63      */

64     protected static Parser parser =
65             new Parser(new StringReader JavaDoc(";")); //$NON-NLS-1$
66

67     /**
68      * ExpressionFactory is a singleton and this is the private
69      * instance fufilling that pattern.
70      */

71     protected static ExpressionFactory ef = new ExpressionFactory();
72
73     /**
74      * Private constructor, the single instance is always obtained
75      * with a call to getInstance().
76      */

77     private ExpressionFactory() {
78     }
79
80     /**
81      * Returns the single instance of ExpressionFactory.
82      * @return the instance of ExpressionFactory.
83      */

84     protected static ExpressionFactory getInstance() {
85         return ef;
86     }
87
88     /**
89      * Creates an Expression from a String containing valid
90      * JEXL syntax. This method parses the expression which
91      * must contain either a reference or an expression.
92      * @param expression A String containing valid JEXL syntax
93      * @return An Expression object which can be evaluated with a JexlContext
94      * @throws Exception An exception can be thrown if there is a problem
95      * parsing this expression, or if the expression is neither an
96      * expression or a reference.
97      */

98     public static Expression createExpression(String JavaDoc expression)
99         throws Exception JavaDoc {
100         return getInstance().createNewExpression(expression);
101     }
102
103
104     /**
105      * Creates a new Expression based on the expression string.
106      *
107      * @param expression valid Jexl expression
108      * @return Expression
109      * @throws Exception for a variety of reasons - mostly malformed
110      * Jexl expression
111      */

112     protected Expression createNewExpression(final String JavaDoc expression)
113         throws Exception JavaDoc {
114
115         String JavaDoc expr = cleanExpression(expression);
116
117         // Parse the Expression
118
SimpleNode tree;
119         synchronized (parser) {
120             log.debug("Parsing expression: " + expr);
121             try {
122                 tree = parser.parse(new StringReader JavaDoc(expr));
123             } catch (TokenMgrError e) {
124                 // this is thrown if there's syntax error.
125
// most callers aren't expecting the parsing error to be this fatal,
126
// so let's wrap it to Exception (not Error) to let the caller catch it
127
throw new JexlException("Failed to parse "+expr,e);
128             }
129         }
130
131         if (tree.jjtGetNumChildren() > 1 && log.isWarnEnabled()) {
132             log.warn("The JEXL Expression created will be a reference"
133                 + " to the first expression from the supplied script: \""
134                 + expression + "\" ");
135         }
136
137         // Must be a simple reference, expression, statement or if, otherwise
138
// throw an exception.
139
SimpleNode node = (SimpleNode) tree.jjtGetChild(0);
140
141         // TODO: Can we get rid of these checks?
142
if (node instanceof ASTReferenceExpression
143             || node instanceof ASTExpressionExpression
144             || node instanceof ASTStatementExpression
145             || node instanceof ASTIfStatement
146             || node instanceof ASTWhileStatement
147             || node instanceof ASTForeachStatement
148             ) {
149             return new ExpressionImpl(expression, node);
150         }
151         log.error("Invalid Expression, node of type: "
152             + node.getClass().getName());
153         throw new Exception JavaDoc("Invalid Expression: not a Reference, Expression, "
154             + "Statement or If");
155     }
156
157     /**
158      * Trims the expression and adds a semi-colon if missing.
159      * @param expression to clean
160      * @return trimmed expression ending in a semi-colon
161      */

162     private String JavaDoc cleanExpression(String JavaDoc expression) {
163         String JavaDoc expr = expression.trim();
164         if (!expr.endsWith(";")) {
165             expr += ";";
166         }
167         return expr;
168     }
169 }
170
Popular Tags