/* * Copyright 2002-2006 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.portlet; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; import javax.portlet.Portlet; import javax.portlet.PortletConfig; import javax.portlet.PortletException; import javax.portlet.PortletRequest; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.support.ManagedMap; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.Ordered; import org.springframework.mock.web.portlet.MockPortletConfig; import org.springframework.mock.web.portlet.MockPortletContext; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.multipart.MultipartException; import org.springframework.web.portlet.bind.PortletRequestBindingException; import org.springframework.web.portlet.context.PortletRequestHandledEvent; import org.springframework.web.portlet.context.StaticPortletApplicationContext; import org.springframework.web.portlet.handler.ParameterHandlerMapping; import org.springframework.web.portlet.handler.ParameterMappingInterceptor; import org.springframework.web.portlet.handler.PortletModeHandlerMapping; import org.springframework.web.portlet.handler.PortletModeParameterHandlerMapping; import org.springframework.web.portlet.handler.SimpleMappingExceptionResolver; import org.springframework.web.portlet.handler.SimplePortletHandlerAdapter; import org.springframework.web.portlet.handler.SimplePortletPostProcessor; import org.springframework.web.portlet.handler.UserRoleAuthorizationInterceptor; import org.springframework.web.portlet.multipart.DefaultMultipartActionRequest; import org.springframework.web.portlet.multipart.MultipartActionRequest; import org.springframework.web.portlet.multipart.PortletMultipartResolver; import org.springframework.web.portlet.mvc.Controller; import org.springframework.web.portlet.mvc.SimpleControllerHandlerAdapter; /** * @author Juergen Hoeller * @author Mark Fisher */ public class ComplexPortletApplicationContext extends StaticPortletApplicationContext { public void refresh() throws BeansException { registerSingleton("standardHandlerAdapter", SimpleControllerHandlerAdapter.class); registerSingleton("portletHandlerAdapter", SimplePortletHandlerAdapter.class); registerSingleton("myHandlerAdapter", MyHandlerAdapter.class); registerSingleton("viewController", ViewController.class); registerSingleton("editController", EditController.class); registerSingleton("helpController1", HelpController1.class); registerSingleton("helpController2", HelpController2.class); registerSingleton("testController1", TestController1.class); registerSingleton("testController2", TestController2.class); registerSingleton("requestLocaleCheckingController", RequestLocaleCheckingController.class); registerSingleton("localeContextCheckingController", LocaleContextCheckingController.class); registerSingleton("exceptionThrowingHandler1", ExceptionThrowingHandler.class); registerSingleton("exceptionThrowingHandler2", ExceptionThrowingHandler.class); registerSingleton("unknownHandler", Object.class); registerSingleton("myPortlet", MyPortlet.class); registerSingleton("portletMultipartResolver", MockMultipartResolver.class); registerSingleton("portletPostProcessor", SimplePortletPostProcessor.class); registerSingleton("testListener", TestApplicationListener.class); ConstructorArgumentValues cvs = new ConstructorArgumentValues(); cvs.addIndexedArgumentValue(0, new MockPortletContext()); cvs.addIndexedArgumentValue(1, "complex"); registerBeanDefinition("portletConfig", new RootBeanDefinition(MockPortletConfig.class, cvs, null)); UserRoleAuthorizationInterceptor userRoleInterceptor = new UserRoleAuthorizationInterceptor(); userRoleInterceptor.setAuthorizedRoles(new String[] {"role1", "role2"}); ParameterHandlerMapping interceptingHandlerMapping = new ParameterHandlerMapping(); interceptingHandlerMapping.setParameterName("interceptingParam"); ParameterMappingInterceptor parameterMappingInterceptor = new ParameterMappingInterceptor(); parameterMappingInterceptor.setParameterName("interceptingParam"); List interceptors = new ArrayList(); interceptors.add(parameterMappingInterceptor); interceptors.add(userRoleInterceptor); interceptors.add(new MyHandlerInterceptor1()); interceptors.add(new MyHandlerInterceptor2()); MutablePropertyValues pvs = new MutablePropertyValues(); Map portletModeMap = new ManagedMap(); portletModeMap.put("view", new RuntimeBeanReference("viewController")); portletModeMap.put("edit", new RuntimeBeanReference("editController")); pvs.addPropertyValue("portletModeMap", portletModeMap); pvs.addPropertyValue("interceptors", interceptors); registerSingleton("handlerMapping3", PortletModeHandlerMapping.class, pvs); pvs = new MutablePropertyValues(); Map parameterMap = new ManagedMap(); parameterMap.put("test1", new RuntimeBeanReference("testController1")); parameterMap.put("test2", new RuntimeBeanReference("testController2")); parameterMap.put("requestLocaleChecker", new RuntimeBeanReference("requestLocaleCheckingController")); parameterMap.put("contextLocaleChecker", new RuntimeBeanReference("localeContextCheckingController")); parameterMap.put("exception1", new RuntimeBeanReference("exceptionThrowingHandler1")); parameterMap.put("exception2", new RuntimeBeanReference("exceptionThrowingHandler2")); parameterMap.put("myPortlet", new RuntimeBeanReference("myPortlet")); parameterMap.put("unknown", new RuntimeBeanReference("unknownHandler")); pvs.addPropertyValue("parameterMap", parameterMap); pvs.addPropertyValue("parameterName", "myParam"); pvs.addPropertyValue("order", "2"); registerSingleton("handlerMapping2", ParameterHandlerMapping.class, pvs); pvs = new MutablePropertyValues(); Map innerMap = new ManagedMap(); innerMap.put("help1", new RuntimeBeanReference("helpController1")); innerMap.put("help2", new RuntimeBeanReference("helpController2")); Map outerMap = new ManagedMap(); outerMap.put("help", innerMap); pvs.addPropertyValue("portletModeParameterMap", outerMap); pvs.addPropertyValue("order", "1"); registerSingleton("handlerMapping1", PortletModeParameterHandlerMapping.class, pvs); pvs = new MutablePropertyValues(); pvs.addPropertyValue("order", "1"); pvs.addPropertyValue("exceptionMappings", "java.lang.IllegalAccessException=failed-illegalaccess\n" + "PortletRequestBindingException=failed-binding\n" + "UnavailableException=failed-unavailable"); pvs.addPropertyValue("defaultErrorView", "failed-default-1"); registerSingleton("exceptionResolver", SimpleMappingExceptionResolver.class, pvs); pvs = new MutablePropertyValues(); pvs.addPropertyValue("order", "0"); pvs.addPropertyValue("exceptionMappings", "java.lang.Exception=failed-exception\n" + "java.lang.RuntimeException=failed-runtime"); List mappedHandlers = new ManagedList(); mappedHandlers.add(new RuntimeBeanReference("exceptionThrowingHandler1")); pvs.addPropertyValue("mappedHandlers", mappedHandlers); pvs.addPropertyValue("defaultErrorView", "failed-default-0"); registerSingleton("handlerExceptionResolver", SimpleMappingExceptionResolver.class, pvs); addMessage("test", Locale.ENGLISH, "test message"); addMessage("test", Locale.CANADA, "Canadian & test message"); addMessage("test.args", Locale.ENGLISH, "test {0} and {1}"); super.refresh(); } public static class TestController1 implements Controller { public void handleActionRequest(ActionRequest request, ActionResponse response) { response.setRenderParameter("result", "test1-action"); } public ModelAndView handleRenderRequest(RenderRequest request, RenderResponse response) throws Exception { return null; } } public static class TestController2 implements Controller { public void handleActionRequest(ActionRequest request, ActionResponse response) {} public ModelAndView handleRenderRequest(RenderRequest request, RenderResponse response) throws Exception { response.setProperty("result", "test2-view"); return null; } } public static class ViewController implements Controller { public void handleActionRequest(ActionRequest request, ActionResponse response) {} public ModelAndView handleRenderRequest(RenderRequest request, RenderResponse response) throws Exception { return new ModelAndView("someViewName", "result", "view was here"); } } public static class EditController implements Controller { public void handleActionRequest(ActionRequest request, ActionResponse response) { response.setRenderParameter("param", "edit was here"); } public ModelAndView handleRenderRequest(RenderRequest request, RenderResponse response) throws Exception { return new ModelAndView(request.getParameter("param")); } } public static class HelpController1 implements Controller { public void handleActionRequest(ActionRequest request, ActionResponse response) { response.setRenderParameter("param", "help1 was here"); } public ModelAndView handleRenderRequest(RenderRequest request, RenderResponse response) throws Exception { return new ModelAndView("help1-view"); } } public static class HelpController2 implements Controller { public void handleActionRequest(ActionRequest request, ActionResponse response) { response.setRenderParameter("param", "help2 was here"); } public ModelAndView handleRenderRequest(RenderRequest request, RenderResponse response) throws Exception { return new ModelAndView("help2-view"); } } public static class RequestLocaleCheckingController implements Controller { public void handleActionRequest(ActionRequest request, ActionResponse response) throws PortletException { if (!Locale.CANADA.equals(request.getLocale())) { throw new PortletException("Incorrect Locale in ActionRequest"); } } public ModelAndView handleRenderRequest(RenderRequest request, RenderResponse response) throws PortletException, IOException { if (!Locale.CANADA.equals(request.getLocale())) { throw new PortletException("Incorrect Locale in RenderRequest"); } response.getWriter().write("locale-ok"); return null; } } public static class LocaleContextCheckingController implements Controller { public void handleActionRequest(ActionRequest request, ActionResponse response) throws PortletException { if (!Locale.CANADA.equals(LocaleContextHolder.getLocale())) { throw new PortletException("Incorrect Locale in LocaleContextHolder"); } } public ModelAndView handleRenderRequest(RenderRequest request, RenderResponse response) throws PortletException, IOException { if (!Locale.CANADA.equals(LocaleContextHolder.getLocale())) { throw new PortletException("Incorrect Locale in LocaleContextHolder"); } response.getWriter().write("locale-ok"); return null; } } public static class MyPortlet implements Portlet { private PortletConfig portletConfig; public void init(PortletConfig portletConfig) throws PortletException { this.portletConfig = portletConfig; } public void processAction(ActionRequest request, ActionResponse response) throws PortletException { response.setRenderParameter("result", "myPortlet action called"); } public void render(RenderRequest request, RenderResponse response) throws PortletException, IOException { response.getWriter().write("myPortlet was here"); } public PortletConfig getPortletConfig() { return this.portletConfig; } public void destroy() { this.portletConfig = null; } } public static interface MyHandler { public void doSomething(PortletRequest request) throws Exception; } public static class ExceptionThrowingHandler implements MyHandler { public void doSomething(PortletRequest request) throws Exception { if (request.getParameter("fail") != null) { throw new ModelAndViewDefiningException(new ModelAndView("failed-modelandview")); } if (request.getParameter("access") != null) { throw new IllegalAccessException("portlet-illegalaccess"); } if (request.getParameter("binding") != null) { throw new PortletRequestBindingException("portlet-binding"); } if (request.getParameter("generic") != null) { throw new Exception("portlet-generic"); } if (request.getParameter("runtime") != null) { throw new RuntimeException("portlet-runtime"); } throw new IllegalArgumentException("illegal argument"); } } public static class MyHandlerAdapter implements HandlerAdapter, Ordered { public int getOrder() { return 99; } public boolean supports(Object handler) { return handler != null && MyHandler.class.isAssignableFrom(handler.getClass()); } public void handleAction(ActionRequest request, ActionResponse response, Object delegate) throws Exception { ((MyHandler) delegate).doSomething(request); } public ModelAndView handleRender(RenderRequest request, RenderResponse response, Object delegate) throws Exception { ((MyHandler) delegate).doSomething(request); return null; } } public static class MyHandlerInterceptor1 implements HandlerInterceptor { public boolean preHandleAction(ActionRequest request, ActionResponse response, Object handler) { return true; } public void afterActionCompletion(ActionRequest request, ActionResponse response, Object handler, Exception ex) { } public boolean preHandleRender(RenderRequest request, RenderResponse response, Object handler) throws PortletException { if (request.getAttribute("test2-remove-never") != null) { throw new PortletException("Wrong interceptor order"); } request.setAttribute("test1-remove-never", "test1-remove-never"); request.setAttribute("test1-remove-post", "test1-remove-post"); request.setAttribute("test1-remove-after", "test1-remove-after"); return true; } public void postHandleRender( RenderRequest request, RenderResponse response, Object handler, ModelAndView modelAndView) throws PortletException { if (request.getAttribute("test2-remove-post") != null) { throw new PortletException("Wrong interceptor order"); } if (!"test1-remove-post".equals(request.getAttribute("test1-remove-post"))) { throw new PortletException("Incorrect request attribute"); } request.removeAttribute("test1-remove-post"); } public void afterRenderCompletion( RenderRequest request, RenderResponse response, Object handler, Exception ex) throws PortletException { if (request.getAttribute("test2-remove-after") != null) { throw new PortletException("Wrong interceptor order"); } request.removeAttribute("test1-remove-after"); } } public static class MyHandlerInterceptor2 implements HandlerInterceptor { public boolean preHandleAction(ActionRequest request, ActionResponse response, Object handler) { return true; } public void afterActionCompletion(ActionRequest request, ActionResponse response, Object handler, Exception ex) { } public boolean preHandleRender(RenderRequest request, RenderResponse response, Object handler) throws PortletException { if (request.getAttribute("test1-remove-post") == null) { throw new PortletException("Wrong interceptor order"); } if ("true".equals(request.getParameter("abort"))) { return false; } request.setAttribute("test2-remove-never", "test2-remove-never"); request.setAttribute("test2-remove-post", "test2-remove-post"); request.setAttribute("test2-remove-after", "test2-remove-after"); return true; } public void postHandleRender( RenderRequest request, RenderResponse response, Object handler, ModelAndView modelAndView) throws PortletException { if ("true".equals(request.getParameter("noView"))) { modelAndView.clear(); } if (request.getAttribute("test1-remove-post") == null) { throw new PortletException("Wrong interceptor order"); } if (!"test2-remove-post".equals(request.getAttribute("test2-remove-post"))) { throw new PortletException("Incorrect request attribute"); } request.removeAttribute("test2-remove-post"); } public void afterRenderCompletion( RenderRequest request, RenderResponse response, Object handler, Exception ex) throws Exception { if (request.getAttribute("test1-remove-after") == null) { throw new PortletException("Wrong interceptor order"); } request.removeAttribute("test2-remove-after"); } } public static class MultipartCheckingHandler implements MyHandler { public void doSomething(PortletRequest request) throws PortletException, IllegalAccessException { if (!(request instanceof MultipartActionRequest)) { throw new PortletException("Not in a MultipartActionRequest"); } } } public static class MockMultipartResolver implements PortletMultipartResolver { public boolean isMultipart(ActionRequest request) { return true; } public MultipartActionRequest resolveMultipart(ActionRequest request) throws MultipartException { if (request.getAttribute("fail") != null) { throw new MaxUploadSizeExceededException(1000); } if (request instanceof MultipartActionRequest) { throw new IllegalStateException("Already a multipart request"); } if (request.getAttribute("resolved") != null) { throw new IllegalStateException("Already resolved"); } request.setAttribute("resolved", Boolean.TRUE); Map files = new HashMap(); files.put("someFile", "someFile"); Map params = new HashMap(); params.put("someParam", "someParam"); return new DefaultMultipartActionRequest(request, files, params); } public void cleanupMultipart(MultipartActionRequest 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 PortletRequestHandledEvent) { this.counter++; } } } }