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  /*
14   * soapUI, copyright (C) 2004-2010 eviware.com
15   *
16   * soapUI is free software; you can redistribute it and/or modify it under the
17   * terms of version 2.1 of the GNU Lesser General Public License as published by
18   * the Free Software Foundation.
19   *
20   * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
21   * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22   * See the GNU Lesser General Public License for more details at gnu.org.
23   */
24  
25  /*
26   * soapUI, copyright (C) 2004-2010 eviware.com
27   *
28   * soapUI is free software; you can redistribute it and/or modify it under the
29   * terms of version 2.1 of the GNU Lesser General Public License as published by
30   * the Free Software Foundation.
31   *
32   * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
33   * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
34   * See the GNU Lesser General Public License for more details at gnu.org.
35   */
36  
37  package com.eviware.soapui.impl.wsdl.mock.dispatch;
38  
39  import java.awt.BorderLayout;
40  import java.awt.event.ActionEvent;
41  import java.beans.PropertyChangeEvent;
42  import java.beans.PropertyChangeListener;
43  
44  import javax.swing.AbstractAction;
45  import javax.swing.Action;
46  import javax.swing.JComponent;
47  import javax.swing.JLabel;
48  import javax.swing.JPanel;
49  
50  import com.eviware.soapui.SoapUI;
51  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
52  import com.eviware.soapui.impl.wsdl.mock.DispatchException;
53  import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation;
54  import com.eviware.soapui.impl.wsdl.mock.WsdlMockRequest;
55  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
56  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResult;
57  import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunContext;
58  import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunner;
59  import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
60  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditor;
61  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditorModel;
62  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
63  import com.eviware.soapui.model.ModelItem;
64  import com.eviware.soapui.model.mock.MockRunContext;
65  import com.eviware.soapui.model.settings.Settings;
66  import com.eviware.soapui.support.StringUtils;
67  import com.eviware.soapui.support.UISupport;
68  import com.eviware.soapui.support.components.JXToolBar;
69  import com.eviware.soapui.support.scripting.ScriptEnginePool;
70  import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
71  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
72  
73  public class ScriptMockOperationDispatcher extends AbstractMockOperationDispatcher implements PropertyChangeListener
74  {
75  	private ScriptEnginePool scriptEnginePool;
76  	private GroovyEditor groovyEditor;
77  	private JPanel groovyEditorPanel;
78  
79  	public ScriptMockOperationDispatcher( WsdlMockOperation mockOperation )
80  	{
81  		super( mockOperation );
82  
83  		scriptEnginePool = new ScriptEnginePool( mockOperation );
84  		scriptEnginePool.setScript( mockOperation.getDispatchPath() );
85  
86  		mockOperation.addPropertyChangeListener( WsdlMockOperation.DISPATCH_PATH_PROPERTY, this );
87  	}
88  
89  	public WsdlMockResponse selectMockResponse( WsdlMockRequest request, WsdlMockResult result )
90  			throws DispatchException
91  	{
92  		String dispatchScript = getMockOperation().getDispatchPath();
93  		if( StringUtils.hasContent( dispatchScript ) )
94  		{
95  			SoapUIScriptEngine scriptEngine = scriptEnginePool.getScriptEngine();
96  
97  			try
98  			{
99  				WsdlMockService mockService = getMockOperation().getMockService();
100 				WsdlMockRunner mockRunner = mockService.getMockRunner();
101 				MockRunContext context = mockRunner == null ? new WsdlMockRunContext( mockService, null ) : mockRunner
102 						.getMockContext();
103 
104 				scriptEngine.setVariable( "context", context );
105 				scriptEngine.setVariable( "requestContext", request == null ? null : request.getRequestContext() );
106 				scriptEngine.setVariable( "mockRequest", request );
107 				scriptEngine.setVariable( "mockOperation", getMockOperation() );
108 				scriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
109 
110 				scriptEngine.setScript( dispatchScript );
111 				Object retVal = scriptEngine.run();
112 				return getMockOperation().getMockResponseByName( String.valueOf( retVal ) );
113 			}
114 			catch( Throwable e )
115 			{
116 				SoapUI.logError( e );
117 				throw new DispatchException( "Failed to dispatch using script; " + e );
118 			}
119 			finally
120 			{
121 				scriptEnginePool.returnScriptEngine( scriptEngine );
122 			}
123 		}
124 
125 		return null;
126 	}
127 
128 	@Override
129 	public void release()
130 	{
131 		scriptEnginePool.release();
132 
133 		releaseEditorComponent();
134 
135 		getMockOperation().removePropertyChangeListener( WsdlMockOperation.DISPATCH_PATH_PROPERTY, this );
136 
137 		super.release();
138 	}
139 
140 	@Override
141 	public JComponent getEditorComponent()
142 	{
143 		if( groovyEditorPanel == null )
144 		{
145 			groovyEditorPanel = new JPanel( new BorderLayout() );
146 		DispatchScriptGroovyEditorModel editorModel = new DispatchScriptGroovyEditorModel();
147 		groovyEditor = ( GroovyEditor )UISupport.getEditorFactory().buildGroovyEditor( editorModel );
148 		groovyEditorPanel.add( groovyEditor, BorderLayout.CENTER );
149 		groovyEditorPanel.add( buildGroovyEditorToolbar( editorModel ), BorderLayout.PAGE_START );
150 		}
151 
152 		return groovyEditorPanel;
153 	}
154 
155 	@Override
156 	public void releaseEditorComponent( )
157 	{
158 		if( groovyEditor != null )
159 			groovyEditor.release();
160 		
161 		groovyEditor = null;
162 		groovyEditorPanel = null;
163 		
164 		super.releaseEditorComponent( );
165 	}
166 
167 	protected JXToolBar buildGroovyEditorToolbar( DispatchScriptGroovyEditorModel editorModel )
168 	{
169 		JXToolBar toolbar = UISupport.createToolbar();
170 		toolbar.addSpace( 3 );
171 		toolbar.addFixed( UISupport.createToolbarButton( editorModel.getRunAction() ) );
172 		toolbar.addGlue();
173 
174 		JLabel label = new JLabel( "<html>Script is invoked with <code>log</code>, <code>context</code>, "
175 				+ "<code>requestContext</code>, <code>mockRequest</code> and <code>mockOperation</code> variables</html>" );
176 		label.setToolTipText( label.getText() );
177 		label.setMaximumSize( label.getPreferredSize() );
178 
179 		toolbar.add( label );
180 		toolbar.addFixed( ModelItemDesktopPanel.createActionButton( new ShowOnlineHelpAction(
181 				HelpUrls.MOCKOPERATION_SCRIPTDISPATCH_HELP_URL ), true ) );
182 		return toolbar;
183 	}
184 
185 	public void propertyChange( PropertyChangeEvent evt )
186 	{
187 		scriptEnginePool.setScript( String.valueOf( evt.getNewValue() ) );
188 	}
189 
190 	public static class Factory implements MockOperationDispatchFactory
191 	{
192 		public MockOperationDispatcher build( WsdlMockOperation mockOperation )
193 		{
194 			return new ScriptMockOperationDispatcher( mockOperation );
195 		}
196 	}
197 
198 	public class DispatchScriptGroovyEditorModel implements GroovyEditorModel
199 	{
200 		private RunScriptAction runScriptAction = new RunScriptAction();
201 
202 		public String[] getKeywords()
203 		{
204 			return new String[] { "mockRequest", "context", "requestContext", "log", "mockOperation" };
205 		}
206 
207 		public Action getRunAction()
208 		{
209 			return runScriptAction;
210 		}
211 
212 		public String getScript()
213 		{
214 			return getMockOperation().getDispatchPath();
215 		}
216 
217 		public Settings getSettings()
218 		{
219 			return getMockOperation().getSettings();
220 		}
221 
222 		public void setScript( String text )
223 		{
224 			getMockOperation().setDispatchPath( text );
225 		}
226 
227 		public String getScriptName()
228 		{
229 			return "Dispatch";
230 		}
231 
232 		public void addPropertyChangeListener( PropertyChangeListener listener )
233 		{
234 		}
235 
236 		public void removePropertyChangeListener( PropertyChangeListener listener )
237 		{
238 		}
239 
240 		public ModelItem getModelItem()
241 		{
242 			return getMockOperation();
243 		}
244 	}
245 
246 	private class RunScriptAction extends AbstractAction
247 	{
248 		public RunScriptAction()
249 		{
250 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ) );
251 			putValue( Action.SHORT_DESCRIPTION, "Runs this script using a mockRequest and context" );
252 		}
253 
254 		public void actionPerformed( ActionEvent e )
255 		{
256 			WsdlMockResult lastMockResult = getMockOperation().getLastMockResult();
257 			WsdlMockRequest mockRequest = lastMockResult == null ? null : lastMockResult.getMockRequest();
258 
259 			try
260 			{
261 				WsdlMockResponse retVal = selectMockResponse( mockRequest, null );
262 				UISupport.showInfoMessage( "Script returned [" + ( retVal == null ? "null" : retVal.getName() ) + "]" );
263 			}
264 			catch( Exception e1 )
265 			{
266 				UISupport.showErrorMessage( e1 );
267 			}
268 		}
269 	}
270 }