Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.PARAMETER_UPLOADED_FILE;
import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_HEIGHT;
import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_WIDTH;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.UserMistakeException;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.filestorage.TempFileHolder;
import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper;
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileAlreadyExistsException;
import edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage;
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.CropRectangle;
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.Dimensions;
import edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor.ImageProcessorException;
/**
* Handle the mechanics of validating, storing, and deleting file images.
*/
public class ImageUploadHelper {
private static final Log log = LogFactory.getLog(ImageUploadHelper.class);
/*
* Keys to text strings for error messages.
*/
private static final String ERROR_CODE_NO_IMAGE_TO_CROP = "imageUpload.errorNoImageForCropping";
private static final String ERROR_CODE_IMAGE_TOO_SMALL = "imageUpload.errorImageTooSmall";
private static final String ERROR_CODE_UNKNOWN = "imageUpload.errorUnknown";
private static final String ERROR_CODE_UNRECOGNIZED_FILE_TYPE = "imageUpload.errorUnrecognizedFileType";
private static final String ERROR_CODE_NO_PHOTO_SELECTED = "imageUpload.errorNoPhotoSelected";
private static final String ERROR_CODE_BAD_MULTIPART_REQUEST = "imageUpload.errorBadMultipartRequest";
private static final String ERROR_CODE_FORM_FIELD_MISSING = "imageUpload.errorFormFieldMissing";
/**
* When they upload a new image, store it as this session attribute until
* we're ready to attach it to the Individual.
*/
public static final String ATTRIBUTE_TEMP_FILE = "ImageUploadHelper.tempFile";
/**
* If the main image is larger than this, it will be displayed at reduced
* scale.
*/
public static final int MAXIMUM_IMAGE_DISPLAY_WIDTH = 500;
/** Recognized file extensions mapped to MIME-types. */
private static final Map RECOGNIZED_FILE_TYPES = createFileTypesMap();
/** Browser-specific MIME-types mapped to recognized MIME-types. */
private static final Map NON_STANDARD_MIME_TYPES = createNonStandardMimeTypesMap();
private static Map createFileTypesMap() {
Map map = new HashMap();
map.put(".gif", "image/gif");
map.put(".png", "image/png");
map.put(".jpg", "image/jpeg");
map.put(".jpeg", "image/jpeg");
map.put(".jpe", "image/jpeg");
return Collections.unmodifiableMap(map);
}
/**
* Internet Explorer can tell us that an image has a funky
* Microsoft-specific MIME-type, and we can replace it with one that
* everyone recognizes. This table records those types.
*/
private static Map createNonStandardMimeTypesMap() {
Map map = new HashMap();
map.put("image/x-png", "image/png");
map.put("image/pjpeg", "image/jpeg");
return Collections.unmodifiableMap(map);
}
private final FileStorage fileStorage;
private final UploadedFileHelper uploadedFileHelper;
ImageUploadHelper(FileStorage fileStorage,
WebappDaoFactory webAppDaoFactory, ServletContext ctx) {
this.fileStorage = fileStorage;
this.uploadedFileHelper = new UploadedFileHelper(fileStorage,
webAppDaoFactory, ctx);
}
/**
* The image must be present and non-empty, and must have a mime-type that
* represents an image we support.
*
* We rely on the fact that a FileUploadServletRequest will always
* have a map of {@link FileItem}s, even if it is empty. However, that map
* may not contain the field that we want, or that field may contain an
* empty file.
*
* @throws UserMistakeException
* if there is no file, if it is empty, or if it is not an image
* file.
*/
FileItem validateImageFromRequest(VitroRequest vreq)
throws UserMistakeException {
Map> map = vreq.getFiles();
if (map == null) {
throw new IllegalStateException(ERROR_CODE_BAD_MULTIPART_REQUEST);
}
List list = map.get(PARAMETER_UPLOADED_FILE);
if ((list == null) || list.isEmpty()) {
throw new UserMistakeException(ERROR_CODE_FORM_FIELD_MISSING,
PARAMETER_UPLOADED_FILE);
}
FileItem file = list.get(0);
if (file.getSize() == 0) {
throw new UserMistakeException(ERROR_CODE_NO_PHOTO_SELECTED);
}
String filename = getSimpleFilename(file);
String mimeType = getMimeType(file);
if (!RECOGNIZED_FILE_TYPES.containsValue(mimeType)) {
log.debug("Unrecognized MIME type: '" + mimeType + "'");
throw new UserMistakeException(ERROR_CODE_UNRECOGNIZED_FILE_TYPE,
filename);
}
return file;
}
/**
* The user has uploaded a new main image, but we're not ready to assign it
* to them.
*
* Put it into the file storage system, and attach it as a temp file on the
* session until we need it.
*/
FileInfo storeNewImage(FileItem fileItem, VitroRequest vreq) {
InputStream inputStream = null;
try {
inputStream = fileItem.getInputStream();
String mimeType = getMimeType(fileItem);
String filename = getSimpleFilename(fileItem);
FileInfo fileInfo = uploadedFileHelper.createFile(filename,
mimeType, inputStream);
TempFileHolder.attach(vreq.getSession(), ATTRIBUTE_TEMP_FILE,
fileInfo);
return fileInfo;
} catch (IOException e) {
throw new IllegalStateException("Can't create the new image file.",
e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Find out how big this image is.
*
* @throws UserMistakeException
* if the image is smaller than a thumbnail.
*/
Dimensions getNewImageSize(FileInfo fileInfo) throws UserMistakeException {
InputStream source = null;
try {
String uri = fileInfo.getBytestreamUri();
String filename = fileInfo.getFilename();
source = fileStorage.getInputStream(uri, filename);
Dimensions size = ApplicationUtils.instance().getImageProcessor()
.getDimensions(source);
log.debug("new image size is " + size);
if ((size.height < THUMBNAIL_HEIGHT)
|| (size.width < THUMBNAIL_WIDTH)) {
throw new UserMistakeException(ERROR_CODE_IMAGE_TOO_SMALL,
THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH);
}
return size;
} catch (FileNotFoundException e) {
throw new IllegalStateException("File not found: " + fileInfo, e);
} catch (IOException e) {
throw new IllegalStateException("Can't read image file: "
+ fileInfo, e);
} catch (UserMistakeException e) {
throw e;
} catch (Exception e) {
log.warn("Unexpected exception in image handling", e);
throw new UserMistakeException(ERROR_CODE_UNKNOWN);
} finally {
if (source != null) {
try {
source.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Get the info for the new image, from where we stored it in the session.
*
* @throws UserMistakeException
* if it isn't there.
*/
FileInfo getNewImageInfo(VitroRequest vreq) throws UserMistakeException {
FileInfo fileInfo = TempFileHolder.remove(vreq.getSession(),
ATTRIBUTE_TEMP_FILE);
if (fileInfo == null) {
throw new UserMistakeException(ERROR_CODE_NO_IMAGE_TO_CROP);
}
return fileInfo;
}
/**
* Crop the main image to create the thumbnail, and put it into the file
* storage system.
*/
FileInfo generateThumbnail(CropRectangle crop, FileInfo newImage) {
InputStream mainStream = null;
InputStream thumbStream = null;
try {
String mainBytestreamUri = newImage.getBytestreamUri();
String mainFilename = newImage.getFilename();
mainStream = fileStorage.getInputStream(mainBytestreamUri,
mainFilename);
thumbStream = ApplicationUtils
.instance()
.getImageProcessor()
.cropAndScale(mainStream, crop,
new Dimensions(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT));
String mimeType = RECOGNIZED_FILE_TYPES.get(".jpg");
String filename = createThumbnailFilename(mainFilename);
FileInfo fileInfo = uploadedFileHelper.createFile(filename,
mimeType, thumbStream);
log.debug("Created thumbnail: " + fileInfo);
return fileInfo;
} catch (FileAlreadyExistsException e) {
throw new IllegalStateException("Can't create the thumbnail file: "
+ e.getMessage(), e);
} catch (IOException e) {
throw new IllegalStateException("Can't create the thumbnail file",
e);
} catch (ImageProcessorException e) {
throw new IllegalStateException("Failed to scale the image", e);
} finally {
if (mainStream != null) {
try {
mainStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (thumbStream != null) {
try {
thumbStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* If this entity already had a main image, remove it. If the image and the
* thumbnail are no longer used by anyone, throw them away.
*/
void removeExistingImage(Individual person) {
uploadedFileHelper.removeMainImage(person);
}
/**
* Store the image on the entity, and the thumbnail on the image.
*/
void storeImageFiles(Individual entity, FileInfo newImage,
FileInfo thumbnail) {
uploadedFileHelper.setImagesOnEntity(entity.getURI(), newImage,
thumbnail);
}
/**
* Internet Explorer and Opera will give you the full path along with the
* filename. This will remove the path.
*/
private String getSimpleFilename(FileItem item) {
String fileName = item.getName();
if (fileName == null) {
return null;
} else {
return FilenameUtils.getName(fileName);
}
}
/**
* Get the MIME type as supplied by the browser. If none, try to infer it
* from the filename extension and the map of recognized MIME types.
*/
private String getMimeType(FileItem file) {
String mimeType = file.getContentType();
if (mimeType != null) {
// If the browser supplied the MIME type, we may need to
// replace it with the standard value.
if (NON_STANDARD_MIME_TYPES.containsKey(mimeType)) {
mimeType = NON_STANDARD_MIME_TYPES.get(mimeType);
}
return mimeType;
}
String filename = getSimpleFilename(file);
int periodHere = filename.lastIndexOf('.');
if (periodHere == -1) {
return null;
}
String extension = filename.substring(periodHere);
return RECOGNIZED_FILE_TYPES.get(extension);
}
/**
* Create a name for the thumbnail from the name of the original file.
* "myPicture.anything" becomes "thumbnail_myPicture.jpg".
*/
private String createThumbnailFilename(String filename) {
String prefix = "thumbnail_";
String extension = ".jpg";
int periodHere = filename.lastIndexOf('.');
if (periodHere == -1) {
return prefix + filename + extension;
} else {
return prefix + filename.substring(0, periodHere) + extension;
}
}
}