/** * */ package org.gcube.portlets.widgets.workspaceuploader.server; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Calendar; import java.util.LinkedHashMap; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileItemStream; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.util.Streams; import org.apache.commons.io.FilenameUtils; import org.gcube.common.homelibary.model.items.type.WorkspaceItemType; import org.gcube.common.homelibrary.home.exceptions.InternalErrorException; import org.gcube.common.homelibrary.home.workspace.Workspace; import org.gcube.common.homelibrary.home.workspace.WorkspaceFolder; import org.gcube.common.homelibrary.home.workspace.WorkspaceItem; import org.gcube.common.homelibrary.home.workspace.exceptions.InsufficientPrivilegesException; import org.gcube.common.homelibrary.home.workspace.exceptions.ItemAlreadyExistException; import org.gcube.common.homelibrary.home.workspace.exceptions.ItemNotFoundException; import org.gcube.common.homelibrary.home.workspace.exceptions.WorkspaceFolderNotFoundException; import org.gcube.common.homelibrary.home.workspace.exceptions.WrongDestinationException; import org.gcube.common.homelibrary.home.workspace.exceptions.WrongItemTypeException; import org.gcube.common.homelibrary.home.workspace.folder.FolderItem; import org.gcube.common.homelibrary.home.workspace.folder.items.Report; import org.gcube.common.homelibrary.home.workspace.folder.items.ReportTemplate; import org.gcube.common.homelibrary.util.Extensions; import org.gcube.common.homelibrary.util.MimeTypeUtil; import org.gcube.common.homelibrary.util.WorkspaceUtil; import org.gcube.portlets.widgets.workspaceuploader.client.ConstantsWorkspaceUploader; import org.gcube.portlets.widgets.workspaceuploader.server.notification.NotificationsWorkspaceUploader; import org.gcube.portlets.widgets.workspaceuploader.server.upload.AbstractUploadProgressListener; import org.gcube.portlets.widgets.workspaceuploader.server.upload.MemoryUploadListener; import org.gcube.portlets.widgets.workspaceuploader.server.upload.UploadCanceledException; import org.gcube.portlets.widgets.workspaceuploader.server.upload.UploadProgressInputStream; import org.gcube.portlets.widgets.workspaceuploader.server.upload.UploadProgressListener; import org.gcube.portlets.widgets.workspaceuploader.server.upload.WorkspaceUploaderMng; import org.gcube.portlets.widgets.workspaceuploader.server.util.WsUtil; import org.gcube.portlets.widgets.workspaceuploader.shared.HandlerResultMessage; import org.gcube.portlets.widgets.workspaceuploader.shared.WorkspaceUploadFile; import org.gcube.portlets.widgets.workspaceuploader.shared.WorkspaceUploaderItem; import org.gcube.portlets.widgets.workspaceuploader.shared.WorkspaceUploaderItem.UPLOAD_STATUS; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The Class WorkspaceUploadServletStream. * * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it * @Jan 21, 2014 */ public class WorkspaceUploadServletStream extends HttpServlet implements Servlet{ public static final String UNKNOWN_UNKNOWN = "unknown/unknown"; private static final long serialVersionUID = 1778008252774571216L; protected static final String UTF_8 = "UTF-8"; public static final String UPLOAD_TYPE = ConstantsWorkspaceUploader.UPLOAD_TYPE; public static final String ID_FOLDER = ConstantsWorkspaceUploader.ID_FOLDER; public static final String UPLOAD_FORM_ELEMENT = ConstantsWorkspaceUploader.UPLOAD_FORM_ELEMENT; public static final String CLIENT_UPLOAD_KEYS = ConstantsWorkspaceUploader.CLIENT_UPLOAD_KEYS; public static final String JSON_CLIENT_KEYS = ConstantsWorkspaceUploader.JSON_CLIENT_KEYS; public static final String IS_OVERWRITE = ConstantsWorkspaceUploader.IS_OVERWRITE; public static final String CANCEL_UPLOAD = ConstantsWorkspaceUploader.CANCEL_UPLOAD; public static final String FILE = "File"; public static final String D4ST = Extensions.REPORT_TEMPLATE.getName(); //extension of Report Template type public static final String D4SR = Extensions.REPORT.getName(); //extension of Report type public static Logger logger = LoggerFactory.getLogger(WorkspaceUploadServletStream.class); private static boolean appEngine = false; /* * (non-Javadoc) * * @see javax.servlet.GenericServlet#init() */ @Override public void init() throws ServletException { super.init(); String appe = getInitParameter("appEngine"); if (appe != null) { appEngine = "true".equalsIgnoreCase(appe); } else { appEngine = isAppEngine(); } logger.debug("init: appEngine is "+appEngine); } /** * {@inheritDoc} */ @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.debug("GET method in "+WorkspaceUploadServletStream.class.getName()+" is running"); String clientUploadKey = request.getParameter(CLIENT_UPLOAD_KEYS); if (clientUploadKey == null){ sendError(response, "Internal error: UPLOAD KEY NOT FOUND"); return; } logger.debug("GET method CLIENT_UPLOAD_KEY "+clientUploadKey); boolean cancelUpload = Boolean.parseBoolean(request.getParameter(CANCEL_UPLOAD)); logger.debug("GET method CANCEL_UPLOAD "+cancelUpload); if (cancelUpload) { cancelUpload(request.getSession(), clientUploadKey); sendMessage(response, "Upload abort: "+request.getParameter(CANCEL_UPLOAD)); }else logger.debug(CANCEL_UPLOAD + " param not found"); // }else // sendError(response, "Internal error: CANCEL_UPLOAD NOT FOUND"); return; } /** * {@inheritDoc} */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("POST on UploadServlet"); logger.info("POST on UploadServlet"); if (!ServletFileUpload.isMultipartContent(request)) { logger.error("ERROR: multipart request not found"); sendError(response, "ERROR: multipart request not found"); } HttpSession session = request.getSession(); logger.debug("UPLOAD-SERVLET (" + session.getId() + ") new upload request received."); String destinationId = null; String uploadType = null; boolean isOverwrite = false; // String clientUploadKey = null; FileItemStream uploadItem = null; ArrayList listClientUploadKeys = null; FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload servletFileUpload = new ServletFileUpload(factory); try { /** * An iterator to instances of FileItemStream * parsed from the request, in the order that they were *transmitted. */ FileItemIterator fileItemIterator = servletFileUpload.getItemIterator(request); int uploadItemsCnt = 0; //GET FILE STREAM while (fileItemIterator.hasNext()) { FileItemStream item = fileItemIterator.next(); if (item.isFormField() && ID_FOLDER.equals(item.getFieldName())){ destinationId = Streams.asString(item.openStream()); logger.debug("ID_FOLDER OK "+destinationId); } if (item.isFormField() && UPLOAD_TYPE.equals(item.getFieldName())){ uploadType = Streams.asString(item.openStream()); logger.debug("UPLOAD_TYPE OK " +uploadType); } if (item.isFormField() && IS_OVERWRITE.equals(item.getFieldName())){ isOverwrite = Boolean.parseBoolean(Streams.asString(item.openStream())); logger.debug("IS_OVERWRITE OK "+ isOverwrite); } if(item.isFormField() && CLIENT_UPLOAD_KEYS.equals(item.getFieldName())){ String jsonClientUploadKey = Streams.asString(item.openStream()); logger.debug("CLIENT_UPLOAD_KEY OK "+jsonClientUploadKey); LinkedHashMap mapKeys = parseJSONClientUploadKeys(jsonClientUploadKey); listClientUploadKeys = new ArrayList(mapKeys.keySet()); removeListenersIfDone(session, listClientUploadKeys); for (String clientUploadKey : listClientUploadKeys) { String fileName = mapKeys.get(clientUploadKey); WorkspaceUploaderItem workspaceUploader = createNewWorkspaceUploader(clientUploadKey,destinationId,mapKeys.get(clientUploadKey)); logger.debug("created "+workspaceUploader); saveWorkspaceUploaderStatus(workspaceUploader, UPLOAD_STATUS.WAIT, "Uploading "+fileName+" at 0%", request.getSession()); } } //MUST BE THE LAST PARAMETER TRASMITTED if (UPLOAD_FORM_ELEMENT.equals(item.getFieldName())){ uploadItem = item; logger.debug("UPLOAD_FORM_ELEMENT OK "+uploadItem.getName()); // break; uploadData(request, response, uploadItem, destinationId, uploadType, listClientUploadKeys.get(uploadItemsCnt), isOverwrite); uploadItemsCnt++; } } } catch (FileUploadException e) { logger.error("Error processing request in upload servlet", e); sendError(response, "Internal error: Error during request processing"); return; } } /** * Removes the listener if done. * * @param session the session * @param keys the keys */ private void removeListenersIfDone(HttpSession session, List keys){ for (String key : keys) { AbstractUploadProgressListener listener = getCurrentListener(session, key); if (listener != null) { logger.debug("Listener found"); if (listener.isCanceled() || listener.getPercentage() >= 100){ logger.debug("Listener isCanceled or 100%, removing"); removeCurrentListener(session, key); } }else logger.debug("Session id: "+session.getId() +" - "+key+" - Listener not found"); } } /** * Parses the json client upload keys. * * @param jsonClientUploadKeys the json client upload keys * @return the linked hash map * @throws FileUploadException the file upload exception */ @SuppressWarnings("rawtypes") private static LinkedHashMap parseJSONClientUploadKeys(final String jsonClientUploadKeys) throws FileUploadException{ JSONTokener tokener = new JSONTokener(jsonClientUploadKeys); JSONObject root; LinkedHashMap keyFiles = null; try { root = new JSONObject(tokener); JSONArray jsonArray = root.getJSONArray(JSON_CLIENT_KEYS); keyFiles = new LinkedHashMap(jsonArray.length()); logger.debug("jsonArray :"+jsonArray.toString()); for (int i=0; i