Path: blob/master/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java
41149 views
/*1* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.script;2627import java.util.*;28import java.io.*;2930/**31* Simple implementation of ScriptContext.32*33* @author Mike Grogan34* @since 1.635*/36public class SimpleScriptContext implements ScriptContext {3738/**39* This is the writer to be used to output from scripts.40* By default, a <code>PrintWriter</code> based on <code>System.out</code>41* is used. Accessor methods getWriter, setWriter are used to manage42* this field.43* @see java.lang.System#out44* @see java.io.PrintWriter45*/46protected Writer writer;4748/**49* This is the writer to be used to output errors from scripts.50* By default, a <code>PrintWriter</code> based on <code>System.err</code> is51* used. Accessor methods getErrorWriter, setErrorWriter are used to manage52* this field.53* @see java.lang.System#err54* @see java.io.PrintWriter55*/56protected Writer errorWriter;5758/**59* This is the reader to be used for input from scripts.60* By default, a <code>InputStreamReader</code> based on <code>System.in</code>61* is used and default charset is used by this reader. Accessor methods62* getReader, setReader are used to manage this field.63* @see java.lang.System#in64* @see java.io.InputStreamReader65*/66protected Reader reader;676869/**70* This is the engine scope bindings.71* By default, a <code>SimpleBindings</code> is used. Accessor72* methods setBindings, getBindings are used to manage this field.73* @see SimpleBindings74*/75protected Bindings engineScope;7677/**78* This is the global scope bindings.79* By default, a null value (which means no global scope) is used. Accessor80* methods setBindings, getBindings are used to manage this field.81*/82protected Bindings globalScope;8384/**85* Create a {@code SimpleScriptContext}.86*/87public SimpleScriptContext() {88this(new InputStreamReader(System.in),89new PrintWriter(System.out , true),90new PrintWriter(System.err, true));91engineScope = new SimpleBindings();92globalScope = null;93}9495/**96* Package-private constructor to avoid needless creation of reader and writers.97* It is the caller's responsability to initialize the engine scope.98*99* @param reader the reader100* @param writer the writer101* @param errorWriter the error writer102*/103SimpleScriptContext(Reader reader, Writer writer, Writer errorWriter) {104this.reader = reader;105this.writer = writer;106this.errorWriter = errorWriter;107}108109/**110* Sets a <code>Bindings</code> of attributes for the given scope. If the value111* of scope is <code>ENGINE_SCOPE</code> the given <code>Bindings</code> replaces the112* <code>engineScope</code> field. If the value113* of scope is <code>GLOBAL_SCOPE</code> the given <code>Bindings</code> replaces the114* <code>globalScope</code> field.115*116* @param bindings The <code>Bindings</code> of attributes to set.117* @param scope The value of the scope in which the attributes are set.118*119* @throws IllegalArgumentException if scope is invalid.120* @throws NullPointerException if the value of scope is <code>ENGINE_SCOPE</code> and121* the specified <code>Bindings</code> is null.122*/123public void setBindings(Bindings bindings, int scope) {124125switch (scope) {126127case ENGINE_SCOPE:128if (bindings == null) {129throw new NullPointerException("Engine scope cannot be null.");130}131engineScope = bindings;132break;133case GLOBAL_SCOPE:134globalScope = bindings;135break;136default:137throw new IllegalArgumentException("Invalid scope value.");138}139}140141142/**143* Retrieves the value of the attribute with the given name in144* the scope occurring earliest in the search order. The order145* is determined by the numeric value of the scope parameter (lowest146* scope values first.)147*148* @param name The name of the attribute to retrieve.149* @return The value of the attribute in the lowest scope for150* which an attribute with the given name is defined. Returns151* null if no attribute with the name exists in any scope.152* @throws NullPointerException if the name is null.153* @throws IllegalArgumentException if the name is empty.154*/155public Object getAttribute(String name) {156checkName(name);157if (engineScope.containsKey(name)) {158return getAttribute(name, ENGINE_SCOPE);159} else if (globalScope != null && globalScope.containsKey(name)) {160return getAttribute(name, GLOBAL_SCOPE);161}162163return null;164}165166/**167* Gets the value of an attribute in a given scope.168*169* @param name The name of the attribute to retrieve.170* @param scope The scope in which to retrieve the attribute.171* @return The value of the attribute. Returns <code>null</code> is the name172* does not exist in the given scope.173*174* @throws IllegalArgumentException175* if the name is empty or if the value of scope is invalid.176* @throws NullPointerException if the name is null.177*/178public Object getAttribute(String name, int scope) {179checkName(name);180switch (scope) {181182case ENGINE_SCOPE:183return engineScope.get(name);184185case GLOBAL_SCOPE:186if (globalScope != null) {187return globalScope.get(name);188}189return null;190191default:192throw new IllegalArgumentException("Illegal scope value.");193}194}195196/**197* Remove an attribute in a given scope.198*199* @param name The name of the attribute to remove200* @param scope The scope in which to remove the attribute201*202* @return The removed value.203* @throws IllegalArgumentException204* if the name is empty or if the scope is invalid.205* @throws NullPointerException if the name is null.206*/207public Object removeAttribute(String name, int scope) {208checkName(name);209switch (scope) {210211case ENGINE_SCOPE:212if (getBindings(ENGINE_SCOPE) != null) {213return getBindings(ENGINE_SCOPE).remove(name);214}215return null;216217case GLOBAL_SCOPE:218if (getBindings(GLOBAL_SCOPE) != null) {219return getBindings(GLOBAL_SCOPE).remove(name);220}221return null;222223default:224throw new IllegalArgumentException("Illegal scope value.");225}226}227228/**229* Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>230* and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.231*232* @param name The name of the attribute to set233* @param value The value of the attribute234* @param scope The scope in which to set the attribute235*236* @throws IllegalArgumentException237* if the name is empty or if the scope is invalid.238* @throws NullPointerException if the name is null.239*/240public void setAttribute(String name, Object value, int scope) {241checkName(name);242switch (scope) {243244case ENGINE_SCOPE:245engineScope.put(name, value);246return;247248case GLOBAL_SCOPE:249if (globalScope != null) {250globalScope.put(name, value);251}252return;253254default:255throw new IllegalArgumentException("Illegal scope value.");256}257}258259/** {@inheritDoc} */260public Writer getWriter() {261return writer;262}263264/** {@inheritDoc} */265public Reader getReader() {266return reader;267}268269/** {@inheritDoc} */270public void setReader(Reader reader) {271this.reader = reader;272}273274/** {@inheritDoc} */275public void setWriter(Writer writer) {276this.writer = writer;277}278279/** {@inheritDoc} */280public Writer getErrorWriter() {281return errorWriter;282}283284/** {@inheritDoc} */285public void setErrorWriter(Writer writer) {286this.errorWriter = writer;287}288289/**290* Get the lowest scope in which an attribute is defined.291* @param name Name of the attribute292* .293* @return The lowest scope. Returns -1 if no attribute with the given294* name is defined in any scope.295* @throws NullPointerException if name is null.296* @throws IllegalArgumentException if name is empty.297*/298public int getAttributesScope(String name) {299checkName(name);300if (engineScope.containsKey(name)) {301return ENGINE_SCOPE;302} else if (globalScope != null && globalScope.containsKey(name)) {303return GLOBAL_SCOPE;304} else {305return -1;306}307}308309/**310* Returns the value of the <code>engineScope</code> field if specified scope is311* <code>ENGINE_SCOPE</code>. Returns the value of the <code>globalScope</code> field if the specified scope is312* <code>GLOBAL_SCOPE</code>.313*314* @param scope The specified scope315* @return The value of either the <code>engineScope</code> or <code>globalScope</code> field.316* @throws IllegalArgumentException if the value of scope is invalid.317*/318public Bindings getBindings(int scope) {319if (scope == ENGINE_SCOPE) {320return engineScope;321} else if (scope == GLOBAL_SCOPE) {322return globalScope;323} else {324throw new IllegalArgumentException("Illegal scope value.");325}326}327328/** {@inheritDoc} */329public List<Integer> getScopes() {330return scopes;331}332333private void checkName(String name) {334Objects.requireNonNull(name);335if (name.isEmpty()) {336throw new IllegalArgumentException("name cannot be empty");337}338}339340private static final List<Integer> scopes = List.of(ENGINE_SCOPE, GLOBAL_SCOPE);341}342343344