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  		initSoapVersion( contentType );
88  	}
89  	
90  	/***
91  	 * Init soapversion from content-type header.. should envelope be checked and/or override? 
92  	 */
93  	
94  	protected boolean initSoapVersion( String contentType )
95  	{
96  		soapVersion = contentType.startsWith( SoapVersion.Soap11.getContentType() ) ? SoapVersion.Soap11 : null;
97  		soapVersion = soapVersion == null && contentType.startsWith( SoapVersion.Soap12.getContentType() ) ? SoapVersion.Soap12 : soapVersion;
98  
99  		return true;
100 	}
101 	
102 	public SoapVersion getSoapVersion()
103 	{
104 		return soapVersion;
105 	}
106 
107 	public String getProtocol()
108 	{
109 		return protocol;
110 	}
111 
112 	private void readMultipartRequest( HttpServletRequest request ) throws MessagingException
113 	{
114 		StringToStringMap values = StringToStringMap.fromHttpHeader( request.getContentType() );
115 		mmSupport = new MultipartMessageSupport( new MockRequestDataSource( request ), values.get( "start" ), null, true );
116 	}
117 
118 	private String readRequestContent( HttpServletRequest request ) throws Exception
119 	{
120 		String encoding = request.getCharacterEncoding();
121 		if( encoding == null )
122 			encoding = "UTF-8";
123 		else
124 			encoding = StringUtils.unquote( encoding );
125 		
126 		BufferedReader reader = new BufferedReader( new InputStreamReader( request.getInputStream(), encoding) );
127 		StringBuffer buf = new StringBuffer();
128 		String line = reader.readLine();
129 		while( line != null )
130 		{
131 			buf.append( line ).append( "\r\n" );
132 			line = reader.readLine();
133 		}
134 		
135 		return buf.toString();
136 	}
137 
138 
139 	public Attachment[] getRequestAttachments()
140 	{
141 		return mmSupport == null ? new Attachment[0] : mmSupport.getAttachments();
142 	}
143 
144 	public String getRequestContent()
145 	{
146 		return mmSupport == null ? requestContent : mmSupport.getContentAsString();
147 	}
148 
149 	public StringToStringMap getRequestHeaders()
150 	{
151 		return requestHeaders;
152 	}
153 
154 	public void setRequestContent( String requestContent )
155 	{
156 		this.requestContent = requestContent;
157 	}
158 
159 	public XmlObject getRequestXmlObject() throws XmlException
160 	{
161 		if( requestXmlObject == null )
162 			requestXmlObject = XmlObject.Factory.parse( getRequestContent() );
163 		
164 		return requestXmlObject;
165 	}
166 
167 	public XmlObject getBodyElement() throws XmlException
168 	{
169 		XmlObject[] envelope = getRequestXmlObject().selectChildren( soapVersion.getEnvelopeQName() );
170 		if( envelope.length != 1 )
171 		    throw new XmlException( "Missing/Invalid SOAP Envelope, expecting [" + soapVersion.getEnvelopeQName() + "]" );
172 		
173 		XmlObject[] body = envelope[0].selectChildren( soapVersion.getBodyQName() );
174 		if( body.length != 1 )
175 		    throw new XmlException( "Missing/Invalid SOAP Body, expecting [" + soapVersion.getBodyQName() + "]" );
176 		
177 		return body[0];
178 	}
179 
180 	public HttpServletResponse getHttpResponse()
181 	{
182 		return response;
183 	}
184 
185 	public HttpServletRequest getHttpRequest() 
186 	{
187 		return request;
188 	}
189 	
190 	public XmlObject getContentElement() throws XmlException
191 	{
192 		XmlObject bodyElement = getBodyElement();
193 		if( bodyElement != null )
194 		{
195 			XmlCursor cursor = bodyElement.newCursor();
196 			
197 			try
198 			{
199 				if( cursor.toFirstChild() )
200 				{
201 					while( !cursor.isContainer() )
202 						cursor.toNextSibling();
203 
204 					if( cursor.isContainer() )
205 					{
206 						return cursor.getObject();
207 					}
208 				}
209 			}
210 			catch( Exception e )
211 			{
212 				SoapUI.logError( e );
213 			}
214 			finally
215 			{
216 				cursor.dispose();
217 			}
218 		}
219 		
220 		return null;
221 	}
222 
223 	public String getPath()
224 	{
225 		return path;
226 	}
227 
228 	public WsdlMockRunContext getContext()
229 	{
230 		return context;
231 	}
232 
233 	public void setOperation( WsdlOperation operation )
234 	{
235 		if( mmSupport != null )
236 			mmSupport.setOperation( operation );
237 	}
238 
239 	public WsdlMockRunContext getRequestContext()
240 	{
241 		return requestContext;
242 	}
243 }