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.submit.transports.http;
    14
    15  import java.io.ByteArrayOutputStream;
    16  import java.lang.ref.WeakReference;
    17
    18  import javax.xml.namespace.QName;
    19
    20  import org.apache.commons.codec.binary.Base64;
    21  import org.apache.commons.codec.binary.Hex;
    22  import org.apache.commons.httpclient.Header;
    23  import org.apache.commons.httpclient.HeaderElement;
    24  import org.apache.commons.httpclient.NameValuePair;
    25  import org.apache.xmlbeans.SchemaGlobalElement;
    26  import org.apache.xmlbeans.SchemaType;
    27  import org.apache.xmlbeans.SchemaTypeSystem;
    28  import org.apache.xmlbeans.XmlCursor;
    29  import org.apache.xmlbeans.XmlHexBinary;
    30  import org.apache.xmlbeans.XmlObject;
    31  import org.w3c.dom.Element;
    32  import org.w3c.dom.Node;
    33
    34  import com.eviware.soapui.SoapUI;
    35  import com.eviware.soapui.impl.wsdl.WsdlRequest;
    36  import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
    37  import com.eviware.soapui.model.iface.Attachment;
    38  import com.eviware.soapui.settings.HttpSettings;
    39  import com.eviware.soapui.support.Tools;
    40  import com.eviware.soapui.support.types.StringToStringMap;
    41
    42  /***
    43   * WsdlMockResponse for a MimeResponse
    44   *
    45   * @author ole.matzura
    46   */
    47
    48  public class MimeMessageResponse implements WsdlResponse
    49  {
    50  	private final WeakReference<WsdlRequest> wsdlRequest;
    51  	private long timeTaken;
    52  	private long responseContentLength;
    53  	private StringToStringMap requestHeaders;
    54  	private StringToStringMap responseHeaders;
    55  	private final String requestContent;
    56  	private SSLInfo sslInfo;
    57  	private MultipartMessageSupport mmSupport;
    58  	private long timestamp;
    59
    60  	public MimeMessageResponse(WsdlRequest wsdlRequest, final TimeablePostMethod postMethod, String requestContent)
    61  	{
    62  		this.wsdlRequest = new WeakReference<WsdlRequest>( wsdlRequest );
    63  		this.requestContent = requestContent;
    64  		this.timeTaken = postMethod.getTimeTaken();
    65  		this.timestamp = System.currentTimeMillis();
    66
    67  		try
    68  		{
    69  			initHeaders( postMethod );
    70  			sslInfo = postMethod.getSSLInfo();
    71  			PostResponseDataSource postResponseDataSource = new PostResponseDataSource( postMethod );
    72  			responseContentLength = postResponseDataSource.getDataSize();
    73
    74  			Header h = postMethod.getResponseHeader( "Content-Type" );
    75  			HeaderElement[] elements = h.getElements();
    76
    77  			String rootPartId = null;
    78  			String multipartType = null;
    79
    80  			for( HeaderElement element : elements )
    81  			{
    82  				String name = element.getName().toUpperCase();
    83  				if( name.startsWith( "MULTIPART/" ))
    84  				{
    85  					NameValuePair parameter = element.getParameterByName("start");
    86  					if (parameter != null)
    87  						rootPartId = parameter.getValue();
    88
    89  					parameter = element.getParameterByName("type");
    90  					if (parameter != null)
    91  						multipartType = parameter.getValue();
    92  				}
    93  			}
    94
    95  			mmSupport = new MultipartMessageSupport( postResponseDataSource, rootPartId, wsdlRequest.getOperation(), false );
    96
    97  			if (wsdlRequest.getSettings().getBoolean(HttpSettings.INCLUDE_RESPONSE_IN_TIME_TAKEN))
    98  				this.timeTaken = postMethod.getTimeTakenUntilNow();
    99
    100 			if (wsdlRequest.isExpandMtomResponseAttachments() && "application/xop+xml".equals( multipartType ))
    101 			{
    102 				expandMtomAttachments( wsdlRequest );
    103 			}
    104 		}
    105 		catch ( Exception e)
    106 		{
    107 			SoapUI.logError( e );
    108 		}
    109 	}
    110
    111 	private void expandMtomAttachments(WsdlRequest wsdlRequest)
    112 	{
    113 		try
    114 		{
    115 			XmlObject xmlObject = XmlObject.Factory.parse(getContentAsString());
    116 			XmlObject[] includes = xmlObject.selectPath( "declare namespace xop='http://www.w3.org/2004/08/xop/include'; //xop:Include" );
    117
    118 			for( XmlObject include : includes )
    119 			{
    120 				Element elm = ( Element ) include.getDomNode();
    121 				String href = elm.getAttribute( "href" );
    122 				Attachment attachment = mmSupport.getAttachmentWithContentId( "<" + href.substring( 4 ) + ">" );
    123 				if( attachment != null )
    124 				{
    125 					ByteArrayOutputStream data = Tools.readAll( attachment.getInputStream(), 0 );
    126 					byte[] byteArray = data.toByteArray();
    127
    128 					XmlCursor cursor = include.newCursor();
    129 					cursor.toParent();
    130 					XmlObject parentXmlObject = cursor.getObject();
    131 					cursor.dispose();
    132
    133 					SchemaType schemaType = parentXmlObject.schemaType();
    134 					Node parentNode = elm.getParentNode();
    135
    136 					if( schemaType.isNoType())
    137 					{
    138 						SchemaTypeSystem typeSystem = wsdlRequest.getOperation().getInterface().getWsdlContext().getSchemaTypeSystem();
    139 						SchemaGlobalElement schemaElement = typeSystem.findElement( new QName( parentNode.getNamespaceURI(), parentNode.getLocalName() ) );
    140 						if( schemaElement != null )
    141 						{
    142 							schemaType = schemaElement.getType();
    143 						}
    144 					}
    145
    146 					String txt = null;
    147
    148 					if( SchemaUtils.isInstanceOf( schemaType, XmlHexBinary.type ))
    149 					{
    150 						txt = new String( Hex.encodeHex( byteArray ));
    151 					}
    152 					else
    153 					{
    154 						txt = new String( Base64.encodeBase64( byteArray ));
    155 					}
    156
    157
    158 					parentNode.replaceChild( elm.getOwnerDocument().createTextNode( txt ), elm );
    159 				}
    160 			}
    161
    162 			mmSupport.setResponseContent( xmlObject.toString() );
    163 		}
    164 		catch( Exception e )
    165 		{
    166 			SoapUI.logError( e );
    167 		}
    168 	}
    169
    170 	public SSLInfo getSSLInfo()
    171 	{
    172 		return sslInfo;
    173 	}
    174
    175 	public long getContentLength()
    176 	{
    177 		return responseContentLength;
    178 	}
    179
    180 	public WsdlRequest getRequest()
    181 	{
    182 		return wsdlRequest.get();
    183 	}
    184
    185 	public long getTimeTaken()
    186 	{
    187 		return timeTaken;
    188 	}
    189
    190 	private void initHeaders(TimeablePostMethod postMethod)
    191 	{
    192 		requestHeaders = new StringToStringMap();
    193 		Header[] headers = postMethod.getRequestHeaders();
    194 		for( Header header : headers )
    195 		{
    196 			requestHeaders.put( header.getName(), header.getValue() );
    197 		}
    198
    199 		responseHeaders = new StringToStringMap();
    200 		headers = postMethod.getResponseHeaders();
    201 		for( Header header : headers )
    202 		{
    203 			responseHeaders.put( header.getName(), header.getValue() );
    204 		}
    205
    206 		responseHeaders.put( "#status#", postMethod.getStatusLine().toString() );
    207 	}
    208
    209 	public StringToStringMap getRequestHeaders()
    210 	{
    211 		return requestHeaders;
    212 	}
    213
    214 	public StringToStringMap getResponseHeaders()
    215 	{
    216 		return responseHeaders;
    217 	}
    218
    219 	public String getRequestContent()
    220 	{
    221 		return requestContent;
    222 	}
    223
    224 	public void setResponseContent( String responseContent )
    225 	{
    226 		mmSupport.setResponseContent( responseContent );
    227 	}
    228
    229 	public Attachment[] getAttachments()
    230 	{
    231 		return mmSupport.getAttachments();
    232 	}
    233
    234 	public Attachment[] getAttachmentsForPart( String partName )
    235 	{
    236 		return mmSupport.getAttachmentsForPart( partName );
    237 	}
    238
    239 	public String getContentAsString()
    240 	{
    241 		return mmSupport.getContentAsString();
    242 	}
    243
    244 	public long getTimestamp()
    245 	{
    246 		return timestamp;
    247 	}
    248 }