diff --git a/core/pom.xml b/core/pom.xml index 021fe1a..926abce 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -9,7 +9,7 @@ com.googlecode.gwtupload gwtupload-project - 1.0.4-SNAPSHOT + 1.0.4-p1 @@ -19,6 +19,12 @@ ${gwtVersion} provided + + com.google.gwt + gwt-dev + ${gwtVersion} + provided + junit junit diff --git a/core/src/main/java/gwtupload/client/AbstractMultiUploader.java b/core/src/main/java/gwtupload/client/AbstractMultiUploader.java index 975fafe..08b7d03 100644 --- a/core/src/main/java/gwtupload/client/AbstractMultiUploader.java +++ b/core/src/main/java/gwtupload/client/AbstractMultiUploader.java @@ -31,7 +31,6 @@ import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.uibinder.client.UiChild; -import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; diff --git a/core/src/main/java/gwtupload/client/IUploadStatus.java b/core/src/main/java/gwtupload/client/IUploadStatus.java index 97e0756..cf53a3b 100644 --- a/core/src/main/java/gwtupload/client/IUploadStatus.java +++ b/core/src/main/java/gwtupload/client/IUploadStatus.java @@ -20,9 +20,6 @@ import java.util.List; import java.util.Set; -import gwtupload.client.IUploadStatus.CancelBehavior; - -import com.google.appengine.api.datastore.Link; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.i18n.client.Constants; diff --git a/core/src/main/java/gwtupload/client/IUploader.java b/core/src/main/java/gwtupload/client/IUploader.java index 8845de9..b1727be 100644 --- a/core/src/main/java/gwtupload/client/IUploader.java +++ b/core/src/main/java/gwtupload/client/IUploader.java @@ -112,7 +112,7 @@ public String toString() { /** * Size in bytes calculated in the server */ - public int size = 0; + public long size = 0; /** * Used when the server sends a special key to identify the file. @@ -143,7 +143,7 @@ public String getCtype() { return ctype; } - public int getSize() { + public long getSize() { return size; } @@ -163,7 +163,7 @@ public void setCtype(String ctype) { this.ctype = ctype; } - public void setSize(int size) { + public void setSize(long size) { this.size = size; } diff --git a/core/src/main/java/gwtupload/client/MultipleFileUpload.java b/core/src/main/java/gwtupload/client/MultipleFileUpload.java index 6270936..7517477 100644 --- a/core/src/main/java/gwtupload/client/MultipleFileUpload.java +++ b/core/src/main/java/gwtupload/client/MultipleFileUpload.java @@ -5,7 +5,6 @@ import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.InputElement; -import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.FileUpload; /** diff --git a/core/src/main/java/gwtupload/client/Uploader.java b/core/src/main/java/gwtupload/client/Uploader.java index 4ba9175..ca593c6 100644 --- a/core/src/main/java/gwtupload/client/Uploader.java +++ b/core/src/main/java/gwtupload/client/Uploader.java @@ -1,5 +1,6 @@ /* * Copyright 2010 Manuel Carrasco Moñino. (manolo at apache/org) + * Copyright 2017 Sven Strickroth * http://code.google.com/p/gwtupload * * Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -19,7 +20,6 @@ import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; -import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.FormElement; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; @@ -48,7 +48,6 @@ import com.google.gwt.xml.client.Node; import com.google.gwt.xml.client.NodeList; import com.google.gwt.xml.client.XMLParser; -import com.google.gwt.xml.client.impl.DOMParseException; import java.util.ArrayList; import java.util.Collection; @@ -76,15 +75,10 @@ import static gwtupload.shared.UConsts.TAG_CANCELED; import static gwtupload.shared.UConsts.TAG_CTYPE; import static gwtupload.shared.UConsts.TAG_CURRENT_BYTES; -import static gwtupload.shared.UConsts.TAG_FIELD; import static gwtupload.shared.UConsts.TAG_FILE; import static gwtupload.shared.UConsts.TAG_FINISHED; import static gwtupload.shared.UConsts.TAG_KEY; import static gwtupload.shared.UConsts.TAG_MESSAGE; -import static gwtupload.shared.UConsts.TAG_MSG_END; -import static gwtupload.shared.UConsts.TAG_MSG_GT; -import static gwtupload.shared.UConsts.TAG_MSG_LT; -import static gwtupload.shared.UConsts.TAG_MSG_START; import static gwtupload.shared.UConsts.TAG_NAME; import static gwtupload.shared.UConsts.TAG_PERCENT; import static gwtupload.shared.UConsts.TAG_SIZE; @@ -439,13 +433,14 @@ public void onSubmitComplete(SubmitCompleteEvent event) { updateStatusTimer.cancel(); onSubmitComplete = true; serverRawResponse = event.getResults(); - if (serverRawResponse != null) { - serverRawResponse = serverRawResponse.replaceFirst(".*" + TAG_MSG_START + "([\\s\\S]*?)" + TAG_MSG_END + ".*", "$1"); - serverRawResponse = serverRawResponse.replace(TAG_MSG_LT, "<").replace(TAG_MSG_GT, ">").replace("<", "<").replaceAll(">", ">").replaceAll(" ", " "); - } try { // Parse the xml and extract UploadedInfos Document doc = XMLParser.parse(serverRawResponse); + // for some reason the response is put inside a "pre" tag + if (doc.getDocumentElement().getNodeName().equals("pre")) { + serverRawResponse = doc.getFirstChild().getFirstChild().getNodeValue(); + doc = XMLParser.parse(serverRawResponse); + } // If the server response is a valid xml parseAjaxResponse(serverRawResponse); } catch (Exception e) { @@ -1144,7 +1139,8 @@ private JavaScriptObject getDataInfo(UploadedInfo info) { getDataImpl(info.fileUrl, info.field, info.name, Utils.basename(info.name), serverRawResponse, info.message, getStatus().toString(), info.size); } - private native JavaScriptObject getDataImpl(String url, String inputName, String fileName, String baseName, String serverResponse, String serverMessage, String status, int size) /*-{ + @com.google.gwt.core.client.UnsafeNativeLong + private native JavaScriptObject getDataImpl(String url, String inputName, String fileName, String baseName, String serverResponse, String serverMessage, String status, long size) /*-{ return { url: url, name: inputName, @@ -1176,7 +1172,6 @@ private void parseAjaxResponse(String responseTxt) { // POST response or FINISHED status String msg = Utils.getXmlNodeValue(doc, TAG_MESSAGE); serverMessage.setMessage(msg); - String fld = Utils.getXmlNodeValue(doc, TAG_FIELD); NodeList list = doc.getElementsByTagName(TAG_FILE); for (int i = 0, l = list.getLength(); i < l; i++) { UploadedInfo info = new UploadedInfo(); @@ -1195,15 +1190,15 @@ private void parseAjaxResponse(String responseTxt) { String size = Utils.getXmlNodeValue(doc, TAG_SIZE, i); if (size != null) { - info.setSize(Integer.parseInt(size)); + info.setSize(Long.parseLong(size)); } serverMessage.getUploadedInfos().add(info); } } } catch (Exception e) { - if (responseTxt.toLowerCase().matches("error")) { + // if (responseTxt.toLowerCase().matches("error")) { error = i18nStrs.uploaderServerError() + "\nAction: " + getServletPath() + "\nException: " + e.getMessage() + responseTxt; - } + // } } if (error != null) { diff --git a/core/src/main/java/gwtupload/client/bundle/Upload.css b/core/src/main/java/gwtupload/client/bundle/Upload.gss similarity index 87% rename from core/src/main/java/gwtupload/client/bundle/Upload.css rename to core/src/main/java/gwtupload/client/bundle/Upload.gss index 719d23c..4156c7c 100644 --- a/core/src/main/java/gwtupload/client/bundle/Upload.css +++ b/core/src/main/java/gwtupload/client/bundle/Upload.gss @@ -1,9 +1,9 @@ @external GWTUpld; -@external gwt-*; -@external upld*; -@external DecoratedFileUpload*; -@external status*; -@external prgbar*; +@external 'gwt-*'; +@external 'upld*'; +@external 'DecoratedFileUpload*'; +@external 'status*'; +@external 'prgbar*'; @external cancel; @external changed; @external filename; @@ -26,7 +26,7 @@ font-weight: bold; } -@if user.agent ie6 ie8 ie9 { +@if (is("ie6") || is("ie8") || is("ie9")) { .GWTUpld .upld-status div.cancel { width: 14px; height: 10px; @@ -42,12 +42,12 @@ } } -@sprite .GWTUpld .upld-status div.cancel { - gwt-image: 'imgCancelUpload'; +.GWTUpld .upld-status div.cancel { + gwt-sprite: 'imgCancelUpload'; } -@sprite .GWTUpld .upld-status div.cancel:hover { - gwt-image: 'imgCancelUploadHover'; +.GWTUpld .upld-status div.cancel:hover { + gwt-sprite: 'imgCancelUploadHover'; } .GWTUpld .upld-status .filename { @@ -86,7 +86,7 @@ padding: 1px; } -@if user.agent ie6 ie8 ie9 { +@if (is("ie6") || is("ie8") || is("ie9")) { .GWTUpld .GWTUpld .prgbar-back { height: 12px; margin-top: 2px; @@ -107,7 +107,7 @@ margin-left: 3px; } -@if user.agent ie6 ie8 ie9 { +@if (is("ie6") || is("ie8") || is("ie9")) { .GWTUpld .prgbar-msg { top: 0px; left: 4px; @@ -134,7 +134,7 @@ opacity: 0.3; } -@if user.agent ie6 ie8 ie9 { +@if (is("ie6") || is("ie8") || is("ie9")) { .upld-modal-glass { filter: literal('alpha(opacity=30)'); } diff --git a/core/src/main/java/gwtupload/client/bundle/UploadCss.java b/core/src/main/java/gwtupload/client/bundle/UploadCss.java index dffd4d5..a97a568 100644 --- a/core/src/main/java/gwtupload/client/bundle/UploadCss.java +++ b/core/src/main/java/gwtupload/client/bundle/UploadCss.java @@ -8,7 +8,7 @@ public interface UploadCss extends ClientBundle { public static final UploadCss INSTANCE = GWT.create(UploadCss.class); - @Source("Upload.css") + @Source("Upload.gss") public CssResource css(); @Source("cancel-upld.gif") diff --git a/core/src/main/java/gwtupload/server/AbstractUploadListener.java b/core/src/main/java/gwtupload/server/AbstractUploadListener.java index 16949cb..bbe4db4 100644 --- a/core/src/main/java/gwtupload/server/AbstractUploadListener.java +++ b/core/src/main/java/gwtupload/server/AbstractUploadListener.java @@ -54,7 +54,7 @@ public static AbstractUploadListener current(String sessionId) { protected boolean exceptionTrhown = false; - private String postResponse = null; + private XMLResponse postResponse = null; protected int frozenTimeout = 60000; @@ -160,7 +160,7 @@ public void setException(RuntimeException e) { save(); } - public void setFinished(String postResponse) { + public void setFinished(XMLResponse postResponse) { this.postResponse = postResponse; save(); } @@ -203,7 +203,7 @@ public void update(long done, long total, int item) { } } - public String getPostResponse() { + public XMLResponse getPostResponse() { return postResponse; } } diff --git a/core/src/main/java/gwtupload/server/UploadAction.java b/core/src/main/java/gwtupload/server/UploadAction.java index d7fd67c..6a0e31a 100644 --- a/core/src/main/java/gwtupload/server/UploadAction.java +++ b/core/src/main/java/gwtupload/server/UploadAction.java @@ -1,5 +1,6 @@ /* * Copyright 2010 Manuel Carrasco Moñino. (manolo at apache/org) + * Copyright 2017 Sven Strickroth * http://code.google.com/p/gwtupload * * Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -24,9 +25,7 @@ import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; @@ -148,6 +147,7 @@ public void removeItem(HttpServletRequest request, String fieldName) throws Upl } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + XMLResponse xmlResponse = new XMLResponse(); String parameter = request.getParameter(UConsts.PARAM_REMOVE); if (parameter != null) { try { @@ -159,7 +159,8 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t removeItem(request, item); } } catch (Exception e) { - renderXmlResponse(request, response, "<" + TAG_ERROR + ">" + e.getMessage() + ""); + xmlResponse.addResponseTag(TAG_ERROR, e.getMessage()); + renderXmlResponse(request, response, xmlResponse); return; } // Remove the item saved in session in the case it was not removed yet @@ -172,20 +173,20 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String error = null; String message = null; - Map tags = new HashMap(); - + XMLResponse xmlResponse = new XMLResponse(); perThreadRequest.set(request); try { // Receive the files and form elements, updating the progress status error = super.parsePostRequest(request, response); if (error == null) { // Fill files status before executing user code which could remove session files - getFileItemsSummary(request, tags); + getFileItemsSummary(request, xmlResponse); // Call to the user code message = executeAction(request, getMyLastReceivedFileItems(request)); } } catch (UploadCanceledException e) { - renderXmlResponse(request, response, "<" + TAG_CANCELED + ">true"); + xmlResponse.addResponseTag(TAG_CANCELED, "true"); + renderXmlResponse(request, response, xmlResponse); return; } catch (UploadActionException e) { logger.info("ExecuteUploadActionException when receiving a file.", e); @@ -197,24 +198,24 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) perThreadRequest.set(null); } - String postResponse = null; AbstractUploadListener listener = getCurrentListener(request); if (error != null) { - postResponse = "<" + TAG_ERROR + ">" + error + ""; - renderXmlResponse(request, response, postResponse); + xmlResponse.addResponseTag(TAG_ERROR, error); + renderXmlResponse(request, response, xmlResponse); if (listener != null) { listener.setException(new RuntimeException(error)); } UploadServlet.removeSessionFileItems(request); } else { if (message != null) { - // see issue #139 - tags.put("message", ""); + xmlResponse.addResponseTag("message", message); } - postResponse = statusToString(tags); - renderXmlResponse(request, response, postResponse, true); + renderXmlResponse(request, response, xmlResponse, true); + } + finish(request, xmlResponse); + if(listener != null && listener.isFinished()) { + removeCurrentListener(request); } - finish(request, postResponse); if (removeSessionFiles) { removeSessionFileItems(request, removeData); diff --git a/core/src/main/java/gwtupload/server/UploadServlet.java b/core/src/main/java/gwtupload/server/UploadServlet.java index dd87b60..dd93bab 100644 --- a/core/src/main/java/gwtupload/server/UploadServlet.java +++ b/core/src/main/java/gwtupload/server/UploadServlet.java @@ -1,5 +1,6 @@ /* * Copyright 2010 Manuel Carrasco Moñino. (manolo at apache/org) + * Copyright 2017 Sven Strickroth * http://code.google.com/p/gwtupload * * Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -35,7 +36,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Map.Entry; import java.util.ResourceBundle; import javax.servlet.Servlet; @@ -52,27 +52,12 @@ import static gwtupload.shared.UConsts.TAG_BLOBSTORE; import static gwtupload.shared.UConsts.TAG_BLOBSTORE_PATH; import static gwtupload.shared.UConsts.TAG_CANCELED; -import static gwtupload.shared.UConsts.TAG_CTYPE; import static gwtupload.shared.UConsts.TAG_CURRENT_BYTES; -import static gwtupload.shared.UConsts.TAG_DELETED; import static gwtupload.shared.UConsts.TAG_ERROR; -import static gwtupload.shared.UConsts.TAG_FIELD; -import static gwtupload.shared.UConsts.TAG_FILE; -import static gwtupload.shared.UConsts.TAG_FILES; import static gwtupload.shared.UConsts.TAG_FINISHED; -import static gwtupload.shared.UConsts.TAG_KEY; -import static gwtupload.shared.UConsts.TAG_MSG_END; -import static gwtupload.shared.UConsts.TAG_MSG_GT; -import static gwtupload.shared.UConsts.TAG_MSG_LT; -import static gwtupload.shared.UConsts.TAG_MSG_START; -import static gwtupload.shared.UConsts.TAG_NAME; -import static gwtupload.shared.UConsts.TAG_PARAM; -import static gwtupload.shared.UConsts.TAG_PARAMS; import static gwtupload.shared.UConsts.TAG_PERCENT; import static gwtupload.shared.UConsts.TAG_SESSION_ID; -import static gwtupload.shared.UConsts.TAG_SIZE; import static gwtupload.shared.UConsts.TAG_TOTAL_BYTES; -import static gwtupload.shared.UConsts.TAG_VALUE; import gwtupload.server.exceptions.UploadActionException; import gwtupload.server.exceptions.UploadCanceledException; @@ -150,11 +135,8 @@ public class UploadServlet extends HttpServlet implements Servlet { protected static final int DEFAULT_REQUEST_LIMIT_KB = 5 * 1024 * 1024; protected static final int DEFAULT_SLOW_DELAY_MILLIS = 300; - protected static final String XML_CANCELED_TRUE = "<" + TAG_CANCELED + ">true"; - protected static final String XML_DELETED_TRUE = "<" + TAG_DELETED + ">true"; - protected static final String XML_ERROR_ITEM_NOT_FOUND = "<" + TAG_ERROR + ">item not found"; - protected static final String XML_ERROR_TIMEOUT = "<" + TAG_ERROR + ">timeout receiving file"; - protected static final String XML_FINISHED_OK = "<" + TAG_FINISHED + ">OK"; + protected static final String XML_ERROR_ITEM_NOT_FOUND = "item not found"; + protected static final String XML_ERROR_TIMEOUT = "timeout receiving file"; protected static UploadLogger logger = UploadLogger.getLogger(UploadServlet.class); @@ -164,8 +146,6 @@ public class UploadServlet extends HttpServlet implements Servlet { private static final long serialVersionUID = 2740693677625051632L; - private static String XML_TPL = "\n%%MESSAGE%%\n"; - private String corsDomainsRegex = "^$"; /** @@ -390,7 +370,9 @@ protected static FileItem removeUploadedFile(HttpServletRequest request, HttpSer logger.info("UPLOAD-SERVLET (" + request.getSession().getId() + ") removeUploadedFile: " + parameter + " not in session."); } - renderXmlResponse(request, response, XML_DELETED_TRUE); + XMLResponse xmlResponse = new XMLResponse(); + xmlResponse.addResponseTag(TAG_ERROR, "true"); + renderXmlResponse(request, response, xmlResponse); return item; } @@ -464,19 +446,16 @@ protected void renderHtmlMessage(HttpServletResponse response, String message) t * specify whether the request is post or not. * @throws IOException */ - protected static void renderXmlResponse(HttpServletRequest request, HttpServletResponse response, String message, boolean post) throws IOException { + protected static void renderXmlResponse(HttpServletRequest request, HttpServletResponse response, XMLResponse xmlResponse, boolean post) throws IOException { String contentType = post ? "text/plain" : "text/html"; - String xml = XML_TPL.replace("%%MESSAGE%%", message != null ? message : ""); - if (post) { - xml = TAG_MSG_START + xml.replaceAll("<", TAG_MSG_LT).replaceAll(">", TAG_MSG_GT) + TAG_MSG_END; - } + String xml = xmlResponse.getXML(); renderMessage(response, xml, contentType); } - protected static void renderXmlResponse(HttpServletRequest request, HttpServletResponse response, String message) throws IOException { - renderXmlResponse(request, response, message, false); + protected static void renderXmlResponse(HttpServletRequest request, HttpServletResponse response, XMLResponse xmlResponse) throws IOException { + renderXmlResponse(request, response, xmlResponse, false); } protected static void setThreadLocalRequest(HttpServletRequest request) { @@ -541,13 +520,15 @@ public void getUploadedFile(HttpServletRequest request, HttpServletResponse resp String parameter = request.getParameter(UConsts.PARAM_SHOW); FileItem item = findFileItem(getMySessionFileItems(request), parameter); if (item != null) { - logger.error("UPLOAD-SERVLET (" + request.getSession().getId() + ") getUploadedFile: " + parameter + " returning: " + item.getContentType() + ", " + item.getName() + ", " + item.getSize() + logger.info("UPLOAD-SERVLET (" + request.getSession().getId() + ") getUploadedFile: " + parameter + " returning: " + item.getContentType() + ", " + item.getName() + ", " + item.getSize() + " bytes"); response.setContentType(item.getContentType()); copyFromInputStreamToOutputStream(item.getInputStream(), response.getOutputStream()); } else { logger.error("UPLOAD-SERVLET (" + request.getSession().getId() + ") getUploadedFile: " + parameter + " file isn't in session."); - renderXmlResponse(request, response, XML_ERROR_ITEM_NOT_FOUND); + XMLResponse xmlResponse = new XMLResponse(); + xmlResponse.addResponseTag(TAG_ERROR, XML_ERROR_ITEM_NOT_FOUND); + renderXmlResponse(request, response, xmlResponse); } } @@ -648,23 +629,26 @@ private long getContentLength(HttpServletRequest request) { */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { perThreadRequest.set(request); + XMLResponse xmlResponse = new XMLResponse(); try { AbstractUploadListener listener = getCurrentListener(request); if (request.getParameter(UConsts.PARAM_SESSION) != null) { logger.debug("UPLOAD-SERVLET (" + request.getSession().getId() + ") new session, blobstore=" + (isAppEngine() && useBlobstore)); String sessionId = request.getSession().getId(); - renderXmlResponse(request, response, - "<" + TAG_BLOBSTORE + ">" + (isAppEngine() && useBlobstore) + "" + - "<" + TAG_SESSION_ID + ">" + sessionId + ""); + xmlResponse.addResponseTag(TAG_BLOBSTORE, (isAppEngine() && useBlobstore) ? "true" : "false"); + xmlResponse.addResponseTag(TAG_SESSION_ID, sessionId); + renderXmlResponse(request, response, xmlResponse); } else if (isAppEngine() && (request.getParameter(UConsts.PARAM_BLOBSTORE) != null || request.getParameterMap().size() == 0)) { String blobStorePath = getBlobstorePath(request); logger.debug("UPLOAD-SERVLET (" + request.getSession().getId() + ") getBlobstorePath=" + blobStorePath); - renderXmlResponse(request, response, "<" + TAG_BLOBSTORE_PATH + ">" + blobStorePath + ""); + xmlResponse.addResponseTag(TAG_BLOBSTORE_PATH, blobStorePath); + renderXmlResponse(request, response, xmlResponse); } else if (request.getParameter(UConsts.PARAM_SHOW) != null) { getUploadedFile(request, response); } else if (request.getParameter(UConsts.PARAM_CANCEL) != null) { cancelUpload(request); - renderXmlResponse(request, response, XML_CANCELED_TRUE); + xmlResponse.addResponseTag(TAG_CANCELED, "true"); + renderXmlResponse(request, response, xmlResponse); } else if (request.getParameter(UConsts.PARAM_REMOVE) != null) { removeUploadedFile(request, response); } else if (request.getParameter(UConsts.PARAM_CLEAN) != null) { @@ -672,31 +656,20 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t if (listener != null) { listener.remove(); } - renderXmlResponse(request, response, XML_FINISHED_OK); + xmlResponse.addResponseTag(TAG_FINISHED, "ok"); + renderXmlResponse(request, response, xmlResponse); } else if (listener != null && listener.isFinished()) { removeCurrentListener(request); renderXmlResponse(request, response, listener.getPostResponse()); } else { - String message = statusToString(getUploadStatus(request, request.getParameter(UConsts.PARAM_FILENAME), null)); - renderXmlResponse(request, response, message); + xmlResponse.addResponseTags(getUploadStatus(request, request.getParameter(UConsts.PARAM_FILENAME), null)); + renderXmlResponse(request, response, xmlResponse); } } finally { perThreadRequest.set(null); } } - protected String statusToString(Map stat) { - String message = ""; - for (Entry e : stat.entrySet()) { - if (e.getValue() != null) { - String k = e.getKey(); - String v = e.getValue().replaceAll("", "").replaceAll("<", "<").replaceAll(">", ">"); - message += "<" + k + ">" + v + "\n"; - } - } - return message; - } - /** * The post method is used to receive the file and save it in the user * session. It returns a very XML page that the client receives in an @@ -708,79 +681,47 @@ protected String statusToString(Map stat) { */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { perThreadRequest.set(request); - String error; + XMLResponse xmlResponse = new XMLResponse(); try { - error = parsePostRequest(request, response); - Map stat = new HashMap(); - if (error != null && error.length() > 0 ) { - stat.put(TAG_ERROR, error); + String error = parsePostRequest(request, response); + if (error != null && !error.isEmpty()) { + xmlResponse.addResponseTag(TAG_ERROR, error); } else { - getFileItemsSummary(request, stat); + getFileItemsSummary(request, xmlResponse); } - String postResponse = statusToString(stat); - finish(request, postResponse); - renderXmlResponse(request, response, postResponse, true); + finish(request, xmlResponse); + renderXmlResponse(request, response, xmlResponse, true); } catch (UploadCanceledException e) { - renderXmlResponse(request, response, XML_CANCELED_TRUE, true); + xmlResponse.addResponseTag(TAG_CANCELED, "true"); + renderXmlResponse(request, response, xmlResponse, true); } catch (UploadTimeoutException e) { - renderXmlResponse(request, response, XML_ERROR_TIMEOUT, true); + xmlResponse.addResponseTag(TAG_ERROR, XML_ERROR_TIMEOUT); + renderXmlResponse(request, response, xmlResponse, true); } catch (UploadSizeLimitException e) { - renderXmlResponse(request, response, "<" + TAG_ERROR + ">" + e.getMessage() + "", true); + xmlResponse.addResponseTag(TAG_ERROR, e.getMessage()); + renderXmlResponse(request, response, xmlResponse, true); } catch (Exception e) { logger.error("UPLOAD-SERVLET (" + request.getSession().getId() + ") Exception -> " + e.getMessage() + "\n" + stackTraceToString(e)); - error = e.getMessage(); - renderXmlResponse(request, response, "<" + TAG_ERROR + ">" + error + "", true); + xmlResponse.addResponseTag(TAG_ERROR, e.getMessage()); + renderXmlResponse(request, response, xmlResponse, true); } finally { perThreadRequest.set(null); } } - protected Map getFileItemsSummary(HttpServletRequest request, Map stat) { - if (stat == null) { - stat = new HashMap(); - } + protected void getFileItemsSummary(HttpServletRequest request, XMLResponse xmlResponse) { List s = getMyLastReceivedFileItems(request); if (s != null) { - String files = ""; - String params = ""; + xmlResponse.prepareFilesParams(); for (FileItem i : s) { if (i.isFormField()) { - params += formFieldToXml(i); + xmlResponse.addParam(i.getFieldName(), i.getString()); } else { - files += fileFieldToXml(i); + xmlResponse.addFile(i.getFieldName(), i.getName(), i.getSize(), i.getContentType() !=null ? i.getContentType() : "unknown", (i instanceof HasKey) ? ((HasKey)i).getKeyString() : null); } } - stat.put(TAG_FILES, files); - stat.put(TAG_PARAMS, params); - stat.put(TAG_FINISHED, "ok"); + xmlResponse.addResponseTag(TAG_FINISHED, "ok"); } - return stat; - } - - private String formFieldToXml(FileItem i) { - Map item = new HashMap(); - item.put(TAG_VALUE, "" + i.getString()); - item.put(TAG_FIELD, "" + i.getFieldName()); - - Map param = new HashMap(); - param.put(TAG_PARAM, statusToString(item)); - return statusToString(param); - } - - private String fileFieldToXml(FileItem i) { - Map item = new HashMap(); - item.put(TAG_CTYPE, i.getContentType() !=null ? i.getContentType() : "unknown"); - item.put(TAG_SIZE, "" + i.getSize()); - item.put(TAG_NAME, "" + i.getName()); - item.put(TAG_FIELD, "" + i.getFieldName()); - if (i instanceof HasKey) { - String k = ((HasKey)i).getKeyString(); - item.put(TAG_KEY, k); - } - - Map file = new HashMap(); - file.put(TAG_FILE, statusToString(item)); - return statusToString(file); } /** @@ -789,7 +730,7 @@ private String fileFieldToXml(FileItem i) { * @param request * @param postResponse */ - protected void finish(HttpServletRequest request, String postResponse) { + protected void finish(HttpServletRequest request, XMLResponse postResponse) { AbstractUploadListener listener = getCurrentListener(request); if (listener != null) { listener.setFinished(postResponse); @@ -943,10 +884,10 @@ protected String parsePostRequest(HttpServletRequest request, HttpServletRespons uploader.setProgressListener(listener); // Receive the files - logger.error("UPLOAD-SERVLET (" + session.getId() + ") parsing HTTP POST request "); + logger.info("UPLOAD-SERVLET (" + session.getId() + ") parsing HTTP POST request "); uploadedItems = uploader.parseRequest(request); session.removeAttribute(getSessionLastFilesKey(request)); - logger.error("UPLOAD-SERVLET (" + session.getId() + ") parsed request, " + uploadedItems.size() + " items received."); + logger.info("UPLOAD-SERVLET (" + session.getId() + ") parsed request, " + uploadedItems.size() + " items received."); // Received files are put in session List sessionFiles = getMySessionFileItems(request); diff --git a/core/src/main/java/gwtupload/server/XMLResponse.java b/core/src/main/java/gwtupload/server/XMLResponse.java new file mode 100644 index 0000000..8185ebf --- /dev/null +++ b/core/src/main/java/gwtupload/server/XMLResponse.java @@ -0,0 +1,158 @@ +/* + * Copyright 2017 Sven Strickroth + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package gwtupload.server; + +import static gwtupload.shared.UConsts.TAG_CTYPE; +import static gwtupload.shared.UConsts.TAG_FIELD; +import static gwtupload.shared.UConsts.TAG_FILE; +import static gwtupload.shared.UConsts.TAG_FILES; +import static gwtupload.shared.UConsts.TAG_KEY; +import static gwtupload.shared.UConsts.TAG_NAME; +import static gwtupload.shared.UConsts.TAG_PARAM; +import static gwtupload.shared.UConsts.TAG_PARAMS; +import static gwtupload.shared.UConsts.TAG_RESPONSE; +import static gwtupload.shared.UConsts.TAG_SIZE; +import static gwtupload.shared.UConsts.TAG_VALUE; + +import java.io.StringWriter; +import java.io.Writer; +import java.util.Map; +import java.util.Map.Entry; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +public class XMLResponse { + private Document responseDocument; + private Node responseNode; + private Node filesNode; + private Node paramsNode; + + public XMLResponse() { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance("com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", null); + DocumentBuilder builder; + try { + builder = dbf.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + return; + } + responseDocument = builder.newDocument(); + responseNode = responseDocument.createElement(TAG_RESPONSE); + responseDocument.appendChild(responseNode); + } + + private Node addResponseNode(String tagName, String value) { + Element el = responseDocument.createElement(tagName); + addTextToNode(el, value); + return responseNode.appendChild(el); + } + + public void addResponseTag(String tagName, String value) { + addResponseNode(tagName, value); + } + + public void addResponseTags(Map uploadStatus) { + for (Entry e : uploadStatus.entrySet()) { + if (e.getValue() == null) { + continue; + } + addResponseTag(e.getKey(), e.getValue().replaceAll("", "")); // TODO: is removing pre really needed? + } + } + + public void prepareFilesParams() { + filesNode = addResponseNode(TAG_FILES, null); + paramsNode = addResponseNode(TAG_PARAMS, null); + } + + public void addParam(String key, String value) { + Node paramNode = responseDocument.createElement(TAG_PARAM); + + Node fieldNode = responseDocument.createElement(TAG_FIELD); + addTextToNode(fieldNode, key); + paramNode.appendChild(fieldNode); + Node valueNode = responseDocument.createElement(TAG_VALUE); + addTextToNode(valueNode, value); + paramNode.appendChild(valueNode); + + paramsNode.appendChild(paramNode); + } + + private void addTextToNode(Node node, String value) { + if (value == null) { + return; + } + + node.appendChild(responseDocument.createTextNode(value)); + } + + public String getXML() { + Transformer tf; + try { + tf = TransformerFactory.newInstance().newTransformer(); + } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) { + e.printStackTrace(); + return ""; + } + tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + tf.setOutputProperty(OutputKeys.INDENT, "yes"); + Writer out = new StringWriter(); + try { + tf.transform(new DOMSource(responseDocument), new StreamResult(out)); + } catch (TransformerException e) { + e.printStackTrace(); + } + return out.toString(); + } + + public void addFile(String fieldName, String fileName, long size, String contentType, String key) { + Node fileNode = responseDocument.createElement(TAG_FILE); + + Node fieldNode = responseDocument.createElement(TAG_FIELD); + addTextToNode(fieldNode, fieldName); + fileNode.appendChild(fieldNode); + Node fileNameNode = responseDocument.createElement(TAG_NAME); + addTextToNode(fileNameNode, fileName); + fileNode.appendChild(fileNameNode); + Node fileSizeNode = responseDocument.createElement(TAG_SIZE); + addTextToNode(fileSizeNode, new Long(size).toString()); + fileNode.appendChild(fileSizeNode); + Node contentTypeNode = responseDocument.createElement(TAG_CTYPE); + addTextToNode(contentTypeNode, contentType); + fileNode.appendChild(contentTypeNode); + if (key != null) { + Node keyNode = responseDocument.createElement(TAG_KEY); + addTextToNode(keyNode, key); + fileNode.appendChild(keyNode); + } + + filesNode.appendChild(fileNode); + } +} diff --git a/core/src/main/java/gwtupload/shared/UConsts.java b/core/src/main/java/gwtupload/shared/UConsts.java index d09845b..eefcd50 100644 --- a/core/src/main/java/gwtupload/shared/UConsts.java +++ b/core/src/main/java/gwtupload/shared/UConsts.java @@ -1,6 +1,7 @@ package gwtupload.shared; public class UConsts { + public static final String TAG_RESPONSE = "response"; public static final String TAG_BLOBSTORE_PATH = "blobpath"; public static final String TAG_BLOBSTORE_NAME = "blobname"; public static final String TAG_BLOBSTORE_PARAM = "blobparam"; @@ -28,11 +29,6 @@ public class UConsts { public static final String TAG_PARAMS = "parameters"; public static final String TAG_SESSION_ID = "sessionid"; - public static final String TAG_MSG_START = "%%%INI%%%"; - public static final String TAG_MSG_END = "%%%END%%%"; - public static final String TAG_MSG_GT = "^^^@@"; - public static final String TAG_MSG_LT = "@@^^^"; - public static final String PARAM_BLOBSTORE = TAG_BLOBSTORE; public static final String PARAM_BLOBKEY = "blob-key"; public static final String PARAM_CANCEL = "cancel"; diff --git a/pom.xml b/pom.xml index 41cb7e3..caa5693 100644 --- a/pom.xml +++ b/pom.xml @@ -5,13 +5,13 @@ gwtupload-project GwtUpload project pom - 1.0.4-SNAPSHOT + 1.0.4-p1 core - gae - jsupload - samples + + + @@ -22,11 +22,11 @@ ${project.parent.basedir} - 1.6 - 1.6 + 1.7 + 1.7 UTF-8 - 2.7.0 - 2.7.0 + 2.8.0 + 2.8.0 1.3.1 2.3 0.9.7 @@ -107,6 +107,7 @@ commons-io ${commonsIoVersion} +