org.sqsh.VariableManager.java Source code

Java tutorial

Introduction

Here is the source code for org.sqsh.VariableManager.java

Source

/*
 * Copyright 2007-2012 Scott C. Gray
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sqsh;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import org.apache.commons.digester.Digester;
import org.sqsh.variables.StringVariable;

/**
 * Provides an interface to manipulating session variables. This class
 * goes to some length so that it can be utilized as a Map but does not
 * properly implement all of the methods that Map requires, as these
 * were not necessary for my purposes.
 */
public class VariableManager implements Map<String, String> {

    private static final Logger LOG = Logger.getLogger(VariableManager.class.getName());

    private VariableManager parent = null;

    private Map<String, Variable> variables = new HashMap<String, Variable>();

    /**
     * Map of named beans that the PropertyVariable can refer to.
     */
    private Map<String, Object> beans = new HashMap<String, Object>();

    private static class VarEntry implements Entry<String, String> {

        private Variable var;

        public VarEntry(Variable var) {

            this.var = var;
        }

        /**
         * @see java.util.Map.Entry#getKey()
         */
        public String getKey() {

            return var.getName();
        }

        /**
         * @see java.util.Map.Entry#getValue()
         */
        public String getValue() {

            return var.toString();
        }

        /**
         * @see java.util.Map.Entry#setValue(java.lang.Object)
         */
        public String setValue(String value) {

            String oldValue = var.toString();
            var.setValue(value);

            return oldValue;
        }
    }

    /**
     * Creates a variable manager.
     * @param session The session that owns the manager.
     */
    public VariableManager() {

    }

    /**
     * Creates a variable manager with a parent manager. In this case,
     * gets will attempt to defer to the parent manager if this one
     * doesn't have the value.
     * 
     * @param parent The parent manager.
     */
    public VariableManager(VariableManager parent) {

        this.parent = parent;
    }

    /**
     * Adds a bean to the context.
     * @param name The name of the bean
     * @param bean The bean
     */
    public void addBean(String name, Object bean) {

        beans.put(name, bean);
    }

    /**
     * Returns a named bean.
     * @param name The name of the bean
     * @return the bean or null if it does not exist.
     */
    public Object getBean(String name) {

        return beans.get(name);
    }

    /**
     * Returns the complete list of variables.
     * 
     * @return The complete list of variables.
     */
    public Variable[] getVariables() {

        return getVariables(false);
    }

    /**
     * Returns the complete list of variables.
     * 
     * @param includeParent If true, then the variables that are defined
     *   in the parent's context are included in the list.
     *   
     * @return The complete list of variables.
     */
    public Variable[] getVariables(boolean includeParent) {

        if (includeParent == false || parent == null) {

            return variables.values().toArray(new Variable[0]);
        }

        List<Variable> vars = new ArrayList<Variable>();
        vars.addAll(variables.values());

        for (Variable var : parent.getVariables()) {

            vars.add(var);
        }

        return vars.toArray(new Variable[0]);
    }

    /**
     * Clears the variable map.
     */
    public void clear() {

        variables.clear();
    }

    /**
     * Sets a variable.
     * 
     * @param name The name of the variable.
     * @param value The value of the variable.
     * 
     * @return The old value of the variable.
     */
    public String put(String name, String value) {

        return put(name, value, false);
    }

    /**
     * @see java.util.Map#putAll(java.util.Map)
     */
    public void putAll(Map<? extends String, ? extends String> map) {

        for (Entry<? extends String, ? extends String> e : map.entrySet()) {

            put(e.getKey(), e.getValue());
        }
    }

    /**
     * Sets the value of a session variable.
     * 
     * @param name The name of the variable to set.
     * @param value The value of the variable to set.
     * @param isExported Set to true if the variable is to be exported
     *   to processes spawned by this session.
     * @return The current state of the variable.
     * 
     * @throws CannotSetValueError if the value of the variable cannot be
     * changed for one reason or another.
     */
    public String put(String name, String value, boolean isExported) throws CannotSetValueError {

        Variable var = variables.get(name);
        String oldValue = null;

        if (var == null) {

            var = new StringVariable(name, value, isExported);
            var.setExported(isExported);

            put(var);
        } else {

            oldValue = var.toString();
            var.setValue(value);
        }

        return oldValue;
    }

    /**
     * Adds a variable.
     * @param var
     */
    public void put(Variable var) {

        var.setManager(this);
        variables.put(var.getName(), var);
    }

    /**
     * Adds a variable that can never be removed.
     * @param var
     */
    public void putUnremoveable(Variable var) {

        var.setRemoveable(false);
        var.setManager(this);
        variables.put(var.getName(), var);
    }

    /**
     * Returns true of the manager contains the provided key.
     * 
     * @param key The name of a variable.
     */
    public boolean containsKey(Object key) {

        boolean ok = variables.containsKey(key);
        if (ok == false && parent != null) {

            ok = parent.containsKey(key);
        }

        return ok;
    }

    /**
     * Same as containsKey() except that it only looks in the local manager
     * and not the parent.
     * 
     * @param key The key to look for.
     * @return true if the key is contained locally.
     */
    public boolean containsLocal(Object key) {

        return variables.containsKey(key);
    }

    /**
     * Returns true if the manager contains the provided variable.
     * 
     * @param value The value we are searching for.
     * @return true on match.
     */
    public boolean containsValue(Object value) {

        boolean ok = false;
        for (Variable var : variables.values()) {

            if (value.equals(var.toString())) {

                ok = true;
                break;
            }
        }

        if (ok == false && parent != null) {

            ok = parent.containsValue(value);
        }

        return ok;
    }

    /**
     * Returns the entry set for the map.
     */
    public Set<Entry<String, String>> entrySet() {

        Set<Entry<String, String>> set = new HashSet<Entry<String, String>>();

        for (Variable var : variables.values()) {

            set.add(new VarEntry(var));
        }

        if (parent != null) {

            set.addAll(parent.entrySet());
        }

        return set;
    }

    /**
     * Returns false.
     */
    public boolean equals(Object o) {

        return false;
    }

    /**
     * Returns the current state of a variable.
     * 
     * @param name The name of the variable to return.
     * @return The current variable state or null if the variable
     *   is not defined.
     */
    public String get(Object name) {

        Variable var = variables.get(name);
        if (var == null && parent != null) {

            return parent.get(name);
        }

        if (var != null) {

            return var.toString();
        }

        return null;
    }

    /**
     * Provides direct access to the underlying variable.
     * 
     * @param name The name of the variable to be retrieved.
     * @return The variable or null if there is none.
     */
    public Variable getVariable(String name) {

        Variable var = variables.get(name);
        if (var == null && parent != null) {

            return parent.getVariable(name);
        }

        return var;
    }

    /**
     * Returns true of the map is empty.
     */
    public boolean isEmpty() {

        boolean ok = (variables.size() == 0);
        if (ok == false && parent != null) {

            ok = parent.isEmpty();
        }

        return ok;
    }

    /**
     * Returns the set of keys installed in this map.
     */
    public Set<String> keySet() {

        if (parent == null) {

            return variables.keySet();
        }

        Set<String> set = new HashSet<String>();
        set.addAll(variables.keySet());
        set.addAll(parent.keySet());

        return set;
    }

    /**
     * Removes a variable.
     * @param name The name of the variable.
     * @return The variable that was removed or null if the variable
     *   was not defined in the first place.
     */
    @Override
    public String remove(Object name) {

        Variable var = variables.get(name);
        if (var == null && parent != null) {

            return parent.remove(name);
        }

        if (!var.isRemoveable()) {

            throw new IllegalAccessError(
                    "Variable \"" + name + "\" is a " + "configuration variable and cannot be unset");
        }

        variables.remove(name);
        return var.toString();
    }

    /**
     * Returns the number of entries in the map.
     */
    public int size() {

        int size = variables.size();
        if (parent != null) {

            size += parent.size();
        }

        return size;
    }

    /**
     * Returns the values o the map.
     */
    public Collection<String> values() {

        List<String> values = new ArrayList<String>();
        for (Variable var : variables.values()) {

            values.add(var.toString());
        }

        if (parent != null) {

            values.addAll(parent.values());
        }

        return values;
    }

    /**
     * Initializes the variable manager with variables as described by
     * the XML file pointed to by URL.
     */
    public void load(String location, InputStream in) {

        String path;
        Digester digester = new Digester();
        digester.setValidating(false);

        path = "Variables/String";
        digester.addObjectCreate(path, "org.sqsh.variables.StringVariable");
        digester.addSetNext(path, "putUnremoveable", "org.sqsh.Variable");
        digester.addCallMethod(path, "setName", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0, "name");
        digester.addCallMethod(path, "setValue", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0, "value");

        path = "Variables/Integer";
        digester.addObjectCreate(path, "org.sqsh.variables.IntegerVariable");
        digester.addSetNext(path, "putUnremoveable", "org.sqsh.Variable");
        digester.addCallMethod(path, "setName", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0, "name");
        digester.addCallMethod(path, "setMinValue", 1, new Class[] { java.lang.Integer.class });
        digester.addCallParam(path, 0, "min");
        digester.addCallMethod(path, "setMaxValue", 1, new Class[] { java.lang.Integer.class });
        digester.addCallParam(path, 0, "max");
        digester.addCallMethod(path, "setValue", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0);

        path = "Variables/Dynamic";
        digester.addObjectCreate(path, "org.sqsh.Variable", "class");
        digester.addSetNext(path, "putUnremoveable", "org.sqsh.Variable");
        digester.addCallMethod(path, "setName", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0, "name");
        digester.addCallMethod(path, "setValue", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0, "value");

        path = "Variables/Property";
        digester.addObjectCreate(path, "org.sqsh.variables.PropertyVariable");
        digester.addSetNext(path, "putUnremoveable", "org.sqsh.Variable");
        digester.addCallMethod(path, "setName", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0, "name");
        digester.addCallMethod(path, "setBean", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0, "bean");
        digester.addCallMethod(path, "setProperty", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0, "property");
        digester.addCallMethod(path, "setSettable", 1, new Class[] { java.lang.Boolean.class });
        digester.addCallParam(path, 0, "settable");
        digester.addCallMethod(path, "setQuiet", 1, new Class[] { java.lang.Boolean.class });
        digester.addCallParam(path, 0, "quiet");

        path = "*/Description";
        digester.addCallMethod(path, "setDescription", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0);
        path = "*/Help";
        digester.addCallMethod(path, "setHelp", 1, new Class[] { java.lang.String.class });
        digester.addCallParam(path, 0);

        digester.push(this);
        try {

            digester.parse(in);
        } catch (Exception e) {

            LOG.severe("Failed to parse variable definition file '" + location + "': " + e.getMessage());
        }
    }

}