/** Hooks into populate process to call form populate method if form is an instanceof PojoForm. */
  @Override
  protected void processPopulate(
      HttpServletRequest request,
      HttpServletResponse response,
      ActionForm form,
      ActionMapping mapping)
      throws ServletException {
    if (form instanceof KualiForm) {
      // Add the ActionForm to GlobalVariables
      // This will allow developers to retrieve both the Document and any
      // request parameters that are not
      // part of the Form and make them available in ValueFinder classes
      // and other places where they are needed.
      KNSGlobalVariables.setKualiForm((KualiForm) form);
    }

    // if not PojoForm, call struts populate
    if (!(form instanceof PojoForm)) {
      super.processPopulate(request, response, form, mapping);
      return;
    }

    final String previousRequestGuid =
        request.getParameter(
            KualiRequestProcessor.PREVIOUS_REQUEST_EDITABLE_PROPERTIES_GUID_PARAMETER_NAME);

    ((PojoForm) form).clearEditablePropertyInformation();
    ((PojoForm) form).registerStrutsActionMappingScope(mapping.getScope());

    String multipart = mapping.getMultipartClass();
    if (multipart != null) {
      request.setAttribute(Globals.MULTIPART_KEY, multipart);
    }

    form.setServlet(this.servlet);
    form.reset(mapping, request);

    ((PojoForm) form).setPopulateEditablePropertiesGuid(previousRequestGuid);
    // call populate on ActionForm
    ((PojoForm) form).populate(request);
    request.setAttribute("UnconvertedValues", ((PojoForm) form).getUnconvertedValues().keySet());
    request.setAttribute("UnconvertedHash", ((PojoForm) form).getUnconvertedValues());
  }
 /** @see org.apache.struts.taglib.html.SelectTag#doEndTag() */
 public int doEndTag() throws JspException {
   int returnVal = super.doEndTag();
   if (!getDisabled() && !getReadonly()) {
     String name = prepareName();
     if (StringUtils.isNotBlank(name)) {
       ActionForm form = WebUtils.getKualiForm(pageContext);
       if (form != null && form instanceof PojoForm) {
         ((PojoForm) form).registerEditableProperty(name);
       }
     }
   }
   return returnVal;
 }
  /**
   * Hook into action perform to handle errors in the error map and catch exceptions.
   *
   * <p>A transaction is started prior to the execution of the action. This allows for the action
   * code to execute efficiently without the need for using PROPAGATION_SUPPORTS in the transaction
   * definitions. The PROPAGATION_SUPPORTS propagation type does not work well with JTA.
   */
  @Override
  protected ActionForward processActionPerform(
      final HttpServletRequest request,
      final HttpServletResponse response,
      final Action action,
      final ActionForm form,
      final ActionMapping mapping)
      throws IOException, ServletException {
    try {
      TransactionTemplate template = new TransactionTemplate(getTransactionManager());
      ActionForward forward = null;
      try {
        forward =
            (ActionForward)
                template.execute(
                    new TransactionCallback() {
                      public Object doInTransaction(TransactionStatus status) {
                        ActionForward actionForward = null;
                        try {
                          actionForward = action.execute(mapping, form, request, response);
                        } catch (Exception e) {
                          if (e.getMessage() != null
                              && e.getMessage()
                                  .equals(KRADConstants.KRAD_INITIATED_DOCUMENT_VIEW_NAME)) {
                            ConfigurationService kualiConfigurationService =
                                CoreApiServiceLocator.getKualiConfigurationService();
                            StringBuffer sb = new StringBuffer();
                            sb.append(
                                kualiConfigurationService.getPropertyValueAsString(
                                    KRADConstants.KRAD_URL_KEY));
                            sb.append(
                                kualiConfigurationService.getPropertyValueAsString(
                                    KRADConstants.KRAD_INITIATED_DOCUMENT_URL_KEY));
                            return new ActionForward(
                                KRADConstants.KRAD_INITIATED_DOCUMENT_VIEW_NAME,
                                sb.toString(),
                                true);
                          }
                          // the doInTransaction method has no means for
                          // throwing exceptions, so we will wrap the
                          // exception in
                          // a RuntimeException and re-throw. The one caveat
                          // here is that this will always result in
                          // the
                          // transaction being rolled back (since
                          // WrappedRuntimeException is a runtime exception).
                          throw new WrappedRuntimeException(e);
                        }
                        if (status.isRollbackOnly()) {
                          // this means that the struts action execution
                          // caused the transaction to rollback, we want to
                          // go ahead
                          // and trigger the rollback by throwing an exception
                          // here but then return the action forward
                          // from this method
                          throw new WrappedActionForwardRuntimeException(actionForward);
                        }
                        return actionForward;
                      }
                    });
      } catch (WrappedActionForwardRuntimeException e) {
        forward = e.getActionForward();
      }

      publishMessages(request);
      saveMessages(request);
      saveAuditErrors(request);

      if (form instanceof PojoForm) {
        if (((PojoForm) form).getEditableProperties() == null
            || ((PojoForm) form).getEditableProperties().isEmpty()) {
          EditablePropertiesHistoryHolder holder =
              (EditablePropertiesHistoryHolder)
                  GlobalVariables.getUserSession()
                      .getObjectMap()
                      .get(KRADConstants.EDITABLE_PROPERTIES_HISTORY_HOLDER_ATTR_NAME);
          if (holder == null) {
            holder = new EditablePropertiesHistoryHolder();
          }

          final String guid =
              holder.addEditablePropertiesToHistory(((PojoForm) form).getEditableProperties());
          ((PojoForm) form).setActionEditablePropertiesGuid(guid);
          GlobalVariables.getUserSession()
              .addObject(KRADConstants.EDITABLE_PROPERTIES_HISTORY_HOLDER_ATTR_NAME, holder);
        }
      }

      return forward;

    } catch (Exception e) {
      if (e instanceof WrappedRuntimeException) {
        e = (Exception) e.getCause();
      }
      if (e instanceof ValidationException) {
        // add a generic error message if there are none
        if (GlobalVariables.getMessageMap().hasNoErrors()) {

          GlobalVariables.getMessageMap()
              .putError(KRADConstants.GLOBAL_ERRORS, RiceKeyConstants.ERROR_CUSTOM, e.getMessage());
        }

        if (form instanceof PojoForm) {
          if (((PojoForm) form).getEditableProperties() == null
              || ((PojoForm) form).getEditableProperties().isEmpty()) {
            EditablePropertiesHistoryHolder holder =
                (EditablePropertiesHistoryHolder)
                    GlobalVariables.getUserSession()
                        .getObjectMap()
                        .get(KRADConstants.EDITABLE_PROPERTIES_HISTORY_HOLDER_ATTR_NAME);
            if (holder == null) {
              holder = new EditablePropertiesHistoryHolder();
            }

            final String guid =
                holder.addEditablePropertiesToHistory(((PojoForm) form).getEditableProperties());
            ((PojoForm) form).setActionEditablePropertiesGuid(guid);
            GlobalVariables.getUserSession()
                .addObject(KRADConstants.EDITABLE_PROPERTIES_HISTORY_HOLDER_ATTR_NAME, holder);
          }
        }
        // display error messages and return to originating page
        publishMessages(request);
        return mapping.findForward(RiceConstants.MAPPING_BASIC);
      }

      publishMessages(request);

      return (processException(request, response, e, form, mapping));
    }
  }
  /**
   * Hooks into validate to catch any errors from the populate, and translate the ErrorMap to
   * ActionMessages.
   */
  @Override
  protected boolean processValidate(
      HttpServletRequest request,
      HttpServletResponse response,
      ActionForm form,
      ActionMapping mapping)
      throws IOException, ServletException, InvalidCancelException {

    // skip form validate if we had errors from populate
    if (GlobalVariables.getMessageMap().hasNoErrors()) {
      if (form == null) {
        return (true);
      }
      // Was this request cancelled?
      if (request.getAttribute(Globals.CANCEL_KEY) != null) {
        if (LOG.isDebugEnabled()) {
          LOG.debug(" Cancelled transaction, skipping validation");
        }
        return (true);
      }

      // Has validation been turned off for this mapping?
      if (!mapping.getValidate()) {
        return (true);
      }

      // call super to call forms validate
      super.processValidate(request, response, form, mapping);
    }

    publishMessages(request);
    if (!GlobalVariables.getMessageMap().hasNoErrors()) {
      // Special handling for multipart request
      if (form.getMultipartRequestHandler() != null) {
        if (LOG.isDebugEnabled()) {
          LOG.debug("  Rolling back multipart request");
        }
        form.getMultipartRequestHandler().rollback();
      }

      // Fix state that could be incorrect because of validation failure
      if (form instanceof PojoForm) {
        ((PojoForm) form).processValidationFail();
      }

      // Was an input path (or forward) specified for this mapping?
      String input = mapping.getInput();
      if (input == null) {
        if (LOG.isDebugEnabled()) {
          LOG.debug("  Validation failed but no input form available");
        }
        response.sendError(
            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
            getInternal().getMessage("noInput", mapping.getPath()));
        return (false);
      }

      if (moduleConfig.getControllerConfig().getInputForward()) {
        ForwardConfig forward = mapping.findForward(input);
        processForwardConfig(request, response, forward);
      } else {
        internalModuleRelativeForward(input, request, response);
      }

      return (false);
    }
    return true;
  }