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