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