1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.sourceforge.servletspy.handler.servlet;
23
24 import java.lang.reflect.Array;
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.Method;
27 import java.lang.reflect.Proxy;
28 import java.util.Arrays;
29 import java.util.Enumeration;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33
34 import javax.servlet.ServletRequest;
35 import javax.servlet.http.HttpServletRequest;
36
37 import net.sourceforge.servletspy.IContext;
38 import net.sourceforge.servletspy.IContextHandler;
39 import net.sourceforge.servletspy.config.Param;
40
41 /***
42 * @author arno schumacher
43 */
44 public final class RequestHandler implements IContextHandler {
45
46 /*** The prefix for all extra contexts to generate. */
47 private static final String BASE_KEY_NAME = "~";
48
49 /*** The name of the sub context for the request attributes. */
50 private static final String ATTRIBUTES_KEY_NAME = BASE_KEY_NAME
51 + "attributes";
52
53 /*** The name of the sub context for the request headers. */
54 private static final String HEADERS_KEY_NAME = BASE_KEY_NAME + "headers";
55
56 /*** The name of the sub context for the request parameters. */
57 private static final String PARAMETERS_KEY_NAME = BASE_KEY_NAME
58 + "parameters";
59
60 /***
61 * A list methods which should be excluded while generating a node
62 * representation for the request object. Retrieval of <code>Reader</code>
63 * and <code>InputStream</code> could cause some troble, see servlet
64 * specification. For <code>ParameterMap</code> and <code>Session</code>
65 * an alternate representation is generated.
66 */
67 private static List excludefilterList = Arrays.asList(new String[] {
68 "getSession", "getInputStream", "getReader", "getParameterMap" });
69
70 /***
71 * Returns the proxy interface for the provided class.
72 *
73 * @param o
74 * The servlet request object.
75 * @return The proxy interface.
76 */
77 private static Class[] getProxyInterfaces(final Object o) {
78 return (o instanceof HttpServletRequest) ? new Class[] {
79 HttpServletRequest.class, ServletRequest.class}
80 : new Class[] {ServletRequest.class};
81 }
82
83 /***
84 * Generates a string represenation of the provided array.
85 *
86 * @param array
87 * The array.
88 * @return A string representation of the provided array.
89 */
90 private static String arrayAsString(final Object array) {
91 if (array == null) {
92 return "null";
93 } else {
94 if (array.getClass().isArray()) {
95 int iLength = Array.getLength(array);
96
97 if (iLength == 0) {
98 return "[]";
99 } else {
100 StringBuffer sb = new StringBuffer();
101 for (int i = 0; i < iLength; i++) {
102 sb.append("[");
103 Object o = Array.get(array, i);
104 String str;
105 try {
106 if (o == null) {
107 str = "null";
108 } else if (o.getClass().isArray()) {
109 str = arrayAsString(o);
110 } else {
111 str = o.toString();
112 }
113 } catch (Throwable t) {
114 str = "?";
115 }
116 sb.append(str);
117 sb.append("]");
118 }
119 return sb.toString();
120 }
121 } else {
122 throw new IllegalArgumentException("Not an array: " + array);
123 }
124 }
125 }
126
127 /***
128 * Returns a map holding all attributes of the provided request object.
129 *
130 * @param request
131 * The request
132 * @return The attribute map generated using the provided request object.
133 */
134 private static Map generateAttributeMap(final ServletRequest request) {
135 final Map map = new HashMap();
136 final Enumeration enumeration = request.getAttributeNames();
137 while (enumeration.hasMoreElements()) {
138 final String key = String.valueOf(enumeration.nextElement());
139 final Object value = request.getAttribute(key);
140 map.put(key, value);
141 }
142 return map;
143 }
144
145 /***
146 * Returns a map holding all headers of the provided request object.
147 *
148 * @param request
149 * The request
150 * @return The header map generated using the provided request object.
151 */
152 private static Map generateHeadersMap(final HttpServletRequest request) {
153 final Map mapParamters = new HashMap();
154 final Enumeration enumeration = request.getHeaderNames();
155 while (enumeration.hasMoreElements()) {
156 final String key = String.valueOf(enumeration.nextElement());
157 final Object value = request.getHeader(key);
158 mapParamters.put(key, value);
159 }
160 return mapParamters;
161 }
162
163 /***
164 * Returns a map holding all request parameters of the provided request
165 * object.
166 *
167 * @param request
168 * The request
169 * @return The request parameter map generated using the provided request
170 * object.
171 */
172 private static Map generateParameterMap(final ServletRequest request) {
173 final Map mapParamters = new HashMap();
174 final Enumeration enumerationParameters = request.getParameterNames();
175 while (enumerationParameters.hasMoreElements()) {
176 final String key = String.valueOf(enumerationParameters
177 .nextElement());
178 final Object value = request.getParameterValues(key);
179 mapParamters.put(key, arrayAsString(value));
180 }
181 return mapParamters;
182 }
183
184
185
186
187
188 public void destroy() {
189 }
190
191
192
193
194
195 public void handle(final IContext context) throws Exception {
196 if (context.getSubject() instanceof ServletRequest) {
197 final ServletRequest request = (ServletRequest) context
198 .getSubject();
199 final ServletRequest requestWrapper = (ServletRequest) Proxy
200 .newProxyInstance(context.getClass().getClassLoader(),
201 getProxyInterfaces(request),
202 new InvocationHandler() {
203 public Object invoke(
204 final Object proxy,
205 final Method method,
206 final Object[] args)
207 throws Throwable {
208 return excludefilterList.contains(method
209 .getName()) ? null : method.invoke(
210 request, args);
211 }
212 });
213
214 context.setSubject(requestWrapper);
215 context.proceed();
216 context.add(ATTRIBUTES_KEY_NAME, generateAttributeMap(request));
217 context.add(PARAMETERS_KEY_NAME, generateParameterMap(request));
218 if (context.getSubject() instanceof HttpServletRequest) {
219 context.add(HEADERS_KEY_NAME,
220 generateHeadersMap((HttpServletRequest) request));
221 }
222 } else {
223 context.proceed();
224 }
225 }
226
227
228
229
230
231 public void init(final Param[] params) {
232 }
233 }