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, 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 UISupport.initDialogActions( dialog, groovyScriptAssertionPanel.getShowOnlineHelpAction(),
129 groovyScriptAssertionPanel.getDefaultButton());
130 dialog.setSize( 600, 500 );
131 dialog.setModal( true );
132 dialog.pack();
133 }
134
135 UISupport.showDialog( dialog );
136
137 setConfiguration( createConfiguration() );
138 return true;
139 }
140
141 protected XmlObject createConfiguration()
142 {
143 XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
144 builder.add( "scriptText", scriptText );
145 return builder.finish();
146 }
147
148 private class GroovyScriptAssertionPanel extends JPanel
149 {
150 private GroovyEditor editor;
151 private JSplitPane mainSplit;
152 private JLogList logArea;
153 private RunAction runAction = new RunAction();
154 private Logger logger;
155 private JButton okButton;
156 private ShowOnlineHelpAction showOnlineHelpAction;
157
158 public GroovyScriptAssertionPanel()
159 {
160 super( new BorderLayout() );
161
162 buildUI();
163 setPreferredSize( new Dimension( 600, 440 ));
164
165 logger = Logger.getLogger( "ScriptAssertion." + getName() );
166 editor.requestFocusInWindow();
167 }
168
169 public void release()
170 {
171 logArea.release();
172 editor.release();
173 logger = null;
174 }
175
176 private void buildUI()
177 {
178 editor = new GroovyEditor( new ScriptStepGroovyEditorModel( ));
179
180 logArea = new JLogList( "Groovy Test Log" );
181 logArea.addLogger( "ScriptAssertion." + getName(), true );
182 logArea.getLogList().addMouseListener( new MouseAdapter() {
183
184 public void mouseClicked(MouseEvent e)
185 {
186 if( e.getClickCount() < 2 )
187 return;
188
189 String value = logArea.getLogList().getSelectedValue().toString();
190 if( value == null )
191 return;
192
193 editor.selectError( value );
194 }} );
195
196 JScrollPane scrollPane = new JScrollPane( editor );
197 scrollPane.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder( 0, 3, 0, 3 ),
198 scrollPane.getBorder() ));
199
200 mainSplit = UISupport.createVerticalSplit( scrollPane, logArea);
201 mainSplit.setDividerLocation( 280 );
202 mainSplit.setResizeWeight( 0.8 );
203 add( mainSplit, BorderLayout.CENTER );
204 add( buildToolbar(), BorderLayout.NORTH );
205 add( buildStatusBar(), BorderLayout.SOUTH );
206 }
207
208 public JButton getDefaultButton()
209 {
210 return okButton;
211 }
212
213 public ShowOnlineHelpAction getShowOnlineHelpAction()
214 {
215 return showOnlineHelpAction;
216 }
217
218 private Component buildStatusBar()
219 {
220 ButtonBarBuilder builder = new ButtonBarBuilder();
221
222 showOnlineHelpAction = new ShowOnlineHelpAction( HelpUrls.GROOVYASSERTION_HELP_URL );
223 builder.addFixed( UISupport.createToolbarButton( showOnlineHelpAction));
224 builder.addGlue();
225 okButton = new JButton( new OkAction() );
226 builder.addFixed( okButton );
227 builder.setBorder( BorderFactory.createEmptyBorder( 0, 3, 3, 3 ));
228 return builder.getPanel();
229 }
230
231 private JComponent buildToolbar()
232 {
233 JXToolBar toolBar = UISupport.createToolbar();
234 JButton runButton = UISupport.createToolbarButton( runAction );
235 toolBar.add( runButton );
236 toolBar.add( Box.createHorizontalGlue() );
237 JLabel label = new JLabel("<html>Script is invoked with <code>log</code>, <code>context</code> " +
238 "and <code>messageExchange</code> variables</html>");
239 label.setToolTipText( label.getText() );
240 label.setMaximumSize( label.getPreferredSize() );
241
242 toolBar.addFixed( label);
243 toolBar.addSpace( 3 );
244
245 return toolBar;
246 }
247
248 private final class OkAction extends AbstractAction
249 {
250 public OkAction()
251 {
252 super( "OK" );
253 }
254
255 public void actionPerformed( ActionEvent e )
256 {
257 dialog.setVisible( false );
258 }
259 }
260
261 private class ScriptStepGroovyEditorModel implements GroovyEditorModel
262 {
263 public String[] getKeywords()
264 {
265 return new String[] {"log", "context", "messageExchange"};
266 }
267
268 public Action getRunAction()
269 {
270 return runAction;
271 }
272
273 public String getScript()
274 {
275 return scriptText;
276 }
277
278 public void setScript( String text )
279 {
280 scriptText = text;
281 scriptEngine.setScript( scriptText );
282 }
283
284 public Settings getSettings()
285 {
286 return SoapUI.getSettings();
287 }}
288
289 private class RunAction extends AbstractAction
290 {
291 public RunAction()
292 {
293 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ));
294 putValue( Action.SHORT_DESCRIPTION, "Runs this assertion script against the last messageExchange with a mock testContext" );
295 }
296
297 public void actionPerformed(ActionEvent e)
298 {
299 TestStep testStep = getAssertable().getTestStep();
300 WsdlMessageExchange exchange = null;
301
302 if( testStep instanceof WsdlTestRequestStep )
303 {
304 WsdlTestRequestStep testRequestStep = ( WsdlTestRequestStep ) testStep;
305 exchange = new WsdlResponseMessageExchange( testRequestStep.getTestRequest() );
306 ((WsdlResponseMessageExchange)exchange).setResponse( testRequestStep.getTestRequest().getResponse() );
307 }
308
309 try
310 {
311 String result = assertScript( exchange, new WsdlTestRunContext( testStep ), logger );
312 UISupport.showInfoMessage( "Script Assertion Passed" + ((result==null) ? "" : ": [" + result + "]" ));
313 }
314 catch( AssertionException e1 )
315 {
316 UISupport.showErrorMessage( e1.getMessage() );
317 }
318 catch( Throwable t )
319 {
320 SoapUI.logError( t );
321 UISupport.showErrorMessage( t.getMessage() );
322 }
323
324 editor.requestFocusInWindow();
325 }
326 }
327 }
328
329 @Override
330 public void release()
331 {
332 super.release();
333 scriptEngine.release();
334
335 if( groovyScriptAssertionPanel != null )
336 groovyScriptAssertionPanel.release();
337 }
338 }