net.anotheria.anosite.photoserver.api.upload.PhotoUploader Maven / Gradle / Ivy
package net.anotheria.anosite.photoserver.api.upload;
import net.anotheria.anosite.photoserver.presentation.shared.PhotoDimension;
import net.anotheria.anosite.photoserver.presentation.shared.PhotoUtil;
import net.anotheria.anosite.photoserver.service.storage.StorageConfig;
import net.anotheria.anosite.photoserver.shared.vo.TempPhotoVO;
import net.anotheria.util.StringUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
public class PhotoUploader implements ProgressListener {
private static final Logger LOG = LoggerFactory.getLogger(PhotoUploader.class);
private static final PhotoUploadAPIConfig uploadConfig = PhotoUploadAPIConfig.getInstance();
private UploadStatusAO status;
private TempPhotoVO photo;
private String id;
private String userId;
private static final String PARAM_UPLOAD_LINK = "pLink";
private static final int CONNECTION_TIMEOUT = 5000; // millisecond
public PhotoUploader(String uploaderId, String userId) {
status = new UploadStatusAO(UploadStatusAO.STATUS_NOT_STARTED);
status.setId(uploaderId);
this.id = uploaderId;
this.userId = userId;
}
public String getId() {
return id;
}
/**
* Gets status of upload (e.g. how many percent of the file is uploaded). If status is set to STATUS_FINISHED then additional infos like filetype, size and
* original filename are set. Also the file can be stored using the InputStream provided.
*
*/
public UploadStatusAO getStatus() {
return status;
}
public TempPhotoVO getUploadedPhoto() {
return photo;
}
@SuppressWarnings("unchecked")
public void doUpload(HttpServletRequest request) {
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(uploadConfig.getMaxUploadFileSize());
upload.setProgressListener(this);
try {
List items = new ArrayList();
if (ServletFileUpload.isMultipartContent(request))
items.addAll(upload.parseRequest(request)); // uploading form data
// uploading by link (if link exist)
boolean result = uploadByLink(request, factory, items);
if (result) // exiting from method if uploading by link fail
return;
for (FileItem item : items) {
// get handle to uploaded file
if (!item.isFormField()) {
if (!uploadConfig.isAllowedMimeType(item.getContentType()) && !uploadConfig.isAllowedLinkEndType(item.getName())) {
status.setStatus(UploadStatusAO.STATUS_ERROR_REJECTED);
return;
}
// convert and scale uploaded file
PhotoUtil photoUtil = new PhotoUtil();
photoUtil.read(item.getInputStream());
if (photoUtil.getWidth() > uploadConfig.getMaxWidth()) {
photoUtil.scale(uploadConfig.getMaxWidth(), -1);
}
if (photoUtil.getHeight() > uploadConfig.getMaxHeight()) {
photoUtil.scale(-1, uploadConfig.getMaxHeight());
}
File baseFolder = new File(StorageConfig.getTmpStoreFolderPath(userId));
baseFolder.mkdirs();
File tmpFile = new File(baseFolder, System.currentTimeMillis() + uploadConfig.getFilePrefix());
photoUtil.write(uploadConfig.getJpegQuality(), tmpFile);
photo = new TempPhotoVO();
photo.setFile(tmpFile);
photo.setDimension(new PhotoDimension(photoUtil.getWidth(), photoUtil.getHeight()));
status.setFilename(item.getName());
status.setSize(item.getSize());
status.setStatus(UploadStatusAO.STATUS_FINISHED);
item.delete();
}
}
} catch (SizeLimitExceededException e) {
status.setStatus(UploadStatusAO.STATUS_ERROR_MAX_FILESIZE_EXCEEDED);
LOG.debug(id + ": UploadStatus=MAX_FILESIZE_EXCEEDED");
} catch (FileUploadException e) {
status.setStatus(UploadStatusAO.STATUS_ERROR_UPLOADEXCEPTION);
LOG.error(id, e);
} catch (IOException e) {
status.setStatus(UploadStatusAO.STATUS_ERROR_UPLOADEXCEPTION);
LOG.error(id, e);
}
}
private boolean uploadByLink(final HttpServletRequest request, final FileItemFactory factory, List items) {
// trying to upload additional photo by link
Object link = request.getAttribute(PARAM_UPLOAD_LINK);
if (!(link instanceof String)) // if basic param null trying to get it from form data
for (FileItem item : items)
if (item.isFormField() && item.getFieldName().equals(PARAM_UPLOAD_LINK) && !StringUtils.isEmpty(item.getString()))
link = item.getString();
InputStream is = null;
if (link instanceof String) {
try {
URL url = new URL(String.class.cast(link));
URLConnection conn = url.openConnection();
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.connect();
// checking content type
if (!uploadConfig.isAllowedMimeType(conn.getContentType()) && !uploadConfig.isAllowedLinkEndType(conn.getURL().getFile())) {
status.setStatus(UploadStatusAO.STATUS_ERROR_REJECTED);
return true;
}
String[] linkSegments = String.class.cast(link).split("/");
String resourceName = "uploaded";
if (linkSegments != null && linkSegments.length > 0)
resourceName = linkSegments[linkSegments.length - 1];
FileItem file = factory.createItem(PARAM_UPLOAD_LINK, conn.getContentType(), false, resourceName);
is = conn.getInputStream();
IOUtils.copyLarge(is, file.getOutputStream());
file.getOutputStream().flush();
items.add(file);
} catch (SocketTimeoutException e) {
status.setStatus(UploadStatusAO.STATUS_ERROR_UPLOADEXCEPTION);
LOG.debug(id, e);
return true;
} catch (MalformedURLException e) {
status.setStatus(UploadStatusAO.STATUS_ERROR_UPLOADEXCEPTION);
LOG.debug(id, e);
return true;
} catch (IOException e) {
status.setStatus(UploadStatusAO.STATUS_ERROR_UPLOADEXCEPTION);
LOG.debug(id, e);
return true;
} finally {
IOUtils.closeQuietly(is);
}
}
return false;
}
@Override
public void update(long bytesRead, long contentLength, int item) {
status.setProgress((int) (((float) bytesRead / (float) contentLength) * 100f));
status.setStatus(UploadStatusAO.STATUS_UPLOADING);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy