1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package org.codehaus.groovy.bsf;
35
36 import groovy.lang.GroovyClassLoader;
37 import groovy.lang.GroovyShell;
38 import groovy.lang.Script;
39 import groovy.lang.Binding;
40
41 import java.io.ByteArrayInputStream;
42 import java.security.AccessController;
43 import java.security.PrivilegedAction;
44 import java.util.HashMap;
45 import java.util.Map;
46 import java.util.Vector;
47
48 import org.apache.bsf.BSFDeclaredBean;
49 import org.apache.bsf.BSFException;
50 import org.apache.bsf.BSFManager;
51 import org.apache.bsf.util.BSFFunctions;
52 import org.codehaus.groovy.runtime.InvokerHelper;
53 import org.codehaus.groovy.control.CompilerConfiguration;
54
55 /***
56 * A Caching implementation of the GroovyEngine
57 *
58 * @author James Birchfield
59 */
60 public class CachingGroovyEngine extends GroovyEngine {
61 private static final String[] EMPTY_ARGS = {
62 };
63
64 private Map evalScripts;
65 private Map execScripts;
66 private Binding context;
67 private ClassLoader parent;
68 private GroovyClassLoader loader;
69
70
71 /***
72 * Evaluate an expression.
73 */
74 public Object eval(String source, int lineNo, int columnNo, Object script) throws BSFException {
75 try {
76
77 Class scriptClass = (Class) evalScripts.get(script);
78 if (scriptClass == null) {
79 scriptClass = loader.parseClass(new ByteArrayInputStream(script.toString().getBytes()), source);
80 evalScripts.put(script, scriptClass);
81 }
82 else {
83 System.out.println("eval() - Using cached script...");
84 }
85
86
87 Script s = InvokerHelper.createScript(scriptClass, context);
88 return s.run();
89 }
90 catch (Exception e) {
91 e.printStackTrace();
92 throw new BSFException(BSFException.REASON_EXECUTION_ERROR, "exception from Groovy: " + e, e);
93 }
94 }
95
96 /***
97 * Execute a script.
98 */
99 public void exec(String source, int lineNo, int columnNo, Object script) throws BSFException {
100 try {
101
102
103 Class scriptClass = (Class) execScripts.get(script);
104 if (scriptClass == null) {
105 scriptClass = loader.parseClass(new ByteArrayInputStream(script.toString().getBytes()), source);
106 execScripts.put(script, scriptClass);
107 }
108 else {
109 System.out.println("exec() - Using cached version of class...");
110 }
111 InvokerHelper.invokeMethod(scriptClass, "main", EMPTY_ARGS);
112 }
113 catch (Exception e) {
114 e.printStackTrace();
115 throw new BSFException(BSFException.REASON_EXECUTION_ERROR, "exception from Groovy: " + e, e);
116 }
117 }
118
119 /***
120 * Initialize the engine.
121 */
122 public void initialize(final BSFManager mgr, String lang, Vector declaredBeans) throws BSFException {
123 super.initialize(mgr, lang, declaredBeans);
124 parent = mgr.getClassLoader();
125 if (parent == null)
126 parent = GroovyShell.class.getClassLoader();
127 final ClassLoader finalParent = parent;
128 this.loader =
129 (GroovyClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
130 public Object run() {
131 CompilerConfiguration configuration = new CompilerConfiguration();
132 configuration.setClasspath(mgr.getClassPath());
133 return new GroovyClassLoader(finalParent, configuration);
134 }
135 });
136 execScripts = new HashMap();
137 evalScripts = new HashMap();
138 context = shell.getContext();
139
140
141
142 context.setVariable("bsf", new BSFFunctions(mgr, this));
143
144 int size = declaredBeans.size();
145 for (int i = 0; i < size; i++) {
146 declareBean((BSFDeclaredBean) declaredBeans.elementAt(i));
147 }
148 }
149 }