From 8a976cabadba6d454718daf05e8ef6948a5c7d5c Mon Sep 17 00:00:00 2001 From: Asharani Date: Thu, 5 May 2016 16:28:12 +0530 Subject: [PATCH 01/16] Minimize/Maximize upload status popup intial commit Signed-off-by: Asharani --- .../event/UploadArtifactUIEvent.java | 2 +- .../artifacts/state/ArtifactUploadState.java | 39 ++- .../ui/artifacts/upload/UploadHandler.java | 27 +- .../ui/artifacts/upload/UploadLayout.java | 125 ++++++-- .../upload/UploadStatusInfoWindow.java | 272 ++++++++++++++---- .../artifacts/upload/UploadStatusObject.java | 71 +++++ .../footer/AbstractDeleteActionsLayout.java | 8 +- .../ui/common/grid/AbstractGridLayout.java | 3 +- .../FilterManagementView.java | 3 +- .../ui/utils/SPUIComponetIdProvider.java | 21 ++ .../ui/utils/SPUIStyleDefinitions.java | 9 +- 11 files changed, 480 insertions(+), 100 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java index 3d75b67a7..de8f5867b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java @@ -16,5 +16,5 @@ package org.eclipse.hawkbit.ui.artifacts.event; */ public enum UploadArtifactUIEvent { - SHOW_DROP_HINTS, HIDE_DROP_HINTS, SOFTWARE_DRAG_START, SOFTWARE_TYPE_DRAG_START, UPDATE_UPLOAD_COUNT, ENABLE_PROCESS_BUTTON, HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DISCARD_DELETE_SOFTWARE, DISCARD_ALL_DELETE_SOFTWARE, DELETED_ALL_SOFWARE, DISABLE_PROCESS_BUTTON, DISCARD_DELETE_SOFTWARE_TYPE, DISCARD_ALL_DELETE_SOFTWARE_TYPE, DELETED_ALL_SOFWARE_TYPE + SHOW_DROP_HINTS, HIDE_DROP_HINTS, SOFTWARE_DRAG_START, SOFTWARE_TYPE_DRAG_START, UPDATE_UPLOAD_COUNT, ENABLE_PROCESS_BUTTON, HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DISCARD_DELETE_SOFTWARE, DISCARD_ALL_DELETE_SOFTWARE, DELETED_ALL_SOFWARE, DISABLE_PROCESS_BUTTON, DISCARD_DELETE_SOFTWARE_TYPE, DISCARD_ALL_DELETE_SOFTWARE_TYPE, DELETED_ALL_SOFWARE_TYPE,MINIMIZED_STATUS_POPUP,MAXIMIZED_STATUS_POPUP,UPLOAD_FINISHED,UPLOAD_STARTED, UPLOAD_STREAMINING_FINISHED } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java index f82ce9ccf..ae6a5860e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java @@ -9,14 +9,17 @@ package org.eclipse.hawkbit.ui.artifacts.state; import java.io.Serializable; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.ui.artifacts.upload.UploadStatusObject; import org.eclipse.hawkbit.ui.common.ManagmentEntityState; import org.springframework.beans.factory.annotation.Autowired; @@ -58,8 +61,42 @@ public class ArtifactUploadState implements ManagmentEntityState, Serializ private final Set selectedDeleteSWModuleTypes = new HashSet<>(); private boolean noDataAvilableSoftwareModule = Boolean.FALSE; + + private boolean isStatusPopupMinimized = Boolean.FALSE; + + private boolean isUploadCompleted = Boolean.FALSE; + + private List uploadedFileStatusList = new ArrayList<>(); + + public List getUploadedFileStatusList() { + return uploadedFileStatusList; + } + + public void setUploadedFileStatusList(List uploadedFileStatusList) { + this.uploadedFileStatusList = uploadedFileStatusList; + } + + public boolean isUploadCompleted() { + return isUploadCompleted; + } + + public void setUploadCompleted(boolean isUploadCompleted) { + this.isUploadCompleted = isUploadCompleted; + } - /** + + public void setStatusPopupMinimized(boolean isStatusPopupMinimized) { + this.isStatusPopupMinimized = isStatusPopupMinimized; + } + + public boolean isStatusPopupMinimized() { + return isStatusPopupMinimized; + } + + + + + /** * Set software. * * @return 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 8c1feeb33..976d5ac27 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 @@ -13,11 +13,13 @@ import java.io.OutputStream; 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.state.CustomFile; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.vaadin.spring.events.EventBus; import com.vaadin.server.StreamVariable; import com.vaadin.ui.Upload; @@ -66,6 +68,8 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene private volatile boolean interrupted = false; private String failureReason; private final I18N i18n; + private transient EventBus.SessionEventBus eventBus; + UploadHandler(final String fileName, final long fileSize, final UploadLayout view, final UploadStatusInfoWindow infoWindow, final long maxSize, final Upload upload, final String mimeType) { @@ -78,7 +82,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene this.upload = upload; this.mimeType = mimeType; this.i18n = SpringContextHelper.getBean(I18N.class); - + this.eventBus = SpringContextHelper.getBean(EventBus.SessionEventBus.class); } /** @@ -166,7 +170,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene if (view.enableProcessBtn()) { infoWindow.uploadSessionFinished(); } - view.updateActionCount(); + eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_STREAMINING_FINISHED); // display the duplicate message after streaming all files view.displayDuplicateValidationMessage(); @@ -237,10 +241,12 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public void updateProgress(final long readBytes, final long contentLength) { if (readBytes > maxSize || contentLength > maxSize) { LOG.error("User tried to upload more than was allowed ({}).", maxSize); + view.decreaseNumberOfFileUploadsExpected(); final SoftwareModule sw = view.getSoftwareModuleSelected(); view.getFileSelected().remove(new CustomFile(fileName, sw.getName(), sw.getVersion())); view.updateActionCount(); + failureReason = i18n.get("message.uploadedfile.size.exceeded", maxSize); infoWindow.uploadFailed(fileName, failureReason); upload.interruptUpload(); @@ -261,10 +267,12 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public void onProgress(final StreamingProgressEvent event) { if (event.getBytesReceived() > maxSize || event.getContentLength() > maxSize) { LOG.error("User tried to upload more than was allowed ({}).", maxSize); + view.decreaseNumberOfFileUploadsExpected(); final SoftwareModule sw = view.getSoftwareModuleSelected(); view.getFileSelected().remove(new CustomFile(fileName, sw.getName(), sw.getVersion())); - view.updateActionCount(); + eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_STREAMINING_FINISHED); + failureReason = i18n.get("message.uploadedfile.size.exceeded", maxSize); infoWindow.uploadFailed(event.getFileName(), failureReason); interrupted = true; @@ -285,11 +293,19 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public void streamingFailed(final StreamingErrorEvent event) { LOG.info("Streaming failed for file :{}", event.getFileName()); + view.decreaseNumberOfFileUploadsExpected(); final SoftwareModule sw = view.getSoftwareModuleSelected(); view.getFileSelected().remove(new CustomFile(fileName, sw.getName(), sw.getVersion())); - view.updateActionCount(); - infoWindow.uploadFailed(event.getFileName(), failureReason); + eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_STREAMINING_FINISHED); + + if (failureReason != null) { + // Display custom error message + infoWindow.uploadFailed(event.getFileName(), failureReason); + } else { + // internal upload error + infoWindow.uploadFailed(event.getFileName(), event.getException().getMessage()); + } // check if we are finished if (view.enableProcessBtn()) { infoWindow.uploadSessionFinished(); @@ -299,6 +315,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene LOG.info("Streaming failed due to :{}", event.getException()); } + /** * Upload failed for {@link Upload} variant. * 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 7376cce13..340f66287 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 @@ -103,7 +103,7 @@ public class UploadLayout extends VerticalLayout { private final List duplicateFileNamesList = new ArrayList<>(); - private Button processBtn; + private Button processBtn ; private Button discardBtn; @@ -119,6 +119,8 @@ public class UploadLayout extends VerticalLayout { private Boolean hasDirectory = Boolean.FALSE; + private Button uploadStatusButton; + /** * Initialize the upload layout. */ @@ -127,12 +129,13 @@ public class UploadLayout extends VerticalLayout { createComponents(); buildLayout(); updateActionCount(); + restoreState(); eventBus.subscribe(this); ui = UI.getCurrent(); } private void createComponents() { - + createUploadStatusButton(); createProcessButton(); createDiscardBtn(); } @@ -154,12 +157,15 @@ public class UploadLayout extends VerticalLayout { fileUploadLayout = new HorizontalLayout(); fileUploadLayout.setSpacing(true); + fileUploadLayout.addStyleName(SPUIStyleDefinitions.FOOTER_LAYOUT); fileUploadLayout.addComponent(upload); fileUploadLayout.setComponentAlignment(upload, Alignment.MIDDLE_LEFT); fileUploadLayout.addComponent(processBtn); fileUploadLayout.setComponentAlignment(processBtn, Alignment.MIDDLE_RIGHT); fileUploadLayout.addComponent(discardBtn); fileUploadLayout.setComponentAlignment(discardBtn, Alignment.MIDDLE_RIGHT); + fileUploadLayout.addComponent(uploadStatusButton); + fileUploadLayout.setComponentAlignment(uploadStatusButton, Alignment.MIDDLE_RIGHT); setMargin(false); /* create drag-drop wrapper for drop area */ @@ -167,7 +173,13 @@ public class UploadLayout extends VerticalLayout { dropAreaWrapper.setDropHandler(new DropAreahandler()); setSizeFull(); setSpacing(true); + } + private void restoreState() { + if (artifactUploadState.isStatusPopupMinimized()) { + showUploadStatusButton(); + setUploadStatusButtonIconToFinished(); + } } public DragAndDropWrapper getDropAreaWrapper() { @@ -324,8 +336,8 @@ public class UploadLayout extends VerticalLayout { final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( + selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); final CustomFile customFile = new CustomFile(name, size, tempFile.getAbsolutePath(), selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion(), mimeType); @@ -403,8 +415,8 @@ public class UploadLayout extends VerticalLayout { public Boolean checkIfFileIsDuplicate(final String name) { Boolean isDuplicate = false; final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( + selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); for (final CustomFile customFile : artifactUploadState.getFileSelected()) { final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( @@ -469,8 +481,8 @@ public class UploadLayout extends VerticalLayout { void updateFileSize(final String name, final long size) { final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( + selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); for (final CustomFile customFile : artifactUploadState.getFileSelected()) { final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( @@ -507,9 +519,10 @@ public class UploadLayout extends VerticalLayout { if (event.getButton().equals(discardBtn)) { if (artifactUploadState.getFileSelected().isEmpty()) { uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); - } else { clearFileList(); + uploadInfoWindow.clearWindow(); + hideUploadStatusButton(); } } } @@ -536,12 +549,12 @@ public class UploadLayout extends VerticalLayout { private void setConfirmationPopupHeightWidth(final float newWidth, final float newHeight) { if (currentUploadConfirmationwindow != null) { - currentUploadConfirmationwindow.getUploadArtifactDetails().setWidth(HawkbitCommonUtil - .getArtifactUploadPopupWidth(newWidth, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), - Unit.PIXELS); - currentUploadConfirmationwindow.getUploadDetailsTable().setHeight(HawkbitCommonUtil - .getArtifactUploadPopupHeight(newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), - Unit.PIXELS); + currentUploadConfirmationwindow.getUploadArtifactDetails().setWidth( + HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, + SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); + currentUploadConfirmationwindow.getUploadDetailsTable().setHeight( + HawkbitCommonUtil.getArtifactUploadPopupHeight(newHeight, + SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); } } @@ -558,10 +571,12 @@ public class UploadLayout extends VerticalLayout { && currentUploadConfirmationwindow.getCurrentUploadResultWindow() != null) { final UploadResultWindow uploadResultWindow = currentUploadConfirmationwindow .getCurrentUploadResultWindow(); - uploadResultWindow.getUploadResultsWindow().setWidth(HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, - SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); - uploadResultWindow.getUploadResultTable().setHeight(HawkbitCommonUtil.getArtifactUploadPopupHeight( - newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); + uploadResultWindow.getUploadResultsWindow().setWidth( + HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, + SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); + uploadResultWindow.getUploadResultTable().setHeight( + HawkbitCommonUtil.getArtifactUploadPopupHeight(newHeight, + SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); } } @@ -572,8 +587,8 @@ public class UploadLayout extends VerticalLayout { } else { currentUploadConfirmationwindow = new UploadConfirmationwindow(this, artifactUploadState); UI.getCurrent().addWindow(currentUploadConfirmationwindow.getUploadConfrimationWindow()); - setConfirmationPopupHeightWidth(Page.getCurrent().getBrowserWindowWidth(), - Page.getCurrent().getBrowserWindowHeight()); + setConfirmationPopupHeightWidth(Page.getCurrent().getBrowserWindowWidth(), Page.getCurrent() + .getBrowserWindowHeight()); } } } @@ -608,7 +623,20 @@ public class UploadLayout extends VerticalLayout { void onEvent(final UploadArtifactUIEvent event) { if (event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE) { ui.access(() -> updateActionCount()); + } else if (event == UploadArtifactUIEvent.MINIMIZED_STATUS_POPUP) { + ui.access(() -> showUploadStatusButton()); + } else if (event == UploadArtifactUIEvent.MAXIMIZED_STATUS_POPUP) { + ui.access(() -> maximizeStatusPopup()); + } else if (event == UploadArtifactUIEvent.UPLOAD_FINISHED) { + ui.access(() -> setUploadStatusButtonIconToFinished()); + } else if (event == UploadArtifactUIEvent.UPLOAD_STARTED) { + ui.access(() -> setUploadStatusButtonIconToInProgress()); + }else if (event == UploadArtifactUIEvent.UPLOAD_STREAMINING_FINISHED) { + //TODO re-check + updateActionCount(); + enableProcessBtn(); } + } @PreDestroy @@ -637,8 +665,8 @@ public class UploadLayout extends VerticalLayout { * @param selectedBaseSoftwareModule */ public void refreshArtifactDetailsLayout(final SoftwareModule selectedBaseSoftwareModule) { - eventBus.publish(this, - new SoftwareModuleEvent(SoftwareModuleEventType.ARTIFACTS_CHANGED, selectedBaseSoftwareModule)); + eventBus.publish(this, new SoftwareModuleEvent(SoftwareModuleEventType.ARTIFACTS_CHANGED, + selectedBaseSoftwareModule)); } /** @@ -655,4 +683,55 @@ public class UploadLayout extends VerticalLayout { public void setHasDirectory(final Boolean hasDirectory) { this.hasDirectory = hasDirectory; } + + private void createUploadStatusButton() { + uploadStatusButton = SPUIComponentProvider.getButton(SPUIComponetIdProvider.UPLOAD_STATUS_BUTTON, "", "", "", + false, null, SPUIButtonStyleSmall.class); + uploadStatusButton.setStyleName(SPUIStyleDefinitions.ACTION_BUTTON); + uploadStatusButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); + uploadStatusButton.setWidth("100px"); + uploadStatusButton.setHtmlContentAllowed(true); + uploadStatusButton.addClickListener(event -> onClickOfUploadStatusButton()); + uploadStatusButton.setVisible(false); + } + + private void onClickOfUploadStatusButton() { + artifactUploadState.setStatusPopupMinimized(false); + eventBus.publish(this, UploadArtifactUIEvent.MAXIMIZED_STATUS_POPUP); + } + + private void showUploadStatusButton() { + if (uploadStatusButton == null) { + return; + } + uploadStatusButton.setVisible(true); + } + + private void hideUploadStatusButton() { + if (uploadStatusButton == null) { + return; + } + uploadStatusButton.setVisible(false); + } + + private void maximizeStatusPopup() { + hideUploadStatusButton(); + uploadInfoWindow.maximizeStatusPopup(); + } + + private void setUploadStatusButtonIconToFinished() { + if (uploadStatusButton == null) { + return; + } + uploadStatusButton.removeStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); + uploadStatusButton.setIcon(FontAwesome.UPLOAD); + } + + private void setUploadStatusButtonIconToInProgress() { + if (uploadStatusButton == null) { + return; + } + uploadStatusButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); + uploadStatusButton.setIcon(null); + } } 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 8b36ef39e..4693ab3dc 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 @@ -8,20 +8,37 @@ */ package org.eclipse.hawkbit.ui.artifacts.upload; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import java.util.List; +import java.util.stream.Collectors; +import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; +import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; +import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.springframework.beans.factory.annotation.Autowired; +import org.vaadin.spring.events.EventBus; + +import com.vaadin.data.Container.Indexed; import com.vaadin.data.Item; import com.vaadin.data.util.IndexedContainer; import com.vaadin.server.FontAwesome; import com.vaadin.shared.ui.window.WindowMode; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Grid; import com.vaadin.ui.Grid.SelectionMode; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.renderers.HtmlRenderer; import com.vaadin.ui.renderers.ProgressBarRenderer; +import com.vaadin.ui.themes.ValoTheme; import elemental.json.JsonValue; @@ -34,7 +51,13 @@ import elemental.json.JsonValue; @ViewScope @SpringComponent -public class UploadStatusInfoWindow extends Window implements Window.CloseListener, Window.WindowModeChangeListener { +public class UploadStatusInfoWindow extends Window { + + @Autowired + private transient EventBus.SessionEventBus eventBus; + + @Autowired + private ArtifactUploadState artifactUploadState; private static final String PROGRESS = "Progress"; @@ -52,39 +75,105 @@ public class UploadStatusInfoWindow extends Window implements Window.CloseListen private volatile boolean errorOccured = false; + private Button minimizeButton; + + private VerticalLayout mainLayout; + + private Label windowCaption; + + private Button closeButton; + + private Button resizeButton; + /** * Default Constructor. */ UploadStatusInfoWindow() { - super("Upload Status"); + super(); - addStyleName(SPUIStyleDefinitions.UPLOAD_INFO); - center(); - setImmediate(true); - setResizable(true); - setDraggable(true); - setClosable(true); - uploads = new IndexedContainer(); - uploads.addContainerProperty(STATUS, String.class, "Active"); - uploads.addContainerProperty(FILE_NAME, String.class, null); - uploads.addContainerProperty(PROGRESS, Double.class, 0D); - uploads.addContainerProperty(REASON, String.class, ""); + setPopupProperties(); + createStatusPopupHeaderComponents(); - grid = new Grid(uploads); - grid.addStyleName(SPUIStyleDefinitions.UPLOAD_STATUS_GRID); - grid.setSelectionMode(SelectionMode.NONE); - grid.getColumn(STATUS).setRenderer(new StatusRenderer()); - grid.getColumn(PROGRESS).setRenderer(new ProgressBarRenderer()); - setColumnWidth(); - grid.setFrozenColumnCount(4); - grid.setColumnOrder(STATUS, PROGRESS, FILE_NAME, REASON); - grid.setHeaderVisible(true); - grid.setImmediate(true); + mainLayout = new VerticalLayout(); + mainLayout.setSpacing(Boolean.TRUE); + mainLayout.setSizeUndefined(); setPopupSizeInMinMode(); - setContent(grid); - addCloseListener(this); - addWindowModeChangeListener(this); + uploads = getGridContainer(); + grid = createGrid(); + setGridColumnProperties(); + + mainLayout.addComponents(getCaptionLayout(), grid); + mainLayout.setExpandRatio(grid, 1.0F); + setContent(mainLayout); + } + + private void restoreState() { + Indexed container = grid.getContainerDataSource(); + if (container.getItemIds().isEmpty()) { + container.removeAllItems(); + for (UploadStatusObject statusObject : artifactUploadState.getUploadedFileStatusList()) { + Item item = container.addItem(statusObject.getFilename()); + item.getItemProperty(REASON).setValue(statusObject.getReason() != null ? statusObject.getReason() : ""); + item.getItemProperty(STATUS).setValue(statusObject.getStatus()); + item.getItemProperty(PROGRESS).setValue(statusObject.getProgress()); + item.getItemProperty(FILE_NAME).setValue(statusObject.getFilename()); + } + artifactUploadState.setUploadCompleted(true); + minimizeButton.setEnabled(false); + } + } + + private void setPopupProperties() { + addStyleName(SPUIStyleDefinitions.UPLOAD_INFO); + setImmediate(true); + setResizable(false); + setDraggable(true); + setClosable(false); + } + + private void setGridColumnProperties() { + grid.getColumn(STATUS).setRenderer(new StatusRenderer()); + grid.getColumn(PROGRESS).setRenderer(new ProgressBarRenderer()); + grid.setColumnOrder(STATUS, PROGRESS, FILE_NAME, REASON); + setColumnWidth(); + grid.setFrozenColumnCount(4); + } + + private Grid createGrid() { + Grid statusGrid = new Grid(uploads); + statusGrid.addStyleName(SPUIStyleDefinitions.UPLOAD_STATUS_GRID); + statusGrid.setSelectionMode(SelectionMode.NONE); + statusGrid.setHeaderVisible(true); + statusGrid.setImmediate(true); + statusGrid.setSizeFull(); + return statusGrid; + } + + private IndexedContainer getGridContainer() { + IndexedContainer uploadContainer = new IndexedContainer(); + uploadContainer.addContainerProperty(STATUS, String.class, "Active"); + uploadContainer.addContainerProperty(FILE_NAME, String.class, null); + uploadContainer.addContainerProperty(PROGRESS, Double.class, 0D); + uploadContainer.addContainerProperty(REASON, String.class, ""); + return uploadContainer; + } + + private HorizontalLayout getCaptionLayout() { + final HorizontalLayout captionLayout = new HorizontalLayout(); + captionLayout.setSizeFull(); + captionLayout.setHeight("36px"); + captionLayout.addComponents(windowCaption, minimizeButton, resizeButton, closeButton); + captionLayout.setExpandRatio(windowCaption, 1.0F); + captionLayout.addStyleName("v-window-header"); + return captionLayout; + } + + private void createStatusPopupHeaderComponents() { + minimizeButton = getMinimizeButton(); + windowCaption = new Label("Upload status"); + closeButton = getCloseButton(); + resizeButton = getResizeButton(); } private void setColumnWidth() { @@ -99,15 +188,13 @@ public class UploadStatusInfoWindow extends Window implements Window.CloseListen grid.getColumn(PROGRESS).setWidthUndefined(); grid.getColumn(FILE_NAME).setWidthUndefined(); grid.getColumn(REASON).setWidthUndefined(); - } private static class StatusRenderer extends HtmlRenderer { @Override public JsonValue encode(final String value) { - - String result = ""; + String result ; switch (value) { case "Finished": result = "
" + FontAwesome.CHECK_CIRCLE.getHtml() + "
"; @@ -129,28 +216,52 @@ public class UploadStatusInfoWindow extends Window implements Window.CloseListen void uploadSessionFinished() { if (!errorOccured) { close(); + eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_FINISHED); + artifactUploadState.setUploadCompleted(true); + minimizeButton.setEnabled(false); } } void uploadSessionStarted() { close(); + openWindow(); + minimizeButton.setEnabled(true); + eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_STARTED); + artifactUploadState.setUploadCompleted(false); + } + + void openWindow() { UI.getCurrent().addWindow(this); center(); } + void maximizeStatusPopup() { + openWindow(); + restoreState(); + } + void uploadStarted(final String filename) { final Item item = uploads.addItem(filename); item.getItemProperty(FILE_NAME).setValue(filename); grid.scrollToEnd(); - + UploadStatusObject uploadStatus = new UploadStatusObject(filename); + uploadStatus.setStatus("Active"); + artifactUploadState.getUploadedFileStatusList().add(uploadStatus); } void updateProgress(final String filename, final long readBytes, final long contentLength) { final Item item = uploads.getItem(filename); if (item != null) { - item.getItemProperty(PROGRESS).setValue((double) readBytes / (double) contentLength); - + double progress = (double) readBytes / (double) contentLength; + item.getItemProperty(PROGRESS).setValue(progress); + List uploadStatusObjectList = (List) artifactUploadState + .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) + .collect(Collectors.toList()); + if (!uploadStatusObjectList.isEmpty()) { + UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); + uploadStatusObject.setProgress(progress); + } } } @@ -163,8 +274,15 @@ public class UploadStatusInfoWindow extends Window implements Window.CloseListen public void uploadSucceeded(final String filename) { final Item item = uploads.getItem(filename); if (item != null) { - item.getItemProperty(STATUS).setValue("Finished"); - + String status = "Finished"; + item.getItemProperty(STATUS).setValue(status); + List uploadStatusObjectList = (List) artifactUploadState + .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) + .collect(Collectors.toList()); + if (!uploadStatusObjectList.isEmpty()) { + UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); + uploadStatusObject.setStatus(status); + } } } @@ -175,51 +293,81 @@ public class UploadStatusInfoWindow extends Window implements Window.CloseListen errorOccured = true; } item.getItemProperty(REASON).setValue(errorReason); - item.getItemProperty(STATUS).setValue("Failed"); - + String status = "Failed"; + item.getItemProperty(STATUS).setValue(status); + List uploadStatusObjectList = (List) artifactUploadState + .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) + .collect(Collectors.toList()); + if (!uploadStatusObjectList.isEmpty()) { + UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); + uploadStatusObject.setStatus(status); + uploadStatusObject.setReason(errorReason); + } } } - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Window.CloseListener#windowClose(com.vaadin.ui.Window. - * CloseEvent) - */ - @Override - public void windowClose(final CloseEvent e) { - clearWindow(); - } - - private void clearWindow() { + protected void clearWindow() { errorOccured = false; uploads.removeAllItems(); setWindowMode(WindowMode.NORMAL); + this.close(); + artifactUploadState.getUploadedFileStatusList().clear(); } - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Window.WindowModeChangeListener#windowModeChanged(com. - * vaadin.ui.Window. WindowModeChangeEvent) - */ - @Override - public void windowModeChanged(final WindowModeChangeEvent event) { - if (event.getWindow().getWindowMode() == WindowMode.MAXIMIZED) { + private void setPopupSizeInMinMode() { + mainLayout.setWidth(800, Unit.PIXELS); + mainLayout.setHeight(510, Unit.PIXELS); + } + + private Button getMinimizeButton() { + final Button minimizeBtn = SPUIComponentProvider.getButton( + SPUIComponetIdProvider.UPLOAD_STATUS_POPUP_MINIMIZE_BUTTON_ID, "", "", "", true, FontAwesome.MINUS, + SPUIButtonStyleSmallNoBorder.class); + minimizeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); + minimizeBtn.addClickListener(event -> minimizeWindow()); + minimizeBtn.setEnabled(true); + return minimizeBtn; + } + + private Button getResizeButton() { + final Button resizeBtn = SPUIComponentProvider.getButton( + SPUIComponetIdProvider.UPLOAD_STATUS_POPUP_RESIZE_BUTTON_ID, "", "", "", true, FontAwesome.EXPAND, + SPUIButtonStyleSmallNoBorder.class); + resizeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); + resizeBtn.addClickListener(event -> resizeWindow(event)); + return resizeBtn; + } + + private void resizeWindow(ClickEvent event) { + if (event.getButton().getIcon() == FontAwesome.EXPAND) { + event.getButton().setIcon(FontAwesome.COMPRESS); + setWindowMode(WindowMode.MAXIMIZED); resetColumnWidth(); grid.getColumn(STATUS).setExpandRatio(0); grid.getColumn(PROGRESS).setExpandRatio(1); grid.getColumn(FILE_NAME).setExpandRatio(2); grid.getColumn(REASON).setExpandRatio(3); - grid.setSizeFull(); + mainLayout.setSizeFull(); } else { + event.getButton().setIcon(FontAwesome.EXPAND); + setWindowMode(WindowMode.NORMAL); setColumnWidth(); setPopupSizeInMinMode(); } } - private void setPopupSizeInMinMode() { - grid.setWidth(800, Unit.PIXELS); - grid.setHeight(510, Unit.PIXELS); + private void minimizeWindow() { + this.close(); + artifactUploadState.setStatusPopupMinimized(true); + eventBus.publish(this, UploadArtifactUIEvent.MINIMIZED_STATUS_POPUP); + } + + private Button getCloseButton() { + final Button closeBtn = SPUIComponentProvider.getButton( + SPUIComponetIdProvider.UPLOAD_STATUS_POPUP_CLOSE_BUTTON_ID, "", "", "", true, FontAwesome.TIMES, + SPUIButtonStyleSmallNoBorder.class); + closeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); + closeBtn.addClickListener(event -> clearWindow()); + return closeBtn; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java new file mode 100644 index 000000000..80c71fe7b --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.upload; + +public class UploadStatusObject { + private String status; + private Double progress; + private String filename; + private String reason; + + public UploadStatusObject(String status, Double progress, String fileName, String reason) { + this(fileName); + this.status = status; + this.progress = progress; + this.reason = reason; + } + + public UploadStatusObject(String fileName) { + this.filename = fileName; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Double getProgress() { + return progress; + } + + public void setProgress(Double progress) { + this.progress = progress; + } + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + @Override + public boolean equals(Object obj) { + if (this == null || obj == null) { + return false; + } + if (obj instanceof UploadStatusObject && this.getFilename() == ((UploadStatusObject) obj).getFilename()) { + return true; + } + return false; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java index 75bd43447..09ab92cee 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java @@ -130,7 +130,7 @@ public abstract class AbstractDeleteActionsLayout extends VerticalLayout impleme addComponent(hLayout); setComponentAlignment(hLayout, Alignment.BOTTOM_CENTER); } - setStyleName("footer-layout"); + setStyleName(SPUIStyleDefinitions.FOOTER_LAYOUT); setWidth("100%"); } @@ -168,7 +168,7 @@ public abstract class AbstractDeleteActionsLayout extends VerticalLayout impleme final Button button = SPUIComponentProvider.getButton(SPUIComponetIdProvider.BULK_UPLOAD_STATUS_BUTTON, "", "", "", false, null, SPUIButtonStyleSmall.class); button.setStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - button.addStyleName(SPUIStyleDefinitions.BULK_UPLOAD_PROGRESS_INDICATOR_STYLE); + button.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); button.setWidth("100px"); button.setHtmlContentAllowed(true); button.addClickListener(event -> onClickBulkUploadNotificationButton()); @@ -199,7 +199,7 @@ public abstract class AbstractDeleteActionsLayout extends VerticalLayout impleme if (bulkUploadStatusButton == null) { return; } - bulkUploadStatusButton.removeStyleName(SPUIStyleDefinitions.BULK_UPLOAD_PROGRESS_INDICATOR_STYLE); + bulkUploadStatusButton.removeStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); bulkUploadStatusButton.setIcon(FontAwesome.UPLOAD); } @@ -207,7 +207,7 @@ public abstract class AbstractDeleteActionsLayout extends VerticalLayout impleme if (bulkUploadStatusButton == null) { return; } - bulkUploadStatusButton.addStyleName(SPUIStyleDefinitions.BULK_UPLOAD_PROGRESS_INDICATOR_STYLE); + bulkUploadStatusButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); bulkUploadStatusButton.setIcon(null); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridLayout.java index 98c14e698..308bbeec4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridLayout.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.common.grid; import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import com.vaadin.ui.Alignment; import com.vaadin.ui.HorizontalLayout; @@ -72,7 +73,7 @@ public abstract class AbstractGridLayout extends VerticalLayout { final Label countMessageLabel = getCountMessageLabel(); countMessageLabel.setId(SPUIComponetIdProvider.ROLLOUT_GROUP_TARGET_LABEL); rolloutGroupTargetsCountLayout.addComponent(getCountMessageLabel()); - rolloutGroupTargetsCountLayout.setStyleName("footer-layout"); + rolloutGroupTargetsCountLayout.setStyleName(SPUIStyleDefinitions.FOOTER_LAYOUT); rolloutGroupTargetsCountLayout.setWidth("100%"); return rolloutGroupTargetsCountLayout; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java index 06cbe4d69..99c586070 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java @@ -14,6 +14,7 @@ import org.eclipse.hawkbit.ui.HawkbitUI; import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; import org.eclipse.hawkbit.ui.filtermanagement.footer.TargetFilterCountMessageLabel; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventScope; @@ -151,7 +152,7 @@ public class FilterManagementView extends VerticalLayout implements View { private HorizontalLayout addTargetFilterMessageLabel() { final HorizontalLayout messageLabelLayout = new HorizontalLayout(); messageLabelLayout.addComponent(targetFilterCountMessageLabel); - messageLabelLayout.addStyleName("footer-layout"); + messageLabelLayout.addStyleName(SPUIStyleDefinitions.FOOTER_LAYOUT); return messageLabelLayout; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java index 48e501e1d..7c25bf90a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java @@ -883,6 +883,27 @@ public final class SPUIComponetIdProvider { */ public static final String VALIDATION_STATUS_ICON_ID = "validation.status.icon"; + /** + * Artifact upload status popup - minimize button id. + */ + public static final String UPLOAD_STATUS_POPUP_MINIMIZE_BUTTON_ID = "artifact.upload.minimize.button.id"; + + /** + * Artifact upload status popup - close button id. + */ + public static final String UPLOAD_STATUS_POPUP_CLOSE_BUTTON_ID = "artifact.upload.close.button.id"; + + /** + * Artifact upload status popup - resize button id. + */ + public static final String UPLOAD_STATUS_POPUP_RESIZE_BUTTON_ID = "artifact.upload.resize.button.id"; + + /** + * Artifact upload view - upload status button id. + */ + public static final String UPLOAD_STATUS_BUTTON = "artficat.upload.status.button.id"; + + /** * /* Private Constructor. */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java index c50135251..ac713a07c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java @@ -240,9 +240,9 @@ public final class SPUIStyleDefinitions { public static final String DISABLE_ACTION_TYPE_LAYOUT = "disable-action-type-layout"; /** - * Bulk upload progress indicator style. + * Upload progress indicator style. */ - public static final String BULK_UPLOAD_PROGRESS_INDICATOR_STYLE = "app-loading"; + public static final String UPLOAD_PROGRESS_INDICATOR_STYLE = "app-loading"; /** * Target filter search progress indicator style. @@ -293,6 +293,11 @@ public final class SPUIStyleDefinitions { * Status pending icon. */ public static final String STATUS_ICON_PENDING = "statusIconPending"; + + /** + * Footer layout style. + */ + public static final String FOOTER_LAYOUT = "footer-layout"; /** * Constructor. From 68ab2eb30e71f404c8caadd4c47f7e6bce09e788 Mon Sep 17 00:00:00 2001 From: Asharani Date: Fri, 6 May 2016 10:28:50 +0530 Subject: [PATCH 02/16] Set error message from exception Signed-off-by: Asharani --- .../hawkbit/ui/artifacts/upload/UploadHandler.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 976d5ac27..c48dac834 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 @@ -333,8 +333,12 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene final SoftwareModule sw = view.getSoftwareModuleSelected(); view.getFileSelected().remove(new CustomFile(fileName, sw.getName(), sw.getVersion())); } - view.updateActionCount(); - infoWindow.uploadFailed(event.getFilename(), failureReason); + eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_STREAMINING_FINISHED); + if (failureReason != null) { + infoWindow.uploadFailed(event.getFilename(), failureReason); + } else { + infoWindow.uploadFailed(event.getFilename(), event.getReason().getMessage()); + } LOG.info("Upload failed for file :{}", event.getReason()); } From 887536b2b79561724e3cf7817fff739b7df650d7 Mon Sep 17 00:00:00 2001 From: Asharani Date: Mon, 9 May 2016 10:42:23 +0530 Subject: [PATCH 03/16] Upload confirmation popup - on discard remove the upload status button Signed-off-by: Asharani --- .../artifacts/upload/UploadConfirmationwindow.java | 2 +- .../hawkbit/ui/artifacts/upload/UploadLayout.java | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java index f009985f9..d7231cafe 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java @@ -544,7 +544,7 @@ public class UploadConfirmationwindow implements Button.ClickListener { if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_ARTIFACT_DETAILS_CLOSE)) { uploadConfrimationWindow.close(); } else if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_DISCARD_DETAILS_BUTTON)) { - uploadLayout.clearFileList(); + uploadLayout.removeUploadedFileDetails(); uploadConfrimationWindow.close(); } else if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_BUTTON)) { processArtifactUpload(); 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 340f66287..9e304efe8 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 @@ -520,13 +520,17 @@ public class UploadLayout extends VerticalLayout { if (artifactUploadState.getFileSelected().isEmpty()) { uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); } else { - clearFileList(); - uploadInfoWindow.clearWindow(); - hideUploadStatusButton(); + removeUploadedFileDetails(); } } } + protected void removeUploadedFileDetails() { + clearFileList(); + uploadInfoWindow.clearWindow(); + hideUploadStatusButton(); + } + /** * Clear details. */ @@ -707,7 +711,7 @@ public class UploadLayout extends VerticalLayout { uploadStatusButton.setVisible(true); } - private void hideUploadStatusButton() { + protected void hideUploadStatusButton() { if (uploadStatusButton == null) { return; } From 8fc1f74f807bbc3c7edd33bb734502c49b746bd0 Mon Sep 17 00:00:00 2001 From: Asharani Date: Thu, 12 May 2016 15:16:41 +0530 Subject: [PATCH 04/16] Refactored UploadHandler.java to update upload status using eventing Signed-off-by: Asharani --- hawkbit-ui/pom.xml | 5 + .../event/UploadArtifactUIEvent.java | 2 +- .../ui/artifacts/event/UploadFileStatus.java | 60 ++++++ .../ui/artifacts/event/UploadStatusEvent.java | 34 ++++ .../artifacts/state/ArtifactUploadState.java | 14 ++ .../ui/artifacts/upload/UploadHandler.java | 152 +++++---------- .../ui/artifacts/upload/UploadLayout.java | 183 +++++++++++++----- .../upload/UploadStatusInfoWindow.java | 102 +++++++--- 8 files changed, 374 insertions(+), 178 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadStatusEvent.java diff --git a/hawkbit-ui/pom.xml b/hawkbit-ui/pom.xml index e0bde576a..38b455367 100644 --- a/hawkbit-ui/pom.xml +++ b/hawkbit-ui/pom.xml @@ -254,5 +254,10 @@ allure-junit-adaptor test + + org.scala-lang + scala-library + 2.10.4 + \ No newline at end of file diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java index de8f5867b..8bd33f483 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java @@ -16,5 +16,5 @@ package org.eclipse.hawkbit.ui.artifacts.event; */ public enum UploadArtifactUIEvent { - SHOW_DROP_HINTS, HIDE_DROP_HINTS, SOFTWARE_DRAG_START, SOFTWARE_TYPE_DRAG_START, UPDATE_UPLOAD_COUNT, ENABLE_PROCESS_BUTTON, HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DISCARD_DELETE_SOFTWARE, DISCARD_ALL_DELETE_SOFTWARE, DELETED_ALL_SOFWARE, DISABLE_PROCESS_BUTTON, DISCARD_DELETE_SOFTWARE_TYPE, DISCARD_ALL_DELETE_SOFTWARE_TYPE, DELETED_ALL_SOFWARE_TYPE,MINIMIZED_STATUS_POPUP,MAXIMIZED_STATUS_POPUP,UPLOAD_FINISHED,UPLOAD_STARTED, UPLOAD_STREAMINING_FINISHED + SHOW_DROP_HINTS, HIDE_DROP_HINTS, SOFTWARE_DRAG_START, SOFTWARE_TYPE_DRAG_START, UPDATE_UPLOAD_COUNT, ENABLE_PROCESS_BUTTON, HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DISCARD_DELETE_SOFTWARE, DISCARD_ALL_DELETE_SOFTWARE, DELETED_ALL_SOFWARE, DISABLE_PROCESS_BUTTON, DISCARD_DELETE_SOFTWARE_TYPE, DISCARD_ALL_DELETE_SOFTWARE_TYPE, DELETED_ALL_SOFWARE_TYPE,MINIMIZED_STATUS_POPUP,MAXIMIZED_STATUS_POPUP, UPLOAD_IN_PROGESS } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java new file mode 100644 index 000000000..776556464 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.event; + +import java.io.Serializable; + +/** + * + * Holds file and upload status details. + * + */ +public class UploadFileStatus implements Serializable { + + private static final long serialVersionUID = -3599629192216760811L; + + private String fileName; + + private long contentLength; + + private long bytesRead; + + private String failureReason; + + public UploadFileStatus(String fileName){ + this.fileName = fileName; + } + + public UploadFileStatus(String fileName, long bytesRead, long contentLength) { + this.fileName = fileName; + this.contentLength = contentLength; + this.bytesRead = bytesRead; + } + + public UploadFileStatus(String fileName, String failureReason) { + this.failureReason = failureReason; + this.fileName = fileName; + } + + public String getFileName() { + return fileName; + } + + public long getContentLength() { + return contentLength; + } + + public long getBytesRead() { + return bytesRead; + } + + public String getFailureReason() { + return failureReason; + } +} 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 new file mode 100644 index 000000000..ab10c2e10 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadStatusEvent.java @@ -0,0 +1,34 @@ +package org.eclipse.hawkbit.ui.artifacts.event; +/** + * + * Holds the upload file status. + * + */ +public class UploadStatusEvent { + + public enum UploadStatusEventType { + UPLOAD_FAILED, UPLOAD_IN_PROGRESS, UPLOAD_STARTED, UPLOAD_FINISHED, UPLOAD_SUCCESSFUL, UPLOAD_STREAMING_FAILED, UPLOAD_STREAMING_FINISHED + } + + private UploadStatusEventType uploadProgressEventType; + + private UploadFileStatus uploadStatus; + + public UploadStatusEvent(UploadStatusEventType eventType, UploadFileStatus entity) { + this.uploadProgressEventType = eventType; + this.uploadStatus = entity; + } + + public UploadFileStatus getUploadStatus() { + return uploadStatus; + } + + public void setUploadStatus(UploadFileStatus uploadStatus) { + this.uploadStatus = uploadStatus; + } + + public UploadStatusEventType getUploadProgressEventType() { + return uploadProgressEventType; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java index ae6a5860e..9c0ade8d1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.ui.artifacts.upload.UploadStatusObject; @@ -68,6 +69,19 @@ public class ArtifactUploadState implements ManagmentEntityState, Serializ private List uploadedFileStatusList = new ArrayList<>(); + private final AtomicInteger numberOfFileUploadsExpected = new AtomicInteger(); + + private final AtomicInteger numberOfFilesActuallyUpload = new AtomicInteger(); + + public AtomicInteger getNumberOfFilesActuallyUpload() { + return numberOfFilesActuallyUpload; + } + + public AtomicInteger getNumberOfFileUploadsExpected() { + return numberOfFileUploadsExpected; + } + + public List getUploadedFileStatusList() { return uploadedFileStatusList; } 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 c48dac834..f9d207193 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 @@ -12,9 +12,10 @@ import java.io.IOException; import java.io.OutputStream; 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.state.CustomFile; +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; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.slf4j.Logger; @@ -59,30 +60,29 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene private final long fileSize; private final UploadLayout view; - private final UploadStatusInfoWindow infoWindow; private final long maxSize; private final Upload upload; private volatile String fileName = null; private volatile String mimeType = null; - private volatile boolean interrupted = false; + private volatile boolean streamingInterrupted = false; + private volatile boolean uploadInterrupted = false; + private String failureReason; private final I18N i18n; private transient EventBus.SessionEventBus eventBus; - UploadHandler(final String fileName, final long fileSize, final UploadLayout view, - final UploadStatusInfoWindow infoWindow, final long maxSize, final Upload upload, final String mimeType) { + final long maxSize, final Upload upload, final String mimeType) { super(); this.fileName = fileName; this.fileSize = fileSize; this.view = view; - this.infoWindow = infoWindow; this.maxSize = maxSize; this.upload = upload; this.mimeType = mimeType; this.i18n = SpringContextHelper.getBean(I18N.class); - this.eventBus = SpringContextHelper.getBean(EventBus.SessionEventBus.class); + this.eventBus = SpringContextHelper.getBean(EventBus.SessionEventBus.class); } /** @@ -97,7 +97,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene } catch (final ArtifactUploadFailedException e) { LOG.error("Atifact upload failed {} ", e); failureReason = e.getMessage(); - interrupted = true; + streamingInterrupted = true; return new NullOutputStream(); } } @@ -112,7 +112,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public OutputStream receiveUpload(final String fileName, final String mimeType) { this.fileName = fileName; this.mimeType = mimeType; - //reset has directory flag before upload + // reset has directory flag before upload view.setHasDirectory(false); try { if (view.checkIfSoftwareModuleIsSelected()) { @@ -127,6 +127,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene LOG.error("Atifact upload failed {} ", e); failureReason = e.getMessage(); upload.interruptUpload(); + uploadInterrupted = true; } // if final validation fails ,final no upload ,return NullOutputStream return new NullOutputStream(); @@ -141,13 +142,8 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public void uploadSucceeded(final SucceededEvent event) { LOG.debug("Streaming finished for file :{}", event.getFilename()); - view.updateFileSize(event.getFilename(), event.getLength()); - - // recorded that we now one more uploaded - view.increaseNumberOfFilesActuallyUpload(); - - // inform upload status window - infoWindow.uploadSucceeded(event.getFilename()); + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_SUCCESSFUL, new UploadFileStatus( + event.getFilename(), 0, event.getLength()))); } /** @@ -160,20 +156,8 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public void streamingFinished(final StreamingEndEvent event) { LOG.debug("Streaming finished for file :{}", event.getFileName()); - // record that we now one more uploaded - view.increaseNumberOfFilesActuallyUpload(); - - // inform upload status window - infoWindow.uploadSucceeded(event.getFileName()); - - // check if we are finished - if (view.enableProcessBtn()) { - infoWindow.uploadSessionFinished(); - } - eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_STREAMINING_FINISHED); - - // display the duplicate message after streaming all files - view.displayDuplicateValidationMessage(); + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STREAMING_FINISHED, + new UploadFileStatus(event.getFileName(), 0, event.getContentLength()))); } /** @@ -185,12 +169,8 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public void uploadFinished(final FinishedEvent event) { LOG.debug("Upload finished for file :{}", event.getFilename()); - // check if we are finished - if (view.enableProcessBtn()) { - infoWindow.uploadSessionFinished(); - } - view.updateActionCount(); - + eventBus.publish(this, + new UploadStatusEvent(UploadStatusEventType.UPLOAD_FINISHED, new UploadFileStatus(event.getFilename()))); } /** @@ -201,7 +181,8 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public void streamingStarted(final StreamingStartEvent event) { LOG.debug("Streaming started for file :{}", fileName); - infoWindow.uploadStarted(fileName); + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STARTED, new UploadFileStatus( + fileName, 0, 0))); } /** @@ -213,12 +194,14 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public void uploadStarted(final StartedEvent event) { // single file session if (view.isSoftwareModuleSelected() && !view.checkIfFileIsDuplicate(event.getFilename())) { - infoWindow.uploadSessionStarted(); LOG.debug("Upload started for file :{}", event.getFilename()); - infoWindow.uploadStarted(event.getFilename()); + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STARTED, new UploadFileStatus( + event.getFilename(), 0, 0))); } else { failureReason = i18n.get("message.upload.failed"); upload.interruptUpload(); + // actual interrupt will happen a bit late so setting the below flag + uploadInterrupted = true; } } @@ -239,23 +222,21 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene */ @Override public void updateProgress(final long readBytes, final long contentLength) { - if (readBytes > maxSize || contentLength > maxSize) { - LOG.error("User tried to upload more than was allowed ({}).", maxSize); - - view.decreaseNumberOfFileUploadsExpected(); - final SoftwareModule sw = view.getSoftwareModuleSelected(); - view.getFileSelected().remove(new CustomFile(fileName, sw.getName(), sw.getVersion())); - view.updateActionCount(); - - failureReason = i18n.get("message.uploadedfile.size.exceeded", maxSize); - infoWindow.uploadFailed(fileName, failureReason); - upload.interruptUpload(); - interrupted = true; - return; + //Update progress is called event after upload interrupted in uploadStarted method + if (!uploadInterrupted) { + 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))); + upload.interruptUpload(); + uploadInterrupted = true; + return; + } + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_IN_PROGRESS, + new UploadFileStatus(fileName, readBytes, contentLength))); + LOG.info("Update progress - {} : {}", fileName, (double) readBytes / (double) contentLength); } - - infoWindow.updateProgress(fileName, readBytes, contentLength); - LOG.info("Update progress - {} : {}", fileName, (double) readBytes / (double) contentLength); } /** @@ -267,19 +248,14 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public void onProgress(final StreamingProgressEvent event) { if (event.getBytesReceived() > maxSize || event.getContentLength() > maxSize) { LOG.error("User tried to upload more than was allowed ({}).", maxSize); - - view.decreaseNumberOfFileUploadsExpected(); - final SoftwareModule sw = view.getSoftwareModuleSelected(); - view.getFileSelected().remove(new CustomFile(fileName, sw.getName(), sw.getVersion())); - eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_STREAMINING_FINISHED); - failureReason = i18n.get("message.uploadedfile.size.exceeded", maxSize); - infoWindow.uploadFailed(event.getFileName(), failureReason); - interrupted = true; + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_FAILED, new UploadFileStatus( + fileName, failureReason))); + streamingInterrupted = true; return; } - - infoWindow.updateProgress(event.getFileName(), event.getBytesReceived(), event.getContentLength()); + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_IN_PROGRESS, new UploadFileStatus( + fileName, event.getBytesReceived(), event.getContentLength()))); // Logging to solve sonar issue LOG.trace("Streaming in progress for file :{}", event.getFileName()); } @@ -293,29 +269,15 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public void streamingFailed(final StreamingErrorEvent event) { LOG.info("Streaming failed for file :{}", event.getFileName()); - - view.decreaseNumberOfFileUploadsExpected(); - final SoftwareModule sw = view.getSoftwareModuleSelected(); - view.getFileSelected().remove(new CustomFile(fileName, sw.getName(), sw.getVersion())); - eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_STREAMINING_FINISHED); - - if (failureReason != null) { - // Display custom error message - infoWindow.uploadFailed(event.getFileName(), failureReason); - } else { - // internal upload error - infoWindow.uploadFailed(event.getFileName(), event.getException().getMessage()); + if (failureReason == null) { + failureReason = event.getException().getMessage(); } - // check if we are finished - if (view.enableProcessBtn()) { - infoWindow.uploadSessionFinished(); - } - view.displayDuplicateValidationMessage(); + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STREAMING_FAILED, + new UploadFileStatus(fileName, failureReason))); LOG.info("Streaming failed due to :{}", event.getException()); } - /** * Upload failed for {@link Upload} variant. * @@ -324,23 +286,13 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public void uploadFailed(final FailedEvent event) { LOG.info("Upload failed for file :{}", event.getFilename()); - view.decreaseNumberOfFileUploadsExpected(); - /** - * If upload interrupted because of duplicate file,do not remove the - * file already in upload list - **/ - if (!view.getDuplicateFileNamesList().isEmpty()) { - final SoftwareModule sw = view.getSoftwareModuleSelected(); - view.getFileSelected().remove(new CustomFile(fileName, sw.getName(), sw.getVersion())); - } - eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_STREAMINING_FINISHED); - if (failureReason != null) { - infoWindow.uploadFailed(event.getFilename(), failureReason); - } else { - infoWindow.uploadFailed(event.getFilename(), event.getReason().getMessage()); + if (failureReason == null) { + failureReason = event.getReason().getMessage(); } + System.out.println("failureReason:::"+failureReason); + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_FAILED, new UploadFileStatus( + fileName, failureReason))); LOG.info("Upload failed for file :{}", event.getReason()); - } /** @@ -348,7 +300,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene */ @Override public boolean isInterrupted() { - return interrupted; + return streamingInterrupted; } private static class NullOutputStream extends OutputStream { 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 9e304efe8..58661773d 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 @@ -16,7 +16,6 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -26,6 +25,8 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType; 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.artifacts.state.CustomFile; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -97,13 +98,9 @@ public class UploadLayout extends VerticalLayout { @Autowired private transient SPInfo spInfo; - private final AtomicInteger numberOfFileUploadsExpected = new AtomicInteger(); - - private final AtomicInteger numberOfFilesActuallyUpload = new AtomicInteger(); - private final List duplicateFileNamesList = new ArrayList<>(); - private Button processBtn ; + private Button processBtn; private Button discardBtn; @@ -128,11 +125,48 @@ public class UploadLayout extends VerticalLayout { void init() { createComponents(); buildLayout(); - updateActionCount(); restoreState(); eventBus.subscribe(this); ui = UI.getCurrent(); } + + + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvent(final UploadArtifactUIEvent event) { + if (event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE) { + ui.access(() -> updateActionCount()); + } else if (event == UploadArtifactUIEvent.MINIMIZED_STATUS_POPUP) { + ui.access(() -> showUploadStatusButton()); + } else if (event == UploadArtifactUIEvent.MAXIMIZED_STATUS_POPUP) { + ui.access(() -> maximizeStatusPopup()); + } + } + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvent(final UploadStatusEvent event) { + if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STARTED) { + ui.access(() -> setUploadStatusButtonIconToInProgress()); + } + else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_FAILED) { + ui.access(() -> onUploadFailure(event)); + } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_FINISHED) { + ui.access(() -> onUploadCompletion()); + } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_SUCCESSFUL) { + ui.access(() -> onUploadSuccess(event)); + } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FAILED) { + ui.access(() -> onUploadStreamingFailure(event)); + } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FINISHED) { + ui.access(() -> onUploadStreamingSuccess(event)); + } + } + + @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); + } private void createComponents() { createUploadStatusButton(); @@ -143,8 +177,8 @@ public class UploadLayout extends VerticalLayout { private void buildLayout() { final Upload upload = new Upload(); - final UploadHandler uploadHandler = new UploadHandler(null, 0, this, uploadInfoWindow, - spInfo.getMaxArtifactFileSize(), upload, null); + final UploadHandler uploadHandler = new UploadHandler(null, 0, this, spInfo.getMaxArtifactFileSize(), upload, + null); upload.setButtonCaption(i18n.get("upload.file")); upload.setImmediate(true); upload.setReceiver(uploadHandler); @@ -176,9 +210,15 @@ public class UploadLayout extends VerticalLayout { } private void restoreState() { + updateActionCount(); + if (!artifactUploadState.getFileSelected().isEmpty() && artifactUploadState.isUploadCompleted()) { + processBtn.setEnabled(true); + } if (artifactUploadState.isStatusPopupMinimized()) { showUploadStatusButton(); - setUploadStatusButtonIconToFinished(); + if (artifactUploadState.isUploadCompleted()) { + setUploadStatusButtonIconToFinished(); + } } } @@ -204,10 +244,10 @@ public class UploadLayout extends VerticalLayout { for (final Html5File file : files) { processFile(file); } - if (numberOfFileUploadsExpected.get() > 0) { + if (artifactUploadState.getNumberOfFileUploadsExpected().get() > 0) { processBtn.setEnabled(false); // reset before we start - uploadInfoWindow.uploadSessionStarted(); + // uploadInfoWindow.uploadSessionStarted(); } else { // If the upload is not started, it signifies all // dropped files as either duplicate or directory.So @@ -220,7 +260,7 @@ public class UploadLayout extends VerticalLayout { private void processFile(final Html5File file) { if (!isDirectory(file)) { if (!checkForDuplicate(file.getFileName())) { - numberOfFileUploadsExpected.incrementAndGet(); + artifactUploadState.getNumberOfFileUploadsExpected().incrementAndGet(); file.setStreamVariable(createStreamVariable(file)); } } else { @@ -229,7 +269,7 @@ public class UploadLayout extends VerticalLayout { } private StreamVariable createStreamVariable(final Html5File file) { - return new UploadHandler(file.getFileName(), file.getFileSize(), UploadLayout.this, uploadInfoWindow, + return new UploadHandler(file.getFileName(), file.getFileSize(), UploadLayout.this, spInfo.getMaxArtifactFileSize(), null, file.getType()); } @@ -282,9 +322,7 @@ public class UploadLayout extends VerticalLayout { processBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); processBtn.addClickListener(event -> displayConfirmWindow(event)); processBtn.setHtmlContentAllowed(true); - if (artifactUploadState.getFileSelected().isEmpty()) { - processBtn.setEnabled(false); - } + processBtn.setEnabled(false); } private void createDiscardBtn() { @@ -349,13 +387,15 @@ public class UploadLayout extends VerticalLayout { artifactUploadState.getBaseSwModuleList().put(currentBaseSoftwareModuleKey, selectedSoftwareModule); } return out; - } catch (final FileNotFoundException e) { + } + catch (final FileNotFoundException e) { LOG.error("Upload failed {}", e); throw new ArtifactUploadFailedException(i18n.get("message.file.not.found")); } catch (final IOException e) { LOG.error("Upload failed {}", e); throw new ArtifactUploadFailedException(i18n.get("message.upload.failed")); } + } Boolean validate(final DragAndDropEvent event) { @@ -430,7 +470,7 @@ public class UploadLayout extends VerticalLayout { } void decreaseNumberOfFileUploadsExpected() { - numberOfFileUploadsExpected.decrementAndGet(); + artifactUploadState.getNumberOfFileUploadsExpected().decrementAndGet(); } List getDuplicateFileNamesList() { @@ -451,7 +491,7 @@ public class UploadLayout extends VerticalLayout { void displayDuplicateValidationMessage() { // check if streaming of all dropped files are completed - if (numberOfFilesActuallyUpload.intValue() == numberOfFileUploadsExpected.intValue()) { + if (artifactUploadState.getNumberOfFilesActuallyUpload().intValue() == artifactUploadState.getNumberOfFileUploadsExpected().intValue()) { displayCompositeMessage(); } } @@ -466,7 +506,6 @@ public class UploadLayout extends VerticalLayout { } else if (duplicateFileNamesList.size() > 1) { message.append(i18n.get("message.no.duplicateFiles")); } - duplicateFileNamesList.clear(); } return message.toString(); } @@ -476,7 +515,7 @@ public class UploadLayout extends VerticalLayout { } void increaseNumberOfFileUploadsExpected() { - numberOfFileUploadsExpected.incrementAndGet(); + artifactUploadState.getNumberOfFileUploadsExpected().incrementAndGet(); } void updateFileSize(final String name, final long size) { @@ -495,17 +534,19 @@ public class UploadLayout extends VerticalLayout { } void increaseNumberOfFilesActuallyUpload() { - numberOfFilesActuallyUpload.incrementAndGet(); + artifactUploadState.getNumberOfFilesActuallyUpload().incrementAndGet(); } /** * Enable process button once upload is completed. */ boolean enableProcessBtn() { - if (numberOfFilesActuallyUpload.intValue() >= numberOfFileUploadsExpected.intValue()) { + if (artifactUploadState.getNumberOfFilesActuallyUpload().intValue() >= artifactUploadState + .getNumberOfFileUploadsExpected().intValue() + && artifactUploadState.getNumberOfFilesActuallyUpload().get() != 0) { processBtn.setEnabled(true); - numberOfFileUploadsExpected.set(0); - numberOfFilesActuallyUpload.set(0); + artifactUploadState.getNumberOfFilesActuallyUpload().set(0); + artifactUploadState.getNumberOfFileUploadsExpected().set(0); return true; } return false; @@ -546,8 +587,8 @@ public class UploadLayout extends VerticalLayout { processBtn.setCaption(SPUILabelDefinitions.PROCESS); /* disable when there is no files to upload. */ processBtn.setEnabled(false); - numberOfFileUploadsExpected.set(0); - numberOfFilesActuallyUpload.set(0); + artifactUploadState.getNumberOfFilesActuallyUpload().set(0); + artifactUploadState.getNumberOfFileUploadsExpected().set(0); duplicateFileNamesList.clear(); } @@ -623,33 +664,70 @@ public class UploadLayout extends VerticalLayout { return dropAreaLayout; } - @EventBusListenerMethod(scope = EventScope.SESSION) - void onEvent(final UploadArtifactUIEvent event) { - if (event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE) { - ui.access(() -> updateActionCount()); - } else if (event == UploadArtifactUIEvent.MINIMIZED_STATUS_POPUP) { - ui.access(() -> showUploadStatusButton()); - } else if (event == UploadArtifactUIEvent.MAXIMIZED_STATUS_POPUP) { - ui.access(() -> maximizeStatusPopup()); - } else if (event == UploadArtifactUIEvent.UPLOAD_FINISHED) { - ui.access(() -> setUploadStatusButtonIconToFinished()); - } else if (event == UploadArtifactUIEvent.UPLOAD_STARTED) { - ui.access(() -> setUploadStatusButtonIconToInProgress()); - }else if (event == UploadArtifactUIEvent.UPLOAD_STREAMINING_FINISHED) { - //TODO re-check - updateActionCount(); - enableProcessBtn(); - } + private void onUploadStreamingSuccess(UploadStatusEvent event) { + increaseNumberOfFilesActuallyUpload(); + updateActionCount(); + enableProcessBtn(); + if (isUploadComplete()) { + uploadInfoWindow.uploadSessionFinished(); + setUploadStatusButtonIconToFinished(); + } + // display the duplicate message after streaming all files + displayDuplicateValidationMessage(); + duplicateFileNamesList.clear(); } - @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); + private void onUploadStreamingFailure(UploadStatusEvent event) { + onUploadFailure(event); + updateActionCount(); + enableProcessBtn(); + // check if we are finished + if (isUploadComplete()) { + uploadInfoWindow.uploadSessionFinished(); + setUploadStatusButtonIconToFinished(); + } + displayDuplicateValidationMessage(); + } + + private void onUploadSuccess(UploadStatusEvent event) { + updateFileSize(event.getUploadStatus().getFileName(), event.getUploadStatus().getContentLength()); + // recorded that we now one more uploaded + increaseNumberOfFilesActuallyUpload(); + } + + private void onUploadCompletion() { + // check if we are finished + if (isUploadComplete()) { + uploadInfoWindow.uploadSessionFinished(); + setUploadStatusButtonIconToFinished(); + } + updateActionCount(); + enableProcessBtn(); + duplicateFileNamesList.clear(); + } + + private boolean isUploadComplete() { + int uploadedCount = artifactUploadState.getNumberOfFilesActuallyUpload().intValue(); + int expectedUploadsCount = artifactUploadState.getNumberOfFileUploadsExpected().intValue(); + return uploadedCount == expectedUploadsCount; + } + + private void onUploadFailure(final UploadStatusEvent event) { + decreaseNumberOfFileUploadsExpected(); + /** + * If upload interrupted because of duplicate file,do not remove the + * file already in upload list + **/ + if (getDuplicateFileNamesList().isEmpty() + || !getDuplicateFileNamesList().contains(event.getUploadStatus().getFileName())) { + final SoftwareModule sw = getSoftwareModuleSelected(); + getFileSelected().remove( + new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); + //failed reason to be updated only if there is error other than duplicate file error + uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() + .getFailureReason()); + } } /** @@ -738,4 +816,5 @@ public class UploadLayout extends VerticalLayout { uploadStatusButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); uploadStatusButton.setIcon(null); } + } 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 4693ab3dc..2efd929d3 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 @@ -11,7 +11,12 @@ package org.eclipse.hawkbit.ui.artifacts.upload; import java.util.List; import java.util.stream.Collectors; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + 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.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -19,6 +24,8 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; import com.vaadin.data.Container.Indexed; import com.vaadin.data.Item; @@ -69,9 +76,9 @@ public class UploadStatusInfoWindow extends Window { private static final long serialVersionUID = 1L; - private final Grid grid; + private Grid grid; - private final IndexedContainer uploads; + private IndexedContainer uploads; private volatile boolean errorOccured = false; @@ -84,12 +91,15 @@ public class UploadStatusInfoWindow extends Window { private Button closeButton; private Button resizeButton; + + private UI ui; + /** * Default Constructor. */ - UploadStatusInfoWindow() { - super(); + @PostConstruct + void init() { setPopupProperties(); createStatusPopupHeaderComponents(); @@ -106,8 +116,45 @@ public class UploadStatusInfoWindow extends Window { mainLayout.addComponents(getCaptionLayout(), grid); mainLayout.setExpandRatio(grid, 1.0F); setContent(mainLayout); + eventBus.subscribe(this); + ui = UI.getCurrent(); + } + + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvent(final UploadStatusEvent event) { + if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_IN_PROGRESS) { + UI.getCurrent().access( + () -> updateProgress(event.getUploadStatus().getFileName(), event.getUploadStatus().getBytesRead(), + event.getUploadStatus().getContentLength())); + } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STARTED) { + UI.getCurrent().access(() -> onStartOfUpload(event)); + } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FAILED) { + ui.access(() -> uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() + .getFailureReason())); + } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_SUCCESSFUL) { + UI.getCurrent().access(() -> uploadSucceeded(event.getUploadStatus().getFileName())); + } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FINISHED) { + ui.access(() -> uploadSucceeded(event.getUploadStatus().getFileName())); + } + } + + private void onStartOfUpload(UploadStatusEvent event) { + uploadSessionStarted(); + uploadStarted(event.getUploadStatus().getFileName()); + } + + + @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); + } + private void restoreState() { Indexed container = grid.getContainerDataSource(); if (container.getItemIds().isEmpty()) { @@ -119,8 +166,10 @@ public class UploadStatusInfoWindow extends Window { item.getItemProperty(PROGRESS).setValue(statusObject.getProgress()); item.getItemProperty(FILE_NAME).setValue(statusObject.getFilename()); } - artifactUploadState.setUploadCompleted(true); - minimizeButton.setEnabled(false); + // artifactUploadState.setUploadCompleted(true); + if (artifactUploadState.isUploadCompleted()) { + minimizeButton.setEnabled(false); + } } } @@ -130,6 +179,7 @@ public class UploadStatusInfoWindow extends Window { setResizable(false); setDraggable(true); setClosable(false); + setModal(true); } private void setGridColumnProperties() { @@ -192,6 +242,8 @@ public class UploadStatusInfoWindow extends Window { private static class StatusRenderer extends HtmlRenderer { + private static final long serialVersionUID = -5365795450234970943L; + @Override public JsonValue encode(final String value) { String result ; @@ -216,18 +268,17 @@ public class UploadStatusInfoWindow extends Window { void uploadSessionFinished() { if (!errorOccured) { close(); - eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_FINISHED); - artifactUploadState.setUploadCompleted(true); - minimizeButton.setEnabled(false); } - + artifactUploadState.setUploadCompleted(true); + minimizeButton.setEnabled(false); } void uploadSessionStarted() { - close(); - openWindow(); + if (!artifactUploadState.isStatusPopupMinimized()) { + close(); + openWindow(); + } minimizeButton.setEnabled(true); - eventBus.publish(this, UploadArtifactUIEvent.UPLOAD_STARTED); artifactUploadState.setUploadCompleted(false); } @@ -287,22 +338,22 @@ public class UploadStatusInfoWindow extends Window { } void uploadFailed(final String filename, final String errorReason) { + if (!errorOccured) { + errorOccured = true; + } + String status = "Failed"; final Item item = uploads.getItem(filename); if (item != null) { - if (!errorOccured) { - errorOccured = true; - } item.getItemProperty(REASON).setValue(errorReason); - String status = "Failed"; item.getItemProperty(STATUS).setValue(status); - List uploadStatusObjectList = (List) artifactUploadState - .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) - .collect(Collectors.toList()); - if (!uploadStatusObjectList.isEmpty()) { - UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); - uploadStatusObject.setStatus(status); - uploadStatusObject.setReason(errorReason); - } + } + List uploadStatusObjectList = (List) artifactUploadState + .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) + .collect(Collectors.toList()); + if (!uploadStatusObjectList.isEmpty()) { + UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); + uploadStatusObject.setStatus(status); + uploadStatusObject.setReason(errorReason); } } @@ -370,4 +421,5 @@ public class UploadStatusInfoWindow extends Window { closeBtn.addClickListener(event -> clearWindow()); return closeBtn; } + } From cb81c78b690d32caf11962f5de1b00cc7b87211b Mon Sep 17 00:00:00 2001 From: Asharani Date: Mon, 16 May 2016 14:56:23 +0530 Subject: [PATCH 05/16] Artifact upload : on discard action interupt the ongoing upload Signed-off-by: Asharani --- .../event/UploadArtifactUIEvent.java | 3 +- .../artifacts/state/ArtifactUploadState.java | 6 + .../upload/UploadConfirmationwindow.java | 6 +- .../ui/artifacts/upload/UploadHandler.java | 43 +++++- .../ui/artifacts/upload/UploadLayout.java | 138 +++++++++++++----- .../artifacts/upload/UploadResultWindow.java | 9 ++ .../upload/UploadStatusInfoWindow.java | 11 +- .../themes/hawkbit/customstyles/others.scss | 11 +- 8 files changed, 171 insertions(+), 56 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java index 8bd33f483..1f5971f4b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java @@ -15,6 +15,5 @@ package org.eclipse.hawkbit.ui.artifacts.event; * */ public enum UploadArtifactUIEvent { - - SHOW_DROP_HINTS, HIDE_DROP_HINTS, SOFTWARE_DRAG_START, SOFTWARE_TYPE_DRAG_START, UPDATE_UPLOAD_COUNT, ENABLE_PROCESS_BUTTON, HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DISCARD_DELETE_SOFTWARE, DISCARD_ALL_DELETE_SOFTWARE, DELETED_ALL_SOFWARE, DISABLE_PROCESS_BUTTON, DISCARD_DELETE_SOFTWARE_TYPE, DISCARD_ALL_DELETE_SOFTWARE_TYPE, DELETED_ALL_SOFWARE_TYPE,MINIMIZED_STATUS_POPUP,MAXIMIZED_STATUS_POPUP, UPLOAD_IN_PROGESS + SHOW_DROP_HINTS, HIDE_DROP_HINTS, SOFTWARE_DRAG_START, SOFTWARE_TYPE_DRAG_START, UPDATE_UPLOAD_COUNT, HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DISCARD_DELETE_SOFTWARE, DISCARD_ALL_DELETE_SOFTWARE, DELETED_ALL_SOFWARE, DISCARD_DELETE_SOFTWARE_TYPE, DISCARD_ALL_DELETE_SOFTWARE_TYPE, DELETED_ALL_SOFWARE_TYPE, MINIMIZED_STATUS_POPUP, MAXIMIZED_STATUS_POPUP, UPLOAD_IN_PROGESS, DISCARD_UPLOAD, ARTIFACT_RESULT_POPUP_CLOSED } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java index 9c0ade8d1..5399e59c8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java @@ -73,6 +73,12 @@ public class ArtifactUploadState implements ManagmentEntityState, Serializ private final AtomicInteger numberOfFilesActuallyUpload = new AtomicInteger(); + private final AtomicInteger numberOfFileUploadsFailed = new AtomicInteger(); + + public AtomicInteger getNumberOfFileUploadsFailed() { + return numberOfFileUploadsFailed; + } + public AtomicInteger getNumberOfFilesActuallyUpload() { return numberOfFilesActuallyUpload; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java index d7231cafe..83a5c6c95 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java @@ -544,7 +544,7 @@ public class UploadConfirmationwindow implements Button.ClickListener { if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_ARTIFACT_DETAILS_CLOSE)) { uploadConfrimationWindow.close(); } else if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_DISCARD_DETAILS_BUTTON)) { - uploadLayout.removeUploadedFileDetails(); + uploadLayout.clearUploadedFileDetails(); uploadConfrimationWindow.close(); } else if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_BUTTON)) { processArtifactUpload(); @@ -568,10 +568,10 @@ public class UploadConfirmationwindow implements Button.ClickListener { uploadDetailsTable.removeItem(((Button) event.getComponent()).getData()); uploadLayout.getFileSelected().remove(customFile); - uploadLayout.updateActionCount(); + uploadLayout.updateUploadCounts(); if (uploadDetailsTable.getItemIds().isEmpty()) { - uploadLayout.clearFileList(); uploadConfrimationWindow.close(); + uploadLayout.clearUploadedFileDetails(); } } 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 f9d207193..2c8220fdf 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 @@ -11,6 +11,8 @@ package org.eclipse.hawkbit.ui.artifacts.upload; import java.io.IOException; import java.io.OutputStream; +import javax.annotation.PreDestroy; + import org.eclipse.hawkbit.repository.exception.ArtifactUploadFailedException; import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; import org.eclipse.hawkbit.ui.artifacts.event.UploadFileStatus; @@ -21,8 +23,11 @@ import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vaadin.spring.events.EventBus; +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; @@ -83,6 +88,24 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene this.mimeType = mimeType; this.i18n = SpringContextHelper.getBean(I18N.class); this.eventBus = SpringContextHelper.getBean(EventBus.SessionEventBus.class); + eventBus.subscribe(this); + } + + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvent(final UploadArtifactUIEvent event) { + if (event == UploadArtifactUIEvent.DISCARD_UPLOAD) { + UI.getCurrent().access(() ->intreruptUploadOnDiscard()); + } + } + +// + @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); } /** @@ -93,6 +116,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public final OutputStream getOutputStream() { try { + streamingInterrupted = false; return view.saveUploadedFileDetails(fileName, fileSize, mimeType); } catch (final ArtifactUploadFailedException e) { LOG.error("Atifact upload failed {} ", e); @@ -110,18 +134,15 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene */ @Override public OutputStream receiveUpload(final String fileName, final String mimeType) { + uploadInterrupted = false; this.fileName = fileName; this.mimeType = mimeType; // reset has directory flag before upload view.setHasDirectory(false); try { - if (view.checkIfSoftwareModuleIsSelected()) { - if (view.checkForDuplicate(fileName)) { - view.showDuplicateMessage(); - } else { - view.increaseNumberOfFileUploadsExpected(); - return view.saveUploadedFileDetails(fileName, 0, mimeType); - } + if (view.checkIfSoftwareModuleIsSelected() && !view.checkForDuplicate(fileName)) { + view.increaseNumberOfFileUploadsExpected(); + return view.saveUploadedFileDetails(fileName, 0, mimeType); } } catch (final ArtifactUploadFailedException e) { LOG.error("Atifact upload failed {} ", e); @@ -350,5 +371,13 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene } return true; } + + protected void intreruptUploadOnDiscard(){ + if(upload!=null && upload.isUploading()){ + upload.interruptUpload(); + uploadInterrupted = true; + } + streamingInterrupted = 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 58661773d..baed534aa 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 @@ -118,6 +118,8 @@ public class UploadLayout extends VerticalLayout { private Button uploadStatusButton; + private Boolean changesDiscarded = Boolean.FALSE; + /** * Initialize the upload layout. */ @@ -129,7 +131,6 @@ public class UploadLayout extends VerticalLayout { eventBus.subscribe(this); ui = UI.getCurrent(); } - @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final UploadArtifactUIEvent event) { @@ -139,14 +140,17 @@ public class UploadLayout extends VerticalLayout { ui.access(() -> showUploadStatusButton()); } else if (event == UploadArtifactUIEvent.MAXIMIZED_STATUS_POPUP) { ui.access(() -> maximizeStatusPopup()); - } + } + else if(event == UploadArtifactUIEvent.ARTIFACT_RESULT_POPUP_CLOSED){ + ui.access(() -> closeUploadStatusPopup()); + } } + @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final UploadStatusEvent event) { if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STARTED) { - ui.access(() -> setUploadStatusButtonIconToInProgress()); - } - else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_FAILED) { + ui.access(() -> onStartOfUpload()); + } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_FAILED) { ui.access(() -> onUploadFailure(event)); } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_FINISHED) { ui.access(() -> onUploadCompletion()); @@ -155,7 +159,7 @@ public class UploadLayout extends VerticalLayout { } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FAILED) { ui.access(() -> onUploadStreamingFailure(event)); } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FINISHED) { - ui.access(() -> onUploadStreamingSuccess(event)); + ui.access(() -> onUploadStreamingSuccess()); } } @@ -211,6 +215,7 @@ public class UploadLayout extends VerticalLayout { private void restoreState() { updateActionCount(); + if (!artifactUploadState.getFileSelected().isEmpty() && artifactUploadState.isUploadCompleted()) { processBtn.setEnabled(true); } @@ -237,6 +242,7 @@ public class UploadLayout extends VerticalLayout { @Override public void drop(final DragAndDropEvent event) { + changesDiscarded = Boolean.FALSE; if (validate(event)) { final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); // reset the flag @@ -342,15 +348,6 @@ public class UploadLayout extends VerticalLayout { return isDuplicate; } - @EventBusListenerMethod(scope = EventScope.SESSION) - void toggleProcessButton(final UploadArtifactUIEvent event) { - if (event == UploadArtifactUIEvent.ENABLE_PROCESS_BUTTON) { - processBtn.setEnabled(true); - } else if (event == UploadArtifactUIEvent.DISABLE_PROCESS_BUTTON) { - processBtn.setEnabled(false); - } - } - /** * Save uploaded file details. * @@ -387,15 +384,14 @@ public class UploadLayout extends VerticalLayout { artifactUploadState.getBaseSwModuleList().put(currentBaseSoftwareModuleKey, selectedSoftwareModule); } return out; - } - catch (final FileNotFoundException e) { + } catch (final FileNotFoundException e) { LOG.error("Upload failed {}", e); throw new ArtifactUploadFailedException(i18n.get("message.file.not.found")); } catch (final IOException e) { LOG.error("Upload failed {}", e); throw new ArtifactUploadFailedException(i18n.get("message.upload.failed")); } - + } Boolean validate(final DragAndDropEvent event) { @@ -491,8 +487,10 @@ public class UploadLayout extends VerticalLayout { void displayDuplicateValidationMessage() { // check if streaming of all dropped files are completed - if (artifactUploadState.getNumberOfFilesActuallyUpload().intValue() == artifactUploadState.getNumberOfFileUploadsExpected().intValue()) { + if (artifactUploadState.getNumberOfFilesActuallyUpload().intValue() == artifactUploadState + .getNumberOfFileUploadsExpected().intValue()) { displayCompositeMessage(); + duplicateFileNamesList.clear(); } } @@ -537,6 +535,10 @@ public class UploadLayout extends VerticalLayout { artifactUploadState.getNumberOfFilesActuallyUpload().incrementAndGet(); } + void increaseNumberOfFileUploadsFailed() { + artifactUploadState.getNumberOfFileUploadsFailed().incrementAndGet(); + } + /** * Enable process button once upload is completed. */ @@ -561,15 +563,22 @@ public class UploadLayout extends VerticalLayout { if (artifactUploadState.getFileSelected().isEmpty()) { uiNotification.displayValidationError(i18n.get("message.error.noFileSelected")); } else { - removeUploadedFileDetails(); + clearUploadedFileDetails(); } } } - protected void removeUploadedFileDetails() { + protected void clearUploadedFileDetails() { + eventBus.publish(this, UploadArtifactUIEvent.DISCARD_UPLOAD); + changesDiscarded = Boolean.TRUE; clearFileList(); + closeUploadStatusPopup(); + } + + private void closeUploadStatusPopup() { uploadInfoWindow.clearWindow(); hideUploadStatusButton(); + artifactUploadState.setStatusPopupMinimized(false); } /** @@ -589,6 +598,7 @@ public class UploadLayout extends VerticalLayout { processBtn.setEnabled(false); artifactUploadState.getNumberOfFilesActuallyUpload().set(0); artifactUploadState.getNumberOfFileUploadsExpected().set(0); + artifactUploadState.getNumberOfFileUploadsFailed().set(0); duplicateFileNamesList.clear(); } @@ -664,10 +674,17 @@ public class UploadLayout extends VerticalLayout { return dropAreaLayout; } + private void onStartOfUpload() { + changesDiscarded = Boolean.FALSE; + setUploadStatusButtonIconToInProgress(); + if (artifactUploadState.isStatusPopupMinimized()) { + updateStatusButtonCount(); + } + } - private void onUploadStreamingSuccess(UploadStatusEvent event) { + private void onUploadStreamingSuccess() { increaseNumberOfFilesActuallyUpload(); - updateActionCount(); + updateUploadCounts(); enableProcessBtn(); if (isUploadComplete()) { uploadInfoWindow.uploadSessionFinished(); @@ -675,19 +692,35 @@ public class UploadLayout extends VerticalLayout { } // display the duplicate message after streaming all files displayDuplicateValidationMessage(); - duplicateFileNamesList.clear(); } private void onUploadStreamingFailure(UploadStatusEvent event) { - onUploadFailure(event); - updateActionCount(); - enableProcessBtn(); - // check if we are finished - if (isUploadComplete()) { - uploadInfoWindow.uploadSessionFinished(); - setUploadStatusButtonIconToFinished(); + if (!changesDiscarded) { + /** + * If upload interrupted because of duplicate file,do not remove the + * file already in upload list + **/ + if (getDuplicateFileNamesList().isEmpty() + || !getDuplicateFileNamesList().contains(event.getUploadStatus().getFileName())) { + final SoftwareModule sw = getSoftwareModuleSelected(); + getFileSelected().remove( + new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); + // failed reason to be updated only if there is error other than + // duplicate file error + uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() + .getFailureReason()); + increaseNumberOfFileUploadsFailed(); + } + decreaseNumberOfFileUploadsExpected(); + updateUploadCounts(); + enableProcessBtn(); + // check if we are finished + if (isUploadComplete()) { + uploadInfoWindow.uploadSessionFinished(); + setUploadStatusButtonIconToFinished(); + } + displayDuplicateValidationMessage(); } - displayDuplicateValidationMessage(); } private void onUploadSuccess(UploadStatusEvent event) { @@ -701,12 +734,14 @@ public class UploadLayout extends VerticalLayout { if (isUploadComplete()) { uploadInfoWindow.uploadSessionFinished(); setUploadStatusButtonIconToFinished(); + displayDuplicateValidationMessage(); } - updateActionCount(); + updateUploadCounts(); enableProcessBtn(); duplicateFileNamesList.clear(); } + private boolean isUploadComplete() { int uploadedCount = artifactUploadState.getNumberOfFilesActuallyUpload().intValue(); int expectedUploadsCount = artifactUploadState.getNumberOfFileUploadsExpected().intValue(); @@ -714,19 +749,22 @@ public class UploadLayout extends VerticalLayout { } private void onUploadFailure(final UploadStatusEvent event) { - decreaseNumberOfFileUploadsExpected(); /** * If upload interrupted because of duplicate file,do not remove the * file already in upload list **/ - if (getDuplicateFileNamesList().isEmpty() - || !getDuplicateFileNamesList().contains(event.getUploadStatus().getFileName())) { + if ((getDuplicateFileNamesList().isEmpty() || !getDuplicateFileNamesList().contains( + event.getUploadStatus().getFileName())) + && !changesDiscarded) { final SoftwareModule sw = getSoftwareModuleSelected(); getFileSelected().remove( new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); - //failed reason to be updated only if there is error other than duplicate file error + // failed reason to be updated only if there is error other than + // duplicate file error uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() .getFailureReason()); + increaseNumberOfFileUploadsFailed(); + decreaseNumberOfFileUploadsExpected(); } } @@ -777,6 +815,24 @@ public class UploadLayout extends VerticalLayout { uploadStatusButton.setVisible(false); } + void updateStatusButtonCount() { + int uploadsPending = artifactUploadState.getNumberOfFileUploadsExpected().get() + - artifactUploadState.getNumberOfFilesActuallyUpload().get(); + int uploadsFailed = artifactUploadState.getNumberOfFileUploadsFailed().get(); + StringBuilder builder = new StringBuilder(""); + if (uploadsFailed != 0) { + if (uploadsPending != 0) { + builder.append("
" + uploadsFailed + "
"); + } else { + builder.append("
" + uploadsFailed + "
"); + } + } + if (uploadsPending != 0) { + builder.append("
" + uploadsPending + "
"); + } + uploadStatusButton.setCaption(builder.toString()); + } + private void onClickOfUploadStatusButton() { artifactUploadState.setStatusPopupMinimized(false); eventBus.publish(this, UploadArtifactUIEvent.MAXIMIZED_STATUS_POPUP); @@ -787,6 +843,7 @@ public class UploadLayout extends VerticalLayout { return; } uploadStatusButton.setVisible(true); + updateStatusButtonCount(); } protected void hideUploadStatusButton() { @@ -816,5 +873,10 @@ public class UploadLayout extends VerticalLayout { uploadStatusButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); uploadStatusButton.setIcon(null); } - + + + protected void updateUploadCounts() { + updateActionCount(); + updateStatusButtonCount(); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadResultWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadResultWindow.java index c5319a221..94029b090 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadResultWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadResultWindow.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.ui.artifacts.upload; import java.util.ArrayList; import java.util.List; +import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleTiny; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; @@ -19,6 +20,8 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.eclipse.hawkbit.ui.utils.SpringContextHelper; +import org.vaadin.spring.events.EventBus; import com.vaadin.data.Item; import com.vaadin.data.util.IndexedContainer; @@ -63,6 +66,9 @@ public class UploadResultWindow implements Button.ClickListener { private static final String UPLOAD_RESULT = "uploadResult"; private static final String REASON = "reason"; + + private transient EventBus.SessionEventBus eventBus; + /** * Initialize upload status popup. @@ -75,6 +81,7 @@ public class UploadResultWindow implements Button.ClickListener { public UploadResultWindow(final List uploadResultList, final I18N i18n) { this.uploadResultList = uploadResultList; this.i18n = i18n; + eventBus = SpringContextHelper.getBean( EventBus.SessionEventBus.class); createComponents(); createLayout(); } @@ -183,6 +190,8 @@ public class UploadResultWindow implements Button.ClickListener { if (event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_ARTIFACT_RESULT_CLOSE) || event.getComponent().getId().equals(SPUIComponetIdProvider.UPLOAD_ARTIFACT_RESULT_POPUP_CLOSE)) { uploadResultsWindow.close(); + //close upload status popup if open + eventBus.publish(this, UploadArtifactUIEvent.ARTIFACT_RESULT_POPUP_CLOSED); } } 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 2efd929d3..177ecd8a3 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 @@ -166,7 +166,6 @@ public class UploadStatusInfoWindow extends Window { item.getItemProperty(PROGRESS).setValue(statusObject.getProgress()); item.getItemProperty(FILE_NAME).setValue(statusObject.getFilename()); } - // artifactUploadState.setUploadCompleted(true); if (artifactUploadState.isUploadCompleted()) { minimizeButton.setEnabled(false); } @@ -294,7 +293,9 @@ public class UploadStatusInfoWindow extends Window { void uploadStarted(final String filename) { final Item item = uploads.addItem(filename); - item.getItemProperty(FILE_NAME).setValue(filename); + if (item != null) { + item.getItemProperty(FILE_NAME).setValue(filename); + } grid.scrollToEnd(); UploadStatusObject uploadStatus = new UploadStatusObject(filename); uploadStatus.setStatus("Active"); @@ -302,11 +303,11 @@ public class UploadStatusInfoWindow extends Window { } void updateProgress(final String filename, final long readBytes, final long contentLength) { - final Item item = uploads.getItem(filename); + final Item item = uploads.getItem(filename); if (item != null) { double progress = (double) readBytes / (double) contentLength; item.getItemProperty(PROGRESS).setValue(progress); - List uploadStatusObjectList = (List) artifactUploadState + List uploadStatusObjectList = (List) artifactUploadState .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) .collect(Collectors.toList()); if (!uploadStatusObjectList.isEmpty()) { @@ -363,6 +364,7 @@ public class UploadStatusInfoWindow extends Window { setWindowMode(WindowMode.NORMAL); this.close(); artifactUploadState.getUploadedFileStatusList().clear(); + artifactUploadState.getNumberOfFileUploadsFailed().set(0); } private void setPopupSizeInMinMode() { @@ -421,5 +423,4 @@ public class UploadStatusInfoWindow extends Window { closeBtn.addClickListener(event -> clearWindow()); return closeBtn; } - } diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/others.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/others.scss index 879fb8dd6..f6f4c2434 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/others.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/others.scss @@ -10,7 +10,7 @@ @mixin others { //Style to display the pending action count - .unread { + .unread, .error-count { @include valo-badge-style; position: absolute; pointer-events: none; @@ -21,6 +21,15 @@ border-radius: $v-border-radius; color: $widget-bg; } + + .error-count { + top: round($v-unit-size / -5); + right: round($v-unit-size / 1.9); + } + + .error-count-color{ + @include valo-gradient($color: $red-color); + } //Deployment view - Style of count message .v-caption-count-msg-box { From eadff47f24a8fc360b055032edee26d4d1b3b6e6 Mon Sep 17 00:00:00 2001 From: Asharani Date: Mon, 16 May 2016 16:26:24 +0530 Subject: [PATCH 06/16] Artifact upload : on discard action interupt the ongoing upload - reverted the changes Signed-off-by: Asharani --- .../event/UploadArtifactUIEvent.java | 2 +- .../ui/artifacts/upload/UploadHandler.java | 26 ------------------- .../ui/artifacts/upload/UploadLayout.java | 13 ++-------- 3 files changed, 3 insertions(+), 38 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java index 1f5971f4b..e1fe4e07f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java @@ -15,5 +15,5 @@ package org.eclipse.hawkbit.ui.artifacts.event; * */ public enum UploadArtifactUIEvent { - SHOW_DROP_HINTS, HIDE_DROP_HINTS, SOFTWARE_DRAG_START, SOFTWARE_TYPE_DRAG_START, UPDATE_UPLOAD_COUNT, HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DISCARD_DELETE_SOFTWARE, DISCARD_ALL_DELETE_SOFTWARE, DELETED_ALL_SOFWARE, DISCARD_DELETE_SOFTWARE_TYPE, DISCARD_ALL_DELETE_SOFTWARE_TYPE, DELETED_ALL_SOFWARE_TYPE, MINIMIZED_STATUS_POPUP, MAXIMIZED_STATUS_POPUP, UPLOAD_IN_PROGESS, DISCARD_UPLOAD, ARTIFACT_RESULT_POPUP_CLOSED + SHOW_DROP_HINTS, HIDE_DROP_HINTS, SOFTWARE_DRAG_START, SOFTWARE_TYPE_DRAG_START, UPDATE_UPLOAD_COUNT, HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DISCARD_DELETE_SOFTWARE, DISCARD_ALL_DELETE_SOFTWARE, DELETED_ALL_SOFWARE, DISCARD_DELETE_SOFTWARE_TYPE, DISCARD_ALL_DELETE_SOFTWARE_TYPE, DELETED_ALL_SOFWARE_TYPE, MINIMIZED_STATUS_POPUP, MAXIMIZED_STATUS_POPUP, UPLOAD_IN_PROGESS, ARTIFACT_RESULT_POPUP_CLOSED } 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 2c8220fdf..5c0373acf 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 @@ -88,24 +88,6 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene this.mimeType = mimeType; this.i18n = SpringContextHelper.getBean(I18N.class); this.eventBus = SpringContextHelper.getBean(EventBus.SessionEventBus.class); - eventBus.subscribe(this); - } - - @EventBusListenerMethod(scope = EventScope.SESSION) - void onEvent(final UploadArtifactUIEvent event) { - if (event == UploadArtifactUIEvent.DISCARD_UPLOAD) { - UI.getCurrent().access(() ->intreruptUploadOnDiscard()); - } - } - -// - @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); } /** @@ -372,12 +354,4 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene return true; } - protected void intreruptUploadOnDiscard(){ - if(upload!=null && upload.isUploading()){ - upload.interruptUpload(); - uploadInterrupted = true; - } - streamingInterrupted = 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 baed534aa..a9f36e8b8 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 @@ -118,7 +118,6 @@ public class UploadLayout extends VerticalLayout { private Button uploadStatusButton; - private Boolean changesDiscarded = Boolean.FALSE; /** * Initialize the upload layout. @@ -242,7 +241,6 @@ public class UploadLayout extends VerticalLayout { @Override public void drop(final DragAndDropEvent event) { - changesDiscarded = Boolean.FALSE; if (validate(event)) { final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); // reset the flag @@ -569,8 +567,6 @@ public class UploadLayout extends VerticalLayout { } protected void clearUploadedFileDetails() { - eventBus.publish(this, UploadArtifactUIEvent.DISCARD_UPLOAD); - changesDiscarded = Boolean.TRUE; clearFileList(); closeUploadStatusPopup(); } @@ -669,13 +665,11 @@ public class UploadLayout extends VerticalLayout { /** * @return */ - VerticalLayout getDropAreaLayout() { return dropAreaLayout; } private void onStartOfUpload() { - changesDiscarded = Boolean.FALSE; setUploadStatusButtonIconToInProgress(); if (artifactUploadState.isStatusPopupMinimized()) { updateStatusButtonCount(); @@ -695,7 +689,6 @@ public class UploadLayout extends VerticalLayout { } private void onUploadStreamingFailure(UploadStatusEvent event) { - if (!changesDiscarded) { /** * If upload interrupted because of duplicate file,do not remove the * file already in upload list @@ -720,7 +713,6 @@ public class UploadLayout extends VerticalLayout { setUploadStatusButtonIconToFinished(); } displayDuplicateValidationMessage(); - } } private void onUploadSuccess(UploadStatusEvent event) { @@ -753,9 +745,8 @@ public class UploadLayout extends VerticalLayout { * If upload interrupted because of duplicate file,do not remove the * file already in upload list **/ - if ((getDuplicateFileNamesList().isEmpty() || !getDuplicateFileNamesList().contains( - event.getUploadStatus().getFileName())) - && !changesDiscarded) { + if (getDuplicateFileNamesList().isEmpty() || !getDuplicateFileNamesList().contains( + event.getUploadStatus().getFileName())) { final SoftwareModule sw = getSoftwareModuleSelected(); getFileSelected().remove( new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); From 0073fdeb403bddd81bcf8c5d688d3657d4e43564 Mon Sep 17 00:00:00 2001 From: Asharani Date: Tue, 17 May 2016 12:48:47 +0530 Subject: [PATCH 07/16] Added comments .Removed changes not required. Signed-off-by: Asharani --- hawkbit-ui/pom.xml | 5 ----- .../hawkbit/ui/artifacts/event/UploadFileStatus.java | 6 +++--- .../hawkbit/ui/artifacts/upload/UploadStatusObject.java | 6 ++++++ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/hawkbit-ui/pom.xml b/hawkbit-ui/pom.xml index 38b455367..e0bde576a 100644 --- a/hawkbit-ui/pom.xml +++ b/hawkbit-ui/pom.xml @@ -254,10 +254,5 @@ allure-junit-adaptor test - - org.scala-lang - scala-library - 2.10.4 - \ No newline at end of file diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java index 776556464..cdfeea653 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java @@ -12,7 +12,7 @@ import java.io.Serializable; /** * - * Holds file and upload status details. + * Holds file and upload status details.Meta data sent with upload events. * */ public class UploadFileStatus implements Serializable { @@ -27,10 +27,10 @@ public class UploadFileStatus implements Serializable { private String failureReason; - public UploadFileStatus(String fileName){ + public UploadFileStatus(String fileName) { this.fileName = fileName; } - + public UploadFileStatus(String fileName, long bytesRead, long contentLength) { this.fileName = fileName; this.contentLength = contentLength; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java index 80c71fe7b..13167b55a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java @@ -8,6 +8,12 @@ */ package org.eclipse.hawkbit.ui.artifacts.upload; +/** + * + * Holds uploaded file status.Used to display the details in upload status + * popup. + * + */ public class UploadStatusObject { private String status; private Double progress; From 652f480667244dca648a3322fd9d8ff5d7fa65e1 Mon Sep 17 00:00:00 2001 From: Asharani Date: Tue, 17 May 2016 15:01:12 +0530 Subject: [PATCH 08/16] Added liscense header Signed-off-by: Asharani --- .../hawkbit/ui/artifacts/event/UploadStatusEvent.java | 8 ++++++++ 1 file changed, 8 insertions(+) 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 ab10c2e10..96513a52a 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 @@ -1,3 +1,11 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ package org.eclipse.hawkbit.ui.artifacts.event; /** * From 51db4204d2ad8c12fa3c4ef02d7727d36554d58f Mon Sep 17 00:00:00 2001 From: Asharani Date: Tue, 17 May 2016 17:50:40 +0530 Subject: [PATCH 09/16] Bug fix :- During upload the files when changing the selection of the software module the upload also changes to the new selected software module Signed-off-by: Asharani --- .../ui/artifacts/event/UploadFileStatus.java | 11 ++- .../ui/artifacts/upload/UploadHandler.java | 30 ++++--- .../ui/artifacts/upload/UploadLayout.java | 84 ++++++++++--------- .../upload/UploadStatusInfoWindow.java | 1 + .../ui/utils/SPUIComponetIdProvider.java | 5 ++ 5 files changed, 79 insertions(+), 52 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java index cdfeea653..f594fad8b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java @@ -10,6 +10,8 @@ package org.eclipse.hawkbit.ui.artifacts.event; import java.io.Serializable; +import org.eclipse.hawkbit.repository.model.SoftwareModule; + /** * * Holds file and upload status details.Meta data sent with upload events. @@ -27,6 +29,8 @@ public class UploadFileStatus implements Serializable { private String failureReason; + private SoftwareModule softwareModule; + public UploadFileStatus(String fileName) { this.fileName = fileName; } @@ -37,9 +41,10 @@ public class UploadFileStatus implements Serializable { this.bytesRead = bytesRead; } - public UploadFileStatus(String fileName, String failureReason) { + public UploadFileStatus(String fileName, String failureReason,SoftwareModule selectedSw) { this.failureReason = failureReason; this.fileName = fileName; + this.softwareModule = selectedSw; } public String getFileName() { @@ -57,4 +62,8 @@ public class UploadFileStatus implements Serializable { public String getFailureReason() { return failureReason; } + + public SoftwareModule getSoftwareModule() { + return softwareModule; + } } 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 f51e171ba..277e56967 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 @@ -14,10 +14,12 @@ import java.io.OutputStream; 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; +import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.slf4j.Logger; @@ -68,9 +70,12 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene private String failureReason; private final I18N i18n; private transient EventBus.SessionEventBus eventBus; + private final SoftwareModule selectedSw; + private SoftwareModule selectedSwForUpload; + private ArtifactUploadState artifactUploadState; - UploadHandler(final String fileName, final long fileSize, final UploadLayout view, - final long maxSize, final Upload upload, final String mimeType) { + UploadHandler(final String fileName, final long fileSize, final UploadLayout view, final long maxSize, + final Upload upload, final String mimeType, SoftwareModule selectedSw) { super(); this.fileName = fileName; this.fileSize = fileSize; @@ -78,8 +83,10 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene this.maxSize = maxSize; this.upload = upload; this.mimeType = mimeType; + this.selectedSw = selectedSw; this.i18n = SpringContextHelper.getBean(I18N.class); this.eventBus = SpringContextHelper.getBean(EventBus.SessionEventBus.class); + this.artifactUploadState = SpringContextHelper.getBean(ArtifactUploadState.class); } /** @@ -91,7 +98,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public final OutputStream getOutputStream() { try { streamingInterrupted = false; - return view.saveUploadedFileDetails(fileName, fileSize, mimeType); + return view.saveUploadedFileDetails(fileName, fileSize, mimeType, selectedSw); } catch (final ArtifactUploadFailedException e) { LOG.error("Atifact upload failed {} ", e); failureReason = e.getMessage(); @@ -116,7 +123,8 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene try { if (view.checkIfSoftwareModuleIsSelected() && !view.checkForDuplicate(fileName)) { view.increaseNumberOfFileUploadsExpected(); - return view.saveUploadedFileDetails(fileName, 0, mimeType); + selectedSwForUpload = artifactUploadState.getSelectedBaseSoftwareModule().get(); + return view.saveUploadedFileDetails(fileName, 0, mimeType, selectedSwForUpload); } } catch (final ArtifactUploadFailedException e) { LOG.error("Atifact upload failed {} ", e); @@ -217,13 +225,14 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene */ @Override public void updateProgress(final long readBytes, final long contentLength) { - //Update progress is called event after upload interrupted in uploadStarted method + // Update progress is called event after upload interrupted in + // uploadStarted method if (!uploadInterrupted) { 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))); + fileName, failureReason, selectedSwForUpload))); upload.interruptUpload(); uploadInterrupted = true; return; @@ -245,7 +254,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene 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))); + fileName, failureReason, selectedSw))); streamingInterrupted = true; return; } @@ -268,7 +277,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene failureReason = event.getException().getMessage(); } eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STREAMING_FAILED, - new UploadFileStatus(fileName, failureReason))); + new UploadFileStatus(fileName, failureReason, selectedSw))); LOG.info("Streaming failed due to :{}", event.getException()); } @@ -284,9 +293,8 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene if (failureReason == null) { failureReason = event.getReason().getMessage(); } - System.out.println("failureReason:::"+failureReason); eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_FAILED, new UploadFileStatus( - fileName, failureReason))); + fileName, failureReason, selectedSwForUpload))); LOG.info("Upload failed for file :{}", event.getReason()); } @@ -335,5 +343,5 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene } return 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 a9f36e8b8..fedee30b9 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 @@ -181,7 +181,7 @@ public class UploadLayout extends VerticalLayout { final Upload upload = new Upload(); final UploadHandler uploadHandler = new UploadHandler(null, 0, this, spInfo.getMaxArtifactFileSize(), upload, - null); + null, null); upload.setButtonCaption(i18n.get("upload.file")); upload.setImmediate(true); upload.setReceiver(uploadHandler); @@ -243,15 +243,16 @@ public class UploadLayout extends VerticalLayout { public void drop(final DragAndDropEvent event) { if (validate(event)) { final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); + // selected software module at the time of file drop is + // considered for upload + SoftwareModule selectedSw = artifactUploadState.getSelectedBaseSoftwareModule().get(); // reset the flag hasDirectory = Boolean.FALSE; for (final Html5File file : files) { - processFile(file); + processFile(file, selectedSw); } if (artifactUploadState.getNumberOfFileUploadsExpected().get() > 0) { processBtn.setEnabled(false); - // reset before we start - // uploadInfoWindow.uploadSessionStarted(); } else { // If the upload is not started, it signifies all // dropped files as either duplicate or directory.So @@ -261,20 +262,20 @@ public class UploadLayout extends VerticalLayout { } } - private void processFile(final Html5File file) { + private void processFile(final Html5File file, SoftwareModule selectedSw) { if (!isDirectory(file)) { if (!checkForDuplicate(file.getFileName())) { artifactUploadState.getNumberOfFileUploadsExpected().incrementAndGet(); - file.setStreamVariable(createStreamVariable(file)); + file.setStreamVariable(createStreamVariable(file,selectedSw)); } } else { hasDirectory = Boolean.TRUE; } } - private StreamVariable createStreamVariable(final Html5File file) { + private StreamVariable createStreamVariable(final Html5File file, SoftwareModule selectedSw) { return new UploadHandler(file.getFileName(), file.getFileSize(), UploadLayout.this, - spInfo.getMaxArtifactFileSize(), null, file.getType()); + spInfo.getMaxArtifactFileSize(), null, file.getType(),selectedSw); } private boolean isDirectory(final Html5File file) { @@ -357,29 +358,28 @@ public class UploadLayout extends VerticalLayout { * file size * @param mimeType * the mimeType of the file + * @param selectedSw * @throws IOException * in case of upload errors */ - OutputStream saveUploadedFileDetails(final String name, final long size, final String mimeType) { + OutputStream saveUploadedFileDetails(final String name, final long size, final String mimeType, SoftwareModule selectedSw) { File tempFile = null; try { tempFile = File.createTempFile("spUiArtifactUpload", null); final OutputStream out = new FileOutputStream(tempFile); - final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( - selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + selectedSw.getName(), selectedSw.getVersion()); final CustomFile customFile = new CustomFile(name, size, tempFile.getAbsolutePath(), - selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion(), mimeType); + selectedSw.getName(), selectedSw.getVersion(), mimeType); artifactUploadState.getFileSelected().add(customFile); processBtn.setEnabled(false); if (!artifactUploadState.getBaseSwModuleList().keySet().contains(currentBaseSoftwareModuleKey)) { - artifactUploadState.getBaseSwModuleList().put(currentBaseSoftwareModuleKey, selectedSoftwareModule); + artifactUploadState.getBaseSwModuleList().put(currentBaseSoftwareModuleKey, selectedSw); } return out; } catch (final FileNotFoundException e) { @@ -689,30 +689,32 @@ public class UploadLayout extends VerticalLayout { } private void onUploadStreamingFailure(UploadStatusEvent event) { - /** - * If upload interrupted because of duplicate file,do not remove the - * file already in upload list - **/ - if (getDuplicateFileNamesList().isEmpty() - || !getDuplicateFileNamesList().contains(event.getUploadStatus().getFileName())) { - final SoftwareModule sw = getSoftwareModuleSelected(); + /** + * If upload interrupted because of duplicate file,do not remove the + * file already in upload list + **/ + if (getDuplicateFileNamesList().isEmpty() + || !getDuplicateFileNamesList().contains(event.getUploadStatus().getFileName())) { + final SoftwareModule sw = event.getUploadStatus().getSoftwareModule(); + if (sw != null) { getFileSelected().remove( new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); - // failed reason to be updated only if there is error other than - // duplicate file error - uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() - .getFailureReason()); - increaseNumberOfFileUploadsFailed(); } - decreaseNumberOfFileUploadsExpected(); - updateUploadCounts(); - enableProcessBtn(); - // check if we are finished - if (isUploadComplete()) { - uploadInfoWindow.uploadSessionFinished(); - setUploadStatusButtonIconToFinished(); - } - displayDuplicateValidationMessage(); + // failed reason to be updated only if there is error other than + // duplicate file error + uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() + .getFailureReason()); + increaseNumberOfFileUploadsFailed(); + } + decreaseNumberOfFileUploadsExpected(); + updateUploadCounts(); + enableProcessBtn(); + // check if we are finished + if (isUploadComplete()) { + uploadInfoWindow.uploadSessionFinished(); + setUploadStatusButtonIconToFinished(); + } + displayDuplicateValidationMessage(); } private void onUploadSuccess(UploadStatusEvent event) { @@ -745,11 +747,13 @@ public class UploadLayout extends VerticalLayout { * If upload interrupted because of duplicate file,do not remove the * file already in upload list **/ - if (getDuplicateFileNamesList().isEmpty() || !getDuplicateFileNamesList().contains( - event.getUploadStatus().getFileName())) { - final SoftwareModule sw = getSoftwareModuleSelected(); - getFileSelected().remove( - new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); + if (getDuplicateFileNamesList().isEmpty() + || !getDuplicateFileNamesList().contains(event.getUploadStatus().getFileName())) { + final SoftwareModule sw = event.getUploadStatus().getSoftwareModule(); + if (sw != null) { + getFileSelected().remove( + new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); + } // failed reason to be updated only if there is error other than // duplicate file error uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() 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 177ecd8a3..e2a486e6c 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 @@ -173,6 +173,7 @@ public class UploadStatusInfoWindow extends Window { } private void setPopupProperties() { + setId(SPUIComponetIdProvider.UPLOAD_STATUS_POPUP_ID); addStyleName(SPUIStyleDefinitions.UPLOAD_INFO); setImmediate(true); setResizable(false); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java index 7c25bf90a..2ada1b7bf 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java @@ -902,6 +902,11 @@ public final class SPUIComponetIdProvider { * Artifact upload view - upload status button id. */ public static final String UPLOAD_STATUS_BUTTON = "artficat.upload.status.button.id"; + + /** + * Artifact uplaod view - uplod status popup id. + */ + public static final String UPLOAD_STATUS_POPUP_ID = "artifact.upload.status.popup.id"; /** From a774412055645759be25942342402c61f3ceb076 Mon Sep 17 00:00:00 2001 From: Asharani Date: Wed, 18 May 2016 11:14:51 +0530 Subject: [PATCH 10/16] Bug fix : During upload the files when changing the selection of the software module the upload also changes to the new selected software module Signed-off-by: Asharani --- .../ui/artifacts/event/UploadFileStatus.java | 3 +- .../ui/artifacts/upload/UploadHandler.java | 19 ++++---- .../ui/artifacts/upload/UploadLayout.java | 45 +++++++------------ 3 files changed, 29 insertions(+), 38 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java index f594fad8b..81b096c3e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java @@ -35,10 +35,11 @@ public class UploadFileStatus implements Serializable { this.fileName = fileName; } - public UploadFileStatus(String fileName, long bytesRead, long contentLength) { + public UploadFileStatus(String fileName, long bytesRead, long contentLength,SoftwareModule softwareModule) { this.fileName = fileName; this.contentLength = contentLength; this.bytesRead = bytesRead; + this.softwareModule = softwareModule; } public UploadFileStatus(String fileName, String failureReason,SoftwareModule selectedSw) { 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 277e56967..848fa2da5 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 @@ -121,9 +121,8 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene // reset has directory flag before upload view.setHasDirectory(false); try { - if (view.checkIfSoftwareModuleIsSelected() && !view.checkForDuplicate(fileName)) { + if (view.checkIfSoftwareModuleIsSelected() && !view.checkForDuplicate(fileName, selectedSwForUpload)) { view.increaseNumberOfFileUploadsExpected(); - selectedSwForUpload = artifactUploadState.getSelectedBaseSoftwareModule().get(); return view.saveUploadedFileDetails(fileName, 0, mimeType, selectedSwForUpload); } } catch (final ArtifactUploadFailedException e) { @@ -146,7 +145,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public void uploadSucceeded(final SucceededEvent event) { LOG.debug("Streaming finished for file :{}", event.getFilename()); eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_SUCCESSFUL, new UploadFileStatus( - event.getFilename(), 0, event.getLength()))); + event.getFilename(), 0, event.getLength(), selectedSwForUpload))); } /** @@ -160,7 +159,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public void streamingFinished(final StreamingEndEvent event) { LOG.debug("Streaming finished for file :{}", event.getFileName()); eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STREAMING_FINISHED, - new UploadFileStatus(event.getFileName(), 0, event.getContentLength()))); + new UploadFileStatus(event.getFileName(), 0, event.getContentLength(), selectedSw))); } /** @@ -185,7 +184,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public void streamingStarted(final StreamingStartEvent event) { LOG.debug("Streaming started for file :{}", fileName); eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STARTED, new UploadFileStatus( - fileName, 0, 0))); + fileName, 0, 0, selectedSw))); } /** @@ -195,11 +194,13 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene */ @Override public void uploadStarted(final StartedEvent event) { + selectedSwForUpload = artifactUploadState.getSelectedBaseSoftwareModule().get(); + // single file session - if (view.isSoftwareModuleSelected() && !view.checkIfFileIsDuplicate(event.getFilename())) { + if (view.isSoftwareModuleSelected() && !view.checkIfFileIsDuplicate(event.getFilename(), selectedSwForUpload)) { LOG.debug("Upload started for file :{}", event.getFilename()); eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STARTED, new UploadFileStatus( - event.getFilename(), 0, 0))); + event.getFilename(), 0, 0, selectedSwForUpload))); } else { failureReason = i18n.get("message.upload.failed"); upload.interruptUpload(); @@ -238,7 +239,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene return; } eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_IN_PROGRESS, - new UploadFileStatus(fileName, readBytes, contentLength))); + new UploadFileStatus(fileName, readBytes, contentLength, selectedSwForUpload))); LOG.info("Update progress - {} : {}", fileName, (double) readBytes / (double) contentLength); } } @@ -259,7 +260,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene return; } eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_IN_PROGRESS, new UploadFileStatus( - fileName, event.getBytesReceived(), event.getContentLength()))); + fileName, event.getBytesReceived(), event.getContentLength(), selectedSw))); // Logging to solve sonar issue LOG.trace("Streaming in progress for file :{}", event.getFileName()); } 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 fedee30b9..cbf766da8 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 @@ -118,7 +118,6 @@ public class UploadLayout extends VerticalLayout { private Button uploadStatusButton; - /** * Initialize the upload layout. */ @@ -139,8 +138,7 @@ public class UploadLayout extends VerticalLayout { ui.access(() -> showUploadStatusButton()); } else if (event == UploadArtifactUIEvent.MAXIMIZED_STATUS_POPUP) { ui.access(() -> maximizeStatusPopup()); - } - else if(event == UploadArtifactUIEvent.ARTIFACT_RESULT_POPUP_CLOSED){ + } else if (event == UploadArtifactUIEvent.ARTIFACT_RESULT_POPUP_CLOSED) { ui.access(() -> closeUploadStatusPopup()); } } @@ -264,9 +262,9 @@ public class UploadLayout extends VerticalLayout { private void processFile(final Html5File file, SoftwareModule selectedSw) { if (!isDirectory(file)) { - if (!checkForDuplicate(file.getFileName())) { + if (!checkForDuplicate(file.getFileName(), selectedSw)) { artifactUploadState.getNumberOfFileUploadsExpected().incrementAndGet(); - file.setStreamVariable(createStreamVariable(file,selectedSw)); + file.setStreamVariable(createStreamVariable(file, selectedSw)); } } else { hasDirectory = Boolean.TRUE; @@ -275,7 +273,7 @@ public class UploadLayout extends VerticalLayout { private StreamVariable createStreamVariable(final Html5File file, SoftwareModule selectedSw) { return new UploadHandler(file.getFileName(), file.getFileSize(), UploadLayout.this, - spInfo.getMaxArtifactFileSize(), null, file.getType(),selectedSw); + spInfo.getMaxArtifactFileSize(), null, file.getType(), selectedSw); } private boolean isDirectory(final Html5File file) { @@ -339,8 +337,8 @@ public class UploadLayout extends VerticalLayout { discardBtn.addClickListener(event -> discardUploadData(event)); } - boolean checkForDuplicate(final String filename) { - final Boolean isDuplicate = checkIfFileIsDuplicate(filename); + boolean checkForDuplicate(final String filename, final SoftwareModule selectedSw) { + final Boolean isDuplicate = checkIfFileIsDuplicate(filename, selectedSw); if (isDuplicate) { getDuplicateFileNamesList().add(filename); } @@ -358,22 +356,23 @@ public class UploadLayout extends VerticalLayout { * file size * @param mimeType * the mimeType of the file - * @param selectedSw + * @param selectedSw * @throws IOException * in case of upload errors */ - OutputStream saveUploadedFileDetails(final String name, final long size, final String mimeType, SoftwareModule selectedSw) { + OutputStream saveUploadedFileDetails(final String name, final long size, final String mimeType, + SoftwareModule selectedSw) { File tempFile = null; try { tempFile = File.createTempFile("spUiArtifactUpload", null); final OutputStream out = new FileOutputStream(tempFile); - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( - selectedSw.getName(), selectedSw.getVersion()); + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion(selectedSw.getName(), + selectedSw.getVersion()); - final CustomFile customFile = new CustomFile(name, size, tempFile.getAbsolutePath(), - selectedSw.getName(), selectedSw.getVersion(), mimeType); + final CustomFile customFile = new CustomFile(name, size, tempFile.getAbsolutePath(), selectedSw.getName(), + selectedSw.getVersion(), mimeType); artifactUploadState.getFileSelected().add(customFile); processBtn.setEnabled(false); @@ -424,13 +423,6 @@ public class UploadLayout extends VerticalLayout { return true; } - SoftwareModule getSoftwareModuleSelected() { - if (artifactUploadState.getSelectedBaseSoftwareModule().isPresent()) { - return artifactUploadState.getSelectedBaseSoftwareModule().get(); - } - return null; - } - Boolean isSoftwareModuleSelected() { if (!artifactUploadState.getSelectedBaseSwModuleId().isPresent()) { return false; @@ -446,9 +438,8 @@ public class UploadLayout extends VerticalLayout { * file name * @return Boolean */ - public Boolean checkIfFileIsDuplicate(final String name) { + public Boolean checkIfFileIsDuplicate(final String name, final SoftwareModule selectedSoftwareModule) { Boolean isDuplicate = false; - final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); @@ -514,8 +505,7 @@ public class UploadLayout extends VerticalLayout { artifactUploadState.getNumberOfFileUploadsExpected().incrementAndGet(); } - void updateFileSize(final String name, final long size) { - final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); + void updateFileSize(final String name, final long size, SoftwareModule selectedSoftwareModule) { final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); @@ -718,7 +708,8 @@ public class UploadLayout extends VerticalLayout { } private void onUploadSuccess(UploadStatusEvent event) { - updateFileSize(event.getUploadStatus().getFileName(), event.getUploadStatus().getContentLength()); + updateFileSize(event.getUploadStatus().getFileName(), event.getUploadStatus().getContentLength(), event + .getUploadStatus().getSoftwareModule()); // recorded that we now one more uploaded increaseNumberOfFilesActuallyUpload(); } @@ -735,7 +726,6 @@ public class UploadLayout extends VerticalLayout { duplicateFileNamesList.clear(); } - private boolean isUploadComplete() { int uploadedCount = artifactUploadState.getNumberOfFilesActuallyUpload().intValue(); int expectedUploadsCount = artifactUploadState.getNumberOfFileUploadsExpected().intValue(); @@ -869,7 +859,6 @@ public class UploadLayout extends VerticalLayout { uploadStatusButton.setIcon(null); } - protected void updateUploadCounts() { updateActionCount(); updateStatusButtonCount(); From c2bf9222b7d4029c30c5c9f41db7eb913f088b61 Mon Sep 17 00:00:00 2001 From: Asharani Date: Thu, 19 May 2016 10:51:12 +0530 Subject: [PATCH 11/16] Signed-off-by: Asharani --- .../ui/artifacts/event/UploadStatusEvent.java | 2 +- .../ui/artifacts/upload/UploadHandler.java | 53 ++++++++++-- .../ui/artifacts/upload/UploadLayout.java | 5 +- .../upload/UploadStatusInfoWindow.java | 83 ++++++++++++++----- .../src/main/resources/messages.properties | 4 + .../src/main/resources/messages_de.properties | 6 +- .../src/main/resources/messages_en.properties | 5 +- 7 files changed, 123 insertions(+), 35 deletions(-) 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 = "
" + FontAwesome.CHECK_CIRCLE.getHtml() + "
"; @@ -266,20 +273,28 @@ public class UploadStatusInfoWindow extends Window { * Automatically close if not error has occured. */ void uploadSessionFinished() { - if (!errorOccured) { - close(); + uploadAborted = false; + if (!errorOccured && !artifactUploadState.isStatusPopupMinimized()) { + clearWindow(); } artifactUploadState.setUploadCompleted(true); minimizeButton.setEnabled(false); + closeButton.setEnabled(true); + confirmDialog.getWindow().close(); + UI.getCurrent().removeWindow(confirmDialog.getWindow()); } void uploadSessionStarted() { - if (!artifactUploadState.isStatusPopupMinimized()) { - close(); + if (artifactUploadState.getNumberOfFilesActuallyUpload().intValue() == 0 + && artifactUploadState.getNumberOfFileUploadsFailed().intValue() == 0 + && !artifactUploadState.isStatusPopupMinimized()) { openWindow(); } - minimizeButton.setEnabled(true); - artifactUploadState.setUploadCompleted(false); + if (!uploadAborted) { + minimizeButton.setEnabled(true); + closeButton.setEnabled(true); + artifactUploadState.setUploadCompleted(false); + } } void openWindow() { @@ -304,11 +319,11 @@ public class UploadStatusInfoWindow extends Window { } void updateProgress(final String filename, final long readBytes, final long contentLength) { - final Item item = uploads.getItem(filename); + final Item item = uploads.getItem(filename); if (item != null) { double progress = (double) readBytes / (double) contentLength; item.getItemProperty(PROGRESS).setValue(progress); - List uploadStatusObjectList = (List) artifactUploadState + List uploadStatusObjectList = (List) artifactUploadState .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) .collect(Collectors.toList()); if (!uploadStatusObjectList.isEmpty()) { @@ -340,9 +355,7 @@ public class UploadStatusInfoWindow extends Window { } void uploadFailed(final String filename, final String errorReason) { - if (!errorOccured) { - errorOccured = true; - } + errorOccured = true; String status = "Failed"; final Item item = uploads.getItem(filename); if (item != null) { @@ -363,6 +376,9 @@ public class UploadStatusInfoWindow extends Window { errorOccured = false; uploads.removeAllItems(); setWindowMode(WindowMode.NORMAL); + setColumnWidth(); + setPopupSizeInMinMode(); + resizeButton.setIcon(FontAwesome.EXPAND); this.close(); artifactUploadState.getUploadedFileStatusList().clear(); artifactUploadState.getNumberOfFileUploadsFailed().set(0); @@ -421,7 +437,34 @@ public class UploadStatusInfoWindow extends Window { SPUIComponetIdProvider.UPLOAD_STATUS_POPUP_CLOSE_BUTTON_ID, "", "", "", true, FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); closeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); - closeBtn.addClickListener(event -> clearWindow()); + closeBtn.addClickListener(event -> onClose()); return closeBtn; } + + private void onClose() { + if (!artifactUploadState.isUploadCompleted()) { + confirmAbortAction(); + } else { + clearWindow(); + } + } + + private void confirmAbortAction() { + UI.getCurrent().addWindow(confirmDialog.getWindow()); + confirmDialog.getWindow().bringToFront(); + } + + private void createConfirmDialog() { + confirmDialog = new ConfirmationDialog(i18n.get("caption.cancel.action.confirmbox"), + i18n.get("message.abort.upload"), i18n.get("button.ok"), i18n.get("button.cancel"), ok -> { + if (ok) { + eventBus.publish(this, UploadStatusEventType.ABORT_UPLOAD); + uploadAborted = true; + errorOccured = true; + minimizeButton.setEnabled(false); + closeButton.setEnabled(false); + } + }); + } + } diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index 25dabd354..7efc6e16d 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -86,6 +86,7 @@ caption.cancel.action.confirmbox = Confirm action cancel caption.forcequit.action.confirmbox = Confirm force quit action caption.forced.datefield = Force update at time caption.force.action.confirmbox = Confirm Force Active Action +caption.confirm.abort.action = Confirm abort action caption.filter.delete.confirmbox = Confirm Filter Delete Action @@ -321,8 +322,11 @@ message.duplicate.filename = Duplicate file name message.swModule.deleted = {0} Software module(s) deleted message.upload.failed = Streaming Failed message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes +message.uploadedfile.aborted = File upload aborted message.file.not.found = File not found message.artifact.deleted =Artifact with file {0} deleted successfully +message.abort.upload = Are you sure that you want to abort the upload? + upload.swModuleTable.header = Software module diff --git a/hawkbit-ui/src/main/resources/messages_de.properties b/hawkbit-ui/src/main/resources/messages_de.properties index 39661e3c9..6a1e25222 100644 --- a/hawkbit-ui/src/main/resources/messages_de.properties +++ b/hawkbit-ui/src/main/resources/messages_de.properties @@ -85,8 +85,9 @@ caption.forced.datefield = Force update at time caption.force.action.confirmbox = Confirm Force Active Action caption.filter.simple = Simple Filter caption.filter.custom = Custom Filter - caption.filter.delete.confirmbox = Confirm Filter Delete Action +caption.confirm.abort.action = Confirm abort action + # Labels prefix with - label label.dist.details.type = Type : @@ -319,8 +320,11 @@ message.swModule.deleted = {0} Software module(s) deleted message.error.missing.tagname = Please select tag name message.upload.failed = Streaming Failed message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes +message.uploadedfile.aborted = File upload aborted message.file.not.found = File not found message.artifact.deleted =Artifact with file {0} deleted successfully +message.abort.upload = Are you sure that you want to abort the upload? + upload.swModuleTable.header = Software module diff --git a/hawkbit-ui/src/main/resources/messages_en.properties b/hawkbit-ui/src/main/resources/messages_en.properties index 23df35ad2..d512b9b97 100644 --- a/hawkbit-ui/src/main/resources/messages_en.properties +++ b/hawkbit-ui/src/main/resources/messages_en.properties @@ -85,8 +85,8 @@ caption.soft.delete.confirmbox = Confirm Software Module Delete Action caption.cancel.action.confirmbox = Confirm action cancellation caption.forced.datefield = Force update at time caption.force.action.confirmbox = Confirm Force Active Action - caption.filter.delete.confirmbox = Confirm Filter Delete Action +caption.confirm.abort.action = Confirm abort action # Labels prefix with - label label.dist.details.type = Type : @@ -313,7 +313,10 @@ message.duplicate.filename = Duplicate file name message.swModule.deleted = {0} Software module(s) deleted message.upload.failed = Streaming Failed message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes +message.uploadedfile.aborted = File upload aborted message.file.not.found = File not found +message.abort.upload = Are you sure that you want to abort the upload? + upload.swModuleTable.header = Software module upload.selectedfile.name = file selected for upload From 037e66e197a24b4244a98f0847180f22ecb8a88e Mon Sep 17 00:00:00 2001 From: Asharani Date: Fri, 20 May 2016 15:48:38 +0530 Subject: [PATCH 12/16] Allowe parallel uploads of same file for different software module. Display software module details in status popup. Signed-off-by: Asharani --- .../ui/artifacts/upload/UploadHandler.java | 25 ++-- .../ui/artifacts/upload/UploadLayout.java | 12 +- .../upload/UploadStatusInfoWindow.java | 110 +++++++++++------- .../artifacts/upload/UploadStatusObject.java | 15 ++- 4 files changed, 101 insertions(+), 61 deletions(-) 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 45a55d138..dc56ff325 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 @@ -249,18 +249,18 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene // Update progress is called event after upload interrupted in // uploadStarted method if (!uploadInterrupted) { - if (readBytes > maxSize || contentLength > maxSize) { - LOG.error("User tried to upload more than was allowed ({}).", maxSize); - failureReason = i18n.get("message.uploadedfile.size.exceeded", maxSize); - interruptFileUpload(); - return; - } if (aborted) { LOG.error("User aborted file upload"); failureReason = i18n.get("message.uploadedfile.aborted"); interruptFileUpload(); return; } + if (readBytes > maxSize || contentLength > maxSize) { + LOG.error("User tried to upload more than was allowed ({}).", maxSize); + failureReason = i18n.get("message.uploadedfile.size.exceeded", maxSize); + interruptFileUpload(); + return; + } eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_IN_PROGRESS, new UploadFileStatus(fileName, readBytes, contentLength, selectedSwForUpload))); LOG.info("Update progress - {} : {}", fileName, (double) readBytes / (double) contentLength); @@ -274,18 +274,18 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene */ @Override public void onProgress(final StreamingProgressEvent event) { - 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); - interruptFileStreaming(); - return; - } if (aborted) { LOG.error("User aborted the upload"); failureReason = i18n.get("message.uploadedfile.aborted"); interruptFileStreaming(); return; } + 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); + interruptFileStreaming(); + return; + } eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_IN_PROGRESS, new UploadFileStatus( fileName, event.getBytesReceived(), event.getContentLength(), selectedSw))); // Logging to solve sonar issue @@ -380,4 +380,5 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene 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 4eaa61096..e19742e4f 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 @@ -222,6 +222,11 @@ public class UploadLayout extends VerticalLayout { setUploadStatusButtonIconToFinished(); } } + if (artifactUploadState.isUploadCompleted()) { + artifactUploadState.getNumberOfFilesActuallyUpload().set(0); + artifactUploadState.getNumberOfFileUploadsExpected().set(0); + artifactUploadState.getNumberOfFileUploadsFailed().set(0); + } } public DragAndDropWrapper getDropAreaWrapper() { @@ -692,7 +697,7 @@ public class UploadLayout extends VerticalLayout { // failed reason to be updated only if there is error other than // duplicate file error uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() - .getFailureReason()); + .getFailureReason(), event.getUploadStatus().getSoftwareModule()); increaseNumberOfFileUploadsFailed(); } decreaseNumberOfFileUploadsExpected(); @@ -722,13 +727,12 @@ public class UploadLayout extends VerticalLayout { } updateUploadCounts(); enableProcessBtn(); - duplicateFileNamesList.clear(); } 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) { @@ -746,7 +750,7 @@ public class UploadLayout extends VerticalLayout { // failed reason to be updated only if there is error other than // duplicate file error uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() - .getFailureReason()); + .getFailureReason(), event.getUploadStatus().getSoftwareModule()); increaseNumberOfFileUploadsFailed(); decreaseNumberOfFileUploadsExpected(); } 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 351d625c9..e4ab8d474 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 @@ -14,6 +14,7 @@ import java.util.stream.Collectors; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; +import org.eclipse.hawkbit.repository.model.SoftwareModule; 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; @@ -21,8 +22,10 @@ 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.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; +import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; @@ -100,7 +103,7 @@ public class UploadStatusInfoWindow extends Window { private Button resizeButton; private UI ui; - + private ConfirmationDialog confirmDialog; /** @@ -126,7 +129,7 @@ public class UploadStatusInfoWindow extends Window { setContent(mainLayout); eventBus.subscribe(this); ui = UI.getCurrent(); - + createConfirmDialog(); } @@ -135,22 +138,25 @@ public class UploadStatusInfoWindow extends Window { if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_IN_PROGRESS) { UI.getCurrent().access( () -> updateProgress(event.getUploadStatus().getFileName(), event.getUploadStatus().getBytesRead(), - event.getUploadStatus().getContentLength())); + event.getUploadStatus().getContentLength(), event.getUploadStatus().getSoftwareModule())); } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STARTED) { UI.getCurrent().access(() -> onStartOfUpload(event)); } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FAILED) { ui.access(() -> uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() - .getFailureReason())); + .getFailureReason(), event.getUploadStatus().getSoftwareModule())); } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_SUCCESSFUL) { - UI.getCurrent().access(() -> uploadSucceeded(event.getUploadStatus().getFileName())); + UI.getCurrent().access( + () -> uploadSucceeded(event.getUploadStatus().getFileName(), event.getUploadStatus() + .getSoftwareModule())); } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FINISHED) { - ui.access(() -> uploadSucceeded(event.getUploadStatus().getFileName())); + ui.access(() -> uploadSucceeded(event.getUploadStatus().getFileName(), event.getUploadStatus() + .getSoftwareModule())); } } private void onStartOfUpload(UploadStatusEvent event) { uploadSessionStarted(); - uploadStarted(event.getUploadStatus().getFileName()); + uploadStarted(event.getUploadStatus().getFileName(), event.getUploadStatus().getSoftwareModule()); } @PreDestroy @@ -167,11 +173,15 @@ public class UploadStatusInfoWindow extends Window { if (container.getItemIds().isEmpty()) { container.removeAllItems(); for (UploadStatusObject statusObject : artifactUploadState.getUploadedFileStatusList()) { - Item item = container.addItem(statusObject.getFilename()); + Item item = container.addItem(getItemid(statusObject.getFilename(), + statusObject.getSelectedSoftwareModule())); item.getItemProperty(REASON).setValue(statusObject.getReason() != null ? statusObject.getReason() : ""); item.getItemProperty(STATUS).setValue(statusObject.getStatus()); item.getItemProperty(PROGRESS).setValue(statusObject.getProgress()); item.getItemProperty(FILE_NAME).setValue(statusObject.getFilename()); + SoftwareModule sw = statusObject.getSelectedSoftwareModule(); + item.getItemProperty(SPUILabelDefinitions.NAME_VERSION).setValue( + HawkbitCommonUtil.getFormattedNameVersion(sw.getName(), sw.getVersion())); } if (artifactUploadState.isUploadCompleted()) { minimizeButton.setEnabled(false); @@ -192,9 +202,10 @@ public class UploadStatusInfoWindow extends Window { private void setGridColumnProperties() { grid.getColumn(STATUS).setRenderer(new StatusRenderer()); grid.getColumn(PROGRESS).setRenderer(new ProgressBarRenderer()); - grid.setColumnOrder(STATUS, PROGRESS, FILE_NAME, REASON); + grid.setColumnOrder(STATUS, PROGRESS, FILE_NAME, SPUILabelDefinitions.NAME_VERSION, REASON); setColumnWidth(); - grid.setFrozenColumnCount(4); + grid.getColumn(SPUILabelDefinitions.NAME_VERSION).setHeaderCaption(i18n.get("upload.swModuleTable.header")); + grid.setFrozenColumnCount(5); } private Grid createGrid() { @@ -213,6 +224,7 @@ public class UploadStatusInfoWindow extends Window { uploadContainer.addContainerProperty(FILE_NAME, String.class, null); uploadContainer.addContainerProperty(PROGRESS, Double.class, 0D); uploadContainer.addContainerProperty(REASON, String.class, ""); + uploadContainer.addContainerProperty(SPUILabelDefinitions.NAME_VERSION, String.class, ""); return uploadContainer; } @@ -234,10 +246,11 @@ public class UploadStatusInfoWindow extends Window { } private void setColumnWidth() { - grid.getColumn(STATUS).setWidth(70); + grid.getColumn(STATUS).setWidth(60); grid.getColumn(PROGRESS).setWidth(150); - grid.getColumn(FILE_NAME).setWidth(280); - grid.getColumn(REASON).setWidth(300); + grid.getColumn(FILE_NAME).setWidth(200); + grid.getColumn(REASON).setWidth(290); + grid.getColumn(SPUILabelDefinitions.NAME_VERSION).setWidth(200); } private void resetColumnWidth() { @@ -245,6 +258,7 @@ public class UploadStatusInfoWindow extends Window { grid.getColumn(PROGRESS).setWidthUndefined(); grid.getColumn(FILE_NAME).setWidthUndefined(); grid.getColumn(REASON).setWidthUndefined(); + grid.getColumn(SPUILabelDefinitions.NAME_VERSION).setWidthUndefined(); } private static class StatusRenderer extends HtmlRenderer { @@ -307,29 +321,32 @@ public class UploadStatusInfoWindow extends Window { restoreState(); } - void uploadStarted(final String filename) { - final Item item = uploads.addItem(filename); + void uploadStarted(final String filename, final SoftwareModule softwareModule) { + final Item item = uploads.addItem(getItemid(filename, softwareModule)); if (item != null) { item.getItemProperty(FILE_NAME).setValue(filename); + item.getItemProperty(SPUILabelDefinitions.NAME_VERSION).setValue( + HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(), softwareModule.getVersion())); } grid.scrollToEnd(); - UploadStatusObject uploadStatus = new UploadStatusObject(filename); + UploadStatusObject uploadStatus = new UploadStatusObject(filename, softwareModule); uploadStatus.setStatus("Active"); artifactUploadState.getUploadedFileStatusList().add(uploadStatus); } - void updateProgress(final String filename, final long readBytes, final long contentLength) { - final Item item = uploads.getItem(filename); + void updateProgress(final String filename, final long readBytes, final long contentLength, + final SoftwareModule softwareModule) { + final Item item = uploads.getItem(getItemid(filename, softwareModule)); + double progress = (double) readBytes / (double) contentLength; if (item != null) { - double progress = (double) readBytes / (double) contentLength; item.getItemProperty(PROGRESS).setValue(progress); - List uploadStatusObjectList = (List) artifactUploadState - .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) - .collect(Collectors.toList()); - if (!uploadStatusObjectList.isEmpty()) { - UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); - uploadStatusObject.setProgress(progress); - } + } + List uploadStatusObjectList = (List) artifactUploadState + .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) + .collect(Collectors.toList()); + if (!uploadStatusObjectList.isEmpty()) { + UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); + uploadStatusObject.setProgress(progress); } } @@ -338,26 +355,29 @@ public class UploadStatusInfoWindow extends Window { * * @param filename * of the uploaded file. + * @param softwareModule + * selected software module */ - public void uploadSucceeded(final String filename) { - final Item item = uploads.getItem(filename); + public void uploadSucceeded(final String filename, SoftwareModule softwareModule) { + final Item item = uploads.getItem(getItemid(filename, softwareModule)); + String status = "Finished"; if (item != null) { - String status = "Finished"; item.getItemProperty(STATUS).setValue(status); - List uploadStatusObjectList = (List) artifactUploadState - .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) - .collect(Collectors.toList()); - if (!uploadStatusObjectList.isEmpty()) { - UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); - uploadStatusObject.setStatus(status); - } + } + List uploadStatusObjectList = (List) artifactUploadState + .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) + .collect(Collectors.toList()); + if (!uploadStatusObjectList.isEmpty()) { + UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); + uploadStatusObject.setStatus(status); + uploadStatusObject.setProgress(1d); } } - void uploadFailed(final String filename, final String errorReason) { + void uploadFailed(final String filename, final String errorReason, SoftwareModule softwareModule) { errorOccured = true; String status = "Failed"; - final Item item = uploads.getItem(filename); + final Item item = uploads.getItem(getItemid(filename, softwareModule)); if (item != null) { item.getItemProperty(REASON).setValue(errorReason); item.getItemProperty(STATUS).setValue(status); @@ -385,7 +405,7 @@ public class UploadStatusInfoWindow extends Window { } private void setPopupSizeInMinMode() { - mainLayout.setWidth(800, Unit.PIXELS); + mainLayout.setWidth(900, Unit.PIXELS); mainLayout.setHeight(510, Unit.PIXELS); } @@ -417,6 +437,7 @@ public class UploadStatusInfoWindow extends Window { grid.getColumn(PROGRESS).setExpandRatio(1); grid.getColumn(FILE_NAME).setExpandRatio(2); grid.getColumn(REASON).setExpandRatio(3); + grid.getColumn(SPUILabelDefinitions.NAME_VERSION).setExpandRatio(4); mainLayout.setSizeFull(); } else { event.getButton().setIcon(FontAwesome.EXPAND); @@ -455,7 +476,7 @@ public class UploadStatusInfoWindow extends Window { } private void createConfirmDialog() { - confirmDialog = new ConfirmationDialog(i18n.get("caption.cancel.action.confirmbox"), + confirmDialog = new ConfirmationDialog(i18n.get("caption.confirm.abort.action"), i18n.get("message.abort.upload"), i18n.get("button.ok"), i18n.get("button.cancel"), ok -> { if (ok) { eventBus.publish(this, UploadStatusEventType.ABORT_UPLOAD); @@ -463,8 +484,13 @@ public class UploadStatusInfoWindow extends Window { errorOccured = true; minimizeButton.setEnabled(false); closeButton.setEnabled(false); - } - }); + } + }); } + private String getItemid(final String filename, final SoftwareModule softwareModule) { + return new StringBuilder(filename).append( + HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(), softwareModule.getVersion())) + .toString(); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java index 13167b55a..4ea82d7dd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.artifacts.upload; +import org.eclipse.hawkbit.repository.model.SoftwareModule; + /** * * Holds uploaded file status.Used to display the details in upload status @@ -19,16 +21,23 @@ public class UploadStatusObject { private Double progress; private String filename; private String reason; + private SoftwareModule selectedSoftwareModule; - public UploadStatusObject(String status, Double progress, String fileName, String reason) { - this(fileName); + public UploadStatusObject(final String status, final Double progress, final String fileName, final String reason, + final SoftwareModule selectedSoftwareModule) { + this(fileName,selectedSoftwareModule); this.status = status; this.progress = progress; this.reason = reason; } - public UploadStatusObject(String fileName) { + public UploadStatusObject(String fileName, SoftwareModule selectedSoftwareModule) { this.filename = fileName; + this.selectedSoftwareModule = selectedSoftwareModule; + } + + public SoftwareModule getSelectedSoftwareModule() { + return selectedSoftwareModule; } public String getStatus() { From 693c6783772880df43041e89e9da59dbbce11de7 Mon Sep 17 00:00:00 2001 From: Asharani Date: Tue, 24 May 2016 14:38:06 +0530 Subject: [PATCH 13/16] Do not log the exception trace when upload fails by user abort action Signed-off-by: Asharani --- .../ui/artifacts/upload/UploadHandler.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) 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 dc56ff325..28b6c5243 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 @@ -250,7 +250,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene // uploadStarted method if (!uploadInterrupted) { if (aborted) { - LOG.error("User aborted file upload"); + LOG.info("User aborted file upload for file : {}", fileName); failureReason = i18n.get("message.uploadedfile.aborted"); interruptFileUpload(); return; @@ -275,7 +275,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene @Override public void onProgress(final StreamingProgressEvent event) { if (aborted) { - LOG.error("User aborted the upload"); + LOG.info("User aborted the upload for file : {}", event.getFileName()); failureReason = i18n.get("message.uploadedfile.aborted"); interruptFileStreaming(); return; @@ -300,14 +300,16 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene */ @Override public void streamingFailed(final StreamingErrorEvent event) { - LOG.info("Streaming failed for file :{}", event.getFileName()); if (failureReason == null) { failureReason = event.getException().getMessage(); } eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STREAMING_FAILED, new UploadFileStatus(fileName, failureReason, selectedSw))); - LOG.info("Streaming failed due to :{}", event.getException()); + if (!aborted) { + LOG.info("Streaming failed for file :{}", event.getFileName()); + LOG.info("Streaming failed due to :{}", event.getException()); + } } /** @@ -317,13 +319,15 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene */ @Override public void uploadFailed(final FailedEvent event) { - LOG.info("Upload failed for file :{}", event.getFilename()); if (failureReason == null) { failureReason = event.getReason().getMessage(); } eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_FAILED, new UploadFileStatus( fileName, failureReason, selectedSwForUpload))); - LOG.info("Upload failed for file :{}", event.getReason()); + if (!aborted) { + LOG.info("Upload failed for file :{}", event.getFilename()); + LOG.info("Upload failed for file :{}", event.getReason()); + } } /** From 1fe267c5c35f05615a1c49df552faa62cca4bcd2 Mon Sep 17 00:00:00 2001 From: Asharani Date: Thu, 2 Jun 2016 15:50:29 +0530 Subject: [PATCH 14/16] Re-added component id's in SPUIComponenetIdProvider Signed-off-by: Asharani --- .../ui/artifacts/upload/UploadLayout.java | 2 +- .../upload/UploadStatusInfoWindow.java | 10 ++++---- .../ui/utils/SPUIComponentIdProvider.java | 24 +++++++++++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) 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 3be271e3c..05c175ead 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 @@ -793,7 +793,7 @@ public class UploadLayout extends VerticalLayout { } private void createUploadStatusButton() { - uploadStatusButton = SPUIComponentProvider.getButton(SPUIComponetIdProvider.UPLOAD_STATUS_BUTTON, "", "", "", + uploadStatusButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.UPLOAD_STATUS_BUTTON, "", "", "", false, null, SPUIButtonStyleSmall.class); uploadStatusButton.setStyleName(SPUIStyleDefinitions.ACTION_BUTTON); uploadStatusButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); 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 e4ab8d474..a58c6ea14 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 @@ -24,7 +24,7 @@ import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; -import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; +import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; @@ -190,7 +190,7 @@ public class UploadStatusInfoWindow extends Window { } private void setPopupProperties() { - setId(SPUIComponetIdProvider.UPLOAD_STATUS_POPUP_ID); + setId(SPUIComponentIdProvider.UPLOAD_STATUS_POPUP_ID); addStyleName(SPUIStyleDefinitions.UPLOAD_INFO); setImmediate(true); setResizable(false); @@ -411,7 +411,7 @@ public class UploadStatusInfoWindow extends Window { private Button getMinimizeButton() { final Button minimizeBtn = SPUIComponentProvider.getButton( - SPUIComponetIdProvider.UPLOAD_STATUS_POPUP_MINIMIZE_BUTTON_ID, "", "", "", true, FontAwesome.MINUS, + SPUIComponentIdProvider.UPLOAD_STATUS_POPUP_MINIMIZE_BUTTON_ID, "", "", "", true, FontAwesome.MINUS, SPUIButtonStyleSmallNoBorder.class); minimizeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); minimizeBtn.addClickListener(event -> minimizeWindow()); @@ -421,7 +421,7 @@ public class UploadStatusInfoWindow extends Window { private Button getResizeButton() { final Button resizeBtn = SPUIComponentProvider.getButton( - SPUIComponetIdProvider.UPLOAD_STATUS_POPUP_RESIZE_BUTTON_ID, "", "", "", true, FontAwesome.EXPAND, + SPUIComponentIdProvider.UPLOAD_STATUS_POPUP_RESIZE_BUTTON_ID, "", "", "", true, FontAwesome.EXPAND, SPUIButtonStyleSmallNoBorder.class); resizeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); resizeBtn.addClickListener(event -> resizeWindow(event)); @@ -455,7 +455,7 @@ public class UploadStatusInfoWindow extends Window { private Button getCloseButton() { final Button closeBtn = SPUIComponentProvider.getButton( - SPUIComponetIdProvider.UPLOAD_STATUS_POPUP_CLOSE_BUTTON_ID, "", "", "", true, FontAwesome.TIMES, + SPUIComponentIdProvider.UPLOAD_STATUS_POPUP_CLOSE_BUTTON_ID, "", "", "", true, FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); closeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); closeBtn.addClickListener(event -> onClose()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java index 80d40104a..6649b12fe 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java @@ -888,6 +888,30 @@ public final class SPUIComponentIdProvider { */ public static final String VALIDATION_STATUS_ICON_ID = "validation.status.icon"; + /** + * Artifact upload status popup - minimize button id. + */ + public static final String UPLOAD_STATUS_POPUP_MINIMIZE_BUTTON_ID = "artifact.upload.minimize.button.id"; + + /** + * Artifact upload status popup - close button id. + */ + public static final String UPLOAD_STATUS_POPUP_CLOSE_BUTTON_ID = "artifact.upload.close.button.id"; + + /** + * Artifact upload status popup - resize button id. + */ + public static final String UPLOAD_STATUS_POPUP_RESIZE_BUTTON_ID = "artifact.upload.resize.button.id"; + + /** + * Artifact upload view - upload status button id. + */ + public static final String UPLOAD_STATUS_BUTTON = "artficat.upload.status.button.id"; + + /** + * Artifact uplaod view - uplod status popup id. + */ + public static final String UPLOAD_STATUS_POPUP_ID = "artifact.upload.status.popup.id"; /** * /* Private Constructor. */ From 223e0f6c857a55e6392ec1fd8ef27a055030b459 Mon Sep 17 00:00:00 2001 From: AMU7KOR Date: Fri, 3 Jun 2016 10:02:50 +0530 Subject: [PATCH 15/16] Fix: Interupt upload if software moudle is not selected Signed-off-by: AMU7KOR --- .../ui/artifacts/upload/UploadHandler.java | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) 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 61f68f397..78a6fd9a9 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 @@ -133,7 +133,6 @@ 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; @@ -214,17 +213,23 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene */ @Override public void uploadStarted(final StartedEvent event) { - selectedSwForUpload = artifactUploadState.getSelectedBaseSoftwareModule().get(); + uploadInterrupted = false; + selectedSwForUpload = artifactUploadState.getSelectedBaseSoftwareModule().isPresent() ? artifactUploadState + .getSelectedBaseSoftwareModule().get() : null; - // single file session - if (view.isSoftwareModuleSelected() && !view.checkIfFileIsDuplicate(event.getFilename(), selectedSwForUpload)) { - LOG.debug("Upload started for file :{}", event.getFilename()); - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STARTED, new UploadFileStatus( - event.getFilename(), 0, 0, selectedSwForUpload))); - } else { + if (view.isSoftwareModuleSelected()) { + // single file session + if (!view.checkIfFileIsDuplicate(event.getFilename(), selectedSwForUpload)) { + LOG.debug("Upload started for file :{}", event.getFilename()); + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STARTED, + new UploadFileStatus(event.getFilename(), 0, 0, selectedSwForUpload))); + } + } + else { failureReason = i18n.get("message.upload.failed"); upload.interruptUpload(); - // actual interrupt will happen a bit late so setting the below flag + // actual interrupt will happen a bit late so setting the below + // flag uploadInterrupted = true; } } @@ -319,14 +324,20 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene */ @Override public void uploadFailed(final FailedEvent event) { - if (failureReason == null) { - failureReason = event.getReason().getMessage(); - } - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_FAILED, new UploadFileStatus( - fileName, failureReason, selectedSwForUpload))); - if (!aborted) { - LOG.info("Upload failed for file :{}", event.getFilename()); - LOG.info("Upload failed for file :{}", event.getReason()); + /** + * If upload failed due to no selected software UPLOAD_FAILED event need + * not be published. + */ + if (selectedSwForUpload != null) { + if (failureReason == null) { + failureReason = event.getReason().getMessage(); + } + eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_FAILED, new UploadFileStatus( + fileName, failureReason, selectedSwForUpload))); + if (!aborted) { + LOG.info("Upload failed for file :{}", event.getFilename()); + LOG.info("Upload failed for file :{}", event.getReason()); + } } } From 92e1d78df377dcf41070cfb8b9c269997f313a43 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 3 Jun 2016 07:47:22 +0200 Subject: [PATCH 16/16] exclude .sonar directory from license check Signed-off-by: Michael Hirsch --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 0e4fec71d..49ef805b3 100644 --- a/pom.xml +++ b/pom.xml @@ -168,6 +168,8 @@ eclipse_codeformatter.xml **/addons.scss **/VAADIN/widgetsets/** + .sonar + **/.sonar/** JAVADOC_STYLE