1 /* GroovyGrailsInterpreter.java
9 Fri Feb 9 15:47:22 2007, Created by tomyeh
10 June 2008, A lot of improvement, by Chanwit
13 Copyright (C) 2007 Potix Corporation. All Rights Reserved.
14 Copyright (C) 2008 Chanwit Kaewkasi
17 This program is distributed under GPL Version 2.0 in the hope that
18 it will be useful, but WITHOUT ANY WARRANTY.
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
;
48 * <p><a href="http://groovy.codehaus.org/">More about Groovy</a>.
49 * <p><a href="http://grails.org/">Grails</a>
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() {
78 /** Returns the native interpreter, or null if it is not initialized
80 * From application's standpoint, it never returns null, and the returned
81 * object must be an instance of {@link groovy.lang.GroovyShell}
84 public Object
getNativeInterpreter() {
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
);
100 protected boolean contains(String name
) {
101 return _global
.getVariables().containsKey(name
);
103 protected Object
get(String name
) {
105 return _global
.getVariable(name
);
106 } catch (groovy
.lang
.MissingPropertyException ex
) { //Groovy throws exceptions instead of returning 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
);
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() {
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
))
141 return new ClosureFunction((Closure
)val
);
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
))
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
) {
163 public Class
[] getParameterTypes() {
166 public Class
getReturnType() {
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() {