KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > gargoylesoftware > htmlunit > MockWebConnection


1 /*
2  * Copyright (c) 2002, 2005 Gargoyle Software Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12  * 3. The end-user documentation included with the redistribution, if any, must
13  * include the following acknowledgment:
14  *
15  * "This product includes software developed by Gargoyle Software Inc.
16  * (http://www.GargoyleSoftware.com/)."
17  *
18  * Alternately, this acknowledgment may appear in the software itself, if
19  * and wherever such third-party acknowledgments normally appear.
20  * 4. The name "Gargoyle Software" must not be used to endorse or promote
21  * products derived from this software without prior written permission.
22  * For written permission, please contact info@GargoyleSoftware.com.
23  * 5. Products derived from this software may not be called "HtmlUnit", nor may
24  * "HtmlUnit" appear in their name, without prior written permission of
25  * Gargoyle Software Inc.
26  *
27  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
28  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
30  * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
33  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
36  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */

38 package com.gargoylesoftware.htmlunit;
39
40 import java.io.ByteArrayInputStream JavaDoc;
41 import java.io.IOException JavaDoc;
42 import java.io.InputStream JavaDoc;
43 import java.io.UnsupportedEncodingException JavaDoc;
44 import java.net.URL JavaDoc;
45 import java.util.Collections JavaDoc;
46 import java.util.HashMap JavaDoc;
47 import java.util.Iterator JavaDoc;
48 import java.util.List JavaDoc;
49 import java.util.Map JavaDoc;
50
51 import org.org.apache.commons.httpclient.HttpState;
52 import org.apache.commons.logging.Log;
53 import org.apache.commons.logging.LogFactory;
54
55 /**
56  * A fake WebConnection designed to mock out the actual http connections.
57  *
58  * @version $Revision: 100 $
59  * @author <a HREF="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
60  * @author Noboru Sinohara
61  * @author Marc Guillemot
62  */

63 public class MockWebConnection extends WebConnection {
64     private class ResponseEntry {
65         private void validateParameters(
66                 final Object JavaDoc content,
67                 final String JavaDoc statusMessage,
68                 final String JavaDoc contentType,
69                 final List JavaDoc responseHeaders) {
70             Assert.notNull("content", content);
71             Assert.notNull("statusMessage", statusMessage);
72             Assert.notNull("contentType", contentType);
73             Assert.notNull("responseHeaders", responseHeaders);
74             // Validate that the response header list only contains KeyValuePairs
75
final Iterator JavaDoc iterator = responseHeaders.iterator();
76             while( iterator.hasNext() ) {
77                 final Object JavaDoc object = iterator.next();
78                 if( object instanceof KeyValuePair == false ) {
79                     throw new IllegalArgumentException JavaDoc(
80                             "Only KeyValuePairs may be in the response header list but found: "
81                             + object.getClass().getName());
82                 }
83             }
84         }
85
86         /**
87          * Create a new instance
88          * @param content The content as a byte array
89          * @param statusCode The status code
90          * @param statusMessage The status message
91          * @param contentType The content type
92          * @param responseHeaders a list of response headers
93          */

94         public ResponseEntry(
95                 final byte[] content,
96                 final int statusCode,
97                 final String JavaDoc statusMessage,
98                 final String JavaDoc contentType,
99                 final List JavaDoc responseHeaders ) {
100
101             validateParameters(content, statusMessage, contentType, responseHeaders);
102             content_ = content;
103             statusCode_ = statusCode;
104             statusMessage_ = statusMessage;
105             contentType_ = contentType;
106             responseHeaders_ = Collections.unmodifiableList(responseHeaders);
107         }
108
109         private final int statusCode_;
110         private final String JavaDoc statusMessage_;
111         private final byte[] content_;
112         private final String JavaDoc contentType_;
113         private final List JavaDoc responseHeaders_;
114     }
115
116     private byte[] stringToByteArray(final String JavaDoc content) {
117         byte[] contentBytes;
118         try {
119             contentBytes = content.getBytes("ISO-8859-1");
120         }
121         catch (final UnsupportedEncodingException JavaDoc e) {
122             contentBytes = new byte[0];
123         }
124         return contentBytes;
125     }
126
127     private final Map JavaDoc responseMap_ = new HashMap JavaDoc(10);
128     private ResponseEntry defaultResponseEntry_;
129
130     private SubmitMethod lastMethod_;
131     private List JavaDoc lastParameters_;
132     private HttpState httpState_ = new HttpState();
133
134     /**
135      * Create an instance
136      *
137      * @param webClient The web client
138      */

139     public MockWebConnection( final WebClient webClient ) {
140         super( webClient );
141     }
142
143     /**
144      * Return the log that is being used for all scripting objects
145      * @return The log.
146      */

147     protected final Log getLog() {
148         return LogFactory.getLog(getClass());
149     }
150
151     /**
152      * Submit a request and retrieve a response
153      *
154      * @param webRequestSettings Settings to make the request with
155      * @return See above
156      * @throws IOException (only for extending classes)
157      */

158     public WebResponse getResponse(final WebRequestSettings webRequestSettings) throws IOException JavaDoc {
159         final URL JavaDoc url = webRequestSettings.getURL();
160         final SubmitMethod method = webRequestSettings.getSubmitMethod();
161         final List JavaDoc parameters = webRequestSettings.getRequestParameters();
162
163         getLog().debug("Getting response for " + url.toExternalForm());
164
165         lastMethod_ = method;
166         lastParameters_ = parameters;
167
168         ResponseEntry entry = (ResponseEntry)responseMap_.get(url.toExternalForm());
169         if( entry == null ) {
170             entry = defaultResponseEntry_;
171             if( entry == null ) {
172                 throw new IllegalStateException JavaDoc(
173                     "No response specified that can handle url ["+url.toExternalForm()+"]");
174             }
175         }
176
177         final ResponseEntry responseEntry = entry;
178         return new WebResponse() {
179             public int getStatusCode() { return responseEntry.statusCode_; }
180             public String JavaDoc getStatusMessage() { return responseEntry.statusMessage_; }
181             public String JavaDoc getContentType() {
182                 final String JavaDoc contentTypeHeaderLine = responseEntry.contentType_;
183                 final int index = contentTypeHeaderLine.indexOf( ';' );
184                 final String JavaDoc contentType;
185                 if( index == -1 ) {
186                     contentType = contentTypeHeaderLine;
187                 }
188                 else {
189                     contentType = contentTypeHeaderLine.substring( 0, index );
190                 }
191                 return contentType;
192             }
193             public String JavaDoc getContentAsString() {
194                 try {
195                     return new String JavaDoc(responseEntry.content_, getContentCharSet());
196                 }
197                 catch (final UnsupportedEncodingException JavaDoc e) {
198                     return null;
199                 }
200             }
201             public URL JavaDoc getUrl() { return url; }
202             public List JavaDoc getResponseHeaders() { return responseEntry.responseHeaders_; }
203             public long getLoadTimeInMilliSeconds() { return 0; }
204
205             public String JavaDoc getResponseHeaderValue( final String JavaDoc headerName ) {
206                 final Iterator JavaDoc iterator = responseEntry.responseHeaders_.iterator();
207                 while( iterator.hasNext() ) {
208                     final KeyValuePair pair = (KeyValuePair)iterator.next();
209                     if( pair.getKey().equals( headerName ) ) {
210                         return pair.getValue();
211                     }
212                 }
213                 return null;
214             }
215
216             public InputStream JavaDoc getContentAsStream() {
217                 return new ByteArrayInputStream JavaDoc(responseEntry.content_);
218             }
219             public byte[] getResponseBody() {
220                 /*
221                  * this method must return raw bytes.
222                  * without encoding, getBytes use locale encoding.
223                  */

224                 return responseEntry.content_;
225             }
226             public String JavaDoc getContentCharSet() {
227                 final String JavaDoc contentType = responseEntry.contentType_;
228                 final String JavaDoc prefix = "charset=";
229                 final int index = contentType.indexOf(prefix);
230                 final String JavaDoc charset;
231                 if( index == -1 ) {
232                     charset = "ISO-8859-1";
233                 }
234                 else {
235                     charset = contentType.substring(index+prefix.length());
236                 }
237                 return charset;
238             }
239         };
240     }
241
242
243     /**
244      * Return the method that was used in the last call to submitRequest()
245      *
246      * @return See above
247      */

248     public SubmitMethod getLastMethod() {
249         return lastMethod_;
250     }
251
252
253     /**
254      * Return the parameters that were used in the last call to submitRequest()
255      *
256      * @return See above
257      */

258     public List JavaDoc getLastParameters() {
259         return lastParameters_;
260     }
261
262
263     /**
264      * Set the response that will be returned when the specified url is requested.
265      * @param url The url that will return the given response
266      * @param content The content to return
267      * @param statusCode The status code to return
268      * @param statusMessage The status message to return
269      * @param contentType The content type to return
270      * @param responseHeaders A list of {@link KeyValuePair}s that will be returned as
271      * response headers.
272      */

273     public void setResponse(
274             final URL JavaDoc url,
275             final String JavaDoc content,
276             final int statusCode,
277             final String JavaDoc statusMessage,
278             final String JavaDoc contentType,
279             final List JavaDoc responseHeaders ) {
280
281         setResponse(url, stringToByteArray(content), statusCode, statusMessage,
282                     contentType, responseHeaders);
283
284     }
285
286     /**
287      * Set the response that will be returned when the specified url is requested.
288      * @param url The url that will return the given response
289      * @param content The content to return
290      * @param statusCode The status code to return
291      * @param statusMessage The status message to return
292      * @param contentType The content type to return
293      * @param responseHeaders A list of {@link KeyValuePair}s that will be returned as
294      * response headers.
295      */

296     public void setResponse(
297             final URL JavaDoc url,
298             final byte[] content,
299             final int statusCode,
300             final String JavaDoc statusMessage,
301             final String JavaDoc contentType,
302             final List JavaDoc responseHeaders ) {
303
304         final ResponseEntry responseEntry =
305             new ResponseEntry(content, statusCode, statusMessage, contentType, responseHeaders);
306         responseMap_.put( url.toExternalForm(), responseEntry );
307     }
308
309     /**
310      * Convenience method that is the same as calling
311      * {@link #setResponse(URL,String,int,String,String,List)} with a status
312      * of "200 OK", a content type of "text/html" and no additonal headers.
313      *
314      * @param url The url that will return the given response
315      * @param content The content to return
316      */

317     public void setResponse( final URL JavaDoc url, final String JavaDoc content ) {
318         setResponse( url, content, 200, "OK", "text/html", Collections.EMPTY_LIST );
319     }
320
321     /**
322      * Convenience method that is the same as calling
323      * {@link #setResponse(URL,String,int,String,String,List)} with a status
324      * of "200 OK" and no additonal headers.
325      *
326      * @param url The url that will return the given response
327      * @param content The content to return
328      * @param contentType The content type to return
329      */

330     public void setResponse(final URL JavaDoc url, final String JavaDoc content, final String JavaDoc contentType) {
331         setResponse( url, content, 200, "OK", contentType, Collections.EMPTY_LIST );
332     }
333
334     /**
335      * Specify a generic html page that will be returned when the given url is specified.
336      * The page will contain only minimal html to satisfy the html parser but will contain
337      * the specified title so that tests can check for titleText.
338      *
339      * @param url The url that will return the given response
340      * @param title The title of the page
341      */

342     public void setResponseAsGenericHtml(
343             final URL JavaDoc url,
344             final String JavaDoc title ) {
345
346         final String JavaDoc content = "<html><head><title>"+title+"</title></head><body></body></html>";
347         final ResponseEntry responseEntry
348             = new ResponseEntry(stringToByteArray(content), 200, "OK", "text/html", Collections.EMPTY_LIST);
349         responseMap_.put( url.toExternalForm(), responseEntry );
350     }
351
352     /**
353      * Set the response that will be returned when a url is requested that does
354      * not have a specific content set for it.
355      *
356      * @param content The content to return
357      * @param statusCode The status code to return
358      * @param statusMessage The status message to return
359      * @param contentType The content type to return
360      */

361     public void setDefaultResponse(
362             final String JavaDoc content,
363             final int statusCode,
364             final String JavaDoc statusMessage,
365             final String JavaDoc contentType ) {
366
367         setDefaultResponse(stringToByteArray(content), statusCode, statusMessage, contentType);
368     }
369
370     /**
371      * Set the response that will be returned when a url is requested that does
372      * not have a specific content set for it.
373      *
374      * @param content The content to return
375      * @param statusCode The status code to return
376      * @param statusMessage The status message to return
377      * @param contentType The content type to return
378      */

379     public void setDefaultResponse(
380             final byte[] content,
381             final int statusCode,
382             final String JavaDoc statusMessage,
383             final String JavaDoc contentType ) {
384
385         defaultResponseEntry_ = new ResponseEntry(content, statusCode, statusMessage,
386                 contentType, Collections.EMPTY_LIST);
387     }
388
389     /**
390      * Set the response that will be returned when a url is requested that does
391      * not have a specific content set for it.
392      *
393      * @param content The content to return
394      */

395     public void setDefaultResponse( final String JavaDoc content ) {
396         setDefaultResponse(content, 200, "OK", "text/html");
397     }
398
399
400     /**
401      * Return the {@link HttpState} that is being used for a given domain
402      * @param url The url from which the domain will be determined
403      * @return The state or null if no state can be found for this domain.
404      */

405     public HttpState getStateForUrl( final URL JavaDoc url ) {
406         return httpState_;
407     }
408 }
409
410
Popular Tags