1 16 17 package org.springframework.web.servlet.mvc; 18 19 import java.util.Enumeration ; 20 import java.util.HashMap ; 21 import java.util.Map ; 22 23 import javax.servlet.ServletException ; 24 import javax.servlet.http.HttpServletRequest ; 25 import javax.servlet.http.HttpServletResponse ; 26 27 import org.springframework.validation.BindException; 28 import org.springframework.validation.Errors; 29 import org.springframework.web.servlet.ModelAndView; 30 import org.springframework.web.util.WebUtils; 31 32 78 public abstract class AbstractWizardFormController extends AbstractFormController { 79 80 84 public static final String PARAM_FINISH = "_finish"; 85 86 90 public static final String PARAM_CANCEL = "_cancel"; 91 92 96 public static final String PARAM_TARGET = "_target"; 97 98 103 public static final String PARAM_PAGE = "_page"; 104 105 106 private String [] pages; 107 108 private String pageAttribute; 109 110 private boolean allowDirtyBack = true; 111 112 private boolean allowDirtyForward = false; 113 114 115 121 public AbstractWizardFormController() { 122 super(); 124 125 setSessionForm(true); 127 128 setValidateOnBinding(false); 131 } 132 133 138 public final void setPages(String [] pages) { 139 if (pages == null || pages.length == 0) { 140 throw new IllegalArgumentException ("No wizard pages defined"); 141 } 142 this.pages = pages; 143 } 144 145 153 public final String [] getPages() { 154 return pages; 155 } 156 157 167 protected final int getPageCount() { 168 return this.pages.length; 169 } 170 171 179 public final void setPageAttribute(String pageAttribute) { 180 this.pageAttribute = pageAttribute; 181 } 182 183 186 public final String getPageAttribute() { 187 return pageAttribute; 188 } 189 190 195 public final void setAllowDirtyBack(boolean allowDirtyBack) { 196 this.allowDirtyBack = allowDirtyBack; 197 } 198 199 202 public final boolean isAllowDirtyBack() { 203 return allowDirtyBack; 204 } 205 206 211 public final void setAllowDirtyForward(boolean allowDirtyForward) { 212 this.allowDirtyForward = allowDirtyForward; 213 } 214 215 218 public final boolean isAllowDirtyForward() { 219 return allowDirtyForward; 220 } 221 222 223 226 protected final void onBindAndValidate(HttpServletRequest request, Object command, BindException errors) 227 throws Exception { 228 229 onBindAndValidate(request, command, errors, getCurrentPage(request)); 230 } 231 232 248 protected void onBindAndValidate(HttpServletRequest request, Object command, BindException errors, int page) 249 throws Exception { 250 } 251 252 257 protected boolean isFormSubmission(HttpServletRequest request) { 258 return super.isFormSubmission(request) || isFinishRequest(request) || isCancelRequest(request); 259 } 260 261 264 protected final Map referenceData(HttpServletRequest request, Object command, Errors errors) 265 throws Exception { 266 267 return referenceData(request, command, errors, getCurrentPage(request)); 268 } 269 270 284 protected Map referenceData(HttpServletRequest request, Object command, Errors errors, int page) 285 throws Exception { 286 287 return referenceData(request, page); 288 } 289 290 301 protected Map referenceData(HttpServletRequest request, int page) throws Exception { 302 return null; 303 } 304 305 306 309 protected final ModelAndView showForm( 310 HttpServletRequest request, HttpServletResponse response, BindException errors) 311 throws Exception { 312 313 return showPage(request, errors, getInitialPage(request, errors.getTarget())); 314 } 315 316 326 protected final ModelAndView showPage(HttpServletRequest request, BindException errors, int page) 327 throws Exception { 328 329 if (page >= 0 && page < getPageCount(request, errors.getTarget())) { 330 if (logger.isDebugEnabled()) { 331 logger.debug("Showing wizard page " + page + " for form bean '" + getCommandName() + "'"); 332 } 333 334 Integer pageInteger = new Integer (page); 336 String pageAttrName = getPageSessionAttributeName(request); 337 if (isSessionForm()) { 338 if (logger.isDebugEnabled()) { 339 logger.debug("Setting page session attribute [" + pageAttrName + "] to: " + pageInteger); 340 } 341 request.getSession().setAttribute(pageAttrName, pageInteger); 342 } 343 request.setAttribute(pageAttrName, pageInteger); 344 345 Map controlModel = new HashMap (); 347 if (this.pageAttribute != null) { 348 controlModel.put(this.pageAttribute, new Integer (page)); 349 } 350 String viewName = getViewName(request, errors.getTarget(), page); 351 return showForm(request, errors, viewName, controlModel); 352 } 353 354 else { 355 throw new ServletException ("Invalid wizard page number: " + page); 356 } 357 } 358 359 368 protected int getPageCount(HttpServletRequest request, Object command) { 369 return getPageCount(); 370 } 371 372 382 protected String getViewName(HttpServletRequest request, Object command, int page) { 383 return getPages()[page]; 384 } 385 386 395 protected int getInitialPage(HttpServletRequest request, Object command) { 396 return getInitialPage(request); 397 } 398 399 405 protected int getInitialPage(HttpServletRequest request) { 406 return 0; 407 } 408 409 420 protected String getPageSessionAttributeName(HttpServletRequest request) { 421 return getPageSessionAttributeName(); 422 } 423 424 435 protected String getPageSessionAttributeName() { 436 return getClass().getName() + ".PAGE." + getCommandName(); 437 } 438 439 452 protected ModelAndView handleInvalidSubmit(HttpServletRequest request, HttpServletResponse response) 453 throws Exception { 454 455 return showNewForm(request, response); 456 } 457 458 459 462 protected final ModelAndView processFormSubmission( 463 HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) 464 throws Exception { 465 466 int currentPage = getCurrentPage(request); 467 String pageAttrName = getPageSessionAttributeName(request); 469 if (isSessionForm()) { 470 if (logger.isDebugEnabled()) { 471 logger.debug("Removing page session attribute [" + pageAttrName + "]"); 472 } 473 request.getSession().removeAttribute(pageAttrName); 474 } 475 request.setAttribute(pageAttrName, new Integer (currentPage)); 476 477 if (isCancelRequest(request)) { 479 if (logger.isDebugEnabled()) { 480 logger.debug("Cancelling wizard for form bean '" + getCommandName() + "'"); 481 } 482 return processCancel(request, response, command, errors); 483 } 484 485 if (isFinishRequest(request)) { 487 if (logger.isDebugEnabled()) { 488 logger.debug("Finishing wizard for form bean '" + getCommandName() + "'"); 489 } 490 return validatePagesAndFinish(request, response, command, errors, currentPage); 491 } 492 493 if (!suppressValidation(request, command)) { 495 if (logger.isDebugEnabled()) { 496 logger.debug("Validating wizard page " + currentPage + " for form bean '" + getCommandName() + "'"); 497 } 498 validatePage(command, errors, currentPage, false); 499 } 500 501 postProcessPage(request, command, errors, currentPage); 504 505 int targetPage = getTargetPage(request, command, errors, currentPage); 506 if (logger.isDebugEnabled()) { 507 logger.debug("Target page " + targetPage + " requested"); 508 } 509 if (targetPage != currentPage) { 510 if (!errors.hasErrors() || (this.allowDirtyBack && targetPage < currentPage) || 511 (this.allowDirtyForward && targetPage > currentPage)) { 512 return showPage(request, errors, targetPage); 514 } 515 } 516 517 return showPage(request, errors, currentPage); 519 } 520 521 528 protected int getCurrentPage(HttpServletRequest request) { 529 String pageAttrName = getPageSessionAttributeName(request); 531 Integer pageAttr = (Integer ) request.getAttribute(pageAttrName); 532 if (pageAttr != null) { 533 return pageAttr.intValue(); 534 } 535 String pageParam = request.getParameter(PARAM_PAGE); 537 if (pageParam != null) { 538 return Integer.parseInt(pageParam); 539 } 540 if (isSessionForm()) { 542 pageAttr = (Integer ) request.getSession().getAttribute(pageAttrName); 543 if (pageAttr != null) { 544 return pageAttr.intValue(); 545 } 546 } 547 throw new IllegalStateException ( 548 "Page attribute [" + pageAttrName + "] neither found in session nor in request"); 549 } 550 551 563 protected boolean isFinishRequest(HttpServletRequest request) { 564 return WebUtils.hasSubmitParameter(request, PARAM_FINISH); 565 } 566 567 579 protected boolean isCancelRequest(HttpServletRequest request) { 580 return WebUtils.hasSubmitParameter(request, PARAM_CANCEL); 581 } 582 583 595 protected int getTargetPage(HttpServletRequest request, Object command, Errors errors, int currentPage) { 596 return getTargetPage(request, currentPage); 597 } 598 599 609 protected int getTargetPage(HttpServletRequest request, int currentPage) { 610 Enumeration paramNames = request.getParameterNames(); 611 while (paramNames.hasMoreElements()) { 612 String paramName = (String ) paramNames.nextElement(); 613 if (paramName.startsWith(PARAM_TARGET)) { 614 for (int i = 0; i < WebUtils.SUBMIT_IMAGE_SUFFIXES.length; i++) { 615 String suffix = WebUtils.SUBMIT_IMAGE_SUFFIXES[i]; 616 if (paramName.endsWith(suffix)) { 617 paramName = paramName.substring(0, paramName.length() - suffix.length()); 618 } 619 } 620 return Integer.parseInt(paramName.substring(PARAM_TARGET.length())); 621 } 622 } 623 return currentPage; 624 } 625 626 630 private ModelAndView validatePagesAndFinish( 631 HttpServletRequest request, HttpServletResponse response, Object command, BindException errors, 632 int currentPage) throws Exception { 633 634 if (errors.hasErrors()) { 636 return showPage(request, errors, currentPage); 637 } 638 639 if (!suppressValidation(request, command)) { 640 for (int page = 0; page < getPageCount(request, command); page++) { 642 validatePage(command, errors, page, true); 643 if (errors.hasErrors()) { 644 return showPage(request, errors, page); 645 } 646 } 647 } 648 649 return processFinish(request, response, command, errors); 651 } 652 653 654 669 protected void validatePage(Object command, Errors errors, int page, boolean finish) { 670 validatePage(command, errors, page); 671 } 672 673 685 protected void validatePage(Object command, Errors errors, int page) { 686 } 687 688 700 protected void postProcessPage(HttpServletRequest request, Object command, Errors errors, int page) 701 throws Exception { 702 } 703 704 722 protected abstract ModelAndView processFinish( 723 HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) 724 throws Exception ; 725 726 743 protected ModelAndView processCancel( 744 HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) 745 throws Exception { 746 747 throw new ServletException ( 748 "Wizard form controller class [" + getClass().getName() + "] does not support a cancel operation"); 749 } 750 751 } 752 | Popular Tags |