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