/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.image.uploader.web.internal.portlet.action;
import com.liferay.document.library.kernel.antivirus.AntivirusScannerException;
import com.liferay.document.library.kernel.exception.FileExtensionException;
import com.liferay.document.library.kernel.exception.FileSizeException;
import com.liferay.document.library.kernel.exception.NoSuchFileEntryException;
import com.liferay.document.library.kernel.exception.NoSuchFileException;
import com.liferay.image.uploader.web.internal.constants.ImageUploaderPortletKeys;
import com.liferay.image.uploader.web.internal.util.UploadImageUtil;
import com.liferay.portal.kernel.exception.ImageTypeException;
import com.liferay.portal.kernel.exception.NoSuchRepositoryException;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.image.ImageBag;
import com.liferay.portal.kernel.image.ImageToolUtil;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.portlet.JSONPortletResponseUtil;
import com.liferay.portal.kernel.portlet.bridges.mvc.BaseMVCActionCommand;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCActionCommand;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.security.auth.PrincipalException;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.upload.UploadException;
import com.liferay.portal.kernel.upload.UploadPortletRequest;
import com.liferay.portal.kernel.upload.UploadRequestSizeException;
import com.liferay.portal.kernel.util.Constants;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.MimeTypesUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.StreamUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.TempFileEntryUtil;
import com.liferay.portal.kernel.util.TextFormatter;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.util.PrefsPropsUtil;
import com.liferay.portal.util.PropsValues;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.InputStream;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletRequest;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* @author Brian Wing Shun Chan
* @author Levente Hudák
*/
@Component(
immediate = true,
property = {
"javax.portlet.name=" + ImageUploaderPortletKeys.IMAGE_UPLOADER,
"mvc.command.name=/image_uploader/view"
},
service = MVCActionCommand.class
)
public class UploadImageMVCActionCommand extends BaseMVCActionCommand {
protected FileEntry addTempImageFileEntry(PortletRequest portletRequest)
throws Exception {
UploadPortletRequest uploadPortletRequest =
_portal.getUploadPortletRequest(portletRequest);
ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
WebKeys.THEME_DISPLAY);
String contentType = uploadPortletRequest.getContentType("fileName");
String fileName = uploadPortletRequest.getFileName("fileName");
File file = uploadPortletRequest.getFile("fileName");
String mimeType = MimeTypesUtil.getContentType(file, fileName);
if (!StringUtil.equalsIgnoreCase(
ContentTypes.APPLICATION_OCTET_STREAM, mimeType)) {
contentType = mimeType;
}
if (!MimeTypesUtil.isWebImage(contentType)) {
throw new ImageTypeException();
}
try {
TempFileEntryUtil.deleteTempFileEntry(
themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
UploadImageUtil.getTempImageFolderName(), fileName);
}
catch (Exception e) {
}
return TempFileEntryUtil.addTempFileEntry(
themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
UploadImageUtil.getTempImageFolderName(), fileName, file,
contentType);
}
@Override
protected void doProcessAction(
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
hideDefaultSuccessMessage(actionRequest);
String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
long maxFileSize = ParamUtil.getLong(actionRequest, "maxFileSize");
try {
UploadException uploadException =
(UploadException)actionRequest.getAttribute(
WebKeys.UPLOAD_EXCEPTION);
if (uploadException != null) {
Throwable cause = uploadException.getCause();
if (uploadException.isExceededFileSizeLimit()) {
throw new FileSizeException(cause);
}
if (uploadException.isExceededUploadRequestSizeLimit()) {
throw new UploadRequestSizeException(cause);
}
throw new PortalException(cause);
}
else if (cmd.equals(Constants.ADD_TEMP)) {
FileEntry tempImageFileEntry = addTempImageFileEntry(
actionRequest);
JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
jsonObject.put(
"tempImageFileName", tempImageFileEntry.getTitle());
JSONPortletResponseUtil.writeJSON(
actionRequest, actionResponse, jsonObject);
}
else {
FileEntry fileEntry = null;
boolean imageUploaded = ParamUtil.getBoolean(
actionRequest, "imageUploaded");
if (imageUploaded) {
fileEntry = saveTempImageFileEntry(actionRequest);
if (fileEntry.getSize() > maxFileSize) {
throw new FileSizeException();
}
}
SessionMessages.add(actionRequest, "imageUploaded", fileEntry);
sendRedirect(actionRequest, actionResponse);
}
}
catch (Exception e) {
handleUploadException(
actionRequest, actionResponse, cmd, maxFileSize, e);
}
}
protected String getTempImageFileName(PortletRequest portletRequest) {
return ParamUtil.getString(portletRequest, "tempImageFileName");
}
protected void handleUploadException(
ActionRequest actionRequest, ActionResponse actionResponse,
String cmd, long maxFileSize, Exception e)
throws Exception {
if (e instanceof PrincipalException) {
SessionErrors.add(actionRequest, e.getClass());
actionResponse.setRenderParameter("mvcPath", "/error.jsp");
}
else if (e instanceof AntivirusScannerException ||
e instanceof FileExtensionException ||
e instanceof FileSizeException ||
e instanceof ImageTypeException ||
e instanceof NoSuchFileException ||
e instanceof UploadException ||
e instanceof UploadRequestSizeException) {
if (cmd.equals(Constants.ADD_TEMP)) {
hideDefaultErrorMessage(actionRequest);
ThemeDisplay themeDisplay =
(ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
String errorMessage = StringPool.BLANK;
if (e instanceof AntivirusScannerException) {
AntivirusScannerException ase =
(AntivirusScannerException)e;
errorMessage = themeDisplay.translate(ase.getMessageKey());
}
else if (e instanceof FileExtensionException) {
errorMessage = themeDisplay.translate(
"please-enter-a-file-with-a-valid-extension-x",
StringUtil.merge(
PropsValues.DL_FILE_EXTENSIONS, StringPool.COMMA));
}
else if (e instanceof FileSizeException) {
if (maxFileSize == 0) {
maxFileSize = PrefsPropsUtil.getLong(
PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE);
}
errorMessage = themeDisplay.translate(
"please-enter-a-file-with-a-valid-file-size-no-" +
"larger-than-x",
TextFormatter.formatStorageSize(
maxFileSize, themeDisplay.getLocale()));
}
else if (e instanceof ImageTypeException) {
errorMessage = themeDisplay.translate(
"please-enter-a-file-with-a-valid-file-type");
}
else if (e instanceof NoSuchFileException ||
e instanceof UploadException) {
errorMessage = themeDisplay.translate(
"an-unexpected-error-occurred-while-uploading-your-" +
"file");
}
JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
jsonObject.put("errorMessage", errorMessage);
JSONPortletResponseUtil.writeJSON(
actionRequest, actionResponse, jsonObject);
}
else {
SessionErrors.add(actionRequest, e.getClass(), e);
}
}
else {
throw e;
}
}
protected FileEntry saveTempImageFileEntry(ActionRequest actionRequest)
throws Exception {
FileEntry tempFileEntry = null;
InputStream tempImageStream = null;
try {
tempFileEntry = UploadImageUtil.getTempImageFileEntry(
actionRequest);
tempImageStream = tempFileEntry.getContentStream();
ImageBag imageBag = ImageToolUtil.read(tempImageStream);
RenderedImage renderedImage = imageBag.getRenderedImage();
String cropRegionJSON = ParamUtil.getString(
actionRequest, "cropRegion");
if (Validator.isNotNull(cropRegionJSON)) {
JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
cropRegionJSON);
int height = jsonObject.getInt("height");
int width = jsonObject.getInt("width");
int x = jsonObject.getInt("x");
int y = jsonObject.getInt("y");
if ((x == 0) && (y == 0) &&
(renderedImage.getHeight() == height) &&
(renderedImage.getWidth() == width)) {
return tempFileEntry;
}
if ((height + y) > renderedImage.getHeight()) {
height = renderedImage.getHeight() - y;
}
if ((width + x) > renderedImage.getWidth()) {
width = renderedImage.getWidth() - x;
}
renderedImage = ImageToolUtil.crop(
renderedImage, height, width, x, y);
}
byte[] bytes = ImageToolUtil.getBytes(
renderedImage, imageBag.getType());
ThemeDisplay themeDisplay =
(ThemeDisplay)actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
File file = FileUtil.createTempFile(bytes);
try {
TempFileEntryUtil.deleteTempFileEntry(
themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
UploadImageUtil.getTempImageFolderName(),
getTempImageFileName(actionRequest));
}
catch (Exception e) {
}
return TempFileEntryUtil.addTempFileEntry(
themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
UploadImageUtil.getTempImageFolderName(),
getTempImageFileName(actionRequest), file,
tempFileEntry.getMimeType());
}
catch (NoSuchFileEntryException nsfee) {
throw new UploadException(nsfee);
}
catch (NoSuchRepositoryException nsre) {
throw new UploadException(nsre);
}
finally {
StreamUtil.cleanUp(tempImageStream);
}
}
private static final Log _log = LogFactoryUtil.getLog(
UploadImageMVCActionCommand.class);
@Reference
private Portal _portal;
}