View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
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 }