| %line | %branch | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| org.apache.commons.jexl.ScriptFactory |
|
|
| 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.BufferedReader; |
|
| 19 | import java.io.File; |
|
| 20 | import java.io.FileReader; |
|
| 21 | import java.io.IOException; |
|
| 22 | import java.io.InputStreamReader; |
|
| 23 | import java.io.StringReader; |
|
| 24 | import java.net.URL; |
|
| 25 | import java.net.URLConnection; |
|
| 26 | ||
| 27 | import org.apache.commons.jexl.parser.ASTJexlScript; |
|
| 28 | import org.apache.commons.jexl.parser.ParseException; |
|
| 29 | import org.apache.commons.jexl.parser.Parser; |
|
| 30 | import org.apache.commons.jexl.parser.SimpleNode; |
|
| 31 | import org.apache.commons.jexl.parser.TokenMgrError; |
|
| 32 | import org.apache.commons.logging.Log; |
|
| 33 | import org.apache.commons.logging.LogFactory; |
|
| 34 | ||
| 35 | /** |
|
| 36 | * <p> |
|
| 37 | * Creates {@link Script}s. To create a JEXL Script, pass |
|
| 38 | * valid JEXL syntax to the static createScript() method: |
|
| 39 | * </p> |
|
| 40 | * |
|
| 41 | * <pre> |
|
| 42 | * String jexl = "y = x * 12 + 44; y = y * 4;"; |
|
| 43 | * Script script = ScriptFactory.createScript( jexl ); |
|
| 44 | * </pre> |
|
| 45 | * |
|
| 46 | * <p> |
|
| 47 | * When an {@link Script} is created, the JEXL syntax is |
|
| 48 | * parsed and verified. |
|
| 49 | * </p> |
|
| 50 | * @since 1.1 |
|
| 51 | * @version $Id: ScriptFactory.java 429175 2006-08-06 19:05:23Z rahul $ |
|
| 52 | */ |
|
| 53 | public class ScriptFactory { |
|
| 54 | ||
| 55 | /** The Log to which all ScriptFactory messages will be logged.*/ |
|
| 56 | 6 | protected static Log log = |
| 57 | LogFactory.getLog("org.apache.commons.jexl.ScriptFactory"); |
|
| 58 | ||
| 59 | /** |
|
| 60 | * The singleton ScriptFactory also holds a single instance of |
|
| 61 | * {@link Parser}. When parsing expressions, ScriptFactory |
|
| 62 | * synchronizes on Parser. |
|
| 63 | */ |
|
| 64 | 3 | protected static Parser parser = new Parser(class="keyword">new StringReader(";")); |
| 65 | ||
| 66 | /** |
|
| 67 | * ScriptFactory is a singleton and this is the private |
|
| 68 | * instance fufilling that pattern. |
|
| 69 | */ |
|
| 70 | 3 | protected static ScriptFactory factory = new ScriptFactory(); |
| 71 | ||
| 72 | /** |
|
| 73 | * Private constructor, the single instance is always obtained |
|
| 74 | * with a call to getInstance(). |
|
| 75 | */ |
|
| 76 | 3 | private ScriptFactory() { |
| 77 | ||
| 78 | 3 | } |
| 79 | ||
| 80 | /** |
|
| 81 | * Returns the single instance of ScriptFactory. |
|
| 82 | * @return the instance of ScriptFactory. |
|
| 83 | */ |
|
| 84 | protected static ScriptFactory getInstance() { |
|
| 85 | 11 | return factory; |
| 86 | } |
|
| 87 | ||
| 88 | /** |
|
| 89 | * Creates a Script from a String containing valid JEXL syntax. |
|
| 90 | * This method parses the script which validates the syntax. |
|
| 91 | * |
|
| 92 | * @param scriptText A String containing valid JEXL syntax |
|
| 93 | * @return A {@link Script} which can be executed with a |
|
| 94 | * {@link JexlContext}. |
|
| 95 | * @throws Exception An exception can be thrown if there is a |
|
| 96 | * problem parsing the script. |
|
| 97 | */ |
|
| 98 | public static Script createScript(String scriptText) throws Exception { |
|
| 99 | 11 | return getInstance().createNewScript(scriptText); |
| 100 | } |
|
| 101 | ||
| 102 | /** |
|
| 103 | * Creates a Script from a {@link File} containing valid JEXL syntax. |
|
| 104 | * This method parses the script and validates the syntax. |
|
| 105 | * |
|
| 106 | * @param scriptFile A {@link File} containing valid JEXL syntax. |
|
| 107 | * Must not be null. Must be a readable file. |
|
| 108 | * @return A {@link Script} which can be executed with a |
|
| 109 | * {@link JexlContext}. |
|
| 110 | * @throws Exception An exception can be thrown if there is a problem |
|
| 111 | * parsing the script. |
|
| 112 | */ |
|
| 113 | public static Script createScript(File scriptFile) throws Exception { |
|
| 114 | 3 | if (scriptFile == null) { |
| 115 | 1 | throw new NullPointerException("scriptFile is null"); |
| 116 | } |
|
| 117 | 2 | if (!scriptFile.canRead()) { |
| 118 | 0 | throw new IOException("Can't read scriptFile (" |
| 119 | + scriptFile.getCanonicalPath() + ")"); |
|
| 120 | } |
|
| 121 | 2 | BufferedReader reader = new BufferedReader(class="keyword">new FileReader(scriptFile)); |
| 122 | 2 | return createScript(readerToString(reader)); |
| 123 | ||
| 124 | } |
|
| 125 | ||
| 126 | /** |
|
| 127 | * Creates a Script from a {@link URL} containing valid JEXL syntax. |
|
| 128 | * This method parses the script and validates the syntax. |
|
| 129 | * |
|
| 130 | * @param scriptUrl A {@link URL} containing valid JEXL syntax. |
|
| 131 | * Must not be null. Must be a readable file. |
|
| 132 | * @return A {@link Script} which can be executed with a |
|
| 133 | * {@link JexlContext}. |
|
| 134 | * @throws Exception An exception can be thrown if there is a problem |
|
| 135 | * parsing the script. |
|
| 136 | */ |
|
| 137 | public static Script createScript(URL scriptUrl) throws Exception { |
|
| 138 | 3 | if (scriptUrl == null) { |
| 139 | 1 | throw new NullPointerException("scriptUrl is null"); |
| 140 | } |
|
| 141 | 2 | URLConnection connection = scriptUrl.openConnection(); |
| 142 | ||
| 143 | 2 | BufferedReader reader = new BufferedReader( |
| 144 | new InputStreamReader(connection.getInputStream())); |
|
| 145 | 2 | return createScript(readerToString(reader)); |
| 146 | } |
|
| 147 | ||
| 148 | /** |
|
| 149 | * Creates a new Script based on the string. |
|
| 150 | * |
|
| 151 | * @param scriptText valid Jexl script |
|
| 152 | * @return Script a new script |
|
| 153 | * @throws Exception for a variety of reasons - mostly malformed scripts |
|
| 154 | */ |
|
| 155 | protected Script createNewScript(String scriptText) throws Exception { |
|
| 156 | 11 | String cleanText = cleanScript(scriptText); |
| 157 | SimpleNode script; |
|
| 158 | // Parse the Expression |
|
| 159 | 10 | synchronized (parser) { |
| 160 | 10 | log.debug("Parsing script: " + cleanText); |
| 161 | try { |
|
| 162 | 10 | script = parser.parse(new StringReader(cleanText)); |
| 163 | 7 | } catch (TokenMgrError tme) { |
| 164 | 2 | throw new ParseException(tme.getMessage()); |
| 165 | } |
|
| 166 | 7 | } |
| 167 | 7 | if (script instanceof ASTJexlScript) { |
| 168 | 7 | return new ScriptImpl(cleanText, (ASTJexlScript) script); |
| 169 | } else { |
|
| 170 | 0 | throw new IllegalStateException("Parsed script is not " |
| 171 | + "an ASTJexlScript"); |
|
| 172 | } |
|
| 173 | } |
|
| 174 | ||
| 175 | /** |
|
| 176 | * @todo move to ParseUtils? |
|
| 177 | * Trims the expression and adds a semi-colon if missing. |
|
| 178 | * @param script to clean |
|
| 179 | * @return trimmed expression ending in a semi-colon |
|
| 180 | */ |
|
| 181 | private String cleanScript(String script) { |
|
| 182 | 11 | String expr = script.trim(); |
| 183 | 10 | if (!expr.endsWith(";")) { |
| 184 | 3 | expr += ";"; |
| 185 | } |
|
| 186 | 10 | return expr; |
| 187 | } |
|
| 188 | ||
| 189 | /** |
|
| 190 | * Read a buffered reader into a StringBuffer and return a String with |
|
| 191 | * the contents of the reader. |
|
| 192 | * @param reader to be read. |
|
| 193 | * @return the contents of the reader as a String. |
|
| 194 | * @throws IOException on any error reading the reader. |
|
| 195 | */ |
|
| 196 | private static String readerToString(BufferedReader reader) |
|
| 197 | throws IOException { |
|
| 198 | 4 | StringBuffer buffer = new StringBuffer(); |
| 199 | try { |
|
| 200 | 4 | String line = null; |
| 201 | 48 | while ((line = reader.readLine()) != null) { |
| 202 | 40 | buffer.append(line).append('\n'); |
| 203 | } |
|
| 204 | 4 | return buffer.toString(); |
| 205 | } finally { |
|
| 206 | 0 | reader.close(); |
| 207 | } |
|
| 208 | ||
| 209 | } |
|
| 210 | ||
| 211 | } |
| This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |