package sino.controller.post;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.Iterator;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;
import sino.controller.image.ImageConverter;
import sino.controller.image.ImageConverterException;
import sino.entities.Post;
import sino.entities.PostType;
import sino.service.PostServiceException;
import sino.utility.ParamUtility;
@Controller
@RequestMapping(ModifyPostController.BASE_PATH)
public class ModifyPostController extends BasePostController {
public static final String BASE_PATH = "/post";
private ImageConverter imageConverter;
private int previewImageWidth = 570;
private int maxImageWidth = 830;
private String editPostView = "/post/edit_post";
private String uploadFileView = "/post/uploaded_file";
@RequestMapping(value = "/index.do")
public String viewBack(HttpServletRequest request, HttpSession session) {
session.setAttribute("user", request.getRemoteUser());
return "back";
}
@RequestMapping(value = "/{type}/edit.do")
public ModelAndView editPost(@PathVariable("type") String type,
@RequestParam(value = "id", required = false, defaultValue = "-1") long id) throws PostControllerException,
PostServiceException {
Post post;
if (id == -1) {
post = new Post();
} else {
post = getPostService().getPost(id);
}
ModelAndView mov = new ModelAndView(this.editPostView);
mov.addObject("post", post);
mov.addObject("type", type);
mov.addObject("new", id == -1);
return mov;
}
@RequestMapping(value = "/{type}/create.do")
public String createPost(@PathVariable("type") String type, Post post,
@RequestParam(value = "previewpicture", required = false) CommonsMultipartFile file)
throws PostControllerException, PostServiceException, ImageConverterException {
ParamUtility.checkStringNotNullOrEmpty(null, type, "type");
ParamUtility.checkNotNull(null, post, "post");
if (file != null) {
File outputFile = saveFile(file, true);
post.setPreview(outputFile.getName());
}
post.setType(PostType.fromName(type));
post.setCreationDate(new Date());
post.setModificationDate(new Date());
getPostService().createPost(post);
return redirectToViewPosts(type);
}
@RequestMapping(value = "/{type}/update.do")
public String updatePost(@PathVariable("type") String type, @RequestParam("id") long id, Post post,
@RequestParam(value = "previewpicture", required = false) CommonsMultipartFile file)
throws PostControllerException, PostServiceException, ImageConverterException {
ParamUtility.checkStringNotNullOrEmpty(null, type, "type");
ParamUtility.checkNotNull(null, post, "post");
Post originalPost = getPostService().getPost(id);
if (originalPost == null) {
throw new PostControllerException("Cannot find Post with the id: " + id);
}
deletePreviewFile(originalPost);
originalPost.setTitle(post.getTitle());
if (file != null) {
File outputFile = saveFile(file, true);
originalPost.setPreview(outputFile.getName());
}
originalPost.setContent(post.getContent());
originalPost.setModificationDate(new Date());
getPostService().updatePost(originalPost);
return redirectToViewPosts(type);
}
@RequestMapping("/{type}/delete.do")
public String deletePost(@PathVariable("type") String type, @RequestParam("id") long id)
throws PostServiceException, PostControllerException {
ParamUtility.checkStringNotNullOrEmpty(null, type, "type");
ParamUtility.checkNotNegative(null, id, "id");
Post post = getPostService().getPost(id);
if (post != null) {
deletePreviewFile(post);
getPostService().deletePost(id);
}
return redirectToViewPosts(type);
}
@RequestMapping("/upload.do")
public ModelAndView uploadFile(HttpServletRequest httpServletRequest) throws PostControllerException,
ImageConverterException {
MultipartRequest request;
try {
request = (MultipartRequest) httpServletRequest;
} catch (ClassCastException e) {
throw new PostControllerException("The request is not a multipart request.", e);
}
Iterator < String > iterator = request.getFileNames();
File outputFile = null;
if (iterator.hasNext()) {
outputFile = saveFile(request.getFile(iterator.next()), false);
}
ModelAndView mov = new ModelAndView(this.uploadFileView);
mov.addObject("fileId", outputFile.getName());
return mov;
}
public void setEditPostView(String editPostView) {
this.editPostView = editPostView;
}
public String getEditPostView() {
return editPostView;
}
private static String redirectToViewPosts(String type) {
return "redirect:/" + type + "/list.do";
}
private File saveFile(MultipartFile file, boolean preview) throws PostControllerException, ImageConverterException {
InputStream is = null;
FileOutputStream os = null;
File outputFile = null;
try {
is = file.getInputStream();
String originalFileName = file.getOriginalFilename().toLowerCase();
String extName = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
if (extName.equals(originalFileName)) {
extName = "";
} else {
extName = "." + extName;
}
outputFile = new File(getUploadFolder(), new Date().getTime() + extName);
os = new FileOutputStream(outputFile);
if (originalFileName.toLowerCase().endsWith(".gif") || originalFileName.toLowerCase().endsWith(".jpg")
|| originalFileName.toLowerCase().endsWith(".jpeg")
|| originalFileName.toLowerCase().endsWith(".tif")
|| originalFileName.toLowerCase().endsWith(".tiff")
|| originalFileName.toLowerCase().endsWith(".bmp")
|| originalFileName.toLowerCase().endsWith(".png")) {
if (preview) {
this.imageConverter.convert(is, os, this.previewImageWidth, true);
} else {
this.imageConverter.convert(is, os, this.maxImageWidth, true);
}
} else {
byte[] buffer = new byte[4096];
int len = is.read(buffer);
while (len != -1) {
os.write(buffer, 0, len);
len = is.read(buffer);
}
}
} catch (IOException e) {
throw new PostControllerException("Cannot upload file. IO exception: " + e.getMessage(), e);
} finally {
close(new Closeable[] {is, os});
}
return outputFile;
}
private void deletePreviewFile(Post post) throws PostControllerException {
if (post.getPreview() != null && post.getPreview().trim().length() != 0) {
File previewPic = new File(getUploadFolder(), post.getPreview());
if (previewPic.isFile()) {
if (!previewPic.delete()) {
getLogger().warn("The preview file associated with post " + post + " cannot be deleted.");
}
}
}
}
private File getUploadFolder() throws PostControllerException {
try {
return new File(ModifyPostController.class.getResource(getUploadDir()).toURI());
} catch (URISyntaxException e) {
throw new PostControllerException("Cannot find the upload folder. URI Syntax exception: " + e.getMessage(),
e);
}
}
public void setUploadFileView(String uploadFileView) {
this.uploadFileView = uploadFileView;
}
public String getUploadFileView() {
return uploadFileView;
}
public void setMaxImageWidth(int maxImageWidth) {
this.maxImageWidth = maxImageWidth;
}
public int getMaxImageWidth() {
return maxImageWidth;
}
public void setImageConverter(ImageConverter imageConverter) {
this.imageConverter = imageConverter;
}
public ImageConverter getImageConverter() {
return imageConverter;
}
public void setPreviewImageWidth(int previewImageWidth) {
this.previewImageWidth = previewImageWidth;
}
public int getPreviewImageWidth() {
return previewImageWidth;
}
}