All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bsh.ExternalNameSpace Maven / Gradle / Ivy

The newest version!
/*
 * #%L
 * The AIBench Shell Plugin
 * %%
 * Copyright (C) 2006 - 2017 Daniel Glez-Peña and Florentino Fdez-Riverola
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */
package bsh;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

/**
 * 

* A namespace which maintains an external map of values held in variables in * its scope. This mechanism provides a standard collections based interface to * the namespace as well as a convenient way to export and view values of the * namespace without the ordinary BeanShell wrappers. *

* *

* Variables are maintained internally in the normal fashion to support * meta-information (such as variable type and visibility modifiers), but * exported and imported in a synchronized way. Variables are exported each time * they are written by BeanShell. Imported variables from the map appear in the * BeanShell namespace as untyped variables with no modifiers and shadow any * previously defined variables in the scope. *

* *

* Note: this class is inherentely dependent on Java 1.2, however it is not used * directly by the core as other than type NameSpace, so no dependency is * introduced. *

*/ /* * Implementation notes: bsh methods are not currently expored to the external * namespace. All that would be required to add this is to override setMethod() * and provide a friendlier view than vector (currently used) for overloaded * forms (perhaps a map by method SignatureKey). */ public class ExternalNameSpace extends NameSpace { private static final long serialVersionUID = 1L; private Map externalMap; public ExternalNameSpace() { this(null, "External Map Namespace", null); } public ExternalNameSpace(NameSpace parent, String name, Map externalMap) { super(parent, name); if (externalMap == null) externalMap = new HashMap(); this.externalMap = externalMap; } /** * Returns the map view of this namespace. * * @return the map view of this namespace. */ public Map getMap() { return externalMap; } /** * Set the external Map to which this namespace synchronizes. The previous * external map is detached from this namespace. Previous map values are * retained in the external map, but are removed from the BeanShell * namespace. * * @param map * the external Map to which this namespace synchronizes. */ public void setMap(Map map) { // Detach any existing namespace to preserve it, then clear this // namespace and set the new one this.externalMap = null; clear(); this.externalMap = map; } void setVariable(String name, Object value, boolean strictJava, boolean recurse) throws UtilEvalError { super.setVariable(name, value, strictJava, recurse); putExternalMap(name, value); } public void unsetVariable(String name) { super.unsetVariable(name); externalMap.remove(name); } public String[] getVariableNames() { // union of the names in the internal namespace and external map Set nameSet = new HashSet(); String[] nsNames = super.getVariableNames(); nameSet.addAll(Arrays.asList(nsNames)); nameSet.addAll(externalMap.keySet()); return (String[]) nameSet.toArray(new String[0]); } /* * Notes: This implmenetation of getVariableImpl handles the following * cases: 1) var in map not in local scope - var was added through map 2) * var in map and in local scope - var was added through namespace 3) var * not in map but in local scope - var was removed via map 4) var not in map * and not in local scope - non-existent var */ protected Variable getVariableImpl(String name, boolean recurse) throws UtilEvalError { // check the external map for the variable name Object value = externalMap.get(name); Variable var; if (value == null) { // The var is not in external map and it should // therefore not be // found in local scope (it may have been removed via // the map). // Clear it prophalactically. super.unsetVariable(name); // Search parent for var if applicable. var = super.getVariableImpl(name, recurse); } else { // Var in external map may be found in local scope with // type and // modifier info. Variable localVar = super.getVariableImpl(name, false); // If not in local scope then it was added via the // external map, // we'll wrap it and pass it along. Else we'll use the // local // version. if (localVar == null) var = new Variable(name, (Class) null, value, (Modifiers) null); else var = localVar; } return var; } /* * Note: the meaning of getDeclaredVariables() is not entirely clear, but * the name (and current usage in class generation support) suggests that * untyped variables should not be inclueded. Therefore we do not currently * have to add the external names here. */ public Variable[] getDeclaredVariables() { return super.getDeclaredVariables(); } public void setTypedVariable(String name, Class type, Object value, Modifiers modifiers) throws UtilEvalError { super.setTypedVariable(name, type, value, modifiers); putExternalMap(name, value); } /* * Note: we could override this method to allow bsh methods to appear in the * external map. */ public void setMethod(String name, BshMethod method) throws UtilEvalError { super.setMethod(name, method); } /* * Note: kind of far-fetched, but... we could override this method to allow * bsh methods to be inserted into this namespace via the map. */ public BshMethod getMethod(String name, Class[] sig, boolean declaredOnly) throws UtilEvalError { return super.getMethod(name, sig, declaredOnly); } /* * Note: this method should be overridden to add the names from the external * map, as is done in getVariableNames(); */ protected void getAllNamesAux(Vector vec) { super.getAllNamesAux(vec); } /** * Clear all variables, methods, and imports from this namespace and clear * all values from the external map (via Map clear()). */ public void clear() { super.clear(); externalMap.clear(); } /** * Place an unwrapped value in the external map. BeanShell primitive types * are represented by their object wrappers, so it is not possible to * differentiate between wrapper types and primitive types via the external * Map. * * @param name * the name of the value. * @param value * the value to set. */ protected void putExternalMap(String name, Object value) { if (value instanceof Variable) try { value = unwrapVariable((Variable) value); } catch (UtilEvalError ute) { // There should be no case for this. // unwrapVariable throws // UtilEvalError in some cases where it holds an // LHS or array // index. throw new InterpreterError("unexpected UtilEvalError"); } if (value instanceof Primitive) value = Primitive.unwrap((Primitive) value); externalMap.put(name, value); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy