001 package com.mockrunner.mock.web;
002
003 import java.io.IOException;
004 import java.util.ArrayList;
005 import java.util.Collections;
006 import java.util.Iterator;
007 import java.util.List;
008
009 import javax.servlet.Filter;
010 import javax.servlet.FilterChain;
011 import javax.servlet.Servlet;
012 import javax.servlet.ServletException;
013 import javax.servlet.ServletRequest;
014 import javax.servlet.ServletResponse;
015
016 import com.mockrunner.base.NestedApplicationException;
017
018 /**
019 * Mock implementation of <code>FilterChain</code>.
020 */
021 public class MockFilterChain implements FilterChain
022 {
023 private List filters = new ArrayList();
024 private Servlet servlet;
025 private Iterator iterator;
026 private List requestList = new ArrayList();
027 private List responseList = new ArrayList();
028
029 public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException
030 {
031 requestList.add(request);
032 responseList.add(response);
033 if(null == iterator)
034 {
035 iterator = filters.iterator();
036 }
037 if(iterator.hasNext())
038 {
039 Filter nextFilter = (Filter)iterator.next();
040 nextFilter.doFilter(request, response, this);
041 }
042 else
043 {
044 reset();
045 if(null == servlet) return;
046 servlet.service(request, response);
047 }
048 }
049
050 /**
051 * Resets the internal iterator of this chain.
052 */
053 public void reset()
054 {
055 iterator = null;
056 }
057
058 /**
059 * Adds a filter to the chain.
060 * @param filter the filter
061 */
062 public void addFilter(Filter filter)
063 {
064 filters.add(filter);
065 }
066
067 /**
068 * Adds a filter to the chain. The filter must implement
069 * <code>javax.servlet.Filter</code>.
070 * @param filterClass the filter class
071 * @throws IllegalArgumentException if the specified class does not implement
072 * <code>javax.servlet.Filter</code>
073 */
074 public void addFilter(Class filterClass)
075 {
076 if(!Filter.class.isAssignableFrom(filterClass))
077 {
078 throw new IllegalArgumentException("filterClass must be an instance of javax.servlet.Filter");
079 }
080 try
081 {
082 filters.add(filterClass.newInstance());
083 }
084 catch(Exception exc)
085 {
086 throw new NestedApplicationException(exc);
087 }
088 }
089
090 /**
091 * Sets the servlet that is called at the end of the chain.
092 * @param servlet the servlet
093 */
094 public void setServlet(Servlet servlet)
095 {
096 this.servlet = servlet;
097 }
098
099 /**
100 * Clears all filters and sets the current servlet to <code>null</code>.
101 */
102 public void release()
103 {
104 filters.clear();
105 setServlet(null);
106 reset();
107 }
108
109 /**
110 * Returns the list of all request objects used to call
111 * {@link #doFilter} when iterating through the chain.
112 * @return the request list
113 */
114 public List getRequestList()
115 {
116 return Collections.unmodifiableList(requestList);
117 }
118
119 /**
120 * Returns the list of all response objects used to call
121 * {@link #doFilter} when iterating through the chain.
122 * @return the response list
123 */
124 public List getResponseList()
125 {
126 return Collections.unmodifiableList(responseList);
127 }
128
129 /**
130 * Returns the last request, usually the request that was
131 * used to call the final servlet. Returns <code>null</code>
132 * if no request is specified, e.g. if the chain wasn't called.
133 * Otherwise returns the last entry of the list returned by
134 * {@link #getRequestList}.
135 * @return the last request
136 */
137 public ServletRequest getLastRequest()
138 {
139 if(requestList.isEmpty()) return null;
140 return (ServletRequest)requestList.get(requestList.size() - 1);
141 }
142
143 /**
144 * Returns the last response, usually the response that was
145 * used to call the final servlet. Returns <code>null</code>
146 * if no response is specified, e.g. if the chain wasn't called.
147 * Otherwise returns the last entry of the list returned by
148 * {@link #getResponseList}.
149 * @return the last response
150 */
151 public ServletResponse getLastResponse()
152 {
153 if(responseList.isEmpty()) return null;
154 return (ServletResponse)responseList.get(responseList.size() - 1);
155 }
156 }