Author: dhanji
Date: Tue Dec 23 22:39:43 2008
New Revision: 738
Added:
trunk/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java
trunk/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java
trunk/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java
trunk/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java
trunk/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java
(contents, props changed)
- copied, changed from r737,
/trunk/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java
trunk/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java
Modified:
trunk/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
trunk/servlet/src/com/google/inject/servlet/GuiceFilter.java
trunk/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
trunk/servlet/src/com/google/inject/servlet/ServletDefinition.java
trunk/servlet/src/com/google/inject/servlet/ServletModule.java
trunk/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java
trunk/servlet/test/com/google/inject/servlet/AllTests.java
Log:
Added varargs mapping for filters and servlets. And added a bunch of tests
that verify the dispatch pipeline, servlet spec compliance, and so forth.
Modified:
trunk/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
(original)
+++ trunk/servlet/src/com/google/inject/servlet/FiltersModuleBuilder.java
Tue Dec 23 22:39:43 2008
@@ -41,21 +41,21 @@
bind(FilterPipeline.class).toInstance(new
ManagedFilterPipeline(filterDefinitions));
}
- public ServletModule.FilterKeyBindingBuilder filter(String urlPattern) {
- return new FilterKeyBindingBuilderImpl(urlPattern,
UriPatternType.SERVLET);
+ public ServletModule.FilterKeyBindingBuilder filter(List<String>
patterns) {
+ return new FilterKeyBindingBuilderImpl(patterns,
UriPatternType.SERVLET);
}
- public ServletModule.FilterKeyBindingBuilder filterRegex(String regex) {
- return new FilterKeyBindingBuilderImpl(regex, UriPatternType.REGEX);
+ public ServletModule.FilterKeyBindingBuilder filterRegex(List<String>
regexes) {
+ return new FilterKeyBindingBuilderImpl(regexes, UriPatternType.REGEX);
}
//non-static inner class so it can access state of enclosing module class
class FilterKeyBindingBuilderImpl implements
ServletModule.FilterKeyBindingBuilder {
- private final String uriPattern;
+ private final List<String> uriPatterns;
private final UriPatternType uriPatternType;
- private FilterKeyBindingBuilderImpl(String uriPattern, UriPatternType
uriPatternType) {
- this.uriPattern = uriPattern;
+ private FilterKeyBindingBuilderImpl(List<String> uriPatterns,
UriPatternType uriPatternType) {
+ this.uriPatterns = uriPatterns;
this.uriPatternType = uriPatternType;
}
@@ -76,9 +76,11 @@
public void through(Key<? extends Filter> filterKey,
Map<String, String> contextParams) {
- filterDefinitions.add(
- new FilterDefinition(uriPattern, filterKey,
UriPatternType.get(uriPatternType),
- contextParams));
+ for (String pattern : uriPatterns) {
+ filterDefinitions.add(
+ new FilterDefinition(pattern, filterKey,
UriPatternType.get(uriPatternType),
+ contextParams));
+ }
}
}
}
Modified: trunk/servlet/src/com/google/inject/servlet/GuiceFilter.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/GuiceFilter.java
(original)
+++ trunk/servlet/src/com/google/inject/servlet/GuiceFilter.java Tue Dec
23
22:39:43 2008
@@ -56,8 +56,7 @@
*/
public class GuiceFilter implements Filter {
static final ThreadLocal<Context> localContext = new
ThreadLocal<Context>();
- static volatile WeakReference<FilterPipeline> pipeline =
- new WeakReference<FilterPipeline>(new DefaultFilterPipeline());
+ static volatile FilterPipeline pipeline = new DefaultFilterPipeline();
/** Used to inject the servlets configured via {...@link ServletModule} */
static volatile WeakReference<ServletContext> servletContext =
@@ -68,7 +67,7 @@
static void setPipeline(FilterPipeline pipeline) {
// Multiple injectors with ServletModules?
- if (GuiceFilter.pipeline.get() instanceof ManagedFilterPipeline) {
+ if (GuiceFilter.pipeline instanceof ManagedFilterPipeline) {
throw new RuntimeException("Multiple injectors detected. Please
install only one"
+ " ServletModule in your web application. While you may "
+ "have more than one injector, you should only configure"
@@ -77,12 +76,12 @@
}
// We will only overwrite the default pipeline
- GuiceFilter.pipeline = new WeakReference<FilterPipeline>(pipeline);
+ GuiceFilter.pipeline = pipeline;
}
//VisibleForTesting
static void clearPipeline() {
- pipeline = new WeakReference<FilterPipeline>(null);
+ pipeline = null;
}
public void doFilter(ServletRequest servletRequest,
@@ -90,7 +89,7 @@
throws IOException, ServletException {
Context previous = localContext.get();
- FilterPipeline filterPipeline = pipeline.get();
+ FilterPipeline filterPipeline = pipeline;
try {
localContext.set(new Context((HttpServletRequest) servletRequest,
@@ -155,17 +154,17 @@
// In the default pipeline, this is a noop. However, if replaced
// by a managed pipeline, a lazy init will be triggered the first time
// dispatch occurs.
- GuiceFilter.pipeline.get().initPipeline(servletContext);
+ GuiceFilter.pipeline.initPipeline(servletContext);
}
public void destroy() {
try {
// Destroy all registered filters & servlets in that order
- pipeline.get().destroyPipeline();
+ pipeline.destroyPipeline();
} finally {
- pipeline.clear();
+ clearPipeline();
servletContext.clear();
}
}
Modified:
trunk/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
(original)
+++ trunk/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
Tue Dec 23 22:39:43 2008
@@ -77,17 +77,17 @@
+ "flush buffers)");
}
- //clear buffer before forwarding
+ // clear buffer before forwarding
servletResponse.resetBuffer();
- //now dispatch to the servlet
+ // now dispatch to the servlet
servletDefinition.doService(servletRequest, servletResponse);
}
public void include(ServletRequest servletRequest,
ServletResponse servletResponse)
throws ServletException, IOException {
- //route to the target servlet
+ // route to the target servlet
servletDefinition.doService(servletRequest, servletResponse);
}
};
Modified: trunk/servlet/src/com/google/inject/servlet/ServletDefinition.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/ServletDefinition.java
(original)
+++ trunk/servlet/src/com/google/inject/servlet/ServletDefinition.java Tue
Dec 23 22:39:43 2008
@@ -153,8 +153,8 @@
pathInfo =
getRequestURI().substring(getContextPath().length()).replaceAll("[/]{2,}", "/")
.substring(servletPathLength);
- //corner case: when servlet path and request path match exactly
(without trailing '/'),
- //pathinfo is null
+ // Corner case: when servlet path and request path match exactly
(without trailing '/'),
+ // then pathinfo is null
if ("".equals(pathInfo) && servletPathLength != 0) {
pathInfo = null;
}
@@ -177,7 +177,7 @@
return (null == info) ? null : getRealPath(info);
}
- //memoizer pattern
+ // Memoizer pattern.
private String computePath() {
if (!pathComputed) {
path = patternMatcher.extractPath(pattern);
Modified: trunk/servlet/src/com/google/inject/servlet/ServletModule.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/ServletModule.java
(original)
+++ trunk/servlet/src/com/google/inject/servlet/ServletModule.java Tue Dec
23 22:39:43 2008
@@ -16,14 +16,13 @@
package com.google.inject.servlet;
-import static com.google.inject.servlet.ServletScopes.REQUEST;
-import static com.google.inject.servlet.ServletScopes.SESSION;
-
+import com.google.common.collect.Lists;
import com.google.inject.AbstractModule;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
-
+import static com.google.inject.servlet.ServletScopes.REQUEST;
+import static com.google.inject.servlet.ServletScopes.SESSION;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
@@ -154,7 +153,13 @@
* <b>serve("/my/*").with(MyServlet.class)</b>
* </pre>
*
- * You are free to register as many servlets and filters as you like
this way:
+ * Every servlet is required to be a singleton and will implicitly be
bound as one if it isn't
+ * already. Mapping a servlet that is bound under any other scope is an
error.
+ *
+ * <p>
+ * <h4>Dispatch Order</h4>
+ * You are free to register as many servlets and filters as you like
this way. They will
+ * be compared and dispatched in the order in which the filter methods
are called:
*
* <pre>
*
@@ -162,17 +167,41 @@
*
* {...@literal @}Override
* protected void configureServlets() {
- * filter("/*").through(MyFilter.class)
- * filter("*.css").through(MyCssFilter.class)
+ * filter("/*").through(MyFilter.class);
+ * filter("*.css").through(MyCssFilter.class);
* // etc..
*
- * serve("*.html").with(MyServlet.class)
- * serve("/my/*").with(MyServlet.class)
+ * serve("*.html").with(MyServlet.class);
+ * serve("/my/*").with(MyServlet.class);
* // etc..
* }
* }
* </pre>
+ * This will traverse down the list of rules in lexical order. For
example, a url
+ * "{...@code /my/file.js}" (after it runs through the matching filters)
will first
+ * be compared against the servlet mapping:
+ *
+ * <pre>
+ * serve("*.html").with(MyServlet.class);
+ * </pre>
+ * And failing that, it will descend to the next servlet mapping:
*
+ * <pre>
+ * serve("/my/*").with(MyServlet.class);
+ * </pre>
+ *
+ * Since this rule matches, Guice Servlet will dispatch to {...@code
MyServlet}. These
+ * two mapping rules can also be written in more compact form using
varargs syntax:
+ *
+ * <pre>
+ * serve(<b>"*.html", "/my/*"</b>).with(MyServlet.class);
+ * </pre>
+ *
+ * This way you can map several URI patterns to the same servlet. A
similar syntax is
+ * also available for filter mappings.
+ *
+ * <p>
+ * <h4>Regular Expressions</h4>
* You can also map servlets (or filters) to URIs using regular
expressions:
* <pre>
* <b>serveRegex("(.)*ajax(.)*").with(MyAjaxServlet.class)</b>
@@ -203,15 +232,14 @@
* serve("/*").with(MyServlet.class, <b>params</b>)
* </pre>
*
- *
+ * <p>
* <h3>Binding Keys</h3>
*
- * <p> You can also bind keys rather than classes. This lets you hide
+ * You can also bind keys rather than classes. This lets you hide
* implementations with package-local visbility and expose them using
* only a Guice module and an annotation:
*
* <pre>
- *
* ...
* filter("/*").through(<b>Key.get(Filter.class, Fave.class)</b>);
* </pre>
@@ -224,7 +252,7 @@
*
bind(Filter.class)<b>.annotatedWith(Fave.class)</b>.to(MyFilterImpl.class);
* </pre>
*
- * See Guice documentation for more information on binding annotations.
+ * See {...@link com.google.inject.Binder} for more information on binding
syntax.
*/
protected void configureServlets() {
}
@@ -236,29 +264,29 @@
/**
* @param urlPattern Any Servlet-style pattern. examples: /*, /html/*,
*.html, etc.
*/
- protected final FilterKeyBindingBuilder filter(String urlPattern) {
- return filtersModuleBuilder.filter(urlPattern);
+ protected final FilterKeyBindingBuilder filter(String urlPattern,
String... morePatterns) {
+ return filtersModuleBuilder.filter(Lists.asList(urlPattern,
morePatterns));
}
/**
* @param regex Any Java-style regular expression.
*/
- protected final FilterKeyBindingBuilder filterRegex(String regex) {
- return filtersModuleBuilder.filterRegex(regex);
+ protected final FilterKeyBindingBuilder filterRegex(String regex,
String... regexes) {
+ return filtersModuleBuilder.filterRegex(Lists.asList(regex, regexes));
}
/**
* @param urlPattern Any Servlet-style pattern. examples: /*, /html/*,
*.html, etc.
*/
- protected final ServletKeyBindingBuilder serve(String urlPattern) {
- return servletsModuleBuilder.serve(urlPattern);
+ protected final ServletKeyBindingBuilder serve(String urlPattern,
String... morePatterns) {
+ return servletsModuleBuilder.serve(Lists.asList(urlPattern,
morePatterns));
}
/**
* @param regex Any Java-style regular expression.
*/
- protected final ServletKeyBindingBuilder serveRegex(String regex) {
- return servletsModuleBuilder.serveRegex(regex);
+ protected final ServletKeyBindingBuilder serveRegex(String regex,
String... regexes) {
+ return servletsModuleBuilder.serveRegex(Lists.asList(regex, regexes));
}
public static interface FilterKeyBindingBuilder {
Modified:
trunk/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java
==============================================================================
--- trunk/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java
(original)
+++ trunk/servlet/src/com/google/inject/servlet/ServletsModuleBuilder.java
Tue Dec 23 22:39:43 2008
@@ -41,21 +41,21 @@
}
//the first level of the EDSL--
- public ServletModule.ServletKeyBindingBuilder serve(String urlPattern) {
- return new ServletKeyBindingBuilderImpl(urlPattern,
UriPatternType.SERVLET);
+ public ServletModule.ServletKeyBindingBuilder serve(List<String>
urlPatterns) {
+ return new ServletKeyBindingBuilderImpl(urlPatterns,
UriPatternType.SERVLET);
}
- public ServletModule.ServletKeyBindingBuilder serveRegex(String regex) {
- return new ServletKeyBindingBuilderImpl(regex, UriPatternType.REGEX);
+ public ServletModule.ServletKeyBindingBuilder serveRegex(List<String>
regexes) {
+ return new ServletKeyBindingBuilderImpl(regexes, UriPatternType.REGEX);
}
//non-static inner class so it can access state of enclosing module class
class ServletKeyBindingBuilderImpl implements
ServletModule.ServletKeyBindingBuilder {
- private final String uriPattern;
+ private final List<String> uriPatterns;
private final UriPatternType uriPatternType;
- private ServletKeyBindingBuilderImpl(String uriPattern, UriPatternType
uriPatternType) {
- this.uriPattern = uriPattern;
+ private ServletKeyBindingBuilderImpl(List<String> uriPatterns,
UriPatternType uriPatternType) {
+ this.uriPatterns = uriPatterns;
this.uriPatternType = uriPatternType;
}
@@ -74,9 +74,12 @@
public void with(Key<? extends HttpServlet> servletKey,
Map<String, String> contextParams) {
- servletDefinitions.add(
- new ServletDefinition(uriPattern, servletKey,
UriPatternType.get(uriPatternType),
- contextParams));
+
+ for (String pattern : uriPatterns) {
+ servletDefinitions.add(
+ new ServletDefinition(pattern, servletKey,
UriPatternType.get(uriPatternType),
+ contextParams));
+ }
}
}
}
Modified: trunk/servlet/test/com/google/inject/servlet/AllTests.java
==============================================================================
--- trunk/servlet/test/com/google/inject/servlet/AllTests.java (original)
+++ trunk/servlet/test/com/google/inject/servlet/AllTests.java Tue Dec 23
22:39:43 2008
@@ -27,12 +27,22 @@
public static Test suite() {
TestSuite suite = new TestSuite();
- // Servlet tests.
+ // Filter tests.
suite.addTestSuite(EdslTest.class);
suite.addTestSuite(FilterDefinitionTest.class);
suite.addTestSuite(FilterDispatchIntegrationTest.class);
suite.addTestSuite(FilterPipelineTest.class);
+
+ // Servlet + integration tests.
suite.addTestSuite(ServletTest.class);
+ suite.addTestSuite(ServletDefinitionTest.class);
+ suite.addTestSuite(ServletDefinitionPathsTest.class);
+ suite.addTestSuite(ServletPipelineRequestDispatcherTest.class);
+ suite.addTestSuite(ServletDispatchIntegrationTest.class);
+
+ // Varargs URL mapping tests.
+ suite.addTestSuite(VarargsFilterDispatchIntegrationTest.class);
+ suite.addTestSuite(VarargsServletDispatchIntegrationTest.class);
return suite;
}
Added:
trunk/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java
==============================================================================
--- (empty file)
+++
trunk/servlet/test/com/google/inject/servlet/ServletDefinitionPathsTest.java
Tue Dec 23 22:39:43 2008
@@ -0,0 +1,260 @@
+/**
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.servlet;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import com.google.inject.Injector;
+import com.google.inject.Key;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.util.HashMap;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Ensures servlet spec compliance for CGI-style variables and general
+ * path/pattern matching.
+ *
+ * @author Dhanji R. Prasanna (dha...@gmail com)
+ */
+public class ServletDefinitionPathsTest extends TestCase {
+
+ // Data-driven test.
+ public final void testServletPathMatching() throws IOException,
ServletException {
+ servletPath("/index.html", "*.html", "/index.html");
+
servletPath("/somewhere/index.html", "*.html", "/somewhere/index.html");
+ servletPath("/somewhere/index.html", "/*", "");
+ servletPath("/index.html", "/*", "");
+ servletPath("/", "/*", "");
+ servletPath("//", "/*", "");
+ servletPath("/////", "/*", "");
+ servletPath("", "/*", "");
+ servletPath("/thing/index.html", "/thing/*", "/thing");
+ servletPath("/thing/wing/index.html", "/thing/*", "/thing");
+ }
+
+ private void servletPath(final String requestPath, String mapping,
+ final String expectedServletPath) throws IOException,
ServletException {
+
+ Injector injector = createMock(Injector.class);
+ HttpServletRequest request = createMock(HttpServletRequest.class);
+ HttpServletResponse response = createMock(HttpServletResponse.class);
+
+ final boolean[] run = new boolean[1];
+
+ //get an instance of this servlet
+ expect(injector.getInstance(Key.get(HttpServlet.class)))
+ .andReturn(new HttpServlet() {
+
+ @Override
+ protected void service(HttpServletRequest servletRequest,
+ HttpServletResponse httpServletResponse) throws
ServletException, IOException {
+
+ final String path = servletRequest.getServletPath();
+ assertEquals(String.format("expected [%s] but was [%s]",
expectedServletPath, path),
+ expectedServletPath, path);
+ run[0] = true;
+ }
+ });
+
+ expect(request.getServletPath())
+ .andReturn(requestPath);
+
+ replay(injector, request);
+
+ ServletDefinition servletDefinition = new ServletDefinition(mapping,
Key.get(HttpServlet.class),
+ UriPatternType.get(UriPatternType.SERVLET), new HashMap<String,
String>());
+
+ servletDefinition.init(null, injector);
+ servletDefinition.doService(request, response);
+
+ assertTrue("Servlet did not run!", run[0]);
+
+ }
+
+ // Data-driven test.
+ public final void testPathInfoWithServletStyleMatching() throws
IOException, ServletException {
+
pathInfoWithServletStyleMatching("/path/index.html", "/path", "/*",
"/index.html", "");
+
pathInfoWithServletStyleMatching("/path//hulaboo///index.html", "/path", "/*",
+ "/hulaboo/index.html", "");
+ pathInfoWithServletStyleMatching("/path/", "/path", "/*", "/", "");
+
pathInfoWithServletStyleMatching("/path////////", "/path", "/*", "/", "");
+
+ // a servlet mapping of /thing/*
+
pathInfoWithServletStyleMatching("/path/thing////////", "/path", "/thing/*",
"/", "/thing");
+
pathInfoWithServletStyleMatching("/path/thing/stuff", "/path", "/thing/*",
"/stuff", "/thing");
+
pathInfoWithServletStyleMatching("/path/thing/stuff.html", "/path", "/thing/*",
"/stuff.html",
+ "/thing");
+ pathInfoWithServletStyleMatching("/path/thing", "/path", "/thing/*",
null, "/thing");
+
+ // *.xx style mapping
+
pathInfoWithServletStyleMatching("/path/thing.thing", "/path", "*.thing",
null, "/thing.thing");
+
pathInfoWithServletStyleMatching("/path///h.thing", "/path", "*.thing",
null, "/h.thing");
+
pathInfoWithServletStyleMatching("/path///...//h.thing", "/path", "*.thing",
null,
+ "/.../h.thing");
+
pathInfoWithServletStyleMatching("/path/my/h.thing", "/path", "*.thing",
null, "/my/h.thing");
+
+ }
+
+ private void pathInfoWithServletStyleMatching(final String requestUri,
final String contextPath,
+ String mapping, final String expectedPathInfo, final String
servletPath)
+ throws IOException, ServletException {
+
+ Injector injector = createMock(Injector.class);
+ HttpServletRequest request = createMock(HttpServletRequest.class);
+ HttpServletResponse response = createMock(HttpServletResponse.class);
+
+ final boolean[] run = new boolean[1];
+
+ //get an instance of this servlet
+ expect(injector.getInstance(Key.get(HttpServlet.class)))
+ .andReturn(new HttpServlet() {
+
+ @Override
+ protected void service(HttpServletRequest servletRequest,
+ HttpServletResponse httpServletResponse) throws
ServletException, IOException {
+
+ final String path = servletRequest.getPathInfo();
+
+ if (null == expectedPathInfo) {
+ assertNull(String.format("expected [%s] but was [%s]",
expectedPathInfo, path),
+ path);
+ }
+ else {
+ assertEquals(String.format("expected [%s] but was [%s]",
expectedPathInfo, path),
+ expectedPathInfo, path);
+ }
+
+ //assert memoizer
+ //noinspection StringEquality
+ assertSame("memo field did not work", path,
servletRequest.getPathInfo());
+
+ run[0] = true;
+ }
+ });
+
+ expect(request.getRequestURI())
+ .andReturn(requestUri);
+
+ expect(request.getServletPath())
+ .andReturn(servletPath)
+ .anyTimes();
+
+ expect(request.getContextPath())
+ .andReturn(contextPath);
+
+ replay(injector, request);
+
+ ServletDefinition servletDefinition = new ServletDefinition(mapping,
Key.get(HttpServlet.class),
+ UriPatternType.get(UriPatternType.SERVLET), new HashMap<String,
String>());
+
+ servletDefinition.init(null, injector);
+ servletDefinition.doService(request, response);
+
+ assertTrue("Servlet did not run!", run[0]);
+
+ }
+
+ // Data-driven test.
+ public final void testPathInfoWithRegexMatching() throws IOException,
ServletException {
+ // first a mapping of /*
+
pathInfoWithRegexMatching("/path/index.html", "/path", "/(.)*", "/index.html",
"");
+
pathInfoWithRegexMatching("/path//hulaboo///index.html", "/path", "/(.)*",
+ "/hulaboo/index.html", "");
+ pathInfoWithRegexMatching("/path/", "/path", "/(.)*", "/", "");
+ pathInfoWithRegexMatching("/path////////", "/path", "/(.)*", "/", "");
+
+ // a servlet mapping of /thing/*
+
pathInfoWithRegexMatching("/path/thing////////", "/path", "/thing/(.)*", "/",
"/thing");
+
pathInfoWithRegexMatching("/path/thing/stuff", "/path", "/thing/(.)*",
"/stuff", "/thing");
+
pathInfoWithRegexMatching("/path/thing/stuff.html", "/path", "/thing/(.)*",
"/stuff.html",
+ "/thing");
+ pathInfoWithRegexMatching("/path/thing", "/path", "/thing/(.)*",
null, "/thing");
+
+ // *.xx style mapping
+
pathInfoWithRegexMatching("/path/thing.thing", "/path", "(.)*\\.thing",
null, "/thing.thing");
+ pathInfoWithRegexMatching("/path///h.thing", "/path", "(.)*\\.thing",
null, "/h.thing");
+
pathInfoWithRegexMatching("/path///...//h.thing", "/path", "(.)*\\.thing",
null,
+ "/.../h.thing");
+ pathInfoWithRegexMatching("/path/my/h.thing", "/path", "(.)*\\.thing",
null, "/my/h.thing");
+ }
+
+ public final void pathInfoWithRegexMatching(final String requestUri,
final String contextPath,
+ String mapping, final String expectedPathInfo, final String
servletPath)
+ throws IOException, ServletException {
+
+ Injector injector = createMock(Injector.class);
+ HttpServletRequest request = createMock(HttpServletRequest.class);
+ HttpServletResponse response = createMock(HttpServletResponse.class);
+
+ final boolean[] run = new boolean[1];
+
+ //get an instance of this servlet
+ expect(injector.getInstance(Key.get(HttpServlet.class)))
+ .andReturn(new HttpServlet() {
+
+ @Override
+ protected void service(HttpServletRequest servletRequest,
+ HttpServletResponse httpServletResponse) throws
ServletException, IOException {
+
+ final String path = servletRequest.getPathInfo();
+
+ if (null == expectedPathInfo) {
+ assertNull(String.format("expected [%s] but was [%s]",
expectedPathInfo, path),
+ path);
+ }
+ else {
+ assertEquals(String.format("expected [%s] but was [%s]",
expectedPathInfo, path),
+ expectedPathInfo, path);
+ }
+
+ //assert memoizer
+ //noinspection StringEquality
+ assertSame("memo field did not work", path,
servletRequest.getPathInfo());
+
+ run[0] = true;
+ }
+ });
+
+ expect(request.getRequestURI())
+ .andReturn(requestUri);
+
+ expect(request.getServletPath())
+ .andReturn(servletPath)
+ .anyTimes();
+
+ expect(request.getContextPath())
+ .andReturn(contextPath);
+
+ replay(injector, request);
+
+ ServletDefinition servletDefinition = new ServletDefinition(mapping,
Key.get(HttpServlet.class),
+ UriPatternType.get(UriPatternType.REGEX), new HashMap<String,
String>());
+
+ servletDefinition.init(null, injector);
+ servletDefinition.doService(request, response);
+
+ assertTrue("Servlet did not run!", run[0]);
+ }
+}
Added:
trunk/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java
==============================================================================
--- (empty file)
+++ trunk/servlet/test/com/google/inject/servlet/ServletDefinitionTest.java
Tue Dec 23 22:39:43 2008
@@ -0,0 +1,90 @@
+/**
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.servlet;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import junit.framework.TestCase;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+
+/**
+ * Basic unit test for lifecycle of a ServletDefinition (wrapper).
+ *
+ * @author Dhanji R. Prasanna (dha...@gmail com)
+ */
+public class ServletDefinitionTest extends TestCase {
+
+ public final void testServletInitAndConfig() throws ServletException {
+ Injector injector = createMock(Injector.class);
+
+ final HttpServlet mockServlet = new HttpServlet() {
+ };
+ expect(injector.getInstance(Key.get(HttpServlet.class)))
+ .andReturn(mockServlet)
+ .anyTimes();
+
+ replay(injector);
+
+ //some init params
+ //noinspection SSBasedInspection
+ final Map<String, String> initParams = new HashMap<String, String>() {
+ {
+ put("ahsd", "asdas24dok");
+ put("ahssd", "asdasd124ok");
+ put("ahfsasd", "asda124sdok");
+ put("ahsasgd", "a124sdasdok");
+ put("ahsd124124", "as124124124dasdok");
+ }
+ };
+
+ final ServletDefinition servletDefinition = new ServletDefinition("/*",
+ Key.get(HttpServlet.class),
UriPatternType.get(UriPatternType.SERVLET), initParams);
+
+ ServletContext servletContext = createMock(ServletContext.class);
+ final String contextName = "thing__!@@44__SRV" + getClass();
+ expect(servletContext.getServletContextName())
+ .andReturn(contextName);
+
+ replay(servletContext);
+
+ servletDefinition.init(servletContext, injector);
+
+ assertNotNull(mockServlet.getServletContext());
+ assertEquals(contextName,
mockServlet.getServletContext().getServletContextName());
+ assertEquals(Key.get(HttpServlet.class).toString(),
mockServlet.getServletName());
+
+ final ServletConfig servletConfig = mockServlet.getServletConfig();
+ final Enumeration names = servletConfig.getInitParameterNames();
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ assertTrue(initParams.containsKey(name));
+ assertEquals(initParams.get(name),
servletConfig.getInitParameter(name));
+ }
+ }
+}
Added:
trunk/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java
==============================================================================
--- (empty file)
+++
trunk/servlet/test/com/google/inject/servlet/ServletDispatchIntegrationTest.java
Tue Dec 23 22:39:43 2008
@@ -0,0 +1,191 @@
+/**
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.servlet;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Singleton;
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * Tests the FilterPipeline that dispatches to guice-managed servlets,
+ * is a full integration test, with a real injector.
+ *
+ * @author Dhanji R. Prasanna (dhanji gmail com)
+ */
+public class ServletDispatchIntegrationTest extends TestCase {
+ private static int inits, services, destroys, doFilters;
+
+ @Override
+ public void setUp() {
+ inits = 0;
+ services = 0;
+ destroys = 0;
+ doFilters = 0;
+
+ GuiceFilter.clearPipeline();
+ }
+
+ public final void testDispatchRequestToManagedPipelineServlets()
+ throws ServletException, IOException {
+ final Injector injector = Guice.createInjector(new ServletModule() {
+
+ @Override
+ protected void configureServlets() {
+ serve("/*").with(TestServlet.class);
+
+ // These servets should never fire... (ordering test)
+ serve("*.html").with(NeverServlet.class);
+ serve("/*").with(Key.get(NeverServlet.class));
+ serve("/index/*").with(Key.get(NeverServlet.class));
+ serve("*.jsp").with(Key.get(NeverServlet.class));
+ }
+ });
+
+ final FilterPipeline pipeline =
injector.getInstance(FilterPipeline.class);
+
+ pipeline.initPipeline(null);
+
+ //create ourselves a mock request with test URI
+ HttpServletRequest requestMock = createMock(HttpServletRequest.class);
+
+ expect(requestMock.getServletPath())
+ .andReturn("/index.html")
+ .times(1);
+
+ //dispatch request
+ replay(requestMock);
+
+ pipeline.dispatch(requestMock, null, createMock(FilterChain.class));
+
+ pipeline.destroyPipeline();
+
+ verify(requestMock);
+
+ assertTrue("lifecycle states did not fire correct number of times--
inits: " + inits + "; dos: "
+ + services + "; destroys: " + destroys,
+ inits == 5 && services == 1 && destroys == 5);
+ }
+
+ public final void testDispatchRequestToManagedPipelineWithFilter()
+ throws ServletException, IOException {
+ final Injector injector = Guice.createInjector(new ServletModule() {
+
+ @Override
+ protected void configureServlets() {
+ filter("/*").through(TestFilter.class);
+
+ serve("/*").with(TestServlet.class);
+
+ // These servets should never fire...
+ serve("*.html").with(NeverServlet.class);
+ serve("/*").with(Key.get(NeverServlet.class));
+ serve("/index/*").with(Key.get(NeverServlet.class));
+ serve("*.jsp").with(Key.get(NeverServlet.class));
+
+ }
+ });
+
+ final FilterPipeline pipeline =
injector.getInstance(FilterPipeline.class);
+
+ pipeline.initPipeline(null);
+
+ //create ourselves a mock request with test URI
+ HttpServletRequest requestMock = createMock(HttpServletRequest.class);
+
+ expect(requestMock.getServletPath())
+ .andReturn("/index.html")
+ .times(2);
+
+ //dispatch request
+ replay(requestMock);
+
+ pipeline.dispatch(requestMock, null, createMock(FilterChain.class));
+
+ pipeline.destroyPipeline();
+
+ verify(requestMock);
+
+ assertTrue("lifecycle states did not fire correct number of times--
inits: " + inits + "; dos: "
+ + services + "; destroys: " + destroys,
+ inits == 6 && services == 1 && destroys == 6 && doFilters == 1);
+ }
+
+ @Singleton
+ public static class TestServlet extends HttpServlet {
+ public void init(ServletConfig filterConfig) throws ServletException {
+ inits++;
+ }
+
+ public void service(ServletRequest servletRequest, ServletResponse
servletResponse)
+ throws IOException, ServletException {
+ services++;
+ }
+
+ public void destroy() {
+ destroys++;
+ }
+ }
+
+ @Singleton
+ public static class NeverServlet extends HttpServlet {
+ public void init(ServletConfig filterConfig) throws ServletException {
+ inits++;
+ }
+
+ public void service(ServletRequest servletRequest, ServletResponse
servletResponse)
+ throws IOException, ServletException {
+ assertTrue("NeverServlet was fired, when it should not have been.",
false);
+ }
+
+ public void destroy() {
+ destroys++;
+ }
+ }
+
+ @Singleton
+ public static class TestFilter implements Filter {
+ public void init(FilterConfig filterConfig) throws ServletException {
+ inits++;
+ }
+
+ public void doFilter(ServletRequest servletRequest, ServletResponse
servletResponse,
+ FilterChain filterChain) throws IOException, ServletException {
+ doFilters++;
+ filterChain.doFilter(servletRequest, servletResponse);
+ }
+
+ public void destroy() {
+ destroys++;
+ }
+ }
+}
\ No newline at end of file
Added:
trunk/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java
==============================================================================
--- (empty file)
+++
trunk/servlet/test/com/google/inject/servlet/ServletPipelineRequestDispatcherTest.java
Tue Dec 23 22:39:43 2008
@@ -0,0 +1,198 @@
+/**
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.servlet;
+
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.UUID;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * Tests forwarding and inclusion (RequestDispatcher actions from the
+ * servlet spec).
+ *
+ * @author Dhanji R. Prasanna (dha...@gmail com)
+ */
+public class ServletPipelineRequestDispatcherTest extends TestCase {
+ private static final Key<HttpServlet> HTTP_SERLVET_KEY =
Key.get(HttpServlet.class);
+ private static final String A_KEY = "thinglyDEgintly" + new Date() +
UUID.randomUUID();
+ private static final String A_VALUE =
ServletPipelineRequestDispatcherTest.class.toString()
+ + new Date() + UUID.randomUUID();
+
+ public final void testIncludeManagedServlet() throws IOException,
ServletException {
+ final ServletDefinition servletDefinition = new
ServletDefinition("blah.html",
+ Key.get(HttpServlet.class),
UriPatternType.get(UriPatternType.SERVLET),
+ new HashMap<String, String>());
+
+ final Injector injector = createMock(Injector.class);
+ final HttpServletRequest mockRequest =
createMock(HttpServletRequest.class);
+
+ expect(mockRequest.getAttribute(A_KEY))
+ .andReturn(A_VALUE);
+
+ final boolean[] run = new boolean[1];
+ final HttpServlet mockServlet = new HttpServlet() {
+ protected void service(HttpServletRequest request,
HttpServletResponse httpServletResponse)
+ throws ServletException, IOException {
+ run[0] = true;
+
+ final Object o = request.getAttribute(A_KEY);
+ assertEquals("Wrong attrib returned - " + o, A_VALUE, o);
+ }
+ };
+
+ expect(injector.getInstance(HTTP_SERLVET_KEY))
+ .andReturn(mockServlet);
+
+ replay(injector, mockRequest);
+
+ // Have to init the Servlet before we can dispatch to it.
+ servletDefinition.init(null, injector);
+
+ final RequestDispatcher dispatcher = new ManagedServletPipeline(
+ Arrays.asList(servletDefinition))
+ .getRequestDispatcher("blah.html");
+
+ assertNotNull(dispatcher);
+ dispatcher.include(mockRequest, createMock(HttpServletResponse.class));
+
+ assertTrue("Include did not dispatch to our servlet!", run[0]);
+
+ verify(injector, mockRequest);
+ }
+
+ public final void testForwardToManagedServlet() throws IOException,
ServletException {
+ final ServletDefinition servletDefinition = new
ServletDefinition("blah.html",
+ Key.get(HttpServlet.class),
UriPatternType.get(UriPatternType.SERVLET),
+ new HashMap<String, String>());
+
+ final Injector injector = createMock(Injector.class);
+ final HttpServletRequest mockRequest =
createMock(HttpServletRequest.class);
+ final HttpServletResponse mockResponse =
createMock(HttpServletResponse.class);
+
+ expect(mockRequest.getAttribute(A_KEY))
+ .andReturn(A_VALUE);
+
+ expect(mockResponse.isCommitted())
+ .andReturn(false);
+
+ mockResponse.resetBuffer();
+ expectLastCall().once();
+
+ final boolean[] run = new boolean[1];
+ final HttpServlet mockServlet = new HttpServlet() {
+ protected void service(HttpServletRequest request,
HttpServletResponse httpServletResponse)
+ throws ServletException, IOException {
+ run[0] = true;
+
+ final Object o = request.getAttribute(A_KEY);
+ assertEquals("Wrong attrib returned - " + o, A_VALUE, o);
+ }
+ };
+
+ expect(injector.getInstance(HTTP_SERLVET_KEY))
+ .andReturn(mockServlet);
+
+ replay(injector, mockRequest, mockResponse);
+
+ // Have to init the Servlet before we can dispatch to it.
+ servletDefinition.init(null, injector);
+
+ final RequestDispatcher dispatcher = new ManagedServletPipeline(
+ Arrays.asList(servletDefinition))
+ .getRequestDispatcher("blah.html");
+
+ assertNotNull(dispatcher);
+ dispatcher.forward(mockRequest, mockResponse);
+
+ assertTrue("Include did not dispatch to our servlet!", run[0]);
+
+ verify(injector, mockRequest, mockResponse);
+ }
+
+ public final void testForwardToManagedServletFailureOnCommittedBuffer()
+ throws IOException, ServletException {
+ IllegalStateException expected = null;
+ try {
+ forwardToManagedServletFailureOnCommittedBuffer();
+ }
+ catch (IllegalStateException ise) {
+ expected = ise;
+ } finally {
+ assertNotNull("Expected IllegalStateException was not thrown",
expected);
+ }
+ }
+
+ public final void forwardToManagedServletFailureOnCommittedBuffer()
+ throws IOException, ServletException {
+ final ServletDefinition servletDefinition = new
ServletDefinition("blah.html",
+ Key.get(HttpServlet.class),
UriPatternType.get(UriPatternType.SERVLET),
+ new HashMap<String, String>());
+
+ final Injector injector = createMock(Injector.class);
+ final HttpServletRequest mockRequest =
createMock(HttpServletRequest.class);
+ final HttpServletResponse mockResponse =
createMock(HttpServletResponse.class);
+
+ expect(mockResponse.isCommitted())
+ .andReturn(true);
+
+ final HttpServlet mockServlet = new HttpServlet() {
+ protected void service(HttpServletRequest request,
HttpServletResponse httpServletResponse)
+ throws ServletException, IOException {
+
+ final Object o = request.getAttribute(A_KEY);
+ assertEquals("Wrong attrib returned - " + o, A_VALUE, o);
+ }
+ };
+
+ expect(injector.getInstance(Key.get(HttpServlet.class)))
+ .andReturn(mockServlet);
+
+ replay(injector, mockRequest, mockResponse);
+
+ // Have to init the Servlet before we can dispatch to it.
+ servletDefinition.init(null, injector);
+
+ final RequestDispatcher dispatcher = new ManagedServletPipeline(
+ Arrays.asList(servletDefinition))
+ .getRequestDispatcher("blah.html");
+
+ assertNotNull(dispatcher);
+
+ try {
+ dispatcher.forward(mockRequest, mockResponse);
+ }
+ finally {
+ verify(injector, mockRequest, mockResponse);
+ }
+
+ }
+}
Copied:
trunk/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java
(from r737,
/trunk/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java)
==============================================================================
---
/trunk/servlet/test/com/google/inject/servlet/FilterDispatchIntegrationTest.java
(original)
+++
trunk/servlet/test/com/google/inject/servlet/VarargsFilterDispatchIntegrationTest.java
Tue Dec 23 22:39:43 2008
@@ -20,7 +20,6 @@
import javax.servlet.http.HttpServletRequest;
import junit.framework.TestCase;
-
/**
*
* This tests that filter stage of the pipeline dispatches
@@ -30,7 +29,7 @@
*
* @author [email protected] (Dhanji R. Prasanna)
*/
-public class FilterDispatchIntegrationTest extends TestCase {
+public class VarargsFilterDispatchIntegrationTest extends TestCase {
private static int inits, doFilters, destroys;
@Override
@@ -48,9 +47,8 @@
@Override
protected void configureServlets() {
- filter("/*").through(TestFilter.class);
- filter("*.html").through(TestFilter.class);
- filter("/*").through(Key.get(TestFilter.class));
+ // This is actually a double match for "/*"
+ filter("/*", "*.html", "/*").through(Key.get(TestFilter.class));
// These filters should never fire
filter("/index/*").through(Key.get(TestFilter.class));
@@ -85,9 +83,7 @@
@Override
protected void configureServlets() {
- filter("/public/*").through(TestFilter.class);
- filter("*.html").through(TestFilter.class);
- filter("*.xml").through(Key.get(TestFilter.class));
+
filter("/public/*", "*.html", "*.xml").through(Key.get(TestFilter.class));
// These filters should never fire
filter("/index/*").through(Key.get(TestFilter.class));
@@ -124,8 +120,7 @@
@Override
protected void configureServlets() {
- filterRegex("/[A-Za-z]*").through(TestFilter.class);
- filterRegex("/index").through(TestFilter.class);
+ filterRegex("/[A-Za-z]*", "/index").through(TestFilter.class);
//these filters should never fire
filterRegex("\\w").through(Key.get(TestFilter.class));
@@ -170,4 +165,4 @@
destroys++;
}
}
-}
+}
\ No newline at end of file
Added:
trunk/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java
==============================================================================
--- (empty file)
+++
trunk/servlet/test/com/google/inject/servlet/VarargsServletDispatchIntegrationTest.java
Tue Dec 23 22:39:43 2008
@@ -0,0 +1,221 @@
+/**
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.servlet;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Singleton;
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * Tests the FilterPipeline that dispatches to guice-managed servlets,
+ * is a full integration test, with a real injector.
+ *
+ * @author Dhanji R. Prasanna (dhanji gmail com)
+ */
+public class VarargsServletDispatchIntegrationTest extends TestCase {
+ private static int inits, services, destroys, doFilters;
+
+ @Override
+ public void setUp() {
+ inits = 0;
+ services = 0;
+ destroys = 0;
+ doFilters = 0;
+
+ GuiceFilter.clearPipeline();
+ }
+
+ public final void testDispatchRequestToManagedPipelineServlets()
+ throws ServletException, IOException {
+ final Injector injector = Guice.createInjector(new ServletModule() {
+
+ @Override
+ protected void configureServlets() {
+ serve("/*", "/index.html").with(TestServlet.class);
+
+ // These servets should never fire... (ordering test)
+
serve("*.html", "/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
+ }
+ });
+
+ final FilterPipeline pipeline =
injector.getInstance(FilterPipeline.class);
+
+ pipeline.initPipeline(null);
+
+ //create ourselves a mock request with test URI
+ HttpServletRequest requestMock = createMock(HttpServletRequest.class);
+
+ expect(requestMock.getServletPath())
+ .andReturn("/index.html")
+ .times(1);
+
+ //dispatch request
+ replay(requestMock);
+
+ pipeline.dispatch(requestMock, null, createMock(FilterChain.class));
+ pipeline.destroyPipeline();
+
+ verify(requestMock);
+
+ assertTrue("lifecycle states did not fire correct number of times--
inits: " + inits + "; dos: "
+ + services + "; destroys: " + destroys,
+ inits == 6 && services == 1 && destroys == 6);
+ }
+
+ public final void
testVarargsSkipDispatchRequestToManagedPipelineServlets()
+ throws ServletException, IOException {
+ final Injector injector = Guice.createInjector(new ServletModule() {
+
+ @Override
+ protected void configureServlets() {
+ serve("/notindex", "/&*", "/index.html").with(TestServlet.class);
+
+ // These servets should never fire... (ordering test)
+
serve("*.html", "/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
+ }
+ });
+
+ final FilterPipeline pipeline =
injector.getInstance(FilterPipeline.class);
+
+ pipeline.initPipeline(null);
+
+ //create ourselves a mock request with test URI
+ HttpServletRequest requestMock = createMock(HttpServletRequest.class);
+
+ expect(requestMock.getServletPath())
+ .andReturn("/index.html")
+ .times(3);
+
+ //dispatch request
+ replay(requestMock);
+
+ pipeline.dispatch(requestMock, null, createMock(FilterChain.class));
+ pipeline.destroyPipeline();
+
+ verify(requestMock);
+
+ assertTrue("lifecycle states did not fire correct number of times--
inits: " + inits + "; dos: "
+ + services + "; destroys: " + destroys,
+ inits == 7 && services == 1 && destroys == 7);
+ }
+
+ public final void testDispatchRequestToManagedPipelineWithFilter()
+ throws ServletException, IOException {
+ final Injector injector = Guice.createInjector(new ServletModule() {
+
+ @Override
+ protected void configureServlets() {
+ filter("/*").through(TestFilter.class);
+
+ serve("/*").with(TestServlet.class);
+
+ // These servets should never fire...
+
serve("*.html", "/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
+
+ }
+ });
+
+ final FilterPipeline pipeline =
injector.getInstance(FilterPipeline.class);
+
+ pipeline.initPipeline(null);
+
+ //create ourselves a mock request with test URI
+ HttpServletRequest requestMock = createMock(HttpServletRequest.class);
+
+ expect(requestMock.getServletPath())
+ .andReturn("/index.html")
+ .times(2);
+
+ //dispatch request
+ replay(requestMock);
+
+ pipeline.dispatch(requestMock, null, createMock(FilterChain.class));
+
+ pipeline.destroyPipeline();
+
+ verify(requestMock);
+
+ assertTrue("lifecycle states did not fire correct number of times--
inits: " + inits + "; dos: "
+ + services + "; destroys: " + destroys,
+ inits == 6 && services == 1 && destroys == 6 && doFilters == 1);
+ }
+
+ @Singleton
+ public static class TestServlet extends HttpServlet {
+ public void init(ServletConfig filterConfig) throws ServletException {
+ inits++;
+ }
+
+ public void service(ServletRequest servletRequest, ServletResponse
servletResponse)
+ throws IOException, ServletException {
+ services++;
+ }
+
+ public void destroy() {
+ destroys++;
+ }
+ }
+
+ @Singleton
+ public static class NeverServlet extends HttpServlet {
+ public void init(ServletConfig filterConfig) throws ServletException {
+ inits++;
+ }
+
+ public void service(ServletRequest servletRequest, ServletResponse
servletResponse)
+ throws IOException, ServletException {
+ assertTrue("NeverServlet was fired, when it should not have been.",
false);
+ }
+
+ public void destroy() {
+ destroys++;
+ }
+ }
+
+ @Singleton
+ public static class TestFilter implements Filter {
+ public void init(FilterConfig filterConfig) throws ServletException {
+ inits++;
+ }
+
+ public void doFilter(ServletRequest servletRequest, ServletResponse
servletResponse,
+ FilterChain filterChain) throws IOException, ServletException {
+ doFilters++;
+ filterChain.doFilter(servletRequest, servletResponse);
+ }
+
+ public void destroy() {
+ destroys++;
+ }
+ }
+}
\ No newline at end of file
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---