View Javadoc

    1   /*
    2    *  soapUI, copyright (C) 2004-2007 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;
    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 }