/*
* 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.teststeps;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.swing.ImageIcon;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.config.AttachmentConfig;
import com.eviware.soapui.config.TestAssertionConfig;
import com.eviware.soapui.config.WsdlRequestConfig;
import com.eviware.soapui.impl.settings.XmlBeansSettingsImpl;
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.WsdlRequest;
import com.eviware.soapui.impl.wsdl.submit.transports.http.HttpResponse;
import com.eviware.soapui.impl.wsdl.submit.transports.jms.JMSResponse;
import com.eviware.soapui.impl.wsdl.support.assertions.AssertableConfig;
import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsSupport;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry.AssertableType;
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.testsuite.Assertable;
import com.eviware.soapui.model.testsuite.AssertionsListener;
import com.eviware.soapui.model.testsuite.TestAssertion;
import com.eviware.soapui.monitor.TestMonitor;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.resolver.ResolveContext;
/**
* WsdlRequest extension that adds WsdlAssertions
*
* @author Ole.Matzura
*/
public class WsdlTestRequest extends WsdlRequest implements Assertable, TestRequest
{
public static final String RESPONSE_PROPERTY = WsdlTestRequest.class.getName() + "@response";
public static final String STATUS_PROPERTY = WsdlTestRequest.class.getName() + "@status";
private static ImageIcon validRequestIcon;
private static ImageIcon failedRequestIcon;
private static ImageIcon disabledRequestIcon;
private static ImageIcon unknownRequestIcon;
private AssertionStatus currentStatus;
private final WsdlTestRequestStep testStep;
private AssertionsSupport assertionsSupport;
private WsdlResponseMessageExchange messageExchange;
private final boolean forLoadTest;
private PropertyChangeNotifier notifier;
public WsdlTestRequest( WsdlOperation operation, WsdlRequestConfig callConfig, WsdlTestRequestStep testStep,
boolean forLoadTest )
{
super( operation, callConfig, forLoadTest );
this.forLoadTest = forLoadTest;
setSettings( new XmlBeansSettingsImpl( this, testStep.getSettings(), callConfig.getSettings() ) );
this.testStep = testStep;
initAssertions();
if( !forLoadTest )
initIcons();
}
public WsdlTestCase getTestCase()
{
return testStep.getTestCase();
}
public ModelItem getParent()
{
return getTestStep();
}
protected void initIcons()
{
if( validRequestIcon == null )
validRequestIcon = UISupport.createImageIcon( "/valid_request.gif" );
if( failedRequestIcon == null )
failedRequestIcon = UISupport.createImageIcon( "/invalid_request.gif" );
if( unknownRequestIcon == null )
unknownRequestIcon = UISupport.createImageIcon( "/unknown_request.gif" );
if( disabledRequestIcon == null )
disabledRequestIcon = UISupport.createImageIcon( "/disabled_request.gif" );
}
@Override
protected RequestIconAnimator<?> initIconAnimator()
{
return new TestRequestIconAnimator( this );
}
private void initAssertions()
{
assertionsSupport = new AssertionsSupport( testStep, new AssertableConfig()
{
public TestAssertionConfig addNewAssertion()
{
return getConfig().addNewAssertion();
}
public List<TestAssertionConfig> getAssertionList()
{
return getConfig().getAssertionList();
}
public void removeAssertion( int ix )
{
getConfig().removeAssertion( ix );
}
public TestAssertionConfig insertAssertion( TestAssertionConfig source, int ix )
{
TestAssertionConfig conf = getConfig().insertNewAssertion( ix );
conf.set( source );
return conf;
}
} );
}
public int getAssertionCount()
{
return assertionsSupport.getAssertionCount();
}
public WsdlMessageAssertion getAssertionAt( int c )
{
return assertionsSupport.getAssertionAt( c );
}
public void setResponse( HttpResponse response, SubmitContext context )
{
super.setResponse( response, context );
assertResponse( context );
}
public void assertResponse( SubmitContext context )
{
if( notifier == null )
notifier = new PropertyChangeNotifier();
if( getResponse() instanceof JMSResponse )
{
messageExchange = getResponse() == null ? null : new WsdlResponseMessageExchange( this )
{
@Override
public boolean hasResponse()
{// JMS tweak
String responseContent = getResponseContent();
return responseContent != null;
}
};
}
else
{
messageExchange = getResponse() == null ? null : new WsdlResponseMessageExchange( this );
}
if( messageExchange != null )
{
// assert!
for( WsdlMessageAssertion assertion : assertionsSupport.getAssertionList() )
{
assertion.assertResponse( messageExchange, context );
}
}
notifier.notifyChange();
}
private class PropertyChangeNotifier
{
private AssertionStatus oldStatus;
private ImageIcon oldIcon;
public PropertyChangeNotifier()
{
oldStatus = getAssertionStatus();
oldIcon = getIcon();
}
public void notifyChange()
{
AssertionStatus newStatus = getAssertionStatus();
ImageIcon newIcon = getIcon();
if( oldStatus != newStatus )
notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
if( oldIcon != newIcon )
notifyPropertyChanged( ICON_PROPERTY, oldIcon, getIcon() );
oldStatus = newStatus;
oldIcon = newIcon;
}
}
public WsdlMessageAssertion addAssertion( String assertionLabel )
{
PropertyChangeNotifier notifier = new PropertyChangeNotifier();
try
{
WsdlMessageAssertion assertion = assertionsSupport.addWsdlAssertion( assertionLabel );
if( assertion == null )
return null;
if( getResponse() != null )
{
assertion.assertResponse( new WsdlResponseMessageExchange( this ), new WsdlTestRunContext( testStep ) );
notifier.notifyChange();
}
return assertion;
}
catch( Exception e )
{
SoapUI.logError( e );
return null;
}
}
public void removeAssertion( TestAssertion assertion )
{
PropertyChangeNotifier notifier = new PropertyChangeNotifier();
try
{
assertionsSupport.removeAssertion( ( WsdlMessageAssertion )assertion );
}
finally
{
( ( WsdlMessageAssertion )assertion ).release();
notifier.notifyChange();
}
}
public TestAssertion moveAssertion( int ix, int offset )
{
WsdlMessageAssertion assertion = getAssertionAt( ix );
PropertyChangeNotifier notifier = new PropertyChangeNotifier();
try
{
return assertionsSupport.moveAssertion( ix, offset );
}
finally
{
( ( WsdlMessageAssertion )assertion ).release();
notifier.notifyChange();
}
}
public AssertionStatus getAssertionStatus()
{
currentStatus = AssertionStatus.UNKNOWN;
if( messageExchange != null )
{
/*
* if( !messageExchange.hasResponse() &&
* getOperation().isBidirectional() && !isWsaEnabled() ) {
* currentStatus = AssertionStatus.FAILED; }
*/
}
else
return currentStatus;
int cnt = getAssertionCount();
if( cnt == 0 )
return currentStatus;
boolean hasEnabled = false;
for( int c = 0; c < cnt; c++ )
{
if( !getAssertionAt( c ).isDisabled() )
hasEnabled = true;
if( getAssertionAt( c ).getStatus() == AssertionStatus.FAILED )
{
currentStatus = AssertionStatus.FAILED;
break;
}
}
if( currentStatus == AssertionStatus.UNKNOWN && hasEnabled )
currentStatus = AssertionStatus.VALID;
return currentStatus;
}
@Override
public ImageIcon getIcon()
{
if( forLoadTest || UISupport.isHeadless() )
return null;
TestMonitor testMonitor = SoapUI.getTestMonitor();
if( testMonitor != null && ( testMonitor.hasRunningLoadTest( testStep.getTestCase() ) ) )
return disabledRequestIcon;
ImageIcon icon = getIconAnimator().getIcon();
if( icon == getIconAnimator().getBaseIcon() )
{
AssertionStatus status = getAssertionStatus();
if( status == AssertionStatus.VALID )
return validRequestIcon;
else if( status == AssertionStatus.FAILED )
return failedRequestIcon;
else if( status == AssertionStatus.UNKNOWN )
return unknownRequestIcon;
}
return icon;
}
public void addAssertionsListener( AssertionsListener listener )
{
assertionsSupport.addAssertionsListener( listener );
}
public void removeAssertionsListener( AssertionsListener listener )
{
assertionsSupport.removeAssertionsListener( listener );
}
/**
* Called when a testrequest is moved in a testcase
*/
@Override
public void updateConfig( WsdlRequestConfig request )
{
super.updateConfig( request );
assertionsSupport.refresh();
List<AttachmentConfig> attachmentConfigs = getConfig().getAttachmentList();
for( int i = 0; i < attachmentConfigs.size(); i++ )
{
AttachmentConfig config = attachmentConfigs.get( i );
getAttachmentsList().get( i ).updateConfig( config );
}
}
@Override
public void release()
{
super.release();
assertionsSupport.release();
}
public String getAssertableContent()
{
return getResponse() == null ? null : getResponse().getContentAsString();
}
public WsdlTestRequestStep getTestStep()
{
return testStep;
}
public WsdlInterface getInterface()
{
return getOperation().getInterface();
}
protected static class TestRequestIconAnimator extends RequestIconAnimator<WsdlTestRequest>
{
public TestRequestIconAnimator( WsdlTestRequest modelItem )
{
super( modelItem, "/request.gif", "/exec_request", 4, "gif" );
}
@Override
public boolean beforeSubmit( Submit submit, SubmitContext context )
{
if( SoapUI.getTestMonitor() != null
&& ( SoapUI.getTestMonitor().hasRunningLoadTest( getTarget().getTestCase() ) ) )
return true;
return super.beforeSubmit( submit, context );
}
@Override
public void afterSubmit( Submit submit, SubmitContext context )
{
if( submit.getRequest() == getTarget() )
stop();
}
}
public AssertableType getAssertableType()
{
return AssertableType.BOTH;
}
public String getInterfaceName()
{
return testStep.getInterfaceName();
}
public String getOperationName()
{
return testStep.getOperationName();
}
public TestAssertion cloneAssertion( TestAssertion source, String name )
{
return assertionsSupport.cloneAssertion( source, name );
}
public WsdlMessageAssertion importAssertion( WsdlMessageAssertion source, boolean overwrite, boolean createCopy,
String newName )
{
return assertionsSupport.importAssertion( source, overwrite, createCopy, newName );
}
public List<TestAssertion> getAssertionList()
{
return new ArrayList<TestAssertion>( assertionsSupport.getAssertionList() );
}
public WsdlMessageAssertion getAssertionByName( String name )
{
return assertionsSupport.getAssertionByName( name );
}
public ModelItem getModelItem()
{
return testStep;
}
public Map<String, TestAssertion> getAssertions()
{
return assertionsSupport.getAssertions();
}
public String getDefaultAssertableContent()
{
return getOperation().createResponse( true );
}
public void resolve( ResolveContext<?> context )
{
super.resolve( context );
assertionsSupport.resolve( context );
}
public boolean isDiscardResponse()
{
return getSettings().getBoolean( "discardResponse" );
}
public void setDiscardResponse( boolean discardResponse )
{
getSettings().setBoolean( "discardResponse", discardResponse );
}
}