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