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