1 16 package org.springframework.webflow.executor.mvc; 17 18 import java.util.HashMap ; 19 import java.util.Map ; 20 21 import javax.portlet.ActionRequest; 22 import javax.portlet.ActionResponse; 23 import javax.portlet.PortletRequest; 24 import javax.portlet.PortletSession; 25 import javax.portlet.RenderRequest; 26 import javax.portlet.RenderResponse; 27 28 import org.springframework.beans.factory.InitializingBean; 29 import org.springframework.util.Assert; 30 import org.springframework.web.portlet.ModelAndView; 31 import org.springframework.web.portlet.mvc.AbstractController; 32 import org.springframework.web.portlet.mvc.Controller; 33 import org.springframework.webflow.context.portlet.PortletExternalContext; 34 import org.springframework.webflow.execution.support.ApplicationView; 35 import org.springframework.webflow.execution.support.ExternalRedirect; 36 import org.springframework.webflow.execution.support.FlowDefinitionRedirect; 37 import org.springframework.webflow.executor.FlowExecutor; 38 import org.springframework.webflow.executor.ResponseInstruction; 39 import org.springframework.webflow.executor.support.FlowExecutorArgumentHandler; 40 import org.springframework.webflow.executor.support.RequestParameterFlowExecutorArgumentHandler; 41 42 68 public class PortletFlowController extends AbstractController implements InitializingBean { 69 70 74 private static final String RESPONSE_INSTRUCTION_SESSION_ATTRIBUTE = "actionRequest.responseInstruction"; 75 76 80 private FlowExecutor flowExecutor; 81 82 85 private FlowExecutorArgumentHandler argumentHandler = new RequestParameterFlowExecutorArgumentHandler(); 86 87 92 public PortletFlowController() { 93 setCacheSeconds(0); 96 setSynchronizeOnSession(true); 100 } 101 102 106 public FlowExecutor getFlowExecutor() { 107 return flowExecutor; 108 } 109 110 114 public void setFlowExecutor(FlowExecutor flowExecutor) { 115 this.flowExecutor = flowExecutor; 116 } 117 118 122 public FlowExecutorArgumentHandler getArgumentHandler() { 123 return argumentHandler; 124 } 125 126 130 public void setArgumentHandler(FlowExecutorArgumentHandler argumentHandler) { 131 this.argumentHandler = argumentHandler; 132 } 133 134 143 public void setDefaultFlowId(String defaultFlowId) { 144 argumentHandler.setDefaultFlowId(defaultFlowId); 145 } 146 147 public void afterPropertiesSet() { 148 Assert.notNull(flowExecutor, "The flow executor property is required"); 149 Assert.notNull(argumentHandler, "The argument handler property is required"); 150 } 151 152 protected ModelAndView handleRenderRequestInternal(RenderRequest request, RenderResponse response) throws Exception { 153 PortletExternalContext context = new PortletExternalContext(getPortletContext(), request, response); 154 if (argumentHandler.isFlowExecutionKeyPresent(context)) { 155 String flowExecutionKey = argumentHandler.extractFlowExecutionKey(context); 158 ResponseInstruction responseInstruction = extractActionResponseInstruction(request); 161 if (responseInstruction == null) { 162 return toModelAndView(flowExecutor.refresh(flowExecutionKey, context)); 165 } 166 else { 167 return toModelAndView(responseInstruction); 169 } 170 } 171 else { 172 ResponseInstruction responseInstruction = extractActionResponseInstruction(request); 176 if (responseInstruction == null) { 177 String flowId = argumentHandler.extractFlowId(context); 180 return toModelAndView(flowExecutor.launch(flowId, context)); 181 } 182 else { 183 return toModelAndView(responseInstruction); 185 } 186 } 187 } 188 189 protected void handleActionRequestInternal(ActionRequest request, ActionResponse response) throws Exception { 190 PortletExternalContext context = new PortletExternalContext(getPortletContext(), request, response); 191 String flowExecutionKey = argumentHandler.extractFlowExecutionKey(context); 192 String eventId = argumentHandler.extractEventId(context); 193 ResponseInstruction responseInstruction = flowExecutor.resume(flowExecutionKey, eventId, context); 196 if (responseInstruction.isApplicationView()) { 197 if (responseInstruction.isActiveView()) { 199 response.setRenderParameter( 203 argumentHandler.getFlowExecutionKeyArgumentName(), 204 responseInstruction.getFlowExecutionKey()); 205 } 206 exposeToRenderPhase(responseInstruction, request); 209 } 210 else if (responseInstruction.isFlowExecutionRedirect()) { 211 response.setRenderParameter( 214 argumentHandler.getFlowExecutionKeyArgumentName(), 215 responseInstruction.getFlowExecutionKey()); 216 } 217 else if (responseInstruction.isFlowDefinitionRedirect()) { 218 FlowDefinitionRedirect redirect = (FlowDefinitionRedirect)responseInstruction.getViewSelection(); 221 response.setRenderParameters(redirect.getExecutionInput()); 222 response.setRenderParameter(argumentHandler.getFlowIdArgumentName(), redirect.getFlowDefinitionId()); 223 } 224 else if (responseInstruction.isExternalRedirect()) { 225 ExternalRedirect redirect = (ExternalRedirect)responseInstruction.getViewSelection(); 227 String url = argumentHandler.createExternalUrl(redirect, flowExecutionKey, context); 228 response.sendRedirect(url); 229 } 230 else { 231 throw new IllegalArgumentException ("Don't know how to handle response instruction " + responseInstruction); 232 } 233 } 234 235 237 241 private void exposeToRenderPhase(ResponseInstruction responseInstruction, ActionRequest request) { 242 PortletSession session = request.getPortletSession(false); 243 Assert.notNull(session, "A PortletSession is required"); 244 session.setAttribute(RESPONSE_INSTRUCTION_SESSION_ATTRIBUTE, responseInstruction); 245 } 246 247 255 private ResponseInstruction extractActionResponseInstruction(PortletRequest request) { 256 PortletSession session = request.getPortletSession(false); 257 ResponseInstruction response = null; 258 if (session != null) { 259 response = (ResponseInstruction)session.getAttribute(RESPONSE_INSTRUCTION_SESSION_ATTRIBUTE); 260 if (response != null) { 261 session.removeAttribute(RESPONSE_INSTRUCTION_SESSION_ATTRIBUTE); 263 } 264 } 265 return response; 266 } 267 268 272 protected ModelAndView toModelAndView(ResponseInstruction response) { 273 if (response.isApplicationView()) { 274 ApplicationView forward = (ApplicationView)response.getViewSelection(); 276 Map model = new HashMap (forward.getModel()); 277 argumentHandler.exposeFlowExecutionContext( 278 response.getFlowExecutionKey(), response.getFlowExecutionContext(), model); 279 return new ModelAndView(forward.getViewName(), model); 280 } 281 else if (response.isNull()) { 282 return null; 284 } 285 else { 286 throw new IllegalArgumentException ("Don't know how to handle response instruction " + response); 287 } 288 } 289 } | Popular Tags |