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 }