1 16 17 package org.springframework.web.portlet.mvc; 18 19 import java.util.Arrays ; 20 import java.util.Map ; 21 22 import javax.portlet.ActionRequest; 23 import javax.portlet.ActionResponse; 24 import javax.portlet.PortletException; 25 import javax.portlet.PortletRequest; 26 import javax.portlet.PortletSession; 27 import javax.portlet.RenderRequest; 28 import javax.portlet.RenderResponse; 29 30 import org.springframework.validation.BindException; 31 import org.springframework.validation.Errors; 32 import org.springframework.web.portlet.ModelAndView; 33 import org.springframework.web.portlet.bind.PortletRequestDataBinder; 34 import org.springframework.web.portlet.handler.PortletSessionRequiredException; 35 36 247 public abstract class AbstractFormController extends BaseCommandController { 248 249 253 private static final String FORM_SUBMISSION_PARAMETER = "form-submit"; 254 255 private static final String INVALID_SUBMISSION_PARAMETER = "invalid-submit"; 256 257 private static final String TRUE = Boolean.TRUE.toString(); 258 259 260 private boolean bindOnNewForm = false; 261 262 private boolean sessionForm = false; 263 264 private boolean redirectAction = false; 265 266 private String [] renderParameters = null; 267 268 269 282 public AbstractFormController() { 283 setCacheSeconds(0); 284 } 285 286 290 public final void setBindOnNewForm(boolean bindOnNewForm) { 291 this.bindOnNewForm = bindOnNewForm; 292 } 293 294 297 public final boolean isBindOnNewForm() { 298 return bindOnNewForm; 299 } 300 301 309 public final void setSessionForm(boolean sessionForm) { 310 this.sessionForm = sessionForm; 311 } 312 313 316 public final boolean isSessionForm() { 317 return sessionForm; 318 } 319 320 330 public void setRedirectAction(boolean redirectAction) { 331 this.redirectAction = redirectAction; 332 } 333 334 338 public boolean isRedirectAction() { 339 return redirectAction; 340 } 341 342 348 public void setRenderParameters(String [] parameters) { 349 this.renderParameters = parameters; 350 } 351 352 359 public String [] getRenderParameters() { 360 return renderParameters; 361 } 362 363 364 373 protected void handleActionRequestInternal(ActionRequest request, ActionResponse response) 374 throws Exception { 375 376 if (isFormSubmission(request)) { 378 try { 380 Object command = getCommand(request); 381 if (logger.isDebugEnabled()) { 382 logger.debug("Processing valid submit (redirectAction = " + isRedirectAction() + ")"); 383 } 384 if (!isRedirectAction()) { 385 setFormSubmit(response); 386 } 387 PortletRequestDataBinder binder = bindAndValidate(request, command); 388 BindException errors = new BindException(binder.getBindingResult()); 389 processFormSubmission(request, response, command, errors); 390 setRenderCommandAndErrors(request, command, errors); 391 return; 392 } 393 catch (PortletSessionRequiredException ex) { 394 if (logger.isDebugEnabled()) { 396 logger.debug("Invalid submit detected: " + ex.getMessage()); 397 } 398 setFormSubmit(response); 399 setInvalidSubmit(response); 400 handleInvalidSubmit(request, response); 401 return; 402 } 403 } 404 405 else { 406 logger.debug("Not a form submit - passing parameters to render phase"); 407 passRenderParameters(request, response); 408 return; 409 } 410 } 411 412 422 protected ModelAndView handleRenderRequestInternal(RenderRequest request, RenderResponse response) 423 throws Exception { 424 425 if (isFormSubmission(request)) { 427 428 if (isInvalidSubmission(request)) { 430 logger.debug("Invalid submit - calling renderInvalidSubmit"); 431 return renderInvalidSubmit(request, response); 432 } 433 434 logger.debug("Valid submit - calling renderFormSubmission"); 436 return renderFormSubmission(request, response, getRenderCommand(request), getRenderErrors(request)); 437 } 438 439 else { 440 return showNewForm(request, response); 442 } 443 } 444 445 459 protected boolean isFormSubmission(PortletRequest request) { 460 return (request instanceof ActionRequest ? true : 461 TRUE.equals(request.getParameter(getFormSubmitParameterName()))); 462 } 463 464 467 protected boolean isInvalidSubmission(PortletRequest request) { 468 return TRUE.equals(request.getParameter(getInvalidSubmitParameterName())); 469 } 470 471 477 protected String getFormSubmitParameterName() { 478 return FORM_SUBMISSION_PARAMETER; 479 } 480 481 487 protected String getInvalidSubmitParameterName() { 488 return INVALID_SUBMISSION_PARAMETER; 489 } 490 491 496 protected final void setFormSubmit(ActionResponse response) { 497 if (logger.isDebugEnabled()) { 498 logger.debug("Setting render parameter [" + getFormSubmitParameterName() + 499 "] to indicate this is a form submission"); 500 } 501 try { 502 response.setRenderParameter(getFormSubmitParameterName(), TRUE); 503 } 504 catch (IllegalStateException ex) { 505 } 507 } 508 509 514 protected final void setInvalidSubmit(ActionResponse response) { 515 if (logger.isDebugEnabled()) { 516 logger.debug("Setting render parameter [" + getInvalidSubmitParameterName() + 517 "] to indicate this is an invalid submission"); 518 } 519 try { 520 response.setRenderParameter(getInvalidSubmitParameterName(), TRUE); 521 } 522 catch (IllegalStateException ex) { 523 } 525 } 526 527 537 protected String getFormSessionAttributeName(PortletRequest request) { 538 return getFormSessionAttributeName(); 539 } 540 541 551 protected String getFormSessionAttributeName() { 552 return getClass().getName() + ".FORM." + getCommandName(); 553 } 554 555 564 protected void passRenderParameters(ActionRequest request, ActionResponse response) { 565 if (this.renderParameters == null) { 566 return; 567 } 568 try { 569 for (int i = 0; i < this.renderParameters.length; i++) { 570 String paramName = this.renderParameters[i]; 571 String paramValues[] = request.getParameterValues(paramName); 572 if (paramValues != null) { 573 if (logger.isDebugEnabled()) { 574 logger.debug("Passing parameter to render phase '" + paramName + "' = " + 575 (paramValues == null ? "NULL" : Arrays.asList(paramValues).toString())); 576 } 577 response.setRenderParameter(paramName, paramValues); 578 } 579 } 580 } 581 catch (IllegalStateException ex) { 582 } 584 } 585 586 587 596 protected final ModelAndView showNewForm(RenderRequest request, RenderResponse response) 597 throws Exception { 598 599 logger.debug("Displaying new form"); 600 return showForm(request, response, getErrorsForNewForm(request)); 601 } 602 603 614 protected final BindException getErrorsForNewForm(RenderRequest request) throws Exception { 615 Object command = formBackingObject(request); 617 if (command == null) { 618 throw new PortletException("Form object returned by formBackingObject() must not be null"); 619 } 620 if (!checkCommand(command)) { 621 throw new PortletException("Form object returned by formBackingObject() must match commandClass"); 622 } 623 624 PortletRequestDataBinder binder = createBinder(request, command); 627 BindException errors = new BindException(binder.getBindingResult()); 628 629 if (isBindOnNewForm()) { 630 if (logger.isDebugEnabled()) { 631 logger.debug("Binding to new form"); 632 } 633 binder.bind(request); 634 onBindOnNewForm(request, command, errors); 635 } 636 637 return errors; 639 } 640 641 653 protected void onBindOnNewForm(RenderRequest request, Object command, BindException errors) 654 throws Exception { 655 656 onBindOnNewForm(request, command); 657 } 658 659 671 protected void onBindOnNewForm(RenderRequest request, Object command) throws Exception { 672 } 673 674 675 682 protected final Object getCommand(PortletRequest request) throws Exception { 683 if (!isSessionForm()) { 685 if (logger.isDebugEnabled()) { 686 logger.debug("Not a session-form -- using new formBackingObject"); 687 } 688 return formBackingObject(request); 689 } 690 691 PortletSession session = request.getPortletSession(false); 693 if (session == null) { 694 throw new PortletSessionRequiredException("Must have session when trying to bind (in session-form mode)"); 695 } 696 String formAttrName = getFormSessionAttributeName(request); 697 Object sessionFormObject = session.getAttribute(formAttrName); 698 if (sessionFormObject == null) { 699 throw new PortletSessionRequiredException("Form object not found in session (in session-form mode)"); 700 } 701 702 if (logger.isDebugEnabled()) { 706 logger.debug("Removing form session attribute [" + formAttrName + "]"); 707 } 708 session.removeAttribute(formAttrName); 709 710 if (!checkCommand(sessionFormObject)) { 712 throw new PortletSessionRequiredException("Object found in session does not match commandClass"); 713 } 714 715 return sessionFormObject; 716 } 717 718 738 protected Object formBackingObject(PortletRequest request) throws Exception { 739 return createCommand(); 740 } 741 742 743 767 protected abstract ModelAndView showForm(RenderRequest request, RenderResponse response, BindException errors) throws Exception ; 768 769 782 protected final ModelAndView showForm(RenderRequest request, BindException errors, String viewName) 783 throws Exception { 784 785 return showForm(request, errors, viewName, null); 786 } 787 788 804 protected final ModelAndView showForm(RenderRequest request, BindException errors, String viewName, Map controlModel) 805 throws Exception { 806 807 if (isSessionForm()) { 811 String formAttrName = getFormSessionAttributeName(request); 812 if (logger.isDebugEnabled()) { 813 logger.debug("Setting form session attribute [" + formAttrName + "] to: " + errors.getTarget()); 814 } 815 request.getPortletSession().setAttribute(formAttrName, errors.getTarget()); 816 } 817 818 Map model = errors.getModel(); 821 822 Map referenceData = referenceData(request, errors.getTarget(), errors); 824 if (referenceData != null) { 825 model.putAll(referenceData); 826 } 827 828 if (controlModel != null) { 830 model.putAll(controlModel); 831 } 832 833 return new ModelAndView(viewName, model); 835 } 836 837 849 protected Map referenceData(PortletRequest request, Object command, Errors errors) throws Exception { 850 return null; 851 } 852 853 854 876 protected abstract ModelAndView renderFormSubmission(RenderRequest request, RenderResponse response, Object command, BindException errors) 877 throws Exception ; 878 879 896 protected abstract void processFormSubmission(ActionRequest request, ActionResponse response, Object command, BindException errors) 897 throws Exception ; 898 899 929 protected ModelAndView renderInvalidSubmit(RenderRequest request, RenderResponse response) 930 throws Exception { 931 932 return renderFormSubmission(request, response, getRenderCommand(request), getRenderErrors(request)); 933 } 934 935 956 protected void handleInvalidSubmit(ActionRequest request, ActionResponse response) throws Exception { 957 passRenderParameters(request, response); 958 Object command = formBackingObject(request); 959 if (command == null) { 960 throw new PortletException("Form object returned by formBackingObject() must not be null"); 961 } 962 if (!checkCommand(command)) { 963 throw new PortletException("Form object returned by formBackingObject() must match commandClass"); 964 } 965 PortletRequestDataBinder binder = bindAndValidate(request, command); 966 BindException errors = new BindException(binder.getBindingResult()); 967 processFormSubmission(request, response, command, errors); 968 setRenderCommandAndErrors(request, command, errors); 969 } 970 971 } 972 | Popular Tags |