diff --git a/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/MyLoginUI.java b/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/MyLoginUI.java deleted file mode 100644 index dab0798aec..0000000000 --- a/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/MyLoginUI.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.app; - -import org.eclipse.hawkbit.im.authentication.MultitenancyIndicator; -import org.eclipse.hawkbit.ui.UiProperties; -import org.eclipse.hawkbit.ui.login.AbstractHawkbitLoginUI; -import org.eclipse.hawkbit.ui.themes.HawkbitTheme; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.vaadin.spring.security.VaadinSecurity; - -import com.vaadin.spring.annotation.SpringUI; - -/** - * Example hawkBit login UI implementation. - * - * A {@link SpringUI} annotated class must be present in the classpath for the - * login path. The easiest way to get an hawkBit login UI running is to extend - * the {@link AbstractHawkbitLoginUI} and to annotated it with {@link SpringUI} - * as in this example to the defined {@link HawkbitTheme#LOGIN_UI_PATH}. - */ -@SpringUI(path = HawkbitTheme.LOGIN_UI_PATH) -// Exception squid:MaximumInheritanceDepth - Most of the inheritance comes from -// Vaadin. -@SuppressWarnings({ "squid:MaximumInheritanceDepth" }) -public class MyLoginUI extends AbstractHawkbitLoginUI { - private static final long serialVersionUID = 1L; - - @Autowired - MyLoginUI(final ApplicationContext context, final VaadinSecurity vaadinSecurity, final VaadinMessageSource i18n, - final UiProperties uiProperties, final MultitenancyIndicator multiTenancyIndicator) { - super(context, vaadinSecurity, i18n, uiProperties, multiTenancyIndicator); - } - -} diff --git a/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/MyUI.java b/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/MyUI.java deleted file mode 100644 index 9f3bab5ab4..0000000000 --- a/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/MyUI.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.app; - -import org.eclipse.hawkbit.ui.AbstractHawkbitUI; -import org.eclipse.hawkbit.ui.UiProperties; -import org.eclipse.hawkbit.ui.components.NotificationUnreadButton; -import org.eclipse.hawkbit.ui.error.ErrorView; -import org.eclipse.hawkbit.ui.menu.DashboardMenu; -import org.eclipse.hawkbit.ui.push.EventPushStrategy; -import org.eclipse.hawkbit.ui.push.UIEventProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.annotations.Push; -import com.vaadin.server.ErrorHandler; -import com.vaadin.shared.communication.PushMode; -import com.vaadin.shared.ui.ui.Transport; -import com.vaadin.spring.annotation.SpringUI; -import com.vaadin.spring.navigator.SpringViewProvider; - -/** - * Example hawkBit UI implementation. - * - * A {@link SpringUI} annotated class must be present in the classpath. The - * easiest way to get an hawkBit UI running is to extend the - * {@link AbstractHawkbitUI} and to annotated it with {@link SpringUI} as in - * this example. WEBSOCKET_XHR transport is used instead of WEBSOCKET in order - * to preserve Spring Security Context, that does not work using websocket - * communication with Vaadin Shared Security. - * - */ -@SpringUI -@Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET_XHR) -// Exception squid:MaximumInheritanceDepth - Most of the inheritance comes from -// Vaadin. -@SuppressWarnings({ "squid:MaximumInheritanceDepth" }) -public class MyUI extends AbstractHawkbitUI { - private static final long serialVersionUID = 1L; - - @Autowired - MyUI(final EventPushStrategy pushStrategy, final UIEventBus eventBus, final UIEventProvider eventProvider, - final SpringViewProvider viewProvider, final ApplicationContext context, final DashboardMenu dashboardMenu, - final ErrorView errorview, final NotificationUnreadButton notificationUnreadButton, - final UiProperties uiProperties, final VaadinMessageSource i18n, final ErrorHandler uiErrorHandler) { - super(pushStrategy, eventBus, eventProvider, viewProvider, context, dashboardMenu, errorview, - notificationUnreadButton, uiProperties, i18n, uiErrorHandler); - } - -} diff --git a/hawkbit-starters/hawkbit-boot-starter-mgmt-ui/README.md b/hawkbit-starters/hawkbit-boot-starter-mgmt-ui/README.md deleted file mode 100644 index 3cf04beca1..0000000000 --- a/hawkbit-starters/hawkbit-boot-starter-mgmt-ui/README.md +++ /dev/null @@ -1 +0,0 @@ -[Spring Boot Starter](http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-starter) for the [Management UI](https://www.eclipse.org/hawkbit/documentation/interfaces/management-ui.html). \ No newline at end of file diff --git a/hawkbit-starters/hawkbit-boot-starter-mgmt-ui/pom.xml b/hawkbit-starters/hawkbit-boot-starter-mgmt-ui/pom.xml deleted file mode 100644 index 093162cb3e..0000000000 --- a/hawkbit-starters/hawkbit-boot-starter-mgmt-ui/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - 4.0.0 - - org.eclipse.hawkbit - hawkbit-starters - ${revision} - - hawkbit-boot-starter-mgmt-ui - hawkBit :: Spring Boot Starter Management UI - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter - - - org.springframework.security - spring-security-web - - - org.springframework.security - spring-security-config - - - org.springframework.security - spring-security-aspects - - - - - - org.eclipse.hawkbit - hawkbit-ui - ${project.version} - - - org.eclipse.hawkbit - hawkbit-http-security - ${project.version} - - - org.eclipse.hawkbit - hawkbit-repository-jpa - ${project.version} - - - org.eclipse.hawkbit - hawkbit-autoconfigure - ${project.version} - - - - - \ No newline at end of file diff --git a/hawkbit-starters/hawkbit-boot-starter/pom.xml b/hawkbit-starters/hawkbit-boot-starter/pom.xml index bf87d82713..66c12f9d1e 100644 --- a/hawkbit-starters/hawkbit-boot-starter/pom.xml +++ b/hawkbit-starters/hawkbit-boot-starter/pom.xml @@ -37,11 +37,5 @@ hawkbit-boot-starter-mgmt-api ${project.version} - - org.eclipse.hawkbit - hawkbit-boot-starter-mgmt-ui - ${project.version} - - \ No newline at end of file diff --git a/hawkbit-starters/pom.xml b/hawkbit-starters/pom.xml index 5d763c14ef..45e7ef3041 100644 --- a/hawkbit-starters/pom.xml +++ b/hawkbit-starters/pom.xml @@ -22,10 +22,8 @@ pom hawkbit-boot-starter - hawkbit-boot-starter-mgmt-ui hawkbit-boot-starter-mgmt-api hawkbit-boot-starter-ddi-api hawkbit-boot-starter-dmf-api - \ No newline at end of file diff --git a/hawkbit-test-report/pom.xml b/hawkbit-test-report/pom.xml index 331cf3719d..7d6e27d8a6 100644 --- a/hawkbit-test-report/pom.xml +++ b/hawkbit-test-report/pom.xml @@ -66,11 +66,6 @@ hawkbit-autoconfigure ${project.version} - - org.eclipse.hawkbit - hawkbit-ui - ${project.version} - org.eclipse.hawkbit hawkbit-ddi-api diff --git a/hawkbit-ui/.gitignore b/hawkbit-ui/.gitignore deleted file mode 100644 index 81311d80e7..0000000000 --- a/hawkbit-ui/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/database/ diff --git a/hawkbit-ui/README.md b/hawkbit-ui/README.md deleted file mode 100644 index 9c6470db68..0000000000 --- a/hawkbit-ui/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# hawkBit User Interface - -The hawkBit user interface is based on the Vaadin and Vaadin-Spring framework and allows to manage software updates and large scale roll-outs via a user interface. - -## Debugging client-side code -### Debug using SuperDevMode -The SuperDevMode can be used to debug client side code without any browser plugin. - -#### Using SuperDevMode with chrome : - -- Add required maven dependencies - - Add vaadin-client-compiler dependency -- Set redirect property in the AppWidgetSet.gwt.xml module descriptor as follows - - < set-configuration-property name="devModeRedirectEnabled" value="true" /> -- Create launch configuration for the SuperDevMode - - The main class to execute should be com.google.gwt.dev.codeserver.CodeServer. - - Add fully-qualified class name of widgetset (org.eclipse.hawkbit.ui.AppWidgetSet) as parameter -- Enable debug in chrome - - Chrome inspector window ▸ Click on settings icon ▸ Scripts ▸ Enable source maps option -- Run the SuperDevMode Code Server with the launch configuration created above -- Open http://localhost:8080/UI/?debug .Click on "SuperDev" button in debug console (Alternatively can directly add ?superdevmode parameter to URL) -- Widgetset is compiled and you can see the java code files loaded in 'Chrome inspector window ▸ Source tab' - - -#### Using SuperDevMode with Eclipse : - -- Install the plugin from http://sdbg.github.io/p2 -- Start the server and Super Dev Mode as mentioned above -- Create a new launch configuration in Eclipse - - Type is "Launch Chrome" - - http://localhost:8080/UI/?superdevmode -- Launch the new configuration in debug mode -- Now breakpoints in eclipse can be set diff --git a/hawkbit-ui/pom.xml b/hawkbit-ui/pom.xml deleted file mode 100644 index 041fb38337..0000000000 --- a/hawkbit-ui/pom.xml +++ /dev/null @@ -1,243 +0,0 @@ - - - 4.0.0 - - org.eclipse.hawkbit - hawkbit-parent - ${revision} - - hawkbit-ui - hawkBit :: Mgmt UI - Bosch IoT Software Provisioning server web application - - - - com.vaadin - vaadin-maven-plugin - ${vaadin.plugin.version} - - -Xmx2g -Xss1024k - - src/main/resources/VAADIN/widgetsets - src/main/resources/VAADIN/widgetsets - src/main/resources - true - - false - ${project.build.directory}/gwtdirt - true - - true - - ${project.build.directory}/gwt-deploy - - - - process-classes - - - - - resources - update-theme - update-widgetset - compile-theme - compile - - - - - - org.apache.maven.plugins - maven-antrun-plugin - - - process-classes - - - - - - - - - - run - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - - org.codehaus.mojo - - - properties-maven-plugin - - - [1.0-alpha-2,) - - - - write-project-properties - - - - - - - - - - com.vaadin - vaadin-maven-plugin - [7.7.3,) - - compile-theme - - - - - - - - - org.apache.maven.plugins - maven-antrun-plugin - [1.7,) - - run - - - - - - - - - - - - - - - - - org.eclipse.hawkbit - hawkbit-repository-api - ${project.version} - - - org.eclipse.hawkbit - hawkbit-http-security - ${project.version} - - - org.eclipse.hawkbit - hawkbit-autoconfigure - ${project.version} - - - commons-io - commons-io - - - - com.vaadin - vaadin-spring-boot - - - org.vaadin.spring.addons - vaadin-spring-addon-eventbus - - - org.vaadin.spring.extensions - vaadin-spring-ext-security - - - com.vaadin - vaadin-server - - - com.vaadin - vaadin-client - - - com.vaadin - vaadin-push - - - org.springframework.security - spring-security-web - - - com.vaadin - vaadin-themes - - - org.vaadin.alump.distributionbar - dbar-addon - - - com.github.gwtd3 - gwt-d3-api - - - com.google.guava - guava - - - org.apache.commons - commons-lang3 - - - com.cronutils - cron-utils - - - com.github.ben-manes.caffeine - caffeine - - - - - org.eclipse.hawkbit - hawkbit-repository-jpa - ${project.version} - test - - - org.springframework.boot - spring-boot-starter-test - test - - - io.qameta.allure - allure-junit5 - test - - - diff --git a/hawkbit-ui/src/main/.gitignore b/hawkbit-ui/src/main/.gitignore deleted file mode 100644 index 263ecccb6a..0000000000 --- a/hawkbit-ui/src/main/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/webapp/ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AbstractHawkbitUI.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AbstractHawkbitUI.java deleted file mode 100644 index ca5d124988..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AbstractHawkbitUI.java +++ /dev/null @@ -1,271 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui; - -import com.vaadin.shared.ui.ContentMode; -import org.eclipse.hawkbit.ui.components.NotificationUnreadButton; -import org.eclipse.hawkbit.ui.error.ErrorView; -import org.eclipse.hawkbit.ui.menu.DashboardEvent.PostViewChangeEvent; -import org.eclipse.hawkbit.ui.menu.DashboardMenu; -import org.eclipse.hawkbit.ui.menu.DashboardMenuItem; -import org.eclipse.hawkbit.ui.push.EventPushStrategy; -import org.eclipse.hawkbit.ui.push.UIEventProvider; -import org.eclipse.hawkbit.ui.themes.HawkbitTheme; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationListener; -import org.springframework.context.support.AbstractApplicationContext; -import org.springframework.util.ObjectUtils; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.annotations.Theme; -import com.vaadin.annotations.Title; -import com.vaadin.annotations.Widgetset; -import com.vaadin.navigator.Navigator; -import com.vaadin.navigator.View; -import com.vaadin.navigator.ViewChangeListener; -import com.vaadin.navigator.ViewProvider; -import com.vaadin.server.ClientConnector.DetachListener; -import com.vaadin.server.ErrorHandler; -import com.vaadin.server.Responsive; -import com.vaadin.server.VaadinRequest; -import com.vaadin.spring.navigator.SpringViewProvider; -import com.vaadin.ui.Alignment; -import com.vaadin.ui.Component; -import com.vaadin.ui.CssLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.Panel; -import com.vaadin.ui.UI; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Vaadin management UI. - * - */ -@Title("hawkBit Update Server") -@Widgetset(value = HawkbitTheme.WIDGET_SET_NAME) -@Theme(HawkbitTheme.THEME_NAME) -public abstract class AbstractHawkbitUI extends UI implements DetachListener { - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(AbstractHawkbitUI.class); - - private static final String EMPTY_VIEW = ""; - - private final VaadinMessageSource i18n; - private final UiProperties uiProperties; - - private Label viewTitle; - - private final DashboardMenu dashboardMenu; - private final ErrorView errorview; - private final NotificationUnreadButton notificationUnreadButton; - - private final SpringViewProvider viewProvider; - private final transient ApplicationContext context; - private final transient EventPushStrategy pushStrategy; - private final transient ErrorHandler uiErrorHandler; - - private final transient HawkbitEntityEventListener entityEventsListener; - - protected AbstractHawkbitUI(final EventPushStrategy pushStrategy, final UIEventBus eventBus, - final UIEventProvider eventProvider, final SpringViewProvider viewProvider, - final ApplicationContext context, final DashboardMenu dashboardMenu, final ErrorView errorview, - final NotificationUnreadButton notificationUnreadButton, final UiProperties uiProperties, - final VaadinMessageSource i18n, final ErrorHandler uiErrorHandler) { - this.pushStrategy = pushStrategy; - this.viewProvider = viewProvider; - this.context = context; - this.dashboardMenu = dashboardMenu; - this.errorview = errorview; - this.notificationUnreadButton = notificationUnreadButton; - this.uiProperties = uiProperties; - this.i18n = i18n; - this.uiErrorHandler = uiErrorHandler; - - this.entityEventsListener = new HawkbitEntityEventListener(eventBus, eventProvider, notificationUnreadButton); - } - - @Override - public void detach(final DetachEvent event) { - LOG.debug("ManagementUI is detached uiid - {}", getUIId()); - - entityEventsListener.unsubscribeListeners(); - - if (pushStrategy != null) { - pushStrategy.clean(); - clearContextListener(); - } - } - - private void clearContextListener() { - if (pushStrategy instanceof ApplicationListener && context instanceof AbstractApplicationContext) { - final ApplicationListener listener = (ApplicationListener) pushStrategy; - ((AbstractApplicationContext) context).getApplicationListeners().remove(listener); - - // we do not need to explicitly remove the listener from - // ApplicationEventMulticaster because it is done by - // UIBeanStore#destroy delegating to - // ApplicationListenerDetector#postProcessBeforeDestruction - } - } - - @Override - protected void init(final VaadinRequest vaadinRequest) { - LOG.debug("ManagementUI init starts uiid - {}", getUI().getUIId()); - if (pushStrategy != null) { - pushStrategy.init(getUI()); - } - addDetachListener(this); - - Responsive.makeResponsive(this); - addStyleName(ValoTheme.UI_WITH_MENU); - setResponsive(Boolean.TRUE); - - final HorizontalLayout rootLayout = new HorizontalLayout(); - rootLayout.setMargin(false); - rootLayout.setSpacing(false); - rootLayout.setSizeFull(); - - HawkbitCommonUtil.initLocalization(this, uiProperties.getLocalization(), i18n); - SPDateTimeUtil.initializeFixedTimeZoneProperty(uiProperties.getFixedTimeZone()); - - dashboardMenu.init(); - dashboardMenu.setResponsive(true); - - final VerticalLayout contentVerticalLayout = new VerticalLayout(); - contentVerticalLayout.setMargin(false); - contentVerticalLayout.setSpacing(false); - contentVerticalLayout.setSizeFull(); - contentVerticalLayout.setStyleName("main-content"); - contentVerticalLayout.addComponent(buildHeader()); - contentVerticalLayout.addComponent(buildViewTitle()); - - final Panel content = buildContent(); - contentVerticalLayout.addComponent(content); - contentVerticalLayout.setExpandRatio(content, 1.0F); - - String footerNotification = uiProperties.getNotification().getText(); - if (!ObjectUtils.isEmpty(footerNotification)) { - contentVerticalLayout.addComponent(buildFooterNotification(footerNotification)); - } - - rootLayout.addComponent(dashboardMenu); - rootLayout.addComponent(contentVerticalLayout); - rootLayout.setExpandRatio(contentVerticalLayout, 1.0F); - setContent(rootLayout); - - final Navigator navigator = new Navigator(this, content); - navigator.addViewChangeListener(new ViewChangeListener() { - private static final long serialVersionUID = 1L; - - @Override - public boolean beforeViewChange(final ViewChangeEvent event) { - return true; - } - - @Override - public void afterViewChange(final ViewChangeEvent event) { - final DashboardMenuItem view = dashboardMenu.getByViewName(event.getViewName()); - dashboardMenu.postViewChange(new PostViewChangeEvent(view)); - if (view == null) { - viewTitle.setCaption(null); - return; - } - viewTitle.setCaption(view.getDashboardCaptionLong()); - } - }); - - navigator.setErrorView(errorview); - navigator.addView(EMPTY_VIEW, new Navigator.EmptyView()); - navigator.addProvider(new ManagementViewProvider()); - setNavigator(navigator); - - if (UI.getCurrent().getErrorHandler() == null) { - UI.getCurrent().setErrorHandler(uiErrorHandler); - } - - LOG.debug("Current locale of the application is : {}", getLocale()); - } - - private static Component buildFooterNotification(String text) { - Label notification = new Label(); - notification.setValue(text); - notification.setWidth("100%"); - notification.setContentMode(ContentMode.HTML); - return notification; - } - - private static Panel buildContent() { - final Panel content = new Panel(); - content.setSizeFull(); - content.setStyleName("view-content"); - return content; - } - - private HorizontalLayout buildViewTitle() { - final HorizontalLayout viewHeadercontent = new HorizontalLayout(); - viewHeadercontent.setMargin(false); - viewHeadercontent.setSpacing(false); - viewHeadercontent.setWidth("100%"); - viewHeadercontent.addStyleName("view-header-layout"); - - viewTitle = new Label(); - viewTitle.setWidth("100%"); - viewTitle.setStyleName("header-content"); - viewHeadercontent.addComponent(viewTitle); - - viewHeadercontent.addComponent(notificationUnreadButton); - viewHeadercontent.setComponentAlignment(notificationUnreadButton, Alignment.MIDDLE_RIGHT); - return viewHeadercontent; - } - - private static Component buildHeader() { - final CssLayout cssLayout = new CssLayout(); - cssLayout.setStyleName("view-header"); - return cssLayout; - } - - private class ManagementViewProvider implements ViewProvider { - private static final long serialVersionUID = 1L; - - private static final String DEFAULT_PARAMETER_SEPARATOR = "/"; - - @Override - public String getViewName(final String viewAndParameters) { - final int paramsDelimeterIndex = viewAndParameters.indexOf(DEFAULT_PARAMETER_SEPARATOR); - final String viewName = paramsDelimeterIndex != -1 ? viewAndParameters.substring(0, paramsDelimeterIndex) - : viewAndParameters; - return viewProvider.getViewName(getStartView(viewName)); - } - - @Override - public View getView(final String viewName) { - return viewProvider.getView(viewName); - } - - private String getStartView(final String viewName) { - final DashboardMenuItem view = dashboardMenu.getByViewName(viewName); - if ("".equals(viewName) && !dashboardMenu.isAccessibleViewsEmpty()) { - return dashboardMenu.getInitialViewName(); - } - if (view == null || dashboardMenu.isAccessDenied(viewName)) { - return " "; - } - return viewName; - } - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml deleted file mode 100644 index 429501bd66..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEntityEventListener.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEntityEventListener.java deleted file mode 100644 index b3009af4c6..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEntityEventListener.java +++ /dev/null @@ -1,177 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui; - -import static java.util.concurrent.TimeUnit.SECONDS; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayloadIdentifier; -import org.eclipse.hawkbit.ui.common.event.EventTopics; -import org.eclipse.hawkbit.ui.components.NotificationUnreadButton; -import org.eclipse.hawkbit.ui.push.UIEventProvider; -import org.springframework.util.CollectionUtils; -import org.vaadin.spring.events.Event; -import org.vaadin.spring.events.EventBus.UIEventBus; -import org.vaadin.spring.events.EventBusListenerMethodFilter; -import org.vaadin.spring.events.EventScope; -import org.vaadin.spring.events.annotation.EventBusListenerMethod; - -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; -import com.vaadin.ui.UI; - -/** - * Listener for internal and remote entity modified events. Keeps a cache of the - * events coming from UI in order to suppress the corresponding remote events. - */ -public class HawkbitEntityEventListener { - private final UIEventBus eventBus; - private final UIEventProvider eventProvider; - private final NotificationUnreadButton notificationUnreadButton; - - private final Cache> uiOriginatedEventsCache; - private final List eventListeners; - - HawkbitEntityEventListener(final UIEventBus eventBus, final UIEventProvider eventProvider, - final NotificationUnreadButton notificationUnreadButton) { - this.eventBus = eventBus; - this.eventProvider = eventProvider; - this.notificationUnreadButton = notificationUnreadButton; - - this.uiOriginatedEventsCache = Caffeine.newBuilder().expireAfterWrite(10, SECONDS).build(); - - this.eventListeners = new ArrayList<>(); - registerEventListeners(); - } - - private void registerEventListeners() { - eventListeners.add(new EntityModifiedListener()); - eventListeners.add(new RemoteEventListener()); - } - - private class EntityModifiedListener { - - /** - * Constructor for EntityModifiedListener - */ - public EntityModifiedListener() { - eventBus.subscribe(this, EventTopics.ENTITY_MODIFIED); - } - - @EventBusListenerMethod(scope = EventScope.UI, filter = IgnoreRemoteEventsFilter.class) - private void onEntityModifiedEvent(final EntityModifiedEventPayload eventPayload) { - // parentId is ignored here because entityIds should be unique - uiOriginatedEventsCache.asMap().merge(EntityModifiedEventPayloadIdentifier.of(eventPayload), - eventPayload.getEntityIds(), (oldEntityIds, newEntityIds) -> Stream - .concat(oldEntityIds.stream(), newEntityIds.stream()).collect(Collectors.toList())); - } - } - - /** - * Ignore remote events filter - */ - public static class IgnoreRemoteEventsFilter implements EventBusListenerMethodFilter { - - @Override - public boolean filter(final Event event) { - return !event.getSource().equals(UI.getCurrent()); - } - } - - private class RemoteEventListener { - - /** - * Constructor for RemoteEventListener - */ - public RemoteEventListener() { - eventBus.subscribe(this, EventTopics.REMOTE_EVENT_RECEIVED); - } - - @EventBusListenerMethod(scope = EventScope.UI) - private void onRemoteEventReceived(final EntityModifiedEventPayload eventPayload) { - if (eventPayload.getEntityType() == null || eventPayload.getEntityModifiedEventType() == null - || CollectionUtils.isEmpty(eventPayload.getEntityIds())) { - return; - } - - getEventPayloadIdentifierFromProvider(eventPayload).ifPresent(eventPayloadIdentifier -> { - final Collection remotelyModifiedEntityIds = getRemotelyModifiedEntityIds(eventPayloadIdentifier, - eventPayload.getEntityIds()); - - if (!remotelyModifiedEntityIds.isEmpty()) { - final EntityModifiedEventPayload remoteEventPayload = EntityModifiedEventPayload - .of(eventPayloadIdentifier, eventPayload.getParentId(), remotelyModifiedEntityIds); - - if (eventPayloadIdentifier.shouldBeDeffered()) { - notificationUnreadButton.incrementUnreadNotification( - eventPayloadIdentifier.getNotificationType(), remoteEventPayload); - } else { - eventBus.publish(EventTopics.ENTITY_MODIFIED, UI.getCurrent(), remoteEventPayload); - } - } - }); - } - - private Optional getEventPayloadIdentifierFromProvider( - final EntityModifiedEventPayload eventPayload) { - return eventProvider.getEvents().values().stream().filter(providedIdentifier -> providedIdentifier - .equals(EntityModifiedEventPayloadIdentifier.of(eventPayload))).findAny(); - } - - private Collection getRemotelyModifiedEntityIds( - final EntityModifiedEventPayloadIdentifier eventPayloadIdentifier, - final Collection remoteEventEntityIds) { - final Collection cachedEventEntityIds = uiOriginatedEventsCache.getIfPresent(eventPayloadIdentifier); - - if (CollectionUtils.isEmpty(cachedEventEntityIds)) { - return remoteEventEntityIds; - } - - final Collection commonEntityIds = getCommonEntityIds(cachedEventEntityIds, remoteEventEntityIds); - if (!commonEntityIds.isEmpty()) { - updateCache(eventPayloadIdentifier, cachedEventEntityIds, commonEntityIds); - remoteEventEntityIds.removeAll(commonEntityIds); - } - - return remoteEventEntityIds; - } - - private Collection getCommonEntityIds(final Collection cachedEventEntityIds, - final Collection remoteEventEntityIds) { - final List commonEntityIds = new ArrayList<>(cachedEventEntityIds); - commonEntityIds.retainAll(remoteEventEntityIds); - - return commonEntityIds; - } - - private void updateCache(final EntityModifiedEventPayloadIdentifier eventPayloadIdentifier, - final Collection cachedEventEntityIds, final Collection commonEntityIds) { - final List updatedCachedEventEntityIds = new ArrayList<>(cachedEventEntityIds); - updatedCachedEventEntityIds.removeAll(commonEntityIds); - - if (updatedCachedEventEntityIds.isEmpty()) { - uiOriginatedEventsCache.invalidate(eventPayloadIdentifier); - } else { - uiOriginatedEventsCache.put(eventPayloadIdentifier, updatedCachedEventEntityIds); - } - } - } - - void unsubscribeListeners() { - eventListeners.forEach(eventBus::unsubscribe); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/LocalizedSystemMessagesProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/LocalizedSystemMessagesProvider.java deleted file mode 100644 index 2c2ff96b45..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/LocalizedSystemMessagesProvider.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui; - -import java.util.Locale; - -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; - -import com.vaadin.server.CustomizedSystemMessages; -import com.vaadin.server.SystemMessages; -import com.vaadin.server.SystemMessagesInfo; -import com.vaadin.server.SystemMessagesProvider; - -/** - * {@link SystemMessagesProvider} that localizes Vaadin system messages. - * - */ -public class LocalizedSystemMessagesProvider implements SystemMessagesProvider { - private static final long serialVersionUID = 1L; - - private final VaadinMessageSource i18n; - private final UiProperties uiProperties; - - /** - * Constructor for LocalizedSystemMessagesProvider - * - * @param uiProperties - * Properties to determine the available Locales - * @param i18n - * Message source used for localization - */ - public LocalizedSystemMessagesProvider(final UiProperties uiProperties, final VaadinMessageSource i18n) { - this.i18n = i18n; - this.uiProperties = uiProperties; - } - - private SystemMessages getLocalizedSystemMessages(final VaadinMessageSource i18n, final Locale local) { - final CustomizedSystemMessages messages = new CustomizedSystemMessages(); - final Locale desiredLocale = HawkbitCommonUtil.getLocaleToBeUsed(uiProperties.getLocalization(), local); - - messages.setSessionExpiredCaption( - i18n.getMessage(desiredLocale, UIMessageIdProvider.VAADIN_SYSTEM_SESSIONEXPIRED_CAPTION)); - messages.setSessionExpiredMessage( - i18n.getMessage(desiredLocale, UIMessageIdProvider.VAADIN_SYSTEM_SESSIONEXPIRED_MESSAGE)); - messages.setCommunicationErrorCaption( - i18n.getMessage(desiredLocale, UIMessageIdProvider.VAADIN_SYSTEM_COMMUNICATIONERROR_CAPTION)); - messages.setCommunicationErrorMessage( - i18n.getMessage(desiredLocale, UIMessageIdProvider.VAADIN_SYSTEM_COMMUNICATIONERROR_MESSAGE)); - messages.setInternalErrorCaption( - i18n.getMessage(desiredLocale, UIMessageIdProvider.VAADIN_SYSTEM_INTERNALERROR_CAPTION)); - messages.setInternalErrorMessage( - i18n.getMessage(desiredLocale, UIMessageIdProvider.VAADIN_SYSTEM_INTERNALERROR_MESSAGE)); - - return messages; - } - - @Override - public SystemMessages getSystemMessages(final SystemMessagesInfo systemMessagesInfo) { - return getLocalizedSystemMessages(i18n, systemMessagesInfo.getLocale()); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/MgmtUiConfiguration.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/MgmtUiConfiguration.java deleted file mode 100644 index 2167985af0..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/MgmtUiConfiguration.java +++ /dev/null @@ -1,267 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui; - -import java.util.List; - -import org.eclipse.hawkbit.im.authentication.PermissionService; -import org.eclipse.hawkbit.repository.TargetManagement; -import org.eclipse.hawkbit.ui.common.data.mappers.TargetToProxyTargetMapper; -import org.eclipse.hawkbit.ui.common.data.suppliers.TargetFilterStateDataSupplier; -import org.eclipse.hawkbit.ui.common.data.suppliers.TargetFilterStateDataSupplierImpl; -import org.eclipse.hawkbit.ui.common.data.suppliers.TargetManagementStateDataSupplier; -import org.eclipse.hawkbit.ui.common.data.suppliers.TargetManagementStateDataSupplierImpl; -import org.eclipse.hawkbit.ui.error.HawkbitUIErrorHandler; -import org.eclipse.hawkbit.ui.error.extractors.ArtifactEncryptionErrorExtractor; -import org.eclipse.hawkbit.ui.error.extractors.ConstraintViolationErrorExtractor; -import org.eclipse.hawkbit.ui.error.extractors.EntityNotFoundErrorExtractor; -import org.eclipse.hawkbit.ui.error.extractors.IncompatibleTargetTypeErrorExtractor; -import org.eclipse.hawkbit.ui.error.extractors.InsufficientPermissionErrorExtractor; -import org.eclipse.hawkbit.ui.error.extractors.InvalidDistributionSetErrorExtractor; -import org.eclipse.hawkbit.ui.error.extractors.AssignmentQuotaExceededErrorExtractor; -import org.eclipse.hawkbit.ui.error.extractors.UiErrorDetailsExtractor; -import org.eclipse.hawkbit.ui.error.extractors.UploadErrorExtractor; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.MessageSource; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.vaadin.spring.servlet.Vaadin4SpringServlet; - -import com.vaadin.server.ErrorHandler; -import com.vaadin.server.SystemMessagesProvider; -import com.vaadin.server.VaadinServlet; -import com.vaadin.spring.annotation.UIScope; - -/** - * Enables UI components for the Management UI. - * - */ -@Configuration -@ComponentScan -@EnableConfigurationProperties(UiProperties.class) -@PropertySource("classpath:/hawkbit-ui-defaults.properties") -public class MgmtUiConfiguration { - - /** - * Permission checker for UI. - * - * @param permissionService - * PermissionService - * - * @return Permission checker for UI - */ - @Bean - @ConditionalOnMissingBean - SpPermissionChecker spPermissionChecker(final PermissionService permissionService) { - return new SpPermissionChecker(permissionService); - } - - /** - * Utility for Vaadin messages source. - * - * @param source - * Delegate MessageSource - * - * @return Vaadin messages source utility - */ - @Bean - @ConditionalOnMissingBean - VaadinMessageSource messageSourceVaadin(final MessageSource source) { - return new VaadinMessageSource(source); - } - - /** - * Localized system message provider bean. - * - * @param uiProperties - * UiProperties - * @param i18n - * VaadinMessageSource - * - * @return Localized system message provider - */ - @Bean - @ConditionalOnMissingBean - SystemMessagesProvider systemMessagesProvider(final UiProperties uiProperties, final VaadinMessageSource i18n) { - return new LocalizedSystemMessagesProvider(uiProperties, i18n); - } - - /** - * UI Error handler bean. - * - * @param i18n - * VaadinMessageSource - * @param uiErrorDetailsExtractor - * ui error details extractors - * - * @return UI Error handler - */ - @Bean - @ConditionalOnMissingBean - ErrorHandler uiErrorHandler(final VaadinMessageSource i18n, - final List uiErrorDetailsExtractors) { - return new HawkbitUIErrorHandler(i18n, uiErrorDetailsExtractors); - } - - /** - * UI Upload Error details extractor bean. - * - * @return UI Upload Error details extractor - */ - @Bean - UiErrorDetailsExtractor uploadErrorExtractor() { - return new UploadErrorExtractor(); - } - - /** - * UI ConstraintViolation Error details extractor bean. - * - * @param i18n - * VaadinMessageSource - * @return UI ConstraintViolation Error details extractor - */ - @Bean - UiErrorDetailsExtractor constraintViolationErrorExtractor(final VaadinMessageSource i18n) { - return new ConstraintViolationErrorExtractor(i18n); - } - - /** - * UI Entity not found Error details extractor bean. - * - * @param i18n - * VaadinMessageSource - * @return UI EntityNotFound Error details extractor - */ - @Bean - UiErrorDetailsExtractor entityNotFoundErrorExtractor(final VaadinMessageSource i18n) { - return new EntityNotFoundErrorExtractor(i18n); - } - - /** - * UI incompatible Target Type error details extractor bean. - * - * @param i18n - * VaadinMessageSource - * @return UI IncompatibleTargetType Error details extractor - */ - @Bean - UiErrorDetailsExtractor incompatibleTargetTypeErrorExtractor(final VaadinMessageSource i18n) { - return new IncompatibleTargetTypeErrorExtractor(i18n); - } - - /** - * UI Insufficient Permission Error details extractor bean. - * - * @param i18n - * VaadinMessageSource - * @return UI InsufficientPermission Error details extractor - */ - @Bean - UiErrorDetailsExtractor insufficientPermissionErrorExtractor(final VaadinMessageSource i18n) { - return new InsufficientPermissionErrorExtractor(i18n); - } - - /** - * Details extractor bean for action not possible because of distribution - * set is invalid. - * - * @param i18n - * VaadinMessageSource - * @return UI invalid distributionset Error details extractor - */ - @Bean - UiErrorDetailsExtractor invalidDistributionSetErrorExtractor(final VaadinMessageSource i18n) { - return new InvalidDistributionSetErrorExtractor(i18n); - } - - /** - * UI Artifact ecnryption operations Error details extractor bean. - * - * @param i18n - * VaadinMessageSource - * @return UI Artifact ecnryption operations Error details extractor - */ - @Bean - UiErrorDetailsExtractor artifactEncryptionErrorExtractor(final VaadinMessageSource i18n) { - return new ArtifactEncryptionErrorExtractor(i18n); - } - - /** - * UI Assignment Quota exceeded Error details extractor bean. - * - * @param i18n - * VaadinMessageSource - * @return UI Assignment Quota exceeded Error details extractor - */ - @Bean - UiErrorDetailsExtractor assignmentQuotaExceededErrorExtractor(final VaadinMessageSource i18n) { - return new AssignmentQuotaExceededErrorExtractor(i18n); - } - - /** - * Vaadin4Spring servlet bean. - * - * @return Vaadin servlet for Spring - */ - @Bean - public VaadinServlet vaadinServlet() { - return new Vaadin4SpringServlet(); - } - - /** - * UI target entity mapper bean. - * - * @param i18n - * VaadinMessageSource - * @return UI target entity mapper - */ - @Bean - public TargetToProxyTargetMapper targetToProxyTargetMapper(final VaadinMessageSource i18n) { - return new TargetToProxyTargetMapper(i18n); - } - - /** - * UI Management target data supplier bean. - * - * @param targetManagement - * TargetManagement - * @param targetToProxyTargetMapper - * UI target entity mapper - * @return UI target data supplier for Management view - */ - @Bean - @ConditionalOnMissingBean - @UIScope - public TargetManagementStateDataSupplier targetManagementStateDataSupplier(final TargetManagement targetManagement, - final TargetToProxyTargetMapper targetToProxyTargetMapper) { - return new TargetManagementStateDataSupplierImpl(targetManagement, targetToProxyTargetMapper); - } - - /** - * UI Filter target data supplier bean. - * - * @param targetManagement - * TargetManagement - * @param targetToProxyTargetMapper - * UI target entity mapper - * @return UI target data supplier for Filter view - */ - @Bean - @ConditionalOnMissingBean - @UIScope - public TargetFilterStateDataSupplier targetFilterStateDataSupplier(final TargetManagement targetManagement, - final TargetToProxyTargetMapper targetToProxyTargetMapper) { - return new TargetFilterStateDataSupplierImpl(targetManagement, targetToProxyTargetMapper); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/SpPermissionChecker.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/SpPermissionChecker.java deleted file mode 100644 index 2316212d65..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/SpPermissionChecker.java +++ /dev/null @@ -1,190 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui; - -import java.io.Serializable; - -import org.eclipse.hawkbit.im.authentication.PermissionService; -import org.eclipse.hawkbit.im.authentication.SpPermission; - -/** - * Bean which contains all permissions. - * - */ -public class SpPermissionChecker implements Serializable { - private static final long serialVersionUID = 1L; - - protected transient PermissionService permissionService; - - protected SpPermissionChecker(final PermissionService permissionService) { - this.permissionService = permissionService; - } - - /** - * Gets the read Target and repository Permission. - * - * @return TARGET_REPOSITORY_READ boolean value - */ - public boolean hasTargetAndRepositoryReadPermission() { - return hasTargetReadPermission() && hasReadRepositoryPermission(); - } - - /** - * Gets the read Target Permission. - * - * @return READ_TARGET boolean value - */ - public boolean hasTargetReadPermission() { - return permissionService.hasPermission(SpPermission.READ_TARGET); - } - - /** - * Gets the create Target Permission. - * - * @return READ_TARGET boolean value - */ - public boolean hasCreateTargetPermission() { - return hasTargetReadPermission() && permissionService.hasPermission(SpPermission.CREATE_TARGET); - } - - /** - * Gets the update Target Permission. - * - * @return READ_TARGET boolean value - */ - public boolean hasUpdateTargetPermission() { - return hasTargetReadPermission() && permissionService.hasPermission(SpPermission.UPDATE_TARGET); - } - - /** - * Gets the delete Target Permission. - * - * @return READ_TARGET boolean value - */ - public boolean hasDeleteTargetPermission() { - return hasTargetReadPermission() && permissionService.hasPermission(SpPermission.DELETE_TARGET); - } - - /** - * Gets the READ Repository Permission. - * - * @return READ_REPOSITORY boolean value - */ - public boolean hasReadRepositoryPermission() { - return permissionService.hasPermission(SpPermission.READ_REPOSITORY); - } - - /** - * Has the download Repository Artifact Permission. - * - * @return DOWNLOAD_REPOSITORY_ARTIFACT boolean value - */ - public boolean hasDownloadRepositoryPermission() { - return permissionService.hasPermission(SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT); - } - - /** - * Gets the create Repository Permission. - * - * @return CREATE_REPOSITORY boolean value - */ - public boolean hasCreateRepositoryPermission() { - return hasReadRepositoryPermission() && permissionService.hasPermission(SpPermission.CREATE_REPOSITORY); - } - - /** - * Gets the update Repository Permission. - * - * @return UPDATE_REPOSITORY boolean value - */ - public boolean hasUpdateRepositoryPermission() { - return hasReadRepositoryPermission() && permissionService.hasPermission(SpPermission.UPDATE_REPOSITORY); - } - - /** - * Has the delete Repository Permission. - * - * @return DELETE_REPOSITORY boolean value - */ - public boolean hasDeleteRepositoryPermission() { - return hasReadRepositoryPermission() && permissionService.hasPermission(SpPermission.DELETE_REPOSITORY); - } - - /** - * Has the rollout update permission. - * - * @return permission for rollout update - */ - public boolean hasRolloutUpdatePermission() { - return hasRolloutReadPermission() && permissionService.hasPermission(SpPermission.UPDATE_ROLLOUT); - } - - /** - * @return true if rollout create permission - */ - public boolean hasRolloutCreatePermission() { - return hasTargetReadPermission() && hasReadRepositoryPermission() - && permissionService.hasPermission(SpPermission.CREATE_ROLLOUT); - } - - /** - * @return true if rollout read permission - */ - public boolean hasRolloutReadPermission() { - return permissionService.hasPermission(SpPermission.READ_ROLLOUT); - } - - /** - * @return true if rollout delete permission - */ - public boolean hasRolloutDeletePermission() { - return hasRolloutReadPermission() && permissionService.hasPermission(SpPermission.DELETE_ROLLOUT); - } - - /** - * @return true if rollout handle permission. - */ - public boolean hasRolloutHandlePermission() { - return hasRolloutReadPermission() && permissionService.hasPermission(SpPermission.HANDLE_ROLLOUT); - } - - /** - * @return permission to read rollout targets - */ - public boolean hasRolloutTargetsReadPermission() { - return hasTargetReadPermission() && permissionService.hasPermission(SpPermission.READ_ROLLOUT); - } - - /** - * - * @return true if rollout can be approved by the user. - */ - public boolean hasRolloutApprovalPermission() { - return hasRolloutReadPermission() && permissionService.hasPermission(SpPermission.APPROVE_ROLLOUT); - } - - /** - * - * @return true if auto assignment can be added/updated to target filter - */ - public boolean hasAutoAssignmentUpdatePermission() { - return hasUpdateTargetPermission() && hasReadRepositoryPermission(); - } - - /** - * - * @return true if default invalidation of distribution set is - * allowed - */ - public boolean hasDistributionSetInvalidatePermission() { - return hasUpdateRepositoryPermission() && hasUpdateTargetPermission(); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java deleted file mode 100644 index 80e4d719fb..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java +++ /dev/null @@ -1,627 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui; - -import java.io.Serializable; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.TimeUnit; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Properties for Management UI customization. - * - */ -@ConfigurationProperties("hawkbit.server.ui") -public class UiProperties implements Serializable { - private static final long serialVersionUID = 1L; - - private boolean gravatar; - - private String fixedTimeZone; - - private final Localization localization = new Localization(); - - private final Links links = new Links(); - - private final Demo demo = new Demo(); - - private final Event event = new Event(); - - private final Notification notification = new Notification(); - - /** - * @return True if menu item has gravatar else false - */ - public boolean isGravatar() { - return gravatar; - } - - /** - * Sets the gravatar - * - * @param gravatar - * Menu icon - */ - public void setGravatar(final boolean gravatar) { - this.gravatar = gravatar; - } - - /** - * @return Fixed time zone if unknown then GMT - */ - public String getFixedTimeZone() { - return fixedTimeZone; - } - - /** - * Sets the fixed time zone - * - * @param fixedTimeZone - * Date time zone - */ - public void setFixedTimeZone(final String fixedTimeZone) { - this.fixedTimeZone = fixedTimeZone; - } - - /** - * Localization information - */ - public static class Localization implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * Default localization - */ - private Locale defaultLocal = Locale.ENGLISH; - - /** - * List of available localizations - */ - private List availableLocals = Collections.singletonList(Locale.ENGLISH); - - /** - * @return Default locale - */ - public Locale getDefaultLocal() { - return defaultLocal; - } - - /** - * @return List of available locale - */ - public List getAvailableLocals() { - return availableLocals; - } - - /** - * Sets the default locale - * - * @param defaultLocal - * Locale - */ - public void setDefaultLocal(final Locale defaultLocal) { - this.defaultLocal = defaultLocal; - } - - /** - * Sets the all available locale - * - * @param availableLocals - * List of locale - */ - public void setAvailableLocals(final List availableLocals) { - this.availableLocals = availableLocals; - } - } - - /** - * Demo account login information. - * - */ - public static class Demo implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * Demo tenant. - */ - private String tenant = ""; - /** - * Demo user name. - */ - private String user = ""; - - /** - * Demo user password. - */ - // Exception squid:S2068 - Empty password - @SuppressWarnings({ "squid:S2068" }) - private String password = ""; - - private String disclaimer = ""; - - /** - * @return password - */ - public String getPassword() { - return password; - } - - /** - * @return tenant - */ - public String getTenant() { - return tenant; - } - - /** - * @return username - */ - public String getUser() { - return user; - } - - /** - * Sets the login password - * - * @param password - * Password value - */ - public void setPassword(final String password) { - this.password = password; - } - - /** - * Sets the tenant - * - * @param tenant - * Tenant value - */ - public void setTenant(final String tenant) { - this.tenant = tenant; - } - - /** - * Sets the login user - * - * @param user - * username - */ - public void setUser(final String user) { - this.user = user; - } - - /** - * @return disclaimer - */ - public String getDisclaimer() { - return disclaimer; - } - - /** - * Sets the disclaimer - * - * @param disclaimer - * Disclaimer value - */ - public void setDisclaimer(final String disclaimer) { - this.disclaimer = disclaimer; - } - } - - /** - * Links to potentially other systems (e.g. support, user management, - * documentation etc.). - * - */ - public static class Links implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * Configuration of UI documentation links. - * - */ - public static class Documentation implements Serializable { - private static final long serialVersionUID = 1L; - /** - * Link to root of documentation and user guides. - */ - private String root = ""; - - /** - * Link to documentation of deployment view. - */ - private String deploymentView = ""; - - /** - * Link to documentation of distribution view. - */ - private String distributionView = ""; - - /** - * Link to documentation of upload view. - */ - private String uploadView = ""; - - /** - * Link to documentation of maintenance window view. - */ - private String maintenanceWindowView = ""; - - /** - * Link to documentation of the user consent and confirmation flow. - */ - private String userConsentAndConfirmationGuide = ""; - - public String getAutoConfirmationView() { - return autoConfirmationView; - } - - /** - * Link to documentation of system configuration view. - */ - private String systemConfigurationView = ""; - - /** - * Link to security related documentation. - */ - private String security = ""; - - /** - * Link to rollout related documentation. - */ - private String rollout = ""; - - /** - * Link to target filter view. - */ - private String targetfilterView = ""; - - /** - * Link to documentation of rollout view. - */ - private String rolloutView = ""; - - /** - * Link to documentation of auto confirmation view. - */ - private String autoConfirmationView = ""; - - /** - * Link to documentation of state machine - */ - private String provisioningStateMachine = ""; - - /** - * Link to documentation of distribution set invalidation - */ - private String distributionSetInvalidation = ""; - - /** - * @return Link to documentation of deployment view - */ - public String getDeploymentView() { - return deploymentView; - } - - public String getDistributionView() { - return distributionView; - } - - /** - * @return Link to documentation of rollout view - */ - public String getRolloutView() { - return rolloutView; - } - - /** - * @return Link to documentation of root - */ - public String getRoot() { - return root; - } - - /** - * @return Link to documentation of security - */ - public String getSecurity() { - return security; - } - - /** - * @return Link to documentation of rollout - */ - public String getRollout() { - return rollout; - } - - /** - * @return Link to documentation of system config - */ - public String getSystemConfigurationView() { - return systemConfigurationView; - } - - /** - * @return Link to documentation of target filter - */ - public String getTargetfilterView() { - return targetfilterView; - } - - public String getUploadView() { - return uploadView; - } - - /** - * @return Link to documentation of maintenance window - */ - public String getMaintenanceWindowView() { - return maintenanceWindowView; - } - - /** - * @return Link to documentation of the user consent and confirmation flow. - */ - public String getUserConsentAndConfirmationGuide() { - return userConsentAndConfirmationGuide; - } - - /** - * @return Link to documentation of provisioning state machine - */ - public String getProvisioningStateMachine() { - return provisioningStateMachine; - } - - /** - * @return Link to documentation of distribution set invalidation - */ - public String getDistributionSetInvalidation() { - return distributionSetInvalidation; - } - - public void setDeploymentView(final String deploymentView) { - this.deploymentView = deploymentView; - } - - public void setDistributionView(final String distributionView) { - this.distributionView = distributionView; - } - - public void setRolloutView(final String rolloutView) { - this.rolloutView = rolloutView; - } - - /** - * Sets the root documentation link - * - * @param root - * link - */ - public void setRoot(final String root) { - this.root = root; - } - - /** - * Sets the security documentation link - * - * @param security - * link - */ - public void setSecurity(final String security) { - this.security = security; - } - - /** - * Sets the rollout documentation link - * - * @param rollout - * link - */ - public void setRollout(final String rollout) { - this.rollout = rollout; - } - - public void setSystemConfigurationView(final String systemConfigurationView) { - this.systemConfigurationView = systemConfigurationView; - } - - public void setTargetfilterView(final String targetfilterView) { - this.targetfilterView = targetfilterView; - } - - public void setUploadView(final String uploadView) { - this.uploadView = uploadView; - } - - public void setMaintenanceWindowView(final String maintenanceWindowView) { - this.maintenanceWindowView = maintenanceWindowView; - } - - public void setUserConsentAndConfirmationGuide(final String userConsentAndConfirmationGuide) { - this.userConsentAndConfirmationGuide = userConsentAndConfirmationGuide; - } - - public void setProvisioningStateMachine(final String provisioningStateMachine) { - this.provisioningStateMachine = provisioningStateMachine; - } - - /** - * Sets the link to the distribution set invalidation documentation - * - * @param distributionSetInvalidation - * Link - */ - public void setDistributionSetInvalidation(String distributionSetInvalidation) { - this.distributionSetInvalidation = distributionSetInvalidation; - } - } - - private final Documentation documentation = new Documentation(); - - /** - * Link to product support. - */ - private String support = ""; - - /** - * Link to request a system account, access. - */ - private String requestAccount = ""; - - /** - * Link to user management. - */ - private String userManagement = ""; - - /** - * @return Link to documentation - */ - public Documentation getDocumentation() { - return documentation; - } - - /** - * @return Link to request a system account, access - */ - public String getRequestAccount() { - return requestAccount; - } - - /** - * @return Link to product support - */ - public String getSupport() { - return support; - } - - /** - * @return Link to user management - */ - public String getUserManagement() { - return userManagement; - } - - /** - * Sets the link to request a system account, access - * - * @param requestAccount - * Link - */ - public void setRequestAccount(final String requestAccount) { - this.requestAccount = requestAccount; - } - - /** - * Sets the link to product support - * - * @param support - * Link - */ - public void setSupport(final String support) { - this.support = support; - } - - /** - * Sets the link to user management - * - * @param userManagement - * Link - */ - public void setUserManagement(final String userManagement) { - this.userManagement = userManagement; - } - - } - - /** - * Configuration of the UI event bus. - */ - public static class Event implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * - * Configuration of the UI push. - * - */ - public static class Push implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * The delay for the ui event forwarding. - */ - private long delay = TimeUnit.SECONDS.toMillis(2); - - public long getDelay() { - return delay; - } - - public void setDelay(final long delay) { - this.delay = delay; - } - } - - private final Push push = new Push(); - - public Push getPush() { - return push; - } - } - - public static class Notification implements Serializable { - private String text = ""; - - public String getText() { - return text; - } - - public void setText(final String text) { - this.text = text; - } - } - - /** - * @return Demo account details - */ - public Demo getDemo() { - return demo; - } - - /** - * @return Document links - */ - public Links getLinks() { - return links; - } - - /** - * @return Events - */ - public Event getEvent() { - return event; - } - - /** - * @return Localization - */ - public Localization getLocalization() { - return localization; - } - - public Notification getNotification() { - return notification; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/ArtifactUploadState.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/ArtifactUploadState.java deleted file mode 100644 index 4fb6332ae0..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/ArtifactUploadState.java +++ /dev/null @@ -1,320 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts; - -import java.io.File; -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.io.FileUtils; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsGridLayoutUiState; -import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadId; -import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress; -import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus; -import org.eclipse.hawkbit.ui.common.state.GridLayoutUiState; -import org.eclipse.hawkbit.ui.common.state.TypeFilterLayoutUiState; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.StringUtils; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.vaadin.spring.annotation.SpringComponent; -import com.vaadin.spring.annotation.VaadinSessionScope; - -/** - * User status of Artifact upload. - */ -@VaadinSessionScope -@SpringComponent -public class ArtifactUploadState implements Serializable { - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(ArtifactUploadState.class); - - private final TypeFilterLayoutUiState smTypeFilterLayoutUiState; - private final GridLayoutUiState smGridLayoutUiState; - private final ArtifactDetailsGridLayoutUiState artifactDetailsGridLayoutUiState; - - private boolean statusPopupMinimized; - - /** - * Map that holds all files that were selected for upload. They remain in - * the list even if upload fails, succeeds or is aborted by the user. - */ - private Map overallFilesInUploadProcess; - - /** - * Constructor for ArtifactUploadState - */ - public ArtifactUploadState() { - this.smTypeFilterLayoutUiState = new TypeFilterLayoutUiState(); - this.smGridLayoutUiState = new GridLayoutUiState(); - this.artifactDetailsGridLayoutUiState = new ArtifactDetailsGridLayoutUiState(); - } - - /** - * Minimize or maximize the status popup view - * - * @param statusPopupMinimized - * boolean - */ - public void setStatusPopupMinimized(final boolean statusPopupMinimized) { - this.statusPopupMinimized = statusPopupMinimized; - } - - /** - * Checks if the status popup view is in minimized state - * - * @return boolean - */ - public boolean isStatusPopupMinimized() { - return statusPopupMinimized; - } - - /** - * Get the Software module type filter UI state - * - * @return TypeFilterLayoutUiState - */ - public TypeFilterLayoutUiState getSmTypeFilterLayoutUiState() { - return smTypeFilterLayoutUiState; - } - - /** - * Get the Software module grid UI state - * - * @return GridLayoutUiState - */ - public GridLayoutUiState getSmGridLayoutUiState() { - return smGridLayoutUiState; - } - - /** - * Get the Artifact details grid UI state - * - * @return ArtifactDetailsGridLayoutUiState - */ - public ArtifactDetailsGridLayoutUiState getArtifactDetailsGridLayoutUiState() { - return artifactDetailsGridLayoutUiState; - } - - /** - * Remove all the files from the upload process list - * - * @param filesToRemove - * Collection of fie upload ID - */ - public void removeFilesFromOverallUploadProcessList(final Collection filesToRemove) { - getOverallFilesInUploadProcessMap().keySet().removeAll(filesToRemove); - } - - /** - * Get all the IDs of uploaded files from the upload process - * - * @return List of IDs of uploaded files - */ - public Set getAllFileUploadIdsFromOverallUploadProcessList() { - return Collections.unmodifiableSet(getOverallFilesInUploadProcessMap().keySet()); - } - - /** - * Get file upload progress values from process list - * - * @return List of FileUploadProgress - */ - public Collection getAllFileUploadProgressValuesFromOverallUploadProcessList() { - return Collections.unmodifiableCollection(getOverallFilesInUploadProcessMap().values()); - } - - /** - * Get all the IDs of files from the failed upload - * - * @return List of IDs of uploaded files - */ - public Set getFilesInFailedState() { - return Collections.unmodifiableSet(getFailedUploads()); - } - - /** - * Get upload progress of the file - * - * @param fileUploadId - * FileUploadId - * - * @return FileUploadProgress - */ - public FileUploadProgress getFileUploadProgress(final FileUploadId fileUploadId) { - return getOverallFilesInUploadProcessMap().get(fileUploadId); - } - - /** - * Get all files that were selected for upload - * - * @param fileUploadId - * FileUploadId - * @param fileUploadProgress - * FileUploadProgress - */ - public void updateFileUploadProgress(final FileUploadId fileUploadId, final FileUploadProgress fileUploadProgress) { - getOverallFilesInUploadProcessMap().put(fileUploadId, fileUploadProgress); - } - - /** - * Check upload state of the file - * - * @param fileUploadId - * FileUploadId - * - * @return boolean - */ - public boolean isFileInUploadState(final FileUploadId fileUploadId) { - return getOverallFilesInUploadProcessMap().containsKey(fileUploadId); - } - - /** - * Check upload state of the file link to the related software module - * - * @param filename - * Name of the file - * - * @param softwareModule - * the {@link SoftwareModule} for which the file is uploaded - * - * @return boolean - */ - public boolean isFileInUploadState(final String filename, final SoftwareModule softwareModule) { - return isFileInUploadState(new FileUploadId(filename, softwareModule)); - } - - /** - * Check if at least one file upload is in progress - * - * @return boolean - */ - public boolean isAtLeastOneUploadInProgress() { - return getInProgressCount() > 0; - } - - /** - * Check if all file uploads are finished - * - * @return boolean - */ - public boolean areAllUploadsFinished() { - return getInProgressCount() == 0; - } - - private int getInProgressCount() { - final int succeededUploadCount = getSucceededUploads().size(); - final int failedUploadCount = getFailedUploads().size(); - final int overallUploadCount = getOverallFilesInUploadProcessMap().size(); - - final int inProgressCount = overallUploadCount - failedUploadCount - succeededUploadCount; - - assertFileStateConsistency(inProgressCount, overallUploadCount, succeededUploadCount, failedUploadCount); - - return inProgressCount; - } - - @SuppressWarnings("java:S2629") // error shall be enable almost every time and evaluation is light - private static void assertFileStateConsistency(final int inProgressCount, final int overallUploadCount, - final int succeededUploadCount, final int failedUploadCount) { - if (inProgressCount < 0) { - LOG.error("IllegalState: \n{}", - getStateListLogMessage(overallUploadCount, succeededUploadCount, failedUploadCount)); - } - } - - private static String getStateListLogMessage(final int overallUploadCount, final int succeededUploadCount, - final int failedUploadCount) { - final StringBuilder buffer = new StringBuilder(); - buffer.append("Overall uploads: " + overallUploadCount); - buffer.append("| succeeded uploads: " + succeededUploadCount); - buffer.append("| Failed Uploads: " + failedUploadCount); - return buffer.toString(); - } - - /** - * Removes all of the data from this Upload process collection - */ - public void clearFileStates() { - getOverallFilesInUploadProcessMap().clear(); - } - - /** - * Clears all temp data collected while uploading files. - */ - public void clearUploadTempData() { - LOG.debug("Cleaning up temp data..."); - // delete file system zombies - for (final FileUploadProgress fileUploadProgress : getAllFileUploadProgressValuesFromOverallUploadProcessList()) { - if (StringUtils.hasText(fileUploadProgress.getFilePath())) { - final boolean deleted = FileUtils.deleteQuietly(new File(fileUploadProgress.getFilePath())); - if (!deleted) { - LOG.warn("TempFile was not deleted: {}", fileUploadProgress.getFilePath()); - } - } - } - clearFileStates(); - } - - /** - * Checks if an upload is in progress for the given Software Module - * - * @param softwareModuleId - * id of the software module - * - * @return boolean - */ - public boolean isUploadInProgressForSelectedSoftwareModule(final Long softwareModuleId) { - for (final FileUploadId fileUploadId : getAllFileUploadIdsFromOverallUploadProcessList()) { - if (fileUploadId.getSoftwareModuleId().equals(softwareModuleId)) { - return true; - } - } - return false; - } - - private Map getOverallFilesInUploadProcessMap() { - if (overallFilesInUploadProcess == null) { - overallFilesInUploadProcess = Maps.newConcurrentMap(); - } - return overallFilesInUploadProcess; - } - - private Set getFailedUploads() { - final Collection allFileUploadProgressObjects = getOverallFilesInUploadProcessMap() - .values(); - final Set failedFileUploads = Sets.newHashSet(); - for (final FileUploadProgress fileUploadProgress : allFileUploadProgressObjects) { - if (fileUploadProgress.getFileUploadStatus() == FileUploadStatus.UPLOAD_FAILED) { - failedFileUploads.add(fileUploadProgress.getFileUploadId()); - } - } - return failedFileUploads; - } - - private Set getSucceededUploads() { - final Collection allFileUploadProgressObjects = getOverallFilesInUploadProcessMap() - .values(); - final Set succeededFileUploads = Sets.newHashSet(); - for (final FileUploadProgress fileUploadProgress : allFileUploadProgressObjects) { - if (fileUploadProgress.getFileUploadStatus() == FileUploadStatus.UPLOAD_SUCCESSFUL) { - succeededFileUploads.add(fileUploadProgress.getFileUploadId()); - } - } - return succeededFileUploads; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java deleted file mode 100644 index 7af5f7302c..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java +++ /dev/null @@ -1,335 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts; - -import static org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus.UPLOAD_STARTED; - -import java.util.Arrays; -import java.util.EnumMap; -import java.util.Map; - -import javax.servlet.MultipartConfigElement; - -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.AbstractHawkbitUI; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsGridLayout; -import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleGridLayout; -import org.eclipse.hawkbit.ui.artifacts.smtype.filter.SMTypeFilterLayout; -import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress; -import org.eclipse.hawkbit.ui.common.AbstractEventListenersAwareView; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.ConfirmationDialog; -import org.eclipse.hawkbit.ui.common.event.EventLayout; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.common.event.EventViewAware; -import org.eclipse.hawkbit.ui.common.layout.listener.LayoutResizeListener; -import org.eclipse.hawkbit.ui.common.layout.listener.LayoutResizeListener.ResizeHandler; -import org.eclipse.hawkbit.ui.common.layout.listener.LayoutVisibilityListener; -import org.eclipse.hawkbit.ui.common.layout.listener.LayoutVisibilityListener.VisibilityHandler; -import org.eclipse.hawkbit.ui.menu.DashboardEvent; -import org.eclipse.hawkbit.ui.menu.DashboardMenu; -import org.eclipse.hawkbit.ui.menu.DashboardMenuItem; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.navigator.ViewBeforeLeaveEvent; -import com.vaadin.server.Page; -import com.vaadin.server.Page.BrowserWindowResizeEvent; -import com.vaadin.server.Page.BrowserWindowResizeListener; -import com.vaadin.spring.annotation.SpringView; -import com.vaadin.spring.annotation.UIScope; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.UI; - -/** - * Display artifacts upload view. - */ -@UIScope -@SpringView(name = UploadArtifactView.VIEW_NAME, ui = AbstractHawkbitUI.class) -public class UploadArtifactView extends AbstractEventListenersAwareView implements BrowserWindowResizeListener { - private static final long serialVersionUID = 1L; - - public static final String VIEW_NAME = "spUpload"; - - private final SpPermissionChecker permChecker; - private final ArtifactUploadState artifactUploadState; - - private final SMTypeFilterLayout smTypeFilterLayout; - private final SoftwareModuleGridLayout smGridLayout; - private final ArtifactDetailsGridLayout artifactDetailsGridLayout; - private final VaadinMessageSource i18n; - private final DashboardMenu dashboardMenu; - - private HorizontalLayout mainLayout; - - private final transient LayoutVisibilityListener layoutVisibilityListener; - private final transient LayoutResizeListener layoutResizeListener; - - @Autowired - UploadArtifactView(final UIEventBus eventBus, final SpPermissionChecker permChecker, final VaadinMessageSource i18n, - final UINotification uiNotification, final ArtifactUploadState artifactUploadState, - final EntityFactory entityFactory, final SoftwareModuleManagement softwareModuleManagement, - final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final MultipartConfigElement multipartConfigElement, final ArtifactManagement artifactManagement, - final DashboardMenu dashboardMenu) { - this.permChecker = permChecker; - this.artifactUploadState = artifactUploadState; - this.i18n = i18n; - this.dashboardMenu = dashboardMenu; - - final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus, - uiNotification, permChecker); - - if (permChecker.hasReadRepositoryPermission()) { - this.smTypeFilterLayout = new SMTypeFilterLayout(uiDependencies, softwareModuleTypeManagement, - artifactUploadState.getSmTypeFilterLayoutUiState(), EventView.UPLOAD); - this.smGridLayout = new SoftwareModuleGridLayout(uiDependencies, softwareModuleManagement, - softwareModuleTypeManagement, artifactUploadState.getSmTypeFilterLayoutUiState(), - artifactUploadState.getSmGridLayoutUiState()); - this.artifactDetailsGridLayout = new ArtifactDetailsGridLayout(uiDependencies, artifactUploadState, - artifactUploadState.getArtifactDetailsGridLayoutUiState(), artifactManagement, - softwareModuleManagement, multipartConfigElement); - - addEventAwareLayouts(Arrays.asList(smTypeFilterLayout, smGridLayout, artifactDetailsGridLayout)); - - final Map layoutVisibilityHandlers = new EnumMap<>(EventLayout.class); - layoutVisibilityHandlers.put(EventLayout.SM_TYPE_FILTER, - new VisibilityHandler(this::showSmTypeLayout, this::hideSmTypeLayout)); - this.layoutVisibilityListener = new LayoutVisibilityListener(eventBus, new EventViewAware(EventView.UPLOAD), - layoutVisibilityHandlers); - - final Map layoutResizeHandlers = new EnumMap<>(EventLayout.class); - layoutResizeHandlers.put(EventLayout.SM_LIST, - new ResizeHandler(this::maximizeSmGridLayout, this::minimizeSmGridLayout)); - layoutResizeHandlers.put(EventLayout.ARTIFACT_LIST, - new ResizeHandler(this::maximizeArtifactGridLayout, this::minimizeArtifactGridLayout)); - this.layoutResizeListener = new LayoutResizeListener(eventBus, new EventViewAware(EventView.UPLOAD), - layoutResizeHandlers); - } else { - this.smTypeFilterLayout = null; - this.smGridLayout = null; - this.artifactDetailsGridLayout = null; - this.layoutVisibilityListener = null; - this.layoutResizeListener = null; - } - } - - @Override - protected void init() { - if (permChecker.hasReadRepositoryPermission()) { - super.init(); - Page.getCurrent().addBrowserWindowResizeListener(this); - } - } - - @Override - protected void buildLayout() { - setMargin(false); - setSpacing(false); - setSizeFull(); - - createMainLayout(); - - addComponent(mainLayout); - setExpandRatio(mainLayout, 1.0F); - } - - private void createMainLayout() { - mainLayout = new HorizontalLayout(); - mainLayout.setSizeFull(); - mainLayout.setMargin(false); - mainLayout.setSpacing(true); - - mainLayout.addComponent(smTypeFilterLayout); - mainLayout.addComponent(smGridLayout); - mainLayout.addComponent(artifactDetailsGridLayout); - - mainLayout.setExpandRatio(smTypeFilterLayout, 0F); - mainLayout.setExpandRatio(smGridLayout, 0.5F); - mainLayout.setExpandRatio(artifactDetailsGridLayout, 0.5F); - } - - @Override - protected void restoreState() { - if (permChecker.hasReadRepositoryPermission()) { - restoreSmWidgetsState(); - restoreArtifactWidgetsState(); - } - - super.restoreState(); - } - - private void restoreSmWidgetsState() { - if (artifactUploadState.getSmTypeFilterLayoutUiState().isHidden() - || artifactUploadState.getArtifactDetailsGridLayoutUiState().isMaximized()) { - hideSmTypeLayout(); - } else { - showSmTypeLayout(); - } - - if (artifactUploadState.getSmGridLayoutUiState().isMaximized()) { - maximizeSmGridLayout(); - } - } - - private void restoreArtifactWidgetsState() { - if (artifactUploadState.getArtifactDetailsGridLayoutUiState().isMaximized()) { - maximizeArtifactGridLayout(); - } - } - - private void showSmTypeLayout() { - smTypeFilterLayout.setVisible(true); - smGridLayout.hideSmTypeHeaderIcon(); - } - - private void hideSmTypeLayout() { - smTypeFilterLayout.setVisible(false); - smGridLayout.showSmTypeHeaderIcon(); - } - - private void maximizeSmGridLayout() { - artifactDetailsGridLayout.setVisible(false); - - mainLayout.setExpandRatio(smTypeFilterLayout, 0F); - mainLayout.setExpandRatio(smGridLayout, 1.0F); - mainLayout.setExpandRatio(artifactDetailsGridLayout, 0F); - - smGridLayout.maximize(); - } - - private void minimizeSmGridLayout() { - artifactDetailsGridLayout.setVisible(true); - - mainLayout.setExpandRatio(smTypeFilterLayout, 0F); - mainLayout.setExpandRatio(smGridLayout, 0.5F); - mainLayout.setExpandRatio(artifactDetailsGridLayout, 0.5F); - - smGridLayout.minimize(); - } - - private void maximizeArtifactGridLayout() { - smTypeFilterLayout.setVisible(false); - smGridLayout.setVisible(false); - - mainLayout.setExpandRatio(smTypeFilterLayout, 0F); - mainLayout.setExpandRatio(smGridLayout, 0F); - mainLayout.setExpandRatio(artifactDetailsGridLayout, 1.0F); - - artifactDetailsGridLayout.maximize(); - } - - private void minimizeArtifactGridLayout() { - if (!artifactUploadState.getSmTypeFilterLayoutUiState().isHidden()) { - smTypeFilterLayout.setVisible(true); - } - smGridLayout.setVisible(true); - - mainLayout.setExpandRatio(smTypeFilterLayout, 0F); - mainLayout.setExpandRatio(smGridLayout, 0.5F); - mainLayout.setExpandRatio(artifactDetailsGridLayout, 0.5F); - - artifactDetailsGridLayout.minimize(); - } - - /** - * Show or hide the filter button based on the event width - * - * @param event - * BrowserWindowResizeEvent - */ - @Override - public void browserWindowResized(final BrowserWindowResizeEvent event) { - showOrHideFilterButtons(event.getWidth()); - } - - private void showOrHideFilterButtons(final int browserWidth) { - if (artifactUploadState.getArtifactDetailsGridLayoutUiState().isMaximized()) { - return; - } - - if (browserWidth < SPUIDefinitions.REQ_MIN_BROWSER_WIDTH) { - if (!artifactUploadState.getSmTypeFilterLayoutUiState().isHidden()) { - hideSmTypeLayout(); - } - } else { - if (artifactUploadState.getSmTypeFilterLayoutUiState().isHidden()) { - showSmTypeLayout(); - } - } - } - - @Override - public String getViewName() { - return UploadArtifactView.VIEW_NAME; - } - - @Override - protected void subscribeListeners() { - if (permChecker.hasReadRepositoryPermission()) { - layoutVisibilityListener.subscribe(); - layoutResizeListener.subscribe(); - } - - super.subscribeListeners(); - } - - @Override - protected void unsubscribeListeners() { - if (permChecker.hasReadRepositoryPermission()) { - layoutVisibilityListener.unsubscribe(); - layoutResizeListener.unsubscribe(); - } - - super.unsubscribeListeners(); - } - - @Override - public void beforeLeave(final ViewBeforeLeaveEvent event) { - if (isAnyUploadInUploadQueue()) { - final ConfirmationDialog confirmDeleteDialog = ConfirmationDialog - .newBuilder(i18n, UIComponentIdProvider.UPLOAD_QUEUE_CLEAR_CONFIRMATION_DIALOG) - .caption(i18n.getMessage(UIMessageIdProvider.CAPTION_CLEAR_FILE_UPLOAD_QUEUE)) - .question(i18n.getMessage(UIMessageIdProvider.MESSAGE_CLEAR_FILE_UPLOAD_QUEUE)) - .onSaveOrUpdate(() -> { - // Clear all queued file uploads - artifactUploadState.clearFileStates(); - super.beforeLeave(event); - }).onCancel(() -> { - // Send a PostViewChangeEvent to the DashboardMenu - // as if the navigation actually - // happened to prevent the DashboardMenu navigation - // from getting stuck - final DashboardMenuItem dashboardMenuItem = dashboardMenu.getByViewName(VIEW_NAME); - dashboardMenu.postViewChange(DashboardEvent.createPostViewChangeEvent(dashboardMenuItem)); - }).build(); - UI.getCurrent().addWindow(confirmDeleteDialog.getWindow()); - confirmDeleteDialog.getWindow().bringToFront(); - } else { - super.beforeLeave(event); - } - } - - private boolean isAnyUploadInUploadQueue() { - return artifactUploadState.getAllFileUploadProgressValuesFromOverallUploadProcessList().stream() - .map(FileUploadProgress::getFileUploadStatus) - .anyMatch(fileUploadStatus -> fileUploadStatus == UPLOAD_STARTED); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactViewMenuItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactViewMenuItem.java deleted file mode 100644 index 6ba56c5fa5..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactViewMenuItem.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.ui.menu.AbstractDashboardMenuItemNotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.annotation.Order; - -import com.vaadin.icons.VaadinIcons; -import com.vaadin.server.Resource; -import com.vaadin.spring.annotation.SpringComponent; -import com.vaadin.spring.annotation.UIScope; - -/** - * Display artifacts upload view menu item. - * - * - */ -@SpringComponent -@UIScope -@Order(500) -public class UploadArtifactViewMenuItem extends AbstractDashboardMenuItemNotification { - private static final long serialVersionUID = 1L; - - @Autowired - UploadArtifactViewMenuItem(final VaadinMessageSource i18n) { - super(i18n); - } - - @Override - public String getViewName() { - return UploadArtifactView.VIEW_NAME; - } - - @Override - public Resource getDashboardIcon() { - return VaadinIcons.UPLOAD; - } - - @Override - public String getDashboardCaption() { - return i18n.getMessage("dashboard.upload.caption"); - } - - @Override - public String getDashboardCaptionLong() { - return i18n.getMessage("dashboard.upload.caption-long"); - } - - @Override - public List getPermissions() { - return Arrays.asList(SpPermission.READ_REPOSITORY); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGrid.java deleted file mode 100644 index a0c6ad1023..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGrid.java +++ /dev/null @@ -1,252 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.details; - -import java.util.Arrays; -import java.util.Collection; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.artifact.repository.model.DbArtifact; -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.builder.GridComponentBuilder; -import org.eclipse.hawkbit.ui.common.data.mappers.ArtifactToProxyArtifactMapper; -import org.eclipse.hawkbit.ui.common.data.providers.ArtifactDataProvider; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyArtifact; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload.EntityModifiedEventType; -import org.eclipse.hawkbit.ui.common.event.EventTopics; -import org.eclipse.hawkbit.ui.common.event.FilterType; -import org.eclipse.hawkbit.ui.common.grid.AbstractGrid; -import org.eclipse.hawkbit.ui.common.grid.support.DeleteSupport; -import org.eclipse.hawkbit.ui.common.grid.support.FilterSupport; -import org.eclipse.hawkbit.ui.common.grid.support.MasterEntitySupport; -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.UINotification; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.vaadin.icons.VaadinIcons; -import com.vaadin.server.FileDownloader; -import com.vaadin.server.StreamResource; -import com.vaadin.ui.Button; -import com.vaadin.ui.UI; - -/** - * Artifact Details grid which is shown on the Upload View. - */ -public class ArtifactDetailsGrid extends AbstractGrid { - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(ArtifactDetailsGrid.class); - - private static final String ARTIFACT_NAME_ID = "artifactName"; - private static final String ARTIFACT_SIZE_ID = "artifactSize"; - private static final String ARTIFACT_MODIFIED_DATE_ID = "artifactModifiedDate"; - private static final String ARTIFACT_SHA1_ID = "artifactSha1"; - private static final String ARTIFACT_MD5_ID = "artifactMd5"; - private static final String ARTIFACT_SHA256_ID = "artifactSha256"; - private static final String ARTIFACT_DOWNLOAD_BUTTON_ID = "artifactDownloadButton"; - private static final String ARTIFACT_DELETE_BUTTON_ID = "artifactDeleteButton"; - - private final UINotification notification; - private final transient ArtifactManagement artifactManagement; - - private final transient DeleteSupport artifactDeleteSupport; - private final transient MasterEntitySupport masterEntitySupport; - - private boolean artifactsEncrypted; - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param artifactManagement - * ArtifactManagement - */ - public ArtifactDetailsGrid(final CommonUiDependencies uiDependencies, final ArtifactManagement artifactManagement) { - super(uiDependencies.getI18n(), uiDependencies.getEventBus(), uiDependencies.getPermChecker()); - - this.notification = uiDependencies.getUiNotification(); - this.artifactManagement = artifactManagement; - - this.artifactDeleteSupport = new DeleteSupport<>(this, i18n, notification, "artifact.details.header", - "caption.artifacts", ProxyArtifact::getFilename, this::artifactsDeletionCallback, - UIComponentIdProvider.ARTIFACT_DELETE_CONFIRMATION_DIALOG); - - setFilterSupport( - new FilterSupport<>(new ArtifactDataProvider(artifactManagement, new ArtifactToProxyArtifactMapper()))); - initFilterMappings(); - - this.masterEntitySupport = new MasterEntitySupport<>(getFilterSupport(), null, - sm -> artifactsEncrypted = sm != null && sm.isEncrypted()); - - init(); - } - - private void initFilterMappings() { - getFilterSupport(). addMapping(FilterType.MASTER, - (filter, masterFilter) -> getFilterSupport().setFilter(masterFilter)); - } - - /** - * Initial method of grid and set style name - */ - @Override - public void init() { - super.init(); - - addStyleName("grid-row-border"); - } - - private boolean artifactsDeletionCallback(final Collection artifactsToBeDeleted) { - final Collection artifactToBeDeletedIds = artifactsToBeDeleted.stream() - .map(ProxyIdentifiableEntity::getId).collect(Collectors.toList()); - artifactToBeDeletedIds.forEach(artifactManagement::delete); - - eventBus.publish(EventTopics.ENTITY_MODIFIED, this, new EntityModifiedEventPayload( - EntityModifiedEventType.ENTITY_UPDATED, ProxySoftwareModule.class, masterEntitySupport.getMasterId())); - - return true; - } - - /** - * @return ID for artifact details table - */ - @Override - public String getGridId() { - return UIComponentIdProvider.UPLOAD_ARTIFACT_DETAILS_TABLE; - } - - /** - * setting up the columns with their required definition - */ - @Override - public void addColumns() { - addFilenameColumn().setExpandRatio(2); - - addSizeColumn(); - - addModifiedDateColumn(); - - GridComponentBuilder.joinToActionColumn(i18n, getDefaultHeaderRow(), - Arrays.asList(addDownloadColumn(), addDeleteColumn())); - } - - private Column addFilenameColumn() { - return GridComponentBuilder.addColumn(this, ProxyArtifact::getFilename).setId(ARTIFACT_NAME_ID) - .setCaption(i18n.getMessage("artifact.filename.caption")); - } - - private Column addSizeColumn() { - return GridComponentBuilder.addColumn(this, ProxyArtifact::getSize).setId(ARTIFACT_SIZE_ID) - .setCaption(i18n.getMessage("artifact.filesize.bytes.caption")); - } - - protected Column addModifiedDateColumn() { - return GridComponentBuilder.addColumn(this, ProxyArtifact::getModifiedDate).setId(ARTIFACT_MODIFIED_DATE_ID) - .setCaption(i18n.getMessage("upload.last.modified.date")); - } - - private Column addDownloadColumn() { - return GridComponentBuilder.addIconColumn(this, this::buildDownloadButton, ARTIFACT_DOWNLOAD_BUTTON_ID, - i18n.getMessage("header.action.download")); - } - - private Button buildDownloadButton(final ProxyArtifact artifact) { - final Button downloadButton = GridComponentBuilder.buildActionButton(i18n, clickEvent -> { - }, VaadinIcons.DOWNLOAD, UIMessageIdProvider.TOOLTIP_ARTIFACT_DOWNLOAD, - SPUIStyleDefinitions.STATUS_ICON_NEUTRAL, - UIComponentIdProvider.ARTIFACT_FILE_DOWNLOAD_ICON + "." + artifact.getId(), - permissionChecker.hasDownloadRepositoryPermission()); - - attachFileDownloader(artifact, downloadButton); - - return downloadButton; - } - - private void attachFileDownloader(final ProxyArtifact artifact, final Button downloadButton) { - final StreamResource artifactStreamResource = new StreamResource(() -> artifactManagement - .loadArtifactBinary(artifact.getSha1Hash(), masterEntitySupport.getMasterId(), artifactsEncrypted) - .map(DbArtifact::getFileInputStream).orElse(null), artifact.getFilename()); - - final FileDownloader fileDownloader = new FileDownloader(artifactStreamResource); - fileDownloader.setErrorHandler(event -> { - LOG.error("Download failed for artifact with id {}, filename {}", artifact.getId(), artifact.getFilename(), - event.getThrowable()); - notification.displayValidationError(i18n.getMessage(UIMessageIdProvider.ARTIFACT_DOWNLOAD_FAILURE_MSG)); - UI.getCurrent().access(() -> { - // give error details extractors a chance to process specific - // error - throw new DownloadException(event.getThrowable()); - }); - }); - - fileDownloader.extend(downloadButton); - } - - private Column addDeleteColumn() { - return GridComponentBuilder.addDeleteColumn(this, i18n, ARTIFACT_DELETE_BUTTON_ID, artifactDeleteSupport, - UIComponentIdProvider.ARTIFACT_DELET_ICON, e -> permissionChecker.hasDeleteRepositoryPermission()); - } - - @Override - protected void addMaxColumns() { - addFilenameColumn().setExpandRatio(2); - - addSizeColumn(); - - addSha1Column(); - addMd5Column(); - addSha256Column(); - - addModifiedDateColumn(); - - GridComponentBuilder.joinToActionColumn(i18n, getDefaultHeaderRow(), - Arrays.asList(addDownloadColumn(), addDeleteColumn())); - - getColumns().forEach(column -> column.setHidable(true)); - } - - private Column addSha1Column() { - return GridComponentBuilder.addColumn(this, ProxyArtifact::getSha1Hash).setId(ARTIFACT_SHA1_ID) - .setCaption(i18n.getMessage("upload.sha1")); - } - - private Column addMd5Column() { - return GridComponentBuilder.addColumn(this, ProxyArtifact::getMd5Hash).setId(ARTIFACT_MD5_ID) - .setCaption(i18n.getMessage("upload.md5")); - } - - private Column addSha256Column() { - return GridComponentBuilder.addColumn(this, ProxyArtifact::getSha256Hash).setId(ARTIFACT_SHA256_ID) - .setCaption(i18n.getMessage("upload.sha256")); - } - - /** - * @return software module entity - */ - public MasterEntitySupport getMasterEntitySupport() { - return masterEntitySupport; - } - - private static class DownloadException extends RuntimeException { - private static final long serialVersionUID = 1L; - - public DownloadException(final Throwable cause) { - super(cause); - } - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGridHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGridHeader.java deleted file mode 100644 index fe90b5a98e..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGridHeader.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.details; - -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.event.CommandTopics; -import org.eclipse.hawkbit.ui.common.event.EventLayout; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.common.event.LayoutResizeEventPayload; -import org.eclipse.hawkbit.ui.common.event.LayoutResizeEventPayload.ResizeType; -import org.eclipse.hawkbit.ui.common.grid.header.AbstractMasterAwareGridHeader; -import org.eclipse.hawkbit.ui.common.grid.header.support.ResizeHeaderSupport; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider; - -/** - * Header for ArtifactDetails with maximize-support. - */ -public class ArtifactDetailsGridHeader extends AbstractMasterAwareGridHeader { - private static final long serialVersionUID = 1L; - - private final ArtifactDetailsGridLayoutUiState artifactDetailsGridLayoutUiState; - - private final transient ResizeHeaderSupport resizeHeaderSupport; - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param artifactDetailsGridLayoutUiState - * ArtifactDetailsGridLayoutUiState - */ - public ArtifactDetailsGridHeader(final CommonUiDependencies uiDependencies, - final ArtifactDetailsGridLayoutUiState artifactDetailsGridLayoutUiState) { - super(uiDependencies.getI18n(), uiDependencies.getPermChecker(), uiDependencies.getEventBus()); - - this.artifactDetailsGridLayoutUiState = artifactDetailsGridLayoutUiState; - - this.resizeHeaderSupport = new ResizeHeaderSupport(i18n, SPUIDefinitions.EXPAND_ARTIFACT_DETAILS, - this::maximizeTable, this::minimizeTable, this::onLoadIsTableMaximized); - addHeaderSupport(resizeHeaderSupport); - - buildHeader(); - } - - @Override - protected String getEntityDetailsCaptionMsgKey() { - return UIMessageIdProvider.CAPTION_ARTIFACT_DETAILS; - } - - @Override - protected String getMasterEntityDetailsCaptionId() { - return UIComponentIdProvider.ARTIFACT_DETAILS_HEADER_LABEL_ID; - } - - @Override - protected String getMasterEntityName(final ProxySoftwareModule masterEntity) { - return masterEntity.getNameAndVersion(); - } - - @Override - protected String getEntityDetailsCaptionOfMsgKey() { - return UIMessageIdProvider.CAPTION_ARTIFACT_DETAILS_OF; - } - - private void maximizeTable() { - eventBus.publish(CommandTopics.RESIZE_LAYOUT, this, - new LayoutResizeEventPayload(ResizeType.MAXIMIZE, EventLayout.ARTIFACT_LIST, EventView.UPLOAD)); - - artifactDetailsGridLayoutUiState.setMaximized(true); - } - - private void minimizeTable() { - eventBus.publish(CommandTopics.RESIZE_LAYOUT, this, - new LayoutResizeEventPayload(ResizeType.MINIMIZE, EventLayout.ARTIFACT_LIST, EventView.UPLOAD)); - - artifactDetailsGridLayoutUiState.setMaximized(false); - } - - private Boolean onLoadIsTableMaximized() { - return artifactDetailsGridLayoutUiState.isMaximized(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGridLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGridLayout.java deleted file mode 100644 index 64a73e322e..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGridLayout.java +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.details; - -import java.util.Arrays; -import java.util.List; - -import javax.servlet.MultipartConfigElement; - -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.ui.artifacts.ArtifactUploadState; -import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress; -import org.eclipse.hawkbit.ui.artifacts.upload.UploadDropAreaLayout; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.event.EventLayout; -import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware; -import org.eclipse.hawkbit.ui.common.event.EventTopics; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.common.layout.AbstractGridComponentLayout; -import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent; -import org.eclipse.hawkbit.ui.common.layout.listener.GenericEventListener; -import org.eclipse.hawkbit.ui.common.layout.listener.SelectionChangedListener; - -/** - * Display the details of the artifacts for a selected software module. - */ -public class ArtifactDetailsGridLayout extends AbstractGridComponentLayout { - private static final long serialVersionUID = 1L; - - private final ArtifactDetailsGridHeader artifactDetailsHeader; - private final ArtifactDetailsGrid artifactDetailsGrid; - private final UploadDropAreaLayout uploadDropAreaLayout; - - private final transient SelectionChangedListener selectionChangedListener; - private final transient GenericEventListener fileUploadChangedListener; - - /** - * Constructor for ArtifactDetailsLayout - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param artifactUploadState - * ArtifactUploadState - * @param artifactDetailsGridLayoutUiState - * ArtifactDetailsGridLayoutUiState - * @param artifactManagement - * ArtifactManagement - * @param softwareManagement - * SoftwareModuleManagement - * @param multipartConfigElement - * MultipartConfigElement - */ - public ArtifactDetailsGridLayout(final CommonUiDependencies uiDependencies, - final ArtifactUploadState artifactUploadState, - final ArtifactDetailsGridLayoutUiState artifactDetailsGridLayoutUiState, - final ArtifactManagement artifactManagement, final SoftwareModuleManagement softwareManagement, - final MultipartConfigElement multipartConfigElement) { - this.artifactDetailsHeader = new ArtifactDetailsGridHeader(uiDependencies, artifactDetailsGridLayoutUiState); - this.artifactDetailsGrid = new ArtifactDetailsGrid(uiDependencies, artifactManagement); - - if (uiDependencies.getPermChecker().hasCreateRepositoryPermission()) { - this.uploadDropAreaLayout = new UploadDropAreaLayout(uiDependencies, artifactUploadState, - multipartConfigElement, softwareManagement, artifactManagement); - - buildLayout(artifactDetailsHeader, artifactDetailsGrid, uploadDropAreaLayout); - } else { - this.uploadDropAreaLayout = null; - - buildLayout(artifactDetailsHeader, artifactDetailsGrid); - } - - final EventLayoutViewAware masterLayoutView = new EventLayoutViewAware(EventLayout.SM_LIST, EventView.UPLOAD); - this.selectionChangedListener = new SelectionChangedListener<>(uiDependencies.getEventBus(), masterLayoutView, - getMasterEntityAwareComponents()); - this.fileUploadChangedListener = new GenericEventListener<>(uiDependencies.getEventBus(), - EventTopics.FILE_UPLOAD_CHANGED, this::onUploadChanged); - } - - private List> getMasterEntityAwareComponents() { - return Arrays.asList(artifactDetailsHeader, artifactDetailsGrid.getMasterEntitySupport(), uploadDropAreaLayout); - } - - /** - * Checks progress on file upload - * - * @param fileUploadProgress - * FileUploadProgress - */ - public void onUploadChanged(final FileUploadProgress fileUploadProgress) { - if (uploadDropAreaLayout != null) { - uploadDropAreaLayout.onUploadChanged(fileUploadProgress); - } - } - - /** - * Maximize the artifact grid - */ - public void maximize() { - artifactDetailsGrid.createMaximizedContent(); - hideDetailsLayout(); - } - - /** - * Minimize the artifact grid - */ - public void minimize() { - artifactDetailsGrid.createMinimizedContent(); - showDetailsLayout(); - } - - @Override - public void restoreState() { - artifactDetailsHeader.restoreState(); - - if (uploadDropAreaLayout != null) { - uploadDropAreaLayout.restoreState(); - } - } - - @Override - public void subscribeListeners() { - selectionChangedListener.subscribe(); - fileUploadChangedListener.subscribe(); - } - - @Override - public void unsubscribeListeners() { - selectionChangedListener.unsubscribe(); - fileUploadChangedListener.unsubscribe(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGridLayoutUiState.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGridLayoutUiState.java deleted file mode 100644 index b92beab70f..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsGridLayoutUiState.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.details; - -import java.io.Serializable; - -/** - * Display and set the current state of the artifacts detail layout - * - */ -public class ArtifactDetailsGridLayoutUiState implements Serializable { - private static final long serialVersionUID = 1L; - - private boolean maximized; - - /** - * @return current state artifact detail grid - */ - public boolean isMaximized() { - return maximized; - } - - /** - * @param maximized set artifact detail grid to true or false - */ - public void setMaximized(final boolean maximized) { - this.maximized = maximized; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/AddSmWindowController.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/AddSmWindowController.java deleted file mode 100644 index 82da93aad2..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/AddSmWindowController.java +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import org.eclipse.hawkbit.repository.ArtifactEncryptionService; -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.builder.SoftwareModuleCreate; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.common.AbstractAddNamedEntityWindowController; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.EntityWindowLayout; -import org.eclipse.hawkbit.ui.common.data.mappers.SoftwareModuleToProxyMapper; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.event.EventLayout; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.common.event.SelectionChangedEventPayload; -import org.eclipse.hawkbit.ui.common.event.SelectionChangedEventPayload.SelectionChangedEventType; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; - -/** - * Controller for populating and saving data in Add Software Module Window. - */ -public class AddSmWindowController - extends AbstractAddNamedEntityWindowController { - - private final SoftwareModuleManagement smManagement; - private final SmWindowLayout layout; - private final EventView view; - private final ProxySmValidator validator; - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smManagement - * SoftwareModuleManagement - * @param layout - * SoftwareModuleWindowLayout - * @param view - * EventView - */ - public AddSmWindowController(final CommonUiDependencies uiDependencies, final SoftwareModuleManagement smManagement, - final SmWindowLayout layout, final EventView view) { - super(uiDependencies); - - this.smManagement = smManagement; - this.layout = layout; - this.view = view; - this.validator = new ProxySmValidator(uiDependencies); - } - - @Override - public EntityWindowLayout getLayout() { - return layout; - } - - @Override - protected void adaptLayout(final ProxySoftwareModule proxyEntity) { - if (!ArtifactEncryptionService.getInstance().isEncryptionSupported()) { - layout.disableEncryptionField(); - } - } - - @Override - protected ProxySoftwareModule buildEntityFromProxy(final ProxySoftwareModule proxyEntity) { - // We ignore the method parameter, because we are interested in the - // empty object, that we can populate with defaults - return new ProxySoftwareModule(); - } - - @Override - protected SoftwareModule persistEntityInRepository(final ProxySoftwareModule entity) { - final SoftwareModuleCreate smCreate = getEntityFactory().softwareModule().create() - .type(entity.getTypeInfo().getKey()).name(entity.getName()).version(entity.getVersion()) - .vendor(entity.getVendor()).description(entity.getDescription()).encrypted(entity.isEncrypted()); - - return smManagement.create(smCreate); - } - - @Override - protected String getDisplayableName(final SoftwareModule entity) { - return HawkbitCommonUtil.getFormattedNameVersion(entity.getName(), entity.getVersion()); - } - - @Override - protected String getDisplayableNameForFailedMessage(final ProxySoftwareModule entity) { - return HawkbitCommonUtil.getFormattedNameVersion(entity.getName(), entity.getVersion()); - } - - @Override - protected Class getEntityClass() { - return ProxySoftwareModule.class; - } - - @Override - protected void selectPersistedEntity(final SoftwareModule entity) { - final ProxySoftwareModule addedItem = new SoftwareModuleToProxyMapper().map(entity); - publishSelectionEvent(new SelectionChangedEventPayload<>(SelectionChangedEventType.ENTITY_SELECTED, addedItem, - EventLayout.SM_LIST, view)); - } - - @Override - protected boolean isEntityValid(final ProxySoftwareModule entity) { - final String name = entity.getName(); - final String version = entity.getVersion(); - final Long typeId = entity.getTypeInfo().getId(); - return validator.isEntityValid(entity, - () -> smManagement.getByNameAndVersionAndType(name, version, typeId).isPresent()); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/ProxySmValidator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/ProxySmValidator.java deleted file mode 100644 index 22f3cb6ee5..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/ProxySmValidator.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import java.util.function.BooleanSupplier; - -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.EntityValidator; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.springframework.util.StringUtils; - -/** - * Validator used in SoftwareModule window controllers to validate - * {@link ProxySoftwareModule}. - */ -public class ProxySmValidator extends EntityValidator { - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - */ - public ProxySmValidator(final CommonUiDependencies uiDependencies) { - super(uiDependencies); - } - - boolean isEntityValid(final ProxySoftwareModule entity, final BooleanSupplier duplicateCheck) { - if (!StringUtils.hasText(entity.getName()) || !StringUtils.hasText(entity.getVersion()) - || entity.getTypeInfo() == null) { - displayValidationError("message.error.missing.nameorversionortype"); - return false; - } - - if (duplicateCheck.getAsBoolean()) { - displayValidationError("message.duplicate.softwaremodule", entity.getName(), entity.getVersion()); - return false; - } - - return true; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmMetaDataAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmMetaDataAddUpdateWindowLayout.java deleted file mode 100644 index 0466564aa0..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmMetaDataAddUpdateWindowLayout.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import java.util.function.BooleanSupplier; - -import org.eclipse.hawkbit.ui.common.detailslayout.MetaDataAddUpdateWindowLayout; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; - -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.VerticalLayout; - -/** - * Class for sm metadata add/update window layout. - */ -public class SmMetaDataAddUpdateWindowLayout extends MetaDataAddUpdateWindowLayout { - protected final CheckBox isVisibleForTarget; - - /** - * Constructor for AbstractTagWindowLayout - * - * @param i18n - * VaadinMessageSource - * @param hasMetadataChangePermission - * checks the permission allowing to change metadata entities - */ - public SmMetaDataAddUpdateWindowLayout(final VaadinMessageSource i18n, - final BooleanSupplier hasMetadataChangePermission) { - super(i18n, hasMetadataChangePermission); - - this.isVisibleForTarget = metaDataComponentBuilder.createVisibleForTargetsField(binder); - } - - @Override - protected VerticalLayout getMetadataAddUpdateLayout() { - final VerticalLayout addUpdateLayout = super.getMetadataAddUpdateLayout(); - addUpdateLayout.addComponent(isVisibleForTarget); - - return addUpdateLayout; - } - - @Override - protected void disableMetadataInputComponents() { - super.disableMetadataInputComponents(); - isVisibleForTarget.setEnabled(false); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmMetaDataWindowBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmMetaDataWindowBuilder.java deleted file mode 100644 index caf4448ec2..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmMetaDataWindowBuilder.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyMetaData; -import org.eclipse.hawkbit.ui.common.detailslayout.AbstractMetaDataWindowBuilder; - -import com.vaadin.ui.Window; - -/** - * Builder for Software module meta data windows - */ -public class SmMetaDataWindowBuilder extends AbstractMetaDataWindowBuilder { - - private final SoftwareModuleManagement smManagement; - - /** - * Constructor for SmMetaDataWindowBuilder - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smManagement - * SoftwareModuleManagement - */ - public SmMetaDataWindowBuilder(final CommonUiDependencies uiDependencies, final SoftwareModuleManagement smManagement) { - super(uiDependencies); - - this.smManagement = smManagement; - } - - /** - * Get software module window without proxy meta data - * - * @param smId - * software module ID - * @param name - * Selected entity name - * - * @return software module window - */ - public Window getWindowForShowSmMetaData(final Long smId, final String name) { - return getWindowForShowSmMetaData(smId, name, null); - } - - /** - * Get software module window with proxy meta data - * - * @param smId - * software module ID - * @param name - * Selected entity name - * @param proxyMetaData - * ProxyMetaData - * - * @return software module window - */ - public Window getWindowForShowSmMetaData(final Long smId, final String name, final ProxyMetaData proxyMetaData) { - return getWindowForShowMetaData(new SmMetaDataWindowLayout(uiDependencies, smManagement), smId, name, proxyMetaData); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmMetaDataWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmMetaDataWindowLayout.java deleted file mode 100644 index 0e525f918f..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmMetaDataWindowLayout.java +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.model.MetaData; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.providers.SmMetaDataDataProvider; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyMetaData; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.detailslayout.AbstractMetaDataWindowLayout; -import org.eclipse.hawkbit.ui.common.detailslayout.AddMetaDataWindowController; -import org.eclipse.hawkbit.ui.common.detailslayout.MetaDataAddUpdateWindowLayout; -import org.eclipse.hawkbit.ui.common.detailslayout.MetaDataWindowGrid; -import org.eclipse.hawkbit.ui.common.detailslayout.UpdateMetaDataWindowController; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload.EntityModifiedEventType; -import org.eclipse.hawkbit.ui.common.event.EventTopics; - -/** - * Class for metadata add/update window layout. - */ -public class SmMetaDataWindowLayout extends AbstractMetaDataWindowLayout { - private static final long serialVersionUID = 1L; - - private final transient SoftwareModuleManagement smManagement; - - private final MetaDataWindowGrid smMetaDataWindowGrid; - - private final transient SmMetaDataAddUpdateWindowLayout smMetaDataAddUpdateWindowLayout; - private final transient AddMetaDataWindowController addSmMetaDataWindowController; - private final transient UpdateMetaDataWindowController updateSmMetaDataWindowController; - - /** - * Constructor for AbstractTagWindowLayout - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smManagement - * SoftwareModuleManagement - */ - public SmMetaDataWindowLayout(final CommonUiDependencies uiDependencies, - final SoftwareModuleManagement smManagement) { - super(uiDependencies); - - this.smManagement = smManagement; - - this.smMetaDataWindowGrid = new MetaDataWindowGrid<>(uiDependencies, new SmMetaDataDataProvider(smManagement), - this::hasMetadataChangePermission, this::deleteMetaData); - - this.smMetaDataAddUpdateWindowLayout = new SmMetaDataAddUpdateWindowLayout(i18n,this::hasMetadataChangePermission); - this.addSmMetaDataWindowController = new AddMetaDataWindowController(uiDependencies, - smMetaDataAddUpdateWindowLayout, this::createMetaData, this::isDuplicate); - this.updateSmMetaDataWindowController = new UpdateMetaDataWindowController(uiDependencies, - smMetaDataAddUpdateWindowLayout, this::updateMetaData, this::isDuplicate); - - buildLayout(); - addGridSelectionListener(); - } - - @Override - protected String getEntityType() { - return i18n.getMessage("caption.software.module"); - } - - @Override - protected MetaData doCreateMetaData(final ProxyMetaData entity) { - return smManagement - .createMetaData(uiDependencies.getEntityFactory().softwareModuleMetadata().create(masterEntityFilter) - .key(entity.getKey()).value(entity.getValue()).targetVisible(entity.isVisibleForTargets())); - } - - @Override - protected MetaData doUpdateMetaData(final ProxyMetaData entity) { - return smManagement.updateMetaData( - uiDependencies.getEntityFactory().softwareModuleMetadata().update(masterEntityFilter, entity.getKey()) - .value(entity.getValue()).targetVisible(entity.isVisibleForTargets())); - } - - @Override - protected void doDeleteMetaDataByKey(final String metaDataKey) { - smManagement.deleteMetaData(masterEntityFilter, metaDataKey); - } - - private boolean isDuplicate(final String metaDataKey) { - return smManagement.getMetaDataBySoftwareModuleId(masterEntityFilter, metaDataKey).isPresent(); - } - - @Override - protected MetaDataWindowGrid getMetaDataWindowGrid() { - return smMetaDataWindowGrid; - } - - /** - * @return add widow controller for software module - */ - @Override - public AddMetaDataWindowController getAddMetaDataWindowController() { - return addSmMetaDataWindowController; - } - - /** - * @return update widow controller for software module - */ - @Override - public UpdateMetaDataWindowController getUpdateMetaDataWindowController() { - return updateSmMetaDataWindowController; - } - - /** - * @return add and update widow layout for software module - */ - @Override - public MetaDataAddUpdateWindowLayout getMetaDataAddUpdateWindowLayout() { - return smMetaDataAddUpdateWindowLayout; - } - - @Override - protected void publishEntityModifiedEvent() { - eventBus.publish(EventTopics.ENTITY_MODIFIED, this, new EntityModifiedEventPayload( - EntityModifiedEventType.ENTITY_UPDATED, ProxySoftwareModule.class, masterEntityFilter)); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmWindowBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmWindowBuilder.java deleted file mode 100644 index 7ced71d04f..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmWindowBuilder.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.common.AbstractEntityWindowBuilder; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; - -import com.vaadin.ui.Window; - -/** - * Builder for Software module windows - */ -public class SmWindowBuilder extends AbstractEntityWindowBuilder { - - private final SoftwareModuleManagement smManagement; - private final SoftwareModuleTypeManagement smTypeManagement; - - private final EventView view; - - /** - * Constructor for SmWindowBuilder - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smManagement - * SoftwareModuleManagement - * @param smTypeManagement - * SoftwareModuleTypeManagement - * @param view - * EventView - */ - public SmWindowBuilder(final CommonUiDependencies uiDependencies, final SoftwareModuleManagement smManagement, - final SoftwareModuleTypeManagement smTypeManagement, final EventView view) { - super(uiDependencies); - - this.smManagement = smManagement; - this.smTypeManagement = smTypeManagement; - - this.view = view; - } - - @Override - protected String getWindowId() { - return UIComponentIdProvider.CREATE_POPUP_ID; - } - - /** - * @return add window for software module - */ - @Override - public Window getWindowForAdd() { - return getWindowForNewEntity(new AddSmWindowController(uiDependencies, smManagement, - new SmWindowLayout(getI18n(), smTypeManagement), view)); - - } - - /** - * @param proxySm - * ProxySoftwareModule - * - * @return update window for software module - */ - @Override - public Window getWindowForUpdate(final ProxySoftwareModule proxySm) { - return getWindowForEntity(proxySm, new UpdateSmWindowController(uiDependencies, smManagement, - new SmWindowLayout(getI18n(), smTypeManagement))); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmWindowLayout.java deleted file mode 100644 index 584e8d5849..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmWindowLayout.java +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.common.AbstractEntityWindowLayout; -import org.eclipse.hawkbit.ui.common.data.mappers.TypeToTypeInfoMapper; -import org.eclipse.hawkbit.ui.common.data.providers.SoftwareModuleTypeDataProvider; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTypeInfo; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; - -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.ComboBox; -import com.vaadin.ui.ComponentContainer; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.TextArea; -import com.vaadin.ui.TextField; - -/** - * Target add/update window layout. - */ -public class SmWindowLayout extends AbstractEntityWindowLayout { - private final SmWindowLayoutComponentBuilder smComponentBuilder; - - private final ComboBox smTypeSelect; - private final TextField smName; - private final TextField smVersion; - private final TextField smVendor; - private final TextArea smDescription; - private final CheckBox artifactEncryption; - - /** - * Constructor for AbstractTagWindowLayout - * - * @param i18n - * VaadinMessageSource - * @param smTypeManagement - * SoftwareModuleTypeManagement - */ - public SmWindowLayout(final VaadinMessageSource i18n, final SoftwareModuleTypeManagement smTypeManagement) { - super(); - - final SoftwareModuleTypeDataProvider smTypeDataProvider = new SoftwareModuleTypeDataProvider<>( - smTypeManagement, new TypeToTypeInfoMapper<>()); - this.smComponentBuilder = new SmWindowLayoutComponentBuilder(i18n, smTypeDataProvider); - - this.smTypeSelect = smComponentBuilder.createSoftwareModuleTypeCombo(binder); - this.smName = smComponentBuilder.createNameField(binder); - this.smVersion = smComponentBuilder.createVersionField(binder); - this.smVendor = smComponentBuilder.createVendorField(binder); - this.smDescription = smComponentBuilder.createDescription(binder); - this.artifactEncryption = smComponentBuilder.createArtifactEncryptionCheck(binder); - } - - /** - * @return software module window layout - */ - @Override - public ComponentContainer getRootComponent() { - final FormLayout smWindowLayout = new FormLayout(); - - smWindowLayout.setSpacing(true); - smWindowLayout.setMargin(true); - smWindowLayout.setSizeUndefined(); - - smWindowLayout.addComponent(smTypeSelect); - - smWindowLayout.addComponent(smName); - smName.focus(); - - smWindowLayout.addComponent(smVersion); - - smWindowLayout.addComponent(smVendor); - - smWindowLayout.addComponent(smDescription); - - smWindowLayout.addComponent(artifactEncryption); - - return smWindowLayout; - } - - /** - * Disable the software module type - */ - public void disableSmTypeSelect() { - smTypeSelect.setEnabled(false); - } - - /** - * Disable the software module name - */ - public void disableNameField() { - smName.setEnabled(false); - } - - /** - * Disable the software module version - */ - public void disableVersionField() { - smVersion.setEnabled(false); - } - - /** - * Disable the software module artifact encryption - */ - public void disableEncryptionField() { - artifactEncryption.setEnabled(false); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmWindowLayoutComponentBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmWindowLayoutComponentBuilder.java deleted file mode 100644 index 18e9c0b85d..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SmWindowLayoutComponentBuilder.java +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.common.builder.FormComponentBuilder; -import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; -import org.eclipse.hawkbit.ui.common.data.providers.SoftwareModuleTypeDataProvider; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTypeInfo; -import org.eclipse.hawkbit.ui.utils.TrimmingStringConverter; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; - -import com.vaadin.data.Binder; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.ComboBox; -import com.vaadin.ui.TextArea; -import com.vaadin.ui.TextField; - -/** - * Builder for software module window layout - */ -public class SmWindowLayoutComponentBuilder { - - public static final String TEXTFIELD_VENDOR = "textfield.vendor"; - public static final String ARTIFACT_ENCRYPTION = "artifact.encryption"; - - private final VaadinMessageSource i18n; - private final SoftwareModuleTypeDataProvider smTypeDataProvider; - - /** - * Constructor for SmWindowLayoutComponentBuilder - * - * @param i18n - * VaadinMessageSource - * @param smTypeDataProvider - * SoftwareModuleTypeDataProvider - */ - public SmWindowLayoutComponentBuilder(final VaadinMessageSource i18n, - final SoftwareModuleTypeDataProvider smTypeDataProvider) { - this.i18n = i18n; - this.smTypeDataProvider = smTypeDataProvider; - } - - /** - * Create combo box options for software module types - * - * @param binder - * binder the input will be bound to - * - * @return input component - */ - public ComboBox createSoftwareModuleTypeCombo(final Binder binder) { - return FormComponentBuilder - .createTypeCombo(binder, smTypeDataProvider, i18n, UIComponentIdProvider.SW_MODULE_TYPE, true) - .getComponent(); - } - - /** - * create name field - * - * @param binder - * binder the input will be bound to - * @return input component - */ - public TextField createNameField(final Binder binder) { - return FormComponentBuilder.createNameInput(binder, i18n, UIComponentIdProvider.SOFT_MODULE_NAME) - .getComponent(); - } - - /** - * create version field - * - * @param binder - * binder the input will be bound to - * @return input component - */ - public TextField createVersionField(final Binder binder) { - return FormComponentBuilder.createVersionInput(binder, i18n, UIComponentIdProvider.SOFT_MODULE_VERSION) - .getComponent(); - } - - /** - * Create vendor field - * - * @param binder - * binder the input will be bound to - * - * @return input component - */ - public TextField createVendorField(final Binder binder) { - final TextField smVendor = new TextFieldBuilder(SoftwareModule.VENDOR_MAX_SIZE) - .id(UIComponentIdProvider.SOFT_MODULE_VENDOR).caption(i18n.getMessage(TEXTFIELD_VENDOR)) - .prompt(i18n.getMessage(TEXTFIELD_VENDOR)).buildTextComponent(); - smVendor.setSizeUndefined(); - - binder.forField(smVendor).withConverter(new TrimmingStringConverter()).bind(ProxySoftwareModule::getVendor, - ProxySoftwareModule::setVendor); - - return smVendor; - } - - /** - * create description field - * - * @param binder - * binder the input will be bound to - * @return input component - */ - public TextArea createDescription(final Binder binder) { - return FormComponentBuilder - .createDescriptionInput(binder, i18n, UIComponentIdProvider.ADD_SW_MODULE_DESCRIPTION).getComponent(); - } - - /** - * Create checkbox for artifact encryption - * - * @param binder - * binder the input will be bound to - * - * @return input component - */ - public CheckBox createArtifactEncryptionCheck(final Binder binder) { - return FormComponentBuilder.createCheckBox(i18n.getMessage(ARTIFACT_ENCRYPTION), - UIComponentIdProvider.ARTIFACT_ENCRYPTION_ID, binder, ProxySoftwareModule::isEncrypted, - ProxySoftwareModule::setEncrypted); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGrid.java deleted file mode 100644 index f589940d72..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGrid.java +++ /dev/null @@ -1,313 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.builder.GridComponentBuilder; -import org.eclipse.hawkbit.ui.common.data.filters.SwFilterParams; -import org.eclipse.hawkbit.ui.common.data.mappers.AssignedSoftwareModuleToProxyMapper; -import org.eclipse.hawkbit.ui.common.data.mappers.SoftwareModuleToProxyMapper; -import org.eclipse.hawkbit.ui.common.data.providers.SoftwareModuleDataProvider; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSet; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload.EntityModifiedEventType; -import org.eclipse.hawkbit.ui.common.event.EventLayout; -import org.eclipse.hawkbit.ui.common.event.EventTopics; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.common.event.FilterType; -import org.eclipse.hawkbit.ui.common.grid.AbstractGrid; -import org.eclipse.hawkbit.ui.common.grid.support.DeleteSupport; -import org.eclipse.hawkbit.ui.common.grid.support.DragAndDropSupport; -import org.eclipse.hawkbit.ui.common.grid.support.FilterSupport; -import org.eclipse.hawkbit.ui.common.grid.support.MasterEntitySupport; -import org.eclipse.hawkbit.ui.common.grid.support.SelectionSupport; -import org.eclipse.hawkbit.ui.common.state.GridLayoutUiState; -import org.eclipse.hawkbit.ui.common.state.TypeFilterLayoutUiState; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; - -import com.vaadin.ui.Button; - -/** - * Software Module grid. - */ -public class SoftwareModuleGrid extends AbstractGrid { - private static final long serialVersionUID = 1L; - - private static final String SM_NAME_ID = "smName"; - private static final String SM_VERSION_ID = "smVersion"; - private static final String SM_DESC_ID = "smDescription"; - private static final String SM_VENDOR_ID = "smVendor"; - private static final String SM_DELETE_BUTTON_ID = "smDeleteButton"; - - private final UINotification notification; - - private final TypeFilterLayoutUiState smTypeFilterLayoutUiState; - private final GridLayoutUiState smGridLayoutUiState; - - private final transient SoftwareModuleManagement softwareModuleManagement; - private final transient SoftwareModuleToProxyMapper softwareModuleToProxyMapper; - - private final transient DeleteSupport swModuleDeleteSupport; - private transient MasterEntitySupport masterEntitySupport; - - private final Map numberOfArtifactUploadsForSm; - - /** - * Constructor for SoftwareModuleGrid - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smTypeFilterLayoutUiState - * TypeFilterLayoutUiState - * @param smGridLayoutUiState - * GridLayoutUiState - * @param softwareModuleManagement - * SoftwareModuleManagement - * @param view - * EventView - */ - public SoftwareModuleGrid(final CommonUiDependencies uiDependencies, - final TypeFilterLayoutUiState smTypeFilterLayoutUiState, final GridLayoutUiState smGridLayoutUiState, - final SoftwareModuleManagement softwareModuleManagement, final EventView view) { - super(uiDependencies.getI18n(), uiDependencies.getEventBus(), uiDependencies.getPermChecker()); - - this.smTypeFilterLayoutUiState = smTypeFilterLayoutUiState; - this.smGridLayoutUiState = smGridLayoutUiState; - this.notification = uiDependencies.getUiNotification(); - this.softwareModuleManagement = softwareModuleManagement; - this.softwareModuleToProxyMapper = new SoftwareModuleToProxyMapper(); - - setSelectionSupport(new SelectionSupport<>(this, eventBus, EventLayout.SM_LIST, view, this::mapIdToProxyEntity, - this::getSelectedEntityIdFromUiState, this::setSelectedEntityIdToUiState)); - if (smGridLayoutUiState.isMaximized()) { - getSelectionSupport().disableSelection(); - } else { - getSelectionSupport().enableMultiSelection(); - } - - this.swModuleDeleteSupport = new DeleteSupport<>(this, i18n, notification, "caption.software.module", - "caption.softwaremodules", ProxySoftwareModule::getNameAndVersion, this::deleteSoftwareModules, - UIComponentIdProvider.SM_DELETE_CONFIRMATION_DIALOG); - - setFilterSupport(new FilterSupport<>( - new SoftwareModuleDataProvider(softwareModuleManagement, - new AssignedSoftwareModuleToProxyMapper(softwareModuleToProxyMapper)), - SwFilterParams::new, this::afterFilterRefresh)); - initFilterMappings(); - getFilterSupport().setFilter(new SwFilterParams()); - - this.numberOfArtifactUploadsForSm = new HashMap<>(); - } - - private void afterFilterRefresh() { - // keep selection on master distribution set change as it does not - // filter out any software module entries, only sorts them - if (masterFilterHasNotChanged()) { - getSelectionSupport().deselectAll(); - } - } - - private boolean masterFilterHasNotChanged() { - final Long filterDsId = getFilter().map(SwFilterParams::getLastSelectedDistributionId).orElse(null); - final Long masterDsId = getMasterEntitySupport() != null ? getMasterEntitySupport().getMasterId() : null; - - return Objects.equals(filterDsId, masterDsId); - } - - private void initFilterMappings() { - getFilterSupport().addMapping(FilterType.SEARCH, SwFilterParams::setSearchText, - smGridLayoutUiState.getSearchFilter()); - getFilterSupport().addMapping(FilterType.TYPE, SwFilterParams::setSoftwareModuleTypeId, - smTypeFilterLayoutUiState.getClickedTypeId()); - } - - /** - * Initial method of grid and set style name - */ - @Override - public void init() { - super.init(); - - addStyleName("grid-row-border"); - } - - /** - * Map SoftwareModule to Proxy type - * - * @param entityId - * EntityId Long type - * - * @return ProxySoftwareModule - */ - public Optional mapIdToProxyEntity(final long entityId) { - return softwareModuleManagement.get(entityId).map(softwareModuleToProxyMapper::map); - } - - private Long getSelectedEntityIdFromUiState() { - return smGridLayoutUiState.getSelectedEntityId(); - } - - private void setSelectedEntityIdToUiState(final Long entityId) { - smGridLayoutUiState.setSelectedEntityId(entityId); - } - - private boolean deleteSoftwareModules(final Collection swModulesToBeDeleted) { - final Collection swModuleToBeDeletedIds = swModulesToBeDeleted.stream() - .map(ProxyIdentifiableEntity::getId).collect(Collectors.toList()); - if (isUploadInProgressForSoftwareModule(swModuleToBeDeletedIds)) { - notification.displayValidationError(i18n.getMessage("message.error.swModule.notDeleted")); - - return false; - } - - softwareModuleManagement.delete(swModuleToBeDeletedIds); - - eventBus.publish(EventTopics.ENTITY_MODIFIED, this, new EntityModifiedEventPayload( - EntityModifiedEventType.ENTITY_REMOVED, ProxySoftwareModule.class, swModuleToBeDeletedIds)); - - return true; - } - - private boolean isUploadInProgressForSoftwareModule(final Collection swModuleToBeDeletedIds) { - return swModuleToBeDeletedIds.stream().anyMatch( - smId -> numberOfArtifactUploadsForSm.containsKey(smId) && numberOfArtifactUploadsForSm.get(smId) > 0); - } - - /** - * Artifacts upload process - * - * @param fileUploadProgress - * FileUploadProgress - */ - public void onUploadChanged(final FileUploadProgress fileUploadProgress) { - final FileUploadProgress.FileUploadStatus uploadProgressEventType = fileUploadProgress.getFileUploadStatus(); - final Long fileUploadSmId = fileUploadProgress.getFileUploadId().getSoftwareModuleId(); - - if (fileUploadSmId == null) { - return; - } - - if (FileUploadProgress.FileUploadStatus.UPLOAD_STARTED == uploadProgressEventType) { - numberOfArtifactUploadsForSm.merge(fileUploadSmId, 1, Integer::sum); - } - - if (FileUploadProgress.FileUploadStatus.UPLOAD_FINISHED == uploadProgressEventType) { - numberOfArtifactUploadsForSm.computeIfPresent(fileUploadSmId, (smId, oldCount) -> { - final Integer newCount = oldCount - 1; - return newCount.equals(0) ? null : newCount; - }); - } - } - - /** - * Drag and drop for grid elements - */ - public void addDragAndDropSupport() { - setDragAndDropSupportSupport( - new DragAndDropSupport<>(this, i18n, notification, Collections.emptyMap(), eventBus)); - if (!smGridLayoutUiState.isMaximized()) { - getDragAndDropSupportSupport().addDragSource(); - } - } - - /** - * Add master filter type - */ - public void addMasterSupport() { - getFilterSupport().addMapping(FilterType.MASTER, SwFilterParams::setLastSelectedDistributionId); - - masterEntitySupport = new MasterEntitySupport<>(getFilterSupport()); - - initMasterDsStyleGenerator(); - } - - private void initMasterDsStyleGenerator() { - setStyleGenerator(sm -> { - if (masterEntitySupport.getMasterId() == null || !sm.isAssigned()) { - return null; - } - - return String.join("-", UIComponentIdProvider.SM_TYPE_COLOR_CLASS, - String.valueOf(sm.getTypeInfo().getId())); - }); - } - - /** - * @return gridId of software module grid - */ - @Override - public String getGridId() { - return UIComponentIdProvider.SOFTWARE_MODULE_TABLE; - } - - /** - * Add columns to Grid - */ - @Override - public void addColumns() { - addNameColumn().setExpandRatio(2); - addVersionColumn(); - addDeleteColumn(); - } - - private Column addNameColumn() { - return GridComponentBuilder.addNameColumn(this, i18n, SM_NAME_ID); - } - - private Column addVersionColumn() { - return GridComponentBuilder.addVersionColumn(this, i18n, ProxySoftwareModule::getVersion, SM_VERSION_ID); - } - - private Column addDeleteColumn() { - return GridComponentBuilder.addDeleteColumn(this, i18n, SM_DELETE_BUTTON_ID, swModuleDeleteSupport, - UIComponentIdProvider.SM_DELET_ICON, e -> permissionChecker.hasDeleteRepositoryPermission()); - } - - @Override - protected void addMaxColumns() { - addNameColumn().setExpandRatio(7); - addVersionColumn(); - addDescriptionColumn().setExpandRatio(5); - addVendorColumn(); - GridComponentBuilder.addCreatedAndModifiedColumns(this, i18n); - addDeleteColumn(); - - getColumns().forEach(column -> column.setHidable(true)); - } - - private Column addDescriptionColumn() { - return GridComponentBuilder.addDescriptionColumn(this, i18n, SM_DESC_ID); - } - - private Column addVendorColumn() { - return GridComponentBuilder.addColumn(this, ProxySoftwareModule::getVendor).setId(SM_VENDOR_ID) - .setCaption(i18n.getMessage("header.vendor")); - } - - /** - * @return ProxyDistributionSet of master entity type - */ - public MasterEntitySupport getMasterEntitySupport() { - return masterEntitySupport; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGridHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGridHeader.java deleted file mode 100644 index d04dfe4cf0..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGridHeader.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.event.EventLayout; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.common.grid.header.AbstractEntityGridHeader; -import org.eclipse.hawkbit.ui.common.state.GridLayoutUiState; -import org.eclipse.hawkbit.ui.common.state.HidableLayoutUiState; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; - -/** - * Header of Software module table. - */ -public class SoftwareModuleGridHeader extends AbstractEntityGridHeader { - private static final long serialVersionUID = 1L; - - private static final String SWM_TABLE_HEADER = "upload.swModuleTable.header"; - private static final String SWM_CAPTION = "caption.software.module"; - - /** - * Constructor for SoftwareModuleGridHeader - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smTypeFilterLayoutUiState - * HidableLayoutUiState - * @param smGridLayoutUiState - * GridLayoutUiState - * @param smWindowBuilder - * SmWindowBuilder - * @param view - * EventView - */ - public SoftwareModuleGridHeader(final CommonUiDependencies uiDependencies, - final HidableLayoutUiState smTypeFilterLayoutUiState, final GridLayoutUiState smGridLayoutUiState, - final SmWindowBuilder smWindowBuilder, final EventView view) { - super(uiDependencies, smTypeFilterLayoutUiState, smGridLayoutUiState, EventLayout.SM_TYPE_FILTER, view); - - addAddHeaderSupport(smWindowBuilder); - } - - @Override - protected String getCaptionMsg() { - return SWM_TABLE_HEADER; - } - - @Override - protected String getSearchFieldId() { - return UIComponentIdProvider.SW_MODULE_SEARCH_TEXT_FIELD; - } - - @Override - protected String getSearchResetIconId() { - return UIComponentIdProvider.SW_MODULE_SEARCH_RESET_ICON; - } - - @Override - protected Class getEntityType() { - return ProxySoftwareModule.class; - } - - @Override - protected String getFilterButtonsIconId() { - return UIComponentIdProvider.SHOW_SM_TYPE_ICON; - } - - @Override - protected String getMaxMinIconId() { - return UIComponentIdProvider.SW_MAX_MIN_TABLE_ICON; - } - - @Override - protected EventLayout getLayout() { - return EventLayout.SM_LIST; - } - - @Override - protected boolean hasCreatePermission() { - return permChecker.hasCreateRepositoryPermission(); - } - - @Override - protected String getAddIconId() { - return UIComponentIdProvider.SW_MODULE_ADD_BUTTON; - } - - @Override - protected String getAddWindowCaptionMsg() { - return SWM_CAPTION; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGridLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGridLayout.java deleted file mode 100644 index 51e9e81ec9..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGridLayout.java +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetails; -import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsHeader; -import org.eclipse.hawkbit.ui.common.event.EventLayout; -import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware; -import org.eclipse.hawkbit.ui.common.event.EventTopics; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent; -import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener; -import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport; -import org.eclipse.hawkbit.ui.common.layout.listener.FilterChangedListener; -import org.eclipse.hawkbit.ui.common.layout.listener.GenericEventListener; -import org.eclipse.hawkbit.ui.common.layout.listener.SelectGridEntityListener; -import org.eclipse.hawkbit.ui.common.layout.listener.SelectionChangedListener; -import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedGridRefreshAwareSupport; -import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedSelectionAwareSupport; -import org.eclipse.hawkbit.ui.common.softwaremodule.AbstractSoftwareModuleGridLayout; -import org.eclipse.hawkbit.ui.common.state.GridLayoutUiState; -import org.eclipse.hawkbit.ui.common.state.TypeFilterLayoutUiState; - -/** - * Software module table layout. (Upload Management) - */ -public class SoftwareModuleGridLayout extends AbstractSoftwareModuleGridLayout { - private static final long serialVersionUID = 1L; - - private final SoftwareModuleGridHeader softwareModuleGridHeader; - private final SoftwareModuleGrid softwareModuleGrid; - private final SoftwareModuleDetailsHeader softwareModuleDetailsHeader; - private final SoftwareModuleDetails softwareModuleDetails; - - /** - * Constructor for SoftwareModuleGridLayout - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param softwareModuleManagement - * SoftwareModuleManagement - * @param softwareModuleTypeManagement - * SoftwareModuleTypeManagement - * @param smTypeFilterLayoutUiState - * TypeFilterLayoutUiState - * @param smGridLayoutUiState - * GridLayoutUiState - */ - public SoftwareModuleGridLayout(final CommonUiDependencies uiDependencies, - final SoftwareModuleManagement softwareModuleManagement, - final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final TypeFilterLayoutUiState smTypeFilterLayoutUiState, final GridLayoutUiState smGridLayoutUiState) { - super(uiDependencies, softwareModuleManagement, softwareModuleTypeManagement, EventView.UPLOAD); - - this.softwareModuleGridHeader = new SoftwareModuleGridHeader(uiDependencies, smTypeFilterLayoutUiState, - smGridLayoutUiState, getSmWindowBuilder(), getEventView()); - this.softwareModuleGridHeader.buildHeader(); - this.softwareModuleGrid = new SoftwareModuleGrid(uiDependencies, smTypeFilterLayoutUiState, smGridLayoutUiState, - softwareModuleManagement, getEventView()); - this.softwareModuleGrid.init(); - - this.softwareModuleDetailsHeader = new SoftwareModuleDetailsHeader(uiDependencies, getSmWindowBuilder(), - getSmMetaDataWindowBuilder()); - this.softwareModuleDetailsHeader.buildHeader(); - this.softwareModuleDetails = new SoftwareModuleDetails(uiDependencies, softwareModuleManagement, - softwareModuleTypeManagement, getSmMetaDataWindowBuilder()); - this.softwareModuleDetails.buildDetails(); - - final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.SM_LIST, getEventView()); - addEventListener(new FilterChangedListener<>(uiDependencies.getEventBus(), ProxySoftwareModule.class, - layoutViewAware, softwareModuleGrid.getFilterSupport())); - addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), layoutViewAware, - getMasterSmAwareComponents())); - addEventListener(new SelectGridEntityListener<>(uiDependencies.getEventBus(), layoutViewAware, - softwareModuleGrid.getSelectionSupport())); - addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxySoftwareModule.class) - .viewAware(layoutViewAware).entityModifiedAwareSupports(getSmModifiedAwareSupports()).build()); - addEventListener(new GenericEventListener<>(uiDependencies.getEventBus(), EventTopics.FILE_UPLOAD_CHANGED, - this::onUploadChanged)); - - buildLayout(softwareModuleGridHeader, softwareModuleGrid, softwareModuleDetailsHeader, softwareModuleDetails); - } - - private List> getMasterSmAwareComponents() { - return Arrays.asList(softwareModuleDetailsHeader, softwareModuleDetails); - } - - private List getSmModifiedAwareSupports() { - return Arrays.asList(EntityModifiedGridRefreshAwareSupport.of(softwareModuleGrid::refreshAll), - EntityModifiedSelectionAwareSupport.of(softwareModuleGrid.getSelectionSupport(), - softwareModuleGrid::mapIdToProxyEntity)); - } - - /** - * Verifies when file upload is in progress - * - * @param fileUploadProgress - * FileUploadProgress - */ - public void onUploadChanged(final FileUploadProgress fileUploadProgress) { - softwareModuleGrid.onUploadChanged(fileUploadProgress); - } - - @Override - protected SoftwareModuleGridHeader getSoftwareModuleGridHeader() { - return softwareModuleGridHeader; - } - - @Override - protected SoftwareModuleGrid getSoftwareModuleGrid() { - return softwareModuleGrid; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/UpdateSmWindowController.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/UpdateSmWindowController.java deleted file mode 100644 index d7afa176ad..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/UpdateSmWindowController.java +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtable; - -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.builder.SoftwareModuleUpdate; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.common.AbstractUpdateNamedEntityWindowController; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.EntityWindowLayout; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; - -/** - * Controller for update software module window - */ -public class UpdateSmWindowController - extends AbstractUpdateNamedEntityWindowController { - - private final SoftwareModuleManagement smManagement; - private final SmWindowLayout layout; - private final ProxySmValidator validator; - - private String nameBeforeEdit; - private String versionBeforeEdit; - - /** - * Constructor for UpdateSmWindowController - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smManagement - * SoftwareModuleManagement - * @param layout - * SmWindowLayout - */ - public UpdateSmWindowController(final CommonUiDependencies uiDependencies, - final SoftwareModuleManagement smManagement, final SmWindowLayout layout) { - super(uiDependencies); - - this.smManagement = smManagement; - this.layout = layout; - this.validator = new ProxySmValidator(uiDependencies); - } - - @Override - protected ProxySoftwareModule buildEntityFromProxy(final ProxySoftwareModule proxyEntity) { - final ProxySoftwareModule sm = new ProxySoftwareModule(); - - sm.setId(proxyEntity.getId()); - sm.setTypeInfo(proxyEntity.getTypeInfo()); - sm.setName(proxyEntity.getName()); - sm.setVersion(proxyEntity.getVersion()); - sm.setVendor(proxyEntity.getVendor()); - sm.setDescription(proxyEntity.getDescription()); - sm.setEncrypted(proxyEntity.isEncrypted()); - - nameBeforeEdit = proxyEntity.getName(); - versionBeforeEdit = proxyEntity.getVersion(); - - return sm; - } - - @Override - public EntityWindowLayout getLayout() { - return layout; - } - - @Override - protected void adaptLayout(final ProxySoftwareModule proxyEntity) { - layout.disableSmTypeSelect(); - layout.disableNameField(); - layout.disableVersionField(); - layout.disableEncryptionField(); - } - - @Override - protected SoftwareModule persistEntityInRepository(final ProxySoftwareModule entity) { - final SoftwareModuleUpdate smUpdate = getEntityFactory().softwareModule().update(entity.getId()) - .vendor(entity.getVendor()).description(entity.getDescription()); - return smManagement.update(smUpdate); - } - - @Override - protected String getDisplayableName(final SoftwareModule entity) { - return HawkbitCommonUtil.getFormattedNameVersion(entity.getName(), entity.getVersion()); - } - - @Override - protected String getDisplayableNameForFailedMessage(final ProxySoftwareModule entity) { - return HawkbitCommonUtil.getFormattedNameVersion(entity.getName(), entity.getVersion()); - } - - @Override - protected Class getEntityClass() { - return ProxySoftwareModule.class; - } - - @Override - protected boolean isEntityValid(final ProxySoftwareModule entity) { - final String name = entity.getName(); - final String version = entity.getVersion(); - final Long typeId = entity.getTypeInfo().getId(); - return validator.isEntityValid(entity, () -> hasNameOrVersionChanged(name, version) - && smManagement.getByNameAndVersionAndType(name, version, typeId).isPresent()); - } - - private boolean hasNameOrVersionChanged(final String trimmedName, final String trimmedVersion) { - return !nameBeforeEdit.equals(trimmedName) || !versionBeforeEdit.equals(trimmedVersion); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/AddSmTypeWindowController.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/AddSmTypeWindowController.java deleted file mode 100644 index 12c079407d..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/AddSmTypeWindowController.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtype; - -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.ui.common.AbstractAddNamedEntityWindowController; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.EntityWindowLayout; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType.SmTypeAssign; -import org.eclipse.hawkbit.ui.common.type.ProxyTypeValidator; - -/** - * Controller for Add software module type window - */ -public class AddSmTypeWindowController - extends AbstractAddNamedEntityWindowController { - - private final SoftwareModuleTypeManagement smTypeManagement; - private final SmTypeWindowLayout layout; - private final ProxyTypeValidator validator; - - /** - * Constructor for AddSmTypeWindowController - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smTypeManagement - * SoftwareModuleTypeManagement - * @param layout - * SmTypeWindowLayout - */ - public AddSmTypeWindowController(final CommonUiDependencies uiDependencies, - final SoftwareModuleTypeManagement smTypeManagement, final SmTypeWindowLayout layout) { - super(uiDependencies); - - this.smTypeManagement = smTypeManagement; - this.layout = layout; - this.validator = new ProxyTypeValidator(uiDependencies); - } - - @Override - public EntityWindowLayout getLayout() { - return layout; - } - - @Override - protected ProxyType buildEntityFromProxy(final ProxyType proxyEntity) { - // We ignore the method parameter, because we are interested in the - // empty object, that we can populate with defaults - return new ProxyType(); - } - - @Override - protected SoftwareModuleType persistEntityInRepository(final ProxyType entity) { - final int assignNumber = entity.getSmTypeAssign() == SmTypeAssign.SINGLE ? 1 : Integer.MAX_VALUE; - - return smTypeManagement - .create(getEntityFactory().softwareModuleType().create().key(entity.getKey()).name(entity.getName()) - .description(entity.getDescription()).colour(entity.getColour()).maxAssignments(assignNumber)); - } - - @Override - protected Class getEntityClass() { - return ProxyType.class; - } - - @Override - protected Class getParentEntityClass() { - return ProxySoftwareModule.class; - } - - @Override - protected boolean isEntityValid(final ProxyType entity) { - return validator.isSmTypeValid(entity, () -> smTypeManagement.getByKey(entity.getKey()).isPresent(), - () -> smTypeManagement.getByName(entity.getName()).isPresent()); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SmTypeWindowBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SmTypeWindowBuilder.java deleted file mode 100644 index 641adcd557..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SmTypeWindowBuilder.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtype; - -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.common.AbstractEntityWindowBuilder; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; - -import com.vaadin.ui.Window; - -/** - * Builder for software module type window - */ -public class SmTypeWindowBuilder extends AbstractEntityWindowBuilder { - - private final SoftwareModuleTypeManagement smTypeManagement; - - /** - * Constructor for SmTypeWindowBuilder - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smTypeManagement - * SoftwareModuleTypeManagement - */ - public SmTypeWindowBuilder(final CommonUiDependencies uiDependencies, final SoftwareModuleTypeManagement smTypeManagement) { - super(uiDependencies); - this.smTypeManagement = smTypeManagement; - } - - @Override - protected String getWindowId() { - return UIComponentIdProvider.TAG_POPUP_ID; - } - - /** - * Add window for software module type - * - * @return Window of Software module type - */ - @Override - public Window getWindowForAdd() { - return getWindowForNewEntity( - new AddSmTypeWindowController(uiDependencies, smTypeManagement, new SmTypeWindowLayout(uiDependencies))); - - } - - /** - * Update window for software module type - * - * @param proxyType - * ProxyType - * - * @return Window of Software module type - */ - @Override - public Window getWindowForUpdate(final ProxyType proxyType) { - return getWindowForEntity(proxyType, - new UpdateSmTypeWindowController(uiDependencies, smTypeManagement, new SmTypeWindowLayout(uiDependencies))); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SmTypeWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SmTypeWindowLayout.java deleted file mode 100644 index ba42de8137..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SmTypeWindowLayout.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtype; - -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.builder.FormComponentBuilder; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType.SmTypeAssign; -import org.eclipse.hawkbit.ui.management.tag.TagWindowLayout; - -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.RadioButtonGroup; -import com.vaadin.ui.TextField; - -/** - * Software module type Window Layout view - */ -public class SmTypeWindowLayout extends TagWindowLayout { - private final SmTypeWindowLayoutComponentBuilder smTypeComponentBuilder; - - private final TextField typeKey; - private final RadioButtonGroup smTypeAssignOptionGroup; - - /** - * Constructor for SmTypeWindowLayout - * - * @param uiDependencies - * {@link CommonUiDependencies} - */ - public SmTypeWindowLayout(final CommonUiDependencies uiDependencies) { - super(uiDependencies); - - this.smTypeComponentBuilder = new SmTypeWindowLayoutComponentBuilder(i18n); - - this.typeKey = FormComponentBuilder.createTypeKeyField(binder, i18n); - this.smTypeAssignOptionGroup = smTypeComponentBuilder.createSmTypeAssignOptionGroup(binder); - - this.colorPickerComponent.getColorPickerBtn().setCaption(i18n.getMessage("label.choose.type.color")); - } - - @Override - protected FormLayout buildFormLayout() { - final FormLayout formLayout = super.buildFormLayout(); - - formLayout.addComponent(typeKey, formLayout.getComponentCount() - 1); - formLayout.addComponent(smTypeAssignOptionGroup, formLayout.getComponentCount() - 1); - - return formLayout; - } - - /** - * Disable the software module type key text field - */ - public void disableTypeKey() { - typeKey.setEnabled(false); - } - - /** - * Disable the software module type assign option - */ - public void disableTypeAssignOptionGroup() { - smTypeAssignOptionGroup.setEnabled(false); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SmTypeWindowLayoutComponentBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SmTypeWindowLayoutComponentBuilder.java deleted file mode 100644 index 09aea360e3..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SmTypeWindowLayoutComponentBuilder.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtype; - -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType.SmTypeAssign; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; - -import com.vaadin.data.Binder; -import com.vaadin.ui.RadioButtonGroup; - -/** - * Builder for software module type window layout component - */ -public class SmTypeWindowLayoutComponentBuilder { - - public static final String TEXTFIELD_KEY = "textfield.key"; - - private final VaadinMessageSource i18n; - - /** - * Constructor for SmTypeWindowLayoutComponentBuilder - * - * @param i18n - * VaadinMessageSource - */ - public SmTypeWindowLayoutComponentBuilder(final VaadinMessageSource i18n) { - this.i18n = i18n; - } - - /** - * Create software module type assignment group - * - * @param binder - * Vaadin binder of ProxyType - * - * @return RadioButtonGroup of software module type assignment - */ - public RadioButtonGroup createSmTypeAssignOptionGroup(final Binder binder) { - final RadioButtonGroup smTypeAssignOptionGroup = new RadioButtonGroup<>(); - smTypeAssignOptionGroup.setId(UIComponentIdProvider.ASSIGN_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID); - - smTypeAssignOptionGroup.setItemCaptionGenerator(item -> { - switch (item) { - case SINGLE: - return i18n.getMessage("label.singleAssign.type"); - case MULTI: - return i18n.getMessage("label.multiAssign.type"); - default: - return null; - } - }); - smTypeAssignOptionGroup.setItemDescriptionGenerator(item -> { - switch (item) { - case SINGLE: - return i18n.getMessage("label.singleAssign.type.desc"); - case MULTI: - return i18n.getMessage("label.multiAssign.type.desc"); - default: - return null; - } - }); - - binder.forField(smTypeAssignOptionGroup).bind(ProxyType::getSmTypeAssign, ProxyType::setSmTypeAssign); - smTypeAssignOptionGroup.setItems(SmTypeAssign.values()); - - return smTypeAssignOptionGroup; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/UpdateSmTypeWindowController.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/UpdateSmTypeWindowController.java deleted file mode 100644 index ae026c8cdc..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/UpdateSmTypeWindowController.java +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtype; - -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeUpdate; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.ui.common.AbstractUpdateNamedEntityWindowController; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.EntityWindowLayout; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType.SmTypeAssign; -import org.eclipse.hawkbit.ui.common.type.ProxyTypeValidator; - -/** - * Controller for update software module type window - */ -public class UpdateSmTypeWindowController - extends AbstractUpdateNamedEntityWindowController { - - private final SoftwareModuleTypeManagement smTypeManagement; - private final SmTypeWindowLayout layout; - private final ProxyTypeValidator validator; - - private String nameBeforeEdit; - private String keyBeforeEdit; - - /** - * Constructor for UpdateSmTypeWindowController - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smTypeManagement - * SoftwareModuleTypeManagement - * @param layout - * SmTypeWindowLayout - */ - public UpdateSmTypeWindowController(final CommonUiDependencies uiDependencies, - final SoftwareModuleTypeManagement smTypeManagement, final SmTypeWindowLayout layout) { - super(uiDependencies); - - this.smTypeManagement = smTypeManagement; - this.layout = layout; - this.validator = new ProxyTypeValidator(uiDependencies); - } - - @Override - protected ProxyType buildEntityFromProxy(final ProxyType proxyEntity) { - final ProxyType smType = new ProxyType(); - - smType.setId(proxyEntity.getId()); - smType.setName(proxyEntity.getName()); - smType.setDescription(proxyEntity.getDescription()); - smType.setColour(proxyEntity.getColour()); - smType.setKey(proxyEntity.getKey()); - smType.setSmTypeAssign(getSmTypeAssignById(proxyEntity.getId())); - - nameBeforeEdit = proxyEntity.getName(); - keyBeforeEdit = proxyEntity.getKey(); - - return smType; - } - - private SmTypeAssign getSmTypeAssignById(final Long id) { - return smTypeManagement.get(id) - .map(smType -> smType.getMaxAssignments() == 1 ? SmTypeAssign.SINGLE : SmTypeAssign.MULTI) - .orElse(SmTypeAssign.SINGLE); - } - - @Override - public EntityWindowLayout getLayout() { - return layout; - } - - @Override - protected void adaptLayout(final ProxyType proxyEntity) { - layout.disableTagName(); - layout.disableTypeKey(); - layout.disableTypeAssignOptionGroup(); - } - - @Override - protected SoftwareModuleType persistEntityInRepository(final ProxyType entity) { - final SoftwareModuleTypeUpdate smTypeUpdate = getEntityFactory().softwareModuleType().update(entity.getId()) - .description(entity.getDescription()).colour(entity.getColour()); - return smTypeManagement.update(smTypeUpdate); - } - - @Override - protected Class getEntityClass() { - return ProxyType.class; - } - - @Override - protected Class getParentEntityClass() { - return ProxySoftwareModule.class; - } - - @Override - protected boolean isEntityValid(final ProxyType entity) { - final String name = entity.getName(); - final String key = entity.getKey(); - return validator.isSmTypeValid(entity, - () -> hasKeyChanged(key) && smTypeManagement.getByKey(key).isPresent(), - () -> hasNameChanged(name) && smTypeManagement.getByName(name).isPresent()); - } - - private boolean hasNameChanged(final String trimmedName) { - return !nameBeforeEdit.equals(trimmedName); - } - - private boolean hasKeyChanged(final String trimmedKey) { - return !keyBeforeEdit.equals(trimmedKey); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterButtons.java deleted file mode 100644 index 84d0e73d3b..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterButtons.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtype.filter; - -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.artifacts.smtype.SmTypeWindowBuilder; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.mappers.TypeToProxyTypeMapper; -import org.eclipse.hawkbit.ui.common.data.providers.SoftwareModuleTypeDataProvider; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.common.filterlayout.AbstractTypeFilterButtons; -import org.eclipse.hawkbit.ui.common.state.TypeFilterLayoutUiState; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; - -import com.vaadin.ui.Window; - -/** - * Software module type filter buttons. - * - */ -public class SMTypeFilterButtons extends AbstractTypeFilterButtons { - private static final long serialVersionUID = 1L; - - private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; - private final transient SmTypeWindowBuilder smTypeWindowBuilder; - - private final EventView view; - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param softwareModuleTypeManagement - * SoftwareModuleTypeManagement - * @param smTypeWindowBuilder - * SmTypeWindowBuilder - * @param typeFilterLayoutUiState - * TypeFilterLayoutUiState - * @param view - * EventView - */ - public SMTypeFilterButtons(final CommonUiDependencies uiDependencies, - final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final SmTypeWindowBuilder smTypeWindowBuilder, final TypeFilterLayoutUiState typeFilterLayoutUiState, - final EventView view) { - super(uiDependencies, typeFilterLayoutUiState); - - this.softwareModuleTypeManagement = softwareModuleTypeManagement; - this.smTypeWindowBuilder = smTypeWindowBuilder; - this.view = view; - - init(); - setDataProvider( - new SoftwareModuleTypeDataProvider<>(softwareModuleTypeManagement, new TypeToProxyTypeMapper<>())); - } - - /** - * Gets id of the software module type grid. - * - * @return id of the grid - */ - @Override - public String getGridId() { - return UIComponentIdProvider.SW_MODULE_TYPE_TABLE_ID; - } - - @Override - protected String getMessageKeyEntityTypeSing() { - return "caption.entity.software.module.type"; - } - - @Override - protected String getMessageKeyEntityTypePlur() { - return "caption.entity.software.module.types"; - } - - @Override - protected String getFilterButtonIdPrefix() { - return UIComponentIdProvider.SOFTWARE_MODULE_TYPE_ID_PREFIXS; - } - - @Override - protected boolean isDefaultType(final ProxyType type) { - // We do not have default type for software module - return false; - } - - @Override - protected Class getFilterMasterEntityType() { - return ProxySoftwareModule.class; - } - - @Override - protected EventView getView() { - return view; - } - - @Override - protected void deleteType(final ProxyType typeToDelete) { - softwareModuleTypeManagement.delete(typeToDelete.getId()); - } - - @Override - protected Window getUpdateWindow(final ProxyType clickedFilter) { - return smTypeWindowBuilder.getWindowForUpdate(clickedFilter); - } - - @Override - protected boolean typeExists(final Long typeId) { - return softwareModuleTypeManagement.exists(typeId); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterHeader.java deleted file mode 100644 index 440fac5617..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterHeader.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtype.filter; - -import org.eclipse.hawkbit.ui.artifacts.smtype.SmTypeWindowBuilder; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.event.EventLayout; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.common.grid.header.AbstractFilterHeader; -import org.eclipse.hawkbit.ui.common.state.TypeFilterLayoutUiState; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider; - -import com.vaadin.ui.Window; - -/** - * Software module type filter buttons header. - */ -public class SMTypeFilterHeader extends AbstractFilterHeader { - private static final long serialVersionUID = 1L; - - private final TypeFilterLayoutUiState smTypeFilterLayoutUiState; - - private final transient SmTypeWindowBuilder smTypeWindowBuilder; - - private final EventView view; - - /** - * Constructor for SMTypeFilterHeader - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param smTypeWindowBuilder - * SmTypeWindowBuilder - * @param smTypeFilterLayoutUiState - * TypeFilterLayoutUiState - * @param view - * EventView - */ - public SMTypeFilterHeader(final CommonUiDependencies uiDependencies, final SmTypeWindowBuilder smTypeWindowBuilder, - final TypeFilterLayoutUiState smTypeFilterLayoutUiState, final EventView view) { - super(uiDependencies.getI18n(), uiDependencies.getPermChecker(), uiDependencies.getEventBus()); - - this.smTypeFilterLayoutUiState = smTypeFilterLayoutUiState; - this.smTypeWindowBuilder = smTypeWindowBuilder; - this.view = view; - - buildHeader(); - } - - @Override - protected String getHeaderCaptionMsgKey() { - return UIMessageIdProvider.CAPTION_FILTER_BY_TYPE; - } - - @Override - protected String getCrudMenuBarId() { - return UIComponentIdProvider.SOFT_MODULE_TYPE_MENU_BAR_ID; - } - - @Override - protected Window getWindowForAdd() { - return smTypeWindowBuilder.getWindowForAdd(); - } - - @Override - protected String getAddEntityWindowCaptionMsgKey() { - return "caption.type"; - } - - @Override - protected String getCloseIconId() { - return UIComponentIdProvider.HIDE_SM_TYPES; - } - - @Override - protected void updateHiddenUiState() { - smTypeFilterLayoutUiState.setHidden(true); - } - - @Override - protected EventLayout getLayout() { - return EventLayout.SM_TYPE_FILTER; - } - - @Override - protected EventView getView() { - return view; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterLayout.java deleted file mode 100644 index 0b410e23ac..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterLayout.java +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.smtype.filter; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.artifacts.smtype.SmTypeWindowBuilder; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType; -import org.eclipse.hawkbit.ui.common.event.EventLayout; -import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware; -import org.eclipse.hawkbit.ui.common.event.EventView; -import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterLayout; -import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener; -import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport; -import org.eclipse.hawkbit.ui.common.layout.listener.GridActionsVisibilityListener; -import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedGenericSupport; -import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedGridRefreshAwareSupport; -import org.eclipse.hawkbit.ui.common.state.TypeFilterLayoutUiState; - -import com.vaadin.ui.ComponentContainer; - -/** - * Software module type filter buttons layout. - */ -public class SMTypeFilterLayout extends AbstractFilterLayout { - - private static final long serialVersionUID = 1L; - - private final SMTypeFilterHeader smTypeFilterHeader; - private final SMTypeFilterButtons smTypeFilterButtons; - - private final transient GridActionsVisibilityListener gridActionsVisibilityListener; - private final transient EntityModifiedListener entityModifiedListener; - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - * @param softwareModuleTypeManagement - * SoftwareModuleTypeManagement - * @param smTypeFilterLayoutUiState - * SMTypeFilterLayoutUiState - * @param eventView - * {@link EventView} - */ - public SMTypeFilterLayout(final CommonUiDependencies uiDependencies, - final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final TypeFilterLayoutUiState smTypeFilterLayoutUiState, final EventView eventView) { - final SmTypeWindowBuilder smTypeWindowBuilder = new SmTypeWindowBuilder(uiDependencies, - softwareModuleTypeManagement); - - this.smTypeFilterHeader = new SMTypeFilterHeader(uiDependencies, smTypeWindowBuilder, smTypeFilterLayoutUiState, - eventView); - this.smTypeFilterButtons = new SMTypeFilterButtons(uiDependencies, softwareModuleTypeManagement, - smTypeWindowBuilder, smTypeFilterLayoutUiState, eventView); - - final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.SM_TYPE_FILTER, eventView); - this.gridActionsVisibilityListener = new GridActionsVisibilityListener(uiDependencies.getEventBus(), - layoutViewAware, smTypeFilterButtons::hideActionColumns, smTypeFilterButtons::showEditColumn, - smTypeFilterButtons::showDeleteColumn); - this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), - ProxyType.class).parentEntityType(ProxySoftwareModule.class).viewAware(layoutViewAware) - .entityModifiedAwareSupports(getEntityModifiedAwareSupports()).build(); - - buildLayout(); - } - - private List getEntityModifiedAwareSupports() { - return Arrays.asList(EntityModifiedGridRefreshAwareSupport.of(this::refreshFilterButtons), - EntityModifiedGenericSupport.of(null, null, smTypeFilterButtons::resetFilterOnTypesDeleted)); - } - - protected void refreshFilterButtons() { - smTypeFilterButtons.refreshAll(); - } - - @Override - protected SMTypeFilterHeader getFilterHeader() { - return smTypeFilterHeader; - } - - @Override - protected ComponentContainer getFilterContent() { - return wrapFilterContent(smTypeFilterButtons); - } - - @Override - public void restoreState() { - smTypeFilterButtons.restoreState(); - } - - @Override - public void onViewEnter() { - smTypeFilterButtons.reevaluateFilter(); - } - - @Override - public void subscribeListeners() { - gridActionsVisibilityListener.subscribe(); - entityModifiedListener.subscribe(); - } - - @Override - public void unsubscribeListeners() { - gridActionsVisibilityListener.unsubscribe(); - entityModifiedListener.unsubscribe(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/AbstractFileTransferHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/AbstractFileTransferHandler.java deleted file mode 100644 index de6acfe032..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/AbstractFileTransferHandler.java +++ /dev/null @@ -1,352 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Serializable; -import java.util.concurrent.Executor; -import java.util.concurrent.locks.Lock; - -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.RegexCharacterCollection; -import org.eclipse.hawkbit.repository.RegexCharacterCollection.RegexChar; -import org.eclipse.hawkbit.repository.exception.ArtifactEncryptionFailedException; -import org.eclipse.hawkbit.repository.exception.ArtifactEncryptionUnsupportedException; -import org.eclipse.hawkbit.repository.exception.ArtifactUploadFailedException; -import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; -import org.eclipse.hawkbit.repository.exception.FileSizeQuotaExceededException; -import org.eclipse.hawkbit.repository.exception.InvalidMD5HashException; -import org.eclipse.hawkbit.repository.exception.InvalidSHA1HashException; -import org.eclipse.hawkbit.repository.exception.StorageQuotaExceededException; -import org.eclipse.hawkbit.repository.model.Artifact; -import org.eclipse.hawkbit.repository.model.ArtifactUpload; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.ArtifactUploadState; -import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload.EntityModifiedEventType; -import org.eclipse.hawkbit.ui.common.event.EventTopics; -import org.eclipse.hawkbit.ui.utils.SpringContextHolder; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.StringUtils; -import org.vaadin.spring.events.EventBus; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.ui.UI; - -/** - * Abstract base class for transferring files from the browser to the - * repository. - */ -public abstract class AbstractFileTransferHandler implements Serializable { - - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(AbstractFileTransferHandler.class); - private static final String MESSAGE_UPLOAD_FAILED = "message.upload.failed"; - - private volatile boolean uploadInterrupted; - - private volatile String failureReason; - - private final ArtifactUploadState artifactUploadState; - - private final transient UIEventBus eventBus; - - private final transient ArtifactManagement artifactManagement; - - private final VaadinMessageSource i18n; - - private final transient Lock uploadLock; - - protected static final RegexCharacterCollection ILLEGAL_FILENAME_CHARACTERS = new RegexCharacterCollection( - RegexChar.GREATER_THAN, RegexChar.LESS_THAN, RegexChar.SLASHES); - - AbstractFileTransferHandler(final ArtifactManagement artifactManagement, final VaadinMessageSource i18n, - final Lock uploadLock) { - this.artifactManagement = artifactManagement; - this.i18n = i18n; - this.eventBus = SpringContextHolder.getInstance().getBean(EventBus.UIEventBus.class); - this.artifactUploadState = SpringContextHolder.getInstance().getBean(ArtifactUploadState.class); - this.uploadLock = uploadLock; - } - - protected boolean isUploadInterrupted() { - return uploadInterrupted; - } - - protected void resetState() { - uploadInterrupted = false; - failureReason = null; - } - - protected ArtifactUploadState getUploadState() { - return artifactUploadState; - } - - protected VaadinMessageSource getI18n() { - return i18n; - } - - protected void startTransferToRepositoryThread(final InputStream inputStream, final FileUploadId fileUploadId, - final String mimeType) { - SpringContextHolder.getInstance().getBean("uiExecutor", Executor.class) - .execute(new TransferArtifactToRepositoryRunnable(inputStream, fileUploadId, mimeType, UI.getCurrent(), - uploadLock)); - } - - private void interruptUploadAndSetReason(final String failureReason) { - uploadInterrupted = true; - this.failureReason = failureReason; - } - - protected void interruptUploadDueToUploadFailed() { - interruptUploadAndSetReason(i18n.getMessage(MESSAGE_UPLOAD_FAILED)); - } - - protected void interruptUploadDueToAssignmentQuotaExceeded() { - interruptUploadAndSetReason(i18n.getMessage("message.upload.assignmentQuota")); - } - - protected void interruptUploadDueToFileSizeQuotaExceeded(final String exceededValue) { - interruptUploadAndSetReason(i18n.getMessage("message.upload.fileSizeQuota", exceededValue)); - } - - protected void interruptUploadDueToStorageQuotaExceeded(final String exceededValue) { - interruptUploadAndSetReason(i18n.getMessage("message.upload.storageQuota", exceededValue)); - } - - protected void interruptUploadDueToDuplicateFile() { - interruptUploadAndSetReason(i18n.getMessage("message.no.duplicateFiles")); - } - - protected void interruptUploadDueToIllegalFilename() { - interruptUploadAndSetReason(i18n.getMessage("message.uploadedfile.illegalFilename")); - } - - protected void interruptUploadDueToEncryptionError() { - interruptUploadAndSetReason(i18n.getMessage("message.encryption.failed")); - } - - protected boolean isFileAlreadyContainedInSoftwareModule(final FileUploadId newFileUploadId, - final SoftwareModule softwareModule) { - for (final Artifact artifact : softwareModule.getArtifacts()) { - final FileUploadId existingId = new FileUploadId(artifact.getFilename(), softwareModule); - if (existingId.equals(newFileUploadId)) { - return true; - } - } - - return false; - } - - protected void publishUploadStarted(final FileUploadId fileUploadId) { - LOG.info("Upload started for file {}", fileUploadId); - final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, - FileUploadStatus.UPLOAD_STARTED); - artifactUploadState.updateFileUploadProgress(fileUploadId, fileUploadProgress); - eventBus.publish(EventTopics.FILE_UPLOAD_CHANGED, this, fileUploadProgress); - } - - protected void publishUploadProgressEvent(final FileUploadId fileUploadId, final long bytesReceived, - final long fileSize) { - if (LOG.isTraceEnabled()) { - LOG.trace("Upload in progress for file {} - {}%", fileUploadId, - String.format("%.0f", (double) bytesReceived / (double) fileSize * 100)); - } - final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, - FileUploadStatus.UPLOAD_IN_PROGRESS, bytesReceived, fileSize); - artifactUploadState.updateFileUploadProgress(fileUploadId, fileUploadProgress); - eventBus.publish(EventTopics.FILE_UPLOAD_CHANGED, this, fileUploadProgress); - } - - protected void publishUploadFinishedEvent(final FileUploadId fileUploadId) { - LOG.debug("Upload finished for file {}", fileUploadId); - final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, - FileUploadStatus.UPLOAD_FINISHED); - eventBus.publish(EventTopics.FILE_UPLOAD_CHANGED, this, fileUploadProgress); - } - - protected void publishUploadSucceeded(final FileUploadId fileUploadId, final long fileSize) { - LOG.info("Upload succeeded for file {}", fileUploadId); - final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, - FileUploadStatus.UPLOAD_SUCCESSFUL, fileSize, fileSize); - artifactUploadState.updateFileUploadProgress(fileUploadId, fileUploadProgress); - eventBus.publish(EventTopics.FILE_UPLOAD_CHANGED, this, fileUploadProgress); - } - - protected void publishUploadFailedEvent(final FileUploadId fileUploadId) { - LOG.info("Upload failed for file {} due to reason: {}", fileUploadId, failureReason); - final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, - FileUploadStatus.UPLOAD_FAILED, - StringUtils.hasText(failureReason) ? failureReason : i18n.getMessage(MESSAGE_UPLOAD_FAILED)); - artifactUploadState.updateFileUploadProgress(fileUploadId, fileUploadProgress); - eventBus.publish(EventTopics.FILE_UPLOAD_CHANGED, this, fileUploadProgress); - } - - protected void publishArtifactsChanged(final FileUploadId fileUploadId) { - eventBus.publish(EventTopics.ENTITY_MODIFIED, this, new EntityModifiedEventPayload( - EntityModifiedEventType.ENTITY_UPDATED, ProxySoftwareModule.class, fileUploadId.getSoftwareModuleId())); - } - - protected void publishUploadFailedAndFinishedEvent(final FileUploadId fileUploadId) { - publishUploadFailedEvent(fileUploadId); - publishUploadFinishedEvent(fileUploadId); - } - - protected void assertStateConsistency(final FileUploadId fileUploadId, final String filenameExtractedFromEvent) { - if (!filenameExtractedFromEvent.equals(fileUploadId.getFilename())) { - throw new IllegalStateException("Event filename " + filenameExtractedFromEvent + " but stored filename " - + fileUploadId.getFilename()); - } - } - - protected static void tryToCloseIOStream(final OutputStream outputStream) { - if (outputStream != null) { - try { - outputStream.close(); - } catch (final IOException e1) { - LOG.warn("Closing output stream caused by", e1); - } - } - - } - - protected static void tryToCloseIOStream(final InputStream inputStream) { - if (inputStream != null) { - try { - inputStream.close(); - } catch (final IOException e1) { - LOG.warn("Closing input stream caused by", e1); - } - } - } - - private final class TransferArtifactToRepositoryRunnable implements Runnable { - private final InputStream inputStream; - private final FileUploadId fileUploadId; - private final String mimeType; - private final UI vaadinUi; - private final Lock uploadLock; - - /** - * Constructor for TransferArtifactToRepositoryRunnable - * - * @param inputStream - * InputStream - * @param fileUploadId - * FileUploadId - * @param mimeType - * String - * @param vaadinUi - * UI - * @param uploadLock - * Lock - */ - public TransferArtifactToRepositoryRunnable(final InputStream inputStream, final FileUploadId fileUploadId, - final String mimeType, final UI vaadinUi, final Lock uploadLock) { - this.inputStream = inputStream; - this.fileUploadId = fileUploadId; - this.mimeType = mimeType; - this.vaadinUi = vaadinUi; - this.uploadLock = uploadLock; - } - - /** - * a lock object is used here that is propagated down from - * {@link org.eclipse.hawkbit.ui.artifacts.UploadArtifactView}. It - * ensures that from within the same UI instance all uploads are - * executed sequentially to avoid issues that occur when multiple files - * are processed at the same time (e.g. regarding quota checks) - */ - @Override - public void run() { - try { - UI.setCurrent(vaadinUi); - uploadLock.lock(); - streamToRepository(); - } catch (final FileSizeQuotaExceededException e) { - interruptUploadDueToFileSizeQuotaExceeded(e.getExceededQuotaValueString()); - publishUploadFailedAndFinishedEvent(fileUploadId); - LOG.debug("Upload failed due to file size quota exceeded:", e); - } catch (final StorageQuotaExceededException e) { - interruptUploadDueToStorageQuotaExceeded(e.getExceededQuotaValueString()); - publishUploadFailedAndFinishedEvent(fileUploadId); - LOG.debug("Upload failed due to storage quota exceeded:", e); - } catch (final AssignmentQuotaExceededException e) { - interruptUploadDueToAssignmentQuotaExceeded(); - publishUploadFailedAndFinishedEvent(fileUploadId); - LOG.debug("Upload failed due to assignment quota exceeded:", e); - } catch (final ArtifactEncryptionUnsupportedException | ArtifactEncryptionFailedException e) { - interruptUploadDueToEncryptionError(); - publishUploadFailedAndFinishedEvent(fileUploadId); - LOG.warn("Upload failed due to encryption error", e); - } catch (final RuntimeException e) { - interruptUploadDueToUploadFailed(); - publishUploadFailedAndFinishedEvent(fileUploadId); - LOG.warn("Failed to transfer file to repository", e); - } finally { - tryToCloseIOStream(inputStream); - uploadLock.unlock(); - } - } - - private void streamToRepository() { - if (fileUploadId == null) { - throw new ArtifactUploadFailedException(); - } - - final String filename = fileUploadId.getFilename(); - final Artifact artifact = uploadArtifact(filename); - - if (isUploadInterrupted()) { - LOG.warn("Upload of {} was interrupted", filename); - handleUploadFailure(artifact); - publishUploadFinishedEvent(fileUploadId); - return; - } - - publishUploadSucceeded(fileUploadId, artifact.getSize()); - publishUploadFinishedEvent(fileUploadId); - publishArtifactsChanged(fileUploadId); - } - - private Artifact uploadArtifact(final String filename) { - LOG.debug("Transfering file {} directly to repository", filename); - try { - return artifactManagement.create(new ArtifactUpload(inputStream, fileUploadId.getSoftwareModuleId(), - filename, null, null, null, true, mimeType, -1)); - } catch (final InvalidSHA1HashException | InvalidMD5HashException e) { - throw new ArtifactUploadFailedException(e); - } - } - - private void handleUploadFailure(final Artifact artifact) { - Exception exception; - int tries = 0; - do { - try { - artifactManagement.delete(artifact.getId()); - return; - } catch (final RuntimeException e) { - exception = e; - tries++; - } - } while (tries < 5); - LOG.error("Failed to delete artifact from repository after upload was interrupted", exception); - } - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerStreamVariable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerStreamVariable.java deleted file mode 100644 index d681872fa9..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerStreamVariable.java +++ /dev/null @@ -1,183 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.util.concurrent.locks.Lock; - -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.RegexCharacterCollection; -import org.eclipse.hawkbit.repository.SizeConversionHelper; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.io.ByteStreams; -import com.vaadin.server.StreamVariable; - -/** - * {@link StreamVariable} implementation to read and upload a file. One instance - * per file stream is used. - * - * The handler manages the output to the user and at the same time ensures that - * the upload does not exceed the configured max file size. - * - */ -public class FileTransferHandlerStreamVariable extends AbstractFileTransferHandler implements StreamVariable { - - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(FileTransferHandlerStreamVariable.class); - - private final long maxSize; - private final long fileSize; - private final String mimeType; - private final FileUploadId fileUploadId; - - private final SoftwareModule selectedSoftwareModule; - - FileTransferHandlerStreamVariable(final String fileName, final long fileSize, final long maxSize, - final String mimeType, final SoftwareModule selectedSw, final ArtifactManagement artifactManagement, - final VaadinMessageSource i18n, final Lock uploadLock) { - super(artifactManagement, i18n, uploadLock); - this.fileSize = fileSize; - this.maxSize = maxSize; - this.mimeType = mimeType; - this.selectedSoftwareModule = selectedSw; - this.fileUploadId = new FileUploadId(fileName, selectedSw); - - publishUploadStarted(fileUploadId); - } - - /** - * Checks for duplication and invalid file name during file upload process - * - * @param event - * StreamingStartEvent - */ - @Override - public void streamingStarted(final StreamingStartEvent event) { - assertStateConsistency(fileUploadId, event.getFileName()); - - if (RegexCharacterCollection.stringContainsCharacter(event.getFileName(), ILLEGAL_FILENAME_CHARACTERS)) { - LOG.debug("Filename contains illegal characters {} for upload {}", fileUploadId.getFilename(), - fileUploadId); - interruptUploadDueToIllegalFilename(); - } else if (isFileAlreadyContainedInSoftwareModule(fileUploadId, selectedSoftwareModule)) { - LOG.debug("File {} already contained in Software Module {}", fileUploadId.getFilename(), - selectedSoftwareModule); - interruptUploadDueToDuplicateFile(); - } - } - - /** - * get the output stream of uploaded file - * - * @return OutputStream - */ - @Override - public final OutputStream getOutputStream() { - if (isUploadInterrupted()) { - return ByteStreams.nullOutputStream(); - } - - // we return the output stream - we cannot close it here - @SuppressWarnings("squid:S2095") - final PipedOutputStream outputStream = new PipedOutputStream(); - final PipedInputStream inputStream; - try { - inputStream = new PipedInputStream(outputStream); - publishUploadProgressEvent(fileUploadId, 0, fileSize); - startTransferToRepositoryThread(inputStream, fileUploadId, mimeType); - } catch (final IOException e) { - LOG.warn("Creating piped Stream failed {}.", e.getMessage()); - tryToCloseIOStream(outputStream); - // input stream is not created in case of and IOException here - interruptUploadDueToUploadFailed(); - publishUploadFailedAndFinishedEvent(fileUploadId); - return ByteStreams.nullOutputStream(); - } - return outputStream; - } - - /** - * listen progress. - * - * @return boolean - */ - @Override - public boolean listenProgress() { - return true; - } - - /** - * Reports progress in {@link StreamVariable} variant. Interrupts - * - * @see com.vaadin.server.StreamVariable#onProgress(com.vaadin.server.StreamVariable.StreamingProgressEvent) - */ - @Override - public void onProgress(final StreamingProgressEvent event) { - assertStateConsistency(fileUploadId, event.getFileName()); - - if (isUploadInterrupted()) { - publishUploadFailedAndFinishedEvent(fileUploadId); - return; - } - - if (event.getBytesReceived() > maxSize || event.getContentLength() > maxSize) { - interruptUploadDueToFileSizeQuotaExceeded(SizeConversionHelper.byteValueToReadableString(maxSize)); - return; - } - - publishUploadProgressEvent(fileUploadId, event.getBytesReceived(), event.getContentLength()); - } - - /** - * Upload finished for {@link StreamVariable} variant. Called only in good - * case. - * - * @see com.vaadin.server.StreamVariable#streamingFinished(com.vaadin.server.StreamVariable.StreamingEndEvent) - */ - @Override - public void streamingFinished(final StreamingEndEvent event) { - assertStateConsistency(fileUploadId, event.getFileName()); - } - - /** - * Upload failed for{@link StreamVariable} variant. - * - * @param event - * StreamingEndEvent - */ - @Override - public void streamingFailed(final StreamingErrorEvent event) { - assertStateConsistency(fileUploadId, event.getFileName()); - - if (!isUploadInterrupted()) { - interruptUploadDueToUploadFailed(); - } - LOG.debug("Streaming of file {} failed due to following exception: {}", fileUploadId, event.getException()); - publishUploadFailedAndFinishedEvent(fileUploadId); - } - - /** - * Verify if upload process is interrupted - * - * @return boolean - */ - @Override - public boolean isInterrupted() { - return isUploadInterrupted(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerVaadinUpload.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerVaadinUpload.java deleted file mode 100644 index 77d97a8d23..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerVaadinUpload.java +++ /dev/null @@ -1,212 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.util.concurrent.locks.Lock; - -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.RegexCharacterCollection; -import org.eclipse.hawkbit.repository.SizeConversionHelper; -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.io.ByteStreams; -import com.vaadin.ui.Upload; -import com.vaadin.ui.Upload.FailedEvent; -import com.vaadin.ui.Upload.FailedListener; -import com.vaadin.ui.Upload.FinishedEvent; -import com.vaadin.ui.Upload.FinishedListener; -import com.vaadin.ui.Upload.ProgressListener; -import com.vaadin.ui.Upload.Receiver; -import com.vaadin.ui.Upload.StartedEvent; -import com.vaadin.ui.Upload.StartedListener; -import com.vaadin.ui.Upload.SucceededEvent; -import com.vaadin.ui.Upload.SucceededListener; - -/** - * Vaadin Upload implementation to read and upload a file. One instance is used - * to handle all the uploads. - * - * The handler manages the output to the user and at the same time ensures that - * the upload does not exceed the configured max file size. - * - */ -public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler - implements Receiver, SucceededListener, FailedListener, FinishedListener, ProgressListener, StartedListener { - - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(FileTransferHandlerVaadinUpload.class); - - private final transient SoftwareModuleManagement softwareModuleManagement; - private final long maxSize; - - private FileUploadId fileUploadId; - - FileTransferHandlerVaadinUpload(final long maxSize, final SoftwareModuleManagement softwareManagement, - final ArtifactManagement artifactManagement, final VaadinMessageSource i18n, final Lock uploadLock) { - super(artifactManagement, i18n, uploadLock); - - this.maxSize = maxSize; - this.softwareModuleManagement = softwareManagement; - } - - private synchronized FileUploadId setFileUploadId(final String fileName, final SoftwareModule softwareModule) { - this.fileUploadId = new FileUploadId(fileName, softwareModule); - return fileUploadId; - } - - /** - * Upload started for {@link Upload} variant. - * - * @see com.vaadin.ui.Upload.StartedListener#uploadStarted(com.vaadin.ui.Upload.StartedEvent) - */ - @Override - public void uploadStarted(final StartedEvent event) { - // reset internal state here because instance is reused for next upload! - resetState(); - - final SoftwareModule softwareModule = getSelectedSoftwareModule(); - final FileUploadId fupId = setFileUploadId(event.getFilename(), softwareModule); - - if (getUploadState().isFileInUploadState(this.fileUploadId)) { - // actual interrupt will happen a bit late so setting the below - // flag - interruptUploadDueToDuplicateFile(); - event.getUpload().interruptUpload(); - } else { - publishUploadStarted(fupId); - - if (RegexCharacterCollection.stringContainsCharacter(event.getFilename(), ILLEGAL_FILENAME_CHARACTERS)) { - LOG.debug("Filename contains illegal characters {} for upload {}", fupId.getFilename(), fupId); - interruptUploadDueToIllegalFilename(); - event.getUpload().interruptUpload(); - } else if (isFileAlreadyContainedInSoftwareModule(fupId, softwareModule)) { - LOG.debug("File {} already contained in Software Module {}", fupId.getFilename(), - softwareModule); - interruptUploadDueToDuplicateFile(); - event.getUpload().interruptUpload(); - } - } - } - - private SoftwareModule getSelectedSoftwareModule() { - final Long lastSelectedSmId = getUploadState().getSmGridLayoutUiState().getSelectedEntityId(); - - return softwareModuleManagement.get(lastSelectedSmId) - .orElseThrow(() -> new IllegalStateException("SoftwareModul with unknown ID selected")); - } - - /** - * Create stream for {@link Upload} variant. - * - * @see com.vaadin.ui.Upload.Receiver#receiveUpload(java.lang.String, - * java.lang.String) - */ - @Override - public OutputStream receiveUpload(final String fileName, final String mimeType) { - if (isUploadInterrupted()) { - return ByteStreams.nullOutputStream(); - } - - // we return the outputstream so we cannot close it here - @SuppressWarnings("squid:S2095") - final PipedOutputStream outputStream = new PipedOutputStream(); - try { - PipedInputStream inputStream = new PipedInputStream(outputStream); - publishUploadProgressEvent(fileUploadId, 0, 0); - startTransferToRepositoryThread(inputStream, fileUploadId, mimeType); - } catch (final IOException e) { - LOG.warn("Creating piped Stream failed!", e); - tryToCloseIOStream(outputStream); - // input stream is not created in case of an IOException - interruptUploadDueToUploadFailed(); - publishUploadFailedAndFinishedEvent(fileUploadId); - return ByteStreams.nullOutputStream(); - } - return outputStream; - } - - /** - * Reports progress in {@link Upload} variant. - * - * @see com.vaadin.ui.Upload.ProgressListener#updateProgress(long, long) - */ - @Override - public void updateProgress(final long readBytes, final long contentLength) { - if (isUploadInterrupted()) { - publishUploadFailedAndFinishedEvent(fileUploadId); - return; - } - - if (readBytes > maxSize || contentLength > maxSize) { - interruptUploadDueToFileSizeQuotaExceeded(SizeConversionHelper.byteValueToReadableString(maxSize)); - return; - } - - publishUploadProgressEvent(fileUploadId, readBytes, contentLength); - } - - /** - * - * Upload sucessfull for {@link Upload} variant. - * - * @see com.vaadin.ui.Upload.SucceededListener#uploadSucceeded(com.vaadin.ui.Upload.SucceededEvent) - */ - @Override - public void uploadSucceeded(final SucceededEvent event) { - if (isUploadInterrupted()) { - // Upload interruption is delayed maybe another event is fired - // before - return; - } - assertStateConsistency(fileUploadId, event.getFilename()); - } - - /** - * Upload finished for {@link Upload} variant. Both for good and error - * variant. - * - * @see com.vaadin.ui.Upload.FinishedListener#uploadFinished(com.vaadin.ui.Upload.FinishedEvent) - */ - @Override - public void uploadFinished(final FinishedEvent event) { - // ignore this event - } - - /** - * Upload failed for {@link Upload} variant. - * - * @see com.vaadin.ui.Upload.FailedListener#uploadFailed(com.vaadin.ui.Upload.FailedEvent) - */ - @Override - public void uploadFailed(final FailedEvent event) { - assertStateConsistency(fileUploadId, event.getFilename()); - - if (!isUploadInterrupted()) { - interruptUploadDueToUploadFailed(); - } - LOG.debug("Upload of file {} failed due to following exception: {}", fileUploadId, event.getReason()); - publishUploadFailedAndFinishedEvent(fileUploadId); - } - - @Override - protected void resetState() { - super.resetState(); - this.fileUploadId = null; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadId.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadId.java deleted file mode 100644 index 9116ba18ec..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadId.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.Serializable; -import java.util.Objects; - -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; - -/** - * The {@link FileUploadId} identifies a file that is uploaded for a - * {@link SoftwareModule}. - * - */ -public class FileUploadId implements Serializable { - private static final long serialVersionUID = 1L; - - private final String filename; - - private final Long softwareModuleId; - private final String softwareModuleName; - private final String softwareModuleVersion; - - /** - * Creates a new {@link FileUploadId} instance. - * - * @param filename - * the name of the file - * @param softwareModule - * the {@link SoftwareModule} for which the file is uploaded - */ - public FileUploadId(final String filename, final SoftwareModule softwareModule) { - this.filename = filename; - this.softwareModuleId = softwareModule.getId(); - this.softwareModuleName = softwareModule.getName(); - this.softwareModuleVersion = softwareModule.getVersion(); - } - - public String getFilename() { - return filename; - } - - public Long getSoftwareModuleId() { - return softwareModuleId; - } - - public String getSoftwareModuleName() { - return softwareModuleName; - } - - public String getSoftwareModuleVersion() { - return softwareModuleVersion; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final FileUploadId other = (FileUploadId) obj; - return Objects.equals(this.getFilename(), other.getFilename()) - && Objects.equals(this.getSoftwareModuleId(), other.getSoftwareModuleId()) - && Objects.equals(this.getSoftwareModuleName(), other.getSoftwareModuleName()) - && Objects.equals(this.getSoftwareModuleVersion(), other.getSoftwareModuleVersion()); - } - - @Override - public int hashCode() { - return Objects.hash(getFilename(), getSoftwareModuleId(), getSoftwareModuleName(), getSoftwareModuleVersion()); - } - - @Override - public String toString() { - return new StringBuilder(filename).append(":") - .append(HawkbitCommonUtil.getFormattedNameVersion(softwareModuleName, softwareModuleVersion)) - .toString(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadProgress.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadProgress.java deleted file mode 100644 index 381e3165a6..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadProgress.java +++ /dev/null @@ -1,193 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.Serializable; - -/** - * Holds file and upload progress details. - */ -public class FileUploadProgress implements Serializable { - - /** - * Status of a file upload. - */ - public enum FileUploadStatus { - - /** - * An upload for a file has been started. - */ - UPLOAD_STARTED, - - /** - * Progress changed for one file upload. - */ - UPLOAD_IN_PROGRESS, - - /** - * Upload of one file failed. - */ - UPLOAD_FAILED, - - /** - * One file upload succeeded. - */ - UPLOAD_SUCCESSFUL, - - /** - * One file upload finished () - */ - UPLOAD_FINISHED - } - - private static final long serialVersionUID = 1L; - - private final FileUploadId fileUploadId; - - private long contentLength; - - private long bytesRead; - - private String failureReason; - - private String filePath; - - private final FileUploadStatus fileUploadStatus; - - /** - * Creates a new {@link FileUploadProgress} instance. - * - * @param fileUploadId - * the {@link FileUploadId} to which this progress information - * belongs. - * @param fileUploadStatus - * the {@link FileUploadStatus} of this progress - */ - public FileUploadProgress(final FileUploadId fileUploadId, final FileUploadStatus fileUploadStatus) { - this.fileUploadId = fileUploadId; - this.fileUploadStatus = fileUploadStatus; - } - - /** - * Creates a new {@link FileUploadProgress} instance. - * - * @param fileUploadId - * the {@link FileUploadId} to which this progress information - * belongs. - * @param fileUploadStatus - * the {@link FileUploadStatus} of this progress - * @param bytesRead - * number of bytes read - * @param contentLength - * size of the file in bytes - */ - FileUploadProgress(final FileUploadId fileUploadId, final FileUploadStatus fileUploadStatus, final long bytesRead, - final long contentLength) { - this.fileUploadId = fileUploadId; - this.fileUploadStatus = fileUploadStatus; - this.contentLength = contentLength; - this.bytesRead = bytesRead; - } - - /** - * Creates a new {@link FileUploadProgress} instance. - * - * @param fileUploadId - * the {@link FileUploadId} to which this progress information - * belongs. - * @param fileUploadStatus - * the {@link FileUploadStatus} of this progress - * @param bytesRead - * number of bytes read - * @param contentLength - * size of the file in bytes - * @param filePath - * the path of the file - */ - FileUploadProgress(final FileUploadId fileUploadId, final FileUploadStatus fileUploadStatus, final long bytesRead, - final long contentLength, final String filePath) { - this.fileUploadId = fileUploadId; - this.fileUploadStatus = fileUploadStatus; - this.contentLength = contentLength; - this.bytesRead = bytesRead; - this.filePath = filePath; - } - - /** - * Creates a new {@link FileUploadProgress} instance. - * - * @param fileUploadId - * the {@link FileUploadId} to which this progress information - * belongs. - * @param fileUploadStatus - * the {@link FileUploadStatus} of this progress - * @param failureReason - * the reason of the failed upload - */ - FileUploadProgress(final FileUploadId fileUploadId, final FileUploadStatus fileUploadStatus, - final String failureReason) { - this.fileUploadId = fileUploadId; - this.fileUploadStatus = fileUploadStatus; - this.failureReason = failureReason; - } - - /** - * Getter for file upload ID - * - * @return FileUploadId - */ - public FileUploadId getFileUploadId() { - return fileUploadId; - } - - /** - * Getter for file content length - * - * @return long - */ - public long getContentLength() { - return contentLength; - } - - /** - * Getter for bytes read of the file - * - * @return long - */ - public long getBytesRead() { - return bytesRead; - } - - /** - * Getter for failed reason for upload - * @return String - */ - public String getFailureReason() { - return failureReason; - } - - /** - * Getter for file path - * - * @return String - */ - public String getFilePath() { - return filePath; - } - - /** - * Get Status of a file upload - * - * @return FileUploadStatus - */ - public FileUploadStatus getFileUploadStatus() { - return fileUploadStatus; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadDropAreaLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadDropAreaLayout.java deleted file mode 100644 index baec4a86b0..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadDropAreaLayout.java +++ /dev/null @@ -1,234 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.util.Collection; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import javax.servlet.MultipartConfigElement; - -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.ArtifactUploadState; -import org.eclipse.hawkbit.ui.common.CommonUiDependencies; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxySoftwareModule; -import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; - -import com.vaadin.icons.VaadinIcons; -import com.vaadin.shared.ui.ContentMode; -import com.vaadin.ui.CustomComponent; -import com.vaadin.ui.Html5File; -import com.vaadin.ui.Label; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.dnd.FileDropHandler; -import com.vaadin.ui.dnd.FileDropTarget; -import com.vaadin.ui.dnd.event.FileDropEvent; - -/** - * Container for drag and drop area in the upload view. - */ -public class UploadDropAreaLayout extends CustomComponent implements MasterEntityAwareComponent { - private static final long serialVersionUID = 1L; - - private final VaadinMessageSource i18n; - private final UINotification uiNotification; - - private final ArtifactUploadState artifactUploadState; - - private final transient ArtifactManagement artifactManagement; - private final transient SoftwareModuleManagement softwareManagement; - - private final transient MultipartConfigElement multipartConfigElement; - private final transient Lock uploadLock = new ReentrantLock(); - - private final UploadProgressButtonLayout uploadButtonLayout; - private VerticalLayout dropAreaLayout; - - /** - * Creates a new {@link UploadDropAreaLayout} instance. - * - * @param uiDependencies - * the {@link CommonUiDependencies} - * @param artifactUploadState - * the {@link ArtifactUploadState} for state information - * @param multipartConfigElement - * the {@link MultipartConfigElement} - * @param softwareManagement - * the {@link SoftwareModuleManagement} for retrieving the - * {@link SoftwareModule} - * @param artifactManagement - * the {@link ArtifactManagement} for storing the uploaded - * artifacts - */ - public UploadDropAreaLayout(final CommonUiDependencies uiDependencies, final ArtifactUploadState artifactUploadState, - final MultipartConfigElement multipartConfigElement, final SoftwareModuleManagement softwareManagement, - final ArtifactManagement artifactManagement) { - this.i18n = uiDependencies.getI18n(); - this.uiNotification = uiDependencies.getUiNotification(); - this.artifactUploadState = artifactUploadState; - this.multipartConfigElement = multipartConfigElement; - this.softwareManagement = softwareManagement; - this.artifactManagement = artifactManagement; - - this.uploadButtonLayout = new UploadProgressButtonLayout(i18n, uiDependencies.getEventBus(), artifactUploadState, - multipartConfigElement, artifactManagement, softwareManagement, uploadLock); - - buildLayout(); - } - - private void buildLayout() { - dropAreaLayout = new VerticalLayout(); - dropAreaLayout.setId(UIComponentIdProvider.UPLOAD_ARTIFACT_FILE_DROP_LAYOUT); - dropAreaLayout.setMargin(false); - dropAreaLayout.setSpacing(false); - dropAreaLayout.addStyleName("upload-drop-area-layout-info"); - dropAreaLayout.setEnabled(false); - dropAreaLayout.setHeightUndefined(); - - final Label dropIcon = new Label(VaadinIcons.ARROW_DOWN.getHtml(), ContentMode.HTML); - dropIcon.addStyleName("drop-icon"); - dropIcon.setWidth(null); - dropAreaLayout.addComponent(dropIcon); - - final Label dropHereLabel = new Label(i18n.getMessage(UIMessageIdProvider.LABEL_DROP_AREA_UPLOAD)); - dropHereLabel.setWidth(null); - dropAreaLayout.addComponent(dropHereLabel); - - uploadButtonLayout.setWidth(null); - uploadButtonLayout.addStyleName("upload-button"); - dropAreaLayout.addComponent(uploadButtonLayout); - - new FileDropTarget<>(dropAreaLayout, new UploadFileDropHandler()); - - setCompositionRoot(dropAreaLayout); - } - - /** - * Update the upload view on file drop - * - * @param masterEntity - * ProxySoftwareModule - */ - @Override - public void masterEntityChanged(final ProxySoftwareModule masterEntity) { - final Long masterEntityId = masterEntity != null ? masterEntity.getId() : null; - - dropAreaLayout.setEnabled(masterEntityId != null); - uploadButtonLayout.updateMasterEntityFilter(masterEntityId); - } - - /** - * Checks progress on file upload - * - * @param fileUploadProgress - * FileUploadProgress - */ - public void onUploadChanged(final FileUploadProgress fileUploadProgress) { - uploadButtonLayout.onUploadChanged(fileUploadProgress); - } - - /** - * Is called when view is shown to the user - */ - public void restoreState() { - uploadButtonLayout.restoreState(); - } - - /** - * Get file drop area layout - * - * @return VerticalLayout - */ - public VerticalLayout getDropAreaLayout() { - return dropAreaLayout; - } - - /** - * Get File upload button layout - * - * @return UploadProgressButtonLayout - */ - public UploadProgressButtonLayout getUploadButtonLayout() { - return uploadButtonLayout; - } - - private class UploadFileDropHandler implements FileDropHandler { - - private static final long serialVersionUID = 1L; - - /** - * Validates the file drop events and triggers the upload - * - * @param event - * FileDropEvent - */ - @Override - public void drop(final FileDropEvent event) { - if (validate(event)) { - // selected software module at the time of file drop is - // considered for upload - final Long lastSelectedSmId = artifactUploadState.getSmGridLayoutUiState().getSelectedEntityId(); - if (lastSelectedSmId != null) { - uploadFilesForSoftwareModule(event.getFiles(), lastSelectedSmId); - } - } - } - - private void uploadFilesForSoftwareModule(final Collection files, final Long softwareModuleId) { - final SoftwareModule softwareModule = softwareManagement.get(softwareModuleId).orElse(null); - - boolean duplicateFound = false; - - for (final Html5File file : files) { - if (artifactUploadState.isFileInUploadState(file.getFileName(), softwareModule)) { - duplicateFound = true; - } else { - file.setStreamVariable(new FileTransferHandlerStreamVariable(file.getFileName(), file.getFileSize(), - multipartConfigElement.getMaxFileSize(), file.getType(), softwareModule, artifactManagement, - i18n, uploadLock)); - } - } - if (duplicateFound) { - uiNotification.displayValidationError(i18n.getMessage("message.no.duplicateFiles")); - } - } - - private boolean validate(final FileDropEvent event) { - // check if drop is valid.If valid ,check if software module is - // selected. - if (!isFilesDropped(event)) { - uiNotification.displayValidationError(i18n.getMessage("message.drop.onlyFiles")); - return false; - } - return validateSoftwareModuleSelection(); - } - - private boolean isFilesDropped(final FileDropEvent event) { - return event.getFiles() != null; - } - - private boolean validateSoftwareModuleSelection() { - final Long lastSelectedSmId = artifactUploadState.getSmGridLayoutUiState().getSelectedEntityId(); - - if (lastSelectedSmId == null) { - uiNotification.displayValidationError(i18n.getMessage("message.error.noSwModuleSelected")); - return false; - } - - return true; - } - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadFixed.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadFixed.java deleted file mode 100644 index a934fba041..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadFixed.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.OutputStream; - -import com.vaadin.server.StreamVariable; -import com.vaadin.ui.Upload; - -/** - * The {@link Upload} class has a bug.The lifecycle methods of the registered - * handler - * com.vaadin.ui.Upload.StartedListener#uploadStarted(com.vaadin.ui.Upload.StartedEvent) - * etc are called even the upload was interrupted. This bug is fixed in this - * class. - * - */ -public class UploadFixed extends Upload { - - private static final long serialVersionUID = 1L; - - private boolean uploadInterrupted; - - /** - * Stops the file upload - */ - @Override - public void interruptUpload() { - super.interruptUpload(); - uploadInterrupted = true; - } - - @Override - protected StreamVariable getStreamVariable() { - return new StreamVariableFixed(super.getStreamVariable()); - } - - private class StreamVariableFixed implements StreamVariable { - private static final long serialVersionUID = 1L; - private final StreamVariable originalStreamVariable; - - /** - * Constructor for StreamVariableFixed - * - * @param originalStreamVariable - * StreamVariable - */ - public StreamVariableFixed(final StreamVariable originalStreamVariable) { - this.originalStreamVariable = originalStreamVariable; - } - - @Override - public boolean listenProgress() { - // this fixes the vaadin bug - return originalStreamVariable.listenProgress() && !uploadInterrupted; - } - - @Override - public void onProgress(final StreamingProgressEvent event) { - originalStreamVariable.onProgress(event); - } - - @Override - public boolean isInterrupted() { - return uploadInterrupted; - } - - @Override - public OutputStream getOutputStream() { - return originalStreamVariable.getOutputStream(); - } - - @Override - public void streamingStarted(final StreamingStartEvent event) { - originalStreamVariable.streamingStarted(event); - } - - @Override - public void streamingFinished(final StreamingEndEvent event) { - originalStreamVariable.streamingFinished(event); - } - - @Override - public void streamingFailed(final StreamingErrorEvent event) { - originalStreamVariable.streamingFailed(event); - uploadInterrupted = false; - } - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressButtonLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressButtonLayout.java deleted file mode 100644 index c2c73c8a2a..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressButtonLayout.java +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.util.concurrent.locks.Lock; - -import javax.servlet.MultipartConfigElement; - -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.ArtifactUploadState; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.ui.Button; -import com.vaadin.ui.UI; -import com.vaadin.ui.Upload; -import com.vaadin.ui.VerticalLayout; - -/** - * Container for upload and progress button. - */ -public class UploadProgressButtonLayout extends VerticalLayout { - private static final long serialVersionUID = 1L; - - private final VaadinMessageSource i18n; - - private final ArtifactUploadState artifactUploadState; - - private final transient ArtifactManagement artifactManagement; - private final transient SoftwareModuleManagement softwareModuleManagement; - - private final transient MultipartConfigElement multipartConfigElement; - private final Upload upload; - private final transient Lock uploadLock; - - private final UploadProgressInfoWindow uploadInfoWindow; - - private Button uploadProgressButton; - - /** - * Creates a new {@link UploadProgressButtonLayout} instance. - * - * @param i18n - * the {@link VaadinMessageSource} - * @param eventBus - * the {@link UIEventBus} for listening to ui events - * @param artifactUploadState - * the {@link ArtifactUploadState} for state information - * @param multipartConfigElement - * the {@link MultipartConfigElement} - * @param softwareManagement - * the {@link SoftwareModuleManagement} for retrieving the - * {@link SoftwareModule} - * @param artifactManagement - * the {@link ArtifactManagement} for storing the uploaded - * artifacts - * @param uploadLock - * A common upload lock that enforced sequential upload within an - * UI instance - */ - public UploadProgressButtonLayout(final VaadinMessageSource i18n, final UIEventBus eventBus, - final ArtifactUploadState artifactUploadState, final MultipartConfigElement multipartConfigElement, - final ArtifactManagement artifactManagement, final SoftwareModuleManagement softwareManagement, - final Lock uploadLock) { - this.artifactUploadState = artifactUploadState; - this.artifactManagement = artifactManagement; - this.uploadInfoWindow = new UploadProgressInfoWindow(i18n, artifactUploadState); - this.uploadInfoWindow.addCloseListener(event -> { - // ensure that the progress button is hidden when the progress - // window is closed and no more uploads running - if (artifactUploadState.areAllUploadsFinished()) { - hideUploadProgressButton(); - } - }); - this.i18n = i18n; - this.multipartConfigElement = multipartConfigElement; - this.softwareModuleManagement = softwareManagement; - this.upload = new UploadFixed(); - this.uploadLock = uploadLock; - - createComponents(); - buildLayout(); - } - - /** - * Perform specific tasks based on the file upload status - * - * @param fileUploadProgress - * FileUploadProgress - */ - public void onUploadChanged(final FileUploadProgress fileUploadProgress) { - final FileUploadProgress.FileUploadStatus uploadProgressEventType = fileUploadProgress.getFileUploadStatus(); - - switch (uploadProgressEventType) { - case UPLOAD_STARTED: - UI.getCurrent().access(() -> { - onStartOfUpload(); - uploadInfoWindow.onUploadStarted(fileUploadProgress); - }); - break; - case UPLOAD_FAILED: - case UPLOAD_SUCCESSFUL: - case UPLOAD_IN_PROGRESS: - UI.getCurrent().access(() -> uploadInfoWindow.updateUploadProgressInfoRowObject(fileUploadProgress)); - break; - case UPLOAD_FINISHED: - UI.getCurrent().access(() -> { - onUploadFinished(); - uploadInfoWindow.onUploadFinished(); - }); - break; - default: - throw new IllegalArgumentException("Enum " + FileUploadProgress.FileUploadStatus.class.getSimpleName() - + " doesn't contain value " + uploadProgressEventType); - } - } - - /** - * Enable the upload view after upload is finished - * - * @param masterEntityId - * Long - */ - public void updateMasterEntityFilter(final Long masterEntityId) { - upload.setEnabled(masterEntityId != null && artifactUploadState.areAllUploadsFinished()); - } - - private void createComponents() { - uploadProgressButton = SPUIComponentProvider.getButton(UIComponentIdProvider.UPLOAD_STATUS_BUTTON, "", "", "", - false, null, SPUIButtonStyleNoBorder.class); - uploadProgressButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); - uploadProgressButton.addClickListener(event -> showUploadInfoWindow()); - } - - private void buildLayout() { - final FileTransferHandlerVaadinUpload uploadHandler = new FileTransferHandlerVaadinUpload( - multipartConfigElement.getMaxFileSize(), softwareModuleManagement, artifactManagement, i18n, - uploadLock); - upload.setButtonCaption(i18n.getMessage("upload.file")); - upload.setReceiver(uploadHandler); - upload.addSucceededListener(uploadHandler); - upload.addFailedListener(uploadHandler); - upload.addFinishedListener(uploadHandler); - upload.addProgressListener(uploadHandler); - upload.addStartedListener(uploadHandler); - upload.setId(UIComponentIdProvider.UPLOAD_BUTTON); - - addComponent(upload); - setSizeFull(); - setMargin(false); - } - - /** - * Is called when view is shown to the user - */ - public void restoreState() { - if (artifactUploadState.areAllUploadsFinished()) { - artifactUploadState.clearUploadTempData(); - hideUploadProgressButton(); - upload.setEnabled(true); - } else if (artifactUploadState.isAtLeastOneUploadInProgress()) { - showUploadProgressButton(); - } - } - - private void onStartOfUpload() { - showUploadProgressButton(); - } - - /** - * Called for every finished (succeeded or failed) upload. - */ - private void onUploadFinished() { - if (artifactUploadState.areAllUploadsFinished()) { - hideUploadProgressButton(); - upload.setEnabled(true); - artifactUploadState.clearUploadTempData(); - } - } - - /** - * Maximize the file upload view - */ - public void showUploadInfoWindow() { - uploadInfoWindow.maximizeWindow(); - } - - private void showUploadProgressButton() { - removeComponent(upload); - addComponent(uploadProgressButton); - } - - private void hideUploadProgressButton() { - removeComponent(uploadProgressButton); - addComponent(upload); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressGrid.java deleted file mode 100644 index 58c924ff98..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressGrid.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import org.eclipse.hawkbit.ui.common.builder.GridComponentBuilder; -import org.eclipse.hawkbit.ui.common.builder.StatusIconBuilder.ProgressStatusIconSupplier; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyUploadProgress; -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 com.vaadin.ui.Grid; -import com.vaadin.ui.renderers.ProgressBarRenderer; - -/** - * Grid for Upload Progress pop up info window. - */ -public class UploadProgressGrid extends Grid { - private static final long serialVersionUID = 1L; - - private final VaadinMessageSource i18n; - - private static final String UPLOAD_PROGRESS_STATUS_ID = "uploadProgressStatus"; - private static final String UPLOAD_PROGRESS_BAR_ID = "uploadProgressBar"; - private static final String UPLOAD_PROGRESS_FILENAME_ID = "uploadProgressFileName"; - private static final String UPLOAD_PROGRESS_SM_ID = "uploadProgressSm"; - private static final String UPLOAD_PROGRESS_REASON_ID = "uploadProgressReason"; - - private final ProgressStatusIconSupplier progressStatusIconSupplier; - - /** - * Constructor for UploadProgressGrid - * - * @param i18n - * VaadinMessageSource - */ - public UploadProgressGrid(final VaadinMessageSource i18n) { - this.i18n = i18n; - - progressStatusIconSupplier = new ProgressStatusIconSupplier<>(i18n, ProxyUploadProgress::getStatus, - UIComponentIdProvider.UPLOAD_STATUS_LABEL_ID); - init(); - } - - private void init() { - setId(UIComponentIdProvider.UPLOAD_STATUS_POPUP_GRID); - addStyleName(SPUIStyleDefinitions.UPLOAD_STATUS_GRID); - setSelectionMode(SelectionMode.NONE); - setSizeFull(); - - addColumns(); - } - - private void addColumns() { - GridComponentBuilder.addIconColumn(this, progressStatusIconSupplier::getLabel, UPLOAD_PROGRESS_STATUS_ID, - i18n.getMessage(UIMessageIdProvider.CAPTION_ARTIFACT_UPLOAD_STATUS)); - - addColumn(ProxyUploadProgress::getProgress, new ProgressBarRenderer()).setId(UPLOAD_PROGRESS_BAR_ID) - .setCaption(i18n.getMessage(UIMessageIdProvider.CAPTION_ARTIFACT_UPLOAD_PROGRESS)).setExpandRatio(1); - - GridComponentBuilder.addColumn(this, uploadProgress -> uploadProgress.getFileUploadId().getFilename()) - .setId(UPLOAD_PROGRESS_FILENAME_ID) - .setCaption(i18n.getMessage(UIMessageIdProvider.CAPTION_ARTIFACT_FILENAME)); - - GridComponentBuilder - .addColumn(this, - uploadProgress -> HawkbitCommonUtil.getFormattedNameVersion( - uploadProgress.getFileUploadId().getSoftwareModuleName(), - uploadProgress.getFileUploadId().getSoftwareModuleVersion())) - .setId(UPLOAD_PROGRESS_SM_ID).setCaption(i18n.getMessage(UIMessageIdProvider.CAPTION_SOFTWARE_MODULE)); - - GridComponentBuilder.addColumn(this, ProxyUploadProgress::getReason).setId(UPLOAD_PROGRESS_REASON_ID) - .setCaption(i18n.getMessage(UIMessageIdProvider.CAPTION_ARTIFACT_UPLOAD_REASON)); - - getColumns().forEach(col -> col.setSortable(false)); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressInfoWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressInfoWindow.java deleted file mode 100644 index 25f4c5dce0..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressInfoWindow.java +++ /dev/null @@ -1,251 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.hawkbit.ui.artifacts.ArtifactUploadState; -import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyUploadProgress; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyUploadProgress.ProgressSatus; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; -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 com.vaadin.icons.VaadinIcons; -import com.vaadin.shared.ui.window.WindowMode; -import com.vaadin.ui.Button; -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.themes.ValoTheme; - -/** - * Window that shows the progress of all uploads. - */ -public class UploadProgressInfoWindow extends Window { - private static final long serialVersionUID = 1L; - - private final VaadinMessageSource i18n; - - private final ArtifactUploadState artifactUploadState; - - private final UploadProgressGrid uploadProgressGrid; - private final VerticalLayout mainLayout; - - private Label windowCaption; - private Button closeButton; - - private final List uploads; - - UploadProgressInfoWindow(final VaadinMessageSource i18n, final ArtifactUploadState artifactUploadState) { - this.i18n = i18n; - this.artifactUploadState = artifactUploadState; - - setPopupProperties(); - createStatusPopupHeaderComponents(); - - mainLayout = new VerticalLayout(); - mainLayout.setSpacing(Boolean.TRUE); - mainLayout.setSizeUndefined(); - setPopupSizeInMinMode(); - - uploads = new ArrayList<>(); - uploadProgressGrid = new UploadProgressGrid(i18n); - uploadProgressGrid.setItems(uploads); - - mainLayout.addComponents(getCaptionLayout(), uploadProgressGrid); - mainLayout.setExpandRatio(uploadProgressGrid, 1.0F); - setContent(mainLayout); - } - - /** - * Updates the status of each file uploaded in the grid view - * - * @param fileUploadProgress - * FileUploadProgress - */ - public void updateUploadProgressInfoRowObject(final FileUploadProgress fileUploadProgress) { - final FileUploadId fileUploadId = fileUploadProgress.getFileUploadId(); - final ProxyUploadProgress gridUploadItem = uploads.stream() - .filter(upload -> upload.getFileUploadId().equals(fileUploadId)).findAny() - .orElse(new ProxyUploadProgress()); - - gridUploadItem.setStatus(getStatusRepresentaion(fileUploadProgress.getFileUploadStatus())); - gridUploadItem.setReason(getFailureReason(fileUploadId)); - - final long bytesRead = fileUploadProgress.getBytesRead(); - final long fileSize = fileUploadProgress.getContentLength(); - if (bytesRead > 0 && fileSize > 0) { - gridUploadItem.setProgress((double) bytesRead / (double) fileSize); - } - - if (gridUploadItem.getFileUploadId() == null) { - gridUploadItem.setFileUploadId(fileUploadId); - uploads.add(gridUploadItem); - } - - uploadProgressGrid.getDataProvider().refreshItem(gridUploadItem); - } - - private static ProgressSatus getStatusRepresentaion(final FileUploadStatus uploadStatus) { - if (uploadStatus == FileUploadStatus.UPLOAD_FAILED) { - return ProgressSatus.FAILED; - } else if (uploadStatus == FileUploadStatus.UPLOAD_SUCCESSFUL) { - return ProgressSatus.FINISHED; - } else { - return ProgressSatus.INPROGRESS; - } - } - - /** - * Returns the failure reason for the provided fileUploadId or an empty - * string but never null. - * - * @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; - } - - /** - * Starts the file upload process and maximize the upload view - * - * @param fileUploadProgress - * FileUploadProgress - */ - public void onUploadStarted(final FileUploadProgress fileUploadProgress) { - updateUploadProgressInfoRowObject(fileUploadProgress); - - if (isWindowNotAlreadyAttached()) { - maximizeWindow(); - } - } - - private boolean isWindowNotAlreadyAttached() { - return !UI.getCurrent().getWindows().contains(this); - } - - private void restoreState() { - uploads.clear(); - for (final FileUploadProgress fileUploadProgress : artifactUploadState - .getAllFileUploadProgressValuesFromOverallUploadProcessList()) { - updateUploadProgressInfoRowObject(fileUploadProgress); - } - } - - private void setPopupProperties() { - setId(UIComponentIdProvider.UPLOAD_STATUS_POPUP_ID); - addStyleName(SPUIStyleDefinitions.UPLOAD_INFO); - - setResizable(false); - setDraggable(true); - setClosable(false); - setModal(true); - } - - 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 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. - */ - public void onUploadFinished() { - if (artifactUploadState.areAllUploadsFinished() && artifactUploadState.isStatusPopupMinimized()) { - if (artifactUploadState.getFilesInFailedState().isEmpty()) { - cleanupStates(); - closeWindow(); - } else { - maximizeWindow(); - } - } - } - - private void cleanupStates() { - uploads.clear(); - 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, VaadinIcons.CLOSE, - 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); - setPopupSizeInMinMode(); - close(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/autoconfigure/MgmtUiAutoConfiguration.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/autoconfigure/MgmtUiAutoConfiguration.java deleted file mode 100644 index 05a1463287..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/autoconfigure/MgmtUiAutoConfiguration.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.autoconfigure; - -import java.util.concurrent.ScheduledExecutorService; - -import org.eclipse.hawkbit.DistributedResourceBundleMessageSource; -import org.eclipse.hawkbit.ui.MgmtUiConfiguration; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.UiProperties; -import org.eclipse.hawkbit.ui.push.DelayedEventBusPushStrategy; -import org.eclipse.hawkbit.ui.push.EventPushStrategy; -import org.eclipse.hawkbit.ui.push.HawkbitEventPermissionChecker; -import org.eclipse.hawkbit.ui.push.HawkbitEventProvider; -import org.eclipse.hawkbit.ui.push.UIEventPermissionChecker; -import org.eclipse.hawkbit.ui.push.UIEventProvider; -import org.eclipse.hawkbit.ui.utils.SpringContextHolder; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.vaadin.spring.annotation.EnableVaadinExtensions; -import org.vaadin.spring.events.EventBus.UIEventBus; -import org.vaadin.spring.events.annotation.EnableEventBus; - -import com.vaadin.spring.annotation.UIScope; - -/** - * The Management UI auto configuration. - */ -@Configuration -@EnableVaadinExtensions -@EnableEventBus -@ConditionalOnClass(MgmtUiConfiguration.class) -@Import(MgmtUiConfiguration.class) -public class MgmtUiAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - RedirectController uiRedirectController() { - return new RedirectController(); - } - - /** - * A message source bean to add distributed message sources. - * - * @return the message bean. - */ - @Bean(name = "messageSource") - DistributedResourceBundleMessageSource messageSource() { - return new DistributedResourceBundleMessageSource(); - } - - /** - * A event provider bean which hold the supported events for the UI. - * - * @return the provider bean - */ - @Bean - @ConditionalOnMissingBean - UIEventProvider eventProvider() { - return new HawkbitEventProvider(); - } - - /** - * A event permission checker bean which verifies supported events for the - * UI. - * - * @return the permission checker bean - */ - @Bean - @ConditionalOnMissingBean - UIEventPermissionChecker eventPermissionChecker(final SpPermissionChecker permChecker) { - return new HawkbitEventPermissionChecker(permChecker); - } - - /** - * Bean for creating a singleton instance of the {@link SpringContextHolder} - * - * @return the singleton instance of the {@link SpringContextHolder} - */ - @Bean - SpringContextHolder springContextHolder() { - return SpringContextHolder.getInstance(); - } - - /** - * The UI scoped event push strategy. Session scope is necessary, that every - * UI has an own strategy. - * - * @param applicationContext - * the context to add the listener to - * @param executorService - * the general scheduler service - * @param eventBus - * the ui event bus - * @param eventProvider - * the event provider - * @param eventPermissionChecker - * the event permission checker - * @param uiProperties - * the ui properties - * @return the push strategy bean - */ - @Bean - @ConditionalOnMissingBean - @UIScope - EventPushStrategy eventPushStrategy(final ConfigurableApplicationContext applicationContext, - final ScheduledExecutorService executorService, final UIEventBus eventBus, - final UIEventProvider eventProvider, final UIEventPermissionChecker eventPermissionChecker, - final UiProperties uiProperties) { - final DelayedEventBusPushStrategy delayedEventBusPushStrategy = new DelayedEventBusPushStrategy(executorService, - eventBus, eventProvider, eventPermissionChecker, uiProperties.getEvent().getPush().getDelay()); - applicationContext.addApplicationListener(delayedEventBusPushStrategy); - - return delayedEventBusPushStrategy; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/autoconfigure/RedirectController.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/autoconfigure/RedirectController.java deleted file mode 100644 index a9ddfacff2..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/autoconfigure/RedirectController.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.autoconfigure; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.servlet.ModelAndView; - -/** - * Redirects for convenience. hawkBit's management UI is by default not - * listening on / but on /UI. - * - */ -@Controller -public class RedirectController { - - /** - * @return redirect to the Management UI - */ - @GetMapping("/") - public ModelAndView home() { - return new ModelAndView("redirect:/UI/"); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/autoconfigure/UISecurityConfigurationAdapter.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/autoconfigure/UISecurityConfigurationAdapter.java deleted file mode 100644 index 3593658e06..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/autoconfigure/UISecurityConfigurationAdapter.java +++ /dev/null @@ -1,257 +0,0 @@ -/** - * Copyright (c) 2021 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.autoconfigure; - -import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; -import org.eclipse.hawkbit.repository.SystemManagement; -import org.eclipse.hawkbit.security.DosFilter; -import org.eclipse.hawkbit.security.HawkbitSecurityProperties; -import org.eclipse.hawkbit.security.SystemSecurityContext; -import org.eclipse.hawkbit.ui.MgmtUiConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.core.annotation.Order; -import org.springframework.security.access.AccessDecisionManager; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.InsufficientAuthenticationException; -import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; -import org.springframework.security.config.annotation.web.WebSecurityConfigurer; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; -import org.springframework.security.oauth2.core.oidc.user.OidcUser; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; -import org.springframework.security.web.authentication.logout.LogoutHandler; -import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; -import org.springframework.security.web.session.HttpSessionEventPublisher; -import org.springframework.util.ObjectUtils; -import org.vaadin.spring.http.HttpService; -import org.vaadin.spring.security.annotation.EnableVaadinSharedSecurity; -import org.vaadin.spring.security.config.VaadinSharedSecurityConfiguration; -import org.vaadin.spring.security.shared.VaadinAuthenticationSuccessHandler; -import org.vaadin.spring.security.shared.VaadinUrlAuthenticationSuccessHandler; -import org.vaadin.spring.security.web.VaadinRedirectStrategy; - -import java.util.Arrays; - -/** - * {@link WebSecurityConfigurer} for external (management) access. - */ -@Configuration -@EnableWebSecurity -@EnableVaadinSharedSecurity -@ConditionalOnClass(MgmtUiConfiguration.class) -public class UISecurityConfigurationAdapter { - - private static final Logger LOG = LoggerFactory.getLogger(UISecurityConfigurationAdapter.class); - - private static final int DOS_FILTER_ORDER = -200; - - @Autowired - private HawkbitSecurityProperties hawkbitSecurityProperties; - - /** - * Filter to protect the hawkBit management UI against to many requests. - * - * @param securityProperties for filter configuration - * @return the spring filter registration bean for registering a denial - * of service protection filter in the filter chain - */ - @Bean - @ConditionalOnProperty(prefix = "hawkbit.server.security.dos.ui-filter", name = "enabled", matchIfMissing = true) - public FilterRegistrationBean dosMgmtUiFilter(final HawkbitSecurityProperties securityProperties) { - final HawkbitSecurityProperties.Dos.Filter filterProperties = securityProperties.getDos().getUiFilter(); - final HawkbitSecurityProperties.Clients clientProperties = securityProperties.getClients(); - - final FilterRegistrationBean filterRegBean = new FilterRegistrationBean<>(); - - filterRegBean.setFilter(new DosFilter(null, filterProperties.getMaxRead(), - filterProperties.getMaxWrite(), filterProperties.getWhitelist(), clientProperties.getBlacklist(), - clientProperties.getRemoteIpHeader())); - - // All URLs that can be called anonymous - filterRegBean.setUrlPatterns(Arrays.asList("/UI/login", "/UI/login/*", "/UI/logout", "/UI/logout/*")); - filterRegBean.setOrder(DOS_FILTER_ORDER); - filterRegBean.setName("dosMgmtUiFilter"); - - return filterRegBean; - } - - @Bean - AuthenticationManager authenticationManager(final AuthenticationConfiguration authenticationConfiguration) throws Exception { - return authenticationConfiguration.getAuthenticationManager(); - } - - /** - * Overwriting VaadinAuthenticationSuccessHandler of default - * VaadinSharedSecurityConfiguration - * - * @return the vaadin success authentication handler - */ - @Primary - @Bean(name = VaadinSharedSecurityConfiguration.VAADIN_AUTHENTICATION_SUCCESS_HANDLER_BEAN) - public VaadinAuthenticationSuccessHandler redirectSaveHandler(final HttpService httpService, - final VaadinRedirectStrategy redirectStrategy) { - final VaadinUrlAuthenticationSuccessHandler handler = new TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler( - httpService, redirectStrategy, "/UI/"); - handler.setTargetUrlParameter("r"); - - return handler; - } - - /** - * Listener to redirect to login page after session timeout. Close the - * vaadin session, because it's is not possible to redirect in - * atmosphere. - * - * @return the servlet listener. - */ - @Bean - public ServletListenerRegistrationBean httpSessionEventPublisher() { - return new ServletListenerRegistrationBean<>(new HttpSessionEventPublisher()); - } - - @Bean - @Order(400) - protected SecurityFilterChain filterChainUI( - final HttpSecurity http, - @Autowired(required = false) - final OAuth2UserService oidcUserService, - @Autowired(required = false) - final AuthenticationSuccessHandler authenticationSuccessHandler, - final LogoutHandler logoutHandler, - final LogoutSuccessHandler logoutSuccessHandler) - throws Exception { - final boolean enableOidc = oidcUserService != null && authenticationSuccessHandler != null; - - // workaround regex: we need to exclude the URL /UI/HEARTBEAT here - // because we bound the vaadin application to /UI and not to root, - // described in vaadin-forum: - // https://vaadin.com/forum#!/thread/3200565. - HttpSecurity httpSec; - if (enableOidc) { - httpSec = http.requestMatchers().antMatchers("/**/UI/**", "/**/oauth2/**").and(); - } else { - httpSec = http.antMatcher("/**/UI/**"); - } - // disable as CSRF is handled by Vaadin - httpSec.csrf(AbstractHttpConfigurer::disable); - // allow same origin X-Frame-Options for correct file download under - // Safari - httpSec.headers().frameOptions().sameOrigin(); - - if (hawkbitSecurityProperties.isRequireSsl()) { - httpSec = httpSec.requiresChannel(crmRegistry -> crmRegistry.anyRequest().requiresSecure()); - } else { - LOG.info( - """ - ****************** - ** Requires HTTPS Security has been disabled for UI, should only be used for developing purposes ** - ******************"""); - } - - if (!ObjectUtils.isEmpty(hawkbitSecurityProperties.getContentSecurityPolicy())) { - httpSec.headers().contentSecurityPolicy(hawkbitSecurityProperties.getContentSecurityPolicy()); - } - - // UI - httpSec.authorizeRequests().antMatchers("/UI/login/**", "/UI/UIDL/**").permitAll().anyRequest() - .authenticated(); - - if (enableOidc) { - // OIDC - httpSec.oauth2Login().userInfoEndpoint().oidcUserService(oidcUserService).and() - .successHandler(authenticationSuccessHandler).and().oauth2Client(); - } else { - // UI login / Basic auth - httpSec.exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/UI/login")); - } - - // UI logout - httpSec.logout().logoutUrl("/UI/logout*").addLogoutHandler(logoutHandler) - .logoutSuccessHandler(logoutSuccessHandler); - - return httpSec.build(); - } - - @Bean - public WebSecurityCustomizer webSecurityCustomizer() { - // No security for static content - return (web) -> web.ignoring().antMatchers("/documentation/**", "/VAADIN/**", "/*.*", "/docs/**"); - } - - /** - * Configuration that defines the {@link AccessDecisionManager} bean for - * UI method security used by the Vaadin Servlet. Notice: we can not use - * the top-level method security configuration because - * AdviceMode.ASPECTJ is not supported. - */ - @Configuration - @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true) - @ConditionalOnClass(MgmtUiConfiguration.class) - static class UIMethodSecurity extends GlobalMethodSecurityConfiguration { - - @Bean(name = VaadinSharedSecurityConfiguration.ACCESS_DECISION_MANAGER_BEAN) - @Override - protected AccessDecisionManager accessDecisionManager() { - return super.accessDecisionManager(); - } - } - - /** - * After a successful login on the UI we need to ensure to create the tenant - * meta data within SP. - */ - class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends VaadinUrlAuthenticationSuccessHandler { - - @Autowired - private SystemManagement systemManagement; - - @Autowired - private SystemSecurityContext systemSecurityContext; - - public TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler(final HttpService http, - final VaadinRedirectStrategy redirectStrategy, final String defaultTargetUrl) { - super(http, redirectStrategy, defaultTargetUrl); - } - - @Override - public void onAuthenticationSuccess(final Authentication authentication) throws Exception { - systemSecurityContext.runAsSystemAsTenant(systemManagement::getTenantMetadata, getTenantFrom(authentication)); - - super.onAuthenticationSuccess(authentication); - } - - private static String getTenantFrom(final Authentication authentication) { - final Object details = authentication.getDetails(); - if (details instanceof TenantAwareAuthenticationDetails) { - return ((TenantAwareAuthenticationDetails) details).getTenant(); - } - - throw new InsufficientAuthenticationException("Authentication details/tenant info are not specified!"); - } - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractAddEntityWindowController.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractAddEntityWindowController.java deleted file mode 100644 index eaff243c48..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractAddEntityWindowController.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload.EntityModifiedEventType; - -/** - * Window controller for entity creations. - * - * @param - * Type of proxy entity - * @param - * Second type of proxy entity - * @param - * Type of repository entity - */ -public abstract class AbstractAddEntityWindowController extends AbstractEntityWindowController { - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - */ - protected AbstractAddEntityWindowController(final CommonUiDependencies uiDependencies) { - super(uiDependencies); - } - - @Override - protected String getPersistSuccessMessageKey() { - return "message.save.success"; - } - - @Override - protected String getPersistFailureMessageKey() { - return "message.save.fail"; - } - - @Override - protected EntityModifiedEventPayload createModifiedEventPayload(final R entity) { - return new EntityModifiedEventPayload(EntityModifiedEventType.ENTITY_ADDED, getParentEntityClass(), - getEntityClass(), getId(entity)); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractAddNamedEntityWindowController.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractAddNamedEntityWindowController.java deleted file mode 100644 index fa7a417bcd..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractAddNamedEntityWindowController.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import org.eclipse.hawkbit.repository.model.NamedEntity; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyNamedEntity; - -/** - * Window controller for named entity creations. - * - * @param - * Type of proxy entity - * @param - * Second type of proxy entity - * @param - * Type of repository entity - */ -public abstract class AbstractAddNamedEntityWindowController - extends AbstractAddEntityWindowController { - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - */ - protected AbstractAddNamedEntityWindowController(final CommonUiDependencies uiDependencies) { - super(uiDependencies); - } - - @Override - protected String getDisplayableName(final R entity) { - return entity.getName(); - } - - @Override - protected String getDisplayableNameForFailedMessage(final E entity) { - return entity.getName(); - } - - @Override - protected Long getId(final R entity) { - return entity.getId(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEntityWindowBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEntityWindowBuilder.java deleted file mode 100644 index 97cdd0799b..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEntityWindowBuilder.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import org.eclipse.hawkbit.ui.common.CommonDialogWindow.SaveDialogCloseListener; -import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; - -import com.vaadin.ui.Component; -import com.vaadin.ui.Window; - -/** - * Builder for abstract entity window - * - * @param - * Generic type entity - */ -public abstract class AbstractEntityWindowBuilder { - protected final CommonUiDependencies uiDependencies; - - protected AbstractEntityWindowBuilder(final CommonUiDependencies uiDependencies) { - this.uiDependencies = uiDependencies; - } - - protected CommonDialogWindow getWindowForNewEntity(final AbstractEntityWindowController controller) { - return getWindowForEntity(null, controller); - } - - protected CommonDialogWindow getWindowForNewEntity(final AbstractEntityWindowController controller, - final Component windowContent) { - return getWindowForEntity(null, controller, windowContent); - } - - protected CommonDialogWindow getWindowForEntity(final T proxyEntity, - final AbstractEntityWindowController controller) { - return getWindowForEntity(proxyEntity, controller, controller.getLayout().getRootComponent()); - } - - protected CommonDialogWindow getWindowForEntity(final T proxyEntity, - final AbstractEntityWindowController controller, final Component windowContent) { - controller.populateWithData(proxyEntity); - - final CommonDialogWindow window = createWindow(windowContent, controller.getSaveDialogCloseListener()); - - controller.getLayout().addValidationListener(window::setSaveButtonEnabled); - - return window; - } - - protected CommonDialogWindow createWindow(final Component content, - final SaveDialogCloseListener saveDialogCloseListener) { - return new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).id(getWindowId()).content(content) - .i18n(uiDependencies.getI18n()).helpLink(getHelpLink()).saveDialogCloseListener(saveDialogCloseListener) - .buildCommonDialogWindow(); - } - - protected abstract String getWindowId(); - - /** - * Gets the add window - * - * @return window - */ - public abstract Window getWindowForAdd(); - - /** - * Gets the update window - * - * @param entity - * Generic type entity - * - * @return window - */ - public abstract Window getWindowForUpdate(final T entity); - - protected String getHelpLink() { - // can be overriden to provide help link to documentation - return null; - } - - protected VaadinMessageSource getI18n() { - return uiDependencies.getI18n(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEntityWindowController.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEntityWindowController.java deleted file mode 100644 index 04cbb6f3ad..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEntityWindowController.java +++ /dev/null @@ -1,206 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import java.util.Objects; - -import javax.validation.ConstraintViolationException; - -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; -import org.eclipse.hawkbit.ui.common.CommonDialogWindow.SaveDialogCloseListener; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; -import org.eclipse.hawkbit.ui.common.event.CommandTopics; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload; -import org.eclipse.hawkbit.ui.common.event.EventTopics; -import org.eclipse.hawkbit.ui.common.event.SelectionChangedEventPayload; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.vaadin.spring.events.EventBus.UIEventBus; - -/** - * Controller for abstract entity window - * - * @param - * Type of proxy entity - * @param - * Second type of proxy entity - * @param - * Type of repository entity - */ -public abstract class AbstractEntityWindowController { - - private static final Logger LOG = LoggerFactory.getLogger(AbstractEntityWindowController.class); - - private final CommonUiDependencies uiDependencies; - - /** - * Constructor. - * - * @param uiDependencies - * the {@link CommonUiDependencies} - */ - protected AbstractEntityWindowController(final CommonUiDependencies uiDependencies) { - this.uiDependencies = uiDependencies; - } - - /** - * Populate entity with data - * - * @param proxyEntity - * Generic type entity - */ - public void populateWithData(final T proxyEntity) { - getLayout().setEntity(buildEntityFromProxy(proxyEntity)); - - adaptLayout(proxyEntity); - } - - /** - * @return layout - */ - public abstract EntityWindowLayout getLayout(); - - protected abstract E buildEntityFromProxy(final T proxyEntity); - - protected void adaptLayout(final T proxyEntity) { - // can be overriden to adapt layout components (e.g. disable/enable - // fields, adapt bindings, etc.) - } - - /** - * @return Save dialog close listener - */ - public SaveDialogCloseListener getSaveDialogCloseListener() { - return new SaveDialogCloseListener() { - @Override - public void saveOrUpdate() { - persistEntity(getLayout().getEntity()); - } - - @Override - public boolean canWindowSaveOrUpdate() { - return isEntityValid(getLayout().getEntity()); - } - - @Override - public boolean canWindowClose() { - return closeWindowAfterSave(); - } - }; - } - - protected void persistEntity(final E entity) { - try { - - final R createdEntity = persistEntityInRepository(entity); - - handleEntityPersistedSuccessfully(createdEntity); - - selectPersistedEntity(createdEntity); - - } catch (final ConstraintViolationException | EntityNotFoundException | EntityReadOnlyException ex) { - - handleEntityPersistFailed(entity, ex); - - } finally { - - postPersist(); - } - } - - protected abstract R persistEntityInRepository(E entity); - - protected void handleEntityPersistedSuccessfully(final R persistedEntity) { - displaySuccess(getPersistSuccessMessageKey(), getDisplayableName(persistedEntity)); - publishModifiedEvent(createModifiedEventPayload(persistedEntity)); - } - - protected void handleEntityPersistFailed(final E entity, final RuntimeException ex) { - final String name = getDisplayableNameForFailedMessage(entity); - final String id = Objects.toString(entity); - final String type = getEntityClass().getSimpleName(); - LOG.warn("Persist of entity name:{}, id:{}, type:{} failed in UI with reason: {}", name, id, type, - ex.getMessage()); - displayWarning(getPersistFailureMessageKey(), name); - } - - protected abstract EntityModifiedEventPayload createModifiedEventPayload(final R entity); - - protected abstract Long getId(R entity); - - protected abstract String getDisplayableNameForFailedMessage(E entity); - - protected abstract String getDisplayableName(R entity); - - protected abstract String getPersistSuccessMessageKey(); - - protected abstract String getPersistFailureMessageKey(); - - protected abstract Class getEntityClass(); - - protected Class getParentEntityClass() { - return null; - } - - protected void selectPersistedEntity(final R entity) { - // entity is not selected by default - } - - protected void postPersist() { - // empty default implementation - } - - protected abstract boolean isEntityValid(final E entity); - - protected boolean closeWindowAfterSave() { - return true; - } - - protected VaadinMessageSource getI18n() { - return uiDependencies.getI18n(); - } - - protected EntityFactory getEntityFactory() { - return uiDependencies.getEntityFactory(); - } - - protected UIEventBus getEventBus() { - return uiDependencies.getEventBus(); - } - - protected UINotification getUiNotification() { - return uiDependencies.getUiNotification(); - } - - protected void displaySuccess(final String messageKey, final Object... args) { - getUiNotification().displaySuccess(getI18n().getMessage(messageKey, args)); - } - - protected void displayValidationError(final String messageKey, final Object... args) { - getUiNotification().displayValidationError(getI18n().getMessage(messageKey, args)); - } - - protected void displayWarning(final String messageKey, final Object... args) { - getUiNotification().displayWarning(getI18n().getMessage(messageKey, args)); - } - - protected void publishModifiedEvent(final EntityModifiedEventPayload eventPayload) { - getEventBus().publish(EventTopics.ENTITY_MODIFIED, this, eventPayload); - } - - protected void publishSelectionEvent(final SelectionChangedEventPayload eventPayload) { - getEventBus().publish(CommandTopics.SELECT_GRID_ENTITY, this, eventPayload); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEntityWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEntityWindowLayout.java deleted file mode 100644 index 262353607b..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEntityWindowLayout.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import java.util.Optional; -import java.util.function.Consumer; - -import com.vaadin.data.Binder; - -/** - * Abstract class for entity window layout - * - * @param - * Generic type entity - */ -public abstract class AbstractEntityWindowLayout implements EntityWindowLayout { - - protected final Binder binder; - - protected Consumer validationCallback; - - protected AbstractEntityWindowLayout() { - this.binder = new Binder<>(); - } - - @Override - public void setEntity(final T proxyEntity) { - binder.setBean(proxyEntity); - } - - @Override - public T getEntity() { - return binder.getBean(); - } - - @Override - public void addValidationListener(final Consumer validationCallback) { - binder.addStatusChangeListener(event -> validationCallback.accept(event.getBinder().isValid())); - this.validationCallback = validationCallback; - } - - /** - * @return Validation callback event - */ - public Optional> getValidationCallback() { - return Optional.ofNullable(validationCallback); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEventListenersAwareView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEventListenersAwareView.java deleted file mode 100644 index f122b8eaa3..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractEventListenersAwareView.java +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Copyright (c) 2021 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - -import org.springframework.util.StringUtils; - -import com.vaadin.navigator.View; -import com.vaadin.navigator.ViewBeforeLeaveEvent; -import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; -import com.vaadin.ui.VerticalLayout; - -/** - * Abstract class managing event listeners aware layouts. - * - */ -public abstract class AbstractEventListenersAwareView extends VerticalLayout implements View, ViewNameAware { - private static final long serialVersionUID = 1L; - - // directly taken from Vaadin Navigator for consistency - private static final String DEFAULT_STATE_PARAMETER_SEPARATOR = "&"; - private static final String DEFAULT_STATE_PARAMETER_KEY_VALUE_SEPARATOR = "="; - - private final transient List eventAwareLayouts = new ArrayList<>(); - private boolean initial; - - /** - * Adds event aware layout. - * - * @param eventAwareLayout - * event aware layout to add - */ - protected void addEventAwareLayout(final EventListenersAwareLayout eventAwareLayout) { - if (eventAwareLayout != null) { - eventAwareLayouts.add(eventAwareLayout); - } - } - - /** - * Adds a list of event aware layouts. - * - * @param eventAwareLayouts - * event aware layouts to add - */ - protected void addEventAwareLayouts(final Collection eventAwareLayouts) { - eventAwareLayouts.forEach(this::addEventAwareLayout); - } - - @PostConstruct - protected void init() { - buildLayout(); - initial = true; - } - - /** - * Builds view layout. - * - */ - protected abstract void buildLayout(); - - @Override - public void enter(final ViewChangeEvent event) { - subscribeListeners(); - - if (initial) { - restoreState(); - initial = false; - } else { - updateLayoutsOnViewEnter(); - } - - if (StringUtils.hasText(event.getParameters())) { - handleStateParams(parseStateParameters(event.getParameters())); - } - } - - private static Map parseStateParameters(final String urlParams) { - return Arrays.stream(urlParams.split(DEFAULT_STATE_PARAMETER_SEPARATOR)).map(paramPair -> { - final String[] keyValue = paramPair.split(DEFAULT_STATE_PARAMETER_KEY_VALUE_SEPARATOR, 2); - if (keyValue.length == 2) { - return new AbstractMap.SimpleEntry<>(keyValue[0], keyValue[1]); - } - return null; - }).filter(Objects::nonNull) - .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)); - } - - /** - * Subscribes all listeners of added event aware layouts to event bus. - * - */ - protected void subscribeListeners() { - eventAwareLayouts.forEach(EventListenersAwareLayout::subscribeListeners); - } - - /** - * Restores session state of added event aware layouts. - * - */ - protected void restoreState() { - eventAwareLayouts.forEach(EventListenersAwareLayout::restoreState); - } - - /** - * Handles state url parameters of added event aware layouts. - * - * @param stateParams - * map of view state url parameters - */ - protected void handleStateParams(final Map stateParams) { - eventAwareLayouts.forEach(layout -> layout.handleStateParameters(stateParams)); - } - - /** - * Called on view enter for added event aware layouts to update their state. - * - */ - protected void updateLayoutsOnViewEnter() { - eventAwareLayouts.forEach(EventListenersAwareLayout::onViewEnter); - } - - @Override - public void beforeLeave(final ViewBeforeLeaveEvent event) { - unsubscribeListeners(); - event.navigate(); - } - - /** - * Unsubscribes all listeners of added event aware layouts to event bus. - * - */ - protected void unsubscribeListeners() { - eventAwareLayouts.forEach(EventListenersAwareLayout::unsubscribeListeners); - } - - @PreDestroy - public void destroy() { - unsubscribeListeners(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractUpdateEntityWindowController.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractUpdateEntityWindowController.java deleted file mode 100644 index 69f1ae2102..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractUpdateEntityWindowController.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload; -import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload.EntityModifiedEventType; - -/** - * Window controller for entity updates. - * - * @param - * Type of proxy entity - * @param - * Second type of proxy entity - * @param - * Type of repository entity - */ -public abstract class AbstractUpdateEntityWindowController extends AbstractEntityWindowController { - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - */ - protected AbstractUpdateEntityWindowController(final CommonUiDependencies uiDependencies) { - super(uiDependencies); - } - - @Override - protected String getPersistSuccessMessageKey() { - return "message.update.success"; - } - - @Override - protected String getPersistFailureMessageKey() { - return "message.deleted.or.notAllowed"; - } - - @Override - protected EntityModifiedEventPayload createModifiedEventPayload(final R entity) { - return new EntityModifiedEventPayload(EntityModifiedEventType.ENTITY_UPDATED, getParentEntityClass(), - getEntityClass(), getId(entity)); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractUpdateNamedEntityWindowController.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractUpdateNamedEntityWindowController.java deleted file mode 100644 index 9afebf2c2a..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractUpdateNamedEntityWindowController.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import org.eclipse.hawkbit.repository.model.NamedEntity; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyNamedEntity; - -/** - * Window controller for entity updates. - * - * @param - * Type of proxy entity - * @param - * Second type of proxy entity - * @param - * Type of repository entity - */ -public abstract class AbstractUpdateNamedEntityWindowController - extends AbstractUpdateEntityWindowController { - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - */ - protected AbstractUpdateNamedEntityWindowController(final CommonUiDependencies uiDependencies) { - super(uiDependencies); - } - - @Override - protected String getDisplayableName(final R entity) { - return entity.getName(); - } - - @Override - protected String getDisplayableNameForFailedMessage(final E entity) { - return entity.getName(); - } - - @Override - protected Long getId(final R entity) { - return entity.getId(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java deleted file mode 100644 index 2a92878f4c..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ /dev/null @@ -1,318 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonDecorator; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon; -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 com.vaadin.event.ShortcutAction.KeyCode; -import com.vaadin.icons.VaadinIcons; -import com.vaadin.ui.AbstractComponent; -import com.vaadin.ui.Alignment; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.Component; -import com.vaadin.ui.GridLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.Link; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; -import com.vaadin.ui.themes.ValoTheme; - -/** - * - * Table pop-up-windows including a minimize and close icon in the upper right - * corner and a save and cancel button at the bottom. Is not intended to reuse. - * - */ -public class CommonDialogWindow extends Window { - private static final long serialVersionUID = 1L; - - private final VaadinMessageSource i18n; - - private final VerticalLayout mainLayout; - private final String caption; - private final Component content; - private final String helpLink; - private final ConfirmStyle confirmStyle; - private final Class buttonDecorator; - private Button confirmButton; - private Button cancelButton; - private HorizontalLayout buttonsLayout; - private Label mandatoryLabel; - - private final ClickListener cancelButtonClickListener; - private final ClickListener closeClickListener; - - private transient SaveDialogCloseListener closeListener; - - /** - * Different kinds of confirm buttons - */ - public enum ConfirmStyle { - SAVE, OK, CONFIRM, NEXT - } - - /** - * Constructor - * - * @param caption - * the caption - * @param content - * the content - * @param helpLink - * the helpLinks - * @param closeListener - * the saveDialogCloseListener - * @param cancelButtonClickListener - * the cancelButtonClickListener - * @param confirmStyle - * what kind of button is used - * @param buttonDecorator - * to style the confirm and cancel buttons - * @param i18n - * internationalization - */ - public CommonDialogWindow(final String caption, final Component content, final String helpLink, - final SaveDialogCloseListener closeListener, final ClickListener cancelButtonClickListener, - final ConfirmStyle confirmStyle, final Class buttonDecorator, - final VaadinMessageSource i18n) { - this.caption = caption; - this.content = content; - this.helpLink = helpLink; - this.closeListener = closeListener; - this.cancelButtonClickListener = cancelButtonClickListener; - this.confirmStyle = confirmStyle; - this.buttonDecorator = buttonDecorator; - this.i18n = i18n; - - this.mainLayout = new VerticalLayout(); - this.closeClickListener = this::onCloseEvent; - - init(); - } - - private void onCloseEvent(final ClickEvent clickEvent) { - if (!clickEvent.getButton().equals(confirmButton)) { - close(); - return; - } - - if (!closeListener.canWindowSaveOrUpdate()) { - return; - } - closeListener.saveOrUpdate(); - - if (closeListener.canWindowClose()) { - close(); - } - - } - - @Override - public void close() { - super.close(); - this.confirmButton.setEnabled(false); - } - - private final void init() { - mainLayout.setMargin(false); - mainLayout.setSpacing(false); - - if (content instanceof GridLayout) { - addStyleName("marginTop"); - } - - if (content != null) { - mainLayout.addComponent(content); - mainLayout.setExpandRatio(content, 1.0F); - } - - createMandatoryLabel(); - - final HorizontalLayout buttonLayout = createActionButtonsLayout(); - mainLayout.addComponent(buttonLayout); - mainLayout.setComponentAlignment(buttonLayout, Alignment.TOP_CENTER); - - setCaptionAsHtml(false); - setCaption(caption); - setContent(mainLayout); - setResizable(false); - center(); - setModal(true); - addStyleName("fontsize"); - } - - protected void addCloseListenerForSaveButton() { - confirmButton.addClickListener(closeClickListener); - } - - protected void addCloseListenerForCancelButton() { - cancelButton.addClickListener(closeClickListener); - } - - private HorizontalLayout createActionButtonsLayout() { - - buttonsLayout = new HorizontalLayout(); - buttonsLayout.setSizeFull(); - buttonsLayout.addStyleName("actionButtonsMargin"); - - createSaveButton(); - createCancelButton(); - - addHelpLink(); - - return buttonsLayout; - } - - private void createMandatoryLabel() { - - mandatoryLabel = new Label(i18n.getMessage("label.mandatory.field")); - mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); - - mainLayout.addComponent(mandatoryLabel); - } - - /** - * Hide the line that explains the mandatory decorator - * - */ - public void hideMandatoryExplanation() { - if (mandatoryLabel != null) { - mainLayout.removeComponent(mandatoryLabel); - } - } - - private void createCancelButton() { - cancelButton = SPUIComponentProvider.getButton(UIComponentIdProvider.CANCEL_BUTTON, - i18n.getMessage(UIMessageIdProvider.BUTTON_CANCEL), "", "", true, VaadinIcons.CLOSE, - SPUIButtonStyleNoBorderWithIcon.class); - cancelButton.setSizeUndefined(); - cancelButton.addStyleName("default-color"); - addCloseListenerForCancelButton(); - if (cancelButtonClickListener != null) { - cancelButton.addClickListener(cancelButtonClickListener); - } - - buttonsLayout.addComponent(cancelButton); - buttonsLayout.setComponentAlignment(cancelButton, Alignment.MIDDLE_LEFT); - buttonsLayout.setExpandRatio(cancelButton, 1.0F); - } - - private void createSaveButton() { - if (confirmStyle == ConfirmStyle.SAVE) { - confirmButton = SPUIComponentProvider.getButton(UIComponentIdProvider.SAVE_BUTTON, - i18n.getMessage(UIMessageIdProvider.BUTTON_SAVE), "", "", true, VaadinIcons.HARDDRIVE, - buttonDecorator); - } else if (confirmStyle == ConfirmStyle.NEXT) { - confirmButton = SPUIComponentProvider.getButton(UIComponentIdProvider.OK_BUTTON, - i18n.getMessage(UIMessageIdProvider.BUTTON_NEXT), "", ValoTheme.BUTTON_PRIMARY, false, null, - buttonDecorator); - } else if (confirmStyle == ConfirmStyle.CONFIRM) { - confirmButton = SPUIComponentProvider.getButton(UIComponentIdProvider.OK_BUTTON, - i18n.getMessage(UIMessageIdProvider.BUTTON_CONFIRM), "", ValoTheme.BUTTON_PRIMARY, false, null, - buttonDecorator); - } else { - confirmButton = SPUIComponentProvider.getButton(UIComponentIdProvider.OK_BUTTON, - i18n.getMessage(UIMessageIdProvider.BUTTON_OK), "", ValoTheme.BUTTON_PRIMARY, false, null, - buttonDecorator); - } - confirmButton.setSizeUndefined(); - confirmButton.addStyleName("default-color"); - addCloseListenerForSaveButton(); - confirmButton.setEnabled(false); - confirmButton.setClickShortcut(KeyCode.ENTER); - buttonsLayout.addComponent(confirmButton); - buttonsLayout.setComponentAlignment(confirmButton, Alignment.MIDDLE_RIGHT); - buttonsLayout.setExpandRatio(confirmButton, 1.0F); - } - - private void addHelpLink() { - - if (StringUtils.isEmpty(helpLink)) { - return; - } - final Link helpLinkComponent = SPUIComponentProvider.getHelpLink(i18n, helpLink); - buttonsLayout.addComponent(helpLinkComponent); - buttonsLayout.setComponentAlignment(helpLinkComponent, Alignment.MIDDLE_RIGHT); - } - - public AbstractComponent getButtonsLayout() { - return this.buttonsLayout; - } - - public VerticalLayout getMainLayout() { - return mainLayout; - } - - /** - * Enables the save confirmation button - * - * @param enabled - * boolean - * - */ - public void setSaveButtonEnabled(final boolean enabled) { - confirmButton.setEnabled(enabled); - } - - public void setCancelButtonEnabled(final boolean enabled) { - cancelButton.setEnabled(enabled); - } - - /** - * Sets the close listener in save dialog - * - * @param closeListener - * SaveDialogCloseListener - */ - public void setCloseListener(final SaveDialogCloseListener closeListener) { - this.closeListener = closeListener; - } - - /** - * Check if the safe action can executed. After a the save action the - * listener checks if the dialog can closed. - * - */ - public interface SaveDialogCloseListener { - - /** - * Checks if the safe action can executed. - * - * @return = save action can executed = cannot execute - * safe action . - */ - boolean canWindowSaveOrUpdate(); - - /** - * Checks if the window can be closed after the save action is executed - * - * @return = window will close = will not closed. - */ - default boolean canWindowClose() { - return true; - } - - /** - * Saves/Updates action. Is called if canWindowSaveOrUpdate is . - * - */ - void saveOrUpdate(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonUiDependencies.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonUiDependencies.java deleted file mode 100644 index a1a2b0466c..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonUiDependencies.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; - -/** - * Container for commonly used dependencies in the UI. - */ -public class CommonUiDependencies { - - private final VaadinMessageSource i18n; - private final EntityFactory entityFactory; - private final UIEventBus eventBus; - private final UINotification uiNotification; - private final SpPermissionChecker permChecker; - - /** - * Public constructor. - * - * @param i18n - * VaadinMessageSource - * @param entityFactory - * EntityFactory - * @param eventBus - * UIEventBus - * @param uiNotification - * UINotification - * @param permChecker - * {@link SpPermissionChecker} - */ - public CommonUiDependencies(final VaadinMessageSource i18n, final EntityFactory entityFactory, - final UIEventBus eventBus, final UINotification uiNotification, final SpPermissionChecker permChecker) { - super(); - this.i18n = i18n; - this.entityFactory = entityFactory; - this.eventBus = eventBus; - this.uiNotification = uiNotification; - this.permChecker = permChecker; - } - - /** - * Returns {@link VaadinMessageSource} - * - * @return the i18n - */ - public VaadinMessageSource getI18n() { - return i18n; - } - - /** - * Returns {@link EntityFactory} - * - * @return the entityFactory - */ - public EntityFactory getEntityFactory() { - return entityFactory; - } - - /** - * Returns {@link UIEventBus} - * - * @return the eventBus - */ - public UIEventBus getEventBus() { - return eventBus; - } - - /** - * Returns {@link UINotification} - * - * @return the uiNotification - */ - public UINotification getUiNotification() { - return uiNotification; - } - - /** - * Returns {@link SpPermissionChecker} - * - * @return the permChecker - */ - public SpPermissionChecker getPermChecker() { - return permChecker; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java deleted file mode 100644 index 77a9c0a304..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java +++ /dev/null @@ -1,226 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import java.io.Serializable; - -import org.eclipse.hawkbit.ui.common.CommonDialogWindow.ConfirmStyle; -import org.eclipse.hawkbit.ui.common.CommonDialogWindow.SaveDialogCloseListener; -import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleTiny; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -import com.vaadin.server.Resource; -import com.vaadin.server.Sizeable.Unit; -import com.vaadin.shared.ui.ContentMode; -import com.vaadin.ui.Component; -import com.vaadin.ui.Label; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; - -/** - * Class for the confirmation dialog which pops up when deleting, assigning... - * entities. - */ -public class ConfirmationDialog implements Serializable { - - private static final long serialVersionUID = 1L; - - private final transient Runnable callback; - - private final CommonDialogWindow window; - - public static Builder newBuilder(final VaadinMessageSource i18n, final String id) { - return new Builder(i18n, id); - } - - /** - * Constructor for configuring confirmation dialog. - * - * @param i18n - * internationalization - * @param caption - * the dialog caption. - * @param question - * the question. - * @param hint - * added in the dialog - * @param onSaveOrUpdate - * the callback onSaveOrUpdate. - * @param onCancel - * the callback on cancel. - * @param icon - * the icon of the dialog - * @param id - * the id of the confirmation dialog - * @param tab - * ConfirmationTab which contains more information about the action - * which has to be confirmed, e.g. maintenance window - */ - private ConfirmationDialog(final VaadinMessageSource i18n, final String caption, final String question, - final String hint, final Runnable onSaveOrUpdate, final Runnable onCancel, final Resource icon, - final String id, final Component tab) { - - final VerticalLayout content = new VerticalLayout(); - content.setMargin(false); - content.setSpacing(false); - - if (question != null) { - content.addComponent(createConfirmationLabel(question)); - } - if (hint != null) { - content.addComponent(createConfirmationLabel(hint)); - } - if (tab != null) { - content.addComponent(tab); - } - final WindowBuilder windowBuilder = new WindowBuilder(SPUIDefinitions.CONFIRMATION_WINDOW).caption(caption) - .content(content).cancelButtonClickListener(e -> { - if (onCancel != null) { - onCancel.run(); - } - }).saveDialogCloseListener(getSaveDialogCloseListener()).hideMandatoryExplanation() - .buttonDecorator(SPUIButtonStyleTiny.class).confirmStyle(ConfirmStyle.OK).i18n(i18n); - - if (!StringUtils.isEmpty(id)) { - windowBuilder.id(id); - } - this.window = windowBuilder.buildCommonDialogWindow(); - window.setSaveButtonEnabled(true); - this.callback = onSaveOrUpdate; - - if (icon != null) { - window.setIcon(icon); - } - - window.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_WINDOW_STYLE); - } - - private SaveDialogCloseListener getSaveDialogCloseListener() { - return new SaveDialogCloseListener() { - @Override - public void saveOrUpdate() { - if (callback != null) { - callback.run(); - } - } - - @Override - public boolean canWindowSaveOrUpdate() { - return true; - } - }; - } - - private static Label createConfirmationLabel(final String text) { - // ContentMode.HTML is used instead of ContentMode.PREFORMATTED here due - // to no linebreaks if an entity name is very long - final String questionHtmlSave = HawkbitCommonUtil.sanitizeHtml(text); - final Label questionLbl = new Label(questionHtmlSave, ContentMode.HTML); - questionLbl.setWidth(100, Unit.PERCENTAGE); - questionLbl.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_QUESTION_LABEL); - - return questionLbl; - } - - /** - * Enables the ok save button - * - * @param enabled - * boolean - */ - public void setOkButtonEnabled(final boolean enabled) { - window.setSaveButtonEnabled(enabled); - } - - /** - * @return confirmation window - */ - public Window getWindow() { - return window; - } - - /** - * Builder for a confirmation dialog - */ - public static class Builder { - - private final VaadinMessageSource i18n; - private final String id; - private String caption; - private String question; - private String hint; - private Resource icon; - private Component tab; - - private Runnable callbackOnSaveOrUpdate; - - private Runnable callbackOnCancel; - - /** - * private constructor - * - * @param i18n - * required field - * @param id - * required field - */ - Builder(final VaadinMessageSource i18n, final String id) { - this.i18n = i18n; - this.id = id; - } - - public Builder caption(final String caption) { - this.caption = caption; - return this; - } - - public Builder question(final String question) { - this.question = question; - return this; - } - - public Builder hint(final String hint) { - this.hint = hint; - return this; - } - - public Builder icon(final Resource icon) { - this.icon = icon; - return this; - } - - public Builder tab(final Component tab) { - this.tab = tab; - return this; - } - - public Builder onSaveOrUpdate(final Runnable callback) { - this.callbackOnSaveOrUpdate = callback; - return this; - } - - public Builder onCancel(final Runnable callback) { - this.callbackOnCancel = callback; - return this; - } - - public ConfirmationDialog build() { - Assert.isTrue(StringUtils.hasText(caption), "Caption cannot be null."); - return new ConfirmationDialog(i18n, caption, question, hint, callbackOnSaveOrUpdate, callbackOnCancel, icon, - id, tab); - } - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CoordinatesToColor.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CoordinatesToColor.java deleted file mode 100644 index 7b52490bda..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CoordinatesToColor.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.AbstractColorPicker.Coordinates2Color; - -/** - * Converts 2d-coordinates to a Color. - */ -public class CoordinatesToColor implements Coordinates2Color { - private static final long serialVersionUID = 1L; - - @Override - public Color calculate(final int x, final int y) { - return calculateHSVColor(x, y); - } - - @Override - public int[] calculate(final Color color) { - final float[] hsv = color.getHSV(); - final int x = (int) Math.round(hsv[0] * 220.0); - final int y = calculateYCoordinateOfColor(hsv); - return new int[] { x, y }; - } - - private static Color calculateHSVColor(final int x, final int y) { - final float h = (float) (x / 220.0); - float s = 1F; - float v = 1F; - if (y < 110) { - s = (float) (y / 110.0); - } else if (y > 110) { - v = (float) (1.0 - (y - 110.0) / 110.0); - } - return new Color(Color.HSVtoRGB(h, s, v)); - } - - private static int calculateYCoordinateOfColor(final float[] hsv) { - int y; - // lower half - /* Assuming hsv[] array value will have in the range of 0 to 1 */ - if (hsv[1] < 1F) { - y = (int) Math.round(hsv[1] * 110.0); - } else { - y = (int) Math.round(110.0 - ((double) hsv[1] + (double) hsv[2]) * 110.0); - } - return y; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/EntityValidator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/EntityValidator.java deleted file mode 100644 index 41d0738c38..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/EntityValidator.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; - -/** - * Base function for a validator used in window controllers. - */ -public class EntityValidator { - - private final CommonUiDependencies uiDependencies; - - /** - * Constructor - * - * @param uiDependencies - * {@link CommonUiDependencies} - */ - protected EntityValidator(final CommonUiDependencies uiDependencies) { - this.uiDependencies = uiDependencies; - - } - - protected void displayValidationError(final String messageKey, final Object... args) { - uiDependencies.getUiNotification() - .displayValidationError(uiDependencies.getI18n().getMessage(messageKey, args)); - } - - protected VaadinMessageSource getI18n() { - return uiDependencies.getI18n(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/EntityWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/EntityWindowLayout.java deleted file mode 100644 index 4b4d048f43..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/EntityWindowLayout.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import java.util.function.Consumer; - -import com.vaadin.ui.ComponentContainer; - -/** - * Interface for entity window layout - * - * @param - * Generic type entity - */ -public interface EntityWindowLayout { - - ComponentContainer getRootComponent(); - - void setEntity(final T proxyEntity); - - T getEntity(); - - /** - * Method to add validation listeners. - * - * @param validationCallback - * Validation callback event - */ - void addValidationListener(final Consumer validationCallback); -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/EventListenersAwareLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/EventListenersAwareLayout.java deleted file mode 100644 index fb072c26d5..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/EventListenersAwareLayout.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2021 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import java.util.Map; - -/** - * Interface for event aware event listeners - * - */ -public interface EventListenersAwareLayout { - - /** - * Restore components state - */ - default void restoreState() { - } - - /** - * Update components on view enter - */ - default void onViewEnter() { - } - - /** - * Set components state based on url parameters - * - * @param stateParameters - * map of state url parameters - */ - default void handleStateParameters(final Map stateParameters) { - } - - /** - * Subscribe event listeners - */ - default void subscribeListeners() { - } - - /** - * Unsubscribe event listeners - */ - default void unsubscribeListeners() { - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java deleted file mode 100644 index dc2ce8eb1a..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java +++ /dev/null @@ -1,219 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -import java.util.Collections; -import java.util.Optional; - -import org.apache.commons.lang3.StringUtils; -import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; -import org.eclipse.hawkbit.im.authentication.UserPrincipal; -import org.eclipse.hawkbit.repository.model.BaseEntity; -import org.eclipse.hawkbit.ui.utils.SpringContextHolder; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; -import org.springframework.security.oauth2.core.oidc.user.OidcUser; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; - -import com.vaadin.server.VaadinService; - -/** - * A Utility class to user details e.g. username - */ -public final class UserDetailsFormatter { - - private static final String TRIM_APPENDIX = "..."; - - private UserDetailsFormatter() { - } - - /** - * Load user details by the user name and format the user name to max 100 - * characters. See - * {@link UserDetailsFormatter#loadAndFormatUsername(String, int)}. - * - * @param username - * the user name - * @return the formatted user name (max 100 characters) cannot be - */ - public static String loadAndFormatUsername(final String username) { - return loadAndFormatUsername(username, 100); - } - - /** - * Load user details by {@link BaseEntity#getCreatedBy()} and format the - * user name. Use {@link UserDetailsFormatter#loadAndFormatUsername(String)} - * - * @param baseEntity - * the entity - * @return the formatted 'created at user name' (max 100 characters) cannot - * be - */ - public static String loadAndFormatCreatedBy(final BaseEntity baseEntity) { - if (baseEntity == null || baseEntity.getCreatedBy() == null) { - return ""; - } - - return loadAndFormatUsername(baseEntity.getCreatedBy()); - } - - /** - * Load user details by {@link BaseEntity#getLastModifiedBy()} and format - * the user name. Use - * {@link UserDetailsFormatter#loadAndFormatUsername(String)} - * - * @param baseEntity - * the entity - * @return the formatted 'last modified by user name' (max 100 characters) - * cannot be - */ - public static String loadAndFormatLastModifiedBy(final BaseEntity baseEntity) { - if (baseEntity == null || baseEntity.getLastModifiedBy() == null) { - return ""; - } - - return loadAndFormatUsername(baseEntity.getLastModifiedBy()); - } - - /** - * Load user details by the current session information and format the user - * name to max 12 characters. @see - * {@link UserDetailsFormatter#loadAndFormatUsername(String, int)} - * - * @return the formatted user name (max 12 characters) cannot be - */ - public static String formatCurrentUsername() { - return loadAndFormatUsername(getCurrentUser().getUsername(), 5); - } - - /** - * Load user details by the user name and format the user name. If the - * loaded {@link UserDetails} is not an instance of a {@link UserPrincipal}, - * then just the {@link UserDetails#getUsername()} will return. - * - * If first and last name available, they will combined. Otherwise the - * {@link UserPrincipal#getLoginname()} will formatted. The formatted name - * is reduced to 100 characters. - * - * @param username - * the user name - * @param expectedNameLength - * the name size of each name part - * @return the formatted user name (max expectedNameLength characters) - * cannot be - */ - public static String loadAndFormatUsername(final String username, final int expectedNameLength) { - final UserDetails userDetails = loadUserByUsername(username); - return formatUserName(expectedNameLength, userDetails); - } - - private static String formatUserName(final int expectedNameLength, final UserDetails userDetails) { - if (!(userDetails instanceof UserPrincipal)) { - return userDetails.getUsername(); - } - - final UserPrincipal userPrincipal = (UserPrincipal) userDetails; - return trimAndFormatDetail(userPrincipal.getLoginname(), expectedNameLength); - } - - /** - * Format the current tenant. The information is loaded by the current - * session information. - * - * @return the formatted user name (max 8 characters) can be - */ - public static String formatCurrentTenant() { - final UserDetails userDetails = getCurrentUser(); - if (!(userDetails instanceof UserPrincipal)) { - return null; - } - - final UserPrincipal userPrincipal = (UserPrincipal) userDetails; - return trimAndFormatDetail(userPrincipal.getTenant(), 8); - } - - /** - * Format the current tenant. The information is loaded by the current - * session information. - * - * @return the formatted user name (max 8 characters) can be - */ - public static Optional getCurrentTenant() { - final UserDetails userDetails = getCurrentUser(); - if (!(userDetails instanceof UserPrincipal)) { - return Optional.empty(); - } - - final UserPrincipal userPrincipal = (UserPrincipal) userDetails; - return Optional.of(userPrincipal.getTenant().trim()); - } - - /** - * @return logged in users Email address - */ - public static Optional getCurrentUserEmail() { - final UserDetails userDetails = getCurrentUser(); - if (!(userDetails instanceof UserPrincipal)) { - return Optional.empty(); - } - - final UserPrincipal userPrincipal = (UserPrincipal) userDetails; - - return Optional.ofNullable(userPrincipal.getEmail()); - } - - /** - * @return Details of currently logged-in user - */ - public static UserDetails getCurrentUser() { - final SecurityContext context = (SecurityContext) VaadinService.getCurrentRequest().getWrappedSession() - .getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); - final Authentication authentication = context.getAuthentication(); - if (authentication instanceof OAuth2AuthenticationToken) { - final OidcUser oidcUser = (OidcUser) authentication.getPrincipal(); - final Object details = authentication.getDetails(); - String tenant = "DEFAULT"; - if (details instanceof TenantAwareAuthenticationDetails) { - tenant = ((TenantAwareAuthenticationDetails) details).getTenant(); - } - return new UserPrincipal(oidcUser.getPreferredUsername(), "***", oidcUser.getGivenName(), - oidcUser.getFamilyName(), oidcUser.getPreferredUsername(), oidcUser.getEmail(), tenant, - oidcUser.getAuthorities()); - } else { - return (UserDetails) authentication.getPrincipal(); - } - } - - private static String trimAndFormatDetail(final String formatString, final int expectedDetailLength) { - final String detail = StringUtils.defaultIfEmpty(formatString, ""); - final String trimmedDetail = StringUtils.substring(detail, 0, expectedDetailLength); - if (StringUtils.length(detail) > expectedDetailLength) { - return trimmedDetail + TRIM_APPENDIX; - } - return trimmedDetail; - } - - // Exception squid:S1166 - exception has to be hidden - @SuppressWarnings({ "squid:S1166" }) - private static UserDetails loadUserByUsername(final String username) { - final UserDetailsService userDetailsService = SpringContextHolder.getInstance() - .getBean(UserDetailsService.class); - try { - return userDetailsService.loadUserByUsername(username); - } catch (final UsernameNotFoundException e) { - return new User(username, "", Collections.emptyList()); - } - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ViewNameAware.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ViewNameAware.java deleted file mode 100644 index d53a6eebb6..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ViewNameAware.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) 2021 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common; - -/** - * Interface for getting view name - * - */ -@FunctionalInterface -public interface ViewNameAware { - - /** - * Provides the name of a view - * - * @return view name - */ - String getViewName(); -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/AbstractTextFieldBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/AbstractTextFieldBuilder.java deleted file mode 100644 index 3f3ee350db..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/AbstractTextFieldBuilder.java +++ /dev/null @@ -1,164 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common.builder; - -import org.springframework.util.StringUtils; - -import com.vaadin.ui.AbstractTextField; - -/** - * Abstract Text field builder. - * - * @param - * type of the builder - * @param - * the text component - * - */ -public abstract class AbstractTextFieldBuilder { - - private String caption; - private String style; - private String styleName; - private String prompt; - private String id; - private boolean readOnly; - private boolean enabled = true; - private final int maxLengthAllowed; - - protected AbstractTextFieldBuilder(final int maxLengthAllowed) { - this.maxLengthAllowed = maxLengthAllowed; - } - - /** - * Add caption to text field - * - * @param caption - * the caption to set - * @return the builder - */ - public T caption(final String caption) { - this.caption = caption; - this.prompt = caption; - return (T) this; - } - - /** - * Add style to text field - * - * @param style - * the style to set * @return the builder - * @return the builder - */ - public T style(final String style) { - this.style = style; - return (T) this; - } - - /** - * Add style name to text field - * - * @param styleName - * the styleName to set - * @return the builder - */ - public T styleName(final String styleName) { - this.styleName = styleName; - return (T) this; - } - - /** - * Add read only to text field - * - * @param readOnly - * the readOnly to set - * @return the builder - */ - public T readOnly(final boolean readOnly) { - this.readOnly = readOnly; - return (T) this; - } - - /** - * Enable the text field - * - * @param enabled - * the enabled to set - * @return the builder - */ - public T enabled(final boolean enabled) { - this.enabled = enabled; - return (T) this; - } - - /** - * Add prompt to text field - * - * @param prompt - * the prompt to set - * @return the builder - */ - public T prompt(final String prompt) { - this.prompt = prompt; - return (T) this; - } - - /** - * Add id to text field - * - * @param id - * the id to set - * @return the builder - */ - public T id(final String id) { - this.id = id; - return (T) this; - } - - /** - * Build a textfield - * - * @return textfield - */ - public E buildTextComponent() { - final E textComponent = createTextComponent(); - - textComponent.setReadOnly(readOnly); - textComponent.setEnabled(enabled); - - if (!StringUtils.isEmpty(caption)) { - textComponent.setCaption(caption); - } - - if (!StringUtils.isEmpty(style)) { - textComponent.setStyleName(style); - } - - if (!StringUtils.isEmpty(styleName)) { - textComponent.addStyleName(styleName); - } - if (!StringUtils.isEmpty(prompt)) { - textComponent.setPlaceholder(prompt); - } - - if (maxLengthAllowed > 0) { - textComponent.setMaxLength(maxLengthAllowed); - } - - if (!StringUtils.isEmpty(id)) { - textComponent.setId(id); - } - - return textComponent; - } - - protected abstract E createTextComponent(); - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/BoundComponent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/BoundComponent.java deleted file mode 100644 index fb11a214e9..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/BoundComponent.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common.builder; - -import java.io.Serializable; - -import com.vaadin.data.Binder.Binding; -import com.vaadin.ui.Component; - -/** - * Holds a {@link Component} and its {@link Binding} - * - * @param - * Component type - */ -public class BoundComponent implements Serializable { - private static final long serialVersionUID = 1L; - - private final T component; - private final Binding binding; - - /** - * Constructor - * - * @param component - * component - * @param binding - * binding of the component - */ - public BoundComponent(final T component, final Binding binding) { - this.component = component; - this.binding = binding; - } - - /** - * @return The component - */ - public T getComponent() { - return component; - } - - /** - * Set to true if the component is required - * - * @param isRequired - * boolean - */ - public void setRequired(final boolean isRequired) { - binding.setAsRequiredEnabled(isRequired); - } - - /** - * @return boolean - */ - public boolean isValid() { - return !binding.validate(false).isError(); - } - - /** - * Validate binding - */ - public void validate() { - binding.validate(); - } - - /** - * unbind the component - */ - public void unbind() { - binding.unbind(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/FormComponentBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/FormComponentBuilder.java deleted file mode 100644 index f50b7bc43b..0000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/FormComponentBuilder.java +++ /dev/null @@ -1,423 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.ui.common.builder; - -import org.eclipse.hawkbit.repository.model.NamedEntity; -import org.eclipse.hawkbit.repository.model.NamedVersionedEntity; -import org.eclipse.hawkbit.repository.model.Type; -import org.eclipse.hawkbit.ui.common.data.aware.ActionTypeAware; -import org.eclipse.hawkbit.ui.common.data.aware.DescriptionAware; -import org.eclipse.hawkbit.ui.common.data.aware.DsIdAware; -import org.eclipse.hawkbit.ui.common.data.aware.NameAware; -import org.eclipse.hawkbit.ui.common.data.aware.StartOptionAware; -import org.eclipse.hawkbit.ui.common.data.aware.TargetFilterQueryAware; -import org.eclipse.hawkbit.ui.common.data.aware.TypeInfoAware; -import org.eclipse.hawkbit.ui.common.data.aware.VersionAware; -import org.eclipse.hawkbit.ui.common.data.providers.AbstractProxyDataProvider; -import org.eclipse.hawkbit.ui.common.data.providers.DistributionSetStatelessDataProvider; -import org.eclipse.hawkbit.ui.common.data.providers.TargetFilterQueryDataProvider; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSet; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSetInfo; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetFilterQuery; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetFilterQueryInfo; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType; -import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTypeInfo; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.management.miscs.ActionTypeOptionGroupAssignmentLayout; -import org.eclipse.hawkbit.ui.rollout.window.components.AutoStartOptionGroupLayout; -import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; -import org.eclipse.hawkbit.ui.utils.TrimmingStringConverter; -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 com.vaadin.data.Binder; -import com.vaadin.data.Binder.Binding; -import com.vaadin.data.Binder.BindingBuilder; -import com.vaadin.data.Validator; -import com.vaadin.data.ValueProvider; -import com.vaadin.server.Setter; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.ComboBox; -import com.vaadin.ui.TextArea; -import com.vaadin.ui.TextField; - -/** - * Builder class for from components - */ -public final class FormComponentBuilder { - public static final String TEXTFIELD_NAME = "textfield.name"; - public static final String TEXTFIELD_VERSION = "textfield.version"; - public static final String TEXTFIELD_DESCRIPTION = "textfield.description"; - - public static final String PROMPT_DISTRIBUTION_SET = "prompt.distribution.set"; - public static final String PROMPT_TARGET_FILTER = "prompt.target.filter"; - - public static final String CAPTION_TYPE = "caption.type"; - - private FormComponentBuilder() { - } - - /** - * Create an input field for a name - * - * @param - * type of the binder - * @param binder - * that is bound to the field - * @param i18n - * message source - * @param fieldId - * id of the field - * @return the TextField with its Binding - */ - public static BoundComponent createNameInput(final Binder binder, - final VaadinMessageSource i18n, final String fieldId) { - final TextField nameInput = new TextFieldBuilder(NamedEntity.NAME_MAX_SIZE).id(fieldId) - .caption(i18n.getMessage(TEXTFIELD_NAME)).prompt(i18n.getMessage(TEXTFIELD_NAME)).buildTextComponent(); - nameInput.setSizeUndefined(); - - final Binding binding = binder.forField(nameInput).withConverter(new TrimmingStringConverter()) - .asRequired(i18n.getMessage(UIMessageIdProvider.MESSAGE_ERROR_NAMEREQUIRED)) - .bind(NameAware::getName, NameAware::setName); - - return new BoundComponent<>(nameInput, binding); - } - - /** - * Create a required input field for a version - * - * @param - * type of the binder - * @param binder - * that is bound to the field - * @param i18n - * message source - * @param fieldId - * id of the field - * @return the TextField - */ - public static BoundComponent createVersionInput(final Binder binder, - final VaadinMessageSource i18n, final String fieldId) { - final TextField versionInput = new TextFieldBuilder(NamedVersionedEntity.VERSION_MAX_SIZE).id(fieldId) - .caption(i18n.getMessage(TEXTFIELD_VERSION)).prompt(i18n.getMessage(TEXTFIELD_VERSION)) - .buildTextComponent(); - versionInput.setSizeUndefined(); - - final Binding binding = binder.forField(versionInput).withConverter(new TrimmingStringConverter()) - .asRequired(i18n.getMessage(UIMessageIdProvider.MESSAGE_ERROR_VERSIONREQUIRED)) - .bind(VersionAware::getVersion, VersionAware::setVersion); - - return new BoundComponent<>(versionInput, binding); - } - - /** - * Create an optional input field for a description - * - * @param - * type of the binder - * @param binder - * that is bound to the field - * @param i18n - * message source - * @param fieldId - * id of the field - * @return the TextArea - */ - public static BoundComponent