protected void storeImage(MasterImageMetaData mimd, MultipartFile mpFile) {
    try {
      InputStream imageStream = mpFile.getInputStream();
      log.debug("storeImage: uploaded a multipart file -- filename: " + FILE_UPLOAD_FIELD);

      ImageData imageData = imageResizeMgr.generateImage(imageStream, null, null);
      log.debug("storeImage: file name is: " + mpFile.getOriginalFilename());
      imageData.setFilename(mpFile.getOriginalFilename());

      // Store the image in the cache
      String imageKey = imageCacheManager.addImage(imageData);

      // Uploading a new image
      if (imageKey != mimd.getImageKey()) {
        // Then clear out the previous sized images and their data
        mimd.clearSizedImages();
      }

      // Add the image key and data to the Master Image
      mimd.setImageKey(imageKey);
      mimd.setMetaData(imageData);
    } catch (Exception e) {
      log.debug(
          "storeImage: An exception was caught in storeImage: No inputStream found because no file was uploaded.",
          e.fillInStackTrace());
    }
  }
  @Override
  protected Map<String, Object> referenceData(
      HttpServletRequest request, Object command, Errors errors, int page) throws Exception {
    UserSessionData usd = getUserSessionData(request);
    Map<String, Object> referenceData = new HashMap<String, Object>();
    int currentPage = getCurrentPage(request);

    log.debug("referenceData: Current page in refData " + currentPage);

    referenceData.put("dirtyFlag", usd.isDirty() ? "true" : "false");
    referenceData.put("ImageUrlBuilder", urlBuilder);
    referenceData.put("allSizes", imageSizeDefMgr.getAllImageSizes());
    referenceData.put("page", currentPage);

    MasterImageMetaData mimd = usd.getMimd();

    if (usd.getPages() == null) {
      log.debug("referenceData: no pages defined yet");
      setPagesDynamically(request, null);
    }
    int pageCount = usd.getPages().length;
    log.debug("Page count is " + pageCount);
    referenceData.put("pagecount", pageCount);

    if (currentPage == 0) {
      String sizedDivStyle = "none";
      if (StringUtils.isNotBlank(mimd.getImageKey())) {
        sizedDivStyle = "block";
      }
      referenceData.put("sizedDivStyle", sizedDivStyle);
      referenceData.put("allDisplaySizes", buildAllSizesList(mimd));
      referenceData.put("metadata", buildMasterImageDisplay(mimd));
    }

    if (currentPage > 0 && currentPage < getPageCount(request, command) - 1) {
      SizedImageMetaData simd = getCurrentSizedImage(mimd, currentPage - 1);
      referenceData.put("SizedImage", simd);
      Map<String, String> cropbox = buildCropBox(simd);
      referenceData.put("cropbox", cropbox);
      ImageSizeDefinition isd = simd.getSizeDefinition();
      referenceData.put("sizecode", isd.getCode());
      referenceData.put("sizelabel", isd.getLabel());
      referenceData.put("definedHeight", isd.getHeight());
      referenceData.put("definedWidth", isd.getWidth());

      Map<String, String> displayImage = buildDisplayImage(usd);
      referenceData.put("displayImage", displayImage);

    } else if (currentPage == getPageCount(request, command) - 1) { // this is the confirm page.

      Map<String, String> displayImage = buildDisplayImage(usd);
      referenceData.put("displayImage", displayImage);
      List<Map<String, String>> sizedImagesDisplay =
          buildAllSizedImagesDisplay(mimd.getSizedImages());
      referenceData.put("sizedImages", sizedImagesDisplay);
    }

    return referenceData;
  }
 protected SimpleImageMetaData createScaledImage(MasterImageMetaData mimd, double scaleFactor)
     throws Exception {
   ImageMetaData imageData = mimd.getMetaData();
   SimpleImageMetaData output = new SimpleImageMetaData();
   long height = Math.round(imageData.getHeight() / scaleFactor);
   long width = Math.round(imageData.getWidth() / scaleFactor);
   Dimension dim = new Dimension(new Long(width).intValue(), new Long(height).intValue());
   resizeSimpleImage(output, mimd.getImageKey(), null, dim);
   return output;
 }
  @Override
  protected ModelAndView processFinish(
      HttpServletRequest request,
      HttpServletResponse response,
      Object command,
      BindException errors)
      throws Exception {
    log.debug("processFinish: Save the Rx content item.");
    String contentid = request.getParameter(IPSHtmlParameters.SYS_CONTENTID);
    log.debug("processFinish: content id is " + contentid);
    String folderid = request.getParameter(IPSHtmlParameters.SYS_FOLDERID);
    log.debug("processFinish: folder id is " + folderid);
    String actionParam = request.getParameter("action");
    log.debug("processFinish: action is " + actionParam);

    Boolean closeWindow = new Boolean(false);

    UserSessionData usd = getUserSessionData(request);
    MasterImageMetaData mimd = usd.getMimd();

    String user = RxRequestUtils.getUserName(request);
    log.debug("processFinish: user is " + user);
    String session = RxRequestUtils.getSessionId(request);
    log.debug("processFinish: session is " + session);

    // remove any empty images (this can happen if the user
    // presses "finish" part way through the process).
    Map<String, SizedImageMetaData> sized = mimd.getSizedImages();
    mimd.setSizedImages(cleanEmptySizedImages(sized));

    if (StringUtils.isNotBlank(contentid)) {
      imagePersistenceManager.UpdateImage(mimd, contentid, null, session, user);
      log.debug("processFinish: mimd persisted to existing Rx item: " + contentid);
    } else {
      if (StringUtils.isBlank(folderid)) folderid = null;

      contentid = imagePersistenceManager.CreateImage(mimd, folderid, false, session, user);
      log.debug("processFinish: the contentid of the new item is: " + contentid);
    }
    // everything is saved now...
    usd.setDirty(false);
    String redirectUrl = "imageeditor?sys_contentid=" + contentid + "&sys_folderid=" + folderid;
    ModelAndView mav = new ModelAndView("results");
    mav.addObject("image", command);
    if (actionParam.equalsIgnoreCase("close")) {
      log.debug("processFinish: closing window");
      redirectUrl = "";
      closeWindow = new Boolean(true);
    }
    mav.addObject("redirectUrl", redirectUrl);
    mav.addObject("closeWindow", closeWindow);
    mav.addObject("contentid", contentid);
    return mav;
  }
  protected Map<String, String> buildMasterImageDisplay(MasterImageMetaData mimd) {
    ImageMetaData md = mimd.getMetaData();
    Map<String, String> masterData = new HashMap<String, String>();
    masterData.put("filename", md.getFilename());
    masterData.put("ext", md.getExt());
    masterData.put("mimetype", md.getMimeType());
    masterData.put("size", String.valueOf(md.getSize()));
    masterData.put("height", String.valueOf(md.getHeight()));
    masterData.put("width", String.valueOf(md.getWidth()));
    String url = this.urlBuilder.buildUrl(mimd.getImageKey());
    masterData.put("url", url);

    return masterData;
  }
  public UserSessionData getUserSessionData(HttpServletRequest request) {
    UserSessionData usd = (UserSessionData) request.getSession().getAttribute("userData");
    if (usd == null) {
      log.debug("getUserSessionData: creating new USD...");

      usd = new UserSessionData();
      MasterImageMetaData mimd = new MasterImageMetaData();
      ImageMetaData imd = new ImageMetaData();
      mimd.setMetaData(imd);

      usd.setMimd(mimd);

      request.getSession().setAttribute("userData", usd);
      log.debug("getUserSessionData: setting usd attribute");
    }

    return usd;
  }
  @Override
  protected void postProcessPage(
      HttpServletRequest request, Object command, Errors errors, int page) throws Exception {
    UserSessionData usd = getUserSessionData(request);
    MasterImageMetaData mimd = usd.getMimd();

    if (page == 0) {
      log.debug("postProcessPage: processing main page");
      if (mimd.getMetaData().getSize() == 0L) {
        log.info("no image uploaded");
        errors.reject("master.image.missing");
      }
      if (mimd.getSizedImages().isEmpty()) {
        log.info("no image sizes selected");
        errors.reject("no.image.sizes.selected");
      }
    }
  }
 protected void setupDisplayImage(MasterImageMetaData mimd, UserSessionData usd) throws Exception {
   log.debug(
       "height is "
           + mimd.getMetaData().getHeight()
           + " width is "
           + mimd.getMetaData().getWidth());
   double scalefactor =
       computeScaleFactor(mimd.getMetaData().getHeight(), mimd.getMetaData().getWidth());
   log.debug("Scale Factor is  " + scalefactor);
   usd.setScaleFactor(scalefactor);
   SimpleImageMetaData displayImage;
   if (scalefactor > 1.0) { // the image must be resized.
     displayImage = createScaledImage(mimd, scalefactor);
     log.debug("Display image is " + displayImage);
   } else {
     displayImage = new SimpleImageMetaData(mimd);
   }
   usd.setDisplayImage(displayImage);
 }
  protected List<Map<String, String>> buildAllSizesList(MasterImageMetaData mimd) {
    List<Map<String, String>> allSizes = new ArrayList<Map<String, String>>();
    Map<String, SizedImageMetaData> sizedImages = mimd.getSizedImages();

    for (ImageSizeDefinition size : imageSizeDefMgr.getAllImageSizes()) {
      Map<String, String> sizeData = new HashMap<String, String>();
      sizeData.put("code", size.getCode());
      sizeData.put("label", size.getLabel());
      if (sizedImages.containsKey(size.getCode())) {
        sizeData.put("checked", "checked");
      }
      allSizes.add(sizeData);
    }

    return allSizes;
  }
  protected Map<String, String> buildDisplayImage(UserSessionData usd) {
    MasterImageMetaData mimd = usd.getMimd();
    Map<String, String> displayImage = new HashMap<String, String>();
    displayImage.put("title", mimd.getDisplayTitle());
    displayImage.put("alt", mimd.getAlt());
    String url;
    if (usd.getDisplayImage() != null) {
      displayImage.put("height", String.valueOf(usd.getDisplayImage().getHeight()));
      displayImage.put("width", String.valueOf(usd.getDisplayImage().getWidth()));
      url = this.urlBuilder.buildUrl(usd.getDisplayImage().getImageKey());
      displayImage.put("url", url);
    } else {
      displayImage.put("height", String.valueOf(mimd.getMetaData().getHeight()));
      displayImage.put("width", String.valueOf(mimd.getMetaData().getWidth()));
      url = this.urlBuilder.buildUrl(mimd.getImageKey());
      displayImage.put("url", url);
    }

    return displayImage;
  }
  @Override
  protected Object formBackingObject(HttpServletRequest request) throws Exception {
    Object cmd = "Exists";

    String openImed = request.getParameter("openImed");
    log.debug("formBackingObject: openImed is: " + openImed);

    if (openImed != null) {
      if (openImed.equals("true")) {
        cmd = null;
        setUserSessionData(request, null);
        log.debug("formBackingObject: set cmd to null and cleared USD");
      }
    }

    // log.debug("in the form backing object with page " + getCurrentPage(request));
    String contentid = request.getParameter(IPSHtmlParameters.SYS_CONTENTID);
    log.debug("formBackingObject: The contentid is: " + contentid);

    if (StringUtils.isBlank(contentid)) {

      log.debug("formBackingObject: cmd is: " + cmd);
      try {
        log.debug(
            "formBackingObject: attempting to get command, if it doesn't exist, catch error and return new");
        Object command = getCommand(request);

        log.debug("formBackingObject: command exists");
        if (cmd == null) {
          log.debug("formBackingObject: opening from Action Menu, returning new");
          return new ImageBean();
        }
        if (command != null) {
          log.debug("formBackingObject: navigating, so using same command");
          return command;
        }
        log.debug(
            "formBackingObject: not coming from Action Menu, but command null? returning new");
        return new ImageBean();
      } catch (HttpSessionRequiredException hsre) {
        log.debug(
            "formBackingObject: info - Command does not exist yet, need to create it, continuing");
      }

      return new ImageBean();
    }
    // Found a content id, so load the item.
    log.debug("formBackingObject: found contentid [id:" + contentid + "]");
    String user = RxRequestUtils.getUserName(request);
    log.debug("formBackingObject: user is " + user);
    String session = RxRequestUtils.getSessionId(request);
    log.debug("formBackingObject: session is " + session);

    if (StringUtils.isNotBlank(contentid) && contentid != null) {
      log.debug("formBackingObject: contentid is not blank, going to open the image...");
      OpenImageResult oir = imagePersistenceManager.OpenImage(contentid, session, user);
      log.debug("formBackingObject: ItemStatus is  " + oir.getItemStatus());

      MasterImageMetaData mimd = oir.getMasterImage();
      log.info("formBackingObject: masterimage " + mimd);

      UserSessionData usd = getUserSessionData(request);
      usd.setMimd(mimd);
      setupDisplayImage(mimd, usd);

      ImageBean ib = new ImageBean();
      ib.setSysTitle(mimd.getSysTitle());
      ib.setDescription(mimd.getDescription());
      ib.setAlt(mimd.getAlt());
      ib.setDisplayTitle(mimd.getDisplayTitle());

      String sizedImages = null;
      Iterator<SizedImageMetaData> simds = mimd.getSizedImages().values().iterator();
      while (simds.hasNext()) {
        SizedImageMetaData simd = simds.next();
        ImageSizeDefinition isd = simd.getSizeDefinition();
        String code = isd.getCode();
        sizedImages += code;
        if (simds.hasNext()) sizedImages += ",";

        // testing to ensure simds have x,y,w,h
        log.debug(
            "formBackingObject: simd ["
                + code
                + "]: x -> "
                + simd.getX()
                + " == y -> "
                + simd.getY());
      }

      ib.setSizedImages(sizedImages);
      setUserSessionData(request, usd);
      setPagesDynamically(request, sizedImages);

      return ib;
    }
    log.debug("formBackingObject: contentid is blank, so creating a new item / imagebean");
    return new ImageBean();
  }
 protected SizedImageMetaData getCurrentSizedImage(MasterImageMetaData mimd, int currPage) {
   log.debug("getCurrentSizedImage: creating array of size: " + mimd.getSizedImages().size());
   List<SizedImageMetaData> simds =
       new ArrayList<SizedImageMetaData>(mimd.getSizedImages().values());
   return simds.get(currPage);
 }
  public void setupSizedImages(
      HttpServletRequest request, String sizedImages, MasterImageMetaData mimd) {
    Collection<SizedImageMetaData> simds = mimd.getSizedImages().values();

    UserSessionData usd = getUserSessionData(request);
    if (!StringUtils.isBlank(sizedImages)) {
      log.debug("setupSizedImages: Handling the sized images...");
      // Images have been selected and we didn't have any images stored previously
      String[] sizedImagesArray = sizedImages.split(",");
      log.debug(
          "setupSizedImages: the bean has " + sizedImagesArray.length + " sized image(s) selected");

      if (simds.size() == 0) {
        log.debug("setupSizedImages: no simds were previously defined");
        for (int x = 1; x <= sizedImagesArray.length; x++) {
          SizedImageMetaData simd = new SizedImageMetaData();
          ImageSizeDefinition isd = imageSizeDefMgr.getImageSize(sizedImagesArray[x - 1]);
          simd.setSizeDefinition(isd);
          mimd.addSizedImage(simd);
          log.debug("setupSizedImages: adding new image size " + isd.getLabel());
          usd.setDirty(true);
        }

      } else
      // Images have been selected and there were others stored previously
      {
        log.debug("setupSizedImages: simds have been previously defined");

        Map<String, SizedImageMetaData> previousSimds = mimd.getSizedImages();
        Map<String, SizedImageMetaData> newSimds = new HashMap<String, SizedImageMetaData>();

        for (int x = 0; x < sizedImagesArray.length; x++) {
          SizedImageMetaData simd = null;

          String key = sizedImagesArray[x];
          if (previousSimds.containsKey(key)) {
            simd = previousSimds.get(key);
            log.debug(
                "setupSizedImages: Image of type ["
                    + key
                    + "] previously chosen, re-using existing one");
            previousSimds.remove(key);
          } else {
            simd = new SizedImageMetaData();
            ImageSizeDefinition isd = imageSizeDefMgr.getImageSize(key);
            simd.setSizeDefinition(isd);
            log.debug(
                "setupSizedImages: Image of type ["
                    + key
                    + "] not previously chosen, created a new one");
            usd.setDirty(true);
          }
          newSimds.put(simd.getSizeDefinition().getCode(), simd);
        }
        mimd.setSizedImages(newSimds);
        if (previousSimds.size() > 0) { // some SIMDs were "left over", something has changed.
          usd.setDirty(true);
        }
      }

      log.debug("setupSizedImages: Sized Images in MIMD: " + mimd.getSizedImages().size());
    } else {
      if (simds.size() > 0) {
        log.debug(
            "setupSizedImages: There were sized images selected, but none have been selected now, so clearing out sized images");
        mimd.setSizedImages(new LinkedHashMap<String, SizedImageMetaData>());
        usd.setDirty(true);
      }
    }
  }
  @Override
  protected void onBind(HttpServletRequest request, Object command, BindException errors)
      throws Exception {
    log.debug("onBind: doing onBind...");
    UserSessionData usd = getUserSessionData(request);
    MasterImageMetaData mimd = usd.getMimd();

    ImageBean ib = (ImageBean) command;

    if (mimd == null) {
      log.error("onBind: mimd attribute is not set in session.");
    } else {
      int currentPage = getCurrentPage(request);

      if (request instanceof MultipartHttpServletRequest) {
        MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
        MultipartFile mpFile = mRequest.getFile(FILE_UPLOAD_FIELD);

        String action = request.getParameter("action");
        log.debug("onBind: the action is: " + action);

        if (mpFile.isEmpty() && StringUtils.isBlank(action)) {
          log.debug("onBind: nothing has been uploaded - not storing image...");
        } else if (mpFile.isEmpty() && action.equals("cleared")) {
          log.debug(
              "onBind: nothing has been uploaded and something has been cleared - clearing stored image if any...");
          mimd.setImageKey(null);
          mimd.setMetaData(null);
          mimd.clearSizedImages();
          usd.setDirty(true); // clearing the file always sets dirty.
        } else {
          log.debug(
              "onBind: the original name of the file being uploaded is: "
                  + mpFile.getOriginalFilename());
          storeImage(mimd, mpFile);
          setupDisplayImage(mimd, usd);
          usd.setDirty(true); // uploaded files are always dirty.
        }

        mimd.setAlt(ib.getAlt());
        mimd.setDescription(ib.getDescription());
        mimd.setDisplayTitle(ib.getDisplayTitle());
        mimd.setSysTitle(ib.getSysTitle());
      }
      // set the dirty flag if the form is dirty or the session is already dirty.
      usd.setDirty(usd.isDirty() || ib.isDirty());
      log.debug("onBind: The dirty flag is " + usd.isDirty());

      log.debug(
          "onBind: There are "
              + getPageCount(request, command)
              + " pages. -- currently on page "
              + getCurrentPage(request));

      log.debug("onBind: current Page is " + currentPage);
      // Figure out how many pages you will need to go through
      if (currentPage == 0) {
        String contentId = request.getParameter("sys_contentid");
        String folderId = request.getParameter("sys_folderid");
        String sessionId = RxRequestUtils.getSessionId(request);
        String username = request.getRemoteUser();
        if (StringUtils.isBlank(contentId)
            && StringUtils.isNotBlank(folderId)
            && StringUtils.isNotBlank(ib.getSysTitle())) {
          boolean bval =
              imagePersistenceManager.validateSystemTitleUnique(
                  ib.getSysTitle(), folderId, sessionId, username);
          if (!bval) {
            log.info("system title is not unique in folder " + ib.getSysTitle());
            errors.rejectValue(
                "sysTitle",
                "title.not.unique",
                new String[] {ib.getSysTitle()},
                "System Title is not unique in the specified folder.");
          }
        }

        log.debug("onBind: ib.getSizedImages(): " + ib.getSizedImages());
        setPagesDynamically(request, ib.getSizedImages());
        setupSizedImages(request, ib.getSizedImages(), mimd);
      }

      if (currentPage > 0 && currentPage < getPageCount(request, command) - 1) {
        log.debug("onBind: dealing with binding data for page " + currentPage);

        SizedImageMetaData simd = getCurrentSizedImage(mimd, currentPage - 1);
        ImageSizeDefinition isd = simd.getSizeDefinition();
        if (ib.getX() == 0
            && ib.getY() == 0
            && ib.getWidth() == 0
            && ib.getHeight() == 0) { // ignore this request, it was likely caused by a refresh...
          log.debug("No crop box data present, skipping this request");
          return;
        }
        // can't do this on the client side because MSIE cannot detect change events.
        if (!usd.isDirty()) { // not already dirty, so we must check to see if the box has changed
          if (simd.getX() != ib.getX()
              || simd.getY() != ib.getY()
              || simd.getHeight() != ib.getHeight()
              || simd.getWidth() != ib.getWidth()) {
            usd.setDirty(true);
          }
        }

        Rectangle cropBox = new Rectangle(ib.getX(), ib.getY(), ib.getWidth(), ib.getHeight());
        double scaleFactor = usd.getScaleFactor();
        if (scaleFactor > 1.0) {
          log.debug("scaling crop box " + scaleFactor);
          ImageMetaData imd = mimd.getMetaData();
          cropBox =
              scaledRectangle(cropBox, scaleFactor, new Dimension(imd.getWidth(), imd.getHeight()));
          log.debug("new crop box is " + cropBox);
        }
        Dimension size = new Dimension(isd.getWidth(), isd.getHeight());

        resizeSimpleImage(simd, mimd.getImageKey(), cropBox, size);
        simd.setX(ib.getX());
        simd.setY(ib.getY());
        simd.setHeight(ib.getHeight());
        simd.setWidth(ib.getWidth());

        Boolean constraint = ib.isConstraint();
        log.debug("constraint from ib: " + constraint);
        log.debug("request constraint: " + request.getParameter("constraint"));
        if (constraint == null) simd.setConstraint(false);
        else if (constraint.booleanValue()) simd.setConstraint(constraint);

      } else log.debug("onBind: page is not > 0 or < " + (getPageCount(request, command) - 1));
    }

    log.debug("onBind: END");
  }