1/* 2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package javax.script; 27import java.io.Reader; 28import java.util.Map; 29import java.util.Iterator; 30 31/** 32 * Provides a standard implementation for several of the variants of the <code>eval</code> 33 * method. 34 * <br><br> 35 * <code><b>eval(Reader)</b></code><p><code><b>eval(String)</b></code><p> 36 * <code><b>eval(String, Bindings)</b></code><p><code><b>eval(Reader, Bindings)</b></code> 37 * <br><br> are implemented using the abstract methods 38 * <br><br> 39 * <code><b>eval(Reader,ScriptContext)</b></code> or 40 * <code><b>eval(String, ScriptContext)</b></code> 41 * <br><br> 42 * with a <code>SimpleScriptContext</code>. 43 * <br><br> 44 * A <code>SimpleScriptContext</code> is used as the default <code>ScriptContext</code> 45 * of the <code>AbstractScriptEngine</code>.. 46 * 47 * @author Mike Grogan 48 * @since 1.6 49 */ 50public abstract class AbstractScriptEngine implements ScriptEngine { 51 52 /** 53 * The default <code>ScriptContext</code> of this <code>AbstractScriptEngine</code>. 54 */ 55 56 protected ScriptContext context; 57 58 /** 59 * Creates a new instance of AbstractScriptEngine using a <code>SimpleScriptContext</code> 60 * as its default <code>ScriptContext</code>. 61 */ 62 public AbstractScriptEngine() { 63 64 context = new SimpleScriptContext(); 65 66 } 67 68 /** 69 * Creates a new instance using the specified <code>Bindings</code> as the 70 * <code>ENGINE_SCOPE</code> <code>Bindings</code> in the protected <code>context</code> field. 71 * 72 * @param n The specified <code>Bindings</code>. 73 * @throws NullPointerException if n is null. 74 */ 75 public AbstractScriptEngine(Bindings n) { 76 77 this(); 78 if (n == null) { 79 throw new NullPointerException("n is null"); 80 } 81 context.setBindings(n, ScriptContext.ENGINE_SCOPE); 82 } 83 84 /** 85 * Sets the value of the protected <code>context</code> field to the specified 86 * <code>ScriptContext</code>. 87 * 88 * @param ctxt The specified <code>ScriptContext</code>. 89 * @throws NullPointerException if ctxt is null. 90 */ 91 public void setContext(ScriptContext ctxt) { 92 if (ctxt == null) { 93 throw new NullPointerException("null context"); 94 } 95 context = ctxt; 96 } 97 98 /** 99 * Returns the value of the protected <code>context</code> field. 100 * 101 * @return The value of the protected <code>context</code> field. 102 */ 103 public ScriptContext getContext() { 104 return context; 105 } 106 107 /** 108 * Returns the <code>Bindings</code> with the specified scope value in 109 * the protected <code>context</code> field. 110 * 111 * @param scope The specified scope 112 * 113 * @return The corresponding <code>Bindings</code>. 114 * 115 * @throws IllegalArgumentException if the value of scope is 116 * invalid for the type the protected <code>context</code> field. 117 */ 118 public Bindings getBindings(int scope) { 119 120 if (scope == ScriptContext.GLOBAL_SCOPE) { 121 return context.getBindings(ScriptContext.GLOBAL_SCOPE); 122 } else if (scope == ScriptContext.ENGINE_SCOPE) { 123 return context.getBindings(ScriptContext.ENGINE_SCOPE); 124 } else { 125 throw new IllegalArgumentException("Invalid scope value."); 126 } 127 } 128 129 /** 130 * Sets the <code>Bindings</code> with the corresponding scope value in the 131 * <code>context</code> field. 132 * 133 * @param bindings The specified <code>Bindings</code>. 134 * @param scope The specified scope. 135 * 136 * @throws IllegalArgumentException if the value of scope is 137 * invalid for the type the <code>context</code> field. 138 * @throws NullPointerException if the bindings is null and the scope is 139 * <code>ScriptContext.ENGINE_SCOPE</code> 140 */ 141 public void setBindings(Bindings bindings, int scope) { 142 143 if (scope == ScriptContext.GLOBAL_SCOPE) { 144 context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);; 145 } else if (scope == ScriptContext.ENGINE_SCOPE) { 146 context.setBindings(bindings, ScriptContext.ENGINE_SCOPE);; 147 } else { 148 throw new IllegalArgumentException("Invalid scope value."); 149 } 150 } 151 152 /** 153 * Sets the specified value with the specified key in the <code>ENGINE_SCOPE</code> 154 * <code>Bindings</code> of the protected <code>context</code> field. 155 * 156 * @param key The specified key. 157 * @param value The specified value. 158 * 159 * @throws NullPointerException if key is null. 160 * @throws IllegalArgumentException if key is empty. 161 */ 162 public void put(String key, Object value) { 163 164 Bindings nn = getBindings(ScriptContext.ENGINE_SCOPE); 165 if (nn != null) { 166 nn.put(key, value); 167 } 168 169 } 170 171 /** 172 * Gets the value for the specified key in the <code>ENGINE_SCOPE</code> of the 173 * protected <code>context</code> field. 174 * 175 * @return The value for the specified key. 176 * 177 * @throws NullPointerException if key is null. 178 * @throws IllegalArgumentException if key is empty. 179 */ 180 public Object get(String key) { 181 182 Bindings nn = getBindings(ScriptContext.ENGINE_SCOPE); 183 if (nn != null) { 184 return nn.get(key); 185 } 186 187 return null; 188 } 189 190 191 /** 192 * <code>eval(Reader, Bindings)</code> calls the abstract 193 * <code>eval(Reader, ScriptContext)</code> method, passing it a <code>ScriptContext</code> 194 * whose Reader, Writers and Bindings for scopes other that <code>ENGINE_SCOPE</code> 195 * are identical to those members of the protected <code>context</code> field. The specified 196 * <code>Bindings</code> is used instead of the <code>ENGINE_SCOPE</code> 197 * 198 * <code>Bindings</code> of the <code>context</code> field. 199 * 200 * @param reader A <code>Reader</code> containing the source of the script. 201 * @param bindings A <code>Bindings</code> to use for the <code>ENGINE_SCOPE</code> 202 * while the script executes. 203 * 204 * @return The return value from <code>eval(Reader, ScriptContext)</code> 205 * @throws ScriptException if an error occurs in script. 206 * @throws NullPointerException if any of the parameters is null. 207 */ 208 public Object eval(Reader reader, Bindings bindings ) throws ScriptException { 209 210 ScriptContext ctxt = getScriptContext(bindings); 211 212 return eval(reader, ctxt); 213 } 214 215 216 /** 217 * Same as <code>eval(Reader, Bindings)</code> except that the abstract 218 * <code>eval(String, ScriptContext)</code> is used. 219 * 220 * @param script A <code>String</code> containing the source of the script. 221 * 222 * @param bindings A <code>Bindings</code> to use as the <code>ENGINE_SCOPE</code> 223 * while the script executes. 224 * 225 * @return The return value from <code>eval(String, ScriptContext)</code> 226 * @throws ScriptException if an error occurs in script. 227 * @throws NullPointerException if any of the parameters is null. 228 */ 229 public Object eval(String script, Bindings bindings) throws ScriptException { 230 231 ScriptContext ctxt = getScriptContext(bindings); 232 233 return eval(script , ctxt); 234 } 235 236 /** 237 * <code>eval(Reader)</code> calls the abstract 238 * <code>eval(Reader, ScriptContext)</code> passing the value of the <code>context</code> 239 * field. 240 * 241 * @param reader A <code>Reader</code> containing the source of the script. 242 * @return The return value from <code>eval(Reader, ScriptContext)</code> 243 * @throws ScriptException if an error occurs in script. 244 * @throws NullPointerException if any of the parameters is null. 245 */ 246 public Object eval(Reader reader) throws ScriptException { 247 248 249 return eval(reader, context); 250 } 251 252 /** 253 * Same as <code>eval(Reader)</code> except that the abstract 254 * <code>eval(String, ScriptContext)</code> is used. 255 * 256 * @param script A <code>String</code> containing the source of the script. 257 * @return The return value from <code>eval(String, ScriptContext)</code> 258 * @throws ScriptException if an error occurs in script. 259 * @throws NullPointerException if any of the parameters is null. 260 */ 261 public Object eval(String script) throws ScriptException { 262 263 264 return eval(script, context); 265 } 266 267 /** 268 * Returns a <code>SimpleScriptContext</code>. The <code>SimpleScriptContext</code>: 269 *<br><br> 270 * <ul> 271 * <li>Uses the specified <code>Bindings</code> for its <code>ENGINE_SCOPE</code> 272 * </li> 273 * <li>Uses the <code>Bindings</code> returned by the abstract <code>getGlobalScope</code> 274 * method as its <code>GLOBAL_SCOPE</code> 275 * </li> 276 * <li>Uses the Reader and Writer in the default <code>ScriptContext</code> of this 277 * <code>ScriptEngine</code> 278 * </li> 279 * </ul> 280 * <br><br> 281 * A <code>SimpleScriptContext</code> returned by this method is used to implement eval methods 282 * using the abstract <code>eval(Reader,Bindings)</code> and <code>eval(String,Bindings)</code> 283 * versions. 284 * 285 * @param nn Bindings to use for the <code>ENGINE_SCOPE</code> 286 * @return The <code>SimpleScriptContext</code> 287 */ 288 protected ScriptContext getScriptContext(Bindings nn) { 289 290 SimpleScriptContext ctxt = new SimpleScriptContext(); 291 Bindings gs = getBindings(ScriptContext.GLOBAL_SCOPE); 292 293 if (gs != null) { 294 ctxt.setBindings(gs, ScriptContext.GLOBAL_SCOPE); 295 } 296 297 if (nn != null) { 298 ctxt.setBindings(nn, 299 ScriptContext.ENGINE_SCOPE); 300 } else { 301 throw new NullPointerException("Engine scope Bindings may not be null."); 302 } 303 304 ctxt.setReader(context.getReader()); 305 ctxt.setWriter(context.getWriter()); 306 ctxt.setErrorWriter(context.getErrorWriter()); 307 308 return ctxt; 309 310 } 311} 312