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 reset(); 049 if(null == servlet) return; 050 servlet.service(request, response); 051 } 052 } 053 054 /** 055 * Resets the internal iterator of this chain. 056 */ 057 public void reset() 058 { 059 iterator = null; 060 } 061 062 /** 063 * Adds a filter to the chain. 064 * @param filter the filter 065 */ 066 public void addFilter(Filter filter) 067 { 068 filters.add(filter); 069 } 070 071 /** 072 * Adds a filter to the chain. The filter must implement 073 * <code>javax.servlet.Filter</code>. 074 * @param filterClass the filter class 075 * @throws IllegalArgumentException if the specified class does not implement 076 * <code>javax.servlet.Filter</code> 077 */ 078 public void addFilter(Class filterClass) 079 { 080 if(!Filter.class.isAssignableFrom(filterClass)) 081 { 082 throw new IllegalArgumentException("filterClass must be an instance of javax.servlet.Filter"); 083 } 084 try 085 { 086 filters.add(filterClass.newInstance()); 087 } 088 catch(Exception exc) 089 { 090 log.error(exc.getMessage(), exc); 091 throw new NestedApplicationException(exc); 092 } 093 } 094 095 /** 096 * Sets the servlet that is called at the end of the chain. 097 * @param servlet the servlet 098 */ 099 public void setServlet(Servlet servlet) 100 { 101 this.servlet = servlet; 102 } 103 104 /** 105 * Clears all filters and sets the current servlet to <code>null</code>. 106 */ 107 public void release() 108 { 109 filters.clear(); 110 setServlet(null); 111 reset(); 112 } 113 114 /** 115 * Returns the list of all request objects used to call 116 * {@link #doFilter} when iterating through the chain. 117 * @return the request list 118 */ 119 public List getRequestList() 120 { 121 return Collections.unmodifiableList(requestList); 122 } 123 124 /** 125 * Returns the list of all response objects used to call 126 * {@link #doFilter} when iterating through the chain. 127 * @return the response list 128 */ 129 public List getResponseList() 130 { 131 return Collections.unmodifiableList(responseList); 132 } 133 134 /** 135 * Returns the last request, usually the request that was 136 * used to call the final servlet. Returns <code>null</code> 137 * if no request is specified, e.g. if the chain wasn't called. 138 * Otherwise returns the last entry of the list returned by 139 * {@link #getRequestList}. 140 * @return the last request 141 */ 142 public ServletRequest getLastRequest() 143 { 144 if(requestList.isEmpty()) return null; 145 return (ServletRequest)requestList.get(requestList.size() - 1); 146 } 147 148 /** 149 * Returns the last response, usually the response that was 150 * used to call the final servlet. Returns <code>null</code> 151 * if no response is specified, e.g. if the chain wasn't called. 152 * Otherwise returns the last entry of the list returned by 153 * {@link #getResponseList}. 154 * @return the last response 155 */ 156 public ServletResponse getLastResponse() 157 { 158 if(responseList.isEmpty()) return null; 159 return (ServletResponse)responseList.get(responseList.size() - 1); 160 } 161 }