Skip to content

Commit

Permalink
Merge pull request #16 from protegeproject/reimplement-multi-part-fil…
Browse files Browse the repository at this point in the history
…e-upload

Reimplement multi part file upload
  • Loading branch information
matthewhorridge authored Jun 14, 2024
2 parents 7e90aff + 8014ed2 commit 10ab788
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import edu.stanford.bmir.protege.web.client.dispatch.ProgressDisplay;
import edu.stanford.bmir.protege.web.client.library.msgbox.MessageBox;
import edu.stanford.bmir.protege.web.client.projectmanager.ProjectCreatedEvent;
import edu.stanford.bmir.protege.web.client.upload.FileUploadFileReader;
import edu.stanford.bmir.protege.web.client.upload.FileUploader;
import edu.stanford.bmir.protege.web.client.user.LoggedInUserManager;
import edu.stanford.bmir.protege.web.client.uuid.UuidV4;
import edu.stanford.bmir.protege.web.shared.csv.DocumentId;
import edu.stanford.bmir.protege.web.shared.dispatch.actions.GetUserInfoAction;
import edu.stanford.bmir.protege.web.shared.dispatch.actions.GetUserInfoResult;
import edu.stanford.bmir.protege.web.shared.permissions.PermissionDeniedException;
import edu.stanford.bmir.protege.web.shared.project.*;
import edu.stanford.bmir.protege.web.shared.upload.SubmitFileAction;
Expand Down Expand Up @@ -118,32 +120,35 @@ private void createEmptyProject(ProjectCreatedHandler projectCreatedHandler) {

private void uploadSourcesAndCreateProject(@Nonnull ProjectCreatedHandler projectCreatedHandler) {
checkNotNull(projectCreatedHandler);
String fileUploadElementId = view.getFileUploadElementId();
FileUploadFileReader fileUploadFileReader = new FileUploadFileReader();
progressDisplay.displayProgress("Uploading file", "Uploading file. Please wait.");
fileUploadFileReader.readFiles(fileUploadElementId, fileContent -> {
progressDisplay.hideProgress();
handleFileReadComplete(fileContent, projectCreatedHandler);
}, readError -> {
progressDisplay.hideProgress();
messageBox.showAlert("Upload Failed", "Your file could not be uploaded.");
});
dispatchServiceManager.execute(new GetUserInfoAction(),
info -> createProjectForUser(info, projectCreatedHandler));
}

private void handleFileReadComplete(@Nonnull String base64EncodedContent,
ProjectCreatedHandler projectCreatedHandler) {
private void createProjectForUser(GetUserInfoResult userInfo,
ProjectCreatedHandler projectCreatedHandler) {

dispatchServiceManager.execute(SubmitFileAction.create(base64EncodedContent),
busy -> {},
result -> {
handleCreateNewProjectFromUploadedSources(projectCreatedHandler, result);
});
String fileUploadElementId = view.getFileUploadElementId();
FileUploader fileUploader = new FileUploader();
fileUploader.uploadFile(fileUploadElementId,
userInfo.getToken(),
fileSubmissionId -> handleFileSubmissionSuccess(projectCreatedHandler, fileSubmissionId),
this::handleFileSubmissionError);
}

private void handleFileSubmissionError(int errorCode) {
messageBox.showMessage("Could not upload file", "Error code: " + errorCode);
progressDisplay.hideProgress();
}

private void handleFileSubmissionSuccess(CreateNewProjectPresenter.ProjectCreatedHandler projectCreatedHandler,
String fileSubmissionId) {
progressDisplay.hideProgress();
handleCreateNewProjectFromUploadedSources(projectCreatedHandler,
new DocumentId(fileSubmissionId));
}

private void handleCreateNewProjectFromUploadedSources(ProjectCreatedHandler projectCreatedHandler, SubmitFileResult result) {
DocumentId documentId = result.getFileSubmissionId();
private void handleCreateNewProjectFromUploadedSources(ProjectCreatedHandler projectCreatedHandler, DocumentId documentId) {
NewProjectSettings newProjectSettings = NewProjectSettings.get(loggedInUserManager.getLoggedInUserId(),
view.getProjectName(),
view.getProjectLanguage(),
Expand Down Expand Up @@ -199,8 +204,4 @@ else if (cause instanceof ProjectDocumentExistsException) {
}
});
}

public NewProjectInfo getNewProjectInfo() {
return new NewProjectInfo(view.getProjectName(), view.getProjectDescription());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package edu.stanford.bmir.protege.web.client.upload;

/**
* Matthew Horridge
* Stanford Center for Biomedical Informatics Research
* 2024-06-10
*/
public interface FileUploadErrorHandler {

void handleFileUploadError(int statusCode);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package edu.stanford.bmir.protege.web.client.upload;

/**
* Matthew Horridge
* Stanford Center for Biomedical Informatics Research
* 2024-06-10
*/
public interface FileUploadSuccessHandler {

void handleFileUploadSuccess(String fileSubmissionId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package edu.stanford.bmir.protege.web.client.upload;

/**
* Matthew Horridge
* Stanford Center for Biomedical Informatics Research
* 2024-06-10
*/
public class FileUploader {

private static final String END_POINT = "/files/submit";

/**
* Upload a file that is retrieved from a FileInput element
* @param fileInputId The Id of the file input element
* @param token The authentication token to use when uploading the file
* @param successHandler The handler that will be called if the upload succeeds.
* @param errorHandler The handle that will be called if the upload fails.
*/
public void uploadFile(String fileInputId,
String token,
FileUploadSuccessHandler successHandler,
FileUploadErrorHandler errorHandler) {
uploadFileNative(fileInputId, END_POINT, token, successHandler, errorHandler);
}

private native void uploadFileNative(String fileInputId, String endPoint, String token,
FileUploadSuccessHandler successHandler,
FileUploadErrorHandler errorHandler)/*-{
var fileElement = $doc.getElementById(fileInputId);
var file = fileElement.files[0];
var formData = new FormData();
formData.append("file", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", endPoint, true);
var authHeader = "bearer " + token;
xhr.setRequestHeader('Authorization', authHeader);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if(xhr.status === 200) {
var submissionId = xhr.responseText.substring(1, xhr.responseText.length - 1);
successHandler.@edu.stanford.bmir.protege.web.client.upload.FileUploadSuccessHandler::handleFileUploadSuccess(*)(submissionId);
}
else {
var errorCode = xhr.status;
errorHandler.@edu.stanford.bmir.protege.web.client.upload.FileUploadErrorHandler::handleFileUploadError(*)(errorCode);
}
}
};
// Initiate a multipart/form-data upload
xhr.send(formData);
}-*/;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@

import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.Widget;
import edu.stanford.bmir.protege.web.client.dispatch.DispatchErrorMessageDisplay;
import edu.stanford.bmir.protege.web.client.dispatch.DispatchServiceCallbackWithProgressDisplay;
import edu.stanford.bmir.protege.web.client.dispatch.DispatchServiceManager;
import edu.stanford.bmir.protege.web.client.dispatch.ProgressDisplay;
import edu.stanford.bmir.protege.web.client.library.dlg.*;
import edu.stanford.bmir.protege.web.client.progress.ProgressMonitor;
import edu.stanford.bmir.protege.web.client.uuid.UuidV4;
import edu.stanford.bmir.protege.web.shared.upload.SubmitFileAction;
import edu.stanford.bmir.protege.web.shared.upload.SubmitFileResult;
import edu.stanford.bmir.protege.web.shared.csv.DocumentId;
import edu.stanford.bmir.protege.web.shared.dispatch.actions.GetUserInfoAction;
import edu.stanford.bmir.protege.web.shared.dispatch.actions.GetUserInfoResult;

import javax.annotation.Nonnull;

Expand All @@ -29,8 +26,6 @@ public class UploadFileDialogController extends WebProtegeOKCancelDialogControll

private final DispatchServiceManager dispatch;

private final DispatchErrorMessageDisplay errorMessageDisplay;

private final ProgressDisplay progressDisplay;

private UploadFileDialogForm form = new UploadFileDialogForm();
Expand All @@ -42,46 +37,29 @@ public UploadFileDialogController(String title,
@Provided ProgressDisplay progressDisplay) {
super(title);
this.dispatch = dispatch;
this.errorMessageDisplay = errorMessageDisplay;
this.progressDisplay = progressDisplay;
setDialogButtonHandler(DialogButton.OK, (data, closer) -> handleButtonPress(resultHandler, closer));
form.getFileUpload().getElement().setId(UuidV4.uuidv4());
}

private void handleButtonPress(UploadFileResultHandler resultHandler, WebProtegeDialogCloser closer) {
ProgressMonitor.get().showProgressMonitor("Preparing file", "Preparing file for upload. Please wait.");
FileUploadFileReader reader = new FileUploadFileReader();
reader.readFiles(form.getFileUpload().getElement().getId(),
content -> {
dispatch.execute(SubmitFileAction.create(content), new DispatchServiceCallbackWithProgressDisplay<SubmitFileResult>(errorMessageDisplay,
progressDisplay) {
@Override
public String getProgressDisplayTitle() {
return "Uploading file";
}

@Override
public String getProgressDisplayMessage() {
return "Please wait";
}
progressDisplay.displayProgress("Uploading file", "Uploading file. Please wait.");
dispatch.execute(new GetUserInfoAction(), userInfo -> {
String token = userInfo.getToken();
String fileUploadId = form.getFileUpload().getElement().getId();
FileUploader fileUploader = new FileUploader();
fileUploader.uploadFile(fileUploadId, token, fileSubmissionId -> {
progressDisplay.hideProgress();
closer.hide();
resultHandler.handleFileUploaded(new DocumentId(fileSubmissionId));
}, errorCode -> {
progressDisplay.hideProgress();
closer.hide();
resultHandler.handleFileUploadFailed("An error occurred uploading the file. Error code: " + errorCode);
});
});

@Override
public void handleSuccess(SubmitFileResult submitFileResult) {
closer.hide();
resultHandler.handleFileUploaded(submitFileResult.getFileSubmissionId());
}

@Override
public void handleErrorFinally(Throwable throwable) {
closer.hide();
resultHandler.handleFileUploadFailed("An error occurred uploading the file: " + throwable.getMessage());
}
});
},
errorHandler -> {
ProgressMonitor.get().hideProgressMonitor();
resultHandler.handleFileUploadFailed("An error occurred preparing the file for upload");
});
}

@Nonnull
Expand Down

0 comments on commit 10ab788

Please sign in to comment.