/*
* soapUI, copyright (C) 2004-2011 eviware.com
*
* soapUI is free software; you can redistribute it and/or modify it under the
* terms of version 2.1 of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details at gnu.org.
*/
package com.eviware.soapui.impl.wsdl.panels.teststeps;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.ListModel;
import javax.swing.SwingUtilities;
import javax.swing.text.Document;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.rest.RestRequestInterface;
import com.eviware.soapui.impl.support.AbstractHttpRequest;
import com.eviware.soapui.impl.support.HttpUtils;
import com.eviware.soapui.impl.support.components.ModelItemXmlEditor;
import com.eviware.soapui.impl.support.http.HttpRequest;
import com.eviware.soapui.impl.support.panels.AbstractHttpXmlRequestDesktopPanel;
import com.eviware.soapui.impl.wsdl.support.HelpUrls;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestInterface;
import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestStep;
import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestStepInterface;
import com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestInterface;
import com.eviware.soapui.impl.wsdl.teststeps.actions.AddAssertionAction;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.iface.Submit;
import com.eviware.soapui.model.iface.SubmitContext;
import com.eviware.soapui.model.iface.Request.SubmitException;
import com.eviware.soapui.model.support.ModelSupport;
import com.eviware.soapui.model.testsuite.AssertionError;
import com.eviware.soapui.model.testsuite.AssertionsListener;
import com.eviware.soapui.model.testsuite.LoadTestRunner;
import com.eviware.soapui.model.testsuite.TestAssertion;
import com.eviware.soapui.model.testsuite.TestCaseRunner;
import com.eviware.soapui.model.testsuite.Assertable.AssertionStatus;
import com.eviware.soapui.monitor.support.TestMonitorListenerAdapter;
import com.eviware.soapui.security.SecurityTestRunner;
import com.eviware.soapui.support.DocumentListenerAdapter;
import com.eviware.soapui.support.ListDataChangeListener;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.components.JComponentInspector;
import com.eviware.soapui.support.components.JInspectorPanel;
import com.eviware.soapui.support.components.JInspectorPanelFactory;
import com.eviware.soapui.support.components.JUndoableTextField;
import com.eviware.soapui.support.components.JXToolBar;
import com.eviware.soapui.support.log.JLogList;
public class HttpTestRequestDesktopPanel extends
AbstractHttpXmlRequestDesktopPanel<HttpTestRequestStepInterface, HttpTestRequestInterface<?>>
{
private JLogList logArea;
private InternalTestMonitorListener testMonitorListener = new InternalTestMonitorListener();
private JButton addAssertionButton;
protected boolean updatingRequest;
private AssertionsPanel assertionsPanel;
private JInspectorPanel inspectorPanel;
private JComponentInspector<?> assertionInspector;
private JComponentInspector<?> logInspector;
private InternalAssertionsListener assertionsListener = new InternalAssertionsListener();
private long startTime;
private SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
private boolean updating;
private JUndoableTextField pathTextField;
private JCheckBox downloadResources;
private JComboBox methodCombo;
public HttpTestRequestDesktopPanel( HttpTestRequestStepInterface testStep )
{
super( testStep, testStep.getTestRequest() );
SoapUI.getTestMonitor().addTestMonitorListener( testMonitorListener );
setEnabled( !SoapUI.getTestMonitor().hasRunningTest( testStep.getTestCase() ) );
testStep.getTestRequest().addAssertionsListener( assertionsListener );
getSubmitButton().setEnabled( getSubmit() == null && StringUtils.hasContent( getRequest().getEndpoint() ) );
}
protected JComponent buildLogPanel()
{
logArea = new JLogList( "Request Log" );
logArea.getLogList().getModel().addListDataListener( new ListDataChangeListener()
{
@Override
public void dataChanged( ListModel model )
{
logInspector.setTitle( "Request Log (" + model.getSize() + ")" );
}
} );
return logArea;
}
protected AssertionsPanel buildAssertionsPanel()
{
return new AssertionsPanel( getRequest() )
{
@Override
protected void selectError( AssertionError error )
{
ModelItemXmlEditor<?, ?> editor = getResponseEditor();
editor.requestFocus();
}
};
}
@Override
public void setContent( JComponent content )
{
inspectorPanel.setContentComponent( content );
}
@Override
public void removeContent( JComponent content )
{
inspectorPanel.setContentComponent( null );
}
@Override
protected String getHelpUrl()
{
return HelpUrls.TESTREQUESTEDITOR_HELP_URL;
}
@Override
protected JComponent buildContent()
{
JComponent component = super.buildContent();
inspectorPanel = JInspectorPanelFactory.build( component );
assertionsPanel = buildAssertionsPanel();
assertionInspector = new JComponentInspector<JComponent>( assertionsPanel, "Assertions ("
+ getModelItem().getAssertionCount() + ")", "Assertions for this Test Request", true );
inspectorPanel.addInspector( assertionInspector );
logInspector = new JComponentInspector<JComponent>( buildLogPanel(), "Request Log (0)", "Log of requests", true );
inspectorPanel.addInspector( logInspector );
inspectorPanel.setDefaultDividerLocation( 0.6F );
inspectorPanel.setCurrentInspector( "Assertions" );
updateStatusIcon();
getSubmitButton().setEnabled( getSubmit() == null && StringUtils.hasContent( getRequest().getEndpoint() ) );
return inspectorPanel.getComponent();
}
@Override
protected JComponent buildEndpointComponent()
{
return null;
}
private void updateStatusIcon()
{
AssertionStatus status = getModelItem().getTestRequest().getAssertionStatus();
switch( status )
{
case FAILED :
{
assertionInspector.setIcon( UISupport.createImageIcon( "/failed_assertion.gif" ) );
inspectorPanel.activate( assertionInspector );
break;
}
case UNKNOWN :
{
assertionInspector.setIcon( UISupport.createImageIcon( "/unknown_assertion.gif" ) );
break;
}
case VALID :
{
assertionInspector.setIcon( UISupport.createImageIcon( "/valid_assertion.gif" ) );
inspectorPanel.deactivate();
break;
}
}
}
protected void addMethodCombo( JXToolBar toolbar )
{
methodCombo = new JComboBox( RestRequestInterface.RequestMethod.getMethods() );
methodCombo.setSelectedItem( getRequest().getMethod() );
methodCombo.setToolTipText( "Set desired HTTP method" );
methodCombo.addItemListener( new ItemListener()
{
public void itemStateChanged( ItemEvent e )
{
updatingRequest = true;
getRequest().setMethod( ( RestRequestInterface.RequestMethod )methodCombo.getSelectedItem() );
updatingRequest = false;
}
} );
toolbar.addLabeledFixed( "Method", methodCombo );
toolbar.addSeparator();
}
protected void addToolbarComponents( JXToolBar toolbar )
{
toolbar.addSeparator();
addMethodCombo( toolbar );
pathTextField = new JUndoableTextField();
pathTextField.setPreferredSize( new Dimension( 300, 20 ) );
pathTextField.setText( getRequest().getEndpoint() );
pathTextField.setToolTipText( pathTextField.getText() );
pathTextField.getDocument().addDocumentListener( new DocumentListenerAdapter()
{
@Override
public void update( Document document )
{
if( updating )
return;
updating = true;
String text = pathTextField.getText();
getRequest().setEndpoint( HttpUtils.ensureEndpointStartsWithProtocol( text ) );
if( !text.equals( getRequest().getEndpoint() ) )
SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
pathTextField.setText( getRequest().getEndpoint() );
}
} );
updating = false;
}
} );
pathTextField.addKeyListener( new KeyAdapter()
{
@Override
public void keyPressed( KeyEvent e )
{
if( e.getKeyCode() == KeyEvent.VK_ENTER )
{
onSubmit();
}
}
} );
toolbar.addLabeledFixed( "Request URL:", pathTextField );
toolbar.addSeparator();
addCheckBox( toolbar );
}
private void addCheckBox( JXToolBar toolbar )
{
downloadResources = new JCheckBox();
try
{
downloadResources.setSelected( ( ( HttpRequest )( ( HttpTestRequestStep )getModelItem() ).getHttpRequest() )
.getDownloadIncludedResources() );
}
catch( Exception cce )
{
SoapUI.logError( cce );
}
downloadResources.setPreferredSize( new Dimension( 17, 17 ) );
downloadResources.setToolTipText( "Download all included resources as attachments!" );
downloadResources.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent e )
{
try
{
if( 1001 == e.getID() && getModelItem() instanceof HttpTestRequestStep )
{
( ( HttpRequest )( ( HttpTestRequestStep )getModelItem() ).getHttpRequest() )
.setDownloadIncludedResources( ( ( JCheckBox )e.getSource() ).isSelected() );
}
}
catch( Exception cce )
{
SoapUI.logError( cce );
}
}
} );
toolbar.addLabeledFixed( "Download Resources", downloadResources );
toolbar.addSeparator();
}
@Override
protected JComponent buildToolbar()
{
addAssertionButton = createActionButton( new AddAssertionAction( getRequest() ), true );
JPanel panel = new JPanel( new BorderLayout() );
panel.add( super.buildToolbar(), BorderLayout.NORTH );
JXToolBar toolbar = UISupport.createToolbar();
addToolbarComponents( toolbar );
panel.add( toolbar, BorderLayout.SOUTH );
return panel;
}
@Override
protected void insertButtons( JXToolBar toolbar )
{
toolbar.add( addAssertionButton );
}
@Override
public void setEnabled( boolean enabled )
{
if( enabled == true )
enabled = !SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem().getTestCase() )
&& !SoapUI.getTestMonitor().hasRunningSecurityTest( getModelItem().getTestCase() );
super.setEnabled( enabled );
addAssertionButton.setEnabled( enabled );
assertionsPanel.setEnabled( enabled );
if( SoapUI.getTestMonitor().hasRunningLoadTest( getRequest().getTestCase() )
|| SoapUI.getTestMonitor().hasRunningSecurityTest( getModelItem().getTestCase() ) )
{
getRequest().removeSubmitListener( this );
}
else
{
getRequest().addSubmitListener( this );
}
}
@Override
protected Submit doSubmit() throws SubmitException
{
return getRequest().submit( new WsdlTestRunContext( getModelItem() ), true );
}
private final class InternalAssertionsListener implements AssertionsListener
{
public void assertionAdded( TestAssertion assertion )
{
assertionInspector.setTitle( "Assertions (" + getModelItem().getAssertionCount() + ")" );
}
public void assertionRemoved( TestAssertion assertion )
{
assertionInspector.setTitle( "Assertions (" + getModelItem().getAssertionCount() + ")" );
}
public void assertionMoved( TestAssertion assertion, int ix, int offset )
{
assertionInspector.setTitle( "Assertions (" + getModelItem().getAssertionCount() + ")" );
}
}
@Override
public boolean beforeSubmit( Submit submit, SubmitContext context )
{
boolean result = super.beforeSubmit( submit, context );
startTime = System.currentTimeMillis();
return result;
}
@Override
protected void logMessages( String message, String infoMessage )
{
super.logMessages( message, infoMessage );
logArea.addLine( sdf.format( new Date( startTime ) ) + " - " + message );
}
@Override
public void afterSubmit( Submit submit, SubmitContext context )
{
super.afterSubmit( submit, context );
if( !isHasClosed() )
updateStatusIcon();
}
@Override
public boolean onClose( boolean canCancel )
{
if( super.onClose( canCancel ) )
{
assertionsPanel.release();
inspectorPanel.release();
SoapUI.getTestMonitor().removeTestMonitorListener( testMonitorListener );
logArea.release();
getModelItem().getTestRequest().removeAssertionsListener( assertionsListener );
return true;
}
return false;
}
@Override
public boolean dependsOn( ModelItem modelItem )
{
if( getRequest().getOperation() == null )
return modelItem == getRequest() || modelItem == getModelItem()
|| ModelSupport.getModelItemProject( getRequest() ) == modelItem
|| modelItem == getModelItem().getTestCase() || modelItem == getModelItem().getTestCase().getTestSuite();
else
return modelItem == getRequest() || modelItem == getModelItem() || modelItem == getRequest().getOperation()
|| modelItem == getRequest().getOperation().getInterface()
|| modelItem == getRequest().getOperation().getInterface().getProject()
|| modelItem == getModelItem().getTestCase() || modelItem == getModelItem().getTestCase().getTestSuite();
}
private class InternalTestMonitorListener extends TestMonitorListenerAdapter
{
@Override
public void loadTestFinished( LoadTestRunner runner )
{
setEnabled( !SoapUI.getTestMonitor().hasRunningTest( getModelItem().getTestCase() ) );
}
@Override
public void loadTestStarted( LoadTestRunner runner )
{
if( runner.getLoadTest().getTestCase() == getModelItem().getTestCase() )
setEnabled( false );
}
public void securityTestFinished( SecurityTestRunner runner )
{
setEnabled( !SoapUI.getTestMonitor().hasRunningTest( getModelItem().getTestCase() ) );
}
public void securityTestStarted( SecurityTestRunner runner )
{
if( runner.getSecurityTest().getTestCase() == getModelItem().getTestCase() )
setEnabled( false );
}
@Override
public void testCaseFinished( TestCaseRunner runner )
{
setEnabled( !SoapUI.getTestMonitor().hasRunningTest( getModelItem().getTestCase() ) );
}
@Override
public void testCaseStarted( TestCaseRunner runner )
{
if( runner.getTestCase() == getModelItem().getTestCase() )
setEnabled( false );
}
}
@Override
public void propertyChange( PropertyChangeEvent evt )
{
if( evt.getPropertyName().equals( RestTestRequestInterface.STATUS_PROPERTY ) )
{
updateStatusIcon();
}
else if( evt.getPropertyName().equals( "path" ) )
{
getSubmitButton().setEnabled( getSubmit() == null && StringUtils.hasContent( getRequest().getEndpoint() ) );
}
else if( evt.getPropertyName().equals( AbstractHttpRequest.ENDPOINT_PROPERTY ) )
{
if( updating )
return;
updating = true;
pathTextField.setText( String.valueOf( evt.getNewValue() ) );
updating = false;
}
super.propertyChange( evt );
}
}