| %line | %branch | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 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; | |
| 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.ParseException; | |
| 27 |  import org.apache.commons.jexl.parser.Parser; | |
| 28 |  import org.apache.commons.jexl.parser.SimpleNode; | |
| 29 |  import org.apache.commons.jexl.parser.TokenMgrError; | |
| 30 |  import org.apache.commons.logging.Log; | |
| 31 |  import org.apache.commons.logging.LogFactory; | |
| 32 | ||
| 33 |  /** | |
| 34 |   * <p> | |
| 35 |   * Creates Expression objects.  To create a JEXL Expression object, pass | |
| 36 |   * valid JEXL syntax to the static createExpression() method: | |
| 37 |   * </p> | |
| 38 |   * | |
| 39 |   * <pre> | |
| 40 |   * String jexl = "array[1]"; | |
| 41 |   * Expression expression = ExpressionFactory.createExpression( jexl ); | |
| 42 |   * </pre> | |
| 43 |   * | |
| 44 |   * <p> | |
| 45 |   * When an {@link Expression} object is created, the JEXL syntax is | |
| 46 |   * parsed and verified.  If the supplied expression is neither an | |
| 47 |   * expression nor a reference, an exception is thrown from createException(). | |
| 48 |   * </p> | |
| 49 |   * @since 1.0 | |
| 50 |   * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a> | |
| 51 |   * @version $Id: ExpressionFactory.java 429169 2006-08-06 18:36:29Z rahul $ | |
| 52 |   */ | |
| 53 | public class ExpressionFactory { | |
| 54 |      /** | |
| 55 |       * The Log to which all ExpressionFactory messages will be logged. | |
| 56 |       */ | |
| 57 | 16 | protected static Log log = | 
| 58 |          LogFactory.getLog("org.apache.commons.jexl.ExpressionFactory"); | |
| 59 | ||
| 60 |      /** | |
| 61 |       * The singleton ExpressionFactory also holds a single instance of | |
| 62 |       * {@link Parser}. | |
| 63 |       * When parsing expressions, ExpressionFactory synchronizes on Parser. | |
| 64 |       */ | |
| 65 | 8 | protected static Parser parser = | 
| 66 | new Parser(class="keyword">new StringReader(";")); //$NON-NLS-1$ | |
| 67 | ||
| 68 |      /** | |
| 69 |       * ExpressionFactory is a singleton and this is the private | |
| 70 |       * instance fufilling that pattern. | |
| 71 |       */ | |
| 72 | 8 | protected static ExpressionFactory ef = new ExpressionFactory(); | 
| 73 | ||
| 74 |      /** | |
| 75 |       * Private constructor, the single instance is always obtained | |
| 76 |       * with a call to getInstance(). | |
| 77 |       */ | |
| 78 | 8 |      private ExpressionFactory() { | 
| 79 | 8 | } | 
| 80 | ||
| 81 |      /** | |
| 82 |       * Returns the single instance of ExpressionFactory. | |
| 83 |       * @return the instance of ExpressionFactory. | |
| 84 |       */ | |
| 85 | protected static ExpressionFactory getInstance() { | |
| 86 | 274 |          return ef; | 
| 87 | } | |
| 88 | ||
| 89 |      /** | |
| 90 |       * Creates an Expression from a String containing valid | |
| 91 |       * JEXL syntax.  This method parses the expression which | |
| 92 |       * must contain either a reference or an expression. | |
| 93 |       * @param expression A String containing valid JEXL syntax | |
| 94 |       * @return An Expression object which can be evaluated with a JexlContext | |
| 95 |       * @throws Exception An exception can be thrown if there is a problem | |
| 96 |       *      parsing this expression, or if the expression is neither an | |
| 97 |       *      expression or a reference. | |
| 98 |       */ | |
| 99 | public static Expression createExpression(String expression) | |
| 100 |          throws Exception { | |
| 101 | 274 |          return getInstance().createNewExpression(expression); | 
| 102 | } | |
| 103 | ||
| 104 | ||
| 105 |      /** | |
| 106 |       *  Creates a new Expression based on the expression string. | |
| 107 |       * | |
| 108 |       *  @param expression valid Jexl expression | |
| 109 |       *  @return Expression | |
| 110 |       *  @throws Exception for a variety of reasons - mostly malformed | |
| 111 |       *          Jexl expression | |
| 112 |       */ | |
| 113 | protected Expression createNewExpression(final String expression) | |
| 114 |          throws Exception { | |
| 115 | ||
| 116 | 274 | String expr = cleanExpression(expression); | 
| 117 | ||
| 118 |          // Parse the Expression | |
| 119 | SimpleNode tree; | |
| 120 | 274 |          synchronized (parser) { | 
| 121 | 274 |              log.debug("Parsing expression: " + expr); | 
| 122 |              try { | |
| 123 | 274 |                  tree = parser.parse(new StringReader(expr)); | 
| 124 | 271 |              } catch (TokenMgrError tme) { | 
| 125 | 1 | throw new ParseException(tme.getMessage()); | 
| 126 | } | |
| 127 | 271 | } | 
| 128 | ||
| 129 | 271 |          if (tree.jjtGetNumChildren() > 1 && log.isWarnEnabled()) { | 
| 130 | 0 |              log.warn("The JEXL Expression created will be a reference" | 
| 131 |                  + " to the first expression from the supplied script: \"" | |
| 132 |                  + expression + "\" "); | |
| 133 | } | |
| 134 | ||
| 135 |          // Must be a simple reference, expression, statement or if, otherwise | |
| 136 |          // throw an exception. | |
| 137 | 271 | SimpleNode node = (SimpleNode) tree.jjtGetChild(0); | 
| 138 | ||
| 139 |          // TODO: Can we get rid of these checks? | |
| 140 | 271 |          if (node instanceof ASTReferenceExpression | 
| 141 | || node instanceof ASTExpressionExpression | |
| 142 | || node instanceof ASTStatementExpression | |
| 143 | || node instanceof ASTIfStatement | |
| 144 | || node instanceof ASTWhileStatement | |
| 145 | || node instanceof ASTForeachStatement | |
| 146 |              ) { | |
| 147 | 271 | return new ExpressionImpl(expression, node); | 
| 148 | } | |
| 149 | 0 |          log.error("Invalid Expression, node of type: " | 
| 150 | + node.getClass().getName()); | |
| 151 | 0 |          throw new Exception("Invalid Expression: not a Reference, Expression, " | 
| 152 |              + "Statement or If"); | |
| 153 | } | |
| 154 | ||
| 155 |      /** | |
| 156 |       * Trims the expression and adds a semi-colon if missing. | |
| 157 |       * @param expression to clean | |
| 158 |       * @return trimmed expression ending in a semi-colon | |
| 159 |       */ | |
| 160 |      private String cleanExpression(String expression) { | |
| 161 | 274 | String expr = expression.trim(); | 
| 162 | 274 | if (!expr.endsWith(";")) { | 
| 163 | 267 |              expr += ";"; | 
| 164 | } | |
| 165 | 274 |          return expr; | 
| 166 | } | |
| 167 | } | 
| This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |