2011/08/05 - Jakarta Cactus has been retired.

For more information, please explore the Attic.

View Javadoc

1   /* 
2    * ========================================================================
3    * 
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   * 
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * 
19   * ========================================================================
20   */
21  package org.apache.cactus.internal.client;
22  
23  import java.io.InputStream;
24  import java.lang.reflect.Constructor;
25  import java.lang.reflect.Method;
26  
27  import java.net.HttpURLConnection;
28  import java.net.URL;
29  import java.net.URLConnection;
30  
31  import org.apache.cactus.Request;
32  import org.apache.cactus.WebRequest;
33  import org.apache.cactus.WebResponse;
34  import org.apache.cactus.spi.client.ResponseObjectFactory;
35  
36  /**
37   * Constructs Web response objects. Supports both Cactus
38   * {@link org.apache.cactus.WebResponse} and HttpUnit 
39   * <code>com.meterware.httpunit.WebResponse</code> response object creation.
40   *
41   * @version $Id: WebResponseObjectFactory.java 293031 2005-10-01 22:00:33Z nchalumeau $
42   */
43  public class WebResponseObjectFactory implements ResponseObjectFactory
44  {
45      /**
46       * Connection object used to connect to the Cactus server side. Required
47       * to create the response object.  
48       */
49      private HttpURLConnection connection;
50      
51      /**
52       * @param theConnection the connection object used to connect to the 
53       *        Cactus server side
54       */
55      public WebResponseObjectFactory(HttpURLConnection theConnection)
56      {
57          this.connection = theConnection;
58      }
59         
60      /**
61       * {@inheritDoc}
62       * @see ResponseObjectFactory#getResponseObject
63       */
64      public Object getResponseObject(String theClassName, Request theRequest) 
65          throws ClientException
66      {
67          Object responseObject;
68  
69          // Is it a Http Unit WebResponse ?
70          if (theClassName.equals("com.meterware.httpunit.WebResponse"))
71          {
72              responseObject = createHttpUnitWebResponse(this.connection);
73  
74              // Is it a Html Unit WebResponse ?
75          }
76          else if (theClassName.equals(
77                      "com.gargoylesoftware.htmlunit.WebResponse"))
78          {
79              responseObject = createHtmlUnitWebResponse(this.connection);
80  
81              // Is it a Cactus WebResponse ?
82          }
83          else if (theClassName.equals("org.apache.cactus.WebResponse"))
84          {
85              responseObject = new WebResponse((WebRequest) theRequest, 
86                  this.connection);
87  
88              // Is it an old HttpURLConnection (deprecated) ?
89          }
90          else if (theClassName.equals("java.net.HttpURLConnection"))
91          {
92              responseObject = this.connection;
93          }
94          else
95          {
96              // Else it is an error ...
97              throw new ClientException("Invalid parameter type [" + theClassName
98                  + "]");
99          }
100 
101         return responseObject;
102     }
103 
104     /**
105      * Create a HttpUnit <code>WebResponse</code> object by reflection (so
106      * that we don't need the HttpUnit jar for users who are not using
107      * the HttpUnit endXXX() signature).
108      *
109      * @param theConnection the HTTP connection that was used when connecting
110      *        to the server side and which now contains the returned HTTP
111      *        response that we will pass to HttpUnit so that it can construt
112      *        a <code>com.meterware.httpunit.WebResponse</code> object.
113      * @return a HttpUnit <code>WebResponse</code> object
114      * @throws ClientException if it failes to create a HttpClient
115      *            WebResponse object for any reason
116      */
117     private Object createHttpUnitWebResponse(HttpURLConnection theConnection)
118         throws ClientException
119     {
120         Object webResponse;
121 
122         try
123         {
124             Class responseClass = 
125                 Class.forName("com.meterware.httpunit.WebResponse");
126             Method method = responseClass.getMethod("newResponse", 
127                 new Class[] {URLConnection.class});
128 
129             webResponse = method.invoke(null, new Object[] {theConnection});
130         }
131         catch (Exception e)
132         {
133             throw new ClientException("Error calling "
134                 + "[public static com.meterware.httpunit.WebResponse "
135                 + "com.meterware.httpunit.WebResponse.newResponse("
136                 + "java.net.URLConnection) throws java.io.IOException]", e);
137         }
138 
139         return webResponse;
140     }
141 
142     /**
143      * Create a HtmlUnit <code>WebResponse</code> object by reflection (so
144      * that we don't need the HtmlUnit jar for users who are not using
145      * the HttpUnit endXXX() signature).
146      *
147      * @param theConnection the HTTP connection that was used when connecting
148      *        to the server side and which now contains the returned HTTP
149      *        response that we will pass to HttpUnit so that it can construct
150      *        a <code>com.gargoylesoftware.htmlunit.WebResponse</code> object.
151      * @return a HtmlUnit <code>WebResponse</code> object
152      * @throws ClientException if it failes to create a HttpClient
153      *        WebResponse object for any reason
154      */
155     private Object createHtmlUnitWebResponse(HttpURLConnection theConnection)
156         throws ClientException
157     {
158         Object webResponse;
159 
160         try
161         {
162             Class responseClass = Class.forName(
163                     "com.gargoylesoftware.htmlunit.StringWebResponse");
164             Constructor method = responseClass.getConstructor(
165                 new Class[] {String.class, URL.class});
166 
167             InputStream input = theConnection.getInputStream();
168             byte[] buffer = new byte[input.available()];
169             input.read(buffer);
170             webResponse = method.newInstance(new Object[] {new String(buffer),
171                     theConnection.getURL()});
172         }
173         catch (Exception e)
174         {
175             throw new ClientException("Error calling "
176                 + "[public static com.meterware.httpunit.WebResponse "
177                 + "com.meterware.httpunit.WebResponse.newResponse("
178                 + "java.net.URLConnection) throws java.io.IOException]", e);
179         }
180 
181         return webResponse;
182     }
183 }