001: /* GroovyInterpreter.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Fri Feb 9 15:47:22 2007, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2007 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.zkmax.scripting.groovy;
020:
021: import java.util.HashMap;
022:
023: import groovy.lang.Binding;
024: import groovy.lang.GroovyShell;
025: import groovy.lang.Script;
026: import groovy.lang.Closure;
027: import org.codehaus.groovy.runtime.InvokerHelper;
028:
029: import org.zkoss.xel.Function;
030: import org.zkoss.zk.ui.Page;
031: import org.zkoss.zk.ui.UiException;
032: import org.zkoss.zk.scripting.util.GenericInterpreter;
033:
034: /**
035: * Groovy interpreter.
036: *
037: * <p><a href="http://groovy.codehaus.org/">More about Groovy</a>.
038: *
039: * @author tomyeh
040: */
041: public class GroovyInterpreter extends GenericInterpreter {
042: private Binding _global;
043: private GroovyShell _ip;
044:
045: public GroovyInterpreter() {
046: }
047:
048: /** Returns the top-level scope.
049: */
050: /*package*/Binding getGlobalScope() {
051: return _global;
052: }
053:
054: /** Returns the native interpreter, or null if it is not initialized
055: * or destroyed.
056: * From application's standpoint, it never returns null, and the returned
057: * object must be an instance of {@link groovy.lang.GroovyShell}
058: * @since 3.0.2
059: */
060: public Object getNativeInterpreter() {
061: return _ip;
062: }
063:
064: //GenericInterpreter//
065: protected void exec(String script) {
066: _ip.evaluate(script);
067: }
068:
069: protected boolean contains(String name) {
070: return _global.getVariables().containsKey(name);
071: }
072:
073: protected Object get(String name) {
074: try {
075: return _global.getVariable(name);
076: } catch (groovy.lang.MissingPropertyException ex) { //Groovy throws exceptions instead of returning null
077: return null;
078: }
079: }
080:
081: protected void set(String name, Object value) {
082: _global.setVariable(name, value);
083: }
084:
085: protected void unset(String name) {
086: _global.getVariables().remove(name);
087: }
088:
089: //Interpreter//
090: public void init(Page owner, String zslang) {
091: super .init(owner, zslang);
092:
093: _global = new Binding(new Variables());
094: _ip = new GroovyShell(_global);
095: }
096:
097: public void destroy() {
098: _ip = null;
099: _global = null;
100: super .destroy();
101: }
102:
103: /**TODO: need to digg out a solution from groovy's manual
104: public Class getClass(String clsnm) {
105: }
106: */
107: /** Returns the method.
108: * <p>Currently it only looks for closures, and argTypes are ignored.
109: */
110: public Function getFunction(String name, Class[] argTypes) {
111: final Object val = get(name);
112: if (!(val instanceof Closure))
113: return null;
114: return new ClosureFunction((Closure) val);
115: }
116:
117: //supporting class//
118: /** Extends Binding to support ZK namespaces.
119: */
120: private class Variables extends HashMap {
121: public Object get(Object key) {
122: Object val = super .get(key);
123: if (val != null || containsKey(key)
124: || !(key instanceof String))
125: return val;
126: val = getFromNamespace((String) key);
127: return val != UNDEFINED ? val : null;
128: }
129: }
130:
131: private static class ClosureFunction implements Function {
132: private final Closure _closure;
133:
134: private ClosureFunction(Closure closure) {
135: _closure = closure;
136: }
137:
138: //-- Function --//
139: public Class[] getParameterTypes() {
140: return new Class[0];
141: }
142:
143: public Class getReturnType() {
144: return Object.class;
145: }
146:
147: public Object invoke(Object obj, Object[] args)
148: throws Exception {
149: if (args == null)
150: return _closure.call();
151: else
152: return _closure.call(args);
153: }
154:
155: public java.lang.reflect.Method toMethod() {
156: return null;
157: }
158: }
159: }
|