View Javadoc

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