public JSONObject changePlateLocation(HttpSession session, JSONObject json) {
    Long plateId = json.getLong("plateId");
    String locationBarcode = json.getString("locationBarcode");

    try {
      String newLocation = LimsUtils.lookupLocation(locationBarcode);
      if (newLocation != null) {
        User user =
            securityManager.getUserByLoginName(
                SecurityContextHolder.getContext().getAuthentication().getName());
        // Plate<LinkedList<Plateable>, Plateable> plate = requestManager.<LinkedList<Plateable>,
        // Plateable> getPlateById(plateId);
        Plate<? extends List<? extends Plateable>, ? extends Plateable> plate =
            requestManager.getPlateById(plateId);
        plate.setLocationBarcode(locationBarcode);
        /*
        Note note = new Note();
        note.setInternalOnly(true);
        note.setText("Location changed to " + newLocation + " by " + user.getLoginName() + " on " + new Date());
        note.setOwner(user);
        note.setCreationDate(new Date());
        plate.getNotes().add(note);
        requestManager.saveSampleNote(sample, note);
        */
        requestManager.savePlate(plate);
      } else {
        return JSONUtils.SimpleJSONError("New location barcode not recognised");
      }
    } catch (IOException e) {
      e.printStackTrace();
      return JSONUtils.SimpleJSONError(e.getMessage());
    }

    return JSONUtils.SimpleJSONResponse("Plate saved successfully");
  }
  public JSONObject plateElementsDataTable(HttpSession session, JSONObject json) {
    if (json.has("plateId")) {
      try {
        JSONObject j = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        long plateId = json.getLong("plateId");

        Plate<? extends List<? extends Plateable>, ? extends Plateable> plate =
            requestManager.getPlateById(plateId);
        if (plate != null) {
          for (Plateable p : plate.getElements()) {
            if (p instanceof Library) {
              Library l = (Library) p;
              String strategyName = "No barcode";

              StringBuilder seqbuilder = new StringBuilder();
              if (!l.getTagBarcodes().isEmpty()) {
                int count = 1;
                Collection<TagBarcode> barcodes = l.getTagBarcodes().values();
                for (TagBarcode tb : barcodes) {
                  strategyName = tb.getStrategyName();
                  seqbuilder.append(tb.getSequence());
                  if (l.getTagBarcodes().values().size() > 1
                      && count < l.getTagBarcodes().values().size()) {
                    seqbuilder.append("-");
                  }
                  count++;
                }
              } else {
                log.info("No tag barcodes!");
              }

              jsonArray.add(
                  "['"
                      + l.getName()
                      + "','"
                      + l.getAlias()
                      + "','"
                      + strategyName
                      + "','"
                      + seqbuilder.toString()
                      + "','"
                      + "<a href=\"/miso/library/"
                      + l.getId()
                      + "\"><span class=\"ui-icon ui-icon-pencil\"></span></a>"
                      + "']");
            }
          }
        }
        j.put("elementsArray", jsonArray);
        return j;
      } catch (IOException e) {
        log.debug("Failed", e);
        return JSONUtils.SimpleJSONError("Failed: " + e.getMessage());
      }
    } else {
      return JSONUtils.SimpleJSONError("No plates to show");
    }
  }
  public JSONObject printPlateBarcodes(HttpSession session, JSONObject json) {
    try {
      User user =
          securityManager.getUserByLoginName(
              SecurityContextHolder.getContext().getAuthentication().getName());

      String serviceName = null;
      if (json.has("serviceName")) {
        serviceName = json.getString("serviceName");
      }

      MisoPrintService<File, PrintContext<File>> mps = null;
      if (serviceName == null) {
        Collection<MisoPrintService> services =
            printManager.listPrintServicesByBarcodeableClass(Plate.class);
        if (services.size() == 1) {
          mps = services.iterator().next();
        } else {
          return JSONUtils.SimpleJSONError(
              "No serviceName specified, but more than one available service able to print this barcode type.");
        }
      } else {
        mps = printManager.getPrintService(serviceName);
      }

      Queue<File> thingsToPrint = new LinkedList<File>();
      JSONArray ss = JSONArray.fromObject(json.getString("plates"));
      for (JSONObject s : (Iterable<JSONObject>) ss) {
        try {
          Long plateId = s.getLong("plateId");
          // Plate<LinkedList<Plateable>, Plateable>  plate = requestManager.<LinkedList<Plateable>,
          // Plateable> getPlateById(plateId);
          Plate<? extends List<? extends Plateable>, ? extends Plateable> plate =
              requestManager.getPlateById(plateId);
          // autosave the barcode if none has been previously generated
          if (plate.getIdentificationBarcode() == null
              || "".equals(plate.getIdentificationBarcode())) {
            requestManager.savePlate(plate);
          }
          File f = mps.getLabelFor(plate);
          if (f != null) thingsToPrint.add(f);
        } catch (IOException e) {
          e.printStackTrace();
          return JSONUtils.SimpleJSONError("Error printing barcodes: " + e.getMessage());
        }
      }
      PrintJob pj = printManager.print(thingsToPrint, mps.getName(), user);
      return JSONUtils.SimpleJSONResponse("Job " + pj.getJobId() + " : Barcodes printed.");
    } catch (MisoPrintException e) {
      e.printStackTrace();
      return JSONUtils.SimpleJSONError("Failed to print barcodes: " + e.getMessage());
    } catch (IOException e) {
      e.printStackTrace();
      return JSONUtils.SimpleJSONError("Failed to print barcodes: " + e.getMessage());
    }
  }
  public JSONObject getPlateBarcode(HttpSession session, JSONObject json) {
    Long plateId = json.getLong("plateId");
    File temploc = new File(session.getServletContext().getRealPath("/") + "temp/");
    try {
      // Plate<LinkedList<Plateable>, Plateable> plate = requestManager.<LinkedList<Plateable>,
      // Plateable> getPlateById(plateId);
      Plate<? extends List<? extends Plateable>, ? extends Plateable> plate =
          requestManager.getPlateById(plateId);
      barcodeFactory.setPointPixels(1.5f);
      barcodeFactory.setBitmapResolution(600);
      RenderedImage bi = null;

      if (json.has("barcodeGenerator")) {
        BarcodeDimension dim = new BarcodeDimension(100, 100);
        if (json.has("dimensionWidth") && json.has("dimensionHeight")) {
          dim =
              new BarcodeDimension(
                  json.getDouble("dimensionWidth"), json.getDouble("dimensionHeight"));
        }
        BarcodeGenerator bg = BarcodeFactory.lookupGenerator(json.getString("barcodeGenerator"));
        if (bg != null) {
          bi = barcodeFactory.generateBarcode(plate, bg, dim);
        } else {
          return JSONUtils.SimpleJSONError(
              "'" + json.getString("barcodeGenerator") + "' is not a valid barcode generator type");
        }
      } else {
        bi = barcodeFactory.generateSquareDataMatrix(plate, 400);
      }

      if (bi != null) {
        File tempimage = misoFileManager.generateTemporaryFile("barcode-", ".png", temploc);
        if (ImageIO.write(bi, "png", tempimage)) {
          return JSONUtils.JSONObjectResponse("img", tempimage.getName());
        }
        return JSONUtils.SimpleJSONError("Writing temp image file failed.");
      } else {
        return JSONUtils.SimpleJSONError("Plate has no parseable barcode");
      }
    } catch (IOException e) {
      e.printStackTrace();
      return JSONUtils.SimpleJSONError(
          e.getMessage() + ": Cannot seem to access " + temploc.getAbsolutePath());
    }
  }
 public JSONObject downloadPlateInputForm(HttpSession session, JSONObject json) {
   if (json.has("documentFormat")) {
     String documentFormat = json.getString("documentFormat");
     try {
       File f =
           misoFileManager.getNewFile(
               Plate.class,
               "forms",
               "PlateInputForm-" + LimsUtils.getCurrentDateAsString() + "." + documentFormat);
       FormUtils.createPlateInputSpreadsheet(f);
       return JSONUtils.SimpleJSONResponse("" + f.getName().hashCode());
     } catch (Exception e) {
       e.printStackTrace();
       return JSONUtils.SimpleJSONError("Failed to get plate input form: " + e.getMessage());
     }
   } else {
     return JSONUtils.SimpleJSONError("Missing project ID or document format supplied.");
   }
 }
 public JSONObject deletePlate(HttpSession session, JSONObject json) {
   try {
     User user =
         securityManager.getUserByLoginName(
             SecurityContextHolder.getContext().getAuthentication().getName());
     if (user.isAdmin()) {
       if (json.has("plateId")) {
         Long plateId = json.getLong("plateId");
         requestManager.deletePlate(requestManager.getPlateById(plateId));
         return JSONUtils.SimpleJSONResponse("Plate deleted");
       } else {
         return JSONUtils.SimpleJSONError("No plate specified to delete.");
       }
     } else {
       return JSONUtils.SimpleJSONError("Only admins can delete objects.");
     }
   } catch (IOException e) {
     e.printStackTrace();
     return JSONUtils.SimpleJSONError("Error getting currently logged in user.");
   }
 }
  public JSONObject getTagBarcodesForMaterialType(HttpSession session, JSONObject json) {
    Map<String, Object> responseMap = new HashMap<String, Object>();
    if (json.has("materialType") && !"".equals(json.getString("materialType"))) {
      String materialType = json.getString("materialType");
      StringBuilder srb = new StringBuilder();
      srb.append("<select name='tagBarcode' id='tagBarcodes'>");
      srb.append("<option value='0' selected='selected'>No barcode</option>");
      //      for (TagBarcode tb :
      // requestManager.listPlateBarcodesByMaterialType(PlateMaterialType.get(materialType))) {
      //        srb.append("<option value='" + tb.getTagBarcodeId() + "'>" + tb.getName() + " ("+
      // tb.getSequence()+")</option>");
      //      }
      srb.append("</select>");

      responseMap.put("plateBarcodes", srb.toString());
    } else {
      return JSONUtils.SimpleJSONError("Unrecognised MaterialType");
    }
    return JSONUtils.JSONObjectResponse(responseMap);
  }
  public JSONObject saveImportedElements(HttpSession session, JSONObject json) {
    if (json.has("elements")) {
      Plate currentPlate = null;
      Pool currentPool = null;

      try {
        String description = json.getString("description");
        String creationDate = json.getString("creationDate");
        String plateMaterialType = null;
        if (json.has("plateMaterialType") && !json.getString("plateMaterialType").equals("")) {
          plateMaterialType = json.getString("plateMaterialType");
        }

        JSONObject elements = json.getJSONObject("elements");
        JSONArray pools = JSONArray.fromObject(elements.get("pools"));
        JSONArray savedPlates = new JSONArray();
        ObjectMapper mapper = new ObjectMapper();

        for (JSONArray innerPoolList : (Iterable<JSONArray>) pools) {
          for (JSONObject pool : (Iterable<JSONObject>) innerPoolList) {
            log.info(pool.toString());

            PlatePool platePool =
                mapper.readValue(pool.toString(), new TypeReference<PlatePool>() {});
            currentPool = platePool;

            for (Plate<LinkedList<Library>, Library> plate : platePool.getPoolableElements()) {
              JSONObject j = new JSONObject();

              //              if (json.has("tagBarcode")) {
              //                String tagBarcode = json.getString("tagBarcode");
              //
              // plate.setTagBarcode(requestManager.listAllTagBarcodesByStrategyName());
              //              }

              if (plate.getDescription() == null) {
                plate.setDescription(description);
              }

              if (plate.getCreationDate() == null) {
                // plate.setCreationDate(DateFormat.getInstance().parse(creationDate));
              }

              if (plate.getPlateMaterialType() == null && plateMaterialType != null) {
                plate.setPlateMaterialType(PlateMaterialType.valueOf(plateMaterialType));
              }
              log.info("Saving plate: " + plate.toString());
              currentPlate = plate;
              long plateId = requestManager.savePlate(plate);
              j.put("plateId", plateId);
              savedPlates.add(j);
              currentPlate = null;
            }

            log.info("Saving pool: " + pool.toString());
            requestManager.savePool(platePool);
            currentPool = null;
          }
        }
        JSONObject resp = new JSONObject();
        resp.put("plates", savedPlates);
        return resp;
      } catch (IOException e) {
        if (currentPool != null) {
          log.error(
              "Error saving pool elements on new plate save. Deleting pool "
                  + currentPool.toString());
          // clear out child elements to make sure plate meets delete requirements
          currentPool.getPoolableElements().clear();
          try {
            requestManager.deletePool(currentPool);
          } catch (IOException e1) {
            log.error("Cannot delete pool. Nothing left to do.");
            e1.printStackTrace();
          }
        }

        if (currentPlate != null) {
          log.error(
              "Error saving plate elements on new plate save. Deleting plate "
                  + currentPlate.toString());
          // clear out child elements to make sure plate meets delete requirements
          currentPlate.getElements().clear();
          try {
            requestManager.deletePlate(currentPlate);
          } catch (IOException e1) {
            log.error("Cannot delete plate. Nothing left to do.");
            e1.printStackTrace();
          }
        }

        log.error("Caused by...");
        e.printStackTrace();
        return JSONUtils.SimpleJSONError("Cannot save imported plate: " + e.getMessage());
      }
    } else {
      return JSONUtils.SimpleJSONError("No valid plates available to save");
    }
  }
  @Deprecated
  public JSONObject previewExperiment(HttpSession session, JSONObject json) {
    String experimentId = (String) json.get("experimentId");

    try {
      Experiment e = requestManager.getExperimentById(Long.parseLong(experimentId));
      Collection<Run> runs = requestManager.listRunsByExperimentId(e.getExperimentId());

      session.setAttribute("experiment", e);

      StringBuilder rb = new StringBuilder();
      for (Run r : runs) {
        rb.append("<li><a href='/miso/run/")
            .append(r.getRunId())
            .append("'>")
            .append(r.getName())
            .append("</a></li>");
      }

      StringBuilder sb = new StringBuilder();
      if (e.getPool() != null) {
        if (e.getPlatform().getPlatformType().equals(PlatformType.ILLUMINA)) {
          for (Object dil : e.getPool().getDilutions()) {
            Sample s = ((LibraryDilution) dil).getLibrary().getSample();
            sb.append("<li><a href='/miso/sample/")
                .append(s.getSampleId())
                .append("'>")
                .append(s.getName())
                .append("</a></li>");
          }
        } else {
          for (Object dil : e.getPool().getDilutions()) {
            Sample s =
                ((emPCRDilution) dil).getEmPCR().getLibraryDilution().getLibrary().getSample();
            sb.append("<li><a href='/miso/sample/")
                .append(s.getSampleId())
                .append("'>")
                .append(s.getName())
                .append("</a></li>");
          }
        }
      }

      StringBuilder b = new StringBuilder();
      b.append(
          "<div onclick=\"Effect.toggle('preview"
              + experimentId
              + "','blind'); return false;\">"
              + "<img src=\"/styles/images/moreinfo.png\" class=\"previewimage\"/></div>");
      b.append("<br/><div id=\"preview" + experimentId + "\" class='exppreview'>");
      b.append("Title: <b>").append(e.getTitle()).append("</b><br/>");
      b.append("Description: <b>").append(e.getDescription()).append("</b><br/>");
      b.append("Samples: <ul class=\"bullets\">").append(sb.toString()).append("</ul>");
      b.append("Runs: <ul class=\"bullets\">").append(rb.toString()).append("</ul>");
      b.append("</div>");
      return JSONUtils.SimpleJSONResponse(b.toString());

    } catch (IOException e) {
      log.debug("Failed", e);
      return JSONUtils.SimpleJSONError("Failed");
    }
  }