001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.impl.wsdl.submit.transports.http;
014:
015: import java.io.ByteArrayOutputStream;
016: import java.lang.ref.WeakReference;
017:
018: import javax.xml.namespace.QName;
019:
020: import org.apache.commons.codec.binary.Base64;
021: import org.apache.commons.codec.binary.Hex;
022: import org.apache.commons.httpclient.Header;
023: import org.apache.commons.httpclient.HeaderElement;
024: import org.apache.commons.httpclient.NameValuePair;
025: import org.apache.xmlbeans.SchemaGlobalElement;
026: import org.apache.xmlbeans.SchemaType;
027: import org.apache.xmlbeans.SchemaTypeSystem;
028: import org.apache.xmlbeans.XmlCursor;
029: import org.apache.xmlbeans.XmlHexBinary;
030: import org.apache.xmlbeans.XmlObject;
031: import org.w3c.dom.Element;
032: import org.w3c.dom.Node;
033:
034: import com.eviware.soapui.SoapUI;
035: import com.eviware.soapui.impl.wsdl.WsdlRequest;
036: import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
037: import com.eviware.soapui.model.iface.Attachment;
038: import com.eviware.soapui.settings.HttpSettings;
039: import com.eviware.soapui.support.Tools;
040: import com.eviware.soapui.support.types.StringToStringMap;
041:
042: /**
043: * WsdlMockResponse for a MimeResponse
044: *
045: * @author ole.matzura
046: */
047:
048: public class MimeMessageResponse implements WsdlResponse {
049: private final WeakReference<WsdlRequest> wsdlRequest;
050: private long timeTaken;
051: private long responseContentLength;
052: private StringToStringMap requestHeaders;
053: private StringToStringMap responseHeaders;
054: private final String requestContent;
055: private SSLInfo sslInfo;
056: private MultipartMessageSupport mmSupport;
057: private long timestamp;
058:
059: public MimeMessageResponse(WsdlRequest wsdlRequest,
060: final TimeablePostMethod postMethod, String requestContent) {
061: this .wsdlRequest = new WeakReference<WsdlRequest>(wsdlRequest);
062: this .requestContent = requestContent;
063: this .timeTaken = postMethod.getTimeTaken();
064: this .timestamp = System.currentTimeMillis();
065:
066: try {
067: initHeaders(postMethod);
068: sslInfo = postMethod.getSSLInfo();
069: PostResponseDataSource postResponseDataSource = new PostResponseDataSource(
070: postMethod);
071: responseContentLength = postResponseDataSource
072: .getDataSize();
073:
074: Header h = postMethod.getResponseHeader("Content-Type");
075: HeaderElement[] elements = h.getElements();
076:
077: String rootPartId = null;
078: String multipartType = null;
079:
080: for (HeaderElement element : elements) {
081: String name = element.getName().toUpperCase();
082: if (name.startsWith("MULTIPART/")) {
083: NameValuePair parameter = element
084: .getParameterByName("start");
085: if (parameter != null)
086: rootPartId = parameter.getValue();
087:
088: parameter = element.getParameterByName("type");
089: if (parameter != null)
090: multipartType = parameter.getValue();
091: }
092: }
093:
094: mmSupport = new MultipartMessageSupport(
095: postResponseDataSource, rootPartId, wsdlRequest
096: .getOperation(), false);
097:
098: if (wsdlRequest.getSettings().getBoolean(
099: HttpSettings.INCLUDE_RESPONSE_IN_TIME_TAKEN))
100: this .timeTaken = postMethod.getTimeTakenUntilNow();
101:
102: if (wsdlRequest.isExpandMtomResponseAttachments()
103: && "application/xop+xml".equals(multipartType)) {
104: expandMtomAttachments(wsdlRequest);
105: }
106: } catch (Exception e) {
107: SoapUI.logError(e);
108: }
109: }
110:
111: private void expandMtomAttachments(WsdlRequest wsdlRequest) {
112: try {
113: XmlObject xmlObject = XmlObject.Factory
114: .parse(getContentAsString());
115: XmlObject[] includes = xmlObject
116: .selectPath("declare namespace xop='http://www.w3.org/2004/08/xop/include'; //xop:Include");
117:
118: for (XmlObject include : includes) {
119: Element elm = (Element) include.getDomNode();
120: String href = elm.getAttribute("href");
121: Attachment attachment = mmSupport
122: .getAttachmentWithContentId("<"
123: + href.substring(4) + ">");
124: if (attachment != null) {
125: ByteArrayOutputStream data = Tools.readAll(
126: attachment.getInputStream(), 0);
127: byte[] byteArray = data.toByteArray();
128:
129: XmlCursor cursor = include.newCursor();
130: cursor.toParent();
131: XmlObject parentXmlObject = cursor.getObject();
132: cursor.dispose();
133:
134: SchemaType schemaType = parentXmlObject
135: .schemaType();
136: Node parentNode = elm.getParentNode();
137:
138: if (schemaType.isNoType()) {
139: SchemaTypeSystem typeSystem = wsdlRequest
140: .getOperation().getInterface()
141: .getWsdlContext().getSchemaTypeSystem();
142: SchemaGlobalElement schemaElement = typeSystem
143: .findElement(new QName(parentNode
144: .getNamespaceURI(), parentNode
145: .getLocalName()));
146: if (schemaElement != null) {
147: schemaType = schemaElement.getType();
148: }
149: }
150:
151: String txt = null;
152:
153: if (SchemaUtils.isInstanceOf(schemaType,
154: XmlHexBinary.type)) {
155: txt = new String(Hex.encodeHex(byteArray));
156: } else {
157: txt = new String(Base64.encodeBase64(byteArray));
158: }
159:
160: parentNode.replaceChild(elm.getOwnerDocument()
161: .createTextNode(txt), elm);
162: }
163: }
164:
165: mmSupport.setResponseContent(xmlObject.toString());
166: } catch (Exception e) {
167: SoapUI.logError(e);
168: }
169: }
170:
171: public SSLInfo getSSLInfo() {
172: return sslInfo;
173: }
174:
175: public long getContentLength() {
176: return responseContentLength;
177: }
178:
179: public WsdlRequest getRequest() {
180: return wsdlRequest.get();
181: }
182:
183: public long getTimeTaken() {
184: return timeTaken;
185: }
186:
187: private void initHeaders(TimeablePostMethod postMethod) {
188: requestHeaders = new StringToStringMap();
189: Header[] headers = postMethod.getRequestHeaders();
190: for (Header header : headers) {
191: requestHeaders.put(header.getName(), header.getValue());
192: }
193:
194: responseHeaders = new StringToStringMap();
195: headers = postMethod.getResponseHeaders();
196: for (Header header : headers) {
197: responseHeaders.put(header.getName(), header.getValue());
198: }
199:
200: responseHeaders.put("#status#", postMethod.getStatusLine()
201: .toString());
202: }
203:
204: public StringToStringMap getRequestHeaders() {
205: return requestHeaders;
206: }
207:
208: public StringToStringMap getResponseHeaders() {
209: return responseHeaders;
210: }
211:
212: public String getRequestContent() {
213: return requestContent;
214: }
215:
216: public void setResponseContent(String responseContent) {
217: mmSupport.setResponseContent(responseContent);
218: }
219:
220: public Attachment[] getAttachments() {
221: return mmSupport.getAttachments();
222: }
223:
224: public Attachment[] getAttachmentsForPart(String partName) {
225: return mmSupport.getAttachmentsForPart(partName);
226: }
227:
228: public String getContentAsString() {
229: return mmSupport.getContentAsString();
230: }
231:
232: public long getTimestamp() {
233: return timestamp;
234: }
235: }
|