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