Java tutorial
/** * 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; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.springframework.util.StringUtils; import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.annotation.EventBusListenerMethod; 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.ui.Button; 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; /** * Window that shows the progress of all uploads. */ public class UploadProgressInfoWindow extends Window { private static final long serialVersionUID = 1L; private static final String COLUMN_PROGRESS = UIMessageIdProvider.CAPTION_ARTIFACT_UPLOAD_PROGRESS; private static final String COLUMN_FILE_NAME = UIMessageIdProvider.CAPTION_ARTIFACT_FILENAME; private static final String COLUMN_STATUS = UIMessageIdProvider.CAPTION_ARTIFACT_UPLOAD_STATUS; private static final String COLUMN_REASON = UIMessageIdProvider.CAPTION_ARTIFACT_UPLOAD_REASON; private static final String COLUMN_SOFTWARE_MODULE = UIMessageIdProvider.CAPTION_SOFTWARE_MODULE; private static final String STATUS_INPROGRESS = "InProgress"; private static final String STATUS_FINISHED = "Finished"; private static final String STATUS_FAILED = "Failed"; private final ArtifactUploadState artifactUploadState; private final VaadinMessageSource i18n; private final Grid grid; private final IndexedContainer uploads; private final VerticalLayout mainLayout; private final UI ui; private Label windowCaption; private Button closeButton; UploadProgressInfoWindow(final UIEventBus eventBus, final ArtifactUploadState artifactUploadState, final VaadinMessageSource i18n) { this.artifactUploadState = artifactUploadState; this.i18n = i18n; setPopupProperties(); createStatusPopupHeaderComponents(); mainLayout = new VerticalLayout(); mainLayout.setSpacing(Boolean.TRUE); mainLayout.setSizeUndefined(); setPopupSizeInMinMode(); uploads = getGridContainer(); grid = createGrid(); setGridColumnProperties(); mainLayout.addComponents(getCaptionLayout(), grid); mainLayout.setExpandRatio(grid, 1.0F); setContent(mainLayout); eventBus.subscribe(this); ui = UI.getCurrent(); } @EventBusListenerMethod(scope = EventScope.UI) void onEvent(final FileUploadProgress fileUploadProgress) { switch (fileUploadProgress.getFileUploadStatus()) { case UPLOAD_STARTED: ui.access(() -> onUploadStarted(fileUploadProgress)); break; case UPLOAD_IN_PROGRESS: case UPLOAD_FAILED: case UPLOAD_SUCCESSFUL: ui.access(() -> updateUploadProgressInfoRowObject(fileUploadProgress)); break; case UPLOAD_FINISHED: ui.access(this::onUploadFinished); break; default: break; } } private void onUploadStarted(final FileUploadProgress fileUploadProgress) { updateUploadProgressInfoRowObject(fileUploadProgress); if (isWindowNotAlreadyAttached()) { maximizeWindow(); } grid.scrollTo(fileUploadProgress.getFileUploadId()); } private boolean isWindowNotAlreadyAttached() { return !UI.getCurrent().getWindows().contains(this); } private void restoreState() { final Indexed container = grid.getContainerDataSource(); container.removeAllItems(); for (final FileUploadProgress fileUploadProgress : artifactUploadState .getAllFileUploadProgressValuesFromOverallUploadProcessList()) { updateUploadProgressInfoRowObject(fileUploadProgress); } } private void setPopupProperties() { setId(UIComponentIdProvider.UPLOAD_STATUS_POPUP_ID); addStyleName(SPUIStyleDefinitions.UPLOAD_INFO); setImmediate(true); setResizable(false); setDraggable(true); setClosable(false); setModal(true); } private void setGridColumnProperties() { grid.getColumn(COLUMN_STATUS).setRenderer(new StatusRenderer()); grid.getColumn(COLUMN_PROGRESS).setRenderer(new ProgressBarRenderer()); grid.setColumnOrder(COLUMN_STATUS, COLUMN_PROGRESS, COLUMN_FILE_NAME, COLUMN_SOFTWARE_MODULE, COLUMN_REASON); setColumnWidth(); grid.getColumn(COLUMN_STATUS).setHeaderCaption(i18n.getMessage(COLUMN_STATUS)); grid.getColumn(COLUMN_PROGRESS).setHeaderCaption(i18n.getMessage(COLUMN_PROGRESS)); grid.getColumn(COLUMN_FILE_NAME).setHeaderCaption(i18n.getMessage(COLUMN_FILE_NAME)); grid.getColumn(COLUMN_SOFTWARE_MODULE).setHeaderCaption(i18n.getMessage(COLUMN_SOFTWARE_MODULE)); grid.getColumn(COLUMN_REASON).setHeaderCaption(i18n.getMessage(COLUMN_REASON)); grid.setFrozenColumnCount(5); } private Grid createGrid() { final Grid statusGrid = new Grid(uploads); statusGrid.addStyleName(SPUIStyleDefinitions.UPLOAD_STATUS_GRID); statusGrid.setId(UIComponentIdProvider.UPLOAD_STATUS_POPUP_GRID); statusGrid.setSelectionMode(SelectionMode.NONE); statusGrid.setHeaderVisible(true); statusGrid.setImmediate(true); statusGrid.setSizeFull(); return statusGrid; } private static IndexedContainer getGridContainer() { final IndexedContainer uploadContainer = new IndexedContainer(); uploadContainer.addContainerProperty(COLUMN_STATUS, String.class, "Active"); uploadContainer.addContainerProperty(COLUMN_FILE_NAME, String.class, null); uploadContainer.addContainerProperty(COLUMN_PROGRESS, Double.class, 0D); uploadContainer.addContainerProperty(COLUMN_REASON, String.class, ""); uploadContainer.addContainerProperty(COLUMN_SOFTWARE_MODULE, String.class, ""); return uploadContainer; } private HorizontalLayout getCaptionLayout() { final HorizontalLayout captionLayout = new HorizontalLayout(); captionLayout.setSizeFull(); captionLayout.setHeight("36px"); captionLayout.addComponents(windowCaption, closeButton); captionLayout.setExpandRatio(windowCaption, 1.0F); captionLayout.addStyleName("v-window-header"); return captionLayout; } private void createStatusPopupHeaderComponents() { windowCaption = new Label(i18n.getMessage(UIMessageIdProvider.CAPTION_ARTIFACT_UPLOAD_POPUP)); closeButton = getCloseButton(); } private void setColumnWidth() { grid.getColumn(COLUMN_STATUS).setWidth(60); grid.getColumn(COLUMN_PROGRESS).setWidth(150); grid.getColumn(COLUMN_FILE_NAME).setWidth(200); grid.getColumn(COLUMN_REASON).setWidth(290); grid.getColumn(COLUMN_SOFTWARE_MODULE).setWidth(200); } private static class StatusRenderer extends HtmlRenderer { private static final long serialVersionUID = 1L; @Override public JsonValue encode(final String value) { if (value == null) { return super.encode(getNullRepresentation()); } final String result; switch (value) { case STATUS_FINISHED: result = "<div class=\"statusIconGreen\">" + FontAwesome.CHECK_CIRCLE.getHtml() + "</div>"; break; case STATUS_FAILED: result = "<div class=\"statusIconRed\">" + FontAwesome.EXCLAMATION_CIRCLE.getHtml() + "</div>"; break; case STATUS_INPROGRESS: result = "<div class=\"statusIconActive\"></div>"; break; default: throw new IllegalArgumentException("Argument " + value + " wasn't expected."); } return super.encode(result); } } private void openWindow() { UI.getCurrent().addWindow(this); center(); } protected void maximizeWindow() { openWindow(); restoreState(); artifactUploadState.setStatusPopupMinimized(false); } private void minimizeWindow() { artifactUploadState.setStatusPopupMinimized(true); closeWindow(); if (artifactUploadState.areAllUploadsFinished()) { cleanupStates(); } } /** * Called for every finished (succeeded or failed) upload. */ private void onUploadFinished() { if (artifactUploadState.areAllUploadsFinished() && artifactUploadState.isStatusPopupMinimized()) { if (artifactUploadState.getFilesInFailedState().isEmpty()) { cleanupStates(); closeWindow(); } else { maximizeWindow(); } } } private void cleanupStates() { uploads.removeAllItems(); artifactUploadState.clearUploadTempData(); } private void setPopupSizeInMinMode() { mainLayout.setWidth(900, Unit.PIXELS); mainLayout.setHeight(510, Unit.PIXELS); } private Button getCloseButton() { final Button closeBtn = SPUIComponentProvider.getButton( UIComponentIdProvider.UPLOAD_STATUS_POPUP_CLOSE_BUTTON_ID, "", "", "", true, FontAwesome.TIMES, SPUIButtonStyleNoBorder.class); closeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); closeBtn.addClickListener(event -> onClose()); return closeBtn; } private void onClose() { if (artifactUploadState.areAllUploadsFinished()) { cleanupStates(); closeWindow(); } else { minimizeWindow(); } } private void closeWindow() { setWindowMode(WindowMode.NORMAL); setColumnWidth(); setPopupSizeInMinMode(); this.close(); } @SuppressWarnings("unchecked") private void updateUploadProgressInfoRowObject(final FileUploadProgress fileUploadProgress) { final FileUploadId fileUploadId = fileUploadProgress.getFileUploadId(); Item item = uploads.getItem(fileUploadId); if (item == null) { item = grid.getContainerDataSource().addItem(fileUploadId); item.getItemProperty(COLUMN_FILE_NAME).setValue(fileUploadId.getFilename()); item.getItemProperty(COLUMN_SOFTWARE_MODULE).setValue(HawkbitCommonUtil.getFormattedNameVersion( fileUploadId.getSoftwareModuleName(), fileUploadId.getSoftwareModuleVersion())); } final String status; final FileUploadStatus uploadStatus = fileUploadProgress.getFileUploadStatus(); if (uploadStatus == FileUploadStatus.UPLOAD_FAILED) { status = STATUS_FAILED; } else if (uploadStatus == FileUploadStatus.UPLOAD_SUCCESSFUL) { status = STATUS_FINISHED; } else { status = STATUS_INPROGRESS; } item.getItemProperty(COLUMN_STATUS).setValue(status); item.getItemProperty(COLUMN_REASON).setValue(getFailureReason(fileUploadId)); final long bytesRead = fileUploadProgress.getBytesRead(); final long fileSize = fileUploadProgress.getContentLength(); if (bytesRead > 0 && fileSize > 0) { item.getItemProperty(COLUMN_PROGRESS).setValue((double) bytesRead / (double) fileSize); } } /** * Returns the failure reason for the provided fileUploadId or an empty * string but never <code>null</code>. * * @param fileUploadId * @return the failure reason or an empty String. */ private String getFailureReason(final FileUploadId fileUploadId) { String failureReason = ""; if (artifactUploadState.getFileUploadProgress(fileUploadId) != null) { failureReason = artifactUploadState.getFileUploadProgress(fileUploadId).getFailureReason(); } if (StringUtils.isEmpty(failureReason)) { return ""; } return failureReason; } }