Commit 47f81c5e authored by Ariane Mora's avatar Ariane Mora

File upload, API to get the networks from a BED file.

parent 0f07fe7e
package com.gnv.eneg;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import com.gnv.eneg.storage.StorageProperties;
import com.gnv.eneg.storage.StorageService;
/**
* Ariane 11/12/2017
* From: https://spring.io/guides/gs/uploading-files/
*/
@SpringBootApplication
@EnableConfigurationProperties(StorageProperties.class)
public class EnegApplication {
public static void main(String[] args) {
SpringApplication.run(EnegApplication.class, args);
}
@Bean
CommandLineRunner init(StorageService storageService) {
return (args) -> {
storageService.deleteAll();
storageService.init();
};
}
}
\ No newline at end of file
package com.gnv.eneg;
import java.io.IOException;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.gnv.eneg.storage.StorageFileNotFoundException;
import com.gnv.eneg.storage.StorageService;
import com.gnv.eneg.PairAPI;
import java.util.concurrent.CountDownLatch;
/**
* Ariane 11/12/2017
* From: https://spring.io/guides/gs/uploading-files/
*/
@Controller
public class GNV {
private final StorageService storageService;
// Where the bedPairFile is stored.
public String bedPairFilePath;
private String directory = "/home/ariane/Documents/bodenlab/ASR/gnvweb/eneg/upload-dir/";
// The PairApi which stores the current instance of the user.
PairAPI pairAPI;
@Autowired
public GNV(StorageService storageService) {
this.storageService = storageService;
}
@GetMapping("/")
public String listUploadedFiles(Model model) throws IOException {
model.addAttribute("files", storageService.loadAll().map(
path -> MvcUriComponentsBuilder.fromMethodName(GNV.class,
"serveFile", path.getFileName().toString()).build().toString())
.collect(Collectors.toList()));
// Set the networks to be None until a user has uploaded a file.
model.addAttribute("networksInBedFile", "None");
return "index";
}
@GetMapping("/files/{filename:.+}")
@ResponseBody
public ResponseEntity<Resource> serveFile(@PathVariable String filename) {
Resource file = storageService.loadAsResource(filename);
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getFilename() + "\"").body(file);
}
@PostMapping("/")
public String handleFileUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
storageService.store(file);
/**
* Gets the file and starts the process of getting the networks from the file.
*
* Initially used to get all the networks within a bedPairFile.
*
* These are relative to the chromosone.
*/
bedPairFilePath = directory + file.getOriginalFilename();
pairAPI = new PairAPI(bedPairFilePath);
// Write the JSON to a file that will be read by the application.
// It is too large to add as a model attribute.
pairAPI.writeJSONArrToLocalFile(pairAPI.getNetworksInUploadedBedFile(), "networksInBedFile.JSON");
// Set the results flag to be true to show the results page.
redirectAttributes.addFlashAttribute("results", true);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
/**
* An Ajax call performed when the user uploads the BED file.
* Only returns once the file has fully loaded.
* @param id
* @param request
* @param response
* @param model
* @return
*/
@RequestMapping(value = "/", method = RequestMethod.GET, params = {"request"})
public @ResponseBody String showStatus(@RequestParam("request") String request, Model model) throws IOException {
return pairAPI.getNetworksInUploadedBedFile().toString();
}
@ExceptionHandler(StorageFileNotFoundException.class)
public ResponseEntity<?> handleStorageFileNotFound(StorageFileNotFoundException exc) {
return ResponseEntity.notFound().build();
}
}
package com.gnv.eneg;
import pairs.*;
import json.*;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
/**
* BINFKIT API for using the BED pair calls from Alex's code.
*
* Created by ariane on 8/11/17.
*/
public class PairAPI {
private static BedPairFile bpf;
// Passed to the class, it is the users' uploaded bed file.
private static String bedPairFilePath;
// Set variables. Default values but updateable.
private static int maxPairSize = 2000000;
private static int padding = 0;
// Where data i.e. JSON is stored locally
private static String dataPath = "/home/ariane/Documents/bodenlab/ASR/gnvweb/eneg/src/main/resources/public/data/vis/";
public PairAPI(String bedPairFilePath) {
this.bpf = new BedPairFile(bedPairFilePath);
this.bedPairFilePath = bedPairFilePath;
}
/**
* Gets the network (or networks) within a specific region within a chromosone.
*
* Returns the Network as a JSON array or elements.
*/
public static JSONArray getNetwork(String chrom, int start, int end) {
bpf.getNetworkAPI(bedPairFilePath, maxPairSize, padding, chrom, start, end);
JSONArray network = bpf.jsonNetwork;
return network;
}
/**
* Writes the JSON object to a local file.
*
* Returns the path of the file.
*/
public static String writeJSONArrToLocalFile(JSONArray jsonArr, String fileName) {
try {
BufferedWriter write = new BufferedWriter(new FileWriter(dataPath + fileName));
write.write(jsonArr.toString());
write.close();
} catch (IOException ex) {
System.out.println("Issue with the file.");
}
return dataPath + fileName;
}
/**
* Gets the networks within a users uploaded bed file.
*
* Returns these as a JSON array of the start, end and chromosone of the network.
*
*/
public static JSONArray getNetworksInUploadedBedFile() {
bpf.getNetworksAsJSONAccrossBedFile(bedPairFilePath, maxPairSize, padding);
JSONArray networks = bpf.jsonNetworksInBedFile;
System.out.println(bpf.jsonNetworksInBedFile);
return networks;
}
}
\ No newline at end of file
package com.gnv.eneg.storage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.stream.Stream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
/**
* Ariane 11/12/2017
* From: https://spring.io/guides/gs/uploading-files/
*/
@Service
public class FileSystemStorageService implements StorageService {
private final Path rootLocation;
@Autowired
public FileSystemStorageService(StorageProperties properties) {
this.rootLocation = Paths.get(properties.getLocation());
}
@Override
public void store(MultipartFile file) {
String filename = StringUtils.cleanPath(file.getOriginalFilename());
try {
if (file.isEmpty()) {
throw new StorageException("Failed to store empty file " + filename);
}
if (filename.contains("..")) {
// This is a security check
throw new StorageException(
"Cannot store file with relative path outside current directory "
+ filename);
}
Files.copy(file.getInputStream(), this.rootLocation.resolve(filename),
StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException e) {
throw new StorageException("Failed to store file " + filename, e);
}
}
@Override
public Stream<Path> loadAll() {
try {
return Files.walk(this.rootLocation, 1)
.filter(path -> !path.equals(this.rootLocation))
.map(path -> this.rootLocation.relativize(path));
}
catch (IOException e) {
throw new StorageException("Failed to read stored files", e);
}
}
@Override
public Path load(String filename) {
return rootLocation.resolve(filename);
}
@Override
public Resource loadAsResource(String filename) {
try {
Path file = load(filename);
Resource resource = new UrlResource(file.toUri());
if (resource.exists() || resource.isReadable()) {
return resource;
}
else {
throw new StorageFileNotFoundException(
"Could not read file: " + filename);
}
}
catch (MalformedURLException e) {
throw new StorageFileNotFoundException("Could not read file: " + filename, e);
}
}
@Override
public void deleteAll() {
FileSystemUtils.deleteRecursively(rootLocation.toFile());
}
@Override
public void init() {
try {
Files.createDirectories(rootLocation);
}
catch (IOException e) {
throw new StorageException("Could not initialize storage", e);
}
}
}
package com.gnv.eneg.storage;
/**
* Ariane 11/12/2017
* From: https://spring.io/guides/gs/uploading-files/
*/
public class StorageException extends RuntimeException {
public StorageException(String message) {
super(message);
}
public StorageException(String message, Throwable cause) {
super(message, cause);
}
}
package com.gnv.eneg.storage;
/**
* Ariane 11/12/2017
* From: https://spring.io/guides/gs/uploading-files/
*/
public class StorageFileNotFoundException extends StorageException {
public StorageFileNotFoundException(String message) {
super(message);
}
public StorageFileNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
\ No newline at end of file
package com.gnv.eneg.storage;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Ariane 11/12/2017
* From: https://spring.io/guides/gs/uploading-files/
*/
@ConfigurationProperties("storage")
public class StorageProperties {
/**
* Folder location for storing files
*/
private String location = "upload-dir";
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
package com.gnv.eneg.storage;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
import java.util.stream.Stream;
/**
* Ariane 11/12/2017
* From: https://spring.io/guides/gs/uploading-files/
*/
public interface StorageService {
void init();
void store(MultipartFile file);
Stream<Path> loadAll();
Path load(String filename);
Resource loadAsResource(String filename);
void deleteAll();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment