View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 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.mock;
14  
15  import java.io.BufferedReader;
16  import java.io.InputStreamReader;
17  import java.util.Enumeration;
18  
19  import javax.mail.MessagingException;
20  import javax.servlet.http.HttpServletRequest;
21  import javax.servlet.http.HttpServletResponse;
22  
23  import org.apache.xmlbeans.XmlCursor;
24  import org.apache.xmlbeans.XmlException;
25  import org.apache.xmlbeans.XmlObject;
26  
27  import com.eviware.soapui.SoapUI;
28  import com.eviware.soapui.impl.wsdl.WsdlOperation;
29  import com.eviware.soapui.impl.wsdl.submit.transports.http.MockRequestDataSource;
30  import com.eviware.soapui.impl.wsdl.submit.transports.http.MultipartMessageSupport;
31  import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
32  import com.eviware.soapui.model.iface.Attachment;
33  import com.eviware.soapui.model.mock.MockRequest;
34  import com.eviware.soapui.support.StringUtils;
35  import com.eviware.soapui.support.types.StringToStringMap;
36  
37  /***
38   * Request-class created when receiving an external request to a WsdlMockService
39   * 
40   * @author ole.matzura
41   */
42  
43  public class WsdlMockRequest implements MockRequest
44  {
45  	private StringToStringMap requestHeaders;
46  	private String requestContent;
47  	private MultipartMessageSupport mmSupport;
48  	private XmlObject requestXmlObject;
49  	private SoapVersion soapVersion;
50  	private final HttpServletResponse response;
51  	private String protocol;
52  	private String path;
53  	private final WsdlMockRunContext context;
54  	private final WsdlMockRunContext requestContext;
55  	private final HttpServletRequest request;
56  
57  	public WsdlMockRequest( HttpServletRequest request, HttpServletResponse response, WsdlMockRunContext context ) throws Exception
58  	{
59  		this.request = request;
60  		this.response = response;
61  		this.context = context;
62  		
63  		requestContext = new WsdlMockRunContext( context.getMockService(), null );
64  		
65  		requestHeaders = new StringToStringMap();
66  		for( Enumeration e = request.getHeaderNames(); e.hasMoreElements(); )
67  		{
68  			String header = ( String ) e.nextElement();
69  			requestHeaders.put( header, request.getHeader( header ) );
70  		}
71  		
72  		protocol = request.getProtocol();
73  		path = request.getPathInfo();
74  		
75  		String contentType = request.getContentType();
76  		
77  		if( contentType != null &&	contentType.toUpperCase().startsWith( "MULTIPART" ))
78  		{
79  			readMultipartRequest( request );
80  			contentType = mmSupport.getRootPart().getContentType();
81  		}
82  		else
83  		{
84  			this.requestContent = readRequestContent( request );
85  		}
86  
87  		if( !initSoapVersion( contentType ))
88  			throw new Exception( "Failed to get SOAP Version of request" );
89  	}
90  	
91  	/***
92  	 * Init soapversion from content-type header.. should envelope be checked and/or override? 
93  	 */
94  	
95  	protected boolean initSoapVersion( String contentType )
96  	{
97  		if( StringUtils.isNullOrEmpty( contentType ) )
98  			return false;
99  		
100 		soapVersion = contentType.startsWith( SoapVersion.Soap11.getContentType() ) ? SoapVersion.Soap11 : null;
101 		soapVersion = soapVersion == null && contentType.startsWith( SoapVersion.Soap12.getContentType() ) ? SoapVersion.Soap12 : soapVersion;
102 		if( soapVersion == null && contentType.startsWith( "application/xop+xml" ))
103 		{
104 			if( contentType.indexOf(  "type=\"" + SoapVersion.Soap11.getContentType() + "\"" ) > 0 )
105 				soapVersion = SoapVersion.Soap11;
106 			else if( contentType.indexOf(  "type=\"" + SoapVersion.Soap12.getContentType() + "\"" ) > 0 )
107 				soapVersion = SoapVersion.Soap12;
108 		}
109 
110 		return soapVersion != null;
111 	}
112 	
113 	public SoapVersion getSoapVersion()
114 	{
115 		return soapVersion;
116 	}
117 
118 	public String getProtocol()
119 	{
120 		return protocol;
121 	}
122 
123 	private void readMultipartRequest( HttpServletRequest request ) throws MessagingException
124 	{
125 		StringToStringMap values = StringToStringMap.fromHttpHeader( request.getContentType() );
126 		mmSupport = new MultipartMessageSupport( new MockRequestDataSource( request ), values.get( "start" ), null, true );
127 	}
128 
129 	private String readRequestContent( HttpServletRequest request ) throws Exception
130 	{
131 		String encoding = request.getCharacterEncoding();
132 		if( encoding == null )
133 			encoding = "UTF-8";
134 		else
135 			encoding = StringUtils.unquote( encoding );
136 		
137 		BufferedReader reader = new BufferedReader( new InputStreamReader( request.getInputStream(), encoding) );
138 		StringBuffer buf = new StringBuffer();
139 		String line = reader.readLine();
140 		while( line != null )
141 		{
142 			buf.append( line ).append( "\r\n" );
143 			line = reader.readLine();
144 		}
145 		
146 		return buf.toString();
147 	}
148 
149 
150 	public Attachment[] getRequestAttachments()
151 	{
152 		return mmSupport == null ? new Attachment[0] : mmSupport.getAttachments();
153 	}
154 
155 	public String getRequestContent()
156 	{
157 		return mmSupport == null ? requestContent : mmSupport.getContentAsString();
158 	}
159 
160 	public StringToStringMap getRequestHeaders()
161 	{
162 		return requestHeaders;
163 	}
164 
165 	public void setRequestContent( String requestContent )
166 	{
167 		this.requestContent = requestContent;
168 	}
169 
170 	public XmlObject getRequestXmlObject() throws XmlException
171 	{
172 		if( requestXmlObject == null )
173 			requestXmlObject = XmlObject.Factory.parse( getRequestContent() );
174 		
175 		return requestXmlObject;
176 	}
177 
178 	public XmlObject getBodyElement() throws XmlException
179 	{
180 		XmlObject[] envelope = getRequestXmlObject().selectChildren( soapVersion.getEnvelopeQName() );
181 		if( envelope.length != 1 )
182 		    throw new XmlException( "Missing/Invalid SOAP Envelope, expecting [" + soapVersion.getEnvelopeQName() + "]" );
183 		
184 		XmlObject[] body = envelope[0].selectChildren( soapVersion.getBodyQName() );
185 		if( body.length != 1 )
186 		    throw new XmlException( "Missing/Invalid SOAP Body, expecting [" + soapVersion.getBodyQName() + "]" );
187 		
188 		return body[0];
189 	}
190 
191 	public HttpServletResponse getHttpResponse()
192 	{
193 		return response;
194 	}
195 
196 	public HttpServletRequest getHttpRequest() 
197 	{
198 		return request;
199 	}
200 	
201 	public XmlObject getContentElement() throws XmlException
202 	{
203 		XmlObject bodyElement = getBodyElement();
204 		if( bodyElement != null )
205 		{
206 			XmlCursor cursor = bodyElement.newCursor();
207 			
208 			try
209 			{
210 				if( cursor.toFirstChild() )
211 				{
212 					while( !cursor.isContainer() )
213 						cursor.toNextSibling();
214 
215 					if( cursor.isContainer() )
216 					{
217 						return cursor.getObject();
218 					}
219 				}
220 			}
221 			catch( Exception e )
222 			{
223 				SoapUI.logError( e );
224 			}
225 			finally
226 			{
227 				cursor.dispose();
228 			}
229 		}
230 		
231 		return null;
232 	}
233 
234 	public String getPath()
235 	{
236 		return path;
237 	}
238 
239 	public WsdlMockRunContext getContext()
240 	{
241 		return context;
242 	}
243 
244 	public void setOperation( WsdlOperation operation )
245 	{
246 		if( mmSupport != null )
247 			mmSupport.setOperation( operation );
248 	}
249 
250 	public WsdlMockRunContext getRequestContext()
251 	{
252 		return requestContext;
253 	}
254 }