1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps.assertions;
14
15 import java.awt.BorderLayout;
16 import java.awt.Component;
17 import java.awt.Dimension;
18 import java.awt.event.ActionEvent;
19 import java.awt.event.MouseAdapter;
20 import java.awt.event.MouseEvent;
21
22 import javax.swing.AbstractAction;
23 import javax.swing.Action;
24 import javax.swing.BorderFactory;
25 import javax.swing.Box;
26 import javax.swing.JButton;
27 import javax.swing.JComponent;
28 import javax.swing.JDialog;
29 import javax.swing.JLabel;
30 import javax.swing.JPanel;
31 import javax.swing.JScrollPane;
32 import javax.swing.JSplitPane;
33
34 import org.apache.log4j.Logger;
35 import org.apache.xmlbeans.XmlObject;
36
37 import com.eviware.soapui.SoapUI;
38 import com.eviware.soapui.config.RequestAssertionConfig;
39 import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
40 import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditor;
41 import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditorModel;
42 import com.eviware.soapui.impl.wsdl.submit.WsdlMessageExchange;
43 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
44 import com.eviware.soapui.impl.wsdl.support.assertions.Assertable;
45 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
46 import com.eviware.soapui.impl.wsdl.teststeps.WsdlMessageAssertion;
47 import com.eviware.soapui.impl.wsdl.teststeps.WsdlResponseMessageExchange;
48 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
49 import com.eviware.soapui.model.iface.SubmitContext;
50 import com.eviware.soapui.model.settings.Settings;
51 import com.eviware.soapui.model.testsuite.TestStep;
52 import com.eviware.soapui.support.UISupport;
53 import com.eviware.soapui.support.components.JXToolBar;
54 import com.eviware.soapui.support.log.JLogList;
55 import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
56 import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
57 import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
58 import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
59 import com.jgoodies.forms.builder.ButtonBarBuilder;
60
61 /***
62 * Assertion performed by a custom Grooy Script
63 *
64 * @author ole.matzura
65 */
66
67 public class GroovyScriptAssertion extends WsdlMessageAssertion implements RequestAssertion, ResponseAssertion
68 {
69 public static final String ID = "GroovyScriptAssertion";
70 public static final String LABEL = "Script Assertion";
71 private String scriptText;
72 private SoapUIScriptEngine scriptEngine;
73 private JDialog dialog;
74 private GroovyScriptAssertionPanel groovyScriptAssertionPanel;
75
76 public GroovyScriptAssertion( RequestAssertionConfig assertionConfig, Assertable modelItem )
77 {
78 super( assertionConfig, modelItem, true, true );
79
80 XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader( getConfiguration());
81 scriptText = reader.readString( "scriptText", "" );
82
83 scriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
84 scriptEngine.setScript( scriptText );
85 }
86
87 @Override
88 protected String internalAssertRequest( WsdlMessageExchange messageExchange, SubmitContext context ) throws AssertionException
89 {
90 return assertScript( messageExchange, context, SoapUI.ensureGroovyLog() );
91 }
92
93 private String assertScript( WsdlMessageExchange messageExchange, SubmitContext context, Logger log ) throws AssertionException
94 {
95 try
96 {
97 scriptEngine.setVariable("context", context);
98 scriptEngine.setVariable("messageExchange", messageExchange);
99 scriptEngine.setVariable( "log", log );
100
101 Object result = scriptEngine.run();
102 return result == null ? null : result.toString();
103 }
104 catch( Throwable e )
105 {
106 throw new AssertionException( new AssertionError( e.getMessage() ));
107 }
108 finally
109 {
110 scriptEngine.clearVariables();
111 }
112 }
113
114 @Override
115 protected String internalAssertResponse( WsdlMessageExchange messageExchange, SubmitContext context ) throws AssertionException
116 {
117 return assertScript( messageExchange, context, SoapUI.ensureGroovyLog() );
118 }
119
120 @Override
121 public boolean configure()
122 {
123 if( dialog == null )
124 {
125 dialog = new JDialog( UISupport.getMainFrame(), "Script Assertion", true );
126 groovyScriptAssertionPanel = new GroovyScriptAssertionPanel();
127 dialog.setContentPane( groovyScriptAssertionPanel );
128 dialog.pack();
129 }
130
131 dialog.setVisible( true );
132
133 setConfiguration( createConfiguration() );
134 return true;
135 }
136
137 protected XmlObject createConfiguration()
138 {
139 XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
140 builder.add( "scriptText", scriptText );
141 return builder.finish();
142 }
143
144 private class GroovyScriptAssertionPanel extends JPanel
145 {
146 private GroovyEditor editor;
147 private JSplitPane mainSplit;
148 private JLogList logArea;
149 private RunAction runAction = new RunAction();
150 private Logger logger;
151
152 public GroovyScriptAssertionPanel()
153 {
154 super( new BorderLayout() );
155
156 buildUI();
157 setPreferredSize( new Dimension( 600, 440 ));
158
159 logger = Logger.getLogger( "ScriptAssertion." + getName() );
160 editor.requestFocusInWindow();
161 }
162
163 public void release()
164 {
165 logArea.release();
166 logger = null;
167 }
168
169 private void buildUI()
170 {
171 editor = new GroovyEditor( new ScriptStepGroovyEditorModel( ));
172
173 logArea = new JLogList( "Groovy Test Log" );
174 logArea.addLogger( "ScriptAssertion." + getName(), true );
175 logArea.getLogList().addMouseListener( new MouseAdapter() {
176
177 public void mouseClicked(MouseEvent e)
178 {
179 if( e.getClickCount() < 2 )
180 return;
181
182 String value = logArea.getLogList().getSelectedValue().toString();
183 if( value == null )
184 return;
185
186 editor.selectError( value );
187 }} );
188
189 JScrollPane scrollPane = new JScrollPane( editor );
190 scrollPane.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder( 0, 3, 0, 3 ),
191 scrollPane.getBorder() ));
192
193 mainSplit = UISupport.createVerticalSplit( scrollPane, logArea);
194 mainSplit.setDividerLocation( 280 );
195 mainSplit.setResizeWeight( 0.8 );
196 add( mainSplit, BorderLayout.CENTER );
197 add( buildToolbar(), BorderLayout.NORTH );
198 add( buildStatusBar(), BorderLayout.SOUTH );
199 }
200
201 private Component buildStatusBar()
202 {
203 ButtonBarBuilder builder = new ButtonBarBuilder();
204
205 builder.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.GROOVYASSERTION_HELP_URL )));
206 builder.addGlue();
207 builder.addFixed( new JButton( new OkAction() ) );
208 builder.setBorder( BorderFactory.createEmptyBorder( 0, 3, 3, 3 ));
209 return builder.getPanel();
210 }
211
212 private JComponent buildToolbar()
213 {
214 JXToolBar toolBar = UISupport.createToolbar();
215 JButton runButton = UISupport.createToolbarButton( runAction );
216 toolBar.add( runButton );
217 toolBar.add( Box.createHorizontalGlue() );
218 JLabel label = new JLabel("<html>Script is invoked with <code>log</code>, <code>context</code> " +
219 "and <code>messageExchange</code> variables</html>");
220 label.setToolTipText( label.getText() );
221 label.setMaximumSize( label.getPreferredSize() );
222
223 toolBar.addFixed( label);
224 toolBar.addSpace( 3 );
225
226 return toolBar;
227 }
228
229 private final class OkAction extends AbstractAction
230 {
231 public OkAction()
232 {
233 super( "OK" );
234 }
235
236 public void actionPerformed( ActionEvent e )
237 {
238 dialog.setVisible( false );
239 }
240 }
241
242 private class ScriptStepGroovyEditorModel implements GroovyEditorModel
243 {
244 public String[] getKeywords()
245 {
246 return new String[] {"log", "context", "messageExchange"};
247 }
248
249 public Action getRunAction()
250 {
251 return runAction;
252 }
253
254 public String getScript()
255 {
256 return scriptText;
257 }
258
259 public void setScript( String text )
260 {
261 scriptText = text;
262 scriptEngine.setScript( scriptText );
263 }
264
265 public Settings getSettings()
266 {
267 return SoapUI.getSettings();
268 }}
269
270 private class RunAction extends AbstractAction
271 {
272 public RunAction()
273 {
274 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ));
275 putValue( Action.SHORT_DESCRIPTION, "Runs this assertion script against the last messageExchange with a mock testContext" );
276 }
277
278 public void actionPerformed(ActionEvent e)
279 {
280 TestStep testStep = getAssertable().getTestStep();
281 WsdlMessageExchange exchange = null;
282
283 if( testStep instanceof WsdlTestRequestStep )
284 {
285 WsdlTestRequestStep testRequestStep = ( WsdlTestRequestStep ) testStep;
286 exchange = new WsdlResponseMessageExchange( testRequestStep.getTestRequest() );
287 ((WsdlResponseMessageExchange)exchange).setResponse( testRequestStep.getTestRequest().getResponse() );
288 }
289
290 try
291 {
292 String result = assertScript( exchange, new WsdlTestRunContext( testStep ), logger );
293 UISupport.showInfoMessage( "Script Assertion Passed" + ((result==null) ? "" : ": [" + result + "]" ));
294 }
295 catch( AssertionException e1 )
296 {
297 UISupport.showErrorMessage( e1.getMessage() );
298 }
299 catch( Throwable t )
300 {
301 SoapUI.logError( t );
302 UISupport.showErrorMessage( t.getMessage() );
303 }
304
305 editor.requestFocusInWindow();
306 }
307 }
308 }
309
310 @Override
311 public void release()
312 {
313 super.release();
314
315 scriptEngine.release();
316
317 if( groovyScriptAssertionPanel != null )
318 groovyScriptAssertionPanel.release();
319 }
320 }