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