diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadStatusEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadStatusEvent.java index 96513a52a..8a4da9f6d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadStatusEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadStatusEvent.java @@ -15,7 +15,7 @@ package org.eclipse.hawkbit.ui.artifacts.event; public class UploadStatusEvent { public enum UploadStatusEventType { - UPLOAD_FAILED, UPLOAD_IN_PROGRESS, UPLOAD_STARTED, UPLOAD_FINISHED, UPLOAD_SUCCESSFUL, UPLOAD_STREAMING_FAILED, UPLOAD_STREAMING_FINISHED + UPLOAD_FAILED, UPLOAD_IN_PROGRESS, UPLOAD_STARTED, UPLOAD_FINISHED, UPLOAD_SUCCESSFUL, UPLOAD_STREAMING_FAILED, UPLOAD_STREAMING_FINISHED, ABORT_UPLOAD } private UploadStatusEventType uploadProgressEventType; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java index 848fa2da5..45a55d138 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java @@ -15,7 +15,6 @@ import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.exception.ArtifactUploadFailedException; import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; import org.eclipse.hawkbit.ui.artifacts.event.UploadFileStatus; import org.eclipse.hawkbit.ui.artifacts.event.UploadStatusEvent; import org.eclipse.hawkbit.ui.artifacts.event.UploadStatusEvent.UploadStatusEventType; @@ -29,7 +28,6 @@ import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.annotation.EventBusListenerMethod; import com.vaadin.server.StreamVariable; -import com.vaadin.ui.UI; import com.vaadin.ui.Upload; import com.vaadin.ui.Upload.FailedEvent; import com.vaadin.ui.Upload.FailedListener; @@ -66,6 +64,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene private volatile String mimeType = null; private volatile boolean streamingInterrupted = false; private volatile boolean uploadInterrupted = false; + private volatile boolean aborted = false; private String failureReason; private final I18N i18n; @@ -77,6 +76,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene UploadHandler(final String fileName, final long fileSize, final UploadLayout view, final long maxSize, final Upload upload, final String mimeType, SoftwareModule selectedSw) { super(); + this.aborted = false; this.fileName = fileName; this.fileSize = fileSize; this.view = view; @@ -87,6 +87,23 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene this.i18n = SpringContextHelper.getBean(I18N.class); this.eventBus = SpringContextHelper.getBean(EventBus.SessionEventBus.class); this.artifactUploadState = SpringContextHelper.getBean(ArtifactUploadState.class); + eventBus.subscribe(this); + } + + @PreDestroy + void destroy() { + /* + * It's good manners to do this, even though vaadin-spring will + * automatically unsubscribe when this UI is garbage collected. + */ + eventBus.unsubscribe(this); + } + + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvent(final UploadStatusEventType event) { + if (event == UploadStatusEventType.ABORT_UPLOAD) { + aborted = true; + } } /** @@ -98,6 +115,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public final OutputStream getOutputStream() { try { streamingInterrupted = false; + failureReason = null; return view.saveUploadedFileDetails(fileName, fileSize, mimeType, selectedSw); } catch (final ArtifactUploadFailedException e) { LOG.error("Atifact upload failed {} ", e); @@ -116,6 +134,8 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public OutputStream receiveUpload(final String fileName, final String mimeType) { uploadInterrupted = false; + aborted = false; + failureReason = null; this.fileName = fileName; this.mimeType = mimeType; // reset has directory flag before upload @@ -232,10 +252,13 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene if (readBytes > maxSize || contentLength > maxSize) { LOG.error("User tried to upload more than was allowed ({}).", maxSize); failureReason = i18n.get("message.uploadedfile.size.exceeded", maxSize); - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_FAILED, new UploadFileStatus( - fileName, failureReason, selectedSwForUpload))); - upload.interruptUpload(); - uploadInterrupted = true; + interruptFileUpload(); + return; + } + if (aborted) { + LOG.error("User aborted file upload"); + failureReason = i18n.get("message.uploadedfile.aborted"); + interruptFileUpload(); return; } eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_IN_PROGRESS, @@ -254,9 +277,13 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene if (event.getBytesReceived() > maxSize || event.getContentLength() > maxSize) { LOG.error("User tried to upload more than was allowed ({}).", maxSize); failureReason = i18n.get("message.uploadedfile.size.exceeded", maxSize); - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_FAILED, new UploadFileStatus( - fileName, failureReason, selectedSw))); - streamingInterrupted = true; + interruptFileStreaming(); + return; + } + if (aborted) { + LOG.error("User aborted the upload"); + failureReason = i18n.get("message.uploadedfile.aborted"); + interruptFileStreaming(); return; } eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_IN_PROGRESS, new UploadFileStatus( @@ -345,4 +372,12 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene return true; } + private void interruptFileStreaming() { + streamingInterrupted = true; + } + + private void interruptFileUpload() { + upload.interruptUpload(); + uploadInterrupted = true; + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index cbf766da8..4eaa61096 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -532,8 +532,7 @@ public class UploadLayout extends VerticalLayout { */ boolean enableProcessBtn() { if (artifactUploadState.getNumberOfFilesActuallyUpload().intValue() >= artifactUploadState - .getNumberOfFileUploadsExpected().intValue() - && artifactUploadState.getNumberOfFilesActuallyUpload().get() != 0) { + .getNumberOfFileUploadsExpected().intValue() && !getFileSelected().isEmpty()) { processBtn.setEnabled(true); artifactUploadState.getNumberOfFilesActuallyUpload().set(0); artifactUploadState.getNumberOfFileUploadsExpected().set(0); @@ -729,7 +728,7 @@ public class UploadLayout extends VerticalLayout { private boolean isUploadComplete() { int uploadedCount = artifactUploadState.getNumberOfFilesActuallyUpload().intValue(); int expectedUploadsCount = artifactUploadState.getNumberOfFileUploadsExpected().intValue(); - return uploadedCount == expectedUploadsCount; + return uploadedCount == expectedUploadsCount; } private void onUploadFailure(final UploadStatusEvent event) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusInfoWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusInfoWindow.java index e2a486e6c..351d625c9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusInfoWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusInfoWindow.java @@ -18,8 +18,10 @@ import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; import org.eclipse.hawkbit.ui.artifacts.event.UploadStatusEvent; import org.eclipse.hawkbit.ui.artifacts.event.UploadStatusEvent.UploadStatusEventType; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; +import org.eclipse.hawkbit.ui.common.ConfirmationDialog; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; @@ -66,6 +68,9 @@ public class UploadStatusInfoWindow extends Window { @Autowired private ArtifactUploadState artifactUploadState; + @Autowired + private I18N i18n; + private static final String PROGRESS = "Progress"; private static final String FILE_NAME = "File name"; @@ -82,6 +87,8 @@ public class UploadStatusInfoWindow extends Window { private volatile boolean errorOccured = false; + private volatile boolean uploadAborted = false; + private Button minimizeButton; private VerticalLayout mainLayout; @@ -91,9 +98,10 @@ public class UploadStatusInfoWindow extends Window { private Button closeButton; private Button resizeButton; - - private UI ui; + private UI ui; + + private ConfirmationDialog confirmDialog; /** * Default Constructor. @@ -118,10 +126,10 @@ public class UploadStatusInfoWindow extends Window { setContent(mainLayout); eventBus.subscribe(this); ui = UI.getCurrent(); - + + createConfirmDialog(); } - @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final UploadStatusEvent event) { if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_IN_PROGRESS) { @@ -139,13 +147,12 @@ public class UploadStatusInfoWindow extends Window { ui.access(() -> uploadSucceeded(event.getUploadStatus().getFileName())); } } - + private void onStartOfUpload(UploadStatusEvent event) { uploadSessionStarted(); uploadStarted(event.getUploadStatus().getFileName()); } - @PreDestroy void destroy() { /* @@ -154,7 +161,7 @@ public class UploadStatusInfoWindow extends Window { */ eventBus.unsubscribe(this); } - + private void restoreState() { Indexed container = grid.getContainerDataSource(); if (container.getItemIds().isEmpty()) { @@ -246,7 +253,7 @@ public class UploadStatusInfoWindow extends Window { @Override public JsonValue encode(final String value) { - String result ; + String result; switch (value) { case "Finished": result = "