bug5479: added percentage of upload progress to progress status spinner.

This commit is contained in:
Udo Wessels committed 2021-05-31 20:43:52 +02:00
1 parent 107c5c65b3
commit 5e04eb3eaa
9 files changed
+234 -1

No files matched your search

@@ -4,6 +4,7 @@ import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.dom.client.AnchorElement;
@@ -14,11 +15,20 @@ import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONException;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.media.client.Audio;
import com.google.gwt.media.client.MediaBase;
import com.google.gwt.regexp.shared.MatchResult;
import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.typedarrays.shared.Int8Array;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
@@ -42,6 +52,7 @@ import com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback;
import com.sap.sailing.gwt.ui.common.client.YoutubeApi;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.fileupload.FileUploadConstants;
import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.MediaSubType;
@@ -58,10 +69,13 @@ import com.sap.sse.gwt.client.dialog.DataEntryDialog;
import com.sap.sse.gwt.client.formfactor.DeviceDetector;
public class NewMediaDialog extends DataEntryDialog<MediaTrack> implements FileStorageServiceConnectionTestObserver {
private final Logger logger = Logger.getLogger(getClass().getName());
private static final boolean DONT_FIRE_EVENTS = false;
private static final Duration DEFAULT_DURATION = new MillisecondsDurationImpl(0L);
private static final NewMediaDialogResources RESOURCES = NewMediaDialogResources.INSTANCE;
private static final String PROGRESS_STATUS_URL = "/sailingserver/fileupload/progress";
protected static class MediaTrackValidator implements Validator<MediaTrack> {
private final StringMessages stringMessages;
@@ -402,23 +416,81 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> implements FileS
progressOverlay.addStyleName(NewMediaDialogResources.INSTANCE.css().progressOverlay());
FlowPanel progressSpinner = new FlowPanel();
progressSpinner.addStyleName(NewMediaDialogResources.INSTANCE.css().progressSpinner());
final Label counter = new Label("0%");
counter.addStyleName(NewMediaDialogResources.INSTANCE.css().progressCounter());
progressOverlay.add(progressSpinner);
progressOverlay.add(counter);
progressOverlay.setVisible(false);
final Timer t = new Timer(){
public void run() {
requestProgressPercentage(this, counter);
}
};
urlBox.setStartUploadEvent(new StartUploadEvent() {
@Override
public void startUpload() {
progressOverlay.setVisible(true);
t.scheduleRepeating(1000);
}
});
urlBox.setEndUploadEvent(new EndUploadEvent() {
@Override
public void endUpload() {
progressOverlay.setVisible(false);
t.cancel();
}
});
mainPanel.add(progressOverlay);
return mainPanel;
}
private void requestProgressPercentage(final Timer t, final Label counter) {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, PROGRESS_STATUS_URL);
try {
builder.sendRequest(null, new RequestCallback() {
@Override
public void onResponseReceived(Request request, Response response) {
try {
String result = response.getText().trim();
JSONValue resultJsonValue = JSONParser.parseStrict(result);
if (resultJsonValue.isObject().get(FileUploadConstants.PROGRESS_PERCENTAGE) != null) {
int percentage = (int) resultJsonValue.isObject()
.get(FileUploadConstants.PROGRESS_PERCENTAGE).isNumber().doubleValue();
long theBytesRead = (long) resultJsonValue.isObject()
.get(FileUploadConstants.PROGRESS_BYTE_DONE).isNumber().doubleValue();
long theContentLength = (long) resultJsonValue.isObject()
.get(FileUploadConstants.PROGRESS_BYTE_TOTAL).isNumber().doubleValue();
if (percentage > 99) {
logger.info("Upload complete.");
t.cancel();
}
counter.setText(percentage + "%");
if (theContentLength == -1) {
counter.setTitle(theBytesRead + " bytes");
} else {
counter.setTitle(theBytesRead + " / " + theContentLength + " bytes.");
}
} else {
logger.severe("Cannot read result from progress request");
t.cancel();
}
} catch (JSONException e) {
logger.log(Level.SEVERE, "Cannot read result from progress request", e);
t.cancel();
}
}
@Override
public void onError(Request request, Throwable exception) {
logger.log(Level.SEVERE, "Error occured while requesting upload status. (1)", exception);
t.cancel();
}
});
} catch (RequestException e) {
logger.log(Level.SEVERE, "Error occured while requesting upload status. (2)", e);
t.cancel();
}
}
private String sliceBefore(String lastPathSegment, String slicer) {
int paramSegment = lastPathSegment.indexOf(slicer);
@@ -104,6 +104,10 @@
-webkit-animation: pulse 4s infinite, spin 2s linear infinite;
}
.progress-counter {
position: absolute;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
@@ -39,6 +39,9 @@ public interface NewMediaDialogResources extends ClientBundle {
@ClassName("progress-spinner")
String progressSpinner();
@ClassName("progress-counter")
String progressCounter();
}
@Source("NewMediaDialogResources.gss")
@@ -221,6 +221,14 @@
<servlet-name>FileUploadServlet</servlet-name>
<url-pattern>/fileupload</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ProgressServlet</servlet-name>
<servlet-class>com.sap.sailing.server.gateway.impl.ProgressServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ProgressServlet</servlet-name>
<url-pattern>/fileupload/progress</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ORCCertificateImportServlet</servlet-name>
<servlet-class>com.sap.sailing.server.gateway.orc.ORCCertificateImportServlet</servlet-class>
@@ -6,6 +6,7 @@ import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
@@ -34,6 +35,12 @@ public abstract class AbstractFileUploadServlet extends AbstractJsonHttpServlet
}
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
HttpSession session = req.getSession(true);
if (session != null) {
ProgressListener progressListener = new ProgressListener();
upload.setProgressListener(progressListener);
session.setAttribute("progressListener", progressListener);
}
try {
@SuppressWarnings("unchecked")
List<FileItem> items = (List<FileItem>) upload.parseRequest(req);
@@ -44,4 +51,5 @@ public abstract class AbstractFileUploadServlet extends AbstractJsonHttpServlet
}
abstract protected void process(List<FileItem> fileItems, HttpServletRequest req, HttpServletResponse resp) throws IOException;
}
@@ -0,0 +1,89 @@
package com.sap.sailing.server.gateway.impl;
public class ProgressListener implements org.apache.commons.fileupload.ProgressListener {
private long num100Ks = 0;
private long theBytesRead = 0;
private long theContentLength = -1;
private int whichItem = 0;
private int percentDone = 0;
private boolean contentLengthKnown = false;
public void update(long bytesRead, long contentLength, int items) {
if (contentLength > -1) {
contentLengthKnown = true;
}
theBytesRead = bytesRead;
theContentLength = contentLength;
whichItem = items;
long nowNum100Ks = bytesRead / 100000;
// Only run this code once every 100K
if (nowNum100Ks > num100Ks || theBytesRead == theContentLength) {
num100Ks = nowNum100Ks;
if (contentLengthKnown) {
percentDone = (int) Math.round(100.00 * bytesRead / contentLength);
}
//System.out.println(getMessage());
}
}
public String getMessage() {
if (theContentLength == -1) {
return "" + theBytesRead + " of Unknown-Total bytes have been read.";
} else {
return "" + theBytesRead + " of " + theContentLength + " bytes have been read (" + percentDone + "% done).";
}
}
public long getNum100Ks() {
return num100Ks;
}
public void setNum100Ks(long num100Ks) {
this.num100Ks = num100Ks;
}
public long getTheBytesRead() {
return theBytesRead;
}
public void setTheBytesRead(long theBytesRead) {
this.theBytesRead = theBytesRead;
}
public long getTheContentLength() {
return theContentLength;
}
public void setTheContentLength(long theContentLength) {
this.theContentLength = theContentLength;
}
public int getWhichItem() {
return whichItem;
}
public void setWhichItem(int whichItem) {
this.whichItem = whichItem;
}
public int getPercentDone() {
return percentDone;
}
public void setPercentDone(int percentDone) {
this.percentDone = percentDone;
}
public boolean isContentLengthKnown() {
return contentLengthKnown;
}
public void setContentLengthKnown(boolean contentLengthKnown) {
this.contentLengthKnown = contentLengthKnown;
}
}
@@ -0,0 +1,45 @@
package com.sap.sailing.server.gateway.impl;
import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.json.simple.JSONObject;
import com.sap.sse.common.fileupload.FileUploadConstants;
public class ProgressServlet extends HttpServlet {
private final Logger logger = Logger.getLogger(getClass().getName());
private static final long serialVersionUID = 6179739052238280324L;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
HttpSession session = request.getSession(true);
if (session == null) {
logger.warning("Sorry, session is null"); // just to be safe
return;
}
ProgressListener progressListener = (ProgressListener) session.getAttribute("progressListener");
if (progressListener == null) {
logger.warning("Progress listener is null");
return;
}
JSONObject json = new JSONObject();
json.put(FileUploadConstants.PROGRESS_PERCENTAGE, progressListener.getPercentDone());
json.put(FileUploadConstants.PROGRESS_BYTE_DONE, progressListener.getTheBytesRead());
json.put(FileUploadConstants.PROGRESS_BYTE_TOTAL, progressListener.getTheContentLength());
json.writeJSONString(response.getWriter());
}
}
@@ -5,4 +5,7 @@ public interface FileUploadConstants {
String FILE_URI = "file_uri";
String MESSAGE = "message";
String STATUS = "status";
String PROGRESS_PERCENTAGE = "progress_percentage";
String PROGRESS_BYTE_DONE = "progress_byte_done";
String PROGRESS_BYTE_TOTAL = "progress_byte_total";
}
@@ -48,6 +48,7 @@ public class URLFieldWithFileUpload extends Composite implements HasValue<String
private final Logger logger = Logger.getLogger(getClass().getName());
private static final URLFieldWithFileUploadResources RESOURCES = URLFieldWithFileUploadResources.INSTANCE;
private static final String UPLOAD_URL = "/sailingserver/fileupload";
private final TextBox urlTextBox;
@@ -126,7 +127,7 @@ public class URLFieldWithFileUpload extends Composite implements HasValue<String
uploadFormPanel = new FormPanel();
uploadPanel = new FlowPanel();
uploadPanel.setStylePrimaryName(RESOURCES.urlFieldWithFileUploadStyle().spaceDirectChildrenClass());
uploadFormPanel.setAction("/sailingserver/fileupload");
uploadFormPanel.setAction(UPLOAD_URL);
uploadFormPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
uploadFormPanel.setMethod(FormPanel.METHOD_POST);
fileUploadField = new FileUpload();