001/*
002 * Copyright 2002-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.context.support;
018
019import java.util.HashSet;
020import java.util.Set;
021
022import javax.servlet.http.HttpServletRequest;
023import javax.servlet.http.HttpServletRequestWrapper;
024
025import org.springframework.lang.Nullable;
026import org.springframework.util.Assert;
027import org.springframework.web.context.WebApplicationContext;
028
029/**
030 * HttpServletRequest decorator that makes all Spring beans in a
031 * given WebApplicationContext accessible as request attributes,
032 * through lazy checking once an attribute gets accessed.
033 *
034 * @author Juergen Hoeller
035 * @since 2.5
036 */
037public class ContextExposingHttpServletRequest extends HttpServletRequestWrapper {
038
039        private final WebApplicationContext webApplicationContext;
040
041        @Nullable
042        private final Set<String> exposedContextBeanNames;
043
044        @Nullable
045        private Set<String> explicitAttributes;
046
047
048        /**
049         * Create a new ContextExposingHttpServletRequest for the given request.
050         * @param originalRequest the original HttpServletRequest
051         * @param context the WebApplicationContext that this request runs in
052         */
053        public ContextExposingHttpServletRequest(HttpServletRequest originalRequest, WebApplicationContext context) {
054                this(originalRequest, context, null);
055        }
056
057        /**
058         * Create a new ContextExposingHttpServletRequest for the given request.
059         * @param originalRequest the original HttpServletRequest
060         * @param context the WebApplicationContext that this request runs in
061         * @param exposedContextBeanNames the names of beans in the context which
062         * are supposed to be exposed (if this is non-null, only the beans in this
063         * Set are eligible for exposure as attributes)
064         */
065        public ContextExposingHttpServletRequest(HttpServletRequest originalRequest, WebApplicationContext context,
066                        @Nullable Set<String> exposedContextBeanNames) {
067
068                super(originalRequest);
069                Assert.notNull(context, "WebApplicationContext must not be null");
070                this.webApplicationContext = context;
071                this.exposedContextBeanNames = exposedContextBeanNames;
072        }
073
074
075        /**
076         * Return the WebApplicationContext that this request runs in.
077         */
078        public final WebApplicationContext getWebApplicationContext() {
079                return this.webApplicationContext;
080        }
081
082
083        @Override
084        @Nullable
085        public Object getAttribute(String name) {
086                if ((this.explicitAttributes == null || !this.explicitAttributes.contains(name)) &&
087                                (this.exposedContextBeanNames == null || this.exposedContextBeanNames.contains(name)) &&
088                                this.webApplicationContext.containsBean(name)) {
089                        return this.webApplicationContext.getBean(name);
090                }
091                else {
092                        return super.getAttribute(name);
093                }
094        }
095
096        @Override
097        public void setAttribute(String name, Object value) {
098                super.setAttribute(name, value);
099                if (this.explicitAttributes == null) {
100                        this.explicitAttributes = new HashSet<>(8);
101                }
102                this.explicitAttributes.add(name);
103        }
104
105}