001: /*
002: $Id: Script.java 4262 2006-11-25 13:27:06Z blackdrag $
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 org.codehaus.groovy.ast.expr.ArgumentListExpression;
049: import org.codehaus.groovy.control.CompilationFailedException;
050: import org.codehaus.groovy.runtime.DefaultGroovyMethods;
051: import org.codehaus.groovy.runtime.InvokerHelper;
052:
053: import java.io.File;
054: import java.io.IOException;
055:
056: /**
057: * This object represents a Groovy script
058: *
059: * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
060: * @author Guillaume Laforge
061: * @version $Revision: 4262 $
062: */
063: public abstract class Script extends GroovyObjectSupport {
064: private Binding binding = new Binding();
065:
066: protected Script() {
067: }
068:
069: protected Script(Binding binding) {
070: this .binding = binding;
071: }
072:
073: public Binding getBinding() {
074: return binding;
075: }
076:
077: public void setBinding(Binding binding) {
078: this .binding = binding;
079: }
080:
081: public Object getProperty(String property) {
082: try {
083: return binding.getVariable(property);
084: } catch (MissingPropertyException e) {
085: return super .getProperty(property);
086: }
087: }
088:
089: public void setProperty(String property, Object newValue) {
090: if ("binding".equals(property))
091: setBinding((Binding) newValue);
092: else
093: binding.setVariable(property, newValue);
094: }
095:
096: /**
097: * Invoke a method (or closure in the binding) defined.
098: *
099: * @param name method to call
100: * @param args arguments to pass to the method
101: * @return value
102: */
103: public Object invokeMethod(String name, Object args) {
104: try {
105: return super .invokeMethod(name, args);
106: }
107: // if the method was not found in the current scope (the script's methods)
108: // let's try to see if there's a method closure with the same name in the binding
109: catch (MissingMethodException mme) {
110: try {
111: if (name.equals(mme.getMethod())) {
112: Object boundClosure = binding.getVariable(name);
113: if (boundClosure != null
114: && boundClosure instanceof Closure) {
115: return ((Closure) boundClosure)
116: .call((Object[]) args);
117: } else {
118: throw mme;
119: }
120: } else {
121: throw mme;
122: }
123: } catch (MissingPropertyException mpe) {
124: throw mme;
125: }
126: }
127: }
128:
129: /**
130: * The main instance method of a script which has variables in scope
131: * as defined by the current {@link Binding} instance.
132: */
133: public abstract Object run();
134:
135: // println helper methods
136:
137: /**
138: * Prints a newline to the current 'out' variable which should be a PrintWriter
139: * or at least have a println() method defined on it.
140: * If there is no 'out' property then print to standard out.
141: */
142: public void println() {
143: Object object;
144:
145: try {
146: object = getProperty("out");
147: } catch (MissingPropertyException e) {
148: System.out.println();
149: return;
150: }
151:
152: InvokerHelper.invokeMethod(object, "println",
153: ArgumentListExpression.EMPTY_ARRAY);
154: }
155:
156: /**
157: * Prints the value to the current 'out' variable which should be a PrintWriter
158: * or at least have a print() method defined on it.
159: * If there is no 'out' property then print to standard out.
160: */
161: public void print(Object value) {
162: Object object;
163:
164: try {
165: object = getProperty("out");
166: } catch (MissingPropertyException e) {
167: DefaultGroovyMethods.print(System.out, value);
168: return;
169: }
170:
171: InvokerHelper.invokeMethod(object, "print",
172: new Object[] { value });
173: }
174:
175: /**
176: * Prints the value and a newline to the current 'out' variable which should be a PrintWriter
177: * or at least have a println() method defined on it.
178: * If there is no 'out' property then print to standard out.
179: */
180: public void println(Object value) {
181: Object object;
182:
183: try {
184: object = getProperty("out");
185: } catch (MissingPropertyException e) {
186: DefaultGroovyMethods.println(System.out, value);
187: return;
188: }
189:
190: InvokerHelper.invokeMethod(object, "println",
191: new Object[] { value });
192: }
193:
194: /**
195: * A helper method to allow the dynamic evaluation of groovy expressions using this
196: * scripts binding as the variable scope
197: *
198: * @param expression is the Groovy script expression to evaluate
199: */
200: public Object evaluate(String expression)
201: throws CompilationFailedException, IOException {
202: GroovyShell shell = new GroovyShell(binding);
203: return shell.evaluate(expression);
204: }
205:
206: /**
207: * A helper method to allow the dynamic evaluation of groovy expressions using this
208: * scripts binding as the variable scope
209: *
210: * @param file is the Groovy script to evaluate
211: */
212: public Object evaluate(File file)
213: throws CompilationFailedException, IOException {
214: GroovyShell shell = new GroovyShell(binding);
215: return shell.evaluate(file);
216: }
217:
218: /**
219: * A helper method to allow scripts to be run taking command line arguments
220: */
221: public void run(File file, String[] arguments)
222: throws CompilationFailedException, IOException {
223: GroovyShell shell = new GroovyShell(binding);
224: shell.run(file, arguments);
225: }
226: }
|