/** This method is called when the {@link SizeLimitExceededException} was thrown. */
 protected void reportSizeLimitExceeded(final SizeLimitExceededException e, Validator validator) {
   validator.add(
       new I18nMessage("upload", "file.limit.exceeded", e.getActualSize(), e.getPermittedSize()));
   logger.warn(
       "The file size limit was exceeded. Actual {} permitted {}",
       e.getActualSize(),
       e.getPermittedSize());
 }
  /**
   * This method parses the submit action, puts in session a listener where the progress status is
   * updated, and eventually stores the received data in the user session.
   *
   * <p>returns null in the case of success or a string with the error
   */
  @SuppressWarnings("unchecked")
  protected String parsePostRequest(HttpServletRequest request, HttpServletResponse response) {

    try {
      String delay = request.getParameter("delay");
      uploadDelay = Integer.parseInt(delay);
    } catch (Exception e) {
    }

    HttpSession session = request.getSession();

    logger.debug("UPLOAD-SERVLET (" + session.getId() + ") new upload request received.");

    AbstractUploadListener listener = getCurrentListener(request);
    if (listener != null) {
      if (listener.isFrozen() || listener.isCanceled() || listener.getPercent() >= 100) {
        removeCurrentListener(request);
      } else {
        String error = getMessage("busy");
        logger.error("UPLOAD-SERVLET (" + session.getId() + ") " + error);
        return error;
      }
    }
    // Create a file upload progress listener, and put it in the user session,
    // so the browser can use ajax to query status of the upload process
    listener = createNewListener(request);

    List<FileItem> uploadedItems;
    try {

      // Call to a method which the user can override
      checkRequest(request);

      // Create the factory used for uploading files,
      FileItemFactory factory = getFileItemFactory(request.getContentLength());
      ServletFileUpload uploader = new ServletFileUpload(factory);
      uploader.setSizeMax(maxSize);
      uploader.setProgressListener(listener);

      // Receive the files
      logger.debug("UPLOAD-SERVLET (" + session.getId() + ") parsing HTTP POST request ");
      uploadedItems = uploader.parseRequest(request);
      logger.debug(
          "UPLOAD-SERVLET ("
              + session.getId()
              + ") parsed request, "
              + uploadedItems.size()
              + " items received.");

      // Received files are put in session
      Vector<FileItem> sessionFiles = (Vector<FileItem>) getSessionFileItems(request);
      if (sessionFiles == null) {
        sessionFiles = new Vector<FileItem>();
      }

      String error = "";
      session.setAttribute(ATTR_LAST_FILES, uploadedItems);

      if (uploadedItems.size() > 0) {
        sessionFiles.addAll(uploadedItems);
        String msg = "";
        for (FileItem i : sessionFiles) {
          msg += i.getFieldName() + " => " + i.getName() + "(" + i.getSize() + " bytes),";
        }
        logger.debug("UPLOAD-SERVLET (" + session.getId() + ") puting items in session: " + msg);
        session.setAttribute(ATTR_FILES, sessionFiles);
      } else {
        logger.error("UPLOAD-SERVLET (" + session.getId() + ") error NO DATA received ");
        error += getMessage("no_data");
      }

      return error.length() > 0 ? error : null;

    } catch (SizeLimitExceededException e) {
      RuntimeException ex = new UploadSizeLimitException(e.getPermittedSize(), e.getActualSize());
      listener.setException(ex);
      throw ex;
    } catch (UploadSizeLimitException e) {
      listener.setException(e);
      throw e;
    } catch (UploadCanceledException e) {
      listener.setException(e);
      throw e;
    } catch (UploadTimeoutException e) {
      listener.setException(e);
      throw e;
    } catch (Exception e) {
      logger.error(
          "UPLOAD-SERVLET ("
              + request.getSession().getId()
              + ") Unexpected Exception -> "
              + e.getMessage()
              + "\n"
              + stackTraceToString(e));
      e.printStackTrace();
      RuntimeException ex = new UploadException(e);
      listener.setException(ex);
      throw ex;
    }
  }