InternalServletModule.java revision f8537eaaaf67e36af7469b392a4941e425459991
1/**
2 * Copyright (C) 2009 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 */
16package com.google.inject.servlet;
17
18import com.google.inject.AbstractModule;
19import com.google.inject.Provider;
20import com.google.inject.Provides;
21import com.google.inject.Singleton;
22import java.util.Map;
23import java.util.logging.Logger;
24import javax.servlet.ServletContext;
25import javax.servlet.ServletRequest;
26import javax.servlet.ServletResponse;
27import javax.servlet.http.HttpServletRequest;
28import javax.servlet.http.HttpServletResponse;
29import javax.servlet.http.HttpSession;
30
31import static com.google.inject.servlet.ServletScopes.REQUEST;
32import static com.google.inject.servlet.ServletScopes.SESSION;
33
34/**
35 * This is a left-factoring of all ServletModules installed in the system.
36 * In other words, this module contains the bindings common to all ServletModules,
37 * and is bound exactly once per injector.
38 *
39 * @author dhanji@gmail.com (Dhanji R. Prasanna)
40 */
41final class InternalServletModule extends AbstractModule {
42
43  /**
44   * Special Provider that tries to obtain an injected servlet context, specific
45   * to the current injector, failing which, it falls back to the static singleton
46   * instance that is available in the legacy Guice Servlet.
47   */
48  @Singleton
49  static class BackwardsCompatibleServletContextProvider implements Provider<ServletContext> {
50    private ServletContext injectedServletContext;
51
52    // This setter is called by the GuiceServletContextListener
53    void set(ServletContext injectedServletContext) {
54      this.injectedServletContext = injectedServletContext;
55    }
56
57    public ServletContext get() {
58      if (null != injectedServletContext) {
59        return injectedServletContext;
60      }
61
62      Logger.getLogger(InternalServletModule.class.getName())
63          .warning("You are attempting to use a deprecated API (specifically,"
64          + " attempting to @Inject ServletContext inside an eagerly created"
65          + " singleton. While we allow this for backwards compatibility, be"
66          + " warned that this MAY have unexpected behavior if you have more"
67          + " than one injector (with ServletModule) running in the same JVM."
68          + " Please consult the Guice documentation at"
69          + " http://code.google.com/p/google-guice/wiki/Servlets for more"
70          + " information.");
71      return GuiceFilter.getServletContext();
72    }
73  }
74
75  @Override
76  protected void configure() {
77    bindScope(RequestScoped.class, REQUEST);
78    bindScope(SessionScoped.class, SESSION);
79    bind(ServletRequest.class).to(HttpServletRequest.class);
80    bind(ServletResponse.class).to(HttpServletResponse.class);
81
82    // inject the pipeline into GuiceFilter so it can route requests correctly
83    // Unfortunate staticness... =(
84    // NOTE(dhanji): This is maintained for legacy purposes.
85    requestStaticInjection(GuiceFilter.class);
86
87    bind(ManagedFilterPipeline.class);
88    bind(ManagedServletPipeline.class);
89    bind(FilterPipeline.class).to(ManagedFilterPipeline.class).asEagerSingleton();
90
91    bind(ServletContext.class).toProvider(BackwardsCompatibleServletContextProvider.class);
92  }
93
94  @Provides @RequestScoped HttpServletRequest provideHttpServletRequest() {
95    return GuiceFilter.getRequest();
96  }
97
98  @Provides @RequestScoped HttpServletResponse provideHttpServletResponse() {
99    return GuiceFilter.getResponse();
100  }
101
102  @Provides HttpSession provideHttpSession() {
103    return GuiceFilter.getRequest().getSession();
104  }
105
106  @SuppressWarnings({"unchecked"})
107  @Provides @RequestScoped @RequestParameters Map<String, String[]> provideRequestParameters() {
108    return GuiceFilter.getRequest().getParameterMap();
109  }
110
111  @Override
112  public boolean equals(Object o) {
113    // Is only ever installed internally, so we don't need to check state.
114    return o instanceof InternalServletModule;
115  }
116
117  @Override
118  public int hashCode() {
119    return InternalServletModule.class.hashCode();
120  }
121}
122