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 at007 *008 * https://www.apache.org/licenses/LICENSE-2.0009 *010 * Unless required by applicable law or agreed to in writing, software011 * 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 and014 * limitations under the License.015 */016017package org.springframework.mock.web;018019import java.io.IOException;020import java.io.UnsupportedEncodingException;021import java.util.Collections;022import java.util.Enumeration;023import java.util.LinkedHashMap;024import java.util.LinkedHashSet;025import java.util.Map;026import javax.el.ELContext;027import javax.servlet.Servlet;028import javax.servlet.ServletConfig;029import javax.servlet.ServletContext;030import javax.servlet.ServletException;031import javax.servlet.ServletRequest;032import javax.servlet.ServletResponse;033import javax.servlet.http.HttpServletRequest;034import javax.servlet.http.HttpServletResponse;035import javax.servlet.http.HttpSession;036import javax.servlet.jsp.JspWriter;037import javax.servlet.jsp.PageContext;038039import org.springframework.util.Assert;040041/**042 * Mock implementation of the {@link javax.servlet.jsp.PageContext} interface.043 * Only necessary for testing applications when testing custom JSP tags.044 *045 * <p>Note: Expects initialization via the constructor rather than via the046 * {@code PageContext.initialize} method. Does not support writing to a047 * JspWriter, request dispatching, or {@code handlePageException} calls.048 *049 * @author Juergen Hoeller050 * @since 1.0.2051 */052public class MockPageContext extends PageContext {053054 private final ServletContext servletContext;055056 private final HttpServletRequest request;057058 private final HttpServletResponse response;059060 private final ServletConfig servletConfig;061062 private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();063064 private JspWriter out;065066067 /**068 * Create new MockPageContext with a default {@link MockServletContext},069 * {@link MockHttpServletRequest}, {@link MockHttpServletResponse},070 * {@link MockServletConfig}.071 */072 public MockPageContext() {073 this(null, null, null, null);074 }075076 /**077 * Create new MockPageContext with a default {@link MockHttpServletRequest},078 * {@link MockHttpServletResponse}, {@link MockServletConfig}.079 * @param servletContext the ServletContext that the JSP page runs in080 * (only necessary when actually accessing the ServletContext)081 */082 public MockPageContext(ServletContext servletContext) {083 this(servletContext, null, null, null);084 }085086 /**087 * Create new MockPageContext with a MockHttpServletResponse,088 * MockServletConfig.089 * @param servletContext the ServletContext that the JSP page runs in090 * @param request the current HttpServletRequest091 * (only necessary when actually accessing the request)092 */093 public MockPageContext(ServletContext servletContext, HttpServletRequest request) {094 this(servletContext, request, null, null);095 }096097 /**098 * Create new MockPageContext with a MockServletConfig.099 * @param servletContext the ServletContext that the JSP page runs in100 * @param request the current HttpServletRequest101 * @param response the current HttpServletResponse102 * (only necessary when actually writing to the response)103 */104 public MockPageContext(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response) {105 this(servletContext, request, response, null);106 }107108 /**109 * Create new MockServletConfig.110 * @param servletContext the ServletContext that the JSP page runs in111 * @param request the current HttpServletRequest112 * @param response the current HttpServletResponse113 * @param servletConfig the ServletConfig (hardly ever accessed from within a tag)114 */115 public MockPageContext(ServletContext servletContext, HttpServletRequest request,116 HttpServletResponse response, ServletConfig servletConfig) {117118 this.servletContext = (servletContext != null ? servletContext : new MockServletContext());119 this.request = (request != null ? request : new MockHttpServletRequest(servletContext));120 this.response = (response != null ? response : new MockHttpServletResponse());121 this.servletConfig = (servletConfig != null ? servletConfig : new MockServletConfig(servletContext));122 }123124125 @Override126 public void initialize(127 Servlet servlet, ServletRequest request, ServletResponse response,128 String errorPageURL, boolean needsSession, int bufferSize, boolean autoFlush) {129130 throw new UnsupportedOperationException("Use appropriate constructor");131 }132133 @Override134 public void release() {135 }136137 @Override138 public void setAttribute(String name, Object value) {139 Assert.notNull(name, "Attribute name must not be null");140 if (value != null) {141 this.attributes.put(name, value);142 }143 else {144 this.attributes.remove(name);145 }146 }147148 @Override149 public void setAttribute(String name, Object value, int scope) {150 Assert.notNull(name, "Attribute name must not be null");151 switch (scope) {152 case PAGE_SCOPE:153 setAttribute(name, value);154 break;155 case REQUEST_SCOPE:156 this.request.setAttribute(name, value);157 break;158