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