View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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.support.attachments;
14  
15  import com.eviware.soapui.SoapUI;
16  import com.eviware.soapui.impl.support.AbstractHttpRequest;
17  import com.eviware.soapui.impl.wsdl.WsdlRequest;
18  import com.eviware.soapui.impl.wsdl.submit.filters.WssRequestFilter;
19  import com.eviware.soapui.impl.wsdl.submit.transports.http.ExtendedHttpMethod;
20  import com.eviware.soapui.impl.wsdl.submit.transports.http.WsdlResponse;
21  import com.eviware.soapui.impl.wsdl.support.wss.IncomingWss;
22  import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
23  import com.eviware.soapui.model.iface.Attachment;
24  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
25  import com.eviware.soapui.support.Tools;
26  import com.eviware.soapui.support.xml.XmlUtils;
27  import org.apache.commons.codec.binary.Base64;
28  import org.apache.commons.codec.binary.Hex;
29  import org.apache.commons.httpclient.Header;
30  import org.apache.commons.httpclient.HeaderElement;
31  import org.apache.commons.httpclient.NameValuePair;
32  import org.apache.xmlbeans.*;
33  import org.w3c.dom.Document;
34  import org.w3c.dom.Element;
35  import org.w3c.dom.Node;
36  
37  import javax.xml.namespace.QName;
38  import java.io.ByteArrayOutputStream;
39  import java.io.StringWriter;
40  import java.util.Vector;
41  
42  public class WsdlMimeMessageResponse extends MimeMessageResponse implements WsdlResponse
43  {
44  	private Vector<Object> wssResult;
45  	
46  	public WsdlMimeMessageResponse(WsdlRequest httpRequest, ExtendedHttpMethod httpMethod,
47  			String requestContent, PropertyExpansionContext context)
48  	{
49  		super(httpRequest, httpMethod, requestContent, context);
50  		
51  			WsdlRequest wsdlRequest = (WsdlRequest) httpRequest;
52  			processIncomingWss( wsdlRequest, context );
53  			
54  			String multipartType = null;
55  			
56  			Header h = httpMethod.getResponseHeader( "Content-Type" );
57  			HeaderElement[] elements = h.getElements();
58  			
59  			for( HeaderElement element : elements )
60  			{
61  				String name = element.getName().toUpperCase();
62  				if( name.startsWith( "MULTIPART/" ))
63  				{
64  					NameValuePair parameter = element.getParameterByName("type");
65  					if (parameter != null)
66  						multipartType = parameter.getValue();
67  				}
68  			}
69  			
70  			if (wsdlRequest.isExpandMtomResponseAttachments() && "application/xop+xml".equals( multipartType ))
71  			{
72  				expandMtomAttachments( wsdlRequest );
73  			}
74  	}
75  
76  	private void processIncomingWss( AbstractHttpRequest<?> wsdlRequest, PropertyExpansionContext context )
77  	{
78  		IncomingWss incomingWss = ( IncomingWss ) context.getProperty( WssRequestFilter.INCOMING_WSS_PROPERTY );
79  		if( incomingWss != null )
80  		{
81  			try
82  			{
83  				Document document = XmlUtils.parseXml( getMmSupport().getContentAsString() );
84  				wssResult = incomingWss.processIncoming( document, context );
85  				if( wssResult != null && wssResult.size() > 0 )
86  				{
87  					StringWriter writer = new StringWriter();
88  					XmlUtils.serializePretty( document, writer );
89  					getMmSupport().setResponseContent( writer.toString() );
90  				}
91  			}
92  			catch( Exception e )
93  			{
94  				if( wssResult == null )
95  					wssResult = new Vector<Object>();
96  				wssResult.add( e );
97  			}
98  		}
99  	}
100 	
101 	private void expandMtomAttachments(WsdlRequest wsdlRequest)
102 	{
103 		try
104 		{
105 			XmlObject xmlObject = XmlObject.Factory.parse(getContentAsString());
106 			XmlObject[] includes = xmlObject.selectPath( "declare namespace xop='http://www.w3.org/2004/08/xop/include'; //xop:Include" );
107 			
108 			for( XmlObject include : includes )
109 			{
110 				Element elm = ( Element ) include.getDomNode();
111 				String href = elm.getAttribute( "href" );
112 				Attachment attachment = getMmSupport().getAttachmentWithContentId( "<" + href.substring( 4 ) + ">" );
113 				if( attachment != null )
114 				{
115 					ByteArrayOutputStream data = Tools.readAll( attachment.getInputStream(), 0 );
116 					byte[] byteArray = data.toByteArray();
117 					
118 					XmlCursor cursor = include.newCursor();
119 					cursor.toParent();
120 					XmlObject parentXmlObject = cursor.getObject();
121 					cursor.dispose();
122 					
123 					SchemaType schemaType = parentXmlObject.schemaType();
124 					Node parentNode = elm.getParentNode();
125 					
126 					if( schemaType.isNoType())
127 					{
128 						SchemaTypeSystem typeSystem = wsdlRequest.getOperation().getInterface().getWsdlContext().getSchemaTypeSystem();
129 						SchemaGlobalElement schemaElement = typeSystem.findElement( new QName( parentNode.getNamespaceURI(), parentNode.getLocalName() ) );
130 						if( schemaElement != null )
131 						{
132 							schemaType = schemaElement.getType();
133 						}
134 					}
135 
136 					String txt = null;
137 					
138 					if( SchemaUtils.isInstanceOf( schemaType, XmlHexBinary.type ))
139 					{
140 						txt = new String( Hex.encodeHex( byteArray ));
141 					}
142 					else
143 					{
144 						txt = new String( Base64.encodeBase64( byteArray ));
145 					}
146 					 
147 					
148 					parentNode.replaceChild( elm.getOwnerDocument().createTextNode( txt ), elm );
149 				}
150 			}
151 			
152 			getMmSupport().setResponseContent( xmlObject.toString() );
153 		}
154 		catch( Exception e )
155 		{
156 			SoapUI.logError( e );
157 		}
158 	}
159 	
160 	@Override
161 	public WsdlRequest getRequest()
162 	{
163 		return (WsdlRequest) super.getRequest();
164 	}
165 
166 	public Vector<?> getWssResult()
167 	{
168 		return wssResult;
169 	}
170 	
171 }