/*
* Copyright (c) 2012. The Genome Analysis Centre, Norwich, UK
* MISO project contacts: Robert Davey, Mario Caccamo @ TGAC
* *********************************************************************
*
* This file is part of MISO.
*
* MISO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MISO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MISO. If not, see <http://www.gnu.org/licenses/>.
*
* *********************************************************************
*/
package uk.ac.bbsrc.tgac.miso.webapp.controller;
import com.eaglegenomics.simlims.core.User;
import com.eaglegenomics.simlims.core.manager.SecurityManager;
//import com.fasterxml.jackson.core.type.TypeReference;
//import com.fasterxml.jackson.databind.ObjectMapper;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sourceforge.fluxion.ajax.util.JSONUtils;
import org.codehaus.jackson.Version;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
import org.codehaus.jackson.map.module.SimpleModule;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import uk.ac.bbsrc.tgac.miso.core.data.*;
import uk.ac.bbsrc.tgac.miso.core.data.impl.PlatePool;
import uk.ac.bbsrc.tgac.miso.core.manager.MisoFilesManager;
import uk.ac.bbsrc.tgac.miso.core.manager.RequestManager;
import uk.ac.bbsrc.tgac.miso.core.service.naming.MisoNamingScheme;
import uk.ac.bbsrc.tgac.miso.core.util.FormUtils;
import uk.ac.bbsrc.tgac.miso.core.util.LimsUtils;
import uk.ac.bbsrc.tgac.miso.core.manager.FilesManager;
import uk.ac.bbsrc.tgac.miso.core.util.jackson.SampleRecursionAvoidanceMixin;
import uk.ac.bbsrc.tgac.miso.webapp.service.forms.MisoFormsService;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
@Controller
@RequestMapping("/upload")
public class UploadController {
protected static final Logger log = LoggerFactory.getLogger(UploadController.class);
@Autowired
private SecurityManager securityManager;
@Autowired
public RequestManager requestManager;
@Autowired
public FilesManager filesManager;
@Autowired
private MisoFilesManager misoFileManager;
@Autowired
public MisoFormsService misoFormsService;
@Autowired
private MisoNamingScheme<Library> libraryNamingScheme;
public void setSecurityManager(SecurityManager securityManager) {
this.securityManager = securityManager;
}
public void setRequestManager(RequestManager requestManager) {
this.requestManager = requestManager;
}
public void setFilesManager(FilesManager filesManager) {
this.filesManager = filesManager;
}
public void setMisoFileManager(MisoFilesManager misoFileManager) {
this.misoFileManager = misoFileManager;
}
public void setMisoFormsService(MisoFormsService misoFormsService) {
this.misoFormsService = misoFormsService;
}
public void setLibraryNamingScheme(MisoNamingScheme<Library> libraryNamingScheme) {
this.libraryNamingScheme = libraryNamingScheme;
}
private Class lookupCoreClass(String className) throws ClassNotFoundException {
return this.getClass().getClassLoader().loadClass("uk.ac.bbsrc.tgac.miso.core." + className);
}
public void uploadFile(Class type, String qualifier, MultipartFile fileItem) throws IOException {
File dir = new File(filesManager.getFileStorageDirectory() + File.separator + type.getSimpleName().toLowerCase() + File.separator + qualifier);
if (LimsUtils.checkDirectory(dir, true)) {
log.info("Attempting to store " + dir.toString() + File.separator + fileItem.getOriginalFilename());
fileItem.transferTo(new File(dir + File.separator + fileItem.getOriginalFilename().replaceAll("\\s", "_")));
}
else {
throw new IOException("Cannot upload file - check that the directory specified in miso.properties exists and is writable");
}
}
public void uploadFile(Object type, String qualifier, MultipartFile fileItem) throws IOException {
uploadFile(type.getClass(), qualifier, fileItem);
}
@RequestMapping(value = "/project", method = RequestMethod.POST)
public void uploadProjectDocument(MultipartHttpServletRequest request) throws IOException {
String projectId = request.getParameter("projectId");
for (MultipartFile fileItem : getMultipartFiles(request)) {
uploadFile(Project.class, projectId, fileItem);
}
}
@RequestMapping(value = "/project/sample-delivery-form", method = RequestMethod.POST)
public String uploadProjectSampleDeliveryForm(MultipartHttpServletRequest request) throws IOException {
String projectId = request.getParameter("projectId");
boolean taxonCheck = (Boolean) request.getSession().getServletContext().getAttribute("taxonLookupEnabled");
try {
for (MultipartFile fileItem : getMultipartFiles(request)) {
uploadFile(Project.class, projectId, fileItem);
File f = filesManager.getFile(Project.class, projectId, fileItem.getOriginalFilename().replaceAll("\\s+", "_"));
List<Sample> samples = FormUtils.importSampleDeliveryForm(f);
log.info("Importing samples from form: " + samples.toString());
misoFormsService.importSampleDeliveryFormSamples(samples, taxonCheck);
}
return "redirect:/miso/project/" + projectId;
}
catch (Exception e) {
log.error("SAMPLE IMPORT FAIL:", e);
throw new IOException(e);
}
}
@RequestMapping(value = "/project/bulk-input-form", method = RequestMethod.POST)
public void uploadProjectBulkInputForm(MultipartHttpServletRequest request) throws IOException {
String projectId = request.getParameter("projectId");
try {
for (MultipartFile fileItem : getMultipartFiles(request)) {
uploadFile(Project.class, projectId, fileItem);
File f = filesManager.getFile(Project.class, projectId, fileItem.getOriginalFilename().replaceAll("\\s+", "_"));
User user = securityManager.getUserByLoginName(SecurityContextHolder.getContext().getAuthentication().getName());
List<Sample> samples = FormUtils.importSampleInputSpreadsheet(f, user, requestManager, libraryNamingScheme);
ObjectMapper mapper = new ObjectMapper();
JSONArray a = new JSONArray();
for (Sample s : samples) {
a.add(JSONObject.fromObject(mapper.writeValueAsString(s)));
}
JSONObject o = new JSONObject();
o.put("bulksamples", a);
log.info(o.toString());
request.getSession(false).setAttribute("bulksamples", o);
}
}
catch (Exception e) {
log.error("SAMPLE IMPORT FAIL:" + e.getMessage());
//JSONObject o = new JSONObject();
//o.put("bulkerror", "Cannot import bulk spreadsheet: " + e.getMessage());
//log.error(o.toString());
//request.getSession(false).setAttribute("bulkerror", o);
}
}
@RequestMapping(value = "/project/plate-form", method = RequestMethod.POST)
public void uploadProjectPlateInputForm(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
String projectId = request.getParameter("projectId");
try {
JSONArray a = new JSONArray();
JSONObject o = new JSONObject();
for (MultipartFile fileItem : getMultipartFiles(request)) {
uploadFile(Project.class, projectId, fileItem);
File f = filesManager.getFile(Project.class, projectId, fileItem.getOriginalFilename().replaceAll("\\s+", "_"));
User user = securityManager.getUserByLoginName(SecurityContextHolder.getContext().getAuthentication().getName());
//Map<String, Pool<Plate<LinkedList<Library>, Library>>> pooledPlates = FormUtils.importPlateInputSpreadsheet(f, user, requestManager, libraryNamingScheme);
Map<String, PlatePool> pooledPlates = FormUtils.importPlateInputSpreadsheet(f, user, requestManager, libraryNamingScheme);
ObjectMapper mapper = new ObjectMapper();
mapper.getSerializationConfig().addMixInAnnotations(Sample.class, SampleRecursionAvoidanceMixin.class);
String s = mapper.writerWithType(new TypeReference<Collection<PlatePool>>() {
})
.writeValueAsString(pooledPlates.values());
a.add(JSONArray.fromObject(s));
}
o.put("pools", a);
log.info(o.toString());
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<input type='hidden' id='uploadresponsebody' value='" + o.toString() + "'/>");
}
catch (Exception e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/plate/plate-form", method = RequestMethod.POST)
public void uploadPlateInputForm(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
try {
JSONArray a = new JSONArray();
JSONObject o = new JSONObject();
for (MultipartFile fileItem : getMultipartFiles(request)) {
uploadFile(Plate.class, "forms", fileItem);
File f = filesManager.getFile(Plate.class, "forms", fileItem.getOriginalFilename().replaceAll("\\s+", "_"));
User user = securityManager.getUserByLoginName(SecurityContextHolder.getContext().getAuthentication().getName());
//Map<String, Pool<Plate<LinkedList<Library>, Library>>> pooledPlates = FormUtils.importPlateInputSpreadsheet(f, user, requestManager, libraryNamingScheme);
Map<String, PlatePool> pooledPlates = FormUtils.importPlateInputSpreadsheet(f, user, requestManager, libraryNamingScheme);
ObjectMapper mapper = new ObjectMapper();
mapper.getSerializationConfig().addMixInAnnotations(Sample.class, SampleRecursionAvoidanceMixin.class);
String s = mapper.writerWithType(new TypeReference<Collection<PlatePool>>() {
})
.writeValueAsString(pooledPlates.values());
a.add(JSONArray.fromObject(s));
}
o.put("pools", a);
log.info(o.toString());
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<input type='hidden' id='uploadresponsebody' value='" + o.toString() + "'/>");
}
catch (Exception e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/importexport/samplesheet", method = RequestMethod.POST)
public void uploadSampleSheet(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
try {
JSONArray jsonArray = new JSONArray();
for (MultipartFile fileItem : getMultipartFiles(request)) {
uploadFile(Sample.class, "forms", fileItem);
File f = filesManager.getFile(Sample.class, "forms", fileItem.getOriginalFilename().replaceAll("\\s+", "_"));
User user = securityManager.getUserByLoginName(SecurityContextHolder.getContext().getAuthentication().getName());
jsonArray = FormUtils.preProcessSampleSheetImport(f, user, requestManager);
}
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<input type='hidden' id='uploadresponsebody' value='" + jsonArray + "'/>");
}
catch (Exception e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/importexport/librarypoolsheet", method = RequestMethod.POST)
public void uploadLibraryPoolSheet(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
try {
JSONObject result = new JSONObject();
for (MultipartFile fileItem : getMultipartFiles(request)) {
uploadFile(Library.class, "forms", fileItem);
File f = filesManager.getFile(Library.class, "forms", fileItem.getOriginalFilename().replaceAll("\\s+", "_"));
User user = securityManager.getUserByLoginName(SecurityContextHolder.getContext().getAuthentication().getName());
result = FormUtils.preProcessLibraryPoolSheetImport(f, user, requestManager);
}
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<input type='hidden' id='uploadresponsebody' value='" + result + "'/>");
}
catch (Exception e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/libraryqc", method = RequestMethod.POST)
public void uploadLibraryQcDocument(MultipartHttpServletRequest request) throws IOException {
String libraryId = request.getParameter("libraryId");
for (MultipartFile fileItem : getMultipartFiles(request)) {
uploadFile(LibraryQC.class, libraryId + File.separator + "qc" + File.separator, fileItem);
}
}
@RequestMapping(value = "/sampleqc", method = RequestMethod.POST)
public void uploadSampleQcDocument(MultipartHttpServletRequest request) throws IOException {
String sampleId = request.getParameter("sampleId");
for (MultipartFile fileItem : getMultipartFiles(request)) {
uploadFile(SampleQC.class, sampleId + File.separator + "qc" + File.separator, fileItem);
}
}
@RequestMapping(value = "/dilution-to-pool", method = RequestMethod.POST)
public void uploadLibraryList(MultipartHttpServletRequest request) throws IOException {
try {
HashSet<String> librarySet = new HashSet<String>();
for (MultipartFile fileItem : getMultipartFiles(request)) {
for (String s : new String(fileItem.getBytes()).split("\n")) {
librarySet.add(s);
}
}
JSONArray a = JSONArray.fromObject(librarySet);
JSONObject o = new JSONObject();
o.put("barcodes", a);
log.debug(o.toString());
request.getSession(false).setAttribute("barcodes", o);
}
catch (Exception e) {
log.debug("UPLOAD FAIL:", e);
//return JSONUtils.SimpleJSONError("Upload failed: "+e.getMessage());
}
}
private List<MultipartFile> getMultipartFiles(MultipartHttpServletRequest request) {
List<MultipartFile> files = new ArrayList<MultipartFile>();
Map<String, MultipartFile> fMap = request.getFileMap();
for (String fileName : fMap.keySet()) {
MultipartFile fileItem = fMap.get(fileName);
if (fileItem.getSize() > 0) {
files.add(fileItem);
}
}
return files;
}
}