1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.support.scripting.groovy;
14
15 import groovy.lang.Binding;
16 import groovy.lang.GroovyClassLoader;
17 import groovy.lang.GroovyShell;
18 import groovy.lang.Script;
19
20 import org.codehaus.groovy.control.CompilerConfiguration;
21
22 import com.eviware.soapui.SoapUIExtensionClassLoader;
23 import com.eviware.soapui.SoapUIExtensionClassLoader.SoapUIClassLoaderState;
24 import com.eviware.soapui.support.StringUtils;
25 import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
26
27 /***
28 * A Groovy ScriptEngine
29 *
30 * @author ole.matzura
31 */
32
33 public class SoapUIGroovyScriptEngine implements SoapUIScriptEngine
34 {
35 private GroovyClassLoader classLoader;
36 private GroovyShell shell;
37 private Binding binding;
38 private Script script;
39 private String scriptText;
40 protected ScriptSaver saver = new ScriptSaver();
41
42 public SoapUIGroovyScriptEngine( ClassLoader parentClassLoader )
43 {
44 classLoader = new GroovyClassLoader( parentClassLoader );
45 binding = new Binding();
46 CompilerConfiguration config = new CompilerConfiguration();
47 config.setDebug( true );
48 config.setVerbose( true );
49 shell = new GroovyShell( classLoader, binding, config );
50 }
51
52 protected class ScriptSaver
53 {
54 private String text = null;
55 private boolean locked = false;
56
57 public synchronized void save( String scriptText )
58 {
59 if( locked )
60 text = scriptText;
61 else
62 synchronizedSetScript( scriptText );
63 }
64
65 public synchronized void lockSave()
66 {
67 locked = true;
68 }
69
70 public synchronized void unlockSave()
71 {
72 if( text != null )
73 {
74 synchronizedSetScript( text );
75 text = null;
76 }
77 locked = false;
78 }
79 }
80
81 public synchronized Object run() throws Exception
82 {
83 saver.lockSave();
84 SoapUIClassLoaderState state = SoapUIExtensionClassLoader.ensure();
85 try
86 {
87
88 if( StringUtils.isNullOrEmpty( scriptText ) )
89 return null;
90
91 if( script == null )
92 {
93 compile();
94 }
95
96 Object result = script.run();
97
98 return result;
99 }
100 finally
101 {
102 state.restore();
103 saver.unlockSave();
104 }
105 }
106
107 protected synchronized void synchronizedSetScript( String scriptText )
108 {
109 if( scriptText != null && scriptText.equals( this.scriptText ) )
110 return;
111
112 if( script != null )
113 {
114 script.setBinding( null );
115 script = null;
116
117 if( shell != null )
118 shell.resetLoadedClasses();
119
120 classLoader.clearCache();
121 }
122
123 this.scriptText = scriptText;
124 }
125
126 public synchronized void setScript( String scriptText )
127 {
128 if( scriptText != null && !scriptText.equals( this.scriptText ) )
129 saver.save( scriptText );
130 }
131
132 protected synchronized void reset()
133 {
134 saver.lockSave();
135
136 script = null;
137
138 saver.unlockSave();
139 }
140
141 public synchronized void compile() throws Exception
142 {
143 if( script == null )
144 {
145 SoapUIClassLoaderState state = SoapUIExtensionClassLoader.ensure();
146 try
147 {
148 script = shell.parse( scriptText );
149 script.setBinding( binding );
150 }
151 finally
152 {
153 state.restore();
154 }
155 }
156 }
157
158 public synchronized void setVariable( String name, Object value )
159 {
160 binding.setVariable( name, value );
161 }
162
163 public synchronized void clearVariables()
164 {
165 if( binding != null )
166 binding.getVariables().clear();
167 }
168
169 public synchronized void release()
170 {
171 script = null;
172
173 if( binding != null )
174 {
175 binding.getVariables().clear();
176 binding = null;
177 }
178
179 if( shell != null )
180 {
181 shell.resetLoadedClasses();
182 shell = null;
183 }
184 }
185
186 protected Binding getBinding()
187 {
188 return binding;
189 }
190
191 protected GroovyClassLoader getClassLoader()
192 {
193 return classLoader;
194 }
195
196 protected Script getScript()
197 {
198 return script;
199 }
200
201 protected String getScriptText()
202 {
203 return scriptText;
204 }
205
206 protected GroovyShell getShell()
207 {
208 return shell;
209 }
210 }