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 }