Reduce stack size and simplify control flow in FilterChainInvocation.
Revision created by MOE tool push_codebase.
MOE_MIGRATION=4878
diff --git a/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java b/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
index ae6d088..ed5f2df 100755
--- a/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
+++ b/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
@@ -23,6 +23,7 @@
import java.util.List;
import java.util.Set;
+import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
@@ -45,7 +46,6 @@
class FilterChainInvocation implements FilterChain {
private static final Set<String> SERVLET_INTERNAL_METHODS = ImmutableSet.of(
- FilterDefinition.class.getName() + ".doFilter",
FilterChainInvocation.class.getName() + ".doFilter");
private final FilterDefinition[] filterDefinitions;
@@ -67,8 +67,6 @@
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
throws IOException, ServletException {
- index++;
-
GuiceFilter.Context previous = GuiceFilter.localContext.get();
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
@@ -76,9 +74,12 @@
= (previous != null) ? previous.getOriginalRequest() : request;
GuiceFilter.localContext.set(new GuiceFilter.Context(originalRequest, request, response));
try {
- //dispatch down the chain while there are more filters
- if (index < filterDefinitions.length) {
- filterDefinitions[index].doFilter(servletRequest, servletResponse, this);
+ Filter filter = findNextFilter(servletRequest, servletResponse);
+ if (filter != null) {
+ // call to the filter, which can either consume the request or
+ // recurse back into this method. (in which case we will go to find the next filter,
+ // or dispatch to the servlet if no more filters are left)
+ filter.doFilter(servletRequest, servletResponse, this);
} else {
//we've reached the end of the filterchain, let's try to dispatch to a servlet
final boolean serviced = servletPipeline.service(servletRequest, servletResponse);
@@ -103,6 +104,20 @@
GuiceFilter.localContext.set(previous);
}
}
+
+ /**
+ * Iterates over the remaining filter definitions.
+ * Returns the first applicable filter, or null if none apply.
+ */
+ private Filter findNextFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+ while (++index < filterDefinitions.length) {
+ Filter filter = filterDefinitions[index].getFilterIfMatching(servletRequest, servletResponse);
+ if (filter != null) {
+ return filter;
+ }
+ }
+ return null;
+ }
/**
* Removes stacktrace elements related to AOP internal mechanics from the
diff --git a/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java b/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
index ee42b14..501a351 100755
--- a/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
+++ b/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
@@ -23,7 +23,6 @@
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderWithExtensionVisitor;
-import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
@@ -153,20 +152,16 @@
}
}
- public void doFilter(ServletRequest servletRequest,
- ServletResponse servletResponse, FilterChainInvocation filterChainInvocation)
- throws IOException, ServletException {
+ public Filter getFilterIfMatching(ServletRequest servletRequest,
+ ServletResponse servletResponse) {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final String path = request.getRequestURI().substring(request.getContextPath().length());
if (shouldFilter(path)) {
- filter.get()
- .doFilter(servletRequest, servletResponse, filterChainInvocation);
-
+ return filter.get();
} else {
- //otherwise proceed down chain anyway
- filterChainInvocation.doFilter(servletRequest, servletResponse);
+ return null;
}
}
diff --git a/extensions/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java b/extensions/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java
index 9d94c75..115a4b0 100644
--- a/extensions/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/FilterDefinitionTest.java
@@ -128,8 +128,11 @@
assertTrue("Init did not fire", mockFilter.isInit());
+ Filter matchingFilter = filterDef.getFilterIfMatching(request, null);
+ assertSame(mockFilter, matchingFilter);
+
final boolean proceed[] = new boolean[1];
- filterDef.doFilter(request, null, new FilterChainInvocation(null, null, null) {
+ matchingFilter.doFilter(request, null, new FilterChainInvocation(null, null, null) {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
proceed[0] = true;
@@ -188,8 +191,11 @@
assertTrue("init did not fire", mockFilter.isInit());
+ Filter matchingFilter = filterDef.getFilterIfMatching(request, null);
+ assertSame(mockFilter, matchingFilter);
+
final boolean proceed[] = new boolean[1];
- filterDef.doFilter(request, null, new FilterChainInvocation(null, null, null) {
+ matchingFilter.doFilter(request, null, new FilterChainInvocation(null, null, null) {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
proceed[0] = true;