1// Copyright 2011 Google Inc. All Rights Reserved.
2
3package com.google.inject.servlet;
4
5import com.google.common.collect.ImmutableMap;
6import com.google.common.collect.Maps;
7
8import java.io.Serializable;
9import java.lang.reflect.InvocationHandler;
10import java.lang.reflect.Method;
11import java.lang.reflect.Proxy;
12import java.util.Map;
13
14import javax.servlet.FilterChain;
15import javax.servlet.ServletRequest;
16import javax.servlet.ServletResponse;
17import javax.servlet.http.HttpServletRequest;
18import javax.servlet.http.HttpServletRequestWrapper;
19import javax.servlet.http.HttpServletResponse;
20import javax.servlet.http.HttpSession;
21
22/**
23 * Utilities for servlet tests.
24 *
25 * @author sameb@google.com (Sam Berlin)
26 */
27public class ServletTestUtils {
28
29  private ServletTestUtils() {}
30
31  private static class ThrowingInvocationHandler implements InvocationHandler {
32    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
33      throw new UnsupportedOperationException("No methods are supported on this object");
34    }
35  }
36
37  /**
38   * Returns a FilterChain that does nothing.
39   */
40  public static FilterChain newNoOpFilterChain() {
41    return new FilterChain() {
42      public void doFilter(ServletRequest request, ServletResponse response) {
43      }
44    };
45  }
46
47  /**
48   * Returns a fake, HttpServletRequest which stores attributes in a HashMap.
49   */
50  public static HttpServletRequest newFakeHttpServletRequest() {
51    HttpServletRequest delegate = (HttpServletRequest) Proxy.newProxyInstance(
52        HttpServletRequest.class.getClassLoader(),
53        new Class[] { HttpServletRequest.class }, new ThrowingInvocationHandler());
54
55    return new HttpServletRequestWrapper(delegate) {
56      final Map<String, Object> attributes = Maps.newHashMap();
57      final HttpSession session = newFakeHttpSession();
58
59      @Override public String getMethod() {
60        return "GET";
61      }
62
63      @Override public Object getAttribute(String name) {
64        return attributes.get(name);
65      }
66
67      @Override public void setAttribute(String name, Object value) {
68        attributes.put(name, value);
69      }
70
71      @Override public Map getParameterMap() {
72        return ImmutableMap.of();
73      }
74
75      @Override public String getRequestURI() {
76        return "/";
77      }
78
79      @Override public String getContextPath() {
80        return "";
81      }
82
83      @Override public HttpSession getSession() {
84        return session;
85      }
86    };
87  }
88
89  /**
90   * Returns a fake, HttpServletResponse which throws an exception if any of its
91   * methods are called.
92   */
93  public static HttpServletResponse newFakeHttpServletResponse() {
94    return (HttpServletResponse) Proxy.newProxyInstance(
95        HttpServletResponse.class.getClassLoader(),
96        new Class[] { HttpServletResponse.class }, new ThrowingInvocationHandler());
97  }
98
99  private static class FakeHttpSessionHandler implements InvocationHandler, Serializable {
100    final Map<String, Object> attributes = Maps.newHashMap();
101
102    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
103      String name = method.getName();
104      if ("setAttribute".equals(name)) {
105        attributes.put((String) args[0], args[1]);
106        return null;
107      } else if ("getAttribute".equals(name)) {
108        return attributes.get(args[0]);
109      } else {
110        throw new UnsupportedOperationException();
111      }
112    }
113  }
114
115  /**
116   * Returns a fake, serializable HttpSession which stores attributes in a HashMap.
117   */
118  public static HttpSession newFakeHttpSession() {
119    return (HttpSession) Proxy.newProxyInstance(HttpSession.class.getClassLoader(),
120        new Class[] { HttpSession.class }, new FakeHttpSessionHandler());
121  }
122
123}
124