/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.core.Ordered;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;
import org.springframework.web.context.support.RequestHandledEvent;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.springframework.web.servlet.handler.SimpleServletHandlerAdapter;
import org.springframework.web.servlet.handler.SimpleServletPostProcessor;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.mvc.ParameterizableViewController;
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.theme.SessionThemeResolver;
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.ResourceBundleViewResolver;
/**
* @author Juergen Hoeller
* @since 21.05.2003
*/
public class ComplexWebApplicationContext extends StaticWebApplicationContext {
public void refresh() throws BeansException {
registerSingleton(DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME, SessionLocaleResolver.class);
registerSingleton(DispatcherServlet.THEME_RESOLVER_BEAN_NAME, SessionThemeResolver.class);
LocaleChangeInterceptor interceptor1 = new LocaleChangeInterceptor();
LocaleChangeInterceptor interceptor2 = new LocaleChangeInterceptor();
interceptor2.setParamName("locale2");
ThemeChangeInterceptor interceptor3 = new ThemeChangeInterceptor();
ThemeChangeInterceptor interceptor4 = new ThemeChangeInterceptor();
interceptor4.setParamName("theme2");
UserRoleAuthorizationInterceptor interceptor5 = new UserRoleAuthorizationInterceptor();
interceptor5.setAuthorizedRoles(new String[] {"role1", "role2"});
List interceptors = new ArrayList();
interceptors.add(interceptor5);
interceptors.add(interceptor1);
interceptors.add(interceptor2);
interceptors.add(interceptor3);
interceptors.add(interceptor4);
interceptors.add(new MyHandlerInterceptor1());
interceptors.add(new MyHandlerInterceptor2());
interceptors.add(new MyWebRequestInterceptor());
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValue(
"mappings", "/view.do=viewHandler\n/locale.do=localeHandler\nloc.do=anotherLocaleHandler");
pvs.addPropertyValue("interceptors", interceptors);
registerSingleton("myUrlMapping1", SimpleUrlHandlerMapping.class, pvs);
pvs = new MutablePropertyValues();
pvs.addPropertyValue(
"mappings", "/form.do=localeHandler\n/unknown.do=unknownHandler\nservlet.do=myServlet");
pvs.addPropertyValue("order", "2");
registerSingleton("myUrlMapping2", SimpleUrlHandlerMapping.class, pvs);
pvs = new MutablePropertyValues();
pvs.addPropertyValue(
"mappings", "/form.do=formHandler\n/head.do=headController\n" +
"body.do=bodyController\n/noview*=noviewController\n/noview/simple*=noviewController");
pvs.addPropertyValue("order", "1");
registerSingleton("handlerMapping", SimpleUrlHandlerMapping.class, pvs);
registerSingleton("myDummyAdapter", MyDummyAdapter.class);
registerSingleton("myHandlerAdapter", MyHandlerAdapter.class);
registerSingleton("standardHandlerAdapter", SimpleControllerHandlerAdapter.class);
registerSingleton("noviewController", NoViewController.class);
pvs = new MutablePropertyValues();
pvs.addPropertyValue("order", new Integer(0));
pvs.addPropertyValue("basename", "org.springframework.web.servlet.complexviews");
registerSingleton("viewResolver", ResourceBundleViewResolver.class, pvs);
pvs = new MutablePropertyValues();
pvs.addPropertyValue("suffix", ".jsp");
registerSingleton("viewResolver2", InternalResourceViewResolver.class, pvs);
pvs = new MutablePropertyValues();
pvs.addPropertyValue("commandClass", "org.springframework.beans.TestBean");
pvs.addPropertyValue("formView", "form");
registerSingleton("formHandler", SimpleFormController.class, pvs);
pvs = new MutablePropertyValues();
pvs.addPropertyValue("viewName", "form");
registerSingleton("viewHandler", ParameterizableViewController.class, pvs);
registerSingleton("localeHandler", ComplexLocaleChecker.class);
registerSingleton("anotherLocaleHandler", ComplexLocaleChecker.class);
registerSingleton("unknownHandler", Object.class);
registerSingleton("headController", HeadController.class);
registerSingleton("bodyController", BodyController.class);
registerSingleton("servletPostProcessor", SimpleServletPostProcessor.class);
registerSingleton("handlerAdapter", SimpleServletHandlerAdapter.class);
registerSingleton("myServlet", MyServlet.class);
pvs = new MutablePropertyValues();
pvs.addPropertyValue("order", "1");
pvs.addPropertyValue("exceptionMappings",
"java.lang.IllegalAccessException=failed2\n" +
"ServletRequestBindingException=failed3");
pvs.addPropertyValue("defaultErrorView", "failed0");
registerSingleton("exceptionResolver1", SimpleMappingExceptionResolver.class, pvs);
pvs = new MutablePropertyValues();
pvs.addPropertyValue("order", "0");
pvs.addPropertyValue("exceptionMappings", "java.lang.Exception=failed1");
List mappedHandlers = new ManagedList();
mappedHandlers.add(new RuntimeBeanReference("anotherLocaleHandler"));
pvs.addPropertyValue("mappedHandlers", mappedHandlers);
pvs.addPropertyValue("defaultStatusCode", "500");
pvs.addPropertyValue("defaultErrorView", "failed2");
registerSingleton("handlerExceptionResolver", SimpleMappingExceptionResolver.class, pvs);
registerSingleton("multipartResolver", MockMultipartResolver.class);
registerSingleton("testListener", TestApplicationListener.class);
addMessage("test", Locale.ENGLISH, "test message");
addMessage("test", Locale.CANADA, "Canadian & test message");
super.refresh();
}
public static class HeadController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
if ("HEAD".equals(request.getMethod())) {
response.setContentLength(5);
}
return null;
}
}
public static class BodyController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.getOutputStream().write("body".getBytes());
return null;
}
}
public static class NoViewController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
return new ModelAndView();
}
}
public static class MyServlet implements Servlet {
private ServletConfig servletConfig;
public void init(ServletConfig servletConfig) throws ServletException {
this.servletConfig = servletConfig;
}
public ServletConfig getServletConfig() {
return servletConfig;
}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
servletResponse.getOutputStream().write("body".getBytes());
}
public String getServletInfo() {
return null;
}
public void destroy() {
this.servletConfig = null;
}
}
public static interface MyHandler {
public void doSomething(HttpServletRequest request) throws ServletException, IllegalAccessException;
public long lastModified();
}
public static class MyHandlerAdapter extends ApplicationObjectSupport implements HandlerAdapter, Ordered {
public int getOrder() {
return 99;
}
public boolean supports(Object handler) {
return handler != null && MyHandler.class.isAssignableFrom(handler.getClass());
}
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object delegate)
throws ServletException, IllegalAccessException {
((MyHandler) delegate).doSomething(request);
return null;
}
public long getLastModified(HttpServletRequest request, Object delegate) {
return ((MyHandler) delegate).lastModified();
}
}
public static class MyDummyAdapter extends ApplicationObjectSupport implements HandlerAdapter {
public boolean supports(Object handler) {
return handler != null && MyHandler.class.isAssignableFrom(handler.getClass());
}
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object delegate)
throws IOException, ServletException {
throw new ServletException("dummy");
}
public long getLastModified(HttpServletRequest request, Object delegate) {
return -1;
}
}
public static class MyHandlerInterceptor1 implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException {
if (request.getAttribute("test2") != null) {
throw new ServletException("Wrong interceptor order");
}
request.setAttribute("test1", "test1");
request.setAttribute("test1x", "test1x");
request.setAttribute("test1y", "test1y");
return true;
}
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws ServletException {
if (request.getAttribute("test2x") != null) {
throw new ServletException("Wrong interceptor order");
}
if (!"test1x".equals(request.getAttribute("test1x"))) {
throw new ServletException("Incorrect request attribute");
}
request.removeAttribute("test1x");
}
public void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws ServletException {
if (request.getAttribute("test2y") != null) {
throw new ServletException("Wrong interceptor order");
}
request.removeAttribute("test1y");
}
}
public static class MyHandlerInterceptor2 implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException {
if (request.getAttribute("test1x") == null) {
throw new ServletException("Wrong interceptor order");
}
if (request.getParameter("abort") != null) {
return false;
}
request.setAttribute("test2", "test2");
request.setAttribute("test2x", "test2x");
request.setAttribute("test2y", "test2y");
return true;
}
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws ServletException {
if (request.getParameter("noView") != null) {
modelAndView.clear();
}
if (request.getAttribute("test1x") == null) {
throw new ServletException("Wrong interceptor order");
}
if (!"test2x".equals(request.getAttribute("test2x"))) {
throw new ServletException("Incorrect request attribute");
}
request.removeAttribute("test2x");
}
public void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
if (request.getAttribute("test1y") == null) {
throw new ServletException("Wrong interceptor order");
}
request.removeAttribute("test2y");
}
}
public static class MyWebRequestInterceptor implements WebRequestInterceptor {
public void preHandle(WebRequest request) throws Exception {
request.setAttribute("test3", "test3", WebRequest.SCOPE_REQUEST);
}
public void postHandle(WebRequest request, ModelMap model) throws Exception {
request.setAttribute("test3x", "test3x", WebRequest.SCOPE_REQUEST);
}
public void afterCompletion(WebRequest request, Exception ex) throws Exception {
request.setAttribute("test3y", "test3y", WebRequest.SCOPE_REQUEST);
}
}
public static class ComplexLocaleChecker implements MyHandler {
public void doSomething(HttpServletRequest request) throws ServletException, IllegalAccessException {
WebApplicationContext wac = RequestContextUtils.getWebApplicationContext(request);
if (!(wac instanceof ComplexWebApplicationContext)) {
throw new ServletException("Incorrect WebApplicationContext");
}
if (!(request instanceof MultipartHttpServletRequest)) {
throw new ServletException("Not in a MultipartHttpServletRequest");
}
if (!(RequestContextUtils.getLocaleResolver(request) instanceof SessionLocaleResolver)) {
throw new ServletException("Incorrect LocaleResolver");
}
if (!Locale.CANADA.equals(RequestContextUtils.getLocale(request))) {
throw new ServletException("Incorrect Locale");
}
if (!Locale.CANADA.equals(LocaleContextHolder.getLocale())) {
throw new ServletException("Incorrect Locale");
}
if (!(RequestContextUtils.getThemeResolver(request) instanceof SessionThemeResolver)) {
throw new ServletException("Incorrect ThemeResolver");
}
if (!"theme".equals(RequestContextUtils.getThemeResolver(request).resolveThemeName(request))) {
throw new ServletException("Incorrect theme name");
}
if (request.getParameter("fail") != null) {
throw new ModelAndViewDefiningException(new ModelAndView("failed1"));
}
if (request.getParameter("access") != null) {
throw new IllegalAccessException("illegal access");
}
if (request.getParameter("servlet") != null) {
throw new ServletRequestBindingException("servlet");
}
if (request.getParameter("exception") != null) {
throw new RuntimeException("servlet");
}
}
public long lastModified() {
return 99;
}
}
public static class MockMultipartResolver implements MultipartResolver {
public boolean isMultipart(HttpServletRequest request) {
return true;
}
public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
if (request.getAttribute("fail") != null) {
throw new MaxUploadSizeExceededException(1000);
}
if (request instanceof MultipartHttpServletRequest) {
throw new IllegalStateException("Already a multipart request");
}
if (request.getAttribute("resolved") != null) {
throw new IllegalStateException("Already resolved");
}
request.setAttribute("resolved", Boolean.TRUE);
return new AbstractMultipartHttpServletRequest(request) {
};
}
public void cleanupMultipart(MultipartHttpServletRequest request) {
if (request.getAttribute("cleanedUp") != null) {
throw new IllegalStateException("Already cleaned up");
}
request.setAttribute("cleanedUp", Boolean.TRUE);
}
}
public static class TestApplicationListener implements ApplicationListener {
public int counter = 0;
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof RequestHandledEvent) {
this.counter++;
}
}
}
}