View Javadoc

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