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 }