package com.jspxcms.core.web.back;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.util.CollectionUtils;
import org.imgscalr.Scalr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.jspxcms.common.image.Images;
import com.jspxcms.common.util.Files;
import com.jspxcms.common.util.JsonMapper;
import com.jspxcms.common.web.PathResolver;
import com.jspxcms.common.web.Servlets;
import com.jspxcms.core.domain.GlobalUpload;
import com.jspxcms.core.domain.Site;
import com.jspxcms.core.domain.SiteWatermark;
import com.jspxcms.core.support.Context;
import com.jspxcms.core.support.UploadUtils;
/**
* UploadController
*
* @author liufang
*
*/
@Controller
@RequestMapping("/core")
public class UploadController {
private static final Logger logger = LoggerFactory
.getLogger(UploadController.class);
@RequiresPermissions("core:upload:image")
@RequestMapping(value = "upload_image.do", method = RequestMethod.POST)
public void uploadImage(Boolean scale, Integer width, Integer height,
Boolean thumbnail, Integer thumbnailWidth, Integer thumbnailHeight,
Boolean watermark, HttpServletRequest request,
HttpServletResponse response) throws IOException {
upload(request, response, UploadUtils.IMAGE, scale, width, height,
thumbnail, thumbnailWidth, thumbnailHeight, watermark);
}
@RequiresPermissions("core:upload:flash")
@RequestMapping(value = "upload_flash.do", method = RequestMethod.POST)
public void uploadFlash(HttpServletRequest request,
HttpServletResponse response) throws IOException {
upload(request, response, UploadUtils.FLASH);
}
@RequiresPermissions("core:upload:file")
@RequestMapping(value = "upload_file.do", method = RequestMethod.POST)
public void uploadFile(HttpServletRequest request,
HttpServletResponse response) throws IOException {
upload(request, response, UploadUtils.FILE);
}
@RequiresPermissions("core:upload:video")
@RequestMapping(value = "upload_video.do", method = RequestMethod.POST)
public void uploadVideo(HttpServletRequest request,
HttpServletResponse response) throws IOException {
upload(request, response, UploadUtils.VIDEO);
}
private void upload(HttpServletRequest request,
HttpServletResponse response, String type) throws IOException {
upload(request, response, type, null, null, null, null, null, null,
null);
}
private void upload(HttpServletRequest request,
HttpServletResponse response, String type, Boolean scale,
Integer width, Integer height, Boolean thumbnail,
Integer thumbnailWidth, Integer thumbnailHeight, Boolean watermark)
throws IOException {
Site site = Context.getCurrentSite(request);
String contextPath = request.getContextPath();
MultipartFile file = getUploadFile(request);
Map<String, Object> resultMap = doUpload(file, type, site, contextPath,
scale, width, height, thumbnail, thumbnailWidth,
thumbnailHeight, watermark);
String ckeditor = request.getParameter("CKEditor");
if (ckeditor != null) {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out = response.getWriter();
String error = resultMap.get("error").toString();
String callback = request.getParameter("CKEditorFuncNum");
out.println("<script type=\"text/javascript\">");
out.println("(function(){var d=document.domain;while (true){try{var A=window.parent.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();\n");
if (StringUtils.isBlank(error)) {
String fileUrl = resultMap.get("fileUrl").toString();
out.println("window.parent.CKEDITOR.tools.callFunction("
+ callback + ",'" + fileUrl + "',''" + ");");
} else {
out.println("alert('" + error + "');");
}
out.print("</script>");
out.flush();
out.close();
}
JsonMapper mapper = new JsonMapper();
String json = mapper.toJson(resultMap);
logger.debug(json);
Servlets.writeHtml(response, json);
}
private Map<String, Object> doUpload(MultipartFile file, String type,
Site site, String contextPath, Boolean scale, Integer width,
Integer height, Boolean thumbnail, Integer thumbnailWidth,
Integer thumbnailHeight, Boolean watermark) {
Map<String, Object> map = new HashMap<String, Object>();
if (file == null || file.isEmpty()) {
logger.debug("file is empty");
map.put("error", "no file upload!");
return map;
}
SiteWatermark sw = site.getWatermark();
String extension = FilenameUtils.getExtension(
file.getOriginalFilename()).toLowerCase();
GlobalUpload gu = site.getGlobal().getUpload();
if (UploadUtils.IMAGE.equals(type)
&& !gu.isImageExtensionValid(extension)) {
logger.debug("image extension not allowed: " + extension);
map.put("error", "image extension not allowed: " + extension);
return map;
} else if (UploadUtils.FILE.equals(type)
&& !gu.isFileExtensionValid(extension)) {
logger.debug("file extension not allowed: " + extension);
map.put("error", "file extension not allowed: " + extension);
return map;
} else if (UploadUtils.VIDEO.equals(type)
&& !gu.isVideoExtensionValid(extension)) {
logger.debug("video extension not allowed: " + extension);
map.put("error", "video extension not allowed: " + extension);
return map;
} else if (UploadUtils.FLASH.equals(type)
&& !gu.isFlashExtensionValid(extension)) {
logger.debug("flash extension not allowed: " + extension);
map.put("error", "flash extension not allowed: " + extension);
return map;
}
if (!UploadUtils.IMAGE.equals(type) || scale == null || width == null
|| height == null) {
scale = false;
}
if (!UploadUtils.IMAGE.equals(type) || thumbnail == null
|| thumbnailWidth == null || thumbnailHeight == null) {
thumbnail = false;
}
if (!UploadUtils.IMAGE.equals(type) || watermark == null
|| sw.getMode() == SiteWatermark.MODE_OFF
|| StringUtils.isBlank(sw.getImageUrl())) {
watermark = false;
}
if (watermark || scale || thumbnail) {
try {
if (!Images.isImageExtension(extension)
|| !Images.isImage(file.getInputStream())) {
watermark = false;
scale = false;
thumbnail = false;
}
} catch (IOException e) {
logger.error("", e);
watermark = false;
scale = false;
thumbnail = false;
}
}
String url = UploadUtils.getUrl(site.getId(), type, extension);
File dest = getDestFile(url);
try {
dest.mkdirs();
if (scale || watermark || thumbnail) {
if (scale) {
BufferedImage buff = ImageIO.read(file.getInputStream());
buff = Scalr.resize(buff, Scalr.Method.QUALITY, width,
height);
}
storeImg(file, scale, width, height, thumbnail, thumbnailWidth,
thumbnailHeight, watermark, sw, dest, extension);
} else {
file.transferTo(dest);
}
String fileName = file.getOriginalFilename();
long fileLength = file.getSize();
String fileUrl;
if (StringUtils.isNotBlank(contextPath)) {
fileUrl = contextPath + url;
} else {
fileUrl = url;
}
map.put("error", "");
map.put("fileUrl", fileUrl);
map.put("fileName", fileName);
map.put("fileLength", fileLength);
map.put("fileExtension", extension);
} catch (IllegalStateException e) {
logger.error("", e);
map.put("error", e.getMessage());
} catch (IOException e) {
logger.error("", e);
map.put("error", e.getMessage());
}
return map;
}
private MultipartFile getUploadFile(HttpServletRequest request) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
if (CollectionUtils.isEmpty(fileMap)) {
throw new IllegalStateException("No upload file found!");
}
return fileMap.entrySet().iterator().next().getValue();
}
private File getDestFile(String url) {
String real = pathResolver.getPath(url);
logger.debug("file path: " + real);
File dest = new File(real);
dest = Files.getUniqueFile(dest);
return dest;
}
private void storeImg(MultipartFile file, boolean scale, Integer width,
Integer height, boolean thumbnail, Integer thumbnailWidth,
Integer thumbnailHeight, boolean watermark, SiteWatermark sw,
File dest, String extension) throws IOException {
BufferedImage buff = ImageIO.read(file.getInputStream());
if (scale) {
buff = Scalr.resize(buff, Scalr.Method.QUALITY, width, height);
}
if (thumbnail) {
BufferedImage thumbnailBuff = Scalr.resize(buff,
Scalr.Method.QUALITY, thumbnailWidth, thumbnailHeight);
File thumbnailFile = new File(UploadUtils.getThumbnailPath(dest
.getAbsolutePath()));
ImageIO.write(thumbnailBuff, extension, thumbnailFile);
}
if (watermark) {
String watermarkPath = pathResolver.getPath(sw.getImagePath());
File watermarkFile = new File(watermarkPath);
BufferedImage watermarkBuff = ImageIO.read(watermarkFile);
Images.watermark(buff, watermarkBuff, sw.getPosition(),
sw.getPaddingX(), sw.getPaddingY(), sw.getAlpha(),
sw.getMinWidth(), sw.getMinHeight());
}
ImageIO.write(buff, extension, dest);
}
private PathResolver pathResolver;
@Autowired
public void setPathResolver(PathResolver pathResolver) {
this.pathResolver = pathResolver;
}
}