package com.aperture_software.glados_wiki.webmvc.controllers;
import com.aperture_software.glados_wiki.entities.FileEntry;
import com.aperture_software.glados_wiki.services.FileStoreService;
import com.aperture_software.glados_wiki.support.*;
import com.aperture_software.glados_wiki.webmvc.controllers.file.FileListPaginationToLinkFunction;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.io.Closer;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
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.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;
import org.springframework.web.servlet.view.RedirectView;
import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.List;
/**
* Created by jhyun on 13. 12. 19.
*/
@RequestMapping(value = "/file")
@Controller
public class FileController {
private static Logger LOG = LoggerFactory.getLogger(FileController.class);
@Inject
private FileStoreService fileStoreService;
@Inject
private HttpFileDownload httpFileDownload;
@Inject
private FlashAlerts flashAlerts;
@RequiresUser
@RequestMapping(value = "/uploadForm", method = RequestMethod.GET)
public ModelAndView uploadForm(ModelMap m) {
return new ModelAndView("file/uploadForm", m);
}
@RequiresUser
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String saveUpload(@RequestParam(value = "file", required = true) MultipartFile file,
@RequestParam(value = "privateFile", required = false, defaultValue = "false") final boolean privateFile,
@RequestParam(value = "description", required = false, defaultValue = "") final String description,
RedirectAttributesModelMap redirectAttributesModelMap) throws Exception {
//
final String creator = SecurityUtils2.getUsername();
//
if (file.isEmpty()) {
throw new Exception("PLEASE SELECT A FILE.");
} else {
Closer closer = Closer.create();
try {
final String mime = file.getContentType();
final String name = file.getOriginalFilename();
//
InputStream in = file.getInputStream();
closer.register(in);
//
Optional<FileEntry> fe = fileStoreService.save(name, mime, creator, privateFile, description, in);
if (fe.isPresent() == false) {
throw new Exception("FILE SAVE FAILED?!");
}
// flashmap-alert.
flashAlerts.add(redirectAttributesModelMap, new FlashAlerts.FlashAlert(BootstrapAlertTypes.INFO, "File Saved."));
//
return String.format("redirect:./info/%s", fe.get().getId());
} finally {
closer.close();
}
}
}
@RequestMapping(value = "/list", method = RequestMethod.GET)
public ModelAndView fileList(ModelMap m,
@RequestParam(value = "offset", required = false, defaultValue = "0") final int offset,
@RequestParam(value = "limit", required = false, defaultValue = "10") final int limit,
@RequestParam(value = "searchTerm", required = false, defaultValue = "") final String searchTerm) {
//
final String myself = SecurityUtils2.getUsername();
Optional<String> myself_ = Optional.absent();
if (false == Strings.isNullOrEmpty(myself)) {
myself_ = Optional.of(myself);
}
//
final boolean isAdmin = SecurityUtils2.isAdmin();
//
Optional<String> searchTerm_ = Strings.isNullOrEmpty(searchTerm) ? Optional.<String>absent() : Optional.of(searchTerm);
List<FileEntry> l = fileStoreService.list(
searchTerm_,
offset, limit, myself_, isAdmin);
final int count = fileStoreService.count(searchTerm_, myself_, isAdmin);
Pagination p = new Pagination(count, offset, limit);
m.put("files", l);
m.put("filesPagination", p);
m.put("searchTerm", searchTerm);
//
FileListPaginationToLinkFunction pf = new FileListPaginationToLinkFunction();
if (Strings.isNullOrEmpty(searchTerm) == false) {
pf.setSearchTerm(Optional.of(searchTerm));
}
pf.setPagination(p);
m.put("filesPaginationToLinkFunction", pf);
//
return new ModelAndView("file/list", m);
}
@RequestMapping(value = "/info/{fileStoreId}", method = RequestMethod.GET)
public ModelAndView fileInfo(ModelMap m, @PathVariable("fileStoreId") final String fileStoreId)
throws Exception {
ObjectId fileStoreId2 = new ObjectId(fileStoreId);
if (fileStoreService.exists(fileStoreId2)) {
Optional<FileEntry> fe = fileStoreService.loadFileEntry(fileStoreId2);
if (fe.isPresent() == false) {
throw new Exception(String.format("FILE NOT FOUND BY ID [%s] (1)", fileStoreId));
}
m.put("fileEntry", fe.get());
return new ModelAndView("file/info", m);
} else {
throw new Exception(String.format("FILE NOT FOUND BY ID [%s] (2)", fileStoreId));
}
}
@RequestMapping(value = "/blob/{fileStoreId}", method = RequestMethod.GET)
public void fileBlob(@PathVariable(value = "fileStoreId") final String fileStoreId,
HttpServletResponse response) throws Exception {
ObjectId fileStoreId2 = new ObjectId(fileStoreId);
if (fileStoreService.exists(fileStoreId2)) {
Closer closer = Closer.create();
try {
Optional<FileEntry> fe = fileStoreService.loadFileEntry(fileStoreId2);
if (fe.isPresent() == false) {
throw new Exception(String.format("FILE NOT FOUND BY ID [%s] (1)", fileStoreId));
}
//
InputStream in = fileStoreService.getInputStream(fileStoreId2);
closer.register(in);
//
httpFileDownload.downloadInputStream(fe.get().getName(), fe.get().getMime(), in, response);
} finally {
closer.close();
}
} else {
throw new Exception(String.format("FILE NOT FOUND BY ID [%s] (2)", fileStoreId));
}
}
@RequiresUser
@RequestMapping(value = "/delete/{fileStoreId}")
public View delete(@PathVariable("fileStoreId") final String fileStoreId) throws Exception {
ObjectId fileStoreId2 = new ObjectId(fileStoreId);
Optional<FileEntry> fe = fileStoreService.loadFileEntry(fileStoreId2);
if (fe.isPresent()) {
if (SecurityUtils2.isAdmin() || SecurityUtils2.getUsername().equals(fe.get().getCreator())) {
fileStoreService.delete(fileStoreId2);
}
return new RedirectView("../list");
} else {
throw new Exception(String.format("FILE FOR ID NOT FOUND -- [%s]", fileStoreId));
}
}
}