1
2
3
4
5
6
7
8
9
10
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 }