001    /*
002     $Id: Binding.java 1590 2005-01-05 14:46:41Z glaforge $
003    
004     Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005    
006     Redistribution and use of this software and associated documentation
007     ("Software"), with or without modification, are permitted provided
008     that the following conditions are met:
009    
010     1. Redistributions of source code must retain copyright
011        statements and notices.  Redistributions must also contain a
012        copy of this document.
013    
014     2. Redistributions in binary form must reproduce the
015        above copyright notice, this list of conditions and the
016        following disclaimer in the documentation and/or other
017        materials provided with the distribution.
018    
019     3. The name "groovy" must not be used to endorse or promote
020        products derived from this Software without prior written
021        permission of The Codehaus.  For written permission,
022        please contact info@codehaus.org.
023    
024     4. Products derived from this Software may not be called "groovy"
025        nor may "groovy" appear in their names without prior written
026        permission of The Codehaus. "groovy" is a registered
027        trademark of The Codehaus.
028    
029     5. Due credit should be given to The Codehaus -
030        http://groovy.codehaus.org/
031    
032     THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033     ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034     NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035     FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
036     THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043     OF THE POSSIBILITY OF SUCH DAMAGE.
044    
045     */
046    package groovy.lang;
047    
048    import java.util.HashMap;
049    import java.util.Map;
050    
051    /**
052     * Represents the variable bindings of a script which can be altered
053     * from outside the script object or created outside of a script and passed
054     * into it.
055     * 
056     * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
057     * @version $Revision: 1590 $
058     */
059    public class Binding extends GroovyObjectSupport {
060        private Map variables;
061        
062        public Binding() {
063            variables = new HashMap();
064        }
065        
066        public Binding(Map variables) {
067            this.variables = variables;
068        }
069        
070        /**
071         * A helper constructor used in main(String[]) method calls
072         * 
073         * @param args are the command line arguments from a main()
074         */
075        public Binding(String[] args) {
076            this();
077            setVariable("args", args);
078        }
079        
080        /**
081         * @param name the name of the variable to lookup
082         * @return the variable value
083         */
084        public Object getVariable(String name) {
085            Object result = variables.get(name);
086            
087            if (result == null && !variables.containsKey(name)) {
088                throw new MissingPropertyException("The property '" + name + "' is missing from the binding.",
089                                                   name, Binding.class);
090            }
091            
092            return result;
093        }
094        
095        /**
096         * Sets the value of the given variable
097         * @param name the name of the variable to set
098         * @param value the new value for the given variable
099         */
100        public void setVariable(String name, Object value) {
101            variables.put(name, value);
102        }
103        
104        public Map getVariables() {
105            return variables;
106        }
107    
108        /**
109         * Overloaded to make variables appear as bean properties or via the subscript operator
110         */
111        public Object getProperty(String property) {
112            /** @todo we should check if we have the property with the metaClass instead of try/catch  */
113            try {
114                return super.getProperty(property);
115            }
116            catch (MissingPropertyException e) {
117                return getVariable(property);
118            }
119        }
120    
121        /**
122         * Overloaded to make variables appear as bean properties or via the subscript operator
123         */
124        public void setProperty(String property, Object newValue) {
125            /** @todo we should check if we have the property with the metaClass instead of try/catch  */
126            try {
127                super.setProperty(property, newValue);
128            }
129            catch (MissingPropertyException e) {
130                setVariable(property, newValue);
131            }
132        }
133    
134    }