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