package nl.oneday.controller;
import nl.oneday.data.domain.uploads.FileMeta;
import nl.oneday.data.domain.uploads.File;
import nl.oneday.data.service.FileService;
import nl.oneday.data.service.UserService;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.imageio.ImageIO;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@Controller
public class FileController extends ControllerBase implements CrudInterface<File,Long> {
@Override
public File add(File object) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public File get(Long id) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public List<File> getAll() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public File update(File object) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public Boolean remove(File object) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
private static final Logger LOG = LoggerFactory.getLogger(FileController.class);
@Value("${upload.directory}")
String uploadDirectory;
@Autowired
FileService fileService;
@Autowired
UserService userService;
@Autowired
ServletContext servletContext;
/***************************************************
* URL: /rest/controller/upload upload(): receives files
*
* @param request : MultipartHttpServletRequest auto passed
* @param response : HttpServletResponse auto passed
* @return LinkedList<FileMeta> as json format
****************************************************/
@PreAuthorize("(hasAnyRole('ROLE_USER','ROLE_ADMIN'))")
@RequestMapping(value = Paths.UPLOAD, method = RequestMethod.POST)
public @ResponseBody
String upload(MultipartHttpServletRequest request, HttpServletResponse response) {
UserDetails userDetails = getCurrentUserDetails();
LinkedList<FileMeta> files = new LinkedList<FileMeta>();
FileMeta fileMeta = null;
JSONObject results = new JSONObject();
// 1. build an iterator
Iterator<String> itr = request.getFileNames();
MultipartFile mpf = null;
// 2. get each file
while (itr.hasNext()) {
// 2.1 get next MultipartFile
mpf = request.getFile(itr.next());
System.out.println(mpf.getOriginalFilename() + " uploaded! " + files.size());
// 2.2 if files > 10 remove the first from the list
if (files.size() >= 10) files.pop();
// 2.3 create new fileMeta
fileMeta = new FileMeta();
fileMeta.setFileName(mpf.getOriginalFilename());
fileMeta.setFileSize(mpf.getSize() / 1024 + " Kb");
fileMeta.setFileType(mpf.getContentType());
try {
fileMeta.setBytes(mpf.getBytes());
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 2.4 add to files
files.add(fileMeta);
FileMeta savedFileMeta = writeFileToDisk(fileMeta);
if (savedFileMeta != null) {
nl.oneday.data.domain.uploads.File fileEntity = new nl.oneday.data.domain.uploads.File();
fileEntity.setFilename(fileMeta.getFileName());
fileEntity.setFilePath(uploadDirectory + userDetails.getUsername() + java.io.File.separator + fileMeta.getFileName());
fileEntity.setType(fileMeta.getFileType());
fileEntity.setTimeStamp(new Date());
fileService.save(fileEntity);
results.put("success", true);
return results.toJSONString();
}
}
results.put("success", false);
return results.toJSONString();
}
private FileMeta writeFileToDisk(FileMeta fileMeta) {
UserDetails userDetails = getCurrentUserDetails();
FileMeta savedFileMeta = null;
if (userDetails != null) {
String userDirPath = uploadDirectory + userDetails.getUsername();
java.io.File file = new java.io.File(userDirPath);
if (!file.exists()) {
try {
boolean dirCreated = file.mkdirs();
if (dirCreated) {
System.out.println("Directory is created!");
}
else {
System.out.println("Failed to create directory!");
}
}
catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
try {
byte[] data = fileMeta.getBytes();
file = new java.io.File(userDirPath + java.io.File.separator + fileMeta.getFileName());
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
fos.close();
savedFileMeta = fileMeta;
}
catch (Exception e) {
LOG.error("Error writing file", e);
}
}
return savedFileMeta;
}
@RequestMapping(value = Paths.DATA_GET_BY_ID)
@ResponseBody
public void getFile(HttpServletResponse response, @PathVariable(value = "id") Long id) throws IOException {
nl.oneday.data.domain.uploads.File file = fileService.find(id);
try {
response.setContentType(file.getType());
response.setHeader("Content-disposition", "attachment; filename=\"" + file.getFilename() + "\"");
FileCopyUtils.copy(fileService.readFile(file.getFilePath()), response.getOutputStream());
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@RequestMapping(value = Paths.DATA_GET_MINI_BY_ID)
@ResponseBody
public void getMinifiedImage(HttpServletResponse response, @PathVariable(value = "id") Long id) throws IOException {
nl.oneday.data.domain.uploads.File file = fileService.find(id);
file.getType();
try {
response.setContentType(file.getType());
response.setHeader("Content-disposition", "attachment; filename=\"" + file.getFilename() + "\"");
streamMinifiedImageResponse(response, file, 50, 50);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@RequestMapping(value = Paths.DATA_GET_PROFILE_BY_ID)
@ResponseBody
public void getMinifiedProfileImage(HttpServletResponse response, @PathVariable(value = "id") Long id) throws IOException {
nl.oneday.data.domain.uploads.File file = fileService.find(id);
try {
response.setContentType(file.getType());
response.setHeader("Content-disposition", "attachment; filename=\"" + file.getFilename() + "\"");
streamMinifiedImageResponse(response, file, 150, 175);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void streamMinifiedImageResponse(HttpServletResponse response, nl.oneday.data.domain.uploads.File file,
int maxWidth, int maxHeight) throws IOException {
java.io.File imageFile = new java.io.File(file.getFilePath());
BufferedImage img = ImageIO.read(imageFile); // load image
int width = img.getWidth();
int height = img.getHeight();
float scaleFactor = width / maxWidth;
height = (int) (height / scaleFactor);
width = (int) (width / scaleFactor);
if (height > maxHeight) height = maxHeight;
// ImageIO.setUseCache(false);
String imgType = file.getType().replace("image/", "");
if (imgType.equals("jpeg")) imgType = "jpg";
Image scaled = img.getScaledInstance(width, height, BufferedImage.SCALE_AREA_AVERAGING);
int imageType = img.getType();
BufferedImage buffered = new BufferedImage(width, height, imageType);
buffered.getGraphics().drawImage(scaled, 0, 0, null);
ImageIO.write(buffered, imgType, response.getOutputStream());
}
}