remove jars
[zkgrails.git] / src / java / org / zkoss / zkmax / scripting / groovy / GroovyGrailsInterpreter.java
blob17e1d89367245d39fa7de67451f14eb35cb9aa84
1 /* GroovyGrailsInterpreter.java
3 {{IS_NOTE
4 Purpose:
6 Description:
8 History:
9 Fri Feb 9 15:47:22 2007, Created by tomyeh
10 June 2008, A lot of improvement, by Chanwit
11 }}IS_NOTE
13 Copyright (C) 2007 Potix Corporation. All Rights Reserved.
14 Copyright (C) 2008 Chanwit Kaewkasi
16 {{IS_RIGHT
17 This program is distributed under GPL Version 2.0 in the hope that
18 it will be useful, but WITHOUT ANY WARRANTY.
19 }}IS_RIGHT
21 package org.zkoss.zkmax.scripting.groovy;
23 import java.util.HashMap;
24 import java.lang.ref.WeakReference;
26 import groovy.lang.Binding;
27 import groovy.lang.GroovyShell;
28 import groovy.lang.Script;
29 import groovy.lang.Closure;
30 import groovy.lang.GroovyClassLoader;
32 import org.codehaus.groovy.grails.commons.GrailsApplication;
34 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
35 import org.springframework.context.ApplicationContext;
36 import org.springframework.web.context.support.WebApplicationContextUtils;
38 import org.codehaus.groovy.runtime.InvokerHelper;
40 import org.zkoss.xel.Function;
41 import org.zkoss.zk.ui.Page;
42 import org.zkoss.zk.ui.UiException;
43 import org.zkoss.zk.scripting.util.GenericInterpreter;
45 /**
46 * Groovy interpreter.
48 * <p><a href="http://groovy.codehaus.org/">More about Groovy</a>.
49 * <p><a href="http://grails.org/">Grails</a>
51 * @author tomyeh
52 * @author Chanwit Kaewkasi
54 public class GroovyGrailsInterpreter extends GenericInterpreter {
56 private static GroovyClassLoader GCL;
57 // TODO make this thread-safe
58 private static HashMap<String,Class<?>> cachedScripts = new HashMap<String,Class<?>>();
60 private Binding _global;
61 private GroovyShell _ip;
62 private String _requestPath;
64 public GroovyGrailsInterpreter() {
65 if(GroovyGrailsInterpreter.GCL == null) {
66 ApplicationContext _ctx = org.zkoss.zkplus.spring.SpringUtil.getApplicationContext();
67 GrailsApplication app = (GrailsApplication) _ctx.getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class);
68 GroovyGrailsInterpreter.GCL = new GroovyClassLoader(app.getClassLoader());
72 /** Returns the top-level scope.
74 /*package*/ Binding getGlobalScope() {
75 return _global;
78 /** Returns the native interpreter, or null if it is not initialized
79 * or destroyed.
80 * From application's standpoint, it never returns null, and the returned
81 * object must be an instance of {@link groovy.lang.GroovyShell}
82 * @since 3.0.2
84 public Object getNativeInterpreter() {
85 return _ip;
88 //GenericInterpreter//
89 protected void exec(String script) {
90 String key = _requestPath + script;
91 if(cachedScripts.containsKey(key)==false) {
92 Class<?> c = GroovyGrailsInterpreter.GCL.parseClass(script);
93 cachedScripts.put(key, c);
95 Class<?> c = cachedScripts.get(key);
96 Script scriptObject = InvokerHelper.createScript(c, _global);
97 scriptObject.run();
100 protected boolean contains(String name) {
101 return _global.getVariables().containsKey(name);
103 protected Object get(String name) {
104 try {
105 return _global.getVariable(name);
106 } catch (groovy.lang.MissingPropertyException ex) { //Groovy throws exceptions instead of returning null
107 return null;
110 protected void set(String name, Object value) {
111 _global.setVariable(name, value);
113 protected void unset(String name) {
114 _global.getVariables().remove(name);
117 //Interpreter//
118 public void init(Page owner, String zslang) {
119 super.init(owner, zslang);
120 _requestPath = owner.getRequestPath();
121 _global = new Binding(new Variables());
122 _ip = new GroovyShell(GroovyGrailsInterpreter.GCL, _global);
124 public void destroy() {
125 _ip = null;
126 _global = null;
127 super.destroy();
130 /**TODO: need to digg out a solution from groovy's manual
131 public Class getClass(String clsnm) {
134 /** Returns the method.
135 * <p>Currently it only looks for closures, and argTypes are ignored.
137 public Function getFunction(String name, Class[] argTypes) {
138 final Object val = get(name);
139 if (!(val instanceof Closure))
140 return null;
141 return new ClosureFunction((Closure)val);
144 //supporting class//
145 /** Extends Binding to support ZK namespaces.
147 private class Variables extends HashMap {
148 public Object get(Object key) {
149 Object val = super.get(key);
150 if (val != null || containsKey(key) || !(key instanceof String))
151 return val;
152 val = getFromNamespace((String)key);
153 return val != UNDEFINED ? val: null;
156 private static class ClosureFunction implements Function {
157 private final Closure _closure;
158 private ClosureFunction(Closure closure) {
159 _closure = closure;
162 //-- Function --//
163 public Class[] getParameterTypes() {
164 return new Class[0];
166 public Class getReturnType() {
167 return Object.class;
169 public Object invoke(Object obj, Object[] args) throws Exception {
170 if (args == null) return _closure.call();
171 else return _closure.call(args);
173 public java.lang.reflect.Method toMethod() {
174 return null;