View Javadoc

1   /*
2    * soapUI, copyright (C) 2004-2009 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-2009 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-2009 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  
78  	public ScriptMockOperationDispatcher( WsdlMockOperation mockOperation )
79  	{
80  		super( mockOperation );
81  
82  		scriptEnginePool = new ScriptEnginePool( mockOperation );
83  		scriptEnginePool.setScript( mockOperation.getDispatchPath() );
84  
85  		mockOperation.addPropertyChangeListener( WsdlMockOperation.DISPATCH_PATH_PROPERTY, this );
86  	}
87  
88  	public WsdlMockResponse selectMockResponse( WsdlMockRequest request, WsdlMockResult result )
89  			throws DispatchException
90  	{
91  		String dispatchScript = getMockOperation().getDispatchPath();
92  		if( StringUtils.hasContent( dispatchScript ) )
93  		{
94  			SoapUIScriptEngine scriptEngine = scriptEnginePool.getScriptEngine();
95  
96  			try
97  			{
98  				WsdlMockService mockService = getMockOperation().getMockService();
99  				WsdlMockRunner mockRunner = mockService.getMockRunner();
100 				MockRunContext context = mockRunner == null ? new WsdlMockRunContext( mockService, null ) : mockRunner
101 						.getMockContext();
102 
103 				scriptEngine.setVariable( "context", context );
104 				scriptEngine.setVariable( "requestContext", request == null ? null : request.getRequestContext() );
105 				scriptEngine.setVariable( "mockRequest", request );
106 				scriptEngine.setVariable( "mockOperation", getMockOperation() );
107 				scriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
108 
109 				scriptEngine.setScript( dispatchScript );
110 				Object retVal = scriptEngine.run();
111 				return getMockOperation().getMockResponseByName( String.valueOf( retVal ) );
112 			}
113 			catch( Throwable e )
114 			{
115 				SoapUI.logError( e );
116 				throw new DispatchException( "Failed to dispatch using script; " + e );
117 			}
118 			finally
119 			{
120 				scriptEnginePool.returnScriptEngine( scriptEngine );
121 			}
122 		}
123 
124 		return null;
125 	}
126 
127 	@Override
128 	public void release()
129 	{
130 		scriptEnginePool.release();
131 
132 		if( groovyEditor != null )
133 			groovyEditor.release();
134 
135 		getMockOperation().removePropertyChangeListener( WsdlMockOperation.DISPATCH_PATH_PROPERTY, this );
136 
137 		super.release();
138 	}
139 
140 	@Override
141 	public JComponent buildEditorComponent()
142 	{
143 		JPanel groovyEditorPanel = new JPanel( new BorderLayout() );
144 		DispatchScriptGroovyEditorModel editorModel = new DispatchScriptGroovyEditorModel();
145 		groovyEditor = ( GroovyEditor )UISupport.getEditorFactory().buildGroovyEditor( editorModel );
146 		groovyEditorPanel.add( groovyEditor, BorderLayout.CENTER );
147 		groovyEditorPanel.add( buildGroovyEditorToolbar( editorModel ), BorderLayout.PAGE_START );
148 
149 		return groovyEditorPanel;
150 	}
151 
152 	protected JXToolBar buildGroovyEditorToolbar( DispatchScriptGroovyEditorModel editorModel )
153 	{
154 		JXToolBar toolbar = UISupport.createToolbar();
155 		toolbar.addSpace( 3 );
156 		toolbar.addFixed( UISupport.createToolbarButton( editorModel.getRunAction() ) );
157 		toolbar.addGlue();
158 
159 		JLabel label = new JLabel( "<html>Script is invoked with <code>log</code>, <code>context</code>, "
160 				+ "<code>requestContext</code>, <code>mockRequest</code> and <code>mockOperation</code> variables</html>" );
161 		label.setToolTipText( label.getText() );
162 		label.setMaximumSize( label.getPreferredSize() );
163 
164 		toolbar.add( label );
165 		toolbar.addFixed( ModelItemDesktopPanel.createActionButton( new ShowOnlineHelpAction(
166 				HelpUrls.MOCKOPERATION_SCRIPTDISPATCH_HELP_URL ), true ) );
167 		return toolbar;
168 	}
169 
170 	public void propertyChange( PropertyChangeEvent evt )
171 	{
172 		scriptEnginePool.setScript( String.valueOf( evt.getNewValue() ) );
173 	}
174 
175 	public static class Factory implements MockOperationDispatchFactory
176 	{
177 		public MockOperationDispatcher build( WsdlMockOperation mockOperation )
178 		{
179 			return new ScriptMockOperationDispatcher( mockOperation );
180 		}
181 	}
182 
183 	public class DispatchScriptGroovyEditorModel implements GroovyEditorModel
184 	{
185 		private RunScriptAction runScriptAction = new RunScriptAction();
186 
187 		public String[] getKeywords()
188 		{
189 			return new String[] { "mockRequest", "context", "requestContext", "log", "mockOperation" };
190 		}
191 
192 		public Action getRunAction()
193 		{
194 			return runScriptAction;
195 		}
196 
197 		public String getScript()
198 		{
199 			return getMockOperation().getDispatchPath();
200 		}
201 
202 		public Settings getSettings()
203 		{
204 			return getMockOperation().getSettings();
205 		}
206 
207 		public void setScript( String text )
208 		{
209 			getMockOperation().setDispatchPath( text );
210 		}
211 
212 		public String getScriptName()
213 		{
214 			return "Dispatch";
215 		}
216 
217 		public void addPropertyChangeListener( PropertyChangeListener listener )
218 		{
219 		}
220 
221 		public void removePropertyChangeListener( PropertyChangeListener listener )
222 		{
223 		}
224 
225 		public ModelItem getModelItem()
226 		{
227 			return getMockOperation();
228 		}
229 	}
230 
231 	private class RunScriptAction extends AbstractAction
232 	{
233 		public RunScriptAction()
234 		{
235 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ) );
236 			putValue( Action.SHORT_DESCRIPTION, "Runs this script using a mockRequest and context" );
237 		}
238 
239 		public void actionPerformed( ActionEvent e )
240 		{
241 			WsdlMockResult lastMockResult = getMockOperation().getLastMockResult();
242 			WsdlMockRequest mockRequest = lastMockResult == null ? null : lastMockResult.getMockRequest();
243 
244 			try
245 			{
246 				WsdlMockResponse retVal = selectMockResponse( mockRequest, null );
247 				UISupport.showInfoMessage( "Script returned [" + ( retVal == null ? "null" : retVal.getName() ) + "]" );
248 			}
249 			catch( Exception e1 )
250 			{
251 				UISupport.showErrorMessage( e1 );
252 			}
253 		}
254 	}
255 }