PageRenderTime 577ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/snapshot20090205/servlet/src/com/google/inject/servlet/ServletModule.java

https://bitbucket.org/cvgaviao/google-guice-mavenized
Java | 276 lines | 44 code | 14 blank | 218 comment | 0 complexity | 66bcd2e62ba1f36b3586addaf4c3c60b MD5 | raw file
Possible License(s): Apache-2.0
  1. /**
  2. * Copyright (C) 2006 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.google.inject.servlet;
  17. import com.google.common.collect.Lists;
  18. import com.google.inject.AbstractModule;
  19. import com.google.inject.Key;
  20. import java.util.Map;
  21. import javax.servlet.Filter;
  22. import javax.servlet.http.HttpServlet;
  23. /**
  24. * Configures the servlet scopes and creates bindings for the servlet API
  25. * objects so you can inject the request, response, session, etc.
  26. *
  27. * <p>
  28. * You should subclass this module to register servlets and
  29. * filters in the {@link #configureServlets()} method.
  30. *
  31. * @author crazybob@google.com (Bob Lee)
  32. * @author dhanji@gmail.com (Dhanji R. Prasanna)
  33. */
  34. public class ServletModule extends AbstractModule {
  35. @Override
  36. protected final void configure() {
  37. // Install common bindings (skipped if already installed).
  38. install(new InternalServletModule());
  39. // Install local filter and servlet bindings.
  40. configureServlets();
  41. install(filtersModuleBuilder);
  42. install(servletsModuleBuilder);
  43. }
  44. /**
  45. * <h3>Servlet Mapping EDSL</h3>
  46. *
  47. * <p> Part of the EDSL builder language for configuring servlets
  48. * and filters with guice-servlet. Think of this as an in-code replacement for web.xml.
  49. * Filters and servlets are configured here using simple java method calls. Here is a typical
  50. * example of registering a filter when creating your Guice injector:
  51. *
  52. * <pre>
  53. * Guice.createInjector(..., new ServletModule() {
  54. *
  55. * {@literal @}Override
  56. * protected void configureServlets() {
  57. * <b>serve("*.html").with(MyServlet.class)</b>
  58. * }
  59. * }
  60. * </pre>
  61. *
  62. * This registers a servlet (subclass of {@code HttpServlet}) called {@code MyServlet} to service
  63. * any web pages ending in {@code .html}. You can also use a path-style syntax to register
  64. * servlets:
  65. *
  66. * <pre>
  67. * <b>serve("/my/*").with(MyServlet.class)</b>
  68. * </pre>
  69. *
  70. * Every servlet is required to be a singleton and will implicitly be bound as one if it isn't
  71. * already. Mapping a servlet that is bound under any other scope is an error.
  72. *
  73. * <p>
  74. * <h4>Dispatch Order</h4>
  75. * You are free to register as many servlets and filters as you like this way. They will
  76. * be compared and dispatched in the order in which the filter methods are called:
  77. *
  78. * <pre>
  79. *
  80. * Guice.createInjector(..., new ServletModule() {
  81. *
  82. * {@literal @}Override
  83. * protected void configureServlets() {
  84. * filter("/*").through(MyFilter.class);
  85. * filter("*.css").through(MyCssFilter.class);
  86. * // etc..
  87. *
  88. * serve("*.html").with(MyServlet.class);
  89. * serve("/my/*").with(MyServlet.class);
  90. * // etc..
  91. * }
  92. * }
  93. * </pre>
  94. * This will traverse down the list of rules in lexical order. For example, a url
  95. * "{@code /my/file.js}" (after it runs through the matching filters) will first
  96. * be compared against the servlet mapping:
  97. *
  98. * <pre>
  99. * serve("*.html").with(MyServlet.class);
  100. * </pre>
  101. * And failing that, it will descend to the next servlet mapping:
  102. *
  103. * <pre>
  104. * serve("/my/*").with(MyServlet.class);
  105. * </pre>
  106. *
  107. * Since this rule matches, Guice Servlet will dispatch to {@code MyServlet}. These
  108. * two mapping rules can also be written in more compact form using varargs syntax:
  109. *
  110. * <pre>
  111. * serve(<b>"*.html", "/my/*"</b>).with(MyServlet.class);
  112. * </pre>
  113. *
  114. * This way you can map several URI patterns to the same servlet. A similar syntax is
  115. * also available for filter mappings.
  116. *
  117. * <p>
  118. * <h4>Regular Expressions</h4>
  119. * You can also map servlets (or filters) to URIs using regular expressions:
  120. * <pre>
  121. * <b>serveRegex("(.)*ajax(.)*").with(MyAjaxServlet.class)</b>
  122. * </pre>
  123. *
  124. * This will map any URI containing the text "ajax" in it to {@code MyAjaxServlet}. Such as:
  125. * <ul>
  126. * <li>http://www.google.com/ajax.html</li>
  127. * <li>http://www.google.com/content/ajax/index</li>
  128. * <li>http://www.google.com/it/is_totally_ajaxian</li>
  129. * </ul>
  130. *
  131. *
  132. * <h3>Initialization Parameters</h3>
  133. *
  134. * Servlets (and filters) allow you to pass in init params
  135. * using the {@code <init-param>} tag in web.xml. You can similarly pass in parameters to
  136. * Servlets and filters registered in Guice-servlet using a {@link java.util.Map} of parameter
  137. * name/value pairs. For example, to initialize {@code MyServlet} with two parameters
  138. * ({@code name="Dhanji", site="google.com"}) you could write:
  139. *
  140. * <pre>
  141. * Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
  142. * params.put("name", "Dhanji");
  143. * params.put("site", "google.com");
  144. *
  145. * ...
  146. * serve("/*").with(MyServlet.class, <b>params</b>)
  147. * </pre>
  148. *
  149. * <p>
  150. * <h3>Binding Keys</h3>
  151. *
  152. * You can also bind keys rather than classes. This lets you hide
  153. * implementations with package-local visbility and expose them using
  154. * only a Guice module and an annotation:
  155. *
  156. * <pre>
  157. * ...
  158. * filter("/*").through(<b>Key.get(Filter.class, Fave.class)</b>);
  159. * </pre>
  160. *
  161. * Where {@code Filter.class} refers to the Servlet API interface and {@code Fave.class} is a
  162. * custom binding annotation. Elsewhere (in one of your own modules) you can bind this
  163. * filter's implementation:
  164. *
  165. * <pre>
  166. * bind(Filter.class)<b>.annotatedWith(Fave.class)</b>.to(MyFilterImpl.class);
  167. * </pre>
  168. *
  169. * See {@link com.google.inject.Binder} for more information on binding syntax.
  170. *
  171. * <p>
  172. * <h3>Multiple Modules</h3>
  173. *
  174. * It is sometimes useful to capture servlet and filter mappings from multiple different
  175. * modules. This is essential if you want to package and offer drop-in Guice plugins that
  176. * provide servlet functionality.
  177. *
  178. * <p>
  179. * Guice Servlet allows you to register several instances of {@code ServletModule} to your
  180. * injector. The order in which these modules are installed determines the dispatch order
  181. * of filters and the precedence order of servlets. For example, if you had two servlet modules,
  182. * {@code RpcModule} and {@code WebServiceModule} and they each contained a filter that mapped
  183. * to the same URI pattern, {@code "/*"}:
  184. *
  185. * <p>
  186. * In {@code RpcModule}:
  187. * <pre>
  188. * filter("/*").through(RpcFilter.class);
  189. * </pre>
  190. *
  191. * In {@code WebServiceModule}:
  192. * <pre>
  193. * filter("/*").through(WebServiceFilter.class);
  194. * </pre>
  195. *
  196. * Then the order in which these filters are dispatched is determined by the order in which
  197. * the modules are installed:
  198. *
  199. * <pre>
  200. * <b>install(new WebServiceModule());</b>
  201. * install(new RpcModule());
  202. * </pre>
  203. *
  204. * In the case shown above {@code WebServiceFilter} will run first.
  205. *
  206. * @since 2.0
  207. */
  208. protected void configureServlets() {
  209. }
  210. private final FiltersModuleBuilder filtersModuleBuilder = new FiltersModuleBuilder();
  211. private final ServletsModuleBuilder servletsModuleBuilder = new ServletsModuleBuilder();
  212. /**
  213. * @param urlPattern Any Servlet-style pattern. examples: /*, /html/*, *.html, etc.
  214. * @since 2.0
  215. */
  216. protected final FilterKeyBindingBuilder filter(String urlPattern, String... morePatterns) {
  217. return filtersModuleBuilder.filter(Lists.asList(urlPattern, morePatterns));
  218. }
  219. /**
  220. * @param regex Any Java-style regular expression.
  221. * @since 2.0
  222. */
  223. protected final FilterKeyBindingBuilder filterRegex(String regex, String... regexes) {
  224. return filtersModuleBuilder.filterRegex(Lists.asList(regex, regexes));
  225. }
  226. /**
  227. * @param urlPattern Any Servlet-style pattern. examples: /*, /html/*, *.html, etc.
  228. * @since 2.0
  229. */
  230. protected final ServletKeyBindingBuilder serve(String urlPattern, String... morePatterns) {
  231. return servletsModuleBuilder.serve(Lists.asList(urlPattern, morePatterns));
  232. }
  233. /**
  234. * @param regex Any Java-style regular expression.
  235. * @since 2.0
  236. */
  237. protected final ServletKeyBindingBuilder serveRegex(String regex, String... regexes) {
  238. return servletsModuleBuilder.serveRegex(Lists.asList(regex, regexes));
  239. }
  240. /**
  241. * See the EDSL examples at {@link ServletModule#configureServlets()}
  242. *
  243. * @since 2.0
  244. */
  245. public static interface FilterKeyBindingBuilder {
  246. void through(Class<? extends Filter> filterKey);
  247. void through(Key<? extends Filter> filterKey);
  248. void through(Class<? extends Filter> dummyFilterClass, Map<String, String> contextParams);
  249. void through(Key<? extends Filter> dummyFilterClass, Map<String, String> contextParams);
  250. }
  251. /**
  252. * See the EDSL examples at {@link ServletModule#configureServlets()}
  253. *
  254. * @since 2.0
  255. */
  256. public static interface ServletKeyBindingBuilder {
  257. void with(Class<? extends HttpServlet> servletKey);
  258. void with(Key<? extends HttpServlet> servletKey);
  259. void with(Class<? extends HttpServlet> servletKey, Map<String, String> contextParams);
  260. void with(Key<? extends HttpServlet> servletKey, Map<String, String> contextParams);
  261. }
  262. }