/* * Cr�� le 17 juil. 2003 */ package org.springframework.web.servlet.mvc; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.validation.BindException; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.util.WebUtils; /** * Base abstract controller for CRUD operations in collaboration with a list view. * * <br>For now, only session mode works due to the use of the handleInvalidSubmit method. * The parent class should be modified a bit for working without Session. * * This is just a brief description of the primarily process. Any parts are in practice done * in the concrete class and are therefore customizable differently. * * Due to the custom isFormSubmit and handleInvalidSubmit, when the Controller is * accessed first (ie a GET call without parameter), the showList method will be called. * This method is intended for providing a view with a list of existing records. * On the list view, calling the same URL (ie the Controller) with <code>_edit</code> * parameter will call the showForm with an empty record. If adding an <code>id</code> * parameter the showForm will be pre-populated with the existing record from the database. * * The formView is normally subitiing data with a submit button or image giving an additional * parameter: _cancel, _insert, _update or _remove. The _edit parameter must be forgetten * since the isFormSubmit method will go the wrong way. * * Depending on booleans confirmXXX values, a showConfirm form will be called or directly * processSubmit, both with the action parameter. * * If a confirmation view is used, it will have button Parameter as _cancel and _confXXX. * * @author Jean-Pierre Pawlak */ public abstract class AbstractListFormController extends AbstractFormController { public static final String PARAM_CANCEL = "_cancel"; public static final String PARAM_INSERT = "_insert"; public static final String PARAM_UPDATE = "_update"; public static final String PARAM_REMOVE = "_remove"; public static final String PARAM_CONFIRM_INSERT = "_confinsert"; public static final String PARAM_CONFIRM_UPDATE = "_confupdate"; public static final String PARAM_CONFIRM_REMOVE = "_confremove"; public static final String PARAM_EDIT = "_edit"; public static final String ERROR_DUPLICATE = "duplicateFormSubmission"; protected static final int UNKNOWN = 0; protected static final int CANCEL = 1; protected static final int INSERT = 2; protected static final int UPDATE = 3; protected static final int REMOVE = 4; protected static final String[] ACTIONS = {"UNKNOWN","CANCEL","INSERT","UPDATE","REMOVE"}; private boolean confirmInsert; private boolean confirmUpdate; private boolean confirmRemove; /** * */ public AbstractListFormController() { super(); } // --- Final methods /** * Return the name of the session attribute that holds * the pagedlist object for this controller. * @return the name of the form session attribute, * or null if not in session form mode. */ protected final String getListSessionAttributeName() { return isSessionForm() ? getClass() + ".list." + getCommandName() : null; } protected final ModelAndView processSubmit( HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws ServletException, IOException { logger.info("processSubmit"); logger.info("cancel ?"); // cancel ? if (WebUtils.hasSubmitParameter(request, PARAM_CANCEL)) { logger.info("Cancelling form bean " + getCommandName()); return processSubmit(request, response, command, errors, CANCEL); } logger.info("insert ?"); // insert ? if (WebUtils.hasSubmitParameter(request, PARAM_CONFIRM_INSERT) || (!confirmInsert && WebUtils.hasSubmitParameter(request, PARAM_INSERT))) { logger.info("Inserting form bean " + getCommandName()); return processSubmit(request, response, command, errors, INSERT); } if (WebUtils.hasSubmitParameter(request, PARAM_INSERT)) { logger.info("Confirming insert form bean " + getCommandName()); // If we are here, the sessionForm is already set to true as confirmInsert is also true. request.getSession().setAttribute(getFormSessionAttributeName(), command); return showConfirm(request, response, command, errors, INSERT); } // update ? logger.info("update ?"); if (WebUtils.hasSubmitParameter(request, PARAM_CONFIRM_UPDATE) || (!confirmUpdate && WebUtils.hasSubmitParameter(request, PARAM_UPDATE))) { logger.info("Updating form bean " + getCommandName()); return processSubmit(request, response, command, errors, UPDATE); } if (WebUtils.hasSubmitParameter(request, PARAM_UPDATE)) { logger.info("Confirming update form bean " + getCommandName()); // If we are here, the sessionForm is already set to true as confirmUpdate is also true. request.getSession().setAttribute(getFormSessionAttributeName(), command); return showConfirm(request, response, command, errors, UPDATE); } // remove ? logger.info("remove ?"); if (WebUtils.hasSubmitParameter(request, PARAM_CONFIRM_REMOVE) || (!confirmRemove && WebUtils.hasSubmitParameter(request, PARAM_REMOVE))) { logger.info("Removing form bean " + getCommandName()); return processSubmit(request, response, command, errors, REMOVE); } if (WebUtils.hasSubmitParameter(request, PARAM_REMOVE)) { logger.info("Confirming remove form bean " + getCommandName()); // If we are here, the sessionForm is already set to true as confirmRemove is also true. request.getSession().setAttribute(getFormSessionAttributeName(), command); return showConfirm(request, response, command, errors, REMOVE); } // Unknown situation logger.info("unknown"); logger.debug("Processing unknown form bean " + getCommandName()); return processSubmit(request, response, command, errors, UNKNOWN); } /** * @see org.springframework.web.servlet.mvc.AbstractFormController#handleInvalidSubmit(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ protected final ModelAndView handleInvalidSubmit( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info("handleInvalidSubmit"); String msg = null; if (WebUtils.hasSubmitParameter(request, PARAM_INSERT) || WebUtils.hasSubmitParameter(request, PARAM_UPDATE) || WebUtils.hasSubmitParameter(request, PARAM_REMOVE) || WebUtils.hasSubmitParameter(request, PARAM_CONFIRM_INSERT) || WebUtils.hasSubmitParameter(request, PARAM_CONFIRM_UPDATE) || WebUtils.hasSubmitParameter(request, PARAM_CONFIRM_REMOVE) ) { msg = ERROR_DUPLICATE; } return showList(request, response, msg); } // --- Not final and abstract methods abstract protected ModelAndView processSubmit( HttpServletRequest request, HttpServletResponse response, Object command, BindException errors, int action) throws ServletException, IOException; abstract protected ModelAndView showList( HttpServletRequest request, HttpServletResponse response, String message) throws ServletException, IOException; /** * Show the confirmation page. Has to be by subclasses * To have a confirmation page displayed, redefine this method in the subclassd * and set the property confirmInsert, confirmUpdate or confirmRemove to true. * @param request * @param response * @param command * @param errors * @return the ModelAndView * @throws ServletException * @throws IOException */ protected ModelAndView showConfirm( HttpServletRequest request, HttpServletResponse response, Object command, BindException errors, int action) throws ServletException, IOException { // In a real confirm page, the session attribute is let in the session. if (this.isSessionForm()) { request.getSession().removeAttribute(getFormSessionAttributeName()); } return processSubmit(request, response, command, errors, action); } /** * @see org.springframework.web.servlet.mvc.AbstractFormController#isFormSubmission(javax.servlet.http.HttpServletRequest) */ protected boolean isFormSubmission(HttpServletRequest request) { boolean b = ! WebUtils.hasSubmitParameter(request, PARAM_EDIT); logger.info("isFormSubmission = " + b); return b; } // --- Accessors methods protected final boolean isConfirmInsert() { return confirmInsert; } protected final boolean isConfirmRemove() { return confirmRemove; } protected final boolean isConfirmUpdate() { return confirmUpdate; } public final void setConfirmInsert(boolean confirmInsert) { this.confirmInsert = confirmInsert; if (confirmInsert) setSessionForm(true); } public final void setConfirmRemove(boolean confirmRemove) { this.confirmRemove = confirmRemove; if (confirmRemove) setSessionForm(true); } public final void setConfirmUpdate(boolean confirmUpdate) { this.confirmUpdate = confirmUpdate; if (confirmUpdate) setSessionForm(true); } }