From 83dc9471dcaf2d0ba9c057853ca5cf1e8b94698d Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 8 Jun 2016 16:05:48 +0200 Subject: [PATCH 01/52] Enable save button if all mandatory fields are filled (softwareModule) Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 68 +++++++++++++++--- .../CreateUpdateSoftwareTypeLayout.java | 4 +- .../hawkbit/ui/common/CommonDialogWindow.java | 69 ++++++++++++++++++- .../ui/components/SPUIComponentProvider.java | 5 +- .../ui/decorators/SPUIWindowDecorator.java | 7 +- .../CreateUpdateDistSetTypeLayout.java | 3 +- .../AbstractCreateUpdateTagLayout.java | 3 +- .../DistributionAddUpdateWindowLayout.java | 3 +- .../TargetAddUpdateWindowLayout.java | 3 +- .../rollout/AddUpdateRolloutWindowLayout.java | 3 +- 10 files changed, 146 insertions(+), 22 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index ddf229651..0dd85d08b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -9,7 +9,11 @@ package org.eclipse.hawkbit.ui.artifacts.smtable; import java.io.Serializable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -29,10 +33,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.spring.events.EventBus; +import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; @@ -129,12 +136,14 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_NAME); + nameTextField.addTextChangeListener(this::nameTextFieldChanged); /* version text field */ versionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); versionTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VERSION); + versionTextField.addTextChangeListener(this::versionTextFieldChanged); /* Vendor text field */ vendorTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.vendor"), "", ValoTheme.TEXTFIELD_TINY, @@ -159,15 +168,40 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se typeComboBox.setStyleName(SPUIDefinitions.COMBO_BOX_SPECIFIC_STYLE + " " + ValoTheme.COMBOBOX_TINY); typeComboBox.setNewItemsAllowed(Boolean.FALSE); typeComboBox.setImmediate(Boolean.TRUE); + typeComboBox.addValueChangeListener(this::typeComboBoxChanged); populateTypeNameCombo(); resetOldValues(); } - /** - * - */ + private void nameTextFieldChanged(final TextChangeEvent event) { + if (StringUtils.isNotBlank(event.getText())) { + window.getRequiredFields().put(nameTextField.getCaption(), Boolean.TRUE); + } else { + window.getRequiredFields().put(nameTextField.getCaption(), Boolean.FALSE); + } + window.checkMandatoryFields(); + } + + private void versionTextFieldChanged(final TextChangeEvent event) { + if (StringUtils.isNotBlank(event.getText())) { + window.getRequiredFields().put(versionTextField.getCaption(), Boolean.TRUE); + } else { + window.getRequiredFields().put(versionTextField.getCaption(), Boolean.FALSE); + } + window.checkMandatoryFields(); + } + + private void typeComboBoxChanged(final ValueChangeEvent event) { + if (event.getProperty().getValue() != null) { + window.getRequiredFields().put(typeComboBox.getCaption(), Boolean.TRUE); + } else { + window.getRequiredFields().put(typeComboBox.getCaption(), Boolean.FALSE); + } + window.checkMandatoryFields(); + } + private void populateTypeNameCombo() { typeComboBox.setContainerDataSource(HawkbitCommonUtil.createLazyQueryContainer( new BeanQueryFactory(SoftwareModuleTypeBeanQuery.class))); @@ -180,10 +214,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se oldVendorValue = null; } - /** - * Build the window content and get an instance of customDialogWindow - * - */ private void createWindow() { final Label madatoryStarLabel = new Label("*"); @@ -197,7 +227,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se addStyleName("lay-color"); final FormLayout formLayout = new FormLayout(); - formLayout.addComponent(mandatoryLabel); + // formLayout.addComponent(mandatoryLabel); formLayout.addComponent(typeComboBox); formLayout.addComponent(nameTextField); formLayout.addComponent(versionTextField); @@ -208,11 +238,31 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, + getMandatoryFields(formLayout)); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); nameTextField.focus(); } + private Map getMandatoryFields(final FormLayout formLayout) { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + // else if (c instanceof TextField && ((TextField) c).isRequired()) + // { + // requiredFields.put(c.getCaption(), null); + // } else if (c instanceof TextArea && ((TextArea) c).isRequired()) + // { + // requiredFields.put(c.getCaption(), null); + // } + } + return requiredFields; + } + private void addDescriptionTextChangeListener() { descTextArea.addTextChangeListener(event -> window.setSaveButtonEnabled(hasDescriptionChanged(event))); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 85844b917..ad78e09e7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -112,11 +112,13 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout getFormLayout().addComponent(assignOptiongroup); } + // TODO MR requiredFields + @Override public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null); } /** 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 index 247ad0c8f..d14830aa4 100644 --- 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 @@ -10,29 +10,38 @@ package org.eclipse.hawkbit.ui.common; import static com.google.common.base.Preconditions.checkNotNull; +import java.util.Map; + import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleBorderWithIcon; +import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.server.FontAwesome; +import com.vaadin.spring.annotation.SpringComponent; +import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Component; 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; /** - * * Superclass for pop-up-windows including a minimize and close icon in the * upper right corner and a save and cancel button at the bottom. - * */ +@SpringComponent +@ViewScope public class CommonDialogWindow extends Window { private static final long serialVersionUID = -1321949234316858703L; @@ -57,6 +66,11 @@ public class CommonDialogWindow extends Window { private final ClickListener cancelButtonClickListener; + private Map requiredFields; + + @Autowired + private I18N i18n; + /** * Constructor. * @@ -72,7 +86,8 @@ public class CommonDialogWindow extends Window { * the cancelButtonClickListener */ public CommonDialogWindow(final String caption, final Component content, final String helpLink, - final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener) { + final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, + final Map requiredFields) { checkNotNull(saveButtonClickListener); checkNotNull(cancelButtonClickListener); this.caption = caption; @@ -80,10 +95,27 @@ public class CommonDialogWindow extends Window { this.helpLink = helpLink; this.saveButtonClickListener = saveButtonClickListener; this.cancelButtonClickListener = cancelButtonClickListener; + this.requiredFields = requiredFields; init(); } + /** + * Checks the mandatory fields in the pop-up-window content. If all + * mandatory fields are filled the save button is enabled. Otherwise the + * save button is disabled. + */ + public void checkMandatoryFields() { + + for (final Map.Entry entry : requiredFields.entrySet()) { + if (entry.getValue() == null || entry.getValue().equals(Boolean.FALSE)) { + saveButton.setEnabled(false); + return; + } + } + saveButton.setEnabled(true); + } + private final void init() { if (content instanceof AbstractOrderedLayout) { @@ -94,6 +126,9 @@ public class CommonDialogWindow extends Window { if (null != content) { mainLayout.addComponent(content); } + + createMandatoryLabel(); + final HorizontalLayout buttonLayout = createActionButtonsLayout(); mainLayout.addComponent(buttonLayout); mainLayout.setComponentAlignment(buttonLayout, Alignment.TOP_CENTER); @@ -122,6 +157,17 @@ public class CommonDialogWindow extends Window { return buttonsLayout; } + private void createMandatoryLabel() { + + if (existsMandatoryFieldsInWindowContent()) { + // final Label madatoryLabel = new + // Label(i18n.get("label.mandatory.field")); + final Label madatoryLabel = new Label("* Mandatory Field"); + madatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); + mainLayout.addComponent(madatoryLabel); + } + } + private void createCancelButton() { cancelButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.CANCEL_BUTTON, "Cancel", "", "", true, FontAwesome.TIMES, SPUIButtonStyleBorderWithIcon.class); @@ -140,11 +186,20 @@ public class CommonDialogWindow extends Window { saveButton.setSizeUndefined(); saveButton.addStyleName("default-color"); saveButton.addClickListener(saveButtonClickListener); + saveButton.setEnabled(!existsMandatoryFieldsInWindowContent()); buttonsLayout.addComponent(saveButton); buttonsLayout.setComponentAlignment(saveButton, Alignment.MIDDLE_RIGHT); buttonsLayout.setExpandRatio(saveButton, 1.0F); } + private boolean existsMandatoryFieldsInWindowContent() { + + if (requiredFields != null && requiredFields.size() > 0) { + return true; + } + return false; + } + private void addHelpLink() { if (StringUtils.isEmpty(helpLink)) { @@ -167,4 +222,12 @@ public class CommonDialogWindow extends Window { return buttonsLayout; } + public Map getRequiredFields() { + return requiredFields; + } + + public void setRequiredFields(final Map requiredFields) { + this.requiredFields = requiredFields; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 170ea8dcc..2b743d2a8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -153,9 +153,10 @@ public final class SPUIComponentProvider { */ public static CommonDialogWindow getWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, - final ClickListener cancelButtonClickListener, final String helpLink) { + final ClickListener cancelButtonClickListener, final String helpLink, + final Map requiredFields) { return SPUIWindowDecorator.getDeocratedWindow(caption, id, type, content, saveButtonClickListener, - cancelButtonClickListener, helpLink); + cancelButtonClickListener, helpLink, requiredFields); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java index 9f436fd65..f9ce37158 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.decorators; +import java.util.Map; + import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; @@ -44,10 +46,11 @@ public final class SPUIWindowDecorator { */ public static CommonDialogWindow getDeocratedWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, - final ClickListener cancelButtonClickListener, final String helpLink) { + final ClickListener cancelButtonClickListener, final String helpLink, + final Map requiredFields) { final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener); + cancelButtonClickListener, requiredFields); if (null != id) { window.setId(id); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index a4a9eee35..48cdbfc6a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -610,11 +610,12 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } } + // TODO MR requiredFields @Override public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index d564accd3..d5f9fef94 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -105,10 +105,11 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected String tagNameValue; protected String tagDescValue; + // TODO MR requiredFields protected void createWindow() { reset(); setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null)); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null)); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 5b5d53524..c0a4dc165 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -504,13 +504,14 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } } + // TODO MR requiredFields public CommonDialogWindow getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); populateRequiredComponents(); resetComponents(); addDistributionWindow = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null); + null, null); addDistributionWindow.getButtonsLayout().removeStyleName("actionButtonsMargin"); return addDistributionWindow; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 5a26df572..a5a562c11 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -241,10 +241,11 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } } + // TODO MR requiredFields public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, null); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 2d180f67b..41742d5f7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -157,11 +157,12 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { buildLayout(); } + // TODO MR requiredFields public CommonDialogWindow getWindow() { addUpdateRolloutWindow = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), - uiProperties.getLinks().getDocumentation().getRolloutView()); + uiProperties.getLinks().getDocumentation().getRolloutView(), null); return addUpdateRolloutWindow; } From bbaa6baa728a7ffae079c3cdd83b277a4ed9692a Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 9 Jun 2016 13:24:40 +0200 Subject: [PATCH 02/52] Improved enable save button functionality when update tag Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 55 +++------ .../CreateUpdateSoftwareTypeLayout.java | 41 ++++++- .../hawkbit/ui/common/CommonDialogWindow.java | 74 +++++++++++- .../ui/components/SPUIComponentProvider.java | 2 + .../CreateUpdateDistSetTypeLayout.java | 49 ++++++-- .../AbstractCreateUpdateTagLayout.java | 71 +++++++++-- .../ui/layouts/CreateUpdateTypeLayout.java | 9 +- .../DistributionAddUpdateWindowLayout.java | 64 ++++++---- ...eateUpdateDistributionTagLayoutWindow.java | 5 + .../TargetAddUpdateWindowLayout.java | 43 +++++-- .../CreateUpdateTargetTagLayoutWindow.java | 4 + .../rollout/AddUpdateRolloutWindowLayout.java | 113 ++++++++++++------ 12 files changed, 384 insertions(+), 146 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 0dd85d08b..309c111ea 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -13,7 +13,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -73,8 +72,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se @Autowired private transient EntityFactory entityFactory; - private Label mandatoryLabel; - private TextField nameTextField; private TextField versionTextField; @@ -136,14 +133,14 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_NAME); - nameTextField.addTextChangeListener(this::nameTextFieldChanged); + nameTextField.addTextChangeListener(this::listenerNameTextFieldChanged); /* version text field */ versionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); versionTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VERSION); - versionTextField.addTextChangeListener(this::versionTextFieldChanged); + versionTextField.addTextChangeListener(this::listenerVersionTextFieldChanged); /* Vendor text field */ vendorTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.vendor"), "", ValoTheme.TEXTFIELD_TINY, @@ -157,49 +154,29 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se addDescriptionTextChangeListener(); addVendorTextChangeListener(); - /* Label for mandatory symbol */ - mandatoryLabel = new Label(i18n.get("label.mandatory.field")); - mandatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - mandatoryLabel.addStyleName(ValoTheme.LABEL_SMALL); - typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true, null, i18n.get("upload.swmodule.type")); typeComboBox.setId(SPUIComponentIdProvider.SW_MODULE_TYPE); typeComboBox.setStyleName(SPUIDefinitions.COMBO_BOX_SPECIFIC_STYLE + " " + ValoTheme.COMBOBOX_TINY); typeComboBox.setNewItemsAllowed(Boolean.FALSE); typeComboBox.setImmediate(Boolean.TRUE); - typeComboBox.addValueChangeListener(this::typeComboBoxChanged); + typeComboBox.addValueChangeListener(this::listenerTypeComboBoxChanged); populateTypeNameCombo(); resetOldValues(); } - private void nameTextFieldChanged(final TextChangeEvent event) { - if (StringUtils.isNotBlank(event.getText())) { - window.getRequiredFields().put(nameTextField.getCaption(), Boolean.TRUE); - } else { - window.getRequiredFields().put(nameTextField.getCaption(), Boolean.FALSE); - } - window.checkMandatoryFields(); + private void listenerNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, nameTextField); } - private void versionTextFieldChanged(final TextChangeEvent event) { - if (StringUtils.isNotBlank(event.getText())) { - window.getRequiredFields().put(versionTextField.getCaption(), Boolean.TRUE); - } else { - window.getRequiredFields().put(versionTextField.getCaption(), Boolean.FALSE); - } - window.checkMandatoryFields(); + private void listenerVersionTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, versionTextField); } - private void typeComboBoxChanged(final ValueChangeEvent event) { - if (event.getProperty().getValue() != null) { - window.getRequiredFields().put(typeComboBox.getCaption(), Boolean.TRUE); - } else { - window.getRequiredFields().put(typeComboBox.getCaption(), Boolean.FALSE); - } - window.checkMandatoryFields(); + private void listenerTypeComboBoxChanged(final ValueChangeEvent event) { + window.checkMandatoryComboBox(event, typeComboBox); } private void populateTypeNameCombo() { @@ -212,6 +189,10 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private void resetOldValues() { oldDescriptionValue = null; oldVendorValue = null; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void createWindow() { @@ -227,7 +208,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se addStyleName("lay-color"); final FormLayout formLayout = new FormLayout(); - // formLayout.addComponent(mandatoryLabel); formLayout.addComponent(typeComboBox); formLayout.addComponent(nameTextField); formLayout.addComponent(versionTextField); @@ -252,13 +232,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { requiredFields.put(c.getCaption(), null); } - // else if (c instanceof TextField && ((TextField) c).isRequired()) - // { - // requiredFields.put(c.getCaption(), null); - // } else if (c instanceof TextArea && ((TextArea) c).isRequired()) - // { - // requiredFields.put(c.getCaption(), null); - // } } return requiredFields; } @@ -347,6 +320,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private void closeThisWindow() { window.close(); UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } /** @@ -383,6 +357,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se } else { addNewBaseSoftware(); } + window.setSaveButtonEnabled(false); } private boolean hasDescriptionChanged(final TextChangeEvent event) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index ad78e09e7..7473d5509 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -9,7 +9,10 @@ package org.eclipse.hawkbit.ui.artifacts.smtype; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; @@ -31,11 +34,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Component; import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.components.colorpicker.ColorChangeListener; @@ -69,7 +75,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout @Override protected void addListeners() { super.addListeners(); - optiongroup.addValueChangeListener(this::createOptionValueChanged); + optiongroup.addValueChangeListener(this::optionValueChanged); } @Override @@ -86,11 +92,13 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_NAME); + tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_KEY); + typeKey.addTextChangeListener(this::typeKeyTextFieldChanged); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "", @@ -103,6 +111,14 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout singleMultiOptionGroup(); } + private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, tagName); + } + + private void typeKeyTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, typeKey); + } + @Override protected void buildLayout() { @@ -112,13 +128,23 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout getFormLayout().addComponent(assignOptiongroup); } - // TODO MR requiredFields - @Override public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields()); + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = getFormLayout().iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; } /** @@ -128,9 +154,9 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout * ValueChangeEvent */ @Override - protected void createOptionValueChanged(final ValueChangeEvent event) { + protected void optionValueChanged(final ValueChangeEvent event) { - super.createOptionValueChanged(event); + super.optionValueChanged(event); if (updateTypeStr.equals(event.getProperty().getValue())) { assignOptiongroup.setEnabled(false); @@ -172,6 +198,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout .findSoftwareModuleTypeByName(targetTagSelected); if (null != selectedTypeTag) { tagDesc.setValue(selectedTypeTag.getDescription()); + setTagDescOriginal(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); if (selectedTypeTag.getMaxAssignments() == Integer.MAX_VALUE) { assignOptiongroup.setValue(multiAssignStr); @@ -201,6 +228,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout @Override protected void save(final ClickEvent event) { if (!mandatoryValuesPresent()) { + window.setSaveButtonEnabled(false); return; } @@ -216,6 +244,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout updateSWModuleType(existingSMTypeByName); } + window.setSaveButtonEnabled(false); } private void createNewSWModuleType() { 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 index d14830aa4..7b5df4a8f 100644 --- 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 @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.common; import static com.google.common.base.Preconditions.checkNotNull; +import java.io.Serializable; import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -20,11 +21,14 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; +import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.FontAwesome; -import com.vaadin.spring.annotation.SpringComponent; -import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.ui.AbstractOrderedLayout; +import com.vaadin.ui.AbstractSelect; +import com.vaadin.ui.AbstractTextField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; @@ -40,9 +44,7 @@ import com.vaadin.ui.themes.ValoTheme; * Superclass for pop-up-windows including a minimize and close icon in the * upper right corner and a save and cancel button at the bottom. */ -@SpringComponent -@ViewScope -public class CommonDialogWindow extends Window { +public class CommonDialogWindow extends Window implements Serializable { private static final long serialVersionUID = -1321949234316858703L; @@ -100,12 +102,38 @@ public class CommonDialogWindow extends Window { init(); } + public void checkMandatoryTextField(final TextChangeEvent event, final AbstractTextField textfield) { + + if (StringUtils.isNotBlank(event.getText())) { + getRequiredFields().put(textfield.getCaption(), Boolean.TRUE); + } else { + getRequiredFields().put(textfield.getCaption(), Boolean.FALSE); + } + checkMandatoryFields(); + } + + public void checkMandatoryComboBox(final ValueChangeEvent event, final AbstractSelect select) { + + if (event.getProperty().getValue() != null) { + if (StringUtils.isNotBlank(select.getCaption())) { + getRequiredFields().put(select.getCaption(), Boolean.TRUE); + } + getRequiredFields().put(select.getId(), Boolean.TRUE); + } else { + if (StringUtils.isNotBlank(select.getCaption())) { + getRequiredFields().put(select.getCaption(), Boolean.FALSE); + } + getRequiredFields().put(select.getId(), Boolean.FALSE); + } + checkMandatoryFields(); + } + /** * Checks the mandatory fields in the pop-up-window content. If all * mandatory fields are filled the save button is enabled. Otherwise the * save button is disabled. */ - public void checkMandatoryFields() { + private void checkMandatoryFields() { for (final Map.Entry entry : requiredFields.entrySet()) { if (entry.getValue() == null || entry.getValue().equals(Boolean.FALSE)) { @@ -116,6 +144,40 @@ public class CommonDialogWindow extends Window { saveButton.setEnabled(true); } + public void updateRequiredFields(final String fieldId, final Boolean filled) { + + getRequiredFields().put(fieldId, Boolean.TRUE); + checkMandatoryFields(); + } + + public void checkChanges(final String newText, final String oldText) { + + if ((StringUtils.isNotBlank(newText) && !newText.equals(oldText)) + || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText))) { + saveButton.setEnabled(true); + } else { + saveButton.setEnabled(false); + } + } + + public void checkColorChange(final Color newColor, final Color oldColor) { + + if (newColor.equals(oldColor)) { + setSaveButtonEnabled(false); + } else { + setSaveButtonEnabled(true); + } + } + + public void resetRequiredFieldsValues() { + // Reset mandatory fields are filled marker + if (getRequiredFields() != null) { + for (final Map.Entry entry : getRequiredFields().entrySet()) { + entry.setValue(null); + } + } + } + private final void init() { if (content instanceof AbstractOrderedLayout) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 2b743d2a8..3ba71fce5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -205,6 +205,8 @@ public final class SPUIComponentProvider { /** * Get Label UI component. * * + * @param caption + * set the caption of the textArea * @param style * set style * @param styleName diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 48cdbfc6a..a04136a48 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -8,7 +8,10 @@ */ package org.eclipse.hawkbit.ui.distributions.disttype; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -37,9 +40,11 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import com.vaadin.data.Item; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.util.IndexedContainer; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; @@ -94,11 +99,13 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_NAME); + tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_KEY); + typeKey.addTextChangeListener(this::listenerTypeKeyTextFieldChanged); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "", @@ -109,6 +116,15 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc.setNullRepresentation(""); } + private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { + + window.checkMandatoryTextField(event, tagName); + } + + private void listenerTypeKeyTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, typeKey); + } + @Override protected void buildLayout() { @@ -247,10 +263,12 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void addSMType() { final Set selectedIds = (Set) sourceTable.getValue(); - if (null != selectedIds && !selectedIds.isEmpty()) { + if (selectedIds != null && !selectedIds.isEmpty()) { for (final Long id : selectedIds) { addTargetTableData(id); } + + window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); } } @@ -264,6 +282,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout selectedTable.removeItem(id); } } + if (selectedIds == null || selectedIds.isEmpty()) { + window.updateRequiredFields(selectedTable.getId(), Boolean.FALSE); + } } @SuppressWarnings("unchecked") @@ -484,9 +505,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout * ValueChangeEvent */ @Override - protected void createOptionValueChanged(final ValueChangeEvent event) { + protected void optionValueChanged(final ValueChangeEvent event) { - super.createOptionValueChanged(event); + super.optionValueChanged(event); if (updateTypeStr.equals(event.getProperty().getValue())) { selectedTable.getContainerDataSource().removeAllItems(); @@ -551,18 +572,17 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout final DistributionSetType selectedTypeTag = fetchDistributionSetType(distSetTypeSelected); if (null != selectedTypeTag) { tagDesc.setValue(selectedTypeTag.getDescription()); + setTagDescOriginal(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); if (distributionSetManagement.countDistributionSetsByType(selectedTypeTag) <= 0) { distTypeSelectLayout.setEnabled(true); selectedTable.setEnabled(true); - window.setSaveButtonEnabled(true); } else { uiNotification.displayValidationError( selectedTypeTag.getName() + " " + i18n.get("message.error.dist.set.type.update")); distTypeSelectLayout.setEnabled(false); selectedTable.setEnabled(false); - window.setSaveButtonEnabled(false); } for (final SoftwareModuleType swModuleType : selectedTypeTag.getOptionalModuleTypes()) { addTargetTableforUpdate(swModuleType, false); @@ -607,15 +627,30 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } else { updateDistributionSetType(existingDistTypeByKey); } + window.setSaveButtonEnabled(false); } } - // TODO MR requiredFields @Override public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields()); + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = getFormLayout().iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + // Selected SoftwareModulesType + requiredFields.put(selectedTable.getId(), null); + + return requiredFields; } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index d5f9fef94..f8fb5c3e0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -8,6 +8,10 @@ */ package org.eclipse.hawkbit.ui.layouts; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.SpPermissionChecker; @@ -25,7 +29,6 @@ import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; @@ -33,11 +36,14 @@ import org.vaadin.spring.events.EventBus; import com.google.common.base.Strings; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.GridLayout; @@ -87,7 +93,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected CommonDialogWindow window; protected Label colorLabel; - protected Label madatoryLabel; protected TextField tagName; protected TextArea tagDesc; protected Button tagColorPreviewBtn; @@ -105,11 +110,25 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected String tagNameValue; protected String tagDescValue; - // TODO MR requiredFields + private Color selectedColorOriginal; + private String tagDescOriginal; + protected void createWindow() { reset(); setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null)); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields())); + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; } /** @@ -158,7 +177,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent createTagStr = i18n.get("label.create.tag"); updateTagStr = i18n.get("label.update.tag"); comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag"), null); - madatoryLabel = getMandatoryLabel(); colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag.color"), null); colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); @@ -166,6 +184,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_TARGET_TAG_NAME); + tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"), @@ -174,6 +193,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagDesc.setId(SPUIDefinitions.NEW_TARGET_TAG_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); + tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); tagNameComboBox = SPUIComponentProvider.getComboBox(null, "", "", null, null, false, "", i18n.get("label.combobox.tag")); @@ -186,6 +206,16 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagColorPreviewBtn.setStyleName(TAG_DYNAMIC_STYLE); } + private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { + + window.checkMandatoryTextField(event, tagName); + } + + private void listenerTagDescTextAreaChanged(final TextChangeEvent event) { + + window.checkChanges(event.getText(), tagDescOriginal); + } + protected void buildLayout() { mainLayout = new GridLayout(3, 2); @@ -201,7 +231,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent formLayout.addComponent(optiongroup); formLayout.addComponent(comboLayout); - formLayout.addComponent(madatoryLabel); formLayout.addComponent(tagName); formLayout.addComponent(tagDesc); formLayout.addStyleName("form-lastrow"); @@ -269,12 +298,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent } } - protected Label getMandatoryLabel() { - final Label label = new Label(i18n.get("label.mandatory.field")); - label.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); - return label; - } - private void tagNameChosen(final ValueChangeEvent event) { final String tagSelected = (String) event.getProperty().getValue(); if (null != tagSelected) { @@ -319,6 +342,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } + window.setSaveButtonEnabled(false); // close the color picker layout tagPreviewBtnClicked = false; // reset the selected color - Set default color @@ -347,6 +371,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor()); colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor()); tagPreviewBtnClicked = false; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } /** @@ -434,11 +462,14 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent createDynamicStyleForComponents(tagName, tagDesc, colorPickedPreview); colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor()); } + + window.checkColorChange(colorPickerLayout.getSelectedColor(), selectedColorOriginal); } protected void closeWindow() { window.close(); UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } /** @@ -643,4 +674,20 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent return formLayout; } + public Color getSelectedColorOriginal() { + return selectedColorOriginal; + } + + public void setSelectedColorOriginal(final Color selectedColorOriginal) { + this.selectedColorOriginal = selectedColorOriginal; + } + + public String getTagDescOriginal() { + return tagDescOriginal; + } + + public void setTagDescOriginal(final String tagDescOriginal) { + this.tagDescOriginal = tagDescOriginal; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index 1987d6053..c67d35321 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -52,7 +52,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { @Override protected void addListeners() { super.addListeners(); - optiongroup.addValueChangeListener(this::createOptionValueChanged); + optiongroup.addValueChangeListener(this::optionValueChanged); } @Override @@ -61,7 +61,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { createTypeStr = i18n.get("label.create.type"); updateTypeStr = i18n.get("label.update.type"); comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type"), null); - madatoryLabel = getMandatoryLabel(); colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type.color"), null); colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); @@ -137,7 +136,8 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { * @param event * ValueChangeEvent */ - protected void createOptionValueChanged(final ValueChangeEvent event) { + @Override + protected void optionValueChanged(final ValueChangeEvent event) { if (updateTypeStr.equals(event.getProperty().getValue())) { tagName.clear(); @@ -158,6 +158,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } + window.setSaveButtonEnabled(false); restoreComponentStyles(); getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); getColorPickerLayout().getSelPreview() @@ -236,12 +237,14 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); createDynamicStyleForComponents(tagName, typeKey, tagDesc, ColorPickerConstants.DEFAULT_COLOR); getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); + setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); } else { getColorPickerLayout().setSelectedColor(ColorPickerHelper.rgbToColorConverter(color)); getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); createDynamicStyleForComponents(tagName, typeKey, tagDesc, color); getPreviewButtonColor(color); + setSelectedColorOriginal(ColorPickerHelper.rgbToColorConverter(color)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index c0a4dc165..82cf2390c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.management.dstable; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -49,12 +50,12 @@ import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.CheckBox; import com.vaadin.ui.ComboBox; import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Label; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; @@ -92,13 +93,12 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private TextField distNameTextField; private TextField distVersionTextField; - private Label madatoryLabel; private TextArea descTextArea; private CheckBox reqMigStepCheckbox; private ComboBox distsetTypeNameComboBox; private boolean editDistribution = Boolean.FALSE; private Long editDistId; - private CommonDialogWindow addDistributionWindow; + private CommonDialogWindow window; private String originalDistName; private String originalDistVersion; private String originalDistDescription; @@ -132,7 +132,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { setSizeUndefined(); formLayout = new FormLayout(); - formLayout.addComponent(madatoryLabel); formLayout.addComponent(distsetTypeNameComboBox); formLayout.addComponent(distNameTextField); formLayout.addComponent(distVersionTextField); @@ -152,12 +151,14 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); distNameTextField.setId(SPUIComponentIdProvider.DIST_ADD_NAME); distNameTextField.setNullRepresentation(""); + distNameTextField.addTextChangeListener(this::listenerDistNameTextFieldChanged); distVersionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); distVersionTextField.setId(SPUIComponentIdProvider.DIST_ADD_VERSION); distVersionTextField.setNullRepresentation(""); + distVersionTextField.addTextChangeListener(this::listenerDistVersionTextFieldChanged); distsetTypeNameComboBox = SPUIComponentProvider.getComboBox(i18n.get("label.combobox.type"), "", "", null, "", false, "", i18n.get("label.combobox.type")); @@ -171,16 +172,20 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { descTextArea.setId(SPUIComponentIdProvider.DIST_ADD_DESC); descTextArea.setNullRepresentation(""); - /* Label for mandatory symbol */ - madatoryLabel = new Label(i18n.get("label.mandatory.field")); - madatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); - reqMigStepCheckbox = SPUIComponentProvider.getCheckBox(i18n.get("checkbox.dist.required.migration.step"), "dist-checkbox-style", null, false, ""); reqMigStepCheckbox.addStyleName(ValoTheme.CHECKBOX_SMALL); reqMigStepCheckbox.setId(SPUIComponentIdProvider.DIST_ADD_MIGRATION_CHECK); } + private void listenerDistNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, distNameTextField); + } + + private void listenerDistVersionTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, distVersionTextField); + } + /** * Get the LazyQueryContainer instance for DistributionSetTypes. * @@ -201,7 +206,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } private void enableSaveButton() { - addDistributionWindow.setSaveButtonEnabled(true); + window.setSaveButtonEnabled(true); } private DistributionSetType getDefaultDistributionSetType() { @@ -210,17 +215,16 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } private void disableSaveButton() { - addDistributionWindow.setSaveButtonEnabled(false); + window.setSaveButtonEnabled(false); } private void saveDistribution() { - /* add new or update target */ if (editDistribution) { updateDistribution(); } else { addNewDistribution(); } - + window.setSaveButtonEnabled(false); } /** @@ -298,8 +302,9 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { * Close window. */ private void closeThisWindow() { - addDistributionWindow.close(); - UI.getCurrent().removeWindow(addDistributionWindow); + window.close(); + UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } /** @@ -398,11 +403,15 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { distsetTypeNameComboBox.removeStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); descTextArea.clear(); reqMigStepCheckbox.clear(); - if (addDistributionWindow != null) { - addDistributionWindow.setSaveButtonEnabled(true); + if (window != null) { + window.setSaveButtonEnabled(true); } removeListeners(); changedComponents.clear(); + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void populateRequiredComponents() { @@ -482,7 +491,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { public void populateValuesOfDistribution(final Long editDistId) { this.editDistId = editDistId; editDistribution = Boolean.TRUE; - addDistributionWindow.setSaveButtonEnabled(false); + window.setSaveButtonEnabled(false); final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); if (distSet != null) { distNameTextField.setValue(distSet.getName()); @@ -504,17 +513,28 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } } - // TODO MR requiredFields public CommonDialogWindow getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); populateRequiredComponents(); resetComponents(); - addDistributionWindow = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, + window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, null); - addDistributionWindow.getButtonsLayout().removeStyleName("actionButtonsMargin"); + null, getMandatoryFields()); + window.getButtonsLayout().removeStyleName("actionButtonsMargin"); - return addDistributionWindow; + return window; + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java index 0d4da54e8..3bee67345 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java @@ -98,6 +98,7 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat updateExistingTag(existingDistTag); } } + window.setSaveButtonEnabled(false); } /** @@ -159,11 +160,14 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat final DistributionSetTag selectedDistTag = tagManagement.findDistributionSetTag(distTagSelected); if (null != selectedDistTag) { tagDesc.setValue(selectedDistTag.getDescription()); + setTagDescOriginal(selectedDistTag.getDescription()); if (null == selectedDistTag.getColour()) { setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); + setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); } else { setTagColor(ColorPickerHelper.rgbToColorConverter(selectedDistTag.getColour()), selectedDistTag.getColour()); + setSelectedColorOriginal(ColorPickerHelper.rgbToColorConverter(selectedDistTag.getColour())); } } } @@ -181,4 +185,5 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat setOptionGroupDefaultValue(permChecker.hasCreateDistributionPermission(), permChecker.hasUpdateDistributionPermission()); } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index a5a562c11..e5d65295b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -8,9 +8,13 @@ */ package org.eclipse.hawkbit.ui.management.targettable; +import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.model.Target; @@ -35,6 +39,8 @@ import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.VaadinSessionScope; +import com.vaadin.ui.AbstractField; +import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; @@ -73,7 +79,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private TextField controllerIDTextField; private TextField nameTextField; private TextArea descTextArea; - private Label madatoryLabel; private boolean editTarget = Boolean.FALSE; private String controllerId; private FormLayout formLayout; @@ -100,6 +105,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { controllerIDTextField = SPUIComponentProvider.getTextField( i18n.get("prompt.target.id"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("prompt.target.id"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); controllerIDTextField.setId(SPUIComponentIdProvider.TARGET_ADD_CONTROLLER_ID); + controllerIDTextField.addTextChangeListener(this::listenerControllerIDTextFieldChanged); /* Textfield for target name */ nameTextField = SPUIComponentProvider.getTextField( i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, false, null, @@ -111,10 +117,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.TARGET_ADD_DESC); descTextArea.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY); - - /* Label for mandatory symbol */ - madatoryLabel = new Label(i18n.get("label.mandatory.field")); - madatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); + } + + private void listenerControllerIDTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, controllerIDTextField); } private void buildLayout() { @@ -125,14 +131,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { */ formLayout = new FormLayout(); - formLayout.addComponent(madatoryLabel); formLayout.addComponent(controllerIDTextField); formLayout.addComponent(nameTextField); formLayout.addComponent(descTextArea); - if (Boolean.TRUE.equals(editTarget)) { - madatoryLabel.setVisible(Boolean.FALSE); - } nameTextField.focus(); } @@ -211,6 +213,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } else { addNewTarget(); } + window.setSaveButtonEnabled(false); } private void discardTargetListner() { @@ -241,13 +244,24 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } } - // TODO MR requiredFields public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields()); return window; } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; + } /** * clear all fields of Target Edit Window. @@ -261,12 +275,17 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { controllerIDTextField.clear(); descTextArea.clear(); editTarget = Boolean.FALSE; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void closeThisWindow() { editTarget = Boolean.FALSE; window.close(); UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } private void setTargetValues(final Target target, final String name, final String description) { @@ -287,7 +306,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private boolean duplicateCheck(final String newControlllerId) { final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim()); if (existingTarget != null) { - uINotification.displayValidationError(i18n.get("message.target.duplicate.check")); + uINotification.displayValidationError(i18n.get("message.target.duplicate.check", new Object[] {newControlllerId})); return false; } else { return true; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java index a7d612f72..81c0c72ae 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java @@ -91,11 +91,14 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa final TargetTag selectedTargetTag = tagManagement.findTargetTag(targetTagSelected); if (null != selectedTargetTag) { tagDesc.setValue(selectedTargetTag.getDescription()); + setTagDescOriginal(selectedTargetTag.getDescription()); if (null == selectedTargetTag.getColour()) { setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); + setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); } else { setTagColor(ColorPickerHelper.rgbToColorConverter(selectedTargetTag.getColour()), selectedTargetTag.getColour()); + setSelectedColorOriginal(ColorPickerHelper.rgbToColorConverter(selectedTargetTag.getColour())); } } } @@ -112,6 +115,7 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa updateExistingTag(existingTag); } } + window.setSaveButtonEnabled(false); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 41742d5f7..1226ec5fb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -10,7 +10,9 @@ package org.eclipse.hawkbit.ui.rollout.rollout; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; @@ -58,6 +60,7 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Validator; import com.vaadin.data.validator.IntegerRangeValidator; import com.vaadin.data.validator.RegexpValidator; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.ComboBox; @@ -115,8 +118,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Autowired private transient EventBus.SessionEventBus eventBus; - private Label mandatoryLabel; - private TextField rolloutName; private ComboBox distributionSet; @@ -135,7 +136,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private OptionGroup errorThresholdOptionGroup; - private CommonDialogWindow addUpdateRolloutWindow; + private CommonDialogWindow window; private Boolean editRolloutEnabled; @@ -157,13 +158,25 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { buildLayout(); } - // TODO MR requiredFields public CommonDialogWindow getWindow() { - addUpdateRolloutWindow = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, + window = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), - uiProperties.getLinks().getDocumentation().getRolloutView(), null); - return addUpdateRolloutWindow; + uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields()); + return window; + } + + private Map getMandatoryFields() { + + final Map requiredFields = new HashMap<>(); + requiredFields.put(rolloutName.getId(), null); + requiredFields.put(distributionSet.getId(), null); + requiredFields.put(targetFilterQueryCombo.getId(), null); + requiredFields.put(noOfGroups.getId(), null); + requiredFields.put(triggerThreshold.getId(), null); + requiredFields.put(errorThreshold.getId(), null); + + return requiredFields; } /** @@ -187,6 +200,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { actionTypeOptionGroupLayout.selectDefaultOption(); totalTargetsCount = 0L; rolloutForEdit = null; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void resetFields() { @@ -208,26 +225,25 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { setRows(9); setColumns(3); - addComponent(mandatoryLabel, 1, 0, 2, 0); - addComponent(getLabel("textfield.name"), 0, 1); - addComponent(rolloutName, 1, 1); - addComponent(getLabel("prompt.distribution.set"), 0, 2); - addComponent(distributionSet, 1, 2); - addComponent(getLabel("prompt.target.filter"), 0, 3); - addComponent(targetFilterQueryCombo, 1, 3); - addComponent(totalTargetsLabel, 2, 3); - addComponent(getLabel("prompt.number.of.groups"), 0, 4); - addComponent(noOfGroups, 1, 4); - addComponent(groupSizeLabel, 2, 4); - addComponent(getLabel("prompt.tigger.threshold"), 0, 5); - addComponent(triggerThreshold, 1, 5); - addComponent(getPercentHintLabel(), 2, 5); - addComponent(getLabel("prompt.error.threshold"), 0, 6); - addComponent(errorThreshold, 1, 6); - addComponent(errorThresholdOptionGroup, 2, 6); - addComponent(getLabel("textfield.description"), 0, 7); - addComponent(description, 1, 7, 2, 7); - addComponent(actionTypeOptionGroupLayout, 0, 8, 2, 8); + addComponent(getLabel("textfield.name"), 0, 0); + addComponent(rolloutName, 1, 0); + addComponent(getLabel("prompt.distribution.set"), 0, 1); + addComponent(distributionSet, 1, 1); + addComponent(getLabel("prompt.target.filter"), 0, 2); + addComponent(targetFilterQueryCombo, 1, 2); + addComponent(totalTargetsLabel, 2, 2); + addComponent(getLabel("prompt.number.of.groups"), 0, 3); + addComponent(noOfGroups, 1, 3); + addComponent(groupSizeLabel, 2, 3); + addComponent(getLabel("prompt.tigger.threshold"), 0, 4); + addComponent(triggerThreshold, 1, 4); + addComponent(getPercentHintLabel(), 2, 4); + addComponent(getLabel("prompt.error.threshold"), 0, 5); + addComponent(errorThreshold, 1, 5); + addComponent(errorThresholdOptionGroup, 2, 5); + addComponent(getLabel("textfield.description"), 0, 6); + addComponent(description, 1, 6, 2, 6); + addComponent(actionTypeOptionGroupLayout, 0, 7, 2, 7); rolloutName.focus(); } @@ -249,7 +265,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void createRequiredComponents() { - mandatoryLabel = createMandatoryLabel(); rolloutName = createRolloutNameField(); distributionSet = createDistributionSetCombo(); populateDistributionSet(); @@ -308,11 +323,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { errorThresoldOptions.addStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL); errorThresoldOptions.addStyleName(SPUIStyleDefinitions.ROLLOUT_OPTION_GROUP); errorThresoldOptions.setSizeUndefined(); - errorThresoldOptions.addValueChangeListener(this::onErrorThresoldOptionChange); + errorThresoldOptions.addValueChangeListener(this::listenerOnErrorThresoldOptionChange); return errorThresoldOptions; } - private void onErrorThresoldOptionChange(final ValueChangeEvent event) { + private void listenerOnErrorThresoldOptionChange(final ValueChangeEvent event) { errorThreshold.clear(); errorThreshold.removeAllValidators(); if (event.getProperty().getValue().equals(ERRORTHRESOLDOPTIONS.COUNT.getValue())) { @@ -331,11 +346,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { targetFilter.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); targetFilter.setId(SPUIComponentIdProvider.ROLLOUT_TARGET_FILTER_COMBO_ID); targetFilter.setSizeUndefined(); - targetFilter.addValueChangeListener(event -> onTargetFilterChange()); + targetFilter.addValueChangeListener(this::onTargetFilterChange); return targetFilter; } - private void onTargetFilterChange() { + private void onTargetFilterChange(final ValueChangeEvent event) { final String filterQueryString = getTargetFilterQuery(); if (!Strings.isNullOrEmpty(filterQueryString)) { totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(filterQueryString); @@ -346,6 +361,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { totalTargetsLabel.setVisible(false); } onGroupNumberChange(); + + window.checkMandatoryComboBox(event, targetFilterQueryCombo); } private String getTotalTargetMessage() { @@ -490,8 +507,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void closeThisWindow() { - addUpdateRolloutWindow.close(); - UI.getCurrent().removeWindow(addUpdateRolloutWindow); + window.close(); + UI.getCurrent().removeWindow(window); } private boolean mandatoryCheck() { @@ -560,18 +577,29 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { errorField.setId(SPUIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_ID); errorField.setMaxLength(7); errorField.setSizeUndefined(); + errorField.addTextChangeListener(this::listenerErrorThresholdTextFieldChanged); return errorField; } + private void listenerErrorThresholdTextFieldChanged(final TextChangeEvent event) { + + window.checkMandatoryTextField(event, errorThreshold); + } + private TextField createTriggerThresold() { final TextField thresholdField = getTextfield("prompt.tigger.threshold"); thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID); thresholdField.addValidator(new ThresholdFieldValidator()); thresholdField.setSizeUndefined(); thresholdField.setMaxLength(3); + thresholdField.addTextChangeListener(this::listenerTriggerThresholdTextFieldChanged); return thresholdField; } + private void listenerTriggerThresholdTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, triggerThreshold); + } + private TextField createNoOfGroupsField() { final TextField noOfGroupsField = getTextfield("prompt.number.of.groups"); noOfGroupsField.setId(SPUIComponentIdProvider.ROLLOUT_NO_OF_GROUPS_ID); @@ -579,9 +607,14 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroupsField.setSizeUndefined(); noOfGroupsField.setMaxLength(3); noOfGroupsField.addValueChangeListener(evevt -> onGroupNumberChange()); + noOfGroupsField.addTextChangeListener(this::listenerNoOfGroupsTextFieldChanged); return noOfGroupsField; } + private void listenerNoOfGroupsTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, noOfGroups); + } + private void onGroupNumberChange() { if (noOfGroups.isValid() && !Strings.isNullOrEmpty(noOfGroups.getValue())) { groupSizeLabel.setValue(getTargetPerGroupMessage(String.valueOf(getGroupSize()))); @@ -599,9 +632,14 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { dsSet.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); dsSet.setId(SPUIComponentIdProvider.ROLLOUT_DS_ID); dsSet.setSizeUndefined(); + dsSet.addValueChangeListener(this::listenerDistributionSetChanged); return dsSet; } + private void listenerDistributionSetChanged(final ValueChangeEvent event) { + window.checkMandatoryComboBox(event, distributionSet); + } + private void populateDistributionSet() { final Container container = createDsComboContainer(); distributionSet.setContainerDataSource(container); @@ -620,13 +658,12 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { final TextField rolloutNameField = getTextfield("textfield.name"); rolloutNameField.setId(SPUIComponentIdProvider.ROLLOUT_NAME_FIELD_ID); rolloutNameField.setSizeUndefined(); + rolloutNameField.addTextChangeListener(this::listenerRolloutNameTextFieldChanged); return rolloutNameField; } - private Label createMandatoryLabel() { - final Label madatoryLbl = new Label(i18n.get("label.mandatory.field")); - madatoryLbl.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); - return madatoryLbl; + private void listenerRolloutNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, rolloutName); } private String getRolloutName() { From 72940d854aeefff501f8fb2f0cab45fa5578d527 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Fri, 10 Jun 2016 09:40:05 +0200 Subject: [PATCH 03/52] Optimize layout Configure new Rollout Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 1 + .../hawkbit/ui/common/CommonDialogWindow.java | 2 +- .../rollout/AddUpdateRolloutWindowLayout.java | 56 ++++++++++++------- .../hawkbit/customstyles/popup-common.scss | 4 ++ 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 309c111ea..85b55d69d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -208,6 +208,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se addStyleName("lay-color"); final FormLayout formLayout = new FormLayout(); + formLayout.setCaption(null); formLayout.addComponent(typeComboBox); formLayout.addComponent(nameTextField); formLayout.addComponent(versionTextField); 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 index 7b5df4a8f..754f61ed2 100644 --- 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 @@ -197,7 +197,7 @@ public class CommonDialogWindow extends Window implements Serializable { setCaption(caption); setContent(mainLayout); - setResizable(true); + setResizable(false); center(); setModal(true); addStyleName("fontsize"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 1226ec5fb..2e419724b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.RolloutManagement; @@ -61,6 +62,7 @@ import com.vaadin.data.Validator; import com.vaadin.data.validator.IntegerRangeValidator; import com.vaadin.data.validator.RegexpValidator; import com.vaadin.event.FieldEvents.TextChangeEvent; +import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.ComboBox; @@ -224,21 +226,22 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { setSizeUndefined(); setRows(9); setColumns(3); + setStyleName("marginTop"); - addComponent(getLabel("textfield.name"), 0, 0); + addComponent(getMandatoryLabel("textfield.name"), 0, 0); addComponent(rolloutName, 1, 0); - addComponent(getLabel("prompt.distribution.set"), 0, 1); + addComponent(getMandatoryLabel("prompt.distribution.set"), 0, 1); addComponent(distributionSet, 1, 1); - addComponent(getLabel("prompt.target.filter"), 0, 2); + addComponent(getMandatoryLabel("prompt.target.filter"), 0, 2); addComponent(targetFilterQueryCombo, 1, 2); addComponent(totalTargetsLabel, 2, 2); - addComponent(getLabel("prompt.number.of.groups"), 0, 3); + addComponent(getMandatoryLabel("prompt.number.of.groups"), 0, 3); addComponent(noOfGroups, 1, 3); addComponent(groupSizeLabel, 2, 3); - addComponent(getLabel("prompt.tigger.threshold"), 0, 4); + addComponent(getMandatoryLabel("prompt.tigger.threshold"), 0, 4); addComponent(triggerThreshold, 1, 4); addComponent(getPercentHintLabel(), 2, 4); - addComponent(getLabel("prompt.error.threshold"), 0, 5); + addComponent(getMandatoryLabel("prompt.error.threshold"), 0, 5); addComponent(errorThreshold, 1, 5); addComponent(errorThresholdOptionGroup, 2, 5); addComponent(getLabel("textfield.description"), 0, 6); @@ -248,12 +251,19 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { rolloutName.focus(); } + private Label getMandatoryLabel(final String key) { + final Label mandatoryLabel = getLabel(i18n.get(key)); + mandatoryLabel.setContentMode(ContentMode.HTML); + mandatoryLabel.setValue(mandatoryLabel.getValue().concat(" *")); + return mandatoryLabel; + } + private Label getLabel(final String key) { return SPUIComponentProvider.getLabel(i18n.get(key), SPUILabelDefinitions.SP_LABEL_SIMPLE); } private TextField getTextfield(final String key) { - return SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get(key), true, + return SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, false, null, i18n.get(key), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); } @@ -340,7 +350,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private ComboBox createTargetFilterQueryCombo() { final ComboBox targetFilter = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL, - true, "", i18n.get("prompt.target.filter")); + false, "", i18n.get("prompt.target.filter")); targetFilter.setImmediate(true); targetFilter.setPageLength(7); targetFilter.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); @@ -625,8 +635,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private ComboBox createDistributionSetCombo() { - final ComboBox dsSet = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL, true, "", - i18n.get("prompt.distribution.set")); + final ComboBox dsSet = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL, false, + "", i18n.get("prompt.distribution.set")); dsSet.setImmediate(true); dsSet.setPageLength(7); dsSet.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); @@ -685,10 +695,12 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { uiNotification .displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing")); } else { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); - final int groupSize = getGroupSize(); - new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0, groupSize) - .validate(Integer.valueOf(value.toString())); + if (StringUtils.isNotBlank(value.toString())) { + new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + final int groupSize = getGroupSize(); + new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0, + groupSize).validate(Integer.valueOf(value.toString())); + } } } // suppress the need of preserve original exception, will blow @@ -710,9 +722,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Override public void validate(final Object value) { try { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); - new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100) - .validate(Integer.valueOf(value.toString())); + if (StringUtils.isNotBlank(value.toString())) { + new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100) + .validate(Integer.valueOf(value.toString())); + } } // suppress the need of preserve original exception, will blow // up the @@ -729,9 +743,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Override public void validate(final Object value) { try { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); - new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500) - .validate(Integer.valueOf(value.toString())); + if (StringUtils.isNotBlank(value.toString())) { + new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500) + .validate(Integer.valueOf(value.toString())); + } } // suppress the need of preserve original exception, will blow // up the diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss index 457fc266d..602298766 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss @@ -53,4 +53,8 @@ font-size: 16px; } + .v-gridlayout .v-gridlayout-marginTop { + padding-top: 20px !important; + } + } From 4e91b87aed4cbd90437eee9d01b166ca08cb86af Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 15 Jun 2016 11:10:29 +0200 Subject: [PATCH 04/52] mandatoryLabel inserted in content Signed-off-by: Melanie Retter --- .../smtable/SoftwareModuleAddUpdateWindow.java | 8 +++++++- .../hawkbit/ui/common/CommonDialogWindow.java | 18 +++++++++++++++--- .../layouts/AbstractCreateUpdateTagLayout.java | 4 ++++ .../TargetAddUpdateWindowLayout.java | 4 ++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 85b55d69d..7fe8e25de 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -92,6 +92,8 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private Long baseSwModuleId; + private FormLayout formLayout; + /** * Create window for new software module. * @@ -207,7 +209,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se */ addStyleName("lay-color"); - final FormLayout formLayout = new FormLayout(); + formLayout = new FormLayout(); formLayout.setCaption(null); formLayout.addComponent(typeComboBox); formLayout.addComponent(nameTextField); @@ -369,4 +371,8 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se return !(event.getText().equals(oldVendorValue) && descTextArea.getValue().equals(oldDescriptionValue)); } + public FormLayout getFormLayout() { + return formLayout; + } + } 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 index 754f61ed2..d3153ee9a 100644 --- 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 @@ -14,8 +14,11 @@ import java.io.Serializable; import java.util.Map; import org.apache.commons.lang3.StringUtils; +import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleBorderWithIcon; +import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout; +import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; @@ -224,9 +227,18 @@ public class CommonDialogWindow extends Window implements Serializable { if (existsMandatoryFieldsInWindowContent()) { // final Label madatoryLabel = new // Label(i18n.get("label.mandatory.field")); - final Label madatoryLabel = new Label("* Mandatory Field"); - madatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); - mainLayout.addComponent(madatoryLabel); + final Label mandatoryLabel = new Label("* Mandatory Field"); + mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); + + if (content instanceof TargetAddUpdateWindowLayout) { + ((TargetAddUpdateWindowLayout) content).getFormLayout().addComponent(mandatoryLabel); + } else if (content instanceof SoftwareModuleAddUpdateWindow) { + ((SoftwareModuleAddUpdateWindow) content).getFormLayout().addComponent(mandatoryLabel); + } else if (content instanceof AbstractCreateUpdateTagLayout) { + ((AbstractCreateUpdateTagLayout) content).getMainLayout().addComponent(mandatoryLabel); + } + + mainLayout.addComponent(mandatoryLabel); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index f8fb5c3e0..85847ccc5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -690,4 +690,8 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent this.tagDescOriginal = tagDescOriginal; } + public GridLayout getMainLayout() { + return mainLayout; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index e5d65295b..287df14b3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -334,4 +334,8 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { window.addStyleName("target-update-window"); } + public FormLayout getFormLayout() { + return formLayout; + } + } From 581748228edecfacd985d80724aa1da78ee403a3 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Fri, 17 Jun 2016 18:17:48 +0200 Subject: [PATCH 05/52] Distribution Filter by type view: save button enabled when changes exist Signed-off-by: Melanie Retter --- .../CreateUpdateSoftwareTypeLayout.java | 2 +- .../hawkbit/ui/common/CommonDialogWindow.java | 2 +- .../CreateUpdateDistSetTypeLayout.java | 133 ++++++++++++------ .../AbstractCreateUpdateTagLayout.java | 6 +- .../ui/layouts/CreateUpdateTypeLayout.java | 20 +++ 5 files changed, 113 insertions(+), 50 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 7473d5509..c8a0c650e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -103,10 +103,10 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "", i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); - tagDesc.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); + tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); singleMultiOptionGroup(); } 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 index d3153ee9a..7818953b0 100644 --- 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 @@ -149,7 +149,7 @@ public class CommonDialogWindow extends Window implements Serializable { public void updateRequiredFields(final String fieldId, final Boolean filled) { - getRequiredFields().put(fieldId, Boolean.TRUE); + getRequiredFields().put(fieldId, filled); checkMandatoryFields(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index a04136a48..facf6e008 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; @@ -87,8 +88,10 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private Table sourceTable; private Table selectedTable; - private IndexedContainer selectedTablecontainer; - private IndexedContainer sourceTablecontainer; + private IndexedContainer selectedTableContainer; + private IndexedContainer sourceTableContainer; + + private IndexedContainer originalSelectedTableContainer; @Override protected void createRequiredComponents() { @@ -114,6 +117,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); + tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); } private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { @@ -175,9 +179,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout return twinColumnLayout; } - /** - * - */ private void buildSelectedTable() { selectedTable = new Table(); @@ -192,7 +193,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout selectedTable.addStyleName("dist_type_twin-table"); selectedTable.setSizeFull(); createSelectedTableContainer(); - selectedTable.setContainerDataSource(selectedTablecontainer); + selectedTable.setContainerDataSource(selectedTableContainer); addTooltTipToSelectedTable(); selectedTable.setImmediate(true); selectedTable.setVisibleColumns(DIST_TYPE_NAME, DIST_TYPE_MANDATORY); @@ -234,14 +235,13 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout sourceTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES); sourceTable.addStyleName(ValoTheme.TABLE_SMALL); sourceTable.setImmediate(true); - // sourceTable sourceTable.setSizeFull(); sourceTable.addStyleName("dist_type_twin-table"); sourceTable.setSortEnabled(false); - sourceTablecontainer = new IndexedContainer(); - sourceTablecontainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); - sourceTablecontainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); - sourceTable.setContainerDataSource(sourceTablecontainer); + sourceTableContainer = new IndexedContainer(); + sourceTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); + sourceTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); + sourceTable.setContainerDataSource(sourceTableContainer); sourceTable.setVisibleColumns(new Object[] { DIST_TYPE_NAME }); sourceTable.setColumnHeaders(i18n.get("header.dist.twintable.available")); @@ -253,10 +253,23 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void createSelectedTableContainer() { - selectedTablecontainer = new IndexedContainer(); - selectedTablecontainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); - selectedTablecontainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); - selectedTablecontainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null); + selectedTableContainer = new IndexedContainer(); + selectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); + selectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); + selectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null); + } + + private void listenerMandatoryCheckboxChanged(final ValueChangeEvent event) { + + window.setSaveButtonEnabled(true); + } + + private void createOriginalSelectedTableContainer() { + + originalSelectedTableContainer = new IndexedContainer(); + originalSelectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); + originalSelectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); + originalSelectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null); } @SuppressWarnings("unchecked") @@ -267,8 +280,14 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Long id : selectedIds) { addTargetTableData(id); } - - window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); + if (optiongroup.getValue().equals(updateTypeStr)) { + updateMandatoryFields(); + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); + } else { + if (!selectedTableContainer.getItemIds().isEmpty()) { + window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); + } + } } } @@ -276,26 +295,57 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout @SuppressWarnings("unchecked") final Set selectedIds = (Set) selectedTable.getValue(); - if (null != selectedIds && !selectedIds.isEmpty()) { + if (selectedIds != null && !selectedIds.isEmpty()) { for (final Long id : selectedIds) { addSourceTableData(id); selectedTable.removeItem(id); + if (optiongroup.getValue().equals(updateTypeStr)) { + updateMandatoryFields(); + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); + } } } - if (selectedIds == null || selectedIds.isEmpty()) { - window.updateRequiredFields(selectedTable.getId(), Boolean.FALSE); + } + + private Boolean hasContentChanged() { + + for (final Iterator itemIterator = selectedTableContainer.getItemIds().iterator(); itemIterator.hasNext();) { + final long itemId = (Long) itemIterator.next(); + if (!originalSelectedTableContainer.containsId(itemId)) { + return Boolean.TRUE; + } + } + + for (final Iterator itemIterator = originalSelectedTableContainer.getItemIds().iterator(); itemIterator + .hasNext();) { + final long itemId = (Long) itemIterator.next(); + if (!selectedTableContainer.containsId(itemId)) { + return Boolean.TRUE; + } + } + + return Boolean.FALSE; + } + + private void updateMandatoryFields() { + + if (StringUtils.isNotBlank(tagName.getValue())) { + window.getRequiredFields().put("Name", Boolean.TRUE); + } + if (StringUtils.isNotBlank(typeKey.getValue())) { + window.getRequiredFields().put("Key", Boolean.TRUE); } } @SuppressWarnings("unchecked") private void getSourceTableData() { - sourceTablecontainer.removeAllItems(); + sourceTableContainer.removeAllItems(); final Iterable moduleTypeBeans = softwareManagement .findSoftwareModuleTypesAll(new PageRequest(0, 1_000)); Item saveTblitem; for (final SoftwareModuleType swTypeTag : moduleTypeBeans) { - saveTblitem = sourceTablecontainer.addItem(swTypeTag.getId()); + saveTblitem = sourceTableContainer.addItem(swTypeTag.getId()); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swTypeTag.getName()); saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(swTypeTag.getDescription()); } @@ -328,8 +378,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void getSelectedTableItemData(final Long id) { Item saveTblitem; - if (null != selectedTablecontainer) { - saveTblitem = selectedTablecontainer.addItem(id); + if (selectedTableContainer != null) { + saveTblitem = selectedTableContainer.addItem(id); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue( sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_NAME).getValue()); saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox()); @@ -341,9 +391,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout @SuppressWarnings("unchecked") private void addSourceTableData(final Long selectedId) { - if (null != sourceTablecontainer) { + if (sourceTableContainer != null) { Item saveTblitem; - saveTblitem = sourceTablecontainer.addItem(selectedId); + saveTblitem = sourceTableContainer.addItem(selectedId); selectedTable.getContainerDataSource().getItem(selectedId).getItemProperty(DIST_TYPE_NAME); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(selectedTable.getContainerDataSource() .getItem(selectedId).getItemProperty(DIST_TYPE_NAME).getValue()); @@ -387,7 +437,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } else { uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey")); - } } @@ -432,7 +481,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } else { uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); } - } private void checkMandatoryAndAddMandatoryModuleType(final DistributionSetType updateDistSetType, @@ -461,26 +509,12 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout return distSetType; } - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.components.colorpicker.HasColorChangeListener# - * addColorChangeListener(com.vaadin - * .ui.components.colorpicker.ColorChangeListener) - */ @Override public void addColorChangeListener(final ColorChangeListener listener) { LOG.info("in side addColorChangeListener() "); } - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.components.colorpicker.HasColorChangeListener# - * removeColorChangeListener(com. - * vaadin.ui.components.colorpicker.ColorChangeListener) - */ @Override public void removeColorChangeListener(final ColorChangeListener listener) { @@ -574,7 +608,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc.setValue(selectedTypeTag.getDescription()); setTagDescOriginal(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); - + setTypeKeyOriginal(selectedTypeTag.getKey()); if (distributionSetManagement.countDistributionSetsByType(selectedTypeTag) <= 0) { distTypeSelectLayout.setEnabled(true); selectedTable.setEnabled(true); @@ -584,6 +618,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout distTypeSelectLayout.setEnabled(false); selectedTable.setEnabled(false); } + + createOriginalSelectedTableContainer(); for (final SoftwareModuleType swModuleType : selectedTypeTag.getOptionalModuleTypes()) { addTargetTableforUpdate(swModuleType, false); } @@ -604,11 +640,18 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void addTargetTableforUpdate(final SoftwareModuleType swModuleType, final boolean mandatory) { Item saveTblitem; - if (null != selectedTablecontainer) { - saveTblitem = selectedTablecontainer.addItem(swModuleType.getId()); + if (selectedTableContainer != null) { + saveTblitem = selectedTableContainer.addItem(swModuleType.getId()); sourceTable.removeItem(swModuleType.getId()); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); + final CheckBox mandatoryCheckbox = (CheckBox) selectedTableContainer + .getContainerProperty(swModuleType.getId(), DIST_TYPE_MANDATORY).getValue(); + mandatoryCheckbox.addValueChangeListener(this::listenerMandatoryCheckboxChanged); + + final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId()); + originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); + originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 85847ccc5..a6fc1accb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -110,7 +110,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected String tagNameValue; protected String tagDescValue; - private Color selectedColorOriginal; + protected Color selectedColorOriginal; private String tagDescOriginal; protected void createWindow() { @@ -189,7 +189,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); - tagDesc.setId(SPUIDefinitions.NEW_TARGET_TAG_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); @@ -211,7 +210,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent window.checkMandatoryTextField(event, tagName); } - private void listenerTagDescTextAreaChanged(final TextChangeEvent event) { + protected void listenerTagDescTextAreaChanged(final TextChangeEvent event) { window.checkChanges(event.getText(), tagDescOriginal); } @@ -416,6 +415,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent */ protected void createDynamicStyleForComponents(final TextField tagName, final TextArea tagDesc, final String taregtTagColor) { + tagName.removeStyleName(SPUIDefinitions.TAG_NAME); tagDesc.removeStyleName(SPUIDefinitions.TAG_DESC); getTargetDynamicStyles(taregtTagColor); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index c67d35321..f2ef71af1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -45,6 +45,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { protected String createTypeStr; protected String updateTypeStr; protected TextField typeKey; + protected String typeKeyOriginal; public static final String TYPE_NAME_DYNAMIC_STYLE = "new-tag-name"; private static final String TYPE_DESC_DYNAMIC_STYLE = "new-tag-desc"; @@ -185,6 +186,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { createDynamicStyleForComponents(tagName, typeKey, tagDesc, colorPickedPreview); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelPreview().getColor()); } + window.checkColorChange(colorPickerLayout.getSelectedColor(), selectedColorOriginal); } /** @@ -321,4 +323,22 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { // is implemented in the inherited class } + @Override + public Color getSelectedColorOriginal() { + return selectedColorOriginal; + } + + @Override + public void setSelectedColorOriginal(final Color selectedColorOriginal) { + this.selectedColorOriginal = selectedColorOriginal; + } + + public String getTypeKeyOriginal() { + return typeKeyOriginal; + } + + public void setTypeKeyOriginal(final String typeKeyOriginal) { + this.typeKeyOriginal = typeKeyOriginal; + } + } From f40fbef4990dd1d0a0d2a13690e02783e26bc074 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 20 Jun 2016 08:24:28 +0200 Subject: [PATCH 06/52] Insert seleniumTest for ColorPickerLayout Signed-off-by: Melanie Retter --- .../eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java | 2 ++ .../eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java index 7d2046bd9..732523560 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java @@ -13,6 +13,7 @@ import java.util.Set; import org.eclipse.hawkbit.ui.common.CoordinatesToColor; import org.eclipse.hawkbit.ui.management.tag.SpColorPickerPreview; +import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.ui.AbstractColorPicker.Coordinates2Color; @@ -47,6 +48,7 @@ public class ColorPickerLayout extends GridLayout { setColumns(2); setRows(4); + setId(SPUIComponentIdProvider.COLOR_PICKER_LAYOUT); init(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java index b4e89a191..9757df522 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java @@ -302,6 +302,11 @@ public final class SPUIComponentIdProvider { * tag color preview button id. */ public static final String TAG_COLOR_PREVIEW_ID = "tag.color.preview"; + + /** + * Id for ColorPickerLayout + */ + public static final String COLOR_PICKER_LAYOUT = "color.picker.layout"; /** * Confirmation dialogue OK button id. */ From 66360721e6e29d4ee60906b6e684993d7a2dd924 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 21 Jun 2016 11:09:54 +0200 Subject: [PATCH 07/52] CSS change Signed-off-by: Melanie Retter --- .../hawkbit/ui/common/CommonDialogWindow.java | 12 +++++++++--- .../disttype/CreateUpdateDistSetTypeLayout.java | 1 - .../TargetAddUpdateWindowLayout.java | 3 --- .../ui/utils/SPUIComponentIdProvider.java | 5 +++++ .../hawkbit/customstyles/popup-common.scss | 17 ++++++++++++++++- 5 files changed, 30 insertions(+), 8 deletions(-) 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 index 80d3de078..4388ee98a 100644 --- 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 @@ -109,9 +109,15 @@ public class CommonDialogWindow extends Window implements Serializable { public void checkMandatoryTextField(final TextChangeEvent event, final AbstractTextField textfield) { if (StringUtils.isNotBlank(event.getText())) { - getRequiredFields().put(textfield.getCaption(), Boolean.TRUE); + if (StringUtils.isNotBlank(textfield.getCaption())) { + getRequiredFields().put(textfield.getCaption(), Boolean.TRUE); + } + getRequiredFields().put(textfield.getId(), Boolean.TRUE); } else { - getRequiredFields().put(textfield.getCaption(), Boolean.FALSE); + if (StringUtils.isNotBlank(textfield.getCaption())) { + getRequiredFields().put(textfield.getCaption(), Boolean.FALSE); + } + getRequiredFields().put(textfield.getId(), Boolean.FALSE); } checkMandatoryFields(); } @@ -189,7 +195,7 @@ public class CommonDialogWindow extends Window implements Serializable { ((AbstractOrderedLayout) content).setMargin(true); } if (content instanceof GridLayout) { - addStyleName(""); + addStyleName("marginTop"); } if (null != content) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 4d5579de0..4b97ce7dd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -113,7 +113,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "", i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); - tagDesc.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 5913bc9d1..9bd3972f0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -52,9 +52,6 @@ import com.vaadin.ui.themes.ValoTheme; /** * Add and Update Target. - * - * - * */ @SpringComponent @VaadinSessionScope diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java index 496bb5cb4..7a7d62b87 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java @@ -927,6 +927,11 @@ public final class SPUIComponentIdProvider { */ public static final String UPLOAD_STATUS_POPUP_ID = "artifact.upload.status.popup.id"; + /** + * Table multiselect for selecting DistType + */ + public static final String SELECT_DIST_TYPE = "select-dist-type"; + /** * /* Private Constructor. */ diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss index 602298766..bab6e5f2a 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss @@ -54,7 +54,22 @@ } .v-gridlayout .v-gridlayout-marginTop { - padding-top: 20px !important; + margin-top: 20px !important; } + .v-slot .v-slot-marginTop { + margin-top: 20px !important; + } + + .v-gridlayout-marginTop { + margin-top: 20px !important; + } + + .v-slot-marginTop { + margin-top: 20px !important; + } + + .marginTop { + margin-top: 20px !important; + } } From 8507626b69d60ef5ee7a8fd5b9b4460666ad85d0 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 21 Jun 2016 13:41:06 +0200 Subject: [PATCH 08/52] Delete useless css styles. Update upper/lower case in properties Signed-off-by: Melanie Retter --- .../hawkbit/customstyles/popup-common.scss | 16 ------- .../src/main/resources/messages.properties | 38 ++++++++--------- .../src/main/resources/messages_de.properties | 42 +++++++++---------- .../src/main/resources/messages_en.properties | 42 +++++++++---------- 4 files changed, 61 insertions(+), 77 deletions(-) diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss index bab6e5f2a..b8e6b1755 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss @@ -53,22 +53,6 @@ font-size: 16px; } - .v-gridlayout .v-gridlayout-marginTop { - margin-top: 20px !important; - } - - .v-slot .v-slot-marginTop { - margin-top: 20px !important; - } - - .v-gridlayout-marginTop { - margin-top: 20px !important; - } - - .v-slot-marginTop { - margin-top: 20px !important; - } - .marginTop { margin-top: 20px !important; } diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index 1fee8dcdb..5b3ad793b 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -79,14 +79,14 @@ caption.delete.swmodule.accordion.tab = Delete SW Modules caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type caption.delete.sw.module.type.accordion.tab = Delete Software Module Type caption.attributes = Attributes -caption.panel.dist.installed = Installed distribution set -caption.panel.dist.assigned = Assigned distribution set +caption.panel.dist.installed = Installed Distribution Set +caption.panel.dist.assigned = Assigned Distribution Set caption.soft.delete.confirmbox = Confirm Software Module Delete Action -caption.cancel.action.confirmbox = Confirm action cancel +caption.cancel.action.confirmbox = Confirm Action Cancellation caption.forcequit.action.confirmbox = Confirm force quit action caption.forced.datefield = Force update at time caption.force.action.confirmbox = Confirm Force Active Action -caption.confirm.abort.action = Confirm abort action +caption.confirm.abort.action = Confirm Abort Action caption.filter.delete.confirmbox = Confirm Filter Delete Action @@ -220,7 +220,7 @@ message.duplicate.softwaremodule = {0} : {1} already exists! message.tag.delete = Please unclick the tag {0}, then try to delete message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete message.cannot.delete.default.dstype = Default distribution set type cannot be deleted -message.swmodule.type.check.delete = Please unclick the software module type {0}, then try to delete +message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete message.targets.already.deleted = Few Target(s) are already deleted.Pending for action message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action message.target.deleted.pending = Target(s) already deleted.Pending for action @@ -262,10 +262,10 @@ message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are alre message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1} message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1} message.dist.no.operation = {0} - already assigned/installed, No operation -message.sm.delete.confirm = Are you sure that you want to delete the selected {0} software module? +message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module? message.error.os.softmodule = Please select the OS to delete message.error.ah.softmodule = Please select the Application to delete -message.error.softmodule.deleted = The selected software module is already deleted +message.error.softmodule.deleted = The selected Software Module is already deleted message.cancel.action = Cancel.. message.cancel.action.success = Action cancelled successfully ! message.cancel.action.failed = Unable to cancel the action ! @@ -284,7 +284,7 @@ message.action.not.allowed = Action not allowed message.onlyone.distribution.assigned = Only one distribution set can be assigned message.onlyone.distribution.dropallowed = Only one distribution set can be dropped message.error.missing.typename = Missing Type Name -message.error.missing.typenameorkey = Missing Type Name or Key or software module type +message.error.missing.typenameorkey = Missing Type Name or Key or Software Module type message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0} message.no.targets.assiged.fortag = No targets are assigned to tag {0} message.error.missing.tagname = Please select tag name @@ -314,12 +314,12 @@ soft.module.os =OS #Artifact upload message.error.noFileSelected = No file selected for upload message.error.noProvidedName = Please provide custom file name -message.error.noSwModuleSelected = Please select a software module +message.error.noSwModuleSelected = Please select a Software Module message.no.duplicateFiles = Duplicate files selected message.no.duplicateFile = Duplicate file selected : message.delete.artifact = Are you sure that you want to delete artifact {0} ? message.duplicate.filename = Duplicate file name -message.swModule.deleted = {0} Software module(s) deleted +message.swModule.deleted = {0} Software Module(s) deleted message.upload.failed = Streaming Failed message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes message.uploadedfile.aborted = File upload aborted @@ -329,7 +329,7 @@ message.abort.upload = Are you sure that you want to abort the upload? -upload.swModuleTable.header = Software module +upload.swModuleTable.header = Software Module upload.selectedfile.name = file selected for upload upload.file.name = File name upload.sha1 = SHA1 checksum @@ -347,7 +347,7 @@ upload.reason = Reason upload.action = Action upload.result.status = Upload status upload.file = Upload File -upload.caption.update.swmodule = Update software module +upload.caption.update.swmodule = Update Software Module caption.tab.details = Details caption.tab.description = Description @@ -363,8 +363,8 @@ label.no.tag.assigned = NO TAG caption.assign.software.dist.accordion.tab = Assign Software Modules message.software.assignment = {0} Software Module(s) Assignment(s) done message.dist.inuse = {0} Distribution is already assigned to target -message.software.dist.already.assigned = {0} Distribution already has software module {1} -message.software.dist.type.notallowed = {0} Software module type can not assign to Distribution {1} +message.software.dist.already.assigned = {0} Distribution already has Software Module {1} +message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1} message.target.assigned = {0} is assigned to {1} message.dist.type.delete = {0} DistributionType(s) Deleted successfully. message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully. @@ -445,7 +445,7 @@ header.caption.mandatory = Mandatory header.caption.typename = SoftwareModuleType header.caption.softwaremodule = SoftwareModule header.caption.unassign = Unassign -message.sw.unassigned = Software module {0} successfully unassigned +message.sw.unassigned = Software Module {0} successfully unassigned header.caption.upload.details = Upload details combo.type.tag.name = Type tag name @@ -469,8 +469,8 @@ prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold prompt.distribution.set = Distribution set -caption.configure.rollout = Configure rollout -caption.update.rollout = Update rollout +caption.configure.rollout = Configure Rollout +caption.update.rollout = Update Rollout prompt.target.filter = Custom target filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 @@ -485,8 +485,8 @@ message.rollout.noofgroups.or.targetfilter.missing = Please enter number of grou message.rollouts = Rollouts label.target.per.group = Targets per group : message.dist.already.assigned = Distribution {0} is already assigned to target -message.error.creating.rollout = Server error. Error creating rollout. Please contact the administrator -message.error.starting.rollout = Server error. Error starting rollout. Please contact the administrator +message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator +message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator #rollout - end #Menu diff --git a/hawkbit-ui/src/main/resources/messages_de.properties b/hawkbit-ui/src/main/resources/messages_de.properties index 1c437071a..2ac5ed9c2 100644 --- a/hawkbit-ui/src/main/resources/messages_de.properties +++ b/hawkbit-ui/src/main/resources/messages_de.properties @@ -77,16 +77,16 @@ caption.delete.swmodule.accordion.tab = Delete SW Modules caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type caption.delete.sw.module.type.accordion.tab = Delete Software Module Type caption.attributes = Attributes -caption.panel.dist.installed = Installed distribution set -caption.panel.dist.assigned = Assigned distribution set +caption.panel.dist.installed = Installed Distribution Set +caption.panel.dist.assigned = Assigned Distribution Set caption.soft.delete.confirmbox = Confirm Software Module Delete Action -caption.cancel.action.confirmbox = Confirm action cancellation +caption.cancel.action.confirmbox = Confirm Action Cancellation caption.forced.datefield = Force update at time caption.force.action.confirmbox = Confirm Force Active Action caption.filter.simple = Simple Filter caption.filter.custom = Custom Filter caption.filter.delete.confirmbox = Confirm Filter Delete Action -caption.confirm.abort.action = Confirm abort action +caption.confirm.abort.action = Confirm Abort Action # Labels prefix with - label @@ -214,13 +214,13 @@ message.target.unassigned.one = {0} is unassigned from {1} message.target.unassigned.many = {0} Targets are unassigned from {1} message.target.assigned.pending = Some target(s) are already assigned.Pending for action message.cannot.delete = Cannot be deleted -message.check.softwaremodule = Please provide both name and verion! +message.check.softwaremodule = Please provide both name and version! message.cannot.delete.default.dstype = Default distribution set type cannot be deleted message.duplicate.softwaremodule = {0} : {1} already exists! message.cannot.delete.default.dstype = Default distribution set type cannot be deleted message.tag.delete = Please unclick the tag {0}, then try to delete message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete -message.swmodule.type.check.delete = Please unclick the software module type {0}, then try to delete +message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete message.targets.already.deleted = Few Target(s) are already deleted.Pending for action message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action message.target.deleted.pending = Target(s) already deleted.Pending for action @@ -243,7 +243,7 @@ message.accessdenied.view = No access to view: {0} message.no.data = No data available message.target.assignment = {0} Assignment(s) done message.target.deleted = {0} Target(s) deleted -message.dist.deleted = {0} Distribution set(s) deleted +message.dist.deleted = {0} Distribution Set(s) deleted message.tag.update.mandatory = Please select the Tag to update message.tag.duplicate.check = {0} already exists, please enter another value message.type.key.duplicate.check = Distribution type with key {0} already exists, please give another value @@ -262,10 +262,10 @@ message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are alre message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1} message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1} message.dist.no.operation = {0} - already assigned/installed, No operation -message.sm.delete.confirm = Are you sure that you want to delete the selected {0} software module? +message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module? message.error.os.softmodule = Please select the OS to delete message.error.ah.softmodule = Please select the Application to delete -message.error.softmodule.deleted = The selected software module is already deleted +message.error.softmodule.deleted = The selected Software Module is already deleted message.cancel.action = Cancel message.cancel.action.success = Action cancelled successfully ! message.cancel.action.failed = Unable to cancel the action ! @@ -311,12 +311,12 @@ soft.module.os =OS #Artifact upload message.error.noFileSelected = No file selected for upload message.error.noProvidedName = Please provide custom file name -message.error.noSwModuleSelected = Please select a software module +message.error.noSwModuleSelected = Please select a Software Module message.no.duplicateFiles = Duplicate files selected message.no.duplicateFile = Duplicate file selected : message.delete.artifact = Are you sure that you want to delete artifact {0} ? message.duplicate.filename = Duplicate file name -message.swModule.deleted = {0} Software module(s) deleted +message.swModule.deleted = {0} Software Module(s) deleted message.error.missing.tagname = Please select tag name message.upload.failed = Streaming Failed message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes @@ -327,7 +327,7 @@ message.abort.upload = Are you sure that you want to abort the upload? -upload.swModuleTable.header = Software module +upload.swModuleTable.header = Software Module upload.selectedfile.name = file selected for upload upload.file.name = File name upload.sha1 = SHA1 checksum @@ -345,7 +345,7 @@ upload.reason = Reason upload.action = Action upload.result.status = Upload status upload.file = Upload File -upload.caption.update.swmodule = Update software module +upload.caption.update.swmodule = Update Software Module caption.tab.details = Details caption.tab.description = Description @@ -356,8 +356,8 @@ label.drop.dist.delete.area = Drop here
to delete caption.assign.software.dist.accordion.tab = Assign Software Modules message.software.assignment = {0} Assignment(s) done message.dist.inuse = {0} Distribution is already assigned to target -message.software.dist.already.assigned = {0} Distribution already has software module {1} -message.software.dist.type.notallowed = {0} Software module type can not assign to Distribution {1} +message.software.dist.already.assigned = {0} Distribution already has Software Module {1} +message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1} message.target.assigned = {0} is assigned to {1} message.dist.type.delete = {0} DistributionType(s) Deleted successfully. message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully. @@ -442,7 +442,7 @@ header.caption.mandatory = Mandatory header.caption.typename = SoftwareModuleType header.caption.softwaremodule = SoftwareModule header.caption.unassign = Unassign -message.sw.unassigned = Software module {0} successfully unassigned +message.sw.unassigned = Software Module {0} successfully unassigned header.caption.upload.details = Upload details combo.type.tag.name = Type tag name @@ -458,9 +458,9 @@ menu.title = Software Provisioning prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold -prompt.distribution.set = Distribution set -caption.configure.rollout = Configure rollout -caption.update.rollout = Update rollout +prompt.distribution.set = Distribution Set +caption.configure.rollout = Configure Rollout +caption.update.rollout = Update Rollout prompt.target.filter = Custom target filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 @@ -475,8 +475,8 @@ message.rollout.noofgroups.or.targetfilter.missing = Please enter number of grou message.rollouts = Rollouts label.target.per.group = Targets per group : message.dist.already.assigned = Distribution {0} is already assigned to target -message.error.creating.rollout = Server error. Error creating rollout. Please contact the administrator -message.error.starting.rollout = Server error. Error starting rollout. Please contact the administrator +message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator +message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator #Target Filter Management breadcrumb.target.filter.custom.filters = Custom Filters diff --git a/hawkbit-ui/src/main/resources/messages_en.properties b/hawkbit-ui/src/main/resources/messages_en.properties index 7716da4f2..459695844 100644 --- a/hawkbit-ui/src/main/resources/messages_en.properties +++ b/hawkbit-ui/src/main/resources/messages_en.properties @@ -79,14 +79,14 @@ caption.delete.swmodule.accordion.tab = Delete SW Modules caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type caption.delete.sw.module.type.accordion.tab = Delete Software Module Type caption.attributes = Attributes -caption.panel.dist.installed = Installed distribution set -caption.panel.dist.assigned = Assigned distribution set +caption.panel.dist.installed = Installed Distribution Set +caption.panel.dist.assigned = Assigned Distribution Set caption.soft.delete.confirmbox = Confirm Software Module Delete Action -caption.cancel.action.confirmbox = Confirm action cancellation +caption.cancel.action.confirmbox = Confirm Action Cancellation caption.forced.datefield = Force update at time caption.force.action.confirmbox = Confirm Force Active Action caption.filter.delete.confirmbox = Confirm Filter Delete Action -caption.confirm.abort.action = Confirm abort action +caption.confirm.abort.action = Confirm Abort Action # Labels prefix with - label label.dist.details.type = Type : @@ -213,11 +213,11 @@ message.target.unassigned.one = {0} is unassigned from {1} message.target.unassigned.many = {0} Targets are unassigned from {1} message.target.assigned.pending = Some target(s) are already assigned.Pending for action message.cannot.delete = Cannot be deleted -message.check.softwaremodule = Please provide both name and verion! +message.check.softwaremodule = Please provide both name and version! message.duplicate.softwaremodule = {0} : {1} already exists! message.tag.delete = Please unclick the tag {0}, then try to delete message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete -message.swmodule.type.check.delete = Please unclick the software module type {0}, then try to delete +message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete message.targets.already.deleted = Few Target(s) are already deleted.Pending for action message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action message.target.deleted.pending = Target(s) already deleted.Pending for action @@ -259,10 +259,10 @@ message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are alre message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1} message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1} message.dist.no.operation = {0} - already assigned/installed, No operation -message.sm.delete.confirm = Are you sure that you want to delete the selected {0} software module? +message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module? message.error.os.softmodule = Please select the OS to delete message.error.ah.softmodule = Please select the Application to delete -message.error.softmodule.deleted = The selected software module is already deleted +message.error.softmodule.deleted = The selected Software Module is already deleted message.cancel.action = Cancel message.cancel.action.success = Action cancelled successfully ! message.cancel.action.failed = Unable to cancel the action ! @@ -277,7 +277,7 @@ message.action.not.allowed = Action not allowed message.onlyone.distribution.assigned = Only one distribution set can be assigned message.onlyone.distribution.dropallowed = Only one distribution set can be dropped message.error.missing.typename = Missing Type Name -message.error.missing.typenameorkey = Missing Type Name or Key or software module type +message.error.missing.typenameorkey = Missing Type Name or Key or Software Module type message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0} message.no.targets.assiged.fortag = No targets are assigned to tag {0} message.error.missing.tagname = Please select tag name @@ -305,12 +305,12 @@ soft.module.os =OS #Artifact upload message.error.noFileSelected = No file selected for upload message.error.noProvidedName = Please provide custom file name -message.error.noSwModuleSelected = Please select a software module +message.error.noSwModuleSelected = Please select a Software Module message.no.duplicateFiles = Duplicate files selected message.no.duplicateFile = Duplicate file selected : message.delete.artifact = Are you sure that you want to delete artifact {0} ? message.duplicate.filename = Duplicate file name -message.swModule.deleted = {0} Software module(s) deleted +message.swModule.deleted = {0} Software Module(s) deleted message.upload.failed = Streaming Failed message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes message.uploadedfile.aborted = File upload aborted @@ -318,7 +318,7 @@ message.file.not.found = File not found message.abort.upload = Are you sure that you want to abort the upload? -upload.swModuleTable.header = Software module +upload.swModuleTable.header = Software Module upload.selectedfile.name = file selected for upload upload.file.name = File name upload.sha1 = SHA1 checksum @@ -336,7 +336,7 @@ upload.reason = Reason upload.action = Action upload.result.status = Upload status upload.file = Upload File -upload.caption.update.swmodule = Update software module +upload.caption.update.swmodule = Update Software Module caption.tab.details = Details caption.tab.description = Description @@ -348,8 +348,8 @@ label.drop.dist.delete.area = Drop here
to delete caption.assign.software.dist.accordion.tab = Assign Software Modules message.software.assignment = {0} Software Module(s) Assignment(s) done message.dist.inuse = {0} Distribution is already assigned to target -message.software.dist.already.assigned = {0} Distribution already has software module {1} -message.software.dist.type.notallowed = {0} Software module type can not assign to Distribution {1} +message.software.dist.already.assigned = {0} Distribution already has Software Module {1} +message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1} message.target.assigned = {0} is assigned to {1} message.dist.type.delete = {0} DistributionType(s) Deleted successfully. message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully. @@ -415,7 +415,7 @@ header.assigned.ds = Assigned DS header.installed.ds = Installed DS header.status = Status header.target.tags = Tags -header.distributionset = Distribution set +header.distributionset = Distribution Set header.numberofgroups = No. of groups header.detail.status = Detail status header.total.targets = Total targets @@ -429,7 +429,7 @@ header.rolloutgroup.target.message = Messages rollout.group.label.target.truncated = {0} targets has been truncated in the list due the target size limit of {1} -distribution.details.header = Distribution set +distribution.details.header = Distribution Set target.details.header = Target header.caption.mandatory = Mandatory header.caption.typename = SoftwareModuleType @@ -449,8 +449,8 @@ prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold prompt.distribution.set = Distribution set -caption.configure.rollout = Configure rollout -caption.update.rollout = Update rollout +caption.configure.rollout = Configure Rollout +caption.update.rollout = Update Rollout prompt.target.filter = Custom target filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 @@ -465,8 +465,8 @@ message.rollout.noofgroups.or.targetfilter.missing = Please enter number of grou message.rollouts = Rollouts label.target.per.group = Targets per group : message.dist.already.assigned = Distribution {0} is already assigned to target -message.error.creating.rollout = Server error. Error creating rollout. Please contact the administrator -message.error.starting.rollout = Server error. Error starting rollout. Please contact the administrator +message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator +message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator #Target Filter Management breadcrumb.target.filter.custom.filters = Custom Filters From f567461993832ac54fc35eb414a9d6d7566ff861 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 23 Jun 2016 09:33:43 +0200 Subject: [PATCH 09/52] correct save button enabled when changes exists. Changed lower/uppercase spelling Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 4 +- .../CreateUpdateSoftwareTypeLayout.java | 3 +- .../hawkbit/ui/common/CommonDialogWindow.java | 72 ++++++--- .../ui/components/SPUIComponentProvider.java | 4 +- .../ui/decorators/SPUIWindowDecorator.java | 4 +- .../CreateUpdateDistSetTypeLayout.java | 3 +- .../AbstractCreateUpdateTagLayout.java | 18 ++- .../ui/layouts/CreateUpdateTypeLayout.java | 3 +- .../DistributionAddUpdateWindowLayout.java | 13 +- .../footer/ActionTypeOptionGroupLayout.java | 2 + .../TargetAddUpdateWindowLayout.java | 6 +- .../rollout/AddUpdateRolloutWindowLayout.java | 150 +++++++++++++++--- .../ui/rollout/rollout/RolloutListGrid.java | 4 +- .../ui/rollout/rollout/RolloutListHeader.java | 2 +- .../src/main/resources/messages.properties | 4 +- .../src/main/resources/messages_de.properties | 4 +- .../src/main/resources/messages_en.properties | 4 +- 17 files changed, 223 insertions(+), 77 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index a9baad65b..43ccbe36f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -193,7 +193,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se oldVendorValue = null; if (window != null) { - window.resetRequiredFieldsValues(); + window.resetMandatoryAndEditedFields(); } } @@ -223,7 +223,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - getMandatoryFields(formLayout)); + getMandatoryFields(formLayout), null); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); nameTextField.focus(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 8578ad2a4..9a87c625d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -132,7 +132,8 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields()); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields(), + getEditedFields()); } private Map getMandatoryFields() { 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 index 4388ee98a..142cd3998 100644 --- 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 @@ -74,6 +74,8 @@ public class CommonDialogWindow extends Window implements Serializable { private Map requiredFields; + private final Map editedFields; + @Autowired private I18N i18n; @@ -93,7 +95,7 @@ public class CommonDialogWindow extends Window implements Serializable { */ public CommonDialogWindow(final String caption, final Component content, final String helpLink, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, - final Map requiredFields) { + final Map requiredFields, final Map editedFields) { checkNotNull(saveButtonClickListener); checkNotNull(cancelButtonClickListener); this.caption = caption; @@ -102,6 +104,7 @@ public class CommonDialogWindow extends Window implements Serializable { this.saveButtonClickListener = saveButtonClickListener; this.cancelButtonClickListener = cancelButtonClickListener; this.requiredFields = requiredFields; + this.editedFields = editedFields; init(); } @@ -110,32 +113,32 @@ public class CommonDialogWindow extends Window implements Serializable { if (StringUtils.isNotBlank(event.getText())) { if (StringUtils.isNotBlank(textfield.getCaption())) { - getRequiredFields().put(textfield.getCaption(), Boolean.TRUE); + requiredFields.put(textfield.getCaption(), Boolean.TRUE); } getRequiredFields().put(textfield.getId(), Boolean.TRUE); } else { if (StringUtils.isNotBlank(textfield.getCaption())) { - getRequiredFields().put(textfield.getCaption(), Boolean.FALSE); + requiredFields.put(textfield.getCaption(), Boolean.FALSE); } - getRequiredFields().put(textfield.getId(), Boolean.FALSE); + requiredFields.put(textfield.getId(), Boolean.FALSE); } - checkMandatoryFields(); + checkMandatoryFieldsFilled(); } public void checkMandatoryComboBox(final ValueChangeEvent event, final AbstractSelect select) { if (event.getProperty().getValue() != null) { if (StringUtils.isNotBlank(select.getCaption())) { - getRequiredFields().put(select.getCaption(), Boolean.TRUE); + requiredFields.put(select.getCaption(), Boolean.TRUE); } - getRequiredFields().put(select.getId(), Boolean.TRUE); + requiredFields.put(select.getId(), Boolean.TRUE); } else { if (StringUtils.isNotBlank(select.getCaption())) { - getRequiredFields().put(select.getCaption(), Boolean.FALSE); + requiredFields.put(select.getCaption(), Boolean.FALSE); } - getRequiredFields().put(select.getId(), Boolean.FALSE); + requiredFields.put(select.getId(), Boolean.FALSE); } - checkMandatoryFields(); + checkMandatoryFieldsFilled(); } /** @@ -143,7 +146,7 @@ public class CommonDialogWindow extends Window implements Serializable { * mandatory fields are filled the save button is enabled. Otherwise the * save button is disabled. */ - private void checkMandatoryFields() { + private void checkMandatoryFieldsFilled() { for (final Map.Entry entry : requiredFields.entrySet()) { if (entry.getValue() == null || entry.getValue().equals(Boolean.FALSE)) { @@ -154,35 +157,56 @@ public class CommonDialogWindow extends Window implements Serializable { saveButton.setEnabled(true); } - public void updateRequiredFields(final String fieldId, final Boolean filled) { + private void checkExistsChanges() { - getRequiredFields().put(fieldId, filled); - checkMandatoryFields(); + if (editedFields == null) { + return; + } + for (final Map.Entry entry : editedFields.entrySet()) { + if (entry.getValue() != null && entry.getValue().equals(Boolean.TRUE)) { + saveButton.setEnabled(true); + return; + } + } + saveButton.setEnabled(false); } - public void checkChanges(final String newText, final String oldText) { + public void updateRequiredFields(final String fieldId, final Boolean filled) { + + requiredFields.put(fieldId, filled); + checkMandatoryFieldsFilled(); + } + + public void checkChanges(final String fieldName, final String newText, final String oldText) { if ((StringUtils.isNotBlank(newText) && !newText.equals(oldText)) || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText))) { - saveButton.setEnabled(true); + editedFields.put(fieldName, Boolean.TRUE); } else { - saveButton.setEnabled(false); + editedFields.put(fieldName, Boolean.FALSE); } + checkExistsChanges(); } - public void checkColorChange(final Color newColor, final Color oldColor) { + public void checkColorChange(final String fieldName, final Color newColor, final Color oldColor) { if (newColor.equals(oldColor)) { - setSaveButtonEnabled(false); + editedFields.put(fieldName, Boolean.FALSE); } else { - setSaveButtonEnabled(true); + editedFields.put(fieldName, Boolean.TRUE); } + checkExistsChanges(); } - public void resetRequiredFieldsValues() { - // Reset mandatory fields are filled marker - if (getRequiredFields() != null) { - for (final Map.Entry entry : getRequiredFields().entrySet()) { + public void resetMandatoryAndEditedFields() { + resetFields(requiredFields); + resetFields(editedFields); + } + + private void resetFields(final Map fields) { + // Reset mandatory fields are filled marker / fields are edited marker + if (fields != null) { + for (final Map.Entry entry : fields.entrySet()) { entry.setValue(null); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 3ba71fce5..ffc0de8ee 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -154,9 +154,9 @@ public final class SPUIComponentProvider { public static CommonDialogWindow getWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields) { + final Map requiredFields, final Map editedFields) { return SPUIWindowDecorator.getDeocratedWindow(caption, id, type, content, saveButtonClickListener, - cancelButtonClickListener, helpLink, requiredFields); + cancelButtonClickListener, helpLink, requiredFields, editedFields); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java index f9ce37158..b627851db 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java @@ -47,10 +47,10 @@ public final class SPUIWindowDecorator { public static CommonDialogWindow getDeocratedWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields) { + final Map requiredFields, final Map editedFields) { final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener, requiredFields); + cancelButtonClickListener, requiredFields, editedFields); if (null != id) { window.setId(id); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 4b97ce7dd..b71eaac23 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -677,7 +677,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields()); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields(), + getEditedFields()); } private Map getMandatoryFields() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 720f61cff..f7a067bfd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -115,8 +115,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected void createWindow() { reset(); - setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields())); + setWindow( + SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, + this, this::save, this::discard, null, getMandatoryFields(), getEditedFields())); } private Map getMandatoryFields() { @@ -131,6 +132,13 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent return requiredFields; } + protected Map getEditedFields() { + final Map changeMap = new HashMap<>(); + changeMap.put(tagDesc.getCaption(), Boolean.FALSE); + changeMap.put(colorPickerLayout.getId(), Boolean.FALSE); + return changeMap; + } + /** * Save new tag / update new tag. * @@ -213,7 +221,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected void listenerTagDescTextAreaChanged(final TextChangeEvent event) { - window.checkChanges(event.getText(), tagDescOriginal); + window.checkChanges(tagDesc.getCaption(), event.getText(), tagDescOriginal); } protected void buildLayout() { @@ -375,7 +383,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagPreviewBtnClicked = false; if (window != null) { - window.resetRequiredFieldsValues(); + window.resetMandatoryAndEditedFields(); } } @@ -466,7 +474,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor()); } - window.checkColorChange(colorPickerLayout.getSelectedColor(), selectedColorOriginal); + window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), selectedColorOriginal); } protected void closeWindow() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index f2ef71af1..ea77d885b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -186,7 +186,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { createDynamicStyleForComponents(tagName, typeKey, tagDesc, colorPickedPreview); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelPreview().getColor()); } - window.checkColorChange(colorPickerLayout.getSelectedColor(), selectedColorOriginal); + window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), selectedColorOriginal); } /** @@ -206,6 +206,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) { optiongroup = new OptionGroup("Select Action"); + optiongroup.setId(SPUIComponentIdProvider.OPTION_GROUP); optiongroup.addStyleName(ValoTheme.OPTIONGROUP_SMALL); optiongroup.addStyleName("custom-option-group"); optiongroup.setNullSelectionAllowed(false); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 82cf2390c..4a6a29e93 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -179,11 +179,15 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } private void listenerDistNameTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, distNameTextField); + if (!editDistribution) { + window.checkMandatoryTextField(event, distNameTextField); + } } private void listenerDistVersionTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, distVersionTextField); + if (!editDistribution) { + window.checkMandatoryTextField(event, distVersionTextField); + } } /** @@ -410,7 +414,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { changedComponents.clear(); if (window != null) { - window.resetRequiredFieldsValues(); + window.resetMandatoryAndEditedFields(); } } @@ -519,9 +523,8 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { resetComponents(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, getMandatoryFields()); + null, getMandatoryFields(), null); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); - return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java index de0938e7e..bc27e7aa3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java @@ -17,6 +17,7 @@ import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; +import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroup; import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent; @@ -78,6 +79,7 @@ public class ActionTypeOptionGroupLayout extends HorizontalLayout { private void createOptionGroup() { actionTypeOptionGroup = new FlexibleOptionGroup(); + actionTypeOptionGroup.setId(SPUIComponentIdProvider.ROLLOUT_ACTION_BUTTON_ID); actionTypeOptionGroup.addItem(ActionTypeOption.SOFT); actionTypeOptionGroup.addItem(ActionTypeOption.FORCED); actionTypeOptionGroup.addItem(ActionTypeOption.AUTO_FORCED); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 9bd3972f0..8ea8665d6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -244,7 +244,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields()); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields(), null); return window; } @@ -259,7 +259,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } return requiredFields; } - + /** * clear all fields of Target Edit Window. */ @@ -274,7 +274,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { editTarget = Boolean.FALSE; if (window != null) { - window.resetRequiredFieldsValues(); + window.resetMandatoryAndEditedFields(); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 2e419724b..566ac4528 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -150,26 +150,47 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextArea targetFilterQuery; + private Boolean updateMode = Boolean.FALSE; + + private String distributionSetOriginal; + + private Object actionGroupOriginal; + + private String rolloutNameOriginal; + + private String errorThresholdOriginal;; + + private String triggerThresholdOriginal; + + private String descriptionOriginal; + /** * Create components and layout. */ public void init() { - setSizeUndefined(); createRequiredComponents(); buildLayout(); } public CommonDialogWindow getWindow() { - window = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), - uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields()); + uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields(), getEditedFields()); return window; } - private Map getMandatoryFields() { + public CommonDialogWindow createUpdateWindow() { + updateMode = Boolean.TRUE; + return getWindow(); + } + public CommonDialogWindow createAddWindow() { + updateMode = Boolean.FALSE; + return getWindow(); + } + + private Map getMandatoryFields() { final Map requiredFields = new HashMap<>(); requiredFields.put(rolloutName.getId(), null); requiredFields.put(distributionSet.getId(), null); @@ -195,16 +216,14 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { setDefaultSaveStartGroupOption(); totalTargetsLabel.setVisible(false); groupSizeLabel.setVisible(false); - removeComponent(targetFilterQuery); - if (getComponent(1, 3) == null) { - addComponent(targetFilterQueryCombo, 1, 3); - } + removeComponent(1, 2); + addComponent(targetFilterQueryCombo, 1, 2); actionTypeOptionGroupLayout.selectDefaultOption(); totalTargetsCount = 0L; rolloutForEdit = null; if (window != null) { - window.resetRequiredFieldsValues(); + window.resetMandatoryAndEditedFields(); } } @@ -284,7 +303,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroups = createNoOfGroupsField(); groupSizeLabel = createGroupSizeLabel(); - triggerThreshold = createTriggerThresold(); + triggerThreshold = createTriggerThreshold(); errorThreshold = createErrorThreshold(); description = createDescription(); errorThresholdOptionGroup = createErrorThresholdOptionGroup(); @@ -293,6 +312,20 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { totalTargetsLabel = createTotalTargetsLabel(); targetFilterQuery = createTargetFilterQuery(); actionTypeOptionGroupLayout.addStyleName(SPUIStyleDefinitions.ROLLOUT_ACTION_TYPE_LAYOUT); + actionTypeOptionGroupLayout.getActionTypeOptionGroup() + .addValueChangeListener(this::listenerActionGroupValueChanged); + } + + private void listenerActionGroupValueChanged(final ValueChangeEvent event) { + if (window != null) { + if (!updateMode) { + window.checkMandatoryComboBox(event, actionTypeOptionGroupLayout.getActionTypeOptionGroup()); + } + if (event.getProperty().getValue() != null) { + window.checkChanges(actionTypeOptionGroupLayout.getActionTypeOptionGroup().getId(), + event.getProperty().getValue().toString(), actionGroupOriginal.toString()); + } + } } private Label createGroupSizeLabel() { @@ -578,9 +611,20 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { descriptionField.setId(SPUIComponentIdProvider.ROLLOUT_DESCRIPTION_ID); descriptionField.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY); descriptionField.setSizeUndefined(); + descriptionField.addTextChangeListener(this::listenerDescriptionTextFieldChanged); return descriptionField; } + private void listenerDescriptionTextFieldChanged(final TextChangeEvent event) { + if (window != null) { + if (!updateMode) { + window.checkMandatoryTextField(event, description); + return; + } + window.checkChanges(description.getId(), event.getText(), descriptionOriginal); + } + } + private TextField createErrorThreshold() { final TextField errorField = getTextfield("prompt.error.threshold"); errorField.addValidator(new ThresholdFieldValidator()); @@ -592,11 +636,16 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void listenerErrorThresholdTextFieldChanged(final TextChangeEvent event) { - - window.checkMandatoryTextField(event, errorThreshold); + if (window != null) { + if (!updateMode) { + window.checkMandatoryTextField(event, errorThreshold); + return; + } + window.checkChanges(errorThreshold.getId(), event.getText(), errorThresholdOriginal); + } } - private TextField createTriggerThresold() { + private TextField createTriggerThreshold() { final TextField thresholdField = getTextfield("prompt.tigger.threshold"); thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID); thresholdField.addValidator(new ThresholdFieldValidator()); @@ -607,7 +656,13 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void listenerTriggerThresholdTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, triggerThreshold); + if (window != null) { + if (!updateMode) { + window.checkMandatoryTextField(event, triggerThreshold); + return; + } + window.checkChanges(triggerThreshold.getId(), event.getText(), triggerThresholdOriginal); + } } private TextField createNoOfGroupsField() { @@ -622,7 +677,13 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void listenerNoOfGroupsTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, noOfGroups); + if (window != null) { + if (!updateMode) { + window.checkMandatoryTextField(event, noOfGroups); + return; + } + window.checkChanges(noOfGroups.getId(), event.getText(), noOfGroups.getValue()); + } } private void onGroupNumberChange() { @@ -647,7 +708,16 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void listenerDistributionSetChanged(final ValueChangeEvent event) { - window.checkMandatoryComboBox(event, distributionSet); + if (window != null) { + if (!updateMode) { + window.checkMandatoryComboBox(event, distributionSet); + return; + } + if (event.getProperty().getValue() != null) { + window.checkChanges(distributionSet.getId(), event.getProperty().getValue().toString(), + distributionSetOriginal); + } + } } private void populateDistributionSet() { @@ -673,7 +743,13 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void listenerRolloutNameTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, rolloutName); + if (window != null) { + if (!updateMode) { + window.checkMandatoryTextField(event, rolloutName); + return; + } + window.checkChanges(rolloutName.getId(), event.getText(), rolloutNameOriginal); + } } private String getRolloutName() { @@ -691,7 +767,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public void validate(final Object value) { try { if (HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null - || HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null) { + || (HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null + && targetFilterQuery.getValue() == null)) { uiNotification .displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing")); } else { @@ -781,12 +858,42 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroups.setEnabled(false); targetFilterQuery.setValue(rolloutForEdit.getTargetFilterQuery()); - removeComponent(targetFilterQueryCombo); - addComponent(targetFilterQuery, 1, 3); + removeComponent(1, 2); + addComponent(targetFilterQuery, 1, 2); totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(rolloutForEdit.getTargetFilterQuery()); totalTargetsLabel.setValue(getTotalTargetMessage()); totalTargetsLabel.setVisible(true); + + setOriginalValues(); + } + + private void setOriginalValues() { + distributionSetOriginal = distributionSet.getValue().toString(); + actionGroupOriginal = actionTypeOptionGroupLayout.getActionTypeOptionGroup().getValue(); + rolloutNameOriginal = rolloutName.getValue(); + triggerThresholdOriginal = triggerThreshold.getValue(); + errorThresholdOriginal = errorThreshold.getValue(); + descriptionOriginal = description.getValue(); + } + + private Map getEditedFields() { + final Map changeMap = new HashMap<>(); + if (rolloutForEdit == null) { + return changeMap; + } + if (rolloutForEdit.getStatus() != RolloutStatus.READY) { + changeMap.put(rolloutName.getId(), Boolean.FALSE); + changeMap.put(description.getId(), Boolean.FALSE); + } else { + changeMap.put(rolloutName.getId(), Boolean.FALSE); + changeMap.put(distributionSet.getId(), Boolean.FALSE); + changeMap.put(triggerThreshold.getId(), Boolean.FALSE); + changeMap.put(errorThreshold.getId(), Boolean.FALSE); + changeMap.put(description.getId(), Boolean.FALSE); + changeMap.put(actionTypeOptionGroupLayout.getActionTypeOptionGroup().getId(), Boolean.FALSE); + } + return changeMap; } private void disableRequiredFieldsOnEdit() { @@ -852,7 +959,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public String getValue() { return value; } - } enum ERRORTHRESOLDOPTIONS { @@ -870,6 +976,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public String getValue() { return value; } - } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index 20c2ca710..d3b17da5f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -28,6 +28,7 @@ import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.grid.AbstractGrid; import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData; import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer; @@ -62,7 +63,6 @@ import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.UI; -import com.vaadin.ui.Window; import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent; import com.vaadin.ui.renderers.HtmlRenderer; @@ -438,7 +438,7 @@ public class RolloutListGrid extends AbstractGrid { private void onUpdate(final ContextMenuData contextMenuData) { addUpdateRolloutWindow.populateData(contextMenuData.getRolloutId()); - final Window addTargetWindow = addUpdateRolloutWindow.getWindow(); + final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.createUpdateWindow(); addTargetWindow.setCaption(i18n.get("caption.update.rollout")); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java index 1a3d2d7a5..22c57740f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java @@ -92,7 +92,7 @@ public class RolloutListHeader extends AbstractGridHeader { @Override protected void addNewItem(final ClickEvent event) { addUpdateRolloutWindow.resetComponents(); - final Window addTargetWindow = addUpdateRolloutWindow.getWindow(); + final Window addTargetWindow = addUpdateRolloutWindow.createAddWindow(); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index 5b3ad793b..c18815b2b 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -468,10 +468,10 @@ rollout.group.label.target.truncated = {0} targets has been truncated in the lis prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold -prompt.distribution.set = Distribution set +prompt.distribution.set = Distribution Set caption.configure.rollout = Configure Rollout caption.update.rollout = Update Rollout -prompt.target.filter = Custom target filter +prompt.target.filter = Custom Target Filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists. diff --git a/hawkbit-ui/src/main/resources/messages_de.properties b/hawkbit-ui/src/main/resources/messages_de.properties index 2ac5ed9c2..2eab56ffa 100644 --- a/hawkbit-ui/src/main/resources/messages_de.properties +++ b/hawkbit-ui/src/main/resources/messages_de.properties @@ -436,7 +436,7 @@ header.rolloutgroup.target.message = Messages rollout.group.label.target.truncated = {0} targets has been truncated in the list due the target size limit of {1} -distribution.details.header = Distribution set +distribution.details.header = Distribution Set target.details.header = Target header.caption.mandatory = Mandatory header.caption.typename = SoftwareModuleType @@ -461,7 +461,7 @@ prompt.error.threshold = Error threshold prompt.distribution.set = Distribution Set caption.configure.rollout = Configure Rollout caption.update.rollout = Update Rollout -prompt.target.filter = Custom target filter +prompt.target.filter = Custom Target Filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists. diff --git a/hawkbit-ui/src/main/resources/messages_en.properties b/hawkbit-ui/src/main/resources/messages_en.properties index 459695844..b1a6bb970 100644 --- a/hawkbit-ui/src/main/resources/messages_en.properties +++ b/hawkbit-ui/src/main/resources/messages_en.properties @@ -448,10 +448,10 @@ menu.title = Software Provisioning prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold -prompt.distribution.set = Distribution set +prompt.distribution.set = Distribution Set caption.configure.rollout = Configure Rollout caption.update.rollout = Update Rollout -prompt.target.filter = Custom target filter +prompt.target.filter = Custom Target Filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists. From a9ebb763f6f9886e425f45af6e740089c5cbfe46 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 23 Jun 2016 11:25:32 +0200 Subject: [PATCH 10/52] Add i18n to CommonDialogWindow constructor Signed-off-by: Melanie Retter --- .../smtable/SoftwareModuleAddUpdateWindow.java | 2 +- .../smtype/CreateUpdateSoftwareTypeLayout.java | 2 +- .../eclipse/hawkbit/ui/common/CommonDialogWindow.java | 10 ++++------ .../hawkbit/ui/components/SPUIComponentProvider.java | 4 ++-- .../hawkbit/ui/decorators/SPUIWindowDecorator.java | 5 +++-- .../disttype/CreateUpdateDistSetTypeLayout.java | 5 ++--- .../ui/layouts/AbstractCreateUpdateTagLayout.java | 2 +- .../dstable/DistributionAddUpdateWindowLayout.java | 2 +- .../targettable/TargetAddUpdateWindowLayout.java | 2 +- .../rollout/rollout/AddUpdateRolloutWindowLayout.java | 3 ++- 10 files changed, 18 insertions(+), 19 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 43ccbe36f..fb03902b1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -223,7 +223,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - getMandatoryFields(formLayout), null); + getMandatoryFields(formLayout), null, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); nameTextField.focus(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 9a87c625d..bfd48113d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -133,7 +133,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields(), - getEditedFields()); + getEditedFields(), i18n); } private Map getMandatoryFields() { 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 index 142cd3998..05d97a0de 100644 --- 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 @@ -77,7 +77,7 @@ public class CommonDialogWindow extends Window implements Serializable { private final Map editedFields; @Autowired - private I18N i18n; + private final I18N i18n; /** * Constructor. @@ -95,7 +95,7 @@ public class CommonDialogWindow extends Window implements Serializable { */ public CommonDialogWindow(final String caption, final Component content, final String helpLink, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, - final Map requiredFields, final Map editedFields) { + final Map requiredFields, final Map editedFields, final I18N i18n) { checkNotNull(saveButtonClickListener); checkNotNull(cancelButtonClickListener); this.caption = caption; @@ -105,7 +105,7 @@ public class CommonDialogWindow extends Window implements Serializable { this.cancelButtonClickListener = cancelButtonClickListener; this.requiredFields = requiredFields; this.editedFields = editedFields; - + this.i18n = i18n; init(); } @@ -259,9 +259,7 @@ public class CommonDialogWindow extends Window implements Serializable { private void createMandatoryLabel() { if (existsMandatoryFieldsInWindowContent()) { - // final Label madatoryLabel = new - // Label(i18n.get("label.mandatory.field")); - final Label mandatoryLabel = new Label("* Mandatory Field"); + final Label mandatoryLabel = new Label(i18n.get("label.mandatory.field")); mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); if (content instanceof TargetAddUpdateWindowLayout) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index ffc0de8ee..3338124c5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -154,9 +154,9 @@ public final class SPUIComponentProvider { public static CommonDialogWindow getWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields, final Map editedFields) { + final Map requiredFields, final Map editedFields, final I18N i18n) { return SPUIWindowDecorator.getDeocratedWindow(caption, id, type, content, saveButtonClickListener, - cancelButtonClickListener, helpLink, requiredFields, editedFields); + cancelButtonClickListener, helpLink, requiredFields, editedFields, i18n); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java index b627851db..d2d7740d3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.ui.decorators; import java.util.Map; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; +import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; @@ -47,10 +48,10 @@ public final class SPUIWindowDecorator { public static CommonDialogWindow getDeocratedWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields, final Map editedFields) { + final Map requiredFields, final Map editedFields, final I18N i18n) { final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener, requiredFields, editedFields); + cancelButtonClickListener, requiredFields, editedFields, i18n); if (null != id) { window.setId(id); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index b71eaac23..303ca1bb2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -318,7 +318,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Iterator itemIterator = originalSelectedTableContainer.getItemIds().iterator(); itemIterator .hasNext();) { final long itemId = (Long) itemIterator.next(); - if (!selectedTableContainer.containsId(itemId)) { + if (selectedTableContainer.size() > 0 && !selectedTableContainer.containsId(itemId)) { return Boolean.TRUE; } } @@ -678,7 +678,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields(), - getEditedFields()); + getEditedFields(), i18n); } private Map getMandatoryFields() { @@ -692,7 +692,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } // Selected SoftwareModulesType requiredFields.put(selectedTable.getId(), null); - return requiredFields; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index f7a067bfd..195d173ed 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -117,7 +117,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent reset(); setWindow( SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, - this, this::save, this::discard, null, getMandatoryFields(), getEditedFields())); + this, this::save, this::discard, null, getMandatoryFields(), getEditedFields(), i18n)); } private Map getMandatoryFields() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 4a6a29e93..03dce184c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -523,7 +523,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { resetComponents(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, getMandatoryFields(), null); + null, getMandatoryFields(), null, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 8ea8665d6..07360ed70 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -244,7 +244,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields(), null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields(), null, i18n); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 566ac4528..c1efa9f4b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -176,7 +176,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public CommonDialogWindow getWindow() { window = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), - uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields(), getEditedFields()); + uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields(), getEditedFields(), + i18n); return window; } From 850b7c68282885fac15c5f56c58cc012b3f5814d Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Fri, 24 Jun 2016 17:26:57 +0200 Subject: [PATCH 11/52] fix enable save button problem when update Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 100 +++---- .../smtable/SoftwareModuleTable.java | 1 - .../CreateUpdateSoftwareTypeLayout.java | 27 +- .../hawkbit/ui/common/CommonDialogWindow.java | 281 +++++++++++------- .../CreateUpdateDistSetTypeLayout.java | 84 +++--- .../AbstractCreateUpdateTagLayout.java | 69 +++-- .../ui/layouts/CreateUpdateTypeLayout.java | 28 +- .../DistributionAddUpdateWindowLayout.java | 186 +++--------- ...eateUpdateDistributionTagLayoutWindow.java | 6 +- .../TargetAddUpdateWindowLayout.java | 135 +++------ .../CreateUpdateTargetTagLayoutWindow.java | 4 +- .../rollout/AddUpdateRolloutWindowLayout.java | 176 +++++------ .../ui/rollout/rollout/RolloutListGrid.java | 9 +- .../ui/rollout/rollout/RolloutListHeader.java | 2 +- 14 files changed, 499 insertions(+), 609 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index fb03902b1..7e3051555 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -32,8 +32,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.spring.events.EventBus; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.AbstractField; @@ -84,9 +82,15 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private CommonDialogWindow window; - private String oldDescriptionValue; + private String originalDescriptionValue; - private String oldVendorValue; + private String originalVendorValue; + + private String originalNameValue; + + private String originalVersionValue; + + private String originalComboBoxValue; private Boolean editSwModule = Boolean.FALSE; @@ -135,26 +139,31 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_NAME); - nameTextField.addTextChangeListener(this::listenerNameTextFieldChanged); + nameTextField.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalNameValue)); + nameTextField.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, nameTextField)); /* version text field */ versionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); versionTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VERSION); - versionTextField.addTextChangeListener(this::listenerVersionTextFieldChanged); + versionTextField + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalVersionValue)); + versionTextField.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, versionTextField)); /* Vendor text field */ vendorTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.vendor"), "", ValoTheme.TEXTFIELD_TINY, false, null, i18n.get("textfield.vendor"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); vendorTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VENDOR); + vendorTextField + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalVendorValue)); descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.ADD_SW_MODULE_DESCRIPTION); - addDescriptionTextChangeListener(); - addVendorTextChangeListener(); + descTextArea + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalDescriptionValue)); typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true, null, i18n.get("upload.swmodule.type")); @@ -162,43 +171,40 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se typeComboBox.setStyleName(SPUIDefinitions.COMBO_BOX_SPECIFIC_STYLE + " " + ValoTheme.COMBOBOX_TINY); typeComboBox.setNewItemsAllowed(Boolean.FALSE); typeComboBox.setImmediate(Boolean.TRUE); - typeComboBox.addValueChangeListener(this::listenerTypeComboBoxChanged); - populateTypeNameCombo(); - - resetOldValues(); - } - - private void listenerNameTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, nameTextField); - } - - private void listenerVersionTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, versionTextField); - } - - private void listenerTypeComboBoxChanged(final ValueChangeEvent event) { - window.checkMandatoryComboBox(event, typeComboBox); + typeComboBox.addValueChangeListener( + event -> window.checkMandatoryEditedValue(event, typeComboBox, originalComboBoxValue)); } private void populateTypeNameCombo() { typeComboBox.setContainerDataSource(HawkbitCommonUtil.createLazyQueryContainer( new BeanQueryFactory(SoftwareModuleTypeBeanQuery.class))); typeComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); - } - private void resetOldValues() { - oldDescriptionValue = null; - oldVendorValue = null; + private void resetComponents() { + + vendorTextField.clear(); + nameTextField.clear(); + versionTextField.clear(); + descTextArea.clear(); + typeComboBox.clear(); + + originalDescriptionValue = null; + originalVendorValue = null; + originalComboBoxValue = null; + originalNameValue = null; + originalVersionValue = null; if (window != null) { - window.resetMandatoryAndEditedFields(); + window.reset(); } } private void createWindow() { + resetComponents(); + final Label madatoryStarLabel = new Label("*"); madatoryStarLabel.setStyleName("v-caption v-required-field-indicator"); madatoryStarLabel.setWidth(null); @@ -223,9 +229,9 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - getMandatoryFields(formLayout), null, i18n); + getMandatoryFields(formLayout), geEditedFields(), i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); - nameTextField.focus(); + typeComboBox.focus(); } private Map getMandatoryFields(final FormLayout formLayout) { @@ -234,18 +240,20 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), Boolean.FALSE); } } return requiredFields; } - private void addDescriptionTextChangeListener() { - descTextArea.addTextChangeListener(event -> window.setSaveButtonEnabled(hasDescriptionChanged(event))); - } - - private void addVendorTextChangeListener() { - vendorTextField.addTextChangeListener(event -> window.setSaveButtonEnabled(hasVendorChanged(event))); + private Map geEditedFields() { + final Map editedFields = new HashMap<>(); + editedFields.put(typeComboBox.getId(), Boolean.FALSE); + editedFields.put(nameTextField.getId(), Boolean.FALSE); + editedFields.put(vendorTextField.getId(), Boolean.FALSE); + editedFields.put(versionTextField.getId(), Boolean.FALSE); + editedFields.put(descTextArea.getId(), Boolean.FALSE); + return editedFields; } /** @@ -309,13 +317,13 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se : HawkbitCommonUtil.trimAndNullIfEmpty(swModle.getVendor())); descTextArea.setValue(swModle.getDescription() == null ? HawkbitCommonUtil.SP_STRING_EMPTY : HawkbitCommonUtil.trimAndNullIfEmpty(swModle.getDescription())); - oldDescriptionValue = descTextArea.getValue(); - oldVendorValue = vendorTextField.getValue(); + originalDescriptionValue = descTextArea.getValue(); + originalVendorValue = vendorTextField.getValue(); + originalComboBoxValue = swModle.getType().getName(); if (swModle.getType().isDeleted()) { typeComboBox.addItem(swModle.getType().getName()); } typeComboBox.setValue(swModle.getType().getName()); - window.setSaveButtonEnabled(Boolean.FALSE); } /** @@ -324,7 +332,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private void closeThisWindow() { window.close(); UI.getCurrent().removeWindow(window); - window.setSaveButtonEnabled(false); } /** @@ -361,15 +368,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se } else { addNewBaseSoftware(); } - window.setSaveButtonEnabled(false); - } - - private boolean hasDescriptionChanged(final TextChangeEvent event) { - return !(event.getText().equals(oldDescriptionValue) && vendorTextField.getValue().equals(oldVendorValue)); - } - - private boolean hasVendorChanged(final TextChangeEvent event) { - return !(event.getText().equals(oldVendorValue) && descTextArea.getValue().equals(oldDescriptionValue)); } public FormLayout getFormLayout() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java index 6527a37be..694399b47 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java @@ -44,7 +44,6 @@ import com.vaadin.ui.UI; /** * Header of Software module table. - * */ @SpringComponent @ViewScope diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index bfd48113d..d8b32efc4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -34,7 +34,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; @@ -92,13 +91,15 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_NAME); - tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); + tagName.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTagName())); + tagName.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, tagName)); typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_KEY); - typeKey.addTextChangeListener(this::typeKeyTextFieldChanged); + typeKey.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTypeKey())); + typeKey.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, typeKey)); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "", @@ -106,19 +107,11 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout tagDesc.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); - tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); + tagDesc.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTagDesc())); singleMultiOptionGroup(); } - private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, tagName); - } - - private void typeKeyTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, typeKey); - } - @Override protected void buildLayout() { @@ -142,7 +135,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), Boolean.FALSE); } } return requiredFields; @@ -164,6 +157,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout } else { assignOptiongroup.setEnabled(true); } + assignOptiongroup.select(singleAssignStr); } /** @@ -195,18 +189,19 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout @Override protected void setTagDetails(final String targetTagSelected) { tagName.setValue(targetTagSelected); + setOriginalTagName(targetTagSelected); final SoftwareModuleType selectedTypeTag = swTypeManagementService .findSoftwareModuleTypeByName(targetTagSelected); if (null != selectedTypeTag) { tagDesc.setValue(selectedTypeTag.getDescription()); - setTagDescOriginal(selectedTypeTag.getDescription()); + setOriginalTagDesc(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); + setOriginalTypeKey(selectedTypeTag.getKey()); if (selectedTypeTag.getMaxAssignments() == Integer.MAX_VALUE) { assignOptiongroup.setValue(multiAssignStr); } else { assignOptiongroup.setValue(singleAssignStr); } - setColorPickerComponentsColor(selectedTypeTag.getColour()); } } @@ -245,7 +240,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout updateSWModuleType(existingSMTypeByName); } - window.setSaveButtonEnabled(false); + // window.setSaveButtonEnabled(false); } private void createNewSWModuleType() { 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 index 05d97a0de..7602f0a83 100644 --- 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 @@ -11,8 +11,10 @@ package org.eclipse.hawkbit.ui.common; import static com.google.common.base.Preconditions.checkNotNull; import java.io.Serializable; +import java.util.Collections; import java.util.Map; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -22,16 +24,14 @@ import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.FontAwesome; import com.vaadin.shared.ui.colorpicker.Color; +import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.AbstractOrderedLayout; -import com.vaadin.ui.AbstractSelect; -import com.vaadin.ui.AbstractTextField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; @@ -74,9 +74,8 @@ public class CommonDialogWindow extends Window implements Serializable { private Map requiredFields; - private final Map editedFields; + private Map editedFields; - @Autowired private final I18N i18n; /** @@ -104,41 +103,155 @@ public class CommonDialogWindow extends Window implements Serializable { this.saveButtonClickListener = saveButtonClickListener; this.cancelButtonClickListener = cancelButtonClickListener; this.requiredFields = requiredFields; + if (requiredFields == null) { + this.requiredFields = Collections.emptyMap(); + } + this.editedFields = editedFields; + if (editedFields == null) { + this.editedFields = Collections.emptyMap(); + } this.i18n = i18n; init(); } - public void checkMandatoryTextField(final TextChangeEvent event, final AbstractTextField textfield) { - - if (StringUtils.isNotBlank(event.getText())) { - if (StringUtils.isNotBlank(textfield.getCaption())) { - requiredFields.put(textfield.getCaption(), Boolean.TRUE); - } - getRequiredFields().put(textfield.getId(), Boolean.TRUE); - } else { - if (StringUtils.isNotBlank(textfield.getCaption())) { - requiredFields.put(textfield.getCaption(), Boolean.FALSE); - } - requiredFields.put(textfield.getId(), Boolean.FALSE); + /** + * Checks if all mandatory fields are filled, and if there are changes in + * the current field. If yes, the save button will be enabled. + * + * @param event + * TextChangeEvent + * @param originalValue + * original Value of the current field + */ + public void checkMandatoryEditedTextField(final TextChangeEvent event, final String originalValue) { + final Component component = event.getComponent(); + if (!(component instanceof AbstractComponent)) { + throw new IllegalStateException("Only AbstractComponent not allow"); } - checkMandatoryFieldsFilled(); + + if (requiredFields.containsKey(component.getId())) { + final boolean isTextChangeNotEmpty = StringUtils.isNotBlank(event.getText()); + setRequiredFieldChangeValue((AbstractComponent) component, isTextChangeNotEmpty); + } + checkChanges(component.getId(), event.getText(), originalValue); + checkSaveButtonEnabled(); } - public void checkMandatoryComboBox(final ValueChangeEvent event, final AbstractSelect select) { - - if (event.getProperty().getValue() != null) { - if (StringUtils.isNotBlank(select.getCaption())) { - requiredFields.put(select.getCaption(), Boolean.TRUE); - } - requiredFields.put(select.getId(), Boolean.TRUE); - } else { - if (StringUtils.isNotBlank(select.getCaption())) { - requiredFields.put(select.getCaption(), Boolean.FALSE); - } - requiredFields.put(select.getId(), Boolean.FALSE); + /** + * Checks if all mandatory fields are filled, and if there are changes in + * the current field. If yes, the save button will be enabled. + * + * @param event + * ValueChangeEvent + * @param component + * current Component + * @param originalValue + * original Value of the current field + */ + public void checkMandatoryEditedValue(final ValueChangeEvent event, final AbstractComponent component, + final String originalValue) { + final boolean isChangedValueNotNull = event.getProperty().getValue() != null; + if (requiredFields.containsKey(component.getId())) { + setRequiredFieldChangeValue(component, isChangedValueNotNull); } - checkMandatoryFieldsFilled(); + if (event.getProperty().getValue() != null) { + checkChanges(component.getId(), event.getProperty().getValue().toString(), originalValue); + } else { + checkChanges(component.getId(), null, originalValue); + } + checkSaveButtonEnabled(); + } + + /** + * Checks if all mandatory fields are filled, and if there are changes in + * the current field. (Boolean) If yes, the save button will be enabled. + * + * @param event + * ValueChangeEvent + * @param component + * current Component + * @param originalValue + * original Boolean Value of the current field + */ + public void checkMandatoryEditedValueBoolean(final ValueChangeEvent event, final AbstractComponent component, + final Boolean originalValue) { + final boolean isChangedValueNotNull = event.getProperty().getValue() != null; + if (requiredFields.containsKey(component.getId())) { + setRequiredFieldChangeValue(component, isChangedValueNotNull); + } + final Boolean changed = (Boolean) event.getProperty().getValue(); + editedFields.put(component.getId(), BooleanUtils.compare(changed, originalValue) != 0); + checkSaveButtonEnabled(); + } + + /** + * Updates the map of required fields if a value is set. (e.g. on Update + * when editing a component) + * + * @param event + * ValueChangeEvent + * @param component + * current Component + */ + public void setRequiredFieldWhenUpdate(final ValueChangeEvent event, final AbstractComponent component) { + final boolean isChangedValueNotNull = event.getProperty().getValue() != null; + setRequiredFieldChangeValue(component, isChangedValueNotNull); + } + + /** + * * Updates the map of required fields if a value is set. (e.g. on Update + * when editing a component) + * + * @param fieldId + * Id of the current component + * @param filled + * Boolean if field is filled + */ + public void updateRequiredFields(final String fieldId, final Boolean filled) { + + requiredFields.put(fieldId, filled); + checkSaveButtonEnabled(); + } + + /** + * Checks if Color is changed + * + * @param fieldId + * Id of the current component + * @param newColor + * new Color + * @param oldColor + * old Color + */ + public void checkColorChange(final String fieldId, final Color newColor, final Color oldColor) { + editedFields.put(fieldId, !newColor.equals(oldColor)); + checkSaveButtonEnabled(); + } + + /** + * Updates the map of fields which can be edited. + * + * @param fieldId + * Id of the current component + * @param hasTextValueChanged + * Boolean if value has changed + */ + public void updateEditedFields(final String fieldId, final Boolean hasTextValueChanged) { + editedFields.put(fieldId, hasTextValueChanged); + checkSaveButtonEnabled(); + } + + /** + * Resets the map of mandatory and edited Fields and disable the save button + */ + public void reset() { + saveButton.setEnabled(false); + resetFields(); + } + + private void setRequiredFieldChangeValue(final AbstractComponent component, final boolean isTextChangeNotEmpty) { + requiredFields.put(component.getId(), isTextChangeNotEmpty); } /** @@ -146,69 +259,23 @@ public class CommonDialogWindow extends Window implements Serializable { * mandatory fields are filled the save button is enabled. Otherwise the * save button is disabled. */ - private void checkMandatoryFieldsFilled() { + private void checkSaveButtonEnabled() { + saveButton.setEnabled(!requiredFields.containsValue(Boolean.FALSE) && editedFields.containsValue(Boolean.TRUE)); + } + private void checkChanges(final String fieldName, final String newText, final String oldText) { + final boolean hasTextValueChanged = (StringUtils.isNotBlank(newText) && !newText.equals(oldText)) + || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText)); + editedFields.put(fieldName, hasTextValueChanged); + } + + private void resetFields() { for (final Map.Entry entry : requiredFields.entrySet()) { - if (entry.getValue() == null || entry.getValue().equals(Boolean.FALSE)) { - saveButton.setEnabled(false); - return; - } + entry.setValue(Boolean.FALSE); } - saveButton.setEnabled(true); - } - private void checkExistsChanges() { - - if (editedFields == null) { - return; - } for (final Map.Entry entry : editedFields.entrySet()) { - if (entry.getValue() != null && entry.getValue().equals(Boolean.TRUE)) { - saveButton.setEnabled(true); - return; - } - } - saveButton.setEnabled(false); - } - - public void updateRequiredFields(final String fieldId, final Boolean filled) { - - requiredFields.put(fieldId, filled); - checkMandatoryFieldsFilled(); - } - - public void checkChanges(final String fieldName, final String newText, final String oldText) { - - if ((StringUtils.isNotBlank(newText) && !newText.equals(oldText)) - || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText))) { - editedFields.put(fieldName, Boolean.TRUE); - } else { - editedFields.put(fieldName, Boolean.FALSE); - } - checkExistsChanges(); - } - - public void checkColorChange(final String fieldName, final Color newColor, final Color oldColor) { - - if (newColor.equals(oldColor)) { - editedFields.put(fieldName, Boolean.FALSE); - } else { - editedFields.put(fieldName, Boolean.TRUE); - } - checkExistsChanges(); - } - - public void resetMandatoryAndEditedFields() { - resetFields(requiredFields); - resetFields(editedFields); - } - - private void resetFields(final Map fields) { - // Reset mandatory fields are filled marker / fields are edited marker - if (fields != null) { - for (final Map.Entry entry : fields.entrySet()) { - entry.setValue(null); - } + entry.setValue(Boolean.FALSE); } } @@ -258,20 +325,22 @@ public class CommonDialogWindow extends Window implements Serializable { private void createMandatoryLabel() { - if (existsMandatoryFieldsInWindowContent()) { - final Label mandatoryLabel = new Label(i18n.get("label.mandatory.field")); - mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); - - if (content instanceof TargetAddUpdateWindowLayout) { - ((TargetAddUpdateWindowLayout) content).getFormLayout().addComponent(mandatoryLabel); - } else if (content instanceof SoftwareModuleAddUpdateWindow) { - ((SoftwareModuleAddUpdateWindow) content).getFormLayout().addComponent(mandatoryLabel); - } else if (content instanceof AbstractCreateUpdateTagLayout) { - ((AbstractCreateUpdateTagLayout) content).getMainLayout().addComponent(mandatoryLabel); - } - - mainLayout.addComponent(mandatoryLabel); + if (!existsMandatoryFieldsInWindowContent()) { + return; } + + final Label mandatoryLabel = new Label(i18n.get("label.mandatory.field")); + mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); + + if (content instanceof TargetAddUpdateWindowLayout) { + ((TargetAddUpdateWindowLayout) content).getFormLayout().addComponent(mandatoryLabel); + } else if (content instanceof SoftwareModuleAddUpdateWindow) { + ((SoftwareModuleAddUpdateWindow) content).getFormLayout().addComponent(mandatoryLabel); + } else if (content instanceof AbstractCreateUpdateTagLayout) { + ((AbstractCreateUpdateTagLayout) content).getMainLayout().addComponent(mandatoryLabel); + } + + mainLayout.addComponent(mandatoryLabel); } private void createCancelButton() { @@ -292,18 +361,14 @@ public class CommonDialogWindow extends Window implements Serializable { saveButton.setSizeUndefined(); saveButton.addStyleName("default-color"); saveButton.addClickListener(saveButtonClickListener); - saveButton.setEnabled(!existsMandatoryFieldsInWindowContent()); + saveButton.setEnabled(false); buttonsLayout.addComponent(saveButton); buttonsLayout.setComponentAlignment(saveButton, Alignment.MIDDLE_RIGHT); buttonsLayout.setExpandRatio(saveButton, 1.0F); } private boolean existsMandatoryFieldsInWindowContent() { - - if (requiredFields != null && requiredFields.size() > 0) { - return true; - } - return false; + return !requiredFields.isEmpty(); } private void addHelpLink() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 303ca1bb2..9c6486200 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -14,7 +14,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; @@ -41,7 +40,6 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import com.vaadin.data.Item; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.util.IndexedContainer; -import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; @@ -93,6 +91,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private IndexedContainer originalSelectedTableContainer; + private String originalTypeKey; + @Override protected void createRequiredComponents() { @@ -102,13 +102,15 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_NAME); - tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); + tagName.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTagName())); + tagName.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, tagName)); typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_KEY); - typeKey.addTextChangeListener(this::listenerTypeKeyTextFieldChanged); + typeKey.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTypeKey)); + typeKey.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, typeKey)); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "", @@ -116,16 +118,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); - tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); - } - - private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { - - window.checkMandatoryTextField(event, tagName); - } - - private void listenerTypeKeyTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, typeKey); + tagDesc.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTagDesc())); } @Override @@ -279,14 +272,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Long id : selectedIds) { addTargetTableData(id); } - if (optiongroup.getValue().equals(updateTypeStr)) { - updateMandatoryFields(); - window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); - } else { - if (!selectedTableContainer.getItemIds().isEmpty()) { - window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); - } - } + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); } } @@ -298,19 +284,20 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Long id : selectedIds) { addSourceTableData(id); selectedTable.removeItem(id); - if (optiongroup.getValue().equals(updateTypeStr)) { - updateMandatoryFields(); - window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); - } + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); } } } private Boolean hasContentChanged() { + if (originalSelectedTableContainer == null) { + originalSelectedTableContainer = new IndexedContainer(); + } for (final Iterator itemIterator = selectedTableContainer.getItemIds().iterator(); itemIterator.hasNext();) { final long itemId = (Long) itemIterator.next(); if (!originalSelectedTableContainer.containsId(itemId)) { + window.updateEditedFields(selectedTable.getId(), Boolean.TRUE); return Boolean.TRUE; } } @@ -319,23 +306,17 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout .hasNext();) { final long itemId = (Long) itemIterator.next(); if (selectedTableContainer.size() > 0 && !selectedTableContainer.containsId(itemId)) { + window.updateEditedFields(selectedTable.getId(), Boolean.TRUE); return Boolean.TRUE; } } + if (selectedTableContainer.size() > 0) { + window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); + } return Boolean.FALSE; } - private void updateMandatoryFields() { - - if (StringUtils.isNotBlank(tagName.getValue())) { - window.getRequiredFields().put("Name", Boolean.TRUE); - } - if (StringUtils.isNotBlank(typeKey.getValue())) { - window.getRequiredFields().put("Key", Boolean.TRUE); - } - } - @SuppressWarnings("unchecked") private void getSourceTableData() { @@ -543,6 +524,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout super.optionValueChanged(event); if (updateTypeStr.equals(event.getProperty().getValue())) { + window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); selectedTable.getContainerDataSource().removeAllItems(); getSourceTableData(); distTypeSelectLayout.setEnabled(false); @@ -600,14 +582,15 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout protected void setTagDetails(final String distSetTypeSelected) { tagName.setValue(distSetTypeSelected); + setOriginalTagName(distSetTypeSelected); getSourceTableData(); selectedTable.getContainerDataSource().removeAllItems(); final DistributionSetType selectedTypeTag = fetchDistributionSetType(distSetTypeSelected); if (null != selectedTypeTag) { tagDesc.setValue(selectedTypeTag.getDescription()); - setTagDescOriginal(selectedTypeTag.getDescription()); + setOriginalTagDesc(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); - setTypeKeyOriginal(selectedTypeTag.getKey()); + setOriginalTypeKey(selectedTypeTag.getKey()); if (distributionSetManagement.countDistributionSetsByType(selectedTypeTag) <= 0) { distTypeSelectLayout.setEnabled(true); selectedTable.setEnabled(true); @@ -669,7 +652,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } else { updateDistributionSetType(existingDistTypeByKey); } - window.setSaveButtonEnabled(false); } } @@ -687,14 +669,24 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), Boolean.FALSE); } } // Selected SoftwareModulesType - requiredFields.put(selectedTable.getId(), null); + requiredFields.put(selectedTable.getId(), Boolean.FALSE); return requiredFields; } + @Override + protected Map getEditedFields() { + final Map changeMap = new HashMap<>(); + changeMap.put(tagName.getId(), Boolean.FALSE); + changeMap.put(colorPickerLayout.getId(), Boolean.FALSE); + changeMap.put(tagDesc.getId(), Boolean.FALSE); + changeMap.put(selectedTable.getId(), Boolean.FALSE); + return changeMap; + } + @Override protected void previewButtonClicked() { if (!tagPreviewBtnClicked) { @@ -729,4 +721,14 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID); } + @Override + public String getOriginalTypeKey() { + return originalTypeKey; + } + + @Override + public void setOriginalTypeKey(final String originalTypeKey) { + this.originalTypeKey = originalTypeKey; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 195d173ed..6beb7d5b7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -36,7 +36,6 @@ import org.vaadin.spring.events.EventBus; import com.google.common.base.Strings; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.ui.AbstractField; @@ -110,8 +109,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected String tagNameValue; protected String tagDescValue; - protected Color selectedColorOriginal; - private String tagDescOriginal; + private Color originalSelectedColor; + private String originalTagDesc; + private String originalTagName; protected void createWindow() { reset(); @@ -126,7 +126,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), null); } } return requiredFields; @@ -134,8 +134,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected Map getEditedFields() { final Map changeMap = new HashMap<>(); - changeMap.put(tagDesc.getCaption(), Boolean.FALSE); + changeMap.put(tagName.getId(), Boolean.FALSE); changeMap.put(colorPickerLayout.getId(), Boolean.FALSE); + changeMap.put(tagDesc.getId(), Boolean.FALSE); return changeMap; } @@ -192,7 +193,8 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_TARGET_TAG_NAME); - tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); + tagName.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTagName)); + tagName.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, tagName)); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"), @@ -200,7 +202,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagDesc.setId(SPUIDefinitions.NEW_TARGET_TAG_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); - tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); + tagDesc.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTagDesc)); tagNameComboBox = SPUIComponentProvider.getComboBox(null, "", "", null, null, false, "", i18n.get("label.combobox.tag")); @@ -214,16 +216,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagColorPreviewBtn.setStyleName(TAG_DYNAMIC_STYLE); } - private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { - - window.checkMandatoryTextField(event, tagName); - } - - protected void listenerTagDescTextAreaChanged(final TextChangeEvent event) { - - window.checkChanges(tagDesc.getCaption(), event.getText(), tagDescOriginal); - } - protected void buildLayout() { mainLayout = new GridLayout(3, 2); @@ -352,7 +344,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } - window.setSaveButtonEnabled(false); + window.reset(); // close the color picker layout tagPreviewBtnClicked = false; // reset the selected color - Set default color @@ -383,7 +375,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagPreviewBtnClicked = false; if (window != null) { - window.resetMandatoryAndEditedFields(); + window.reset(); } } @@ -474,13 +466,12 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor()); } - window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), selectedColorOriginal); + window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), originalSelectedColor); } protected void closeWindow() { window.close(); UI.getCurrent().removeWindow(window); - window.setSaveButtonEnabled(false); } /** @@ -687,23 +678,39 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent } public Color getSelectedColorOriginal() { - return selectedColorOriginal; + return originalSelectedColor; } public void setSelectedColorOriginal(final Color selectedColorOriginal) { - this.selectedColorOriginal = selectedColorOriginal; - } - - public String getTagDescOriginal() { - return tagDescOriginal; - } - - public void setTagDescOriginal(final String tagDescOriginal) { - this.tagDescOriginal = tagDescOriginal; + this.originalSelectedColor = selectedColorOriginal; } public GridLayout getMainLayout() { return mainLayout; } + public Color getOriginalSelectedColor() { + return originalSelectedColor; + } + + public void setOriginalSelectedColor(final Color originalSelectedColor) { + this.originalSelectedColor = originalSelectedColor; + } + + public String getOriginalTagDesc() { + return originalTagDesc; + } + + public void setOriginalTagDesc(final String originalTagDesc) { + this.originalTagDesc = originalTagDesc; + } + + public String getOriginalTagName() { + return originalTagName; + } + + public void setOriginalTagName(final String originalTagName) { + this.originalTagName = originalTagName; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index ea77d885b..556347e4f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -33,10 +33,8 @@ import com.vaadin.ui.components.colorpicker.ColorSelector; import com.vaadin.ui.themes.ValoTheme; /** - * * Superclass defining common properties and methods for creating/updating * types. - * */ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { @@ -45,7 +43,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { protected String createTypeStr; protected String updateTypeStr; protected TextField typeKey; - protected String typeKeyOriginal; + protected String originalTypeKey; public static final String TYPE_NAME_DYNAMIC_STYLE = "new-tag-name"; private static final String TYPE_DESC_DYNAMIC_STYLE = "new-tag-desc"; @@ -152,14 +150,13 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { } else { typeKey.setEnabled(true); tagName.setEnabled(true); - window.setSaveButtonEnabled(true); tagName.clear(); tagDesc.clear(); typeKey.clear(); comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } - window.setSaveButtonEnabled(false); + window.reset(); restoreComponentStyles(); getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); getColorPickerLayout().getSelPreview() @@ -186,7 +183,8 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { createDynamicStyleForComponents(tagName, typeKey, tagDesc, colorPickedPreview); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelPreview().getColor()); } - window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), selectedColorOriginal); + window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), + getOriginalSelectedColor()); } /** @@ -324,22 +322,12 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { // is implemented in the inherited class } - @Override - public Color getSelectedColorOriginal() { - return selectedColorOriginal; + public String getOriginalTypeKey() { + return originalTypeKey; } - @Override - public void setSelectedColorOriginal(final Color selectedColorOriginal) { - this.selectedColorOriginal = selectedColorOriginal; - } - - public String getTypeKeyOriginal() { - return typeKeyOriginal; - } - - public void setTypeKeyOriginal(final String typeKeyOriginal) { - this.typeKeyOriginal = typeKeyOriginal; + public void setOriginalTypeKey(final String originalTypeKey) { + this.originalTypeKey = originalTypeKey; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 03dce184c..90dd8a6a6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -8,10 +8,8 @@ */ package org.eclipse.hawkbit.ui.management.dstable; -import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; @@ -44,10 +42,6 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition; import org.vaadin.spring.events.EventBus; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.event.FieldEvents.TextChangeEvent; -import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.AbstractField; @@ -62,8 +56,7 @@ import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** - * - * + * WindowContent for adding/editing a Distribution */ @SpringComponent @ViewScope @@ -104,12 +97,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private String originalDistDescription; private Boolean originalReqMigStep; private String originalDistSetType; - private final List changedComponents = new ArrayList<>(); - private ValueChangeListener reqMigStepCheckboxListerner; - private TextChangeListener descTextAreaListener; - private TextChangeListener distNameTextFieldListener; - private TextChangeListener distVersionTextFieldListener; - private ValueChangeListener distsetTypeNameComboBoxListener; private FormLayout formLayout; @@ -139,7 +126,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { formLayout.addComponent(reqMigStepCheckbox); setCompositionRoot(formLayout); - distNameTextField.focus(); } @@ -151,43 +137,42 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); distNameTextField.setId(SPUIComponentIdProvider.DIST_ADD_NAME); distNameTextField.setNullRepresentation(""); - distNameTextField.addTextChangeListener(this::listenerDistNameTextFieldChanged); + distNameTextField.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalDistName)); + distNameTextField.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, distNameTextField)); distVersionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); distVersionTextField.setId(SPUIComponentIdProvider.DIST_ADD_VERSION); distVersionTextField.setNullRepresentation(""); - distVersionTextField.addTextChangeListener(this::listenerDistVersionTextFieldChanged); + distVersionTextField + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalDistVersion)); + distVersionTextField + .addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, distVersionTextField)); distsetTypeNameComboBox = SPUIComponentProvider.getComboBox(i18n.get("label.combobox.type"), "", "", null, "", false, "", i18n.get("label.combobox.type")); distsetTypeNameComboBox.setImmediate(true); distsetTypeNameComboBox.setNullSelectionAllowed(false); distsetTypeNameComboBox.setId(SPUIComponentIdProvider.DIST_ADD_DISTSETTYPE); + populateDistSetTypeNameCombo(); + distsetTypeNameComboBox.addValueChangeListener( + event -> window.checkMandatoryEditedValue(event, distsetTypeNameComboBox, originalDistSetType)); descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.DIST_ADD_DESC); descTextArea.setNullRepresentation(""); + descTextArea + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalDistDescription)); reqMigStepCheckbox = SPUIComponentProvider.getCheckBox(i18n.get("checkbox.dist.required.migration.step"), "dist-checkbox-style", null, false, ""); reqMigStepCheckbox.addStyleName(ValoTheme.CHECKBOX_SMALL); reqMigStepCheckbox.setId(SPUIComponentIdProvider.DIST_ADD_MIGRATION_CHECK); - } - - private void listenerDistNameTextFieldChanged(final TextChangeEvent event) { - if (!editDistribution) { - window.checkMandatoryTextField(event, distNameTextField); - } - } - - private void listenerDistVersionTextFieldChanged(final TextChangeEvent event) { - if (!editDistribution) { - window.checkMandatoryTextField(event, distVersionTextField); - } + reqMigStepCheckbox.addValueChangeListener( + event -> window.checkMandatoryEditedValueBoolean(event, reqMigStepCheckbox, originalReqMigStep)); } /** @@ -209,26 +194,17 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { return disttypeContainer; } - private void enableSaveButton() { - window.setSaveButtonEnabled(true); - } - private DistributionSetType getDefaultDistributionSetType() { final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); return tenantMetaData.getDefaultDsType(); } - private void disableSaveButton() { - window.setSaveButtonEnabled(false); - } - private void saveDistribution() { if (editDistribution) { updateDistribution(); } else { addNewDistribution(); } - window.setSaveButtonEnabled(false); } /** @@ -262,19 +238,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } } - private void addListeners() { - reqMigStepCheckboxListerner = event -> checkValueChanged(originalReqMigStep, event); - descTextAreaListener = event -> checkValueChanged(originalDistDescription, event); - distNameTextFieldListener = event -> checkValueChanged(originalDistName, event); - distVersionTextFieldListener = event -> checkValueChanged(originalDistVersion, event); - distsetTypeNameComboBoxListener = event -> checkValueChanged(originalDistSetType, event); - reqMigStepCheckbox.addValueChangeListener(reqMigStepCheckboxListerner); - descTextArea.addTextChangeListener(descTextAreaListener); - distNameTextField.addTextChangeListener(distNameTextFieldListener); - distVersionTextField.addTextChangeListener(distVersionTextFieldListener); - distsetTypeNameComboBox.addValueChangeListener(distsetTypeNameComboBoxListener); - } - /** * Add new Distribution set. */ @@ -308,7 +271,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private void closeThisWindow() { window.close(); UI.getCurrent().removeWindow(window); - window.setSaveButtonEnabled(false); } /** @@ -381,7 +343,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { if (distSetTypeName == null) { distsetTypeNameComboBox.addStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); } - notificationMessage.displayValidationError(i18n.get("message.mandatory.check")); return false; } @@ -391,7 +352,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private void discardDistribution() { /* Just close this window */ - distsetTypeNameComboBox.removeValueChangeListener(distsetTypeNameComboBoxListener); closeThisWindow(); } @@ -407,14 +367,15 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { distsetTypeNameComboBox.removeStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); descTextArea.clear(); reqMigStepCheckbox.clear(); - if (window != null) { - window.setSaveButtonEnabled(true); - } - removeListeners(); - changedComponents.clear(); + + originalDistDescription = null; + originalDistName = null; + originalDistSetType = null; + originalDistVersion = null; + originalReqMigStep = Boolean.FALSE; if (window != null) { - window.resetMandatoryAndEditedFields(); + window.reset(); } } @@ -422,71 +383,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { populateDistSetTypeNameCombo(); } - private void removeListeners() { - reqMigStepCheckbox.removeValueChangeListener(reqMigStepCheckboxListerner); - descTextArea.removeTextChangeListener(descTextAreaListener); - distNameTextField.removeTextChangeListener(distNameTextFieldListener); - distVersionTextField.removeTextChangeListener(distVersionTextFieldListener); - } - - public void setOriginalDistName(final String originalDistName) { - this.originalDistName = originalDistName; - } - - public void setOriginalDistVersion(final String originalDistVersion) { - this.originalDistVersion = originalDistVersion; - } - - public void setOriginalDistDescription(final String originalDistDescription) { - this.originalDistDescription = originalDistDescription; - } - - private void checkValueChanged(final String originalValue, final TextChangeEvent event) { - if (editDistribution) { - final String newValue = event.getText(); - if (!originalValue.equalsIgnoreCase(newValue)) { - changedComponents.add(event.getComponent()); - } else { - changedComponents.remove(event.getComponent()); - } - enableDisableSaveButton(); - } - } - - private void checkValueChanged(final Boolean originalValue, final ValueChangeEvent event) { - if (editDistribution) { - if (!originalValue.equals(event.getProperty().getValue())) { - changedComponents.add(reqMigStepCheckbox); - } else { - changedComponents.remove(reqMigStepCheckbox); - } - enableDisableSaveButton(); - } - } - - private void checkValueChanged(final String originalValue, final ValueChangeEvent event) { - if (editDistribution) { - if (!originalValue.equals(event.getProperty().getValue())) { - changedComponents.add(distsetTypeNameComboBox); - } else { - changedComponents.remove(distsetTypeNameComboBox); - } - enableDisableSaveButton(); - } - } - - private void enableDisableSaveButton() { - if (changedComponents.isEmpty()) { - disableSaveButton(); - } else { - enableSaveButton(); - } - } - - private void setOriginalReqMigStep(final Boolean originalReqMigStep) { - this.originalReqMigStep = originalReqMigStep; - } - /** * populate data. * @@ -495,7 +391,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { public void populateValuesOfDistribution(final Long editDistId) { this.editDistId = editDistId; editDistribution = Boolean.TRUE; - window.setSaveButtonEnabled(false); final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); if (distSet != null) { distNameTextField.setValue(distSet.getName()); @@ -508,23 +403,24 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { if (distSet.getDescription() != null) { descTextArea.setValue(distSet.getDescription()); } - setOriginalDistName(distSet.getName()); - setOriginalDistVersion(distSet.getVersion()); - setOriginalDistDescription(distSet.getDescription()); - setOriginalReqMigStep(distSet.isRequiredMigrationStep()); - setOriginalDistSetTYpe(distSet.getType().getName()); - addListeners(); + originalDistName = distSet.getName(); + originalDistVersion = distSet.getVersion(); + originalDistDescription = distSet.getDescription(); + originalReqMigStep = distSet.isRequiredMigrationStep(); + originalDistSetType = distSet.getType().getName(); + window.updateEditedFields(distsetTypeNameComboBox.getId(), Boolean.FALSE); + window.updateEditedFields(reqMigStepCheckbox.getId(), Boolean.FALSE); } } public CommonDialogWindow getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); - populateRequiredComponents(); - resetComponents(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, getMandatoryFields(), null, i18n); + null, getMandatoryFields(), getEditedFields(), i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); + populateRequiredComponents(); + resetComponents(); return window; } @@ -534,12 +430,22 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), Boolean.FALSE); } } return requiredFields; } + private Map getEditedFields() { + final Map editedFields = new HashMap<>(); + editedFields.put(distsetTypeNameComboBox.getId(), Boolean.FALSE); + editedFields.put(distNameTextField.getId(), Boolean.FALSE); + editedFields.put(distVersionTextField.getId(), Boolean.FALSE); + editedFields.put(descTextArea.getId(), Boolean.FALSE); + editedFields.put(reqMigStepCheckbox.getId(), Boolean.FALSE); + return editedFields; + } + /** * Populate DistributionSet Type name combo. */ @@ -549,12 +455,4 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { distsetTypeNameComboBox.setValue(getDefaultDistributionSetType().getName()); } - /** - * @param originalDistSetTYpe - * the originalDistSetTYpe to set - */ - public void setOriginalDistSetTYpe(final String originalDistSetType) { - this.originalDistSetType = originalDistSetType; - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java index 3bee67345..0bcee9d09 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java @@ -32,9 +32,7 @@ import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.UI; /** - * * Class for Create/Update Tag Layout of distribution set - * */ @SpringComponent @ViewScope @@ -98,7 +96,6 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat updateExistingTag(existingDistTag); } } - window.setSaveButtonEnabled(false); } /** @@ -157,10 +154,11 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat @Override public void setTagDetails(final String distTagSelected) { tagName.setValue(distTagSelected); + setOriginalTagName(distTagSelected); final DistributionSetTag selectedDistTag = tagManagement.findDistributionSetTag(distTagSelected); if (null != selectedDistTag) { tagDesc.setValue(selectedDistTag.getDescription()); - setTagDescOriginal(selectedDistTag.getDescription()); + setOriginalTagDesc(selectedDistTag.getDescription()); if (null == selectedDistTag.getColour()) { setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 07360ed70..6c2193adb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -14,7 +14,6 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.model.Target; @@ -35,15 +34,12 @@ import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; -import com.vaadin.event.FieldEvents.TextChangeEvent; -import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.VaadinSessionScope; import com.vaadin.ui.AbstractField; import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Label; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; @@ -57,7 +53,7 @@ import com.vaadin.ui.themes.ValoTheme; @VaadinSessionScope public class TargetAddUpdateWindowLayout extends CustomComponent { private static final long serialVersionUID = -6659290471705262389L; - + @Autowired private I18N i18n; @@ -69,10 +65,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { @Autowired private transient UINotification uINotification; - + @Autowired private transient EntityFactory entityFactory; - + private TextField controllerIDTextField; private TextField nameTextField; private TextArea descTextArea; @@ -81,47 +77,47 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private FormLayout formLayout; private CommonDialogWindow window; - private String oldTargetName; - private String oldTargetDesc; - + private String originalTargetName; + private String originalTargetDesc; + private String originalControllerId; + /** * Initialize the Add Update Window Component for Target. */ public void init() { - /* create components */ createRequiredComponents(); - /* display components in layout */ buildLayout(); - /* register all listeners related to the Window */ - addListeners(); setCompositionRoot(formLayout); } private void createRequiredComponents() { /* Textfield for controller Id */ - controllerIDTextField = SPUIComponentProvider.getTextField( i18n.get("prompt.target.id"), "", ValoTheme.TEXTFIELD_TINY, true, null, - i18n.get("prompt.target.id"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); + controllerIDTextField = SPUIComponentProvider.getTextField(i18n.get("prompt.target.id"), "", + ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("prompt.target.id"), true, + SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); controllerIDTextField.setId(SPUIComponentIdProvider.TARGET_ADD_CONTROLLER_ID); - controllerIDTextField.addTextChangeListener(this::listenerControllerIDTextFieldChanged); + controllerIDTextField + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalControllerId)); + controllerIDTextField + .addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, controllerIDTextField)); /* Textfield for target name */ - nameTextField = SPUIComponentProvider.getTextField( i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, false, null, - i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); + nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, + false, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.TARGET_ADD_NAME); + nameTextField.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTargetName)); /* Textarea for target description */ - descTextArea = SPUIComponentProvider.getTextArea( i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTFIELD_TINY, false, null, - i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); + descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", + ValoTheme.TEXTFIELD_TINY, false, null, i18n.get("textfield.description"), + SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.TARGET_ADD_DESC); descTextArea.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY); - } - - private void listenerControllerIDTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, controllerIDTextField); + descTextArea.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTargetDesc)); } private void buildLayout() { - + /* * The main layout of the window contains mandatory info, textboxes * (controller Id, name & description) and action buttons layout @@ -131,56 +127,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { formLayout.addComponent(controllerIDTextField); formLayout.addComponent(nameTextField); formLayout.addComponent(descTextArea); - + controllerIDTextField.focus(); } - private void addListeners() { - - addTargetNameChangeListner(); - addTargetDescChangeListner(); - } - - private void addTargetNameChangeListner() { - nameTextField.addTextChangeListener(new TextChangeListener() { - - /** - * - */ - private static final long serialVersionUID = 1761855781481115921L; - - @Override - public void textChange(final TextChangeEvent event) { - if (event.getText().equals(oldTargetName) && descTextArea.getValue().equals(oldTargetDesc)) { - window.setSaveButtonEnabled(false); - } else { - window.setSaveButtonEnabled(true); - } - - } - }); - } - - private void addTargetDescChangeListner() { - descTextArea.addTextChangeListener(new TextChangeListener() { - - /** - * - */ - private static final long serialVersionUID = 5770734934988115068L; - - @Override - public void textChange(final TextChangeEvent event) { - if (event.getText().equals(oldTargetDesc) && nameTextField.getValue().equals(oldTargetName)) { - window.setSaveButtonEnabled(false); - } else { - window.setSaveButtonEnabled(true); - } - - } - }); - } - /** * Update the Target if modified. */ @@ -210,7 +160,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } else { addNewTarget(); } - window.setSaveButtonEnabled(false); } private void discardTargetListner() { @@ -244,37 +193,49 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields(), null, i18n); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), + event -> discardTargetListner(), null, getMandatoryFields(), getEditedFields(), i18n); return window; } - + private Map getMandatoryFields() { final Map requiredFields = new HashMap<>(); final Iterator iterate = formLayout.iterator(); while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), Boolean.FALSE); } } return requiredFields; } - + + private Map getEditedFields() { + final Map editedFields = new HashMap<>(); + editedFields.put(controllerIDTextField.getId(), Boolean.FALSE); + editedFields.put(nameTextField.getId(), Boolean.FALSE); + editedFields.put(descTextArea.getId(), Boolean.FALSE); + return editedFields; + } + /** * clear all fields of Target Edit Window. */ public void resetComponents() { nameTextField.clear(); nameTextField.removeStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - controllerIDTextField.setEnabled(true); - controllerIDTextField.setReadOnly(false); + controllerIDTextField.setEnabled(Boolean.TRUE); controllerIDTextField.removeStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); controllerIDTextField.clear(); descTextArea.clear(); editTarget = Boolean.FALSE; + originalControllerId = null; + originalTargetDesc = null; + originalTargetName = null; + if (window != null) { - window.resetMandatoryAndEditedFields(); + window.reset(); } } @@ -282,7 +243,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { editTarget = Boolean.FALSE; window.close(); UI.getCurrent().removeWindow(window); - window.setSaveButtonEnabled(false); } private void setTargetValues(final Target target, final String name, final String description) { @@ -303,7 +263,8 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private boolean duplicateCheck(final String newControlllerId) { final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim()); if (existingTarget != null) { - uINotification.displayValidationError(i18n.get("message.target.duplicate.check", new Object[] {newControlllerId})); + uINotification.displayValidationError( + i18n.get("message.target.duplicate.check", new Object[] { newControlllerId })); return false; } else { return true; @@ -319,15 +280,15 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { editTarget = Boolean.TRUE; final Target target = targetManagement.findTargetByControllerID(controllerId); controllerIDTextField.setValue(target.getControllerId()); - controllerIDTextField.setReadOnly(Boolean.TRUE); + controllerIDTextField.setEnabled(Boolean.FALSE); nameTextField.setValue(target.getName()); if (target.getDescription() != null) { descTextArea.setValue(target.getDescription()); } - window.setSaveButtonEnabled(Boolean.FALSE); - oldTargetDesc = descTextArea.getValue(); - oldTargetName = nameTextField.getValue(); + originalTargetDesc = descTextArea.getValue(); + originalTargetName = nameTextField.getValue(); + originalControllerId = controllerIDTextField.getValue(); window.addStyleName("target-update-window"); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java index 81c0c72ae..781e13ef6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java @@ -88,10 +88,11 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa @Override public void setTagDetails(final String targetTagSelected) { tagName.setValue(targetTagSelected); + setOriginalTagName(targetTagSelected); final TargetTag selectedTargetTag = tagManagement.findTargetTag(targetTagSelected); if (null != selectedTargetTag) { tagDesc.setValue(selectedTargetTag.getDescription()); - setTagDescOriginal(selectedTargetTag.getDescription()); + setOriginalTagDesc(selectedTargetTag.getDescription()); if (null == selectedTargetTag.getColour()) { setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); @@ -115,7 +116,6 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa updateExistingTag(existingTag); } } - window.setSaveButtonEnabled(false); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index c1efa9f4b..18e06814a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -75,9 +75,7 @@ import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** - * * Rollout add or update popup layout. - * */ @SpringComponent @ViewScope @@ -150,19 +148,21 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextArea targetFilterQuery; - private Boolean updateMode = Boolean.FALSE; + private String originalDistributionSet; - private String distributionSetOriginal; + private Object originalActionGroup; - private Object actionGroupOriginal; + private String originalRolloutName; - private String rolloutNameOriginal; + private String originalErrorThreshold; - private String errorThresholdOriginal;; + private String originalTriggerThreshold; - private String triggerThresholdOriginal; + private String originalDescription; - private String descriptionOriginal; + private String originalTargetFilterQueryCombo; + + private String originalNoOfGroups; /** * Create components and layout. @@ -174,6 +174,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } public CommonDialogWindow getWindow() { + window = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields(), getEditedFields(), @@ -181,25 +182,14 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return window; } - public CommonDialogWindow createUpdateWindow() { - updateMode = Boolean.TRUE; - return getWindow(); - } - - public CommonDialogWindow createAddWindow() { - updateMode = Boolean.FALSE; - return getWindow(); - } - private Map getMandatoryFields() { final Map requiredFields = new HashMap<>(); - requiredFields.put(rolloutName.getId(), null); - requiredFields.put(distributionSet.getId(), null); - requiredFields.put(targetFilterQueryCombo.getId(), null); - requiredFields.put(noOfGroups.getId(), null); - requiredFields.put(triggerThreshold.getId(), null); - requiredFields.put(errorThreshold.getId(), null); - + requiredFields.put(rolloutName.getId(), Boolean.FALSE); + requiredFields.put(distributionSet.getId(), Boolean.FALSE); + requiredFields.put(targetFilterQueryCombo.getId(), Boolean.FALSE); + requiredFields.put(noOfGroups.getId(), Boolean.FALSE); + requiredFields.put(triggerThreshold.getId(), Boolean.FALSE); + requiredFields.put(errorThreshold.getId(), Boolean.FALSE); return requiredFields; } @@ -224,7 +214,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { rolloutForEdit = null; if (window != null) { - window.resetMandatoryAndEditedFields(); + window.reset(); } } @@ -319,13 +309,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private void listenerActionGroupValueChanged(final ValueChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryComboBox(event, actionTypeOptionGroupLayout.getActionTypeOptionGroup()); - } - if (event.getProperty().getValue() != null) { - window.checkChanges(actionTypeOptionGroupLayout.getActionTypeOptionGroup().getId(), - event.getProperty().getValue().toString(), actionGroupOriginal.toString()); - } + window.checkMandatoryEditedValue(event, actionTypeOptionGroupLayout.getActionTypeOptionGroup(), + originalActionGroup.toString()); } } @@ -346,9 +331,16 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { filterField.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY); filterField.setEnabled(false); filterField.setSizeUndefined(); + filterField.addValueChangeListener(event -> listenerFilterFieldValueChanged(event, filterField)); return filterField; } + private void listenerFilterFieldValueChanged(final ValueChangeEvent event, final TextArea filterField) { + if (window != null) { + window.setRequiredFieldWhenUpdate(event, targetFilterQueryCombo); + } + } + private Label createTotalTargetsLabel() { final Label targetCountLabel = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); targetCountLabel.addStyleName(ValoTheme.LABEL_TINY + " " + "rollout-target-count-message"); @@ -404,9 +396,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { totalTargetsCount = 0L; totalTargetsLabel.setVisible(false); } - onGroupNumberChange(); - - window.checkMandatoryComboBox(event, targetFilterQueryCombo); + onGroupNumberChange(event); + window.setRequiredFieldWhenUpdate(event, targetFilterQueryCombo); + window.checkMandatoryEditedValue(event, targetFilterQueryCombo, originalTargetFilterQueryCombo); } private String getTotalTargetMessage() { @@ -618,11 +610,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private void listenerDescriptionTextFieldChanged(final TextChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryTextField(event, description); - return; - } - window.checkChanges(description.getId(), event.getText(), descriptionOriginal); + window.checkMandatoryEditedTextField(event, originalDescription); } } @@ -633,16 +621,19 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { errorField.setMaxLength(7); errorField.setSizeUndefined(); errorField.addTextChangeListener(this::listenerErrorThresholdTextFieldChanged); + errorField.addValueChangeListener(event -> listenerErrorThresholdValueChanged(event, errorField)); return errorField; } private void listenerErrorThresholdTextFieldChanged(final TextChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryTextField(event, errorThreshold); - return; - } - window.checkChanges(errorThreshold.getId(), event.getText(), errorThresholdOriginal); + window.checkMandatoryEditedTextField(event, originalErrorThreshold); + } + } + + private void listenerErrorThresholdValueChanged(final ValueChangeEvent event, final TextField errorField) { + if (window != null) { + window.setRequiredFieldWhenUpdate(event, errorField); } } @@ -653,16 +644,19 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { thresholdField.setSizeUndefined(); thresholdField.setMaxLength(3); thresholdField.addTextChangeListener(this::listenerTriggerThresholdTextFieldChanged); + thresholdField.addValueChangeListener(event -> listenerTriggerTresholdValueChanged(event, thresholdField)); return thresholdField; } + private void listenerTriggerTresholdValueChanged(final ValueChangeEvent event, final TextField thresholdField) { + if (window != null) { + window.setRequiredFieldWhenUpdate(event, thresholdField); + } + } + private void listenerTriggerThresholdTextFieldChanged(final TextChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryTextField(event, triggerThreshold); - return; - } - window.checkChanges(triggerThreshold.getId(), event.getText(), triggerThresholdOriginal); + window.checkMandatoryEditedTextField(event, originalTriggerThreshold); } } @@ -672,28 +666,27 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroupsField.addValidator(new GroupNumberValidator()); noOfGroupsField.setSizeUndefined(); noOfGroupsField.setMaxLength(3); - noOfGroupsField.addValueChangeListener(evevt -> onGroupNumberChange()); + noOfGroupsField.addValueChangeListener(this::onGroupNumberChange); noOfGroupsField.addTextChangeListener(this::listenerNoOfGroupsTextFieldChanged); return noOfGroupsField; } private void listenerNoOfGroupsTextFieldChanged(final TextChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryTextField(event, noOfGroups); - return; - } - window.checkChanges(noOfGroups.getId(), event.getText(), noOfGroups.getValue()); + window.checkMandatoryEditedTextField(event, originalNoOfGroups); } } - private void onGroupNumberChange() { + private void onGroupNumberChange(final ValueChangeEvent event) { if (noOfGroups.isValid() && !Strings.isNullOrEmpty(noOfGroups.getValue())) { groupSizeLabel.setValue(getTargetPerGroupMessage(String.valueOf(getGroupSize()))); groupSizeLabel.setVisible(true); } else { groupSizeLabel.setVisible(false); } + if (window != null) { + window.setRequiredFieldWhenUpdate(event, noOfGroups); + } } private ComboBox createDistributionSetCombo() { @@ -710,14 +703,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private void listenerDistributionSetChanged(final ValueChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryComboBox(event, distributionSet); - return; - } - if (event.getProperty().getValue() != null) { - window.checkChanges(distributionSet.getId(), event.getProperty().getValue().toString(), - distributionSetOriginal); - } + window.checkMandatoryEditedValue(event, distributionSet, originalDistributionSet); } } @@ -732,7 +718,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return new LazyQueryContainer( new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_DIST_ID_NAME), distributionQF); - } private TextField createRolloutNameField() { @@ -740,16 +725,19 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { rolloutNameField.setId(SPUIComponentIdProvider.ROLLOUT_NAME_FIELD_ID); rolloutNameField.setSizeUndefined(); rolloutNameField.addTextChangeListener(this::listenerRolloutNameTextFieldChanged); + rolloutNameField.addValueChangeListener(event -> listenerRolloutNameValueChanged(event, rolloutNameField)); return rolloutNameField; } private void listenerRolloutNameTextFieldChanged(final TextChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryTextField(event, rolloutName); - return; - } - window.checkChanges(rolloutName.getId(), event.getText(), rolloutNameOriginal); + window.checkMandatoryEditedTextField(event, originalRolloutName); + } + } + + private void listenerRolloutNameValueChanged(final ValueChangeEvent event, final TextField rolloutNameField) { + if (window != null) { + window.setRequiredFieldWhenUpdate(event, rolloutNameField); } } @@ -851,7 +839,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { description.setValue(rolloutForEdit.getDescription()); distributionSet.setValue(DistributionSetIdName.generate(rolloutForEdit.getDistributionSet())); final List rolloutGroups = rolloutForEdit.getRolloutGroups(); - setThresoldValues(rolloutGroups); + setThresholdValues(rolloutGroups); setActionType(rolloutForEdit); if (rolloutForEdit.getStatus() != RolloutStatus.READY) { disableRequiredFieldsOnEdit(); @@ -870,30 +858,28 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void setOriginalValues() { - distributionSetOriginal = distributionSet.getValue().toString(); - actionGroupOriginal = actionTypeOptionGroupLayout.getActionTypeOptionGroup().getValue(); - rolloutNameOriginal = rolloutName.getValue(); - triggerThresholdOriginal = triggerThreshold.getValue(); - errorThresholdOriginal = errorThreshold.getValue(); - descriptionOriginal = description.getValue(); + originalDistributionSet = distributionSet.getValue().toString(); + originalActionGroup = actionTypeOptionGroupLayout.getActionTypeOptionGroup().getValue(); + originalRolloutName = rolloutName.getValue(); + originalTriggerThreshold = triggerThreshold.getValue(); + originalErrorThreshold = errorThreshold.getValue(); + originalDescription = description.getValue(); + originalNoOfGroups = noOfGroups.getValue(); + if (targetFilterQueryCombo.getValue() != null) { + originalTargetFilterQueryCombo = targetFilterQueryCombo.getValue().toString(); + } } private Map getEditedFields() { final Map changeMap = new HashMap<>(); - if (rolloutForEdit == null) { - return changeMap; - } - if (rolloutForEdit.getStatus() != RolloutStatus.READY) { - changeMap.put(rolloutName.getId(), Boolean.FALSE); - changeMap.put(description.getId(), Boolean.FALSE); - } else { - changeMap.put(rolloutName.getId(), Boolean.FALSE); - changeMap.put(distributionSet.getId(), Boolean.FALSE); - changeMap.put(triggerThreshold.getId(), Boolean.FALSE); - changeMap.put(errorThreshold.getId(), Boolean.FALSE); - changeMap.put(description.getId(), Boolean.FALSE); - changeMap.put(actionTypeOptionGroupLayout.getActionTypeOptionGroup().getId(), Boolean.FALSE); - } + changeMap.put(rolloutName.getId(), Boolean.FALSE); + changeMap.put(distributionSet.getId(), Boolean.FALSE); + changeMap.put(targetFilterQueryCombo.getId(), Boolean.FALSE); + changeMap.put(noOfGroups.getId(), Boolean.FALSE); + changeMap.put(triggerThreshold.getId(), Boolean.FALSE); + changeMap.put(errorThreshold.getId(), Boolean.FALSE); + changeMap.put(description.getId(), Boolean.FALSE); + changeMap.put(actionTypeOptionGroupLayout.getActionTypeOptionGroup().getId(), Boolean.FALSE); return changeMap; } @@ -933,7 +919,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { /** * @param rolloutGroups */ - private void setThresoldValues(final List rolloutGroups) { + private void setThresholdValues(final List rolloutGroups) { if (null != rolloutGroups && !rolloutGroups.isEmpty()) { errorThreshold.setValue(rolloutGroups.get(0).getErrorConditionExp()); triggerThreshold.setValue(rolloutGroups.get(0).getSuccessConditionExp()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index d3b17da5f..b40c3d93d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -67,9 +67,7 @@ import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent; import com.vaadin.ui.renderers.HtmlRenderer; /** - * * Rollout list grid component. - * */ @SpringComponent @ViewScope @@ -159,7 +157,6 @@ public class RolloutListGrid extends AbstractGrid { } item.getItemProperty(ROLLOUT_RENDERER_DATA) .setValue(new RolloutRendererData(rollout.getName(), rollout.getStatus().toString())); - } @Override @@ -200,7 +197,6 @@ public class RolloutListGrid extends AbstractGrid { rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.ACTION, String.class, FontAwesome.CIRCLE_O.getHtml(), false, false); - } @Override @@ -292,7 +288,6 @@ public class RolloutListGrid extends AbstractGrid { for (final Object propertyId : columnsToBeHidden) { getColumn(propertyId).setHidden(true); } - } @Override @@ -315,7 +310,6 @@ public class RolloutListGrid extends AbstractGrid { final RolloutRenderer customObjectRenderer = new RolloutRenderer(RolloutRendererData.class); customObjectRenderer.addClickListener(this::onClickOfRolloutName); getColumn(ROLLOUT_RENDERER_DATA).setRenderer(customObjectRenderer); - } private void createRolloutStatusToFontMap() { @@ -437,8 +431,8 @@ public class RolloutListGrid extends AbstractGrid { } private void onUpdate(final ContextMenuData contextMenuData) { + final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(); addUpdateRolloutWindow.populateData(contextMenuData.getRolloutId()); - final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.createUpdateWindow(); addTargetWindow.setCaption(i18n.get("caption.update.rollout")); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); @@ -684,7 +678,6 @@ public class RolloutListGrid extends AbstractGrid { public Class getPresentationType() { return String.class; } - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java index 22c57740f..1a3d2d7a5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java @@ -92,7 +92,7 @@ public class RolloutListHeader extends AbstractGridHeader { @Override protected void addNewItem(final ClickEvent event) { addUpdateRolloutWindow.resetComponents(); - final Window addTargetWindow = addUpdateRolloutWindow.createAddWindow(); + final Window addTargetWindow = addUpdateRolloutWindow.getWindow(); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); From 8578f6726b24f6f8b309a9453b55f680a2700c19 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Mon, 27 Jun 2016 11:20:57 +0200 Subject: [PATCH 12/52] Return last throwable in response Signed-off-by: SirWayne --- .../exception/ResponseExceptionHandler.java | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java index 13e214c45..3a6250209 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java @@ -9,17 +9,20 @@ package org.eclipse.hawkbit.rest.exception; import java.util.EnumMap; +import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; -import org.apache.tomcat.util.http.fileupload.FileUploadException; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerRtException; import org.eclipse.hawkbit.repository.exception.MultiPartFileUploadException; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ResourceLoader; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; @@ -27,6 +30,8 @@ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.multipart.MultipartException; +import com.google.common.collect.Iterables; + /** * General controller advice for exception handling. */ @@ -37,6 +42,9 @@ public class ResponseExceptionHandler { private static final Map ERROR_TO_HTTP_STATUS = new EnumMap<>(SpServerError.class); private static final HttpStatus DEFAULT_RESPONSE_STATUS = HttpStatus.INTERNAL_SERVER_ERROR; + @Autowired + private ResourceLoader resourceLoader; + static { ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_ENTITY_NOT_EXISTS, HttpStatus.NOT_FOUND); ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_ENTITY_ALRREADY_EXISTS, HttpStatus.CONFLICT); @@ -135,13 +143,8 @@ public class ResponseExceptionHandler { logRequest(request, ex); - Throwable responseCause = ex; - - final Throwable searchForCause = searchForCause(ex, FileUploadException.class); - if (searchForCause != null) { - responseCause = searchForCause; - } - + final List throwables = ExceptionUtils.getThrowableList(ex); + final Throwable responseCause = Iterables.getLast(throwables); final ExceptionInfo response = createExceptionInfo(new MultiPartFileUploadException(responseCause)); return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); } @@ -150,19 +153,6 @@ public class ResponseExceptionHandler { LOG.debug("Handling exception {} of request {}", ex.getClass().getName(), request.getRequestURL()); } - private static Throwable searchForCause(final Throwable t, final Class lookFor) { - if (t == null || t.getCause() == null) { - return null; - } - - final Throwable cause = t.getCause(); - - if (cause.getClass().equals(lookFor)) { - return cause; - } - return searchForCause(cause, lookFor); - } - private ExceptionInfo createExceptionInfo(final Exception ex) { final ExceptionInfo response = new ExceptionInfo(); response.setMessage(ex.getMessage()); From c4fcdea0e0290ab4c7f857a557334b3df007bb7e Mon Sep 17 00:00:00 2001 From: SirWayne Date: Mon, 27 Jun 2016 12:24:29 +0200 Subject: [PATCH 13/52] Remove resouce loader Signed-off-by: SirWayne --- .../hawkbit/rest/exception/ResponseExceptionHandler.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java index 3a6250209..02a48ef78 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java @@ -21,8 +21,6 @@ import org.eclipse.hawkbit.repository.exception.MultiPartFileUploadException; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.ResourceLoader; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; @@ -42,9 +40,6 @@ public class ResponseExceptionHandler { private static final Map ERROR_TO_HTTP_STATUS = new EnumMap<>(SpServerError.class); private static final HttpStatus DEFAULT_RESPONSE_STATUS = HttpStatus.INTERNAL_SERVER_ERROR; - @Autowired - private ResourceLoader resourceLoader; - static { ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_ENTITY_NOT_EXISTS, HttpStatus.NOT_FOUND); ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_ENTITY_ALRREADY_EXISTS, HttpStatus.CONFLICT); From 6692f92c61558146a78039eea2e2521e13a6bcf3 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 27 Jun 2016 12:33:07 +0200 Subject: [PATCH 14/52] delete unused method Signed-off-by: Melanie Retter --- .../CreateUpdateSoftwareTypeLayout.java | 7 ------- .../hawkbit/ui/common/CommonDialogWindow.java | 3 +-- .../CreateUpdateDistSetTypeLayout.java | 21 ++++++++----------- .../ui/layouts/CreateUpdateTypeLayout.java | 20 ------------------ ...eateUpdateDistributionTagLayoutWindow.java | 15 ++++++------- .../CreateUpdateTargetTagLayoutWindow.java | 14 ++++++------- 6 files changed, 22 insertions(+), 58 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index d8b32efc4..0c47772ea 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -223,11 +223,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout @Override protected void save(final ClickEvent event) { - if (!mandatoryValuesPresent()) { - window.setSaveButtonEnabled(false); - return; - } - final SoftwareModuleType existingSMTypeByKey = swTypeManagementService .findSoftwareModuleTypeByKey(typeKey.getValue()); final SoftwareModuleType existingSMTypeByName = swTypeManagementService @@ -237,10 +232,8 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout createNewSWModuleType(); } } else { - updateSWModuleType(existingSMTypeByName); } - // window.setSaveButtonEnabled(false); } private void createNewSWModuleType() { 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 index 7602f0a83..f6ff9e553 100644 --- 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 @@ -127,7 +127,7 @@ public class CommonDialogWindow extends Window implements Serializable { public void checkMandatoryEditedTextField(final TextChangeEvent event, final String originalValue) { final Component component = event.getComponent(); if (!(component instanceof AbstractComponent)) { - throw new IllegalStateException("Only AbstractComponent not allow"); + throw new IllegalStateException("Only AbstractComponent are allowed"); } if (requiredFields.containsKey(component.getId())) { @@ -209,7 +209,6 @@ public class CommonDialogWindow extends Window implements Serializable { * Boolean if field is filled */ public void updateRequiredFields(final String fieldId, final Boolean filled) { - requiredFields.put(fieldId, filled); checkSaveButtonEnabled(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 9c6486200..4a566cb51 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -639,19 +639,16 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout @Override protected void save(final ClickEvent event) { - - if (mandatoryValuesPresent()) { - final DistributionSetType existingDistTypeByKey = distributionSetManagement - .findDistributionSetTypeByKey(typeKey.getValue()); - final DistributionSetType existingDistTypeByName = distributionSetManagement - .findDistributionSetTypeByName(tagName.getValue()); - if (optiongroup.getValue().equals(createTypeStr)) { - if (!checkIsDuplicateByKey(existingDistTypeByKey) && !checkIsDuplicate(existingDistTypeByName)) { - createNewDistributionSetType(); - } - } else { - updateDistributionSetType(existingDistTypeByKey); + final DistributionSetType existingDistTypeByKey = distributionSetManagement + .findDistributionSetTypeByKey(typeKey.getValue()); + final DistributionSetType existingDistTypeByName = distributionSetManagement + .findDistributionSetTypeByName(tagName.getValue()); + if (optiongroup.getValue().equals(createTypeStr)) { + if (!checkIsDuplicateByKey(existingDistTypeByKey) && !checkIsDuplicate(existingDistTypeByName)) { + createNewDistributionSetType(); } + } else { + updateDistributionSetType(existingDistTypeByKey); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index 556347e4f..6ede668b0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -17,9 +17,7 @@ import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import com.google.common.base.Strings; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; @@ -289,24 +287,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { return Boolean.FALSE; } - @Override - protected Boolean mandatoryValuesPresent() { - if (Strings.isNullOrEmpty(tagName.getValue()) || Strings.isNullOrEmpty(typeKey.getValue())) { - if (optiongroup.getValue().equals(createTypeStr)) { - displayValidationError(SPUILabelDefinitions.MISSING_TYPE_NAME_KEY); - } - if (optiongroup.getValue().equals(updateTypeStr)) { - if (null == tagNameComboBox.getValue()) { - displayValidationError(i18n.get("message.error.missing.tagName")); - } else { - displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME); - } - } - return Boolean.FALSE; - } - return Boolean.TRUE; - } - @Override protected void save(final ClickEvent event) { // is implemented in the inherited class diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java index 0bcee9d09..1522c19c3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java @@ -85,16 +85,13 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat */ @Override public void save(final ClickEvent event) { - if (mandatoryValuesPresent()) { - final DistributionSetTag existingDistTag = tagManagement.findDistributionSetTag(tagName.getValue()); - if (optiongroup.getValue().equals(createTagStr)) { - if (!checkIsDuplicate(existingDistTag)) { - createNewTag(); - } - } else { - - updateExistingTag(existingDistTag); + final DistributionSetTag existingDistTag = tagManagement.findDistributionSetTag(tagName.getValue()); + if (optiongroup.getValue().equals(createTagStr)) { + if (!checkIsDuplicate(existingDistTag)) { + createNewTag(); } + } else { + updateExistingTag(existingDistTag); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java index 781e13ef6..8bba7f2f2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java @@ -106,15 +106,13 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa @Override public void save(final ClickEvent event) { - if (mandatoryValuesPresent()) { - final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue()); - if (optiongroup.getValue().equals(createTagStr)) { - if (!checkIsDuplicate(existingTag)) { - createNewTag(); - } - } else { - updateExistingTag(existingTag); + final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue()); + if (optiongroup.getValue().equals(createTagStr)) { + if (!checkIsDuplicate(existingTag)) { + createNewTag(); } + } else { + updateExistingTag(existingTag); } } From 1436aae22a63100fca3f7cfb094e5d110b4cf6b8 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 27 Jun 2016 15:56:50 +0200 Subject: [PATCH 15/52] code review improvements Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 18 +--- .../CreateUpdateSoftwareTypeLayout.java | 22 +---- .../hawkbit/ui/common/CommonDialogWindow.java | 16 +--- .../CreateUpdateDistSetTypeLayout.java | 90 +++++++++---------- .../AbstractCreateUpdateTagLayout.java | 26 ++---- .../ui/layouts/CreateUpdateTypeLayout.java | 2 +- .../DistributionAddUpdateWindowLayout.java | 18 +--- .../TargetAddUpdateWindowLayout.java | 19 +--- .../ui/utils/CommonDialogWindowHelper.java | 32 +++++++ 9 files changed, 95 insertions(+), 148 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 7e3051555..140760bbb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.artifacts.smtable; import java.io.Serializable; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import org.eclipse.hawkbit.repository.EntityFactory; @@ -21,6 +20,7 @@ import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -34,9 +34,7 @@ import org.vaadin.spring.events.EventBus; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.AbstractField; import com.vaadin.ui.ComboBox; -import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; @@ -229,23 +227,11 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - getMandatoryFields(formLayout), geEditedFields(), i18n); + CommonDialogWindowHelper.getMandatoryFields(formLayout), geEditedFields(), i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); typeComboBox.focus(); } - private Map getMandatoryFields(final FormLayout formLayout) { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = formLayout.iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } - return requiredFields; - } - private Map geEditedFields() { final Map editedFields = new HashMap<>(); editedFields.put(typeComboBox.getId(), Boolean.FALSE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 0c47772ea..71581113d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -9,10 +9,7 @@ package org.eclipse.hawkbit.ui.artifacts.smtype; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; -import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; @@ -25,6 +22,7 @@ import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -37,10 +35,8 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Component; import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.components.colorpicker.ColorChangeListener; @@ -125,20 +121,8 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields(), - getEditedFields(), i18n); - } - - private Map getMandatoryFields() { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = getFormLayout().iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } - return requiredFields; + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, + CommonDialogWindowHelper.getMandatoryFields(getFormLayout()), getEditedFields(), i18n); } /** 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 index f6ff9e553..d80446ee8 100644 --- 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 @@ -127,7 +127,7 @@ public class CommonDialogWindow extends Window implements Serializable { public void checkMandatoryEditedTextField(final TextChangeEvent event, final String originalValue) { final Component component = event.getComponent(); if (!(component instanceof AbstractComponent)) { - throw new IllegalStateException("Only AbstractComponent are allowed"); + throw new IllegalStateException("Only AbstractComponents are allowed"); } if (requiredFields.containsKey(component.getId())) { @@ -155,10 +155,10 @@ public class CommonDialogWindow extends Window implements Serializable { if (requiredFields.containsKey(component.getId())) { setRequiredFieldChangeValue(component, isChangedValueNotNull); } - if (event.getProperty().getValue() != null) { - checkChanges(component.getId(), event.getProperty().getValue().toString(), originalValue); - } else { + if (event.getProperty().getValue() == null) { checkChanges(component.getId(), null, originalValue); + } else { + checkChanges(component.getId(), event.getProperty().getValue().toString(), originalValue); } checkSaveButtonEnabled(); } @@ -392,12 +392,4 @@ public class CommonDialogWindow extends Window implements Serializable { return buttonsLayout; } - public Map getRequiredFields() { - return requiredFields; - } - - public void setRequiredFields(final Map requiredFields) { - this.requiredFields = requiredFields; - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 4a566cb51..7c06493e5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -27,6 +27,7 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent.DistributionSetTypeEnum; import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -43,7 +44,6 @@ import com.vaadin.data.util.IndexedContainer; import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.AbstractField; import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; @@ -91,8 +91,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private IndexedContainer originalSelectedTableContainer; - private String originalTypeKey; - @Override protected void createRequiredComponents() { @@ -109,7 +107,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_KEY); - typeKey.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTypeKey)); + typeKey.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTypeKey())); typeKey.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, typeKey)); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", @@ -268,24 +266,26 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void addSMType() { final Set selectedIds = (Set) sourceTable.getValue(); - if (selectedIds != null && !selectedIds.isEmpty()) { - for (final Long id : selectedIds) { - addTargetTableData(id); - } - window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); + if (selectedIds == null) { + return; } + for (final Long id : selectedIds) { + addTargetTableData(id); + } + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); } private void removeSMType() { @SuppressWarnings("unchecked") final Set selectedIds = (Set) selectedTable.getValue(); - if (selectedIds != null && !selectedIds.isEmpty()) { - for (final Long id : selectedIds) { - addSourceTableData(id); - selectedTable.removeItem(id); - window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); - } + if (selectedIds == null) { + return; + } + for (final Long id : selectedIds) { + addSourceTableData(id); + selectedTable.removeItem(id); + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); } } @@ -294,6 +294,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout if (originalSelectedTableContainer == null) { originalSelectedTableContainer = new IndexedContainer(); } + // is new softwareModule added? for (final Iterator itemIterator = selectedTableContainer.getItemIds().iterator(); itemIterator.hasNext();) { final long itemId = (Long) itemIterator.next(); if (!originalSelectedTableContainer.containsId(itemId)) { @@ -302,6 +303,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } } + // is softwareModule removed and at least one softwareModule is selected for (final Iterator itemIterator = originalSelectedTableContainer.getItemIds().iterator(); itemIterator .hasNext();) { final long itemId = (Long) itemIterator.next(); @@ -311,9 +313,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } } - if (selectedTableContainer.size() > 0) { - window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); - } return Boolean.FALSE; } @@ -621,20 +620,20 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout @SuppressWarnings("unchecked") private void addTargetTableforUpdate(final SoftwareModuleType swModuleType, final boolean mandatory) { - Item saveTblitem; - if (selectedTableContainer != null) { - saveTblitem = selectedTableContainer.addItem(swModuleType.getId()); - sourceTable.removeItem(swModuleType.getId()); - saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); - saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); - final CheckBox mandatoryCheckbox = (CheckBox) selectedTableContainer - .getContainerProperty(swModuleType.getId(), DIST_TYPE_MANDATORY).getValue(); - mandatoryCheckbox.addValueChangeListener(this::listenerMandatoryCheckboxChanged); - - final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId()); - originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); - originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); + if (selectedTableContainer == null) { + return; } + final Item saveTblitem = selectedTableContainer.addItem(swModuleType.getId()); + sourceTable.removeItem(swModuleType.getId()); + saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); + saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); + final CheckBox mandatoryCheckbox = (CheckBox) selectedTableContainer + .getContainerProperty(swModuleType.getId(), DIST_TYPE_MANDATORY).getValue(); + mandatoryCheckbox.addValueChangeListener(this::listenerMandatoryCheckboxChanged); + + final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId()); + originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); + originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); } @Override @@ -660,15 +659,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout getEditedFields(), i18n); } - private Map getMandatoryFields() { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = getFormLayout().iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } + protected Map getMandatoryFields() { + final Map requiredFields = CommonDialogWindowHelper.getMandatoryFields(getFormLayout()); // Selected SoftwareModulesType requiredFields.put(selectedTable.getId(), Boolean.FALSE); return requiredFields; @@ -718,14 +710,14 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID); } - @Override - public String getOriginalTypeKey() { - return originalTypeKey; - } - - @Override - public void setOriginalTypeKey(final String originalTypeKey) { - this.originalTypeKey = originalTypeKey; - } + // @Override + // public String getOriginalTypeKey() { + // return originalTypeKey; + // } + // + // @Override + // public void setOriginalTypeKey(final String originalTypeKey) { + // this.originalTypeKey = originalTypeKey; + // } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 6beb7d5b7..5eb64773b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -9,7 +9,6 @@ package org.eclipse.hawkbit.ui.layouts; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import javax.annotation.PreDestroy; @@ -24,6 +23,7 @@ import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerLayout; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -38,11 +38,9 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.ComboBox; -import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.GridLayout; @@ -115,21 +113,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected void createWindow() { reset(); - setWindow( - SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, - this, this::save, this::discard, null, getMandatoryFields(), getEditedFields(), i18n)); - } - - private Map getMandatoryFields() { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = formLayout.iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), null); - } - } - return requiredFields; + setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, + CommonDialogWindowHelper.getMandatoryFields(formLayout), getEditedFields(), i18n)); } protected Map getEditedFields() { @@ -344,7 +330,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } - window.reset(); + if (window != null) { + window.reset(); + } // close the color picker layout tagPreviewBtnClicked = false; // reset the selected color - Set default color diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index 6ede668b0..e03e6b42d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -41,7 +41,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { protected String createTypeStr; protected String updateTypeStr; protected TextField typeKey; - protected String originalTypeKey; + private String originalTypeKey; public static final String TYPE_NAME_DYNAMIC_STYLE = "new-tag-name"; private static final String TYPE_DESC_DYNAMIC_STYLE = "new-tag-desc"; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 90dd8a6a6..b733dbe58 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -9,7 +9,6 @@ package org.eclipse.hawkbit.ui.management.dstable; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import javax.annotation.PostConstruct; @@ -27,6 +26,7 @@ import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.management.event.DragEvent; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -44,10 +44,8 @@ import org.vaadin.spring.events.EventBus; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.AbstractField; import com.vaadin.ui.CheckBox; import com.vaadin.ui.ComboBox; -import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.TextArea; @@ -417,25 +415,13 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, getMandatoryFields(), getEditedFields(), i18n); + null, CommonDialogWindowHelper.getMandatoryFields(formLayout), getEditedFields(), i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); populateRequiredComponents(); resetComponents(); return window; } - private Map getMandatoryFields() { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = formLayout.iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } - return requiredFields; - } - private Map getEditedFields() { final Map editedFields = new HashMap<>(); editedFields.put(distsetTypeNameComboBox.getId(), Boolean.FALSE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 6c2193adb..7cf047d5e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.management.targettable; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -23,6 +22,7 @@ import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.management.event.DragEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -36,8 +36,6 @@ import org.vaadin.spring.events.EventBus; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.VaadinSessionScope; -import com.vaadin.ui.AbstractField; -import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.TextArea; @@ -194,22 +192,11 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), - event -> discardTargetListner(), null, getMandatoryFields(), getEditedFields(), i18n); + event -> discardTargetListner(), null, CommonDialogWindowHelper.getMandatoryFields(formLayout), + getEditedFields(), i18n); return window; } - private Map getMandatoryFields() { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = formLayout.iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } - return requiredFields; - } - private Map getEditedFields() { final Map editedFields = new HashMap<>(); editedFields.put(controllerIDTextField.getId(), Boolean.FALSE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java new file mode 100644 index 000000000..c906a87dd --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java @@ -0,0 +1,32 @@ +package org.eclipse.hawkbit.ui.utils; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import com.vaadin.ui.AbstractField; +import com.vaadin.ui.Component; +import com.vaadin.ui.FormLayout; + +public class CommonDialogWindowHelper { + + /** + * Run through a FormLayout and collect all required Component's IDs in a + * Map + * + * @param formLayout + * Form to be analysed + * @return Map with all required component's IDs + */ + public static Map getMandatoryFields(final FormLayout formLayout) { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getId(), Boolean.FALSE); + } + } + return requiredFields; + } +} From 63cf97f6b46ea46772c43e60c0ea8e186d85c8bf Mon Sep 17 00:00:00 2001 From: SirWayne Date: Mon, 27 Jun 2016 17:02:44 +0200 Subject: [PATCH 16/52] Refactor Signed-off-by: SirWayne --- .../SoftwareModuleAddUpdateWindow.java | 17 +- .../hawkbit/ui/common/CommonDialogWindow.java | 305 ++++++------------ .../ui/components/SPUIComponentProvider.java | 7 +- .../ui/decorators/SPUIWindowDecorator.java | 9 +- 4 files changed, 111 insertions(+), 227 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 7e3051555..1d692b6d2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -139,31 +139,22 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_NAME); - nameTextField.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalNameValue)); - nameTextField.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, nameTextField)); /* version text field */ versionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); versionTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VERSION); - versionTextField - .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalVersionValue)); - versionTextField.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, versionTextField)); /* Vendor text field */ vendorTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.vendor"), "", ValoTheme.TEXTFIELD_TINY, false, null, i18n.get("textfield.vendor"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); vendorTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VENDOR); - vendorTextField - .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalVendorValue)); descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.ADD_SW_MODULE_DESCRIPTION); - descTextArea - .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalDescriptionValue)); typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true, null, i18n.get("upload.swmodule.type")); @@ -172,8 +163,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se typeComboBox.setNewItemsAllowed(Boolean.FALSE); typeComboBox.setImmediate(Boolean.TRUE); populateTypeNameCombo(); - typeComboBox.addValueChangeListener( - event -> window.checkMandatoryEditedValue(event, typeComboBox, originalComboBoxValue)); } private void populateTypeNameCombo() { @@ -195,10 +184,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se originalComboBoxValue = null; originalNameValue = null; originalVersionValue = null; - - if (window != null) { - window.reset(); - } } private void createWindow() { @@ -229,7 +214,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - getMandatoryFields(formLayout), geEditedFields(), i18n); + formLayout, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); typeComboBox.focus(); } 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 index f6ff9e553..d920d2f58 100644 --- 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 @@ -11,10 +11,12 @@ package org.eclipse.hawkbit.ui.common; import static com.google.common.base.Preconditions.checkNotNull; import java.io.Serializable; -import java.util.Collections; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Objects; -import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -25,17 +27,17 @@ import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.event.FieldEvents.TextChangeEvent; +import com.vaadin.event.FieldEvents.TextChangeNotifier; import com.vaadin.server.FontAwesome; -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.AbstractField; +import com.vaadin.ui.AbstractLayout; import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Component; +import com.vaadin.ui.FormLayout; import com.vaadin.ui.GridLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; @@ -45,12 +47,13 @@ import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; /** - * Superclass for pop-up-windows including a minimize and close icon in the - * upper right corner and a save and cancel button at the bottom. + * TODO: AbstractColorPicker und FlexibleOptionGroupItemComponent Superclass for + * pop-up-windows including a minimize and close icon in the upper right corner + * and a save and cancel button at the bottom. */ public class CommonDialogWindow extends Window implements Serializable { - private static final long serialVersionUID = -1321949234316858703L; + private static final long serialVersionUID = 1L; private final VerticalLayout mainLayout = new VerticalLayout(); @@ -72,9 +75,9 @@ public class CommonDialogWindow extends Window implements Serializable { private final ClickListener cancelButtonClickListener; - private Map requiredFields; + private Map orginalValues; - private Map editedFields; + private final List> allComponents; private final I18N i18n; @@ -94,7 +97,7 @@ public class CommonDialogWindow extends Window implements Serializable { */ public CommonDialogWindow(final String caption, final Component content, final String helpLink, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, - final Map requiredFields, final Map editedFields, final I18N i18n) { + final FormLayout formLayout, final I18N i18n) { checkNotNull(saveButtonClickListener); checkNotNull(cancelButtonClickListener); this.caption = caption; @@ -102,180 +105,21 @@ public class CommonDialogWindow extends Window implements Serializable { this.helpLink = helpLink; this.saveButtonClickListener = saveButtonClickListener; this.cancelButtonClickListener = cancelButtonClickListener; - this.requiredFields = requiredFields; - if (requiredFields == null) { - this.requiredFields = Collections.emptyMap(); - } - - this.editedFields = editedFields; - if (editedFields == null) { - this.editedFields = Collections.emptyMap(); - } + this.allComponents = getAllComponents(formLayout); this.i18n = i18n; init(); } - /** - * Checks if all mandatory fields are filled, and if there are changes in - * the current field. If yes, the save button will be enabled. - * - * @param event - * TextChangeEvent - * @param originalValue - * original Value of the current field - */ - public void checkMandatoryEditedTextField(final TextChangeEvent event, final String originalValue) { - final Component component = event.getComponent(); - if (!(component instanceof AbstractComponent)) { - throw new IllegalStateException("Only AbstractComponent are allowed"); - } - - if (requiredFields.containsKey(component.getId())) { - final boolean isTextChangeNotEmpty = StringUtils.isNotBlank(event.getText()); - setRequiredFieldChangeValue((AbstractComponent) component, isTextChangeNotEmpty); - } - checkChanges(component.getId(), event.getText(), originalValue); - checkSaveButtonEnabled(); + public void setSaveButtonEnabled(final boolean enabled) { + saveButton.setEnabled(enabled); } - /** - * Checks if all mandatory fields are filled, and if there are changes in - * the current field. If yes, the save button will be enabled. - * - * @param event - * ValueChangeEvent - * @param component - * current Component - * @param originalValue - * original Value of the current field - */ - public void checkMandatoryEditedValue(final ValueChangeEvent event, final AbstractComponent component, - final String originalValue) { - final boolean isChangedValueNotNull = event.getProperty().getValue() != null; - if (requiredFields.containsKey(component.getId())) { - setRequiredFieldChangeValue(component, isChangedValueNotNull); - } - if (event.getProperty().getValue() != null) { - checkChanges(component.getId(), event.getProperty().getValue().toString(), originalValue); - } else { - checkChanges(component.getId(), null, originalValue); - } - checkSaveButtonEnabled(); + public void setCancelButtonEnabled(final boolean enabled) { + cancelButton.setEnabled(enabled); } - /** - * Checks if all mandatory fields are filled, and if there are changes in - * the current field. (Boolean) If yes, the save button will be enabled. - * - * @param event - * ValueChangeEvent - * @param component - * current Component - * @param originalValue - * original Boolean Value of the current field - */ - public void checkMandatoryEditedValueBoolean(final ValueChangeEvent event, final AbstractComponent component, - final Boolean originalValue) { - final boolean isChangedValueNotNull = event.getProperty().getValue() != null; - if (requiredFields.containsKey(component.getId())) { - setRequiredFieldChangeValue(component, isChangedValueNotNull); - } - final Boolean changed = (Boolean) event.getProperty().getValue(); - editedFields.put(component.getId(), BooleanUtils.compare(changed, originalValue) != 0); - checkSaveButtonEnabled(); - } - - /** - * Updates the map of required fields if a value is set. (e.g. on Update - * when editing a component) - * - * @param event - * ValueChangeEvent - * @param component - * current Component - */ - public void setRequiredFieldWhenUpdate(final ValueChangeEvent event, final AbstractComponent component) { - final boolean isChangedValueNotNull = event.getProperty().getValue() != null; - setRequiredFieldChangeValue(component, isChangedValueNotNull); - } - - /** - * * Updates the map of required fields if a value is set. (e.g. on Update - * when editing a component) - * - * @param fieldId - * Id of the current component - * @param filled - * Boolean if field is filled - */ - public void updateRequiredFields(final String fieldId, final Boolean filled) { - requiredFields.put(fieldId, filled); - checkSaveButtonEnabled(); - } - - /** - * Checks if Color is changed - * - * @param fieldId - * Id of the current component - * @param newColor - * new Color - * @param oldColor - * old Color - */ - public void checkColorChange(final String fieldId, final Color newColor, final Color oldColor) { - editedFields.put(fieldId, !newColor.equals(oldColor)); - checkSaveButtonEnabled(); - } - - /** - * Updates the map of fields which can be edited. - * - * @param fieldId - * Id of the current component - * @param hasTextValueChanged - * Boolean if value has changed - */ - public void updateEditedFields(final String fieldId, final Boolean hasTextValueChanged) { - editedFields.put(fieldId, hasTextValueChanged); - checkSaveButtonEnabled(); - } - - /** - * Resets the map of mandatory and edited Fields and disable the save button - */ - public void reset() { - saveButton.setEnabled(false); - resetFields(); - } - - private void setRequiredFieldChangeValue(final AbstractComponent component, final boolean isTextChangeNotEmpty) { - requiredFields.put(component.getId(), isTextChangeNotEmpty); - } - - /** - * Checks the mandatory fields in the pop-up-window content. If all - * mandatory fields are filled the save button is enabled. Otherwise the - * save button is disabled. - */ - private void checkSaveButtonEnabled() { - saveButton.setEnabled(!requiredFields.containsValue(Boolean.FALSE) && editedFields.containsValue(Boolean.TRUE)); - } - - private void checkChanges(final String fieldName, final String newText, final String oldText) { - final boolean hasTextValueChanged = (StringUtils.isNotBlank(newText) && !newText.equals(oldText)) - || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText)); - editedFields.put(fieldName, hasTextValueChanged); - } - - private void resetFields() { - for (final Map.Entry entry : requiredFields.entrySet()) { - entry.setValue(Boolean.FALSE); - } - - for (final Map.Entry entry : editedFields.entrySet()) { - entry.setValue(Boolean.FALSE); - } + public HorizontalLayout getButtonsLayout() { + return buttonsLayout; } private final void init() { @@ -304,6 +148,85 @@ public class CommonDialogWindow extends Window implements Serializable { center(); setModal(true); addStyleName("fontsize"); + setOrginaleValues(); + addListeners(); + } + + private final void setOrginaleValues() { + for (final AbstractField field : allComponents) { + orginalValues.put(field, field.getValue()); + } + } + + private final void addListeners() { + for (final AbstractField field : allComponents) { + field.addValueChangeListener(event -> saveButton.setEnabled(isSaveButtonEnabled())); + if (field instanceof TextChangeNotifier) { + ((TextChangeNotifier) field) + .addTextChangeListener(event -> saveButton.setEnabled(isSaveButtonEnabled())); + } + } + + saveButton.addClickListener(event -> save()); + } + + private void save() { + saveButton.setEnabled(false); + setOrginaleValues(); + } + + private boolean isSaveButtonEnabled() { + return isMandatoyFieldNotEmpty() && isValuesChanged(); + } + + private boolean isValuesChanged() { + for (final AbstractField field : allComponents) { + final Object currentValue = field.getValue(); + final Object orginalValue = orginalValues.get(field); + + if (!Objects.equals(currentValue, orginalValue)) { + return true; + } + + } + return false; + } + + private boolean shouldMandatoryLabelShown() { + for (final AbstractField field : allComponents) { + if (field.isRequired()) { + return true; + } + } + + return false; + } + + private boolean isMandatoyFieldNotEmpty() { + for (final AbstractField field : allComponents) { + // TODO empty string. + if (field.isRequired() && field.getValue() == null) { + return false; + } + } + return true; + } + + private List> getAllComponents(final AbstractLayout abstractLayout) { + final List> components = new ArrayList<>(); + + final Iterator iterate = abstractLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractLayout) { + components.addAll(getAllComponents((AbstractLayout) c)); + } + + if (c instanceof AbstractField) { + components.add((AbstractField) c); + } + } + return components; } private HorizontalLayout createActionButtonsLayout() { @@ -324,7 +247,7 @@ public class CommonDialogWindow extends Window implements Serializable { private void createMandatoryLabel() { - if (!existsMandatoryFieldsInWindowContent()) { + if (!shouldMandatoryLabelShown()) { return; } @@ -366,10 +289,6 @@ public class CommonDialogWindow extends Window implements Serializable { buttonsLayout.setExpandRatio(saveButton, 1.0F); } - private boolean existsMandatoryFieldsInWindowContent() { - return !requiredFields.isEmpty(); - } - private void addHelpLink() { if (StringUtils.isEmpty(helpLink)) { @@ -380,24 +299,4 @@ public class CommonDialogWindow extends Window implements Serializable { buttonsLayout.setComponentAlignment(helpLinkComponent, Alignment.MIDDLE_RIGHT); } - public void setSaveButtonEnabled(final boolean enabled) { - saveButton.setEnabled(enabled); - } - - public void setCancelButtonEnabled(final boolean enabled) { - cancelButton.setEnabled(enabled); - } - - public HorizontalLayout getButtonsLayout() { - return buttonsLayout; - } - - public Map getRequiredFields() { - return requiredFields; - } - - public void setRequiredFields(final Map requiredFields) { - this.requiredFields = requiredFields; - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 3338124c5..d0e509f7e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -37,6 +37,7 @@ import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.CheckBox; import com.vaadin.ui.ComboBox; import com.vaadin.ui.Component; +import com.vaadin.ui.FormLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Link; @@ -153,10 +154,10 @@ public final class SPUIComponentProvider { */ public static CommonDialogWindow getWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, - final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields, final Map editedFields, final I18N i18n) { + final ClickListener cancelButtonClickListener, final String helpLink, final FormLayout formLayout, + final I18N i18n) { return SPUIWindowDecorator.getDeocratedWindow(caption, id, type, content, saveButtonClickListener, - cancelButtonClickListener, helpLink, requiredFields, editedFields, i18n); + cancelButtonClickListener, helpLink, formLayout, i18n); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java index d2d7740d3..242d8931a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java @@ -8,8 +8,6 @@ */ package org.eclipse.hawkbit.ui.decorators; -import java.util.Map; - import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; @@ -17,6 +15,7 @@ import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Component; +import com.vaadin.ui.FormLayout; import com.vaadin.ui.Window; /** @@ -47,11 +46,11 @@ public final class SPUIWindowDecorator { */ public static CommonDialogWindow getDeocratedWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, - final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields, final Map editedFields, final I18N i18n) { + final ClickListener cancelButtonClickListener, final String helpLink, final FormLayout formLayout, + final I18N i18n) { final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener, requiredFields, editedFields, i18n); + cancelButtonClickListener, formLayout, i18n); if (null != id) { window.setId(id); } From 4fdeb1661aafcf74f1e0ecb63a09c2642c05ec62 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 28 Jun 2016 15:02:36 +0200 Subject: [PATCH 17/52] Add require textfielder to rollouts and remove colorpicker Signed-off-by: SirWayne --- .../CreateUpdateSoftwareTypeLayout.java | 34 ------------- .../hawkbit/ui/common/CommonDialogWindow.java | 2 +- .../CreateUpdateDistSetTypeLayout.java | 36 -------------- .../rollout/AddUpdateRolloutWindowLayout.java | 48 +++++++------------ 4 files changed, 18 insertions(+), 102 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 2c6dcd702..3ca0e3631 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -11,13 +11,11 @@ package org.eclipse.hawkbit.ui.artifacts.smtype; import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -34,7 +32,6 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.Alignment; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; @@ -266,37 +263,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout } - /** - * Open color picker on click of preview button. Auto select the color based - * on target tag if already selected. - */ - @Override - protected void previewButtonClicked() { - if (!tagPreviewBtnClicked) { - final String selectedOption = (String) optiongroup.getValue(); - if (StringUtils.isNotEmpty(selectedOption) && selectedOption.equalsIgnoreCase(updateTypeStr)) { - if (null != tagNameComboBox.getValue()) { - final SoftwareModuleType typeSelected = swTypeManagementService - .findSoftwareModuleTypeByName(tagNameComboBox.getValue().toString()); - if (null != typeSelected) { - getColorPickerLayout().setSelectedColor(typeSelected.getColour() != null - ? ColorPickerHelper.rgbToColorConverter(typeSelected.getColour()) - : ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - } - } else { - getColorPickerLayout().setSelectedColor( - ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - } - } - getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); - mainLayout.addComponent(colorPickerLayout, 1, 0); - mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER); - } else { - mainLayout.removeComponent(colorPickerLayout); - } - tagPreviewBtnClicked = !tagPreviewBtnClicked; - } - @Override public void addColorChangeListener(final ColorChangeListener listener) { LOG.debug("inside addColorChangeListener"); 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 index e6fb5e957..db1c8bfdb 100644 --- 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 @@ -219,7 +219,7 @@ public class CommonDialogWindow extends Window implements Serializable { if (String.class.equals(field.getType())) { orginalValue = Strings.emptyToNull((String) orginalValue); - currentValue = Strings.emptyToNull((String) orginalValue); + currentValue = Strings.emptyToNull((String) currentValue); } if (!Objects.equals(orginalValue, currentValue)) { return true; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 6dcb1af0b..b33d7b087 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -654,33 +654,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout return requiredFields; } - @Override - protected void previewButtonClicked() { - if (!tagPreviewBtnClicked) { - final String selectedOption = (String) optiongroup.getValue(); - if (null != selectedOption && selectedOption.equalsIgnoreCase(updateTypeStr) - && null != tagNameComboBox.getValue()) { - - final DistributionSetType existedDistType = distributionSetManagement - .findDistributionSetTypeByKey(tagNameComboBox.getValue().toString()); - if (null != existedDistType) { - getColorPickerLayout().setSelectedColor(existedDistType.getColour() != null - ? ColorPickerHelper.rgbToColorConverter(existedDistType.getColour()) - : ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - } else { - getColorPickerLayout().setSelectedColor( - ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - } - } - getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); - mainLayout.addComponent(colorPickerLayout, 1, 0); - mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER); - } else { - mainLayout.removeComponent(colorPickerLayout); - } - tagPreviewBtnClicked = !tagPreviewBtnClicked; - } - @Override protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) { @@ -688,14 +661,5 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID); } - // @Override - // public String getOriginalTypeKey() { - // return originalTypeKey; - // } - // - // @Override - // public void setOriginalTypeKey(final String originalTypeKey) { - // this.originalTypeKey = originalTypeKey; - // } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 071b9c749..e03f72b1e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -146,22 +146,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextArea targetFilterQuery; - private String originalDistributionSet; - - private Object originalActionGroup; - - private String originalRolloutName; - - private String originalErrorThreshold; - - private String originalTriggerThreshold; - - private String originalDescription; - - private String originalTargetFilterQueryCombo; - - private String originalNoOfGroups; - /** * Create components and layout. */ @@ -172,7 +156,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } public CommonDialogWindow getWindow() { - + resetComponents(); window = SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); @@ -222,20 +206,35 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { addComponent(getMandatoryLabel("textfield.name"), 0, 0); addComponent(rolloutName, 1, 0); + rolloutName.setRequired(true); + addComponent(getMandatoryLabel("prompt.distribution.set"), 0, 1); addComponent(distributionSet, 1, 1); + distributionSet.setRequired(true); + addComponent(getMandatoryLabel("prompt.target.filter"), 0, 2); addComponent(targetFilterQueryCombo, 1, 2); + targetFilterQueryCombo.setRequired(true); + addComponent(totalTargetsLabel, 2, 2); + addComponent(getMandatoryLabel("prompt.number.of.groups"), 0, 3); addComponent(noOfGroups, 1, 3); + noOfGroups.setRequired(true); + addComponent(groupSizeLabel, 2, 3); + addComponent(getMandatoryLabel("prompt.tigger.threshold"), 0, 4); addComponent(triggerThreshold, 1, 4); + triggerThreshold.setRequired(true); + addComponent(getPercentHintLabel(), 2, 4); + addComponent(getMandatoryLabel("prompt.error.threshold"), 0, 5); addComponent(errorThreshold, 1, 5); + errorThreshold.setRequired(true); addComponent(errorThresholdOptionGroup, 2, 5); + addComponent(getLabel("textfield.description"), 0, 6); addComponent(description, 1, 6, 2, 6); addComponent(actionTypeOptionGroupLayout, 0, 7, 2, 7); @@ -752,20 +751,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { totalTargetsLabel.setValue(getTotalTargetMessage()); totalTargetsLabel.setVisible(true); - setOriginalValues(); - } - - private void setOriginalValues() { - originalDistributionSet = distributionSet.getValue().toString(); - originalActionGroup = actionTypeOptionGroupLayout.getActionTypeOptionGroup().getValue(); - originalRolloutName = rolloutName.getValue(); - originalTriggerThreshold = triggerThreshold.getValue(); - originalErrorThreshold = errorThreshold.getValue(); - originalDescription = description.getValue(); - originalNoOfGroups = noOfGroups.getValue(); - if (targetFilterQueryCombo.getValue() != null) { - originalTargetFilterQueryCombo = targetFilterQueryCombo.getValue().toString(); - } + window.setOrginaleValues(); } private void disableRequiredFieldsOnEdit() { From 7723c30ce4b1186f7d0b28fae3ab068236b2e740 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 28 Jun 2016 16:25:50 +0200 Subject: [PATCH 18/52] Fix window open issues and set values when a entity is selected Signed-off-by: SirWayne --- .../SoftwareModuleAddUpdateWindow.java | 40 ++++++----- .../hawkbit/ui/common/CommonDialogWindow.java | 34 ++++++++- .../CreateUpdateDistSetTypeLayout.java | 11 --- .../dstable/DistributionSetDetails.java | 3 +- .../dstable/DistributionSetTableHeader.java | 2 +- .../AbstractCreateUpdateTagLayout.java | 4 +- .../DistributionAddUpdateWindowLayout.java | 72 +++++++------------ .../dstable/DistributionDetails.java | 3 +- .../dstable/DistributionTableHeader.java | 2 +- .../ui/utils/CommonDialogWindowHelper.java | 32 --------- 10 files changed, 85 insertions(+), 118 deletions(-) delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 4c31aefec..73346454d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -10,6 +10,8 @@ package org.eclipse.hawkbit.ui.artifacts.smtable; import java.io.Serializable; +import javax.annotation.PostConstruct; + import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -39,7 +41,6 @@ import com.vaadin.ui.Label; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; -import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; /** @@ -84,6 +85,14 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private FormLayout formLayout; + /** + * Initialize Distribution Add and Edit Window. + */ + @PostConstruct + void init() { + createRequiredComponents(); + } + /** * Create window for new software module. * @@ -91,11 +100,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se * module. */ public CommonDialogWindow createAddSoftwareModuleWindow() { - - editSwModule = Boolean.FALSE; - createRequiredComponents(); - createWindow(); - return window; + return createUpdateSoftwareModuleWindow(null); } /** @@ -106,15 +111,11 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se * @return reference of {@link com.vaadin.ui.Window} to update software * module. */ - public Window createUpdateSoftwareModuleWindow(final Long baseSwModuleId) { - - editSwModule = Boolean.TRUE; + public CommonDialogWindow createUpdateSoftwareModuleWindow(final Long baseSwModuleId) { this.baseSwModuleId = baseSwModuleId; - createRequiredComponents(); + resetComponents(); + populateValuesOfSwModule(); createWindow(); - nameTextField.setEnabled(false); - versionTextField.setEnabled(false); - typeComboBox.setEnabled(false); return window; } @@ -162,12 +163,10 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se versionTextField.clear(); descTextArea.clear(); typeComboBox.clear(); + editSwModule = Boolean.FALSE; } private void createWindow() { - - resetComponents(); - final Label madatoryStarLabel = new Label("*"); madatoryStarLabel.setStyleName("v-caption v-required-field-indicator"); madatoryStarLabel.setWidth(null); @@ -184,11 +183,15 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se setCompositionRoot(formLayout); - populateValuesOfSwModule(); window = SPUIWindowDecorator.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, formLayout, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); + + nameTextField.setEnabled(!editSwModule); + versionTextField.setEnabled(!editSwModule); + typeComboBox.setEnabled(!editSwModule); + typeComboBox.focus(); } @@ -243,6 +246,9 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se * fill the data of a softwareModule in the content of the window */ private void populateValuesOfSwModule() { + if (baseSwModuleId == null) { + return; + } final SoftwareModule swModle = softwareManagement.findSoftwareModuleById(baseSwModuleId); nameTextField.setValue(swModle.getName()); versionTextField.setValue(swModle.getVersion()); 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 index db1c8bfdb..888fd1409 100644 --- 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 @@ -31,6 +31,8 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import com.google.common.base.Strings; +import com.vaadin.data.Container.ItemSetChangeEvent; +import com.vaadin.data.Container.ItemSetChangeListener; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.event.FieldEvents.TextChangeEvent; @@ -50,6 +52,7 @@ import com.vaadin.ui.GridLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Link; +import com.vaadin.ui.Table; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; @@ -132,6 +135,18 @@ public class CommonDialogWindow extends Window implements Serializable { for (final AbstractField field : allComponents) { removeTextListener(field); removeValueChangeListener(field); + removeItemSetChangeistener(field); + } + } + + private void removeItemSetChangeistener(final AbstractField field) { + if (!(field instanceof Table)) { + return; + } + for (final Object listener : field.getListeners(ItemSetChangeEvent.class)) { + if (listener instanceof ChangeListener) { + ((Table) field).removeItemSetChangeListener((ChangeListener) listener); + } } } @@ -186,8 +201,14 @@ public class CommonDialogWindow extends Window implements Serializable { public final void setOrginaleValues() { for (final AbstractField field : allComponents) { - orginalValues.put(field, field.getValue()); + Object value = field.getValue(); + + if (field instanceof Table) { + value = ((Table) field).getContainerDataSource().getItemIds(); + } + orginalValues.put(field, value); } + saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(null, null)); } @@ -197,6 +218,10 @@ public class CommonDialogWindow extends Window implements Serializable { if (field instanceof TextChangeNotifier) { ((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field)); } + + if (field instanceof Table) { + ((Table) field).addItemSetChangeListener(new ChangeListener(field)); + } } saveButton.addClickListener(event -> close()); @@ -360,7 +385,7 @@ public class CommonDialogWindow extends Window implements Serializable { return this.buttonsLayout; } - private class ChangeListener implements ValueChangeListener, TextChangeListener { + private class ChangeListener implements ValueChangeListener, TextChangeListener, ItemSetChangeListener { private final Field field; @@ -380,6 +405,11 @@ public class CommonDialogWindow extends Window implements Serializable { saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, field.getValue())); } + @Override + public void containerItemSetChange(final ItemSetChangeEvent event) { + saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, event.getContainer().getItemIds())); + } + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index b33d7b087..cc73e3467 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.distributions.disttype; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Set; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -18,7 +17,6 @@ import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -26,7 +24,6 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent.DistributionSetTypeEnum; import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; -import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -647,13 +644,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout return i18n.get("caption.add.type"); } - protected Map getMandatoryFields() { - final Map requiredFields = CommonDialogWindowHelper.getMandatoryFields(getFormLayout()); - // Selected SoftwareModulesType - requiredFields.put(selectedTable.getId(), Boolean.FALSE); - return requiredFields; - } - @Override protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) { @@ -661,5 +651,4 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID); } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java index 95441ae57..d51d4fb28 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java @@ -259,8 +259,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet @Override protected void onEdit(final ClickEvent event) { - distributionAddUpdateWindowLayout.populateValuesOfDistribution(getSelectedBaseEntityId()); - final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(); + final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(getSelectedBaseEntityId()); newDistWindow.setCaption(getI18n().get("caption.update.dist")); UI.getCurrent().addWindow(newDistWindow); newDistWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableHeader.java index 817b465c2..8f392101f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableHeader.java @@ -152,7 +152,7 @@ public class DistributionSetTableHeader extends AbstractTableHeader { @Override protected void addNewItem(final ClickEvent event) { - final Window newDistWindow = addUpdateWindowLayout.getWindow(); + final Window newDistWindow = addUpdateWindowLayout.getWindow(null); newDistWindow.setCaption(i18n.get("caption.add.new.dist")); UI.getCurrent().addWindow(newDistWindow); newDistWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 5b3266f02..8c85f63a5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -331,6 +331,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent comboLayout.removeComponent(tagNameComboBox); // Default green color + colorPickerLayout.setVisible(false); colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor()); colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor()); tagPreviewBtnClicked = false; @@ -424,9 +425,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor()); } - // TODO: - // window.checkColorChange(colorPickerLayout.getId(), - // colorPickerLayout.getSelectedColor(), originalSelectedColor); } protected void closeWindow() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 939753380..3e60a20ab 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -90,11 +90,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private boolean editDistribution = Boolean.FALSE; private Long editDistId; private CommonDialogWindow window; - private String originalDistName; - private String originalDistVersion; - private String originalDistDescription; - private Boolean originalReqMigStep; - private String originalDistSetType; private FormLayout formLayout; @@ -108,11 +103,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } private void buildLayout() { - - /* - * The main layout of the window contains mandatory info, textboxes - * (controller Id, name & description) and action buttons layout - */ addStyleName("lay-color"); setSizeUndefined(); @@ -354,50 +344,38 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { descTextArea.clear(); reqMigStepCheckbox.clear(); - originalDistDescription = null; - originalDistName = null; - originalDistSetType = null; - originalDistVersion = null; - originalReqMigStep = Boolean.FALSE; - } - private void populateRequiredComponents() { + private void populateValuesOfDistribution(final Long editDistId) { + this.editDistId = editDistId; + if (editDistId == null) { + return; + } + + final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); + if (distSet == null) { + return; + } + + editDistribution = Boolean.TRUE; + distNameTextField.setValue(distSet.getName()); + distVersionTextField.setValue(distSet.getVersion()); + if (distSet.getType().isDeleted()) { + distsetTypeNameComboBox.addItem(distSet.getType().getName()); + } + distsetTypeNameComboBox.setValue(distSet.getType().getName()); + reqMigStepCheckbox.setValue(distSet.isRequiredMigrationStep()); + if (distSet.getDescription() != null) { + descTextArea.setValue(distSet.getDescription()); + } populateDistSetTypeNameCombo(); } - /** - * populate data. - * - * @param editDistId - */ - public void populateValuesOfDistribution(final Long editDistId) { - this.editDistId = editDistId; - editDistribution = Boolean.TRUE; - final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); - if (distSet != null) { - distNameTextField.setValue(distSet.getName()); - distVersionTextField.setValue(distSet.getVersion()); - if (distSet.getType().isDeleted()) { - distsetTypeNameComboBox.addItem(distSet.getType().getName()); - } - distsetTypeNameComboBox.setValue(distSet.getType().getName()); - reqMigStepCheckbox.setValue(distSet.isRequiredMigrationStep()); - if (distSet.getDescription() != null) { - descTextArea.setValue(distSet.getDescription()); - } - originalDistName = distSet.getName(); - originalDistVersion = distSet.getVersion(); - originalDistDescription = distSet.getDescription(); - originalReqMigStep = distSet.isRequiredMigrationStep(); - originalDistSetType = distSet.getType().getName(); - } - } - - public CommonDialogWindow getWindow() { + public CommonDialogWindow getWindow(final Long editDistId) { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); - populateRequiredComponents(); resetComponents(); + + populateValuesOfDistribution(editDistId); window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), null, formLayout, i18n); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java index 0bf9ef81b..30ee80317 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java @@ -77,8 +77,7 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail @Override protected void onEdit(final ClickEvent event) { - distributionAddUpdateWindowLayout.populateValuesOfDistribution(getSelectedBaseEntityId()); - final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(); + final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(getSelectedBaseEntityId()); newDistWindow.setCaption(getI18n().get("caption.update.dist")); UI.getCurrent().addWindow(newDistWindow); newDistWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableHeader.java index b0ed19f8f..0e63ddb95 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableHeader.java @@ -154,7 +154,7 @@ public class DistributionTableHeader extends AbstractTableHeader { @Override protected void addNewItem(final ClickEvent event) { - final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(); + final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(null); newDistWindow.setCaption(i18n.get("caption.add.new.dist")); UI.getCurrent().addWindow(newDistWindow); newDistWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java deleted file mode 100644 index c906a87dd..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.eclipse.hawkbit.ui.utils; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import com.vaadin.ui.AbstractField; -import com.vaadin.ui.Component; -import com.vaadin.ui.FormLayout; - -public class CommonDialogWindowHelper { - - /** - * Run through a FormLayout and collect all required Component's IDs in a - * Map - * - * @param formLayout - * Form to be analysed - * @return Map with all required component's IDs - */ - public static Map getMandatoryFields(final FormLayout formLayout) { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = formLayout.iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } - return requiredFields; - } -} From 7e32cbd21c9a317e79e90b639a86f66fa5536b2b Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 28 Jun 2016 17:38:21 +0200 Subject: [PATCH 19/52] Add table items comparison to enable save button Signed-off-by: SirWayne --- hawkbit-ui/pom.xml | 4 ++ .../hawkbit/ui/common/CommonDialogWindow.java | 65 +++++++++++++------ pom.xml | 6 ++ 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/hawkbit-ui/pom.xml b/hawkbit-ui/pom.xml index 08d225c62..b90e36e88 100644 --- a/hawkbit-ui/pom.xml +++ b/hawkbit-ui/pom.xml @@ -200,6 +200,10 @@ org.springframework.security spring-security-web + + org.apache.commons + commons-collections4 + com.vaadin 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 index 888fd1409..7cba5df4a 100644 --- 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 @@ -12,6 +12,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -20,6 +21,7 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -31,6 +33,7 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import com.google.common.base.Strings; +import com.google.common.collect.Sets; import com.vaadin.data.Container.ItemSetChangeEvent; import com.vaadin.data.Container.ItemSetChangeListener; import com.vaadin.data.Property.ValueChangeEvent; @@ -204,7 +207,7 @@ public class CommonDialogWindow extends Window implements Serializable { Object value = field.getValue(); if (field instanceof Table) { - value = ((Table) field).getContainerDataSource().getItemIds(); + value = Sets.newHashSet(((Table) field).getContainerDataSource().getItemIds()); } orginalValues.put(field, value); } @@ -214,13 +217,15 @@ public class CommonDialogWindow extends Window implements Serializable { private final void addListeners() { for (final AbstractField field : allComponents) { - field.addValueChangeListener(new ChangeListener(field)); + if (field instanceof TextChangeNotifier) { ((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field)); } if (field instanceof Table) { ((Table) field).addItemSetChangeListener(new ChangeListener(field)); + } else { + field.addValueChangeListener(new ChangeListener(field)); } } @@ -236,17 +241,10 @@ public class CommonDialogWindow extends Window implements Serializable { private boolean isValuesChanged(final Component currentChangedComponent, final Object newValue) { for (final AbstractField field : allComponents) { - Object orginalValue = orginalValues.get(field); - Object currentValue = field.getValue(); - if (field.equals(currentChangedComponent)) { - currentValue = newValue; - } + final Object orginalValue = orginalValues.get(field); + final Object currentValue = getCurrentVaue(currentChangedComponent, newValue, field); - if (String.class.equals(field.getType())) { - orginalValue = Strings.emptyToNull((String) orginalValue); - currentValue = Strings.emptyToNull((String) currentValue); - } - if (!Objects.equals(orginalValue, currentValue)) { + if (!isValueEquals(field, orginalValue, currentValue)) { return true; } @@ -254,6 +252,33 @@ public class CommonDialogWindow extends Window implements Serializable { return false; } + private boolean isValueEquals(final AbstractField field, final Object orginalValue, final Object currentValue) { + if (Set.class.equals(field.getType())) { + return CollectionUtils.isEqualCollection(CollectionUtils.emptyIfNull((Collection) orginalValue), + CollectionUtils.emptyIfNull((Collection) currentValue)); + } + + if (String.class.equals(field.getType())) { + return Objects.equals(Strings.emptyToNull((String) orginalValue), + Strings.emptyToNull((String) currentValue)); + } + + return Objects.equals(orginalValue, currentValue); + } + + private Object getCurrentVaue(final Component currentChangedComponent, final Object newValue, + final AbstractField field) { + Object currentValue = field.getValue(); + if (field instanceof Table) { + currentValue = ((Table) field).getContainerDataSource().getItemIds(); + } + + if (field.equals(currentChangedComponent)) { + currentValue = newValue; + } + return currentValue; + } + private boolean shouldMandatoryLabelShown() { for (final AbstractField field : allComponents) { if (field.isRequired()) { @@ -269,17 +294,14 @@ public class CommonDialogWindow extends Window implements Serializable { .collect(Collectors.toList()); for (final AbstractField field : requiredComponents) { - Object value = field.getValue(); - if (field.equals(currentChangedComponent)) { - value = newValue; - } + Object value = getCurrentVaue(currentChangedComponent, newValue, field); if (String.class.equals(field.getType())) { value = Strings.emptyToNull((String) value); } if (Set.class.equals(field.getType())) { - value = emptyToNull((Set) value); + value = emptyToNull((Collection) value); } if (value == null) { @@ -290,7 +312,7 @@ public class CommonDialogWindow extends Window implements Serializable { } - private static Object emptyToNull(final Set c) { + private static Object emptyToNull(final Collection c) { return (c == null || c.isEmpty()) ? null : c; } @@ -407,7 +429,12 @@ public class CommonDialogWindow extends Window implements Serializable { @Override public void containerItemSetChange(final ItemSetChangeEvent event) { - saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, event.getContainer().getItemIds())); + if (!(field instanceof Table)) { + return; + } + final Table table = (Table) field; + saveButton.setEnabled( + isSaveButtonEnabledAfterValueChange(table, table.getContainerDataSource().getItemIds())); } } diff --git a/pom.xml b/pom.xml index 444883bba..5995b8faf 100644 --- a/pom.xml +++ b/pom.xml @@ -111,6 +111,7 @@ 1.1 1.1.1 3.4 + 4.0 20141113 2.0.0 @@ -560,6 +561,11 @@ commons-lang3 ${commons-lang3.version} + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + org.springframework.boot spring-boot-starter-test From 9ce6e43b876e9b5f27a3a2c81a7959457a92f1a2 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 28 Jun 2016 17:49:16 +0200 Subject: [PATCH 20/52] Set value if rollout is edited Signed-off-by: SirWayne --- .../dstable/DistributionAddUpdateWindowLayout.java | 6 +++--- .../rollout/rollout/AddUpdateRolloutWindowLayout.java | 10 +++++++--- .../hawkbit/ui/rollout/rollout/RolloutListGrid.java | 3 +-- .../hawkbit/ui/rollout/rollout/RolloutListHeader.java | 3 +-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 3e60a20ab..c2f125e3a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -348,6 +348,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private void populateValuesOfDistribution(final Long editDistId) { this.editDistId = editDistId; + if (editDistId == null) { return; } @@ -368,13 +369,12 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { if (distSet.getDescription() != null) { descTextArea.setValue(distSet.getDescription()); } - populateDistSetTypeNameCombo(); } public CommonDialogWindow getWindow(final Long editDistId) { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); resetComponents(); - + populateDistSetTypeNameCombo(); populateValuesOfDistribution(editDistId); window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), @@ -386,7 +386,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { /** * Populate DistributionSet Type name combo. */ - public void populateDistSetTypeNameCombo() { + private void populateDistSetTypeNameCombo() { distsetTypeNameComboBox.setContainerDataSource(getDistSetTypeLazyQueryContainer()); distsetTypeNameComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); distsetTypeNameComboBox.setValue(getDefaultDistributionSetType().getName()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index e03f72b1e..777682ff1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -155,8 +155,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { buildLayout(); } - public CommonDialogWindow getWindow() { + public CommonDialogWindow getWindow(final Long rolloutId) { resetComponents(); + populateData(rolloutId); window = SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); @@ -728,8 +729,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { * @param rolloutId * rollout id */ - public void populateData(final Long rolloutId) { - resetComponents(); + private void populateData(final Long rolloutId) { + if (rolloutId == null) { + return; + } + editRolloutEnabled = Boolean.TRUE; rolloutForEdit = rolloutManagement.findRolloutById(rolloutId); rolloutName.setValue(rolloutForEdit.getName()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index 97bd4bd35..db4fbb929 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -431,8 +431,7 @@ public class RolloutListGrid extends AbstractGrid { } private void onUpdate(final ContextMenuData contextMenuData) { - addUpdateRolloutWindow.populateData(contextMenuData.getRolloutId()); - final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(); + final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(contextMenuData.getRolloutId()); addTargetWindow.setCaption(i18n.get("caption.update.rollout")); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java index 1a3d2d7a5..49bb90100 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java @@ -91,8 +91,7 @@ public class RolloutListHeader extends AbstractGridHeader { @Override protected void addNewItem(final ClickEvent event) { - addUpdateRolloutWindow.resetComponents(); - final Window addTargetWindow = addUpdateRolloutWindow.getWindow(); + final Window addTargetWindow = addUpdateRolloutWindow.getWindow(null); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); From 8cd6e5d614b3f5c711d65f4fc82881e4c8391d1d Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 29 Jun 2016 14:20:40 +0200 Subject: [PATCH 21/52] Made queue declaration retry count configurable. Signed-off-by: Kai Zimmermann --- .../hawkbit/amqp/AmqpConfiguration.java | 13 ++--- .../amqp/AmqpMessageHandlerService.java | 34 ++++++------- .../eclipse/hawkbit/amqp/AmqpProperties.java | 23 +++++++++ ...gurableRabbitListenerContainerFactory.java | 49 +++++++++++++++++++ 4 files changed, 89 insertions(+), 30 deletions(-) create mode 100644 hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index 538f82213..11f892654 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -22,11 +22,11 @@ import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.FanoutExchange; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.QueueBuilder; -import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; import org.springframework.beans.factory.annotation.Autowired; @@ -268,15 +268,8 @@ public class AmqpConfiguration { * AMQP messages */ @Bean(name = { "listenerContainerFactory" }) - public SimpleRabbitListenerContainerFactory listenerContainerFactory() { - final SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory(); - containerFactory.setDefaultRequeueRejected(true); - containerFactory.setConnectionFactory(rabbitConnectionFactory); - containerFactory.setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal()); - containerFactory.setConcurrentConsumers(amqpProperties.getInitialConcurrentConsumers()); - containerFactory.setMaxConcurrentConsumers(amqpProperties.getMaxConcurrentConsumers()); - containerFactory.setPrefetchCount(amqpProperties.getPrefetchCount()); - return containerFactory; + public RabbitListenerContainerFactory listenerContainerFactory() { + return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory); } private static Map getTTLMaxArgsAuthenticationQueue() { diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index b003d316a..9636de5c7 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -138,9 +138,18 @@ public class AmqpMessageHandlerService extends BaseAmqpService { } @RabbitListener(queues = "${hawkbit.dmf.rabbitmq.authenticationReceiverQueue}", containerFactory = "listenerContainerFactory") - public Message onAuthenticationRequest(final Message message, - @Header(MessageHeaderKey.TENANT) final String tenant) { - return onAuthenticationRequest(message); + public Message onAuthenticationRequest(final Message message) { + checkContentTypeJson(message); + final SecurityContext oldContext = SecurityContextHolder.getContext(); + try { + return handleAuthentifiactionMessage(message); + } catch (final IllegalArgumentException ex) { + throw new AmqpRejectAndDontRequeueException("Invalid message!", ex); + } catch (final TenantNotExistException teex) { + throw new AmqpRejectAndDontRequeueException(teex); + } finally { + SecurityContextHolder.setContext(oldContext); + } } public Message onMessage(final Message message, final String type, final String tenant, final String virtualHost) { @@ -159,7 +168,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService { final EventTopic eventTopic = EventTopic.valueOf(topicValue); handleIncomingEvent(message, eventTopic); break; - default: logAndThrowMessageError(message, "No handle method was found for the given message type."); } @@ -173,20 +181,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService { return null; } - public Message onAuthenticationRequest(final Message message) { - checkContentTypeJson(message); - final SecurityContext oldContext = SecurityContextHolder.getContext(); - try { - return handleAuthentifiactionMessage(message); - } catch (final IllegalArgumentException ex) { - throw new AmqpRejectAndDontRequeueException("Invalid message!", ex); - } catch (final TenantNotExistException teex) { - throw new AmqpRejectAndDontRequeueException(teex); - } finally { - SecurityContextHolder.setContext(oldContext); - } - } - private Message handleAuthentifiactionMessage(final Message message) { final DownloadResponse authentificationResponse = new DownloadResponse(); final MessageProperties messageProperties = message.getMessageProperties(); @@ -414,7 +408,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { if (ArrayUtils.isNotEmpty(message.getMessageProperties().getCorrelationId())) { actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message correlation-id " - + message.getMessageProperties().getCorrelationId()); + + new String(message.getMessageProperties().getCorrelationId())); } actionStatus.setAction(action); @@ -466,7 +460,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { if (messageProperties.getContentType() != null && messageProperties.getContentType().contains("json")) { return; } - throw new IllegalArgumentException("Content-Type is not JSON compatible"); + throw new AmqpRejectAndDontRequeueException("Content-Type is not JSON compatible"); } void setControllerManagement(final ControllerManagement controllerManagement) { diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java index 888b204e7..56aa37772 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java @@ -68,6 +68,29 @@ public class AmqpProperties { */ private int initialConcurrentConsumers = 3; + /** + * The number of retry attempts when passive queue declaration fails. + * Passive queue declaration occurs when the consumer starts or, when + * consuming from multiple queues, when not all queues were available during + * initialization. + */ + private int declarationRetries = 50; + + /** + * @return the declarationRetries + */ + public int getDeclarationRetries() { + return declarationRetries; + } + + /** + * @param declarationRetries + * the declarationRetries to set + */ + public void setDeclarationRetries(final int declarationRetries) { + this.declarationRetries = declarationRetries; + } + public String getAuthenticationReceiverQueue() { return authenticationReceiverQueue; } diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java new file mode 100644 index 000000000..fd0a1d2a1 --- /dev/null +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.amqp; + +import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; + +/** + * {@link RabbitListenerContainerFactory} that can be configured through + * hawkBit's {@link AmqpProperties}. + * + */ +public class ConfigurableRabbitListenerContainerFactory extends SimpleRabbitListenerContainerFactory { + private final AmqpProperties amqpProperties; + + /** + * Constructor. + * + * @param rabbitConnectionFactory + * for the container factory + * @param amqpProperties + * to configure the container factory + */ + public ConfigurableRabbitListenerContainerFactory(final AmqpProperties amqpProperties, + final ConnectionFactory rabbitConnectionFactory) { + this.amqpProperties = amqpProperties; + setDefaultRequeueRejected(true); + setConnectionFactory(rabbitConnectionFactory); + setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal()); + setConcurrentConsumers(amqpProperties.getInitialConcurrentConsumers()); + setMaxConcurrentConsumers(amqpProperties.getMaxConcurrentConsumers()); + setPrefetchCount(amqpProperties.getPrefetchCount()); + + } + + @Override + protected void initializeContainer(final SimpleMessageListenerContainer instance) { + super.initializeContainer(instance); + instance.setDeclarationRetries(amqpProperties.getDeclarationRetries()); + } +} From 0c4d88a8f4714f7087bc10702eec6e7b2a600bd6 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 29 Jun 2016 15:15:06 +0200 Subject: [PATCH 22/52] Fixed test. Signed-off-by: Kai Zimmermann --- .../org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index 6e61d1642..0dcf6cd85 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -141,7 +141,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost"); fail("IllegalArgumentException was excepeted due to worng content type"); - } catch (final IllegalArgumentException e) { + } catch (final AmqpRejectAndDontRequeueException e) { } } From 202054e129631d820440d0d1b1a8ee59565ad739 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 29 Jun 2016 15:20:23 +0200 Subject: [PATCH 23/52] Fixed sonar issue. Signed-off-by: Kai Zimmermann --- .../amqp/ConfigurableRabbitListenerContainerFactory.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java index fd0a1d2a1..14e6f8fcb 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java @@ -42,6 +42,9 @@ public class ConfigurableRabbitListenerContainerFactory extends SimpleRabbitList } @Override + // Exception squid:UnusedProtectedMethod - called by + // AbstractRabbitListenerContainerFactory + @SuppressWarnings("squid:UnusedProtectedMethod") protected void initializeContainer(final SimpleMessageListenerContainer instance) { super.initializeContainer(instance); instance.setDeclarationRetries(amqpProperties.getDeclarationRetries()); From c3b999792b5190f943171c45e04aec2618d302a7 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 29 Jun 2016 16:18:35 +0200 Subject: [PATCH 24/52] Clarified string conversion. Signed-off-by: Kai Zimmermann --- .../org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 9636de5c7..d1bf85103 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -408,7 +408,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { if (ArrayUtils.isNotEmpty(message.getMessageProperties().getCorrelationId())) { actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message correlation-id " - + new String(message.getMessageProperties().getCorrelationId())); + + convertCorrelationId(message)); } actionStatus.setAction(action); @@ -416,6 +416,10 @@ public class AmqpMessageHandlerService extends BaseAmqpService { return actionStatus; } + private static String convertCorrelationId(final Message message) { + return new String(message.getMessageProperties().getCorrelationId()); + } + private Action getUpdateActionStatus(final ActionStatus actionStatus) { if (actionStatus.getStatus().equals(Status.CANCELED)) { return controllerManagement.addCancelActionStatus(actionStatus); From 8d6526ae8fe25c164d46597b3966c74e0731571c Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 29 Jun 2016 17:01:24 +0200 Subject: [PATCH 25/52] Fixed fail messages. Signed-off-by: Kai Zimmermann --- .../amqp/AmqpMessageHandlerServiceTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index 0dcf6cd85..2627731c6 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -140,7 +140,7 @@ public class AmqpMessageHandlerServiceTest { final Message message = new Message(new byte[0], messageProperties); try { amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted due to worng content type"); + fail("AmqpRejectAndDontRequeueException was excepeted due to worng content type"); } catch (final AmqpRejectAndDontRequeueException e) { } } @@ -175,7 +175,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted since no replyTo header was set"); + fail("AmqpRejectAndDontRequeueException was excepeted since no replyTo header was set"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -189,7 +189,7 @@ public class AmqpMessageHandlerServiceTest { final Message message = messageConverter.toMessage(new byte[0], messageProperties); try { amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted since no thingID was set"); + fail("AmqpRejectAndDontRequeueException was excepeted since no thingID was set"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -205,7 +205,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, type, TENANT, "vHost"); - fail("IllegalArgumentException was excepeted due to unknown message type"); + fail("AmqpRejectAndDontRequeueException was excepeted due to unknown message type"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -218,21 +218,21 @@ public class AmqpMessageHandlerServiceTest { final Message message = new Message(new byte[0], messageProperties); try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted due to unknown message type"); + fail("AmqpRejectAndDontRequeueException was excepeted due to unknown message type"); } catch (final AmqpRejectAndDontRequeueException e) { } try { messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic"); amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted due to unknown topic"); + fail("AmqpRejectAndDontRequeueException was excepeted due to unknown topic"); } catch (final AmqpRejectAndDontRequeueException e) { } messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name()); try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted because there was no event topic"); + fail("AmqpRejectAndDontRequeueException was excepeted because there was no event topic"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -251,7 +251,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted since no action id was set"); + fail("AmqpRejectAndDontRequeueException was excepeted since no action id was set"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -268,7 +268,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted since no action id was set"); + fail("AmqpRejectAndDontRequeueException was excepeted since no action id was set"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } From f79073a15e72f76b0d351e6ec47ee90533b7c626 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 29 Jun 2016 19:16:17 +0200 Subject: [PATCH 26/52] Save button is only enabled if validation is successful Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 49 +------ .../CreateUpdateSoftwareTypeLayout.java | 6 +- .../hawkbit/ui/common/CommonDialogWindow.java | 68 ++++++---- .../CreateUpdateDistSetTypeLayout.java | 58 +-------- .../AbstractCreateUpdateTagLayout.java | 49 ++----- .../ui/layouts/CreateUpdateTypeLayout.java | 5 - .../DistributionAddUpdateWindowLayout.java | 58 +-------- .../TargetAddUpdateWindowLayout.java | 55 +------- .../CreateUpdateTargetTagLayoutWindow.java | 1 - .../rollout/AddUpdateRolloutWindowLayout.java | 122 ++++++------------ 10 files changed, 110 insertions(+), 361 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 73346454d..c8eb74313 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -26,7 +26,6 @@ import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; @@ -40,7 +39,6 @@ import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; -import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** @@ -184,8 +182,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se setCompositionRoot(formLayout); window = SPUIWindowDecorator.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - formLayout, i18n); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), null, null, formLayout, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); nameTextField.setEnabled(!editSwModule); @@ -202,10 +199,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se final String description = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); final String type = typeComboBox.getValue() != null ? typeComboBox.getValue().toString() : null; - if (!mandatoryCheck(name, version, type)) { - return; - } - if (HawkbitCommonUtil.isDuplicate(name, version, type)) { uiNotifcation.displayValidationError( i18n.get("message.duplicate.softwaremodule", new Object[] { name, version })); @@ -218,8 +211,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se new Object[] { newBaseSoftwareModule.getName() + ":" + newBaseSoftwareModule.getVersion() })); eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.NEW_ENTITY, newBaseSoftwareModule)); } - // close the window - closeThisWindow(); } } @@ -239,7 +230,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.UPDATED_ENTITY, newSWModule)); } - closeThisWindow(); } /** @@ -249,6 +239,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se if (baseSwModuleId == null) { return; } + editSwModule = Boolean.TRUE; final SoftwareModule swModle = softwareManagement.findSoftwareModuleById(baseSwModuleId); nameTextField.setValue(swModle.getName()); versionTextField.setValue(swModle.getVersion()); @@ -262,42 +253,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se typeComboBox.setValue(swModle.getType().getName()); } - /** - * Method to close window. - */ - private void closeThisWindow() { - window.close(); - UI.getCurrent().removeWindow(window); - } - - /** - * Validation check - Mandatory. - * - * @param name - * as String - * @param version - * as version - * @return boolena as flag - */ - private boolean mandatoryCheck(final String name, final String version, final String type) { - boolean isValid = true; - if (name == null || version == null || type == null) { - if (name == null) { - nameTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - } - if (version == null) { - versionTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - } - if (type == null) { - typeComboBox.addStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); - } - - uiNotifcation.displayValidationError(i18n.get("message.mandatory.check")); - isValid = false; - } - return isValid; - } - private void saveOrUpdate() { if (editSwModule) { updateSwModule(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 3ca0e3631..18d6b159c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -36,7 +36,6 @@ import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.components.colorpicker.ColorChangeListener; -import com.vaadin.ui.components.colorpicker.ColorSelector; import com.vaadin.ui.themes.ValoTheme; /** @@ -45,8 +44,7 @@ import com.vaadin.ui.themes.ValoTheme; */ @SpringComponent @ViewScope -public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout - implements ColorChangeListener, ColorSelector { +public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { private static final long serialVersionUID = -5169398523815919367L; private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateSoftwareTypeLayout.class); @@ -231,7 +229,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout newSWType = swTypeManagementService.createSoftwareModuleType(newSWType); uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newSWType.getName() })); - closeWindow(); eventBus.publish(this, new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE, newSWType)); @@ -253,7 +250,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout existingType.setColour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview())); swTypeManagementService.updateSoftwareModuleType(existingType); uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { existingType.getName() })); - closeWindow(); eventBus.publish(this, new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE, existingType)); 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 index 7cba5df4a..1d2f3b2d4 100644 --- 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 @@ -31,6 +31,7 @@ import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent; import com.google.common.base.Strings; import com.google.common.collect.Sets; @@ -38,6 +39,8 @@ import com.vaadin.data.Container.ItemSetChangeEvent; import com.vaadin.data.Container.ItemSetChangeListener; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.data.Validator; +import com.vaadin.data.validator.NullValidator; import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.event.FieldEvents.TextChangeNotifier; @@ -64,6 +67,7 @@ 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 implements Serializable { @@ -89,6 +93,8 @@ public class CommonDialogWindow extends Window implements Serializable { private final ClickListener cancelButtonClickListener; + private final ClickListener close = event -> close(); + private final Map orginalValues; private final List> allComponents; @@ -113,7 +119,6 @@ public class CommonDialogWindow extends Window implements Serializable { final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final AbstractLayout layout, final I18N i18n) { checkNotNull(saveButtonClickListener); - checkNotNull(cancelButtonClickListener); this.caption = caption; this.content = content; this.helpLink = helpLink; @@ -211,13 +216,11 @@ public class CommonDialogWindow extends Window implements Serializable { } orginalValues.put(field, value); } - saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(null, null)); } private final void addListeners() { for (final AbstractField field : allComponents) { - if (field instanceof TextChangeNotifier) { ((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field)); } @@ -229,13 +232,13 @@ public class CommonDialogWindow extends Window implements Serializable { } } - saveButton.addClickListener(event -> close()); - cancelButton.addClickListener(event -> close()); + saveButton.addClickListener(close); + cancelButton.addClickListener(close); } private boolean isSaveButtonEnabledAfterValueChange(final Component currentChangedComponent, final Object newValue) { - return isMandatoyFieldNotEmpty(currentChangedComponent, newValue) + return isMandatoryFieldNotEmptyAndValid(currentChangedComponent, newValue) && isValuesChanged(currentChangedComponent, newValue); } @@ -247,7 +250,6 @@ public class CommonDialogWindow extends Window implements Serializable { if (!isValueEquals(field, orginalValue, currentValue)) { return true; } - } return false; } @@ -289,31 +291,45 @@ public class CommonDialogWindow extends Window implements Serializable { return false; } - private boolean isMandatoyFieldNotEmpty(final Component currentChangedComponent, final Object newValue) { + private boolean isMandatoryFieldNotEmptyAndValid(final Component currentChangedComponent, final Object newValue) { + + boolean valid = true; final List> requiredComponents = allComponents.stream().filter(field -> field.isRequired()) .collect(Collectors.toList()); - for (final AbstractField field : requiredComponents) { - Object value = getCurrentVaue(currentChangedComponent, newValue, field); + requiredComponents.addAll(allComponents.stream().filter(this::hasNullValidator).collect(Collectors.toList())); - if (String.class.equals(field.getType())) { - value = Strings.emptyToNull((String) value); - } - - if (Set.class.equals(field.getType())) { - value = emptyToNull((Collection) value); - } + for (final AbstractField field : requiredComponents) { + final Object value = getCurrentVaue(currentChangedComponent, newValue, field); if (value == null) { return false; } - } - return true; + // We need to loop through the entire loop for validity testing. + // Otherwise the UI will only mark the + // first field with errors and then stop. If there are several + // fields with errors, this is bad. + field.setValue(value); + if (!field.isValid()) { + valid = false; + } + } + + return valid; } - private static Object emptyToNull(final Collection c) { - return (c == null || c.isEmpty()) ? null : c; + private boolean hasNullValidator(final Component component) { + + if (component instanceof AbstractField) { + final AbstractField fieldComponent = (AbstractField) component; + for (final Validator validator : fieldComponent.getValidators()) { + if (validator instanceof NullValidator) { + return true; + } + } + } + return false; } private List> getAllComponents(final AbstractLayout abstractLayout) { @@ -329,6 +345,10 @@ public class CommonDialogWindow extends Window implements Serializable { if (c instanceof AbstractField) { components.add((AbstractField) c); } + + if (c instanceof FlexibleOptionGroupItemComponent) { + components.add(((FlexibleOptionGroupItemComponent) c).getOwner()); + } } return components; } @@ -374,7 +394,9 @@ public class CommonDialogWindow extends Window implements Serializable { FontAwesome.TIMES, SPUIButtonStyleBorderWithIcon.class); cancelButton.setSizeUndefined(); cancelButton.addStyleName("default-color"); - cancelButton.addClickListener(cancelButtonClickListener); + if (cancelButtonClickListener != null) { + cancelButton.addClickListener(cancelButtonClickListener); + } buttonsLayout.addComponent(cancelButton); buttonsLayout.setComponentAlignment(cancelButton, Alignment.MIDDLE_LEFT); @@ -419,7 +441,6 @@ public class CommonDialogWindow extends Window implements Serializable { @Override public void textChange(final TextChangeEvent event) { saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, event.getText())); - } @Override @@ -436,7 +457,6 @@ public class CommonDialogWindow extends Window implements Serializable { saveButton.setEnabled( isSaveButtonEnabledAfterValueChange(table, table.getContainerDataSource().getItemIds())); } - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index cc73e3467..122599520 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.ui.distributions.disttype; -import java.util.Iterator; import java.util.List; import java.util.Set; @@ -49,8 +48,6 @@ import com.vaadin.ui.Component; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Table; import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.components.colorpicker.ColorChangeListener; -import com.vaadin.ui.components.colorpicker.ColorSelector; import com.vaadin.ui.themes.ValoTheme; /** @@ -58,8 +55,7 @@ import com.vaadin.ui.themes.ValoTheme; */ @SpringComponent @ViewScope -public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout - implements ColorChangeListener, ColorSelector { +public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { private static final long serialVersionUID = -5169398523815877767L; private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateDistSetTypeLayout.class); @@ -259,9 +255,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Long id : selectedIds) { addTargetTableData(id); } - // TODO: Add Table to window - // window.updateRequiredFields(selectedTable.getId(), - // hasContentChanged()); } private void removeSMType() { @@ -274,40 +267,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Long id : selectedIds) { addSourceTableData(id); selectedTable.removeItem(id); - // window.updateRequiredFields(selectedTable.getId(), - // hasContentChanged()); } } - private Boolean hasContentChanged() { - - if (originalSelectedTableContainer == null) { - originalSelectedTableContainer = new IndexedContainer(); - } - // is new softwareModule added? - for (final Iterator itemIterator = selectedTableContainer.getItemIds().iterator(); itemIterator.hasNext();) { - final long itemId = (Long) itemIterator.next(); - if (!originalSelectedTableContainer.containsId(itemId)) { - // window.updateEditedFields(selectedTable.getId(), - // Boolean.TRUE); - return Boolean.TRUE; - } - } - - // is softwareModule removed and at least one softwareModule is selected - for (final Iterator itemIterator = originalSelectedTableContainer.getItemIds().iterator(); itemIterator - .hasNext();) { - final long itemId = (Long) itemIterator.next(); - if (selectedTableContainer.size() > 0 && !selectedTableContainer.containsId(itemId)) { - // window.updateEditedFields(selectedTable.getId(), - // Boolean.TRUE); - return Boolean.TRUE; - } - } - - return Boolean.FALSE; - } - @SuppressWarnings("unchecked") private void getSourceTableData() { @@ -402,10 +364,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout newDistType.setColour(colorPicked); newDistType = distributionSetManagement.createDistributionSetType(newDistType); uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newDistType.getName() })); - closeWindow(); eventBus.publish(this, new DistributionSetTypeEvent(DistributionSetTypeEnum.ADD_DIST_SET_TYPE, newDistType)); - } else { uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey")); } @@ -445,7 +405,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout distributionSetManagement.updateDistributionSetType(updateDistSetType); uiNotification .displaySuccess(i18n.get("message.update.success", new Object[] { updateDistSetType.getName() })); - closeWindow(); eventBus.publish(this, new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType)); @@ -480,18 +439,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout return distSetType; } - @Override - public void addColorChangeListener(final ColorChangeListener listener) { - - LOG.info("in side addColorChangeListener() "); - } - - @Override - public void removeColorChangeListener(final ColorChangeListener listener) { - - LOG.info("in side removeColorChangeListener() "); - } - /** * reset the components. */ @@ -515,7 +462,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout super.optionValueChanged(event); if (updateTypeStr.equals(event.getProperty().getValue())) { - // window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); selectedTable.getContainerDataSource().removeAllItems(); getSourceTableData(); distTypeSelectLayout.setEnabled(false); @@ -616,6 +562,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout sourceTable.removeItem(swModuleType.getId()); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); + + // TODO CHECKBOX final CheckBox mandatoryCheckbox = (CheckBox) selectedTableContainer .getContainerProperty(swModuleType.getId(), DIST_TYPE_MANDATORY).getValue(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 8c85f63a5..6527d5db5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -30,7 +30,6 @@ import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; -import com.google.common.base.Strings; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.server.Page; @@ -335,7 +334,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor()); colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor()); tagPreviewBtnClicked = false; - } /** @@ -427,11 +425,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent } - protected void closeWindow() { - window.close(); - UI.getCurrent().removeWindow(window); - } - /** * create option group with Create tag/Update tag based on permissions. */ @@ -463,14 +456,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent } } - @Override - public void addColorChangeListener(final ColorChangeListener listener) { - } - - @Override - public void removeColorChangeListener(final ColorChangeListener listener) { - } - public ColorPickerLayout getColorPickerLayout() { return colorPickerLayout; } @@ -554,7 +539,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagManagement.updateDistributionSetTag((DistributionSetTag) targetObj); } uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { targetObj.getName() })); - closeWindow(); } else { uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); } @@ -576,27 +560,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent getPreviewButtonColor(previewColor); } - /** - * - * @return - */ - protected Boolean mandatoryValuesPresent() { - if (Strings.isNullOrEmpty(tagName.getValue())) { - if (optiongroup.getValue().equals(createTagStr)) { - displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME); - } - if (optiongroup.getValue().equals(updateTagStr)) { - if (null == tagNameComboBox.getValue()) { - displayValidationError(i18n.get(MESSAGE_ERROR_MISSING_TAGNAME)); - } else { - displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME); - } - } - return Boolean.FALSE; - } - return Boolean.TRUE; - } - protected Boolean checkIsDuplicate(final Tag existingTag) { if (existingTag != null) { displayValidationError(i18n.get("message.tag.duplicate.check", new Object[] { existingTag.getName() })); @@ -637,4 +600,16 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent return mainLayout; } + @Override + public void addColorChangeListener(final ColorChangeListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void removeColorChangeListener(final ColorChangeListener listener) { + // TODO Auto-generated method stub + + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index 47451d662..f25a4b485 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -179,11 +179,6 @@ public abstract class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayo createDynamicStyleForComponents(tagName, typeKey, tagDesc, colorPickedPreview); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelPreview().getColor()); } - - // TODO: - // window.checkColorChange(colorPickerLayout.getId(), - // colorPickerLayout.getSelectedColor(), - // getOriginalSelectedColor()); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index c2f125e3a..069b9b407 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -50,7 +50,6 @@ import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; -import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** @@ -192,7 +191,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { final String distSetTypeName = HawkbitCommonUtil .trimAndNullIfEmpty((String) distsetTypeNameComboBox.getValue()); - if (mandatoryCheck(name, version, distSetTypeName) && duplicateCheck(name, version)) { + if (duplicateCheck(name, version)) { final DistributionSet currentDS = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); final String desc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); final boolean isMigStepReq = reqMigStepCheckbox.getValue(); @@ -210,7 +209,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { notificationMessage.displayValidationError( i18n.get("message.distribution.no.update", currentDS.getName() + ":" + currentDS.getVersion())); } - closeThisWindow(); } } @@ -224,7 +222,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { final String distSetTypeName = HawkbitCommonUtil .trimAndNullIfEmpty((String) distsetTypeNameComboBox.getValue()); - if (mandatoryCheck(name, version, distSetTypeName) && duplicateCheck(name, version)) { + if (duplicateCheck(name, version)) { final String desc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); final boolean isMigStepReq = reqMigStepCheckbox.getValue(); DistributionSet newDist = entityFactory.generateDistributionSet(); @@ -234,21 +232,11 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success", new Object[] { newDist.getName(), newDist.getVersion() })); - /* close the window */ - closeThisWindow(); eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.NEW_ENTITY, newDist)); } } - /** - * Close window. - */ - private void closeThisWindow() { - window.close(); - UI.getCurrent().removeWindow(window); - } - /** * Set Values for Distribution set. * @@ -292,45 +280,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } } - /** - * Mandatory Check. - * - * @param name - * as String - * @param version - * as String - * @param selectedJVM - * as String - * @param selectedAgentHub - * as String - * @param selectedOs - * as String - * @return boolean as flag - */ - private boolean mandatoryCheck(final String name, final String version, final String distSetTypeName) { - - if (name == null || version == null || distSetTypeName == null) { - if (name == null) { - distNameTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - } - if (version == null) { - distVersionTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - } - if (distSetTypeName == null) { - distsetTypeNameComboBox.addStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); - } - notificationMessage.displayValidationError(i18n.get("message.mandatory.check")); - return false; - } - - return true; - } - - private void discardDistribution() { - /* Just close this window */ - closeThisWindow(); - } - /** * clear all the fields. */ @@ -377,8 +326,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { populateDistSetTypeNameCombo(); populateValuesOfDistribution(editDistId); window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.dist"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, formLayout, i18n); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), null, null, formLayout, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index fb7307f5f..93c5a4514 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -8,9 +8,7 @@ */ package org.eclipse.hawkbit.ui.management.targettable; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; import org.eclipse.hawkbit.repository.EntityFactory; @@ -40,7 +38,6 @@ import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; -import com.vaadin.ui.UI; import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; @@ -75,10 +72,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private FormLayout formLayout; private CommonDialogWindow window; - private String originalTargetName; - private String originalTargetDesc; - private String originalControllerId; - /** * Initialize the Add Update Window Component for Target. */ @@ -139,10 +132,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { uINotification.displaySuccess(i18n.get("message.update.success", new Object[] { latestTarget.getName() })); // publishing through event bus eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.UPDATED_ENTITY, latestTarget)); - - /* close the window */ - closeThisWindow(); - /* update details in table */ } private void saveTargetListner() { @@ -153,13 +142,9 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } } - private void discardTargetListner() { - closeThisWindow(); - } - private void addNewTarget() { final String newControlllerId = HawkbitCommonUtil.trimAndNullIfEmpty(controllerIDTextField.getValue()); - if (mandatoryCheck(newControlllerId) && duplicateCheck(newControlllerId)) { + if (duplicateCheck(newControlllerId)) { final String newName = HawkbitCommonUtil.trimAndNullIfEmpty(nameTextField.getValue()); final String newDesc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); @@ -176,27 +161,16 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { /* display success msg */ uINotification.displaySuccess(i18n.get("message.save.success", new Object[] { newTarget.getName() })); - /* close the window */ - closeThisWindow(); } } public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), - event -> discardTargetListner(), null, formLayout, i18n); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), null, null, formLayout, i18n); return window; } - private Map getEditedFields() { - final Map editedFields = new HashMap<>(); - editedFields.put(controllerIDTextField.getId(), Boolean.FALSE); - editedFields.put(nameTextField.getId(), Boolean.FALSE); - editedFields.put(descTextArea.getId(), Boolean.FALSE); - return editedFields; - } - /** * clear all fields of Target Edit Window. */ @@ -208,17 +182,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { controllerIDTextField.clear(); descTextArea.clear(); editTarget = Boolean.FALSE; - - originalControllerId = null; - originalTargetDesc = null; - originalTargetName = null; - - } - - private void closeThisWindow() { - editTarget = Boolean.FALSE; - window.close(); - UI.getCurrent().removeWindow(window); } private void setTargetValues(final Target target, final String name, final String description) { @@ -226,16 +189,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { target.setDescription(description); } - private boolean mandatoryCheck(final String newControlllerId) { - if (newControlllerId == null) { - controllerIDTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - uINotification.displayValidationError("Mandatory details are missing"); - return false; - } else { - return true; - } - } - private boolean duplicateCheck(final String newControlllerId) { final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim()); if (existingTarget != null) { @@ -261,10 +214,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { if (target.getDescription() != null) { descTextArea.setValue(target.getDescription()); } - - originalTargetDesc = descTextArea.getValue(); - originalTargetName = nameTextField.getValue(); - originalControllerId = controllerIDTextField.getValue(); window.addStyleName("target-update-window"); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java index 765704da8..f96c3b174 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java @@ -129,7 +129,6 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa } newTargetTag = tagManagement.createTargetTag(newTargetTag); displaySuccess(newTargetTag.getName()); - closeWindow(); } else { displayValidationError(i18n.get(MESSAGE_ERROR_MISSING_TAGNAME)); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 777682ff1..f97f8e43f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -12,7 +12,6 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.RolloutManagement; @@ -58,8 +57,9 @@ import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Validator; +import com.vaadin.data.util.converter.StringToIntegerConverter; import com.vaadin.data.validator.IntegerRangeValidator; -import com.vaadin.data.validator.RegexpValidator; +import com.vaadin.data.validator.NullValidator; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; @@ -69,7 +69,6 @@ import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; -import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** @@ -87,8 +86,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private static final String MESSAGE_ENTER_NUMBER = "message.enter.number"; - private static final String NUMBER_REGEXP = "[-]?[0-9]*\\.?,?[0-9]+"; - @Autowired private ActionTypeOptionGroupLayout actionTypeOptionGroupLayout; @@ -146,6 +143,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextArea targetFilterQuery; + private final NullValidator nullValidator = new NullValidator(null, false); + /** * Create components and layout. */ @@ -157,10 +156,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public CommonDialogWindow getWindow(final Long rolloutId) { resetComponents(); - populateData(rolloutId); window = SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), null, uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); + populateData(rolloutId); return window; } @@ -207,33 +206,34 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { addComponent(getMandatoryLabel("textfield.name"), 0, 0); addComponent(rolloutName, 1, 0); - rolloutName.setRequired(true); + rolloutName.addValidator(nullValidator); addComponent(getMandatoryLabel("prompt.distribution.set"), 0, 1); addComponent(distributionSet, 1, 1); - distributionSet.setRequired(true); + distributionSet.addValidator(nullValidator); addComponent(getMandatoryLabel("prompt.target.filter"), 0, 2); addComponent(targetFilterQueryCombo, 1, 2); - targetFilterQueryCombo.setRequired(true); + targetFilterQueryCombo.addValidator(nullValidator); + targetFilterQuery.removeValidator(nullValidator); addComponent(totalTargetsLabel, 2, 2); addComponent(getMandatoryLabel("prompt.number.of.groups"), 0, 3); addComponent(noOfGroups, 1, 3); - noOfGroups.setRequired(true); + noOfGroups.addValidator(nullValidator); addComponent(groupSizeLabel, 2, 3); addComponent(getMandatoryLabel("prompt.tigger.threshold"), 0, 4); addComponent(triggerThreshold, 1, 4); - triggerThreshold.setRequired(true); + triggerThreshold.addValidator(nullValidator); addComponent(getPercentHintLabel(), 2, 4); addComponent(getMandatoryLabel("prompt.error.threshold"), 0, 5); addComponent(errorThreshold, 1, 5); - errorThreshold.setRequired(true); + errorThreshold.addValidator(nullValidator); addComponent(errorThresholdOptionGroup, 2, 5); addComponent(getLabel("textfield.description"), 0, 6); @@ -386,10 +386,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { targetFilterQF); } - private void onDiscard() { - closeThisWindow(); - } - private void onRolloutSave() { if (editRolloutEnabled) { editRollout(); @@ -399,7 +395,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void editRollout() { - if (mandatoryCheckForEdit() && validateFields() && duplicateCheckForEdit() && null != rolloutForEdit) { + if (duplicateCheckForEdit() && rolloutForEdit != null) { rolloutForEdit.setName(rolloutName.getValue()); rolloutForEdit.setDescription(description.getValue()); final DistributionSetIdName distributionSetIdName = (DistributionSetIdName) distributionSet.getValue(); @@ -417,7 +413,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { final Rollout updatedRollout = rolloutManagement.updateRollout(rolloutForEdit); uiNotification .displaySuccess(i18n.get("message.update.success", new Object[] { updatedRollout.getName() })); - closeThisWindow(); eventBus.publish(this, RolloutEvent.UPDATE_ROLLOUT); } } @@ -445,11 +440,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void createRollout() { - if (mandatoryCheck() && validateFields() && duplicateCheck()) { + if (duplicateCheck()) { final Rollout rolloutToCreate = saveRollout(); uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { rolloutToCreate.getName() })); eventBus.publish(this, RolloutEvent.CREATE_ROLLOUT); - closeThisWindow(); } } @@ -506,48 +500,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return true; } - private void closeThisWindow() { - window.close(); - UI.getCurrent().removeWindow(window); - } - - private boolean mandatoryCheck() { - final DistributionSetIdName ds = getDistributionSetSelected(); - final String targetFilter = (String) targetFilterQueryCombo.getValue(); - final String triggerThresoldValue = triggerThreshold.getValue(); - final String errorThresoldValue = errorThreshold.getValue(); - if (hasNoNameOrTargetFilter(targetFilter) || ds == null - || HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null - || isThresholdValueMissing(triggerThresoldValue, errorThresoldValue)) { - uiNotification.displayValidationError(i18n.get("message.mandatory.check")); - return false; - } - return true; - } - - private boolean mandatoryCheckForEdit() { - final DistributionSetIdName ds = getDistributionSetSelected(); - final String targetFilter = targetFilterQuery.getValue(); - final String triggerThresoldValue = triggerThreshold.getValue(); - final String errorThresoldValue = errorThreshold.getValue(); - if (hasNoNameOrTargetFilter(targetFilter) || ds == null - || HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null - || isThresholdValueMissing(triggerThresoldValue, errorThresoldValue)) { - uiNotification.displayValidationError(i18n.get("message.mandatory.check")); - return false; - } - return true; - } - - private boolean hasNoNameOrTargetFilter(final String targetFilter) { - return getRolloutName() == null || targetFilter == null; - } - - private boolean isThresholdValueMissing(final String triggerThresoldValue, final String errorThresoldValue) { - return HawkbitCommonUtil.trimAndNullIfEmpty(triggerThresoldValue) == null - || HawkbitCommonUtil.trimAndNullIfEmpty(errorThresoldValue) == null; - } - private boolean duplicateCheck() { if (rolloutManagement.findRolloutByName(getRolloutName()) != null) { uiNotification.displayValidationError( @@ -573,7 +525,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextField createErrorThreshold() { final TextField errorField = getTextfield("prompt.error.threshold"); + errorField.setNullRepresentation(""); errorField.addValidator(new ThresholdFieldValidator()); + errorField.setConverter(new StringToIntegerConverter()); + errorField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER)); errorField.setId(SPUIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_ID); errorField.setMaxLength(7); errorField.setSizeUndefined(); @@ -583,7 +538,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextField createTriggerThreshold() { final TextField thresholdField = getTextfield("prompt.tigger.threshold"); thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID); + thresholdField.setNullRepresentation(""); thresholdField.addValidator(new ThresholdFieldValidator()); + thresholdField.setConverter(new StringToIntegerConverter()); + thresholdField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER)); thresholdField.setSizeUndefined(); thresholdField.setMaxLength(3); return thresholdField; @@ -595,12 +553,15 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroupsField.addValidator(new GroupNumberValidator()); noOfGroupsField.setSizeUndefined(); noOfGroupsField.setMaxLength(3); + noOfGroupsField.setConverter(new StringToIntegerConverter()); + noOfGroupsField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER)); noOfGroupsField.addValueChangeListener(this::onGroupNumberChange); + noOfGroupsField.setNullRepresentation(""); return noOfGroupsField; } private void onGroupNumberChange(final ValueChangeEvent event) { - if (noOfGroups.isValid() && !Strings.isNullOrEmpty(noOfGroups.getValue())) { + if (event.getProperty().getValue() != null && noOfGroups.isValid()) { groupSizeLabel.setValue(getTargetPerGroupMessage(String.valueOf(getGroupSize()))); groupSizeLabel.setVisible(true); } else { @@ -643,10 +604,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return HawkbitCommonUtil.trimAndNullIfEmpty(rolloutName.getValue()); } - private DistributionSetIdName getDistributionSetSelected() { - return (DistributionSetIdName) distributionSet.getValue(); - } - class ErrorThresoldOptionValidator implements Validator { private static final long serialVersionUID = 9049939751976326550L; @@ -659,8 +616,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { uiNotification .displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing")); } else { - if (StringUtils.isNotBlank(value.toString())) { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + if (value != null) { final int groupSize = getGroupSize(); new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0, groupSize).validate(Integer.valueOf(value.toString())); @@ -670,8 +626,12 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // suppress the need of preserve original exception, will blow // up the // log and not necessary here - catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) { - LOG.error(ex.getMessage()); + catch ( + + @SuppressWarnings("squid:S1166") final InvalidValueException ex) { + // we have to throw the exception here, otherwise the UI won't + // show the vaadin validation error! + throw ex; } } } @@ -686,8 +646,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Override public void validate(final Object value) { try { - if (StringUtils.isNotBlank(value.toString())) { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + if (value != null) { new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100) .validate(Integer.valueOf(value.toString())); } @@ -696,7 +655,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // up the // log and not necessary here catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) { - LOG.error(ex.getMessage()); + // we have to throw the exception here, otherwise the UI won't + // show the vaadin validation error! + throw ex; } } } @@ -707,8 +668,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Override public void validate(final Object value) { try { - if (StringUtils.isNotBlank(value.toString())) { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + if (value != null) { new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500) .validate(Integer.valueOf(value.toString())); } @@ -717,7 +677,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // up the // log and not necessary here catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) { - LOG.error(ex.getMessage()); + // we have to throw the exception here, otherwise the UI won't + // show the vaadin validation error! + throw ex; } } } @@ -749,7 +711,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroups.setEnabled(false); targetFilterQuery.setValue(rolloutForEdit.getTargetFilterQuery()); removeComponent(1, 2); + targetFilterQueryCombo.removeValidator(nullValidator); addComponent(targetFilterQuery, 1, 2); + targetFilterQuery.addValidator(nullValidator); totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(rolloutForEdit.getTargetFilterQuery()); totalTargetsLabel.setValue(getTotalTargetMessage()); @@ -795,7 +759,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { * @param rolloutGroups */ private void setThresholdValues(final List rolloutGroups) { - if (null != rolloutGroups && !rolloutGroups.isEmpty()) { + if (rolloutGroups != null && !rolloutGroups.isEmpty()) { errorThreshold.setValue(rolloutGroups.get(0).getErrorConditionExp()); triggerThreshold.setValue(rolloutGroups.get(0).getSuccessConditionExp()); noOfGroups.setValue(String.valueOf(rolloutGroups.size())); From fa2e801e7648a4c68fe897220f2ec46f44d50dab Mon Sep 17 00:00:00 2001 From: venu1278 Date: Thu, 30 Jun 2016 14:50:20 +0530 Subject: [PATCH 27/52] RolloutView_update_automaticaly_changes_in_repository Signed-off-by: venu1278 --- .../org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index 20c2ca710..d16060eea 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -145,6 +145,7 @@ public class RolloutListGrid extends AbstractGrid { final LazyQueryContainer rolloutContainer = (LazyQueryContainer) getContainerDataSource(); final Item item = rolloutContainer.getItem(rolloutChangeEvent.getRolloutId()); if (item == null) { + refreshGrid(); return; } item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rollout.getStatus()); From 67ee674d412da216644813fe4ddcd7b81c95b8af Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 30 Jun 2016 17:48:58 +0200 Subject: [PATCH 28/52] Fix Update bug of softwareModuleType, refactored based on git comments Signed-off-by: Melanie Retter --- .../repository/jpa/JpaSoftwareManagement.java | 2 +- .../CreateUpdateSoftwareTypeLayout.java | 15 +------ .../hawkbit/ui/common/CommonDialogWindow.java | 40 +++++++++++++++++-- .../CreateUpdateDistSetTypeLayout.java | 29 +++++++------- .../AbstractCreateUpdateTagLayout.java | 4 -- .../TargetAddUpdateWindowLayout.java | 10 ++++- .../management/targettable/TargetDetails.java | 3 +- .../rollout/AddUpdateRolloutWindowLayout.java | 30 ++++++++------ .../ui/rollout/rollout/RolloutListHeader.java | 2 +- 9 files changed, 83 insertions(+), 52 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index 50127e227..b561667a9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -132,7 +132,7 @@ public class JpaSoftwareManagement implements SoftwareManagement { final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); boolean updated = false; - if (sm.getDescription() != null && !sm.getDescription().equals(type.getDescription())) { + if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) { type.setDescription(sm.getDescription()); updated = true; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 18d6b159c..ce7631c26 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -220,21 +220,14 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { SoftwareModuleType newSWType = entityFactory.generateSoftwareModuleType(typeKeyValue, typeNameValue, typeDescValue, assignNumber); newSWType.setColour(colorPicked); - - if (null != typeDescValue) { - newSWType.setDescription(typeDescValue); - } - + newSWType.setDescription(typeDescValue); newSWType.setColour(colorPicked); - newSWType = swTypeManagementService.createSoftwareModuleType(newSWType); uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newSWType.getName() })); eventBus.publish(this, new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE, newSWType)); - } else { uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey")); - } } @@ -244,19 +237,15 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { final String typeDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue()); if (null != typeNameValue) { existingType.setName(typeNameValue); - - existingType.setDescription(null != typeDescValue ? typeDescValue : null); - + existingType.setDescription(typeDescValue); existingType.setColour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview())); swTypeManagementService.updateSoftwareModuleType(existingType); uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { existingType.getName() })); eventBus.publish(this, new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE, existingType)); - } else { uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); } - } @Override 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 index 1d2f3b2d4..725ff4b9b 100644 --- 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 @@ -52,6 +52,7 @@ import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.CheckBox; import com.vaadin.ui.Component; import com.vaadin.ui.Field; import com.vaadin.ui.GridLayout; @@ -207,6 +208,10 @@ public class CommonDialogWindow extends Window implements Serializable { addListeners(); } + /** + * saves the original values in a Map so we can use them for detecting + * changes + */ public final void setOrginaleValues() { for (final AbstractField field : allComponents) { Object value = field.getValue(); @@ -244,10 +249,13 @@ public class CommonDialogWindow extends Window implements Serializable { private boolean isValuesChanged(final Component currentChangedComponent, final Object newValue) { for (final AbstractField field : allComponents) { - final Object orginalValue = orginalValues.get(field); + Object originalValue = orginalValues.get(field); + if (field instanceof CheckBox && originalValue == null) { + originalValue = Boolean.FALSE; + } final Object currentValue = getCurrentVaue(currentChangedComponent, newValue, field); - if (!isValueEquals(field, orginalValue, currentValue)) { + if (!isValueEquals(field, originalValue, currentValue)) { return true; } } @@ -300,7 +308,15 @@ public class CommonDialogWindow extends Window implements Serializable { requiredComponents.addAll(allComponents.stream().filter(this::hasNullValidator).collect(Collectors.toList())); for (final AbstractField field : requiredComponents) { - final Object value = getCurrentVaue(currentChangedComponent, newValue, field); + Object value = getCurrentVaue(currentChangedComponent, newValue, field); + + if (String.class.equals(field.getType())) { + value = Strings.emptyToNull((String) value); + } + + if (Set.class.equals(field.getType())) { + value = emptyToNull((Collection) value); + } if (value == null) { return false; @@ -319,6 +335,10 @@ public class CommonDialogWindow extends Window implements Serializable { return valid; } + private static Object emptyToNull(final Collection c) { + return (c == null || c.isEmpty()) ? null : c; + } + private boolean hasNullValidator(final Component component) { if (component instanceof AbstractField) { @@ -459,4 +479,18 @@ public class CommonDialogWindow extends Window implements Serializable { } } + /** + * Adds the component manually to the allComponents-List and adds a + * ValueChangeListener to it. Necessary in Update Distribution Type as the + * CheckBox concerned is an ItemProperty... + * + * @param component + * AbstractField + */ + public void updateAllComponents(final AbstractField component) { + + allComponents.add(component); + component.addValueChangeListener(new ChangeListener(component)); + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 122599520..2a12bc859 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.distributions.disttype; import java.util.List; +import java.util.Map; import java.util.Set; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -83,6 +84,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { private IndexedContainer originalSelectedTableContainer; + private Map mandatoryCheckboxMap; + @Override protected void createRequiredComponents() { @@ -315,7 +318,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { saveTblitem = selectedTableContainer.addItem(id); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue( sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_NAME).getValue()); - saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox()); + final CheckBox mandatoryCheckBox = new CheckBox(); + window.updateAllComponents(mandatoryCheckBox); + saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckBox); saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue( sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_DESCRIPTION).getValue()); } @@ -327,7 +332,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { if (sourceTableContainer != null) { Item saveTblitem; saveTblitem = sourceTableContainer.addItem(selectedId); - selectedTable.getContainerDataSource().getItem(selectedId).getItemProperty(DIST_TYPE_NAME); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(selectedTable.getContainerDataSource() .getItem(selectedId).getItemProperty(DIST_TYPE_NAME).getValue()); saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(selectedTable.getContainerDataSource() @@ -357,10 +361,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { final SoftwareModuleType swModuleType = softwareManagement.findSoftwareModuleTypeByName(distTypeName); checkMandatoryAndAddMandatoryModuleType(newDistType, isMandatory, swModuleType); } - if (null != typeDescValue) { - newDistType.setDescription(typeDescValue); - } - + newDistType.setDescription(typeDescValue); newDistType.setColour(colorPicked); newDistType = distributionSetManagement.createDistributionSetType(newDistType); uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newDistType.getName() })); @@ -387,7 +388,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { if (null != typeNameValue) { updateDistSetType.setName(typeNameValue); updateDistSetType.setKey(typeKeyValue); - updateDistSetType.setDescription(null != typeDescValue ? typeDescValue : null); + updateDistSetType.setDescription(typeDescValue); if (distributionSetManagement.countDistributionSetsByType(existingType) <= 0 && null != itemIds && !itemIds.isEmpty()) { @@ -407,7 +408,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { .displaySuccess(i18n.get("message.update.success", new Object[] { updateDistSetType.getName() })); eventBus.publish(this, new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType)); - } else { uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); } @@ -417,7 +417,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { final Boolean isMandatory, final SoftwareModuleType swModuleType) { if (isMandatory) { updateDistSetType.addMandatoryModuleType(swModuleType); - } else { updateDistSetType.addOptionalModuleType(swModuleType); } @@ -561,15 +560,15 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { final Item saveTblitem = selectedTableContainer.addItem(swModuleType.getId()); sourceTable.removeItem(swModuleType.getId()); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); - saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); - - // TODO CHECKBOX - final CheckBox mandatoryCheckbox = (CheckBox) selectedTableContainer - .getContainerProperty(swModuleType.getId(), DIST_TYPE_MANDATORY).getValue(); + final CheckBox mandatoryCheckbox = new CheckBox("", mandatory); + mandatoryCheckbox.setId(swModuleType.getName()); + saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckbox); final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId()); originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); - originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); + originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckbox); + + window.updateAllComponents(mandatoryCheckbox); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 6527d5db5..8269d4e89 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -602,14 +602,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent @Override public void addColorChangeListener(final ColorChangeListener listener) { - // TODO Auto-generated method stub - } @Override public void removeColorChangeListener(final ColorChangeListener listener) { - // TODO Auto-generated method stub - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 93c5a4514..2b08c4dbf 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -171,6 +171,13 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { return window; } + public Window getWindow(final String entityId) { + populateValuesOfTarget(entityId); + getWindow(); + window.addStyleName("target-update-window"); + return window; + } + /** * clear all fields of Target Edit Window. */ @@ -203,7 +210,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { /** * @param controllerId */ - public void populateValuesOfTarget(final String controllerId) { + private void populateValuesOfTarget(final String controllerId) { resetComponents(); this.controllerId = controllerId; editTarget = Boolean.TRUE; @@ -214,7 +221,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { if (target.getDescription() != null) { descTextArea.setValue(target.getDescription()); } - window.addStyleName("target-update-window"); } public FormLayout getFormLayout() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java index ffaa39411..020b29372 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java @@ -106,7 +106,8 @@ public class TargetDetails extends AbstractTableDetailsLayout { if (getSelectedBaseEntity() == null) { return; } - targetAddUpdateWindowLayout.populateValuesOfTarget(getSelectedBaseEntity().getControllerId()); + targetAddUpdateWindowLayout.getWindow(getSelectedBaseEntity().getControllerId()); + // targetAddUpdateWindowLayout.populateValuesOfTarget(getSelectedBaseEntity().getControllerId()); openWindow(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index f97f8e43f..05eabf249 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -155,14 +155,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } public CommonDialogWindow getWindow(final Long rolloutId) { - resetComponents(); - window = SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), null, - uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); + window = getWindow(); populateData(rolloutId); return window; } + public CommonDialogWindow getWindow() { + resetComponents(); + return SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), null, + uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); + } + /** * Reset the field values. */ @@ -610,9 +614,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Override public void validate(final Object value) { try { - if (HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null - || (HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null - && targetFilterQuery.getValue() == null)) { + if (isNoOfGroupsOrTargetFilterEmpty()) { uiNotification .displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing")); } else { @@ -626,14 +628,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // suppress the need of preserve original exception, will blow // up the // log and not necessary here - catch ( - - @SuppressWarnings("squid:S1166") final InvalidValueException ex) { + catch (final InvalidValueException ex) { // we have to throw the exception here, otherwise the UI won't // show the vaadin validation error! throw ex; } } + + private boolean isNoOfGroupsOrTargetFilterEmpty() { + return HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null + || (HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null + && targetFilterQuery.getValue() == null); + } } private int getGroupSize() { @@ -654,7 +660,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // suppress the need of preserve original exception, will blow // up the // log and not necessary here - catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) { + catch (final InvalidValueException ex) { // we have to throw the exception here, otherwise the UI won't // show the vaadin validation error! throw ex; @@ -676,7 +682,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // suppress the need of preserve original exception, will blow // up the // log and not necessary here - catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) { + catch (final InvalidValueException ex) { // we have to throw the exception here, otherwise the UI won't // show the vaadin validation error! throw ex; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java index 49bb90100..81608d42d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java @@ -91,7 +91,7 @@ public class RolloutListHeader extends AbstractGridHeader { @Override protected void addNewItem(final ClickEvent event) { - final Window addTargetWindow = addUpdateRolloutWindow.getWindow(null); + final Window addTargetWindow = addUpdateRolloutWindow.getWindow(); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); From 11f9b6737e3f91926b135ddc216f12298e3f6daf Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 30 Jun 2016 18:06:08 +0200 Subject: [PATCH 29/52] Added Ids for components Signed-off-by: Melanie Retter --- .../eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java | 1 + .../hawkbit/ui/management/tag/SpColorPickerPreview.java | 4 +++- .../eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java index 732523560..2c6191bc8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java @@ -73,6 +73,7 @@ public class ColorPickerLayout extends GridLayout { colorSelect.setWidth("220px"); redSlider = createRGBSlider("", "red"); + redSlider.setId(SPUIComponentIdProvider.COLOR_PICKER_RED_SLIDER); greenSlider = createRGBSlider("", "green"); blueSlider = createRGBSlider("", "blue"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/tag/SpColorPickerPreview.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/tag/SpColorPickerPreview.java index 29db56009..afbed85a6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/tag/SpColorPickerPreview.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/tag/SpColorPickerPreview.java @@ -10,6 +10,8 @@ package org.eclipse.hawkbit.ui.management.tag; import java.lang.reflect.Field; +import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; + import com.google.common.base.Throwables; import com.vaadin.data.Property; import com.vaadin.data.Property.ValueChangeEvent; @@ -44,7 +46,7 @@ public final class SpColorPickerPreview extends ColorPickerPreview implements Te try { final Field textField = ColorPickerPreview.class.getDeclaredField("field"); textField.setAccessible(true); - ((TextField) textField.get(this)).setId("color-preview-field"); + ((TextField) textField.get(this)).setId(SPUIComponentIdProvider.COLOR_PREVIEW_FIELD); ((TextField) textField.get(this)).addTextChangeListener(this); } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) { Throwables.propagate(e); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java index 7a7d62b87..826985162 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java @@ -310,6 +310,14 @@ public final class SPUIComponentIdProvider { * Id for ColorPickerLayout */ public static final String COLOR_PICKER_LAYOUT = "color.picker.layout"; + /** + * Id for ColorPickerLayout's red slider + */ + public static final String COLOR_PICKER_RED_SLIDER = "color.picker.red.slider"; + /** + * Id for Color preview field with the color code + */ + public static final String COLOR_PREVIEW_FIELD = "color-preview-field"; /** * Id for OptionGroup Create/Update tag */ From a4252283dbc8f408525639f95930126b9fbcade8 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Fri, 1 Jul 2016 08:42:17 +0200 Subject: [PATCH 30/52] Target securityToken and address fully manageable through MGMT API. Signed-off-by: kaizimmerm --- .../model/target/MgmtTargetRequestBody.java | 11 ++++ .../mgmt/rest/resource/MgmtTargetMapper.java | 3 +- .../rest/resource/MgmtTargetResource.java | 7 +++ .../rest/resource/MgmtTargetResourceTest.java | 56 ++++++++++++++++++- .../hawkbit/repository/EntityFactory.java | 14 +++++ .../hawkbit/repository/model/Target.java | 6 ++ .../repository/jpa/JpaEntityFactory.java | 9 +++ .../repository/jpa/model/JpaTarget.java | 14 ++++- .../repository/jpa/TargetManagementTest.java | 8 +-- .../hawkbit/rest/util/JsonBuilder.java | 10 ++-- 10 files changed, 124 insertions(+), 14 deletions(-) diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java index b9c0b001a..f7a297be1 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java @@ -21,6 +21,17 @@ public class MgmtTargetRequestBody { @JsonProperty private String address; + @JsonProperty + private String securityToken; + + public String getSecurityToken() { + return securityToken; + } + + public void setSecurityToken(final String securityToken) { + this.securityToken = securityToken; + } + /** * @return the name */ diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java index f6cf9f54b..a889edc35 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java @@ -182,10 +182,11 @@ public final class MgmtTargetMapper { } static Target fromRequest(final EntityFactory entityFactory, final MgmtTargetRequestBody targetRest) { - final Target target = entityFactory.generateTarget(targetRest.getControllerId()); + final Target target = entityFactory.generateTarget(targetRest.getControllerId(), targetRest.getSecurityToken()); target.setDescription(targetRest.getDescription()); target.setName(targetRest.getName()); target.getTargetInfo().setAddress(targetRest.getAddress()); + return target; } diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java index c41dadd27..5ddb74314 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java @@ -125,6 +125,13 @@ public class MgmtTargetResource implements MgmtTargetRestApi { if (targetRest.getName() != null) { existingTarget.setName(targetRest.getName()); } + if (targetRest.getAddress() != null) { + existingTarget.getTargetInfo().setAddress(targetRest.getAddress()); + } + if (targetRest.getSecurityToken() != null) { + existingTarget.setSecurityToken(targetRest.getSecurityToken()); + } + final Target updateTarget = this.targetManagement.updateTarget(existingTarget); return new ResponseEntity<>(MgmtTargetMapper.toResponse(updateTarget), HttpStatus.OK); diff --git a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index ed6ee4a93..a528438bb 100644 --- a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -355,6 +355,54 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy); } + @Test + @Description("Ensures that target update request is reflected by repository.") + public void updateTargetSecurityToken() throws Exception { + final String knownControllerId = "123"; + final String knownNewToken = "6567576565"; + final String knownNameNotModiy = "nameNotModiy"; + final String body = new JSONObject().put("securityToken", knownNewToken).toString(); + + // prepare + final Target t = entityFactory.generateTarget(knownControllerId); + t.setName(knownNameNotModiy); + targetManagement.createTarget(t); + + mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) + .andExpect(jsonPath("$.securityToken", equalTo(knownNewToken))) + .andExpect(jsonPath("$.name", equalTo(knownNameNotModiy))); + + final Target findTargetByControllerID = targetManagement.findTargetByControllerID(knownControllerId); + assertThat(findTargetByControllerID.getSecurityToken()).isEqualTo(knownNewToken); + assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy); + } + + @Test + @Description("Ensures that target update request is reflected by repository.") + public void updateTargetAddress() throws Exception { + final String knownControllerId = "123"; + final String knownNewAddress = "amqp://test123/foobar"; + final String knownNameNotModiy = "nameNotModiy"; + final String body = new JSONObject().put("address", knownNewAddress).toString(); + + // prepare + final Target t = entityFactory.generateTarget(knownControllerId); + t.setName(knownNameNotModiy); + targetManagement.createTarget(t); + + mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) + .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) + .andExpect(jsonPath("$.name", equalTo(knownNameNotModiy))); + + final Target findTargetByControllerID = targetManagement.findTargetByControllerID(knownControllerId); + assertThat(findTargetByControllerID.getTargetInfo().getAddress().toString()).isEqualTo(knownNewAddress); + assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy); + } + @Test @Description("Ensures that target query returns list of targets in defined format.") public void getTargetWithoutAddtionalRequestParameters() throws Exception { @@ -679,7 +727,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { @Test public void createTargetsListReturnsSuccessful() throws Exception { - final Target test1 = entityFactory.generateTarget("id1"); + final Target test1 = entityFactory.generateTarget("id1", "token"); test1.setDescription("testid1"); test1.setName("testname1"); test1.getTargetInfo().setAddress("amqp://test123/foobar"); @@ -696,7 +744,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { targets.add(test3); final MvcResult mvcResult = mvc - .perform(post("/rest/v1/targets/").content(JsonBuilder.targets(targets)) + .perform(post("/rest/v1/targets/").content(JsonBuilder.targets(targets, true)) .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) @@ -705,6 +753,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { .andExpect(jsonPath("[0].description", equalTo("testid1"))) .andExpect(jsonPath("[0].createdAt", not(equalTo(0)))) .andExpect(jsonPath("[0].createdBy", equalTo("bumlux"))) + .andExpect(jsonPath("[0].securityToken", equalTo("token"))) .andExpect(jsonPath("[0].address", equalTo("amqp://test123/foobar"))) .andExpect(jsonPath("[1].name", equalTo("testname2"))) .andExpect(jsonPath("[1].createdBy", equalTo("bumlux"))) @@ -731,6 +780,9 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { assertThat(targetManagement.findTargetByControllerID("id1")).isNotNull(); assertThat(targetManagement.findTargetByControllerID("id1").getName()).isEqualTo("testname1"); assertThat(targetManagement.findTargetByControllerID("id1").getDescription()).isEqualTo("testid1"); + assertThat(targetManagement.findTargetByControllerID("id1").getSecurityToken()).isEqualTo("token"); + assertThat(targetManagement.findTargetByControllerID("id1").getTargetInfo().getAddress().toString()) + .isEqualTo("amqp://test123/foobar"); assertThat(targetManagement.findTargetByControllerID("id2")).isNotNull(); assertThat(targetManagement.findTargetByControllerID("id2").getName()).isEqualTo("testname2"); assertThat(targetManagement.findTargetByControllerID("id2").getDescription()).isEqualTo("testid2"); diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/EntityFactory.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/EntityFactory.java index 7542cd2ce..87919729e 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/EntityFactory.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/EntityFactory.java @@ -287,6 +287,7 @@ public interface EntityFactory { /** * Generates an empty {@link Target} without persisting it. + * {@link Target#getSecurityToken()} is generated. * * @param controllerID * of the {@link Target} @@ -295,6 +296,19 @@ public interface EntityFactory { */ Target generateTarget(@NotEmpty String controllerID); + /** + * Generates an empty {@link Target} without persisting it. + * + * @param controllerID + * of the {@link Target} + * @param securityToken + * of the {@link Target} for authentication if enabled on tenant. + * Generates one if empty or null. + * + * @return {@link Target} object + */ + Target generateTarget(@NotEmpty String controllerID, @NotEmpty String securityToken); + /** * Generates an empty {@link TargetFilterQuery} without persisting it. * diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java index 56ab89ad3..c09b28a2f 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java @@ -58,4 +58,10 @@ public interface Target extends NamedEntity { */ String getSecurityToken(); + /** + * @param token + * new securityToken + */ + void setSecurityToken(String token); + } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java index a3792de54..51b59f08f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.Collection; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; @@ -87,6 +88,14 @@ public class JpaEntityFactory implements EntityFactory { return new JpaTarget(controllerId); } + @Override + public Target generateTarget(final String controllerId, final String securityToken) { + if (StringUtils.isEmpty(securityToken)) { + return new JpaTarget(controllerId); + } + return new JpaTarget(controllerId, securityToken); + } + @Override public TargetTag generateTargetTag() { return new JpaTargetTag(); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index 94f50ff0d..183405470 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -115,9 +115,21 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable targets) { + public static String targets(final List targets, final boolean withToken) { final StringBuilder builder = new StringBuilder(); builder.append("["); @@ -381,10 +377,12 @@ public abstract class JsonBuilder { final String address = target.getTargetInfo().getAddress() != null ? target.getTargetInfo().getAddress().toString() : null; + final String token = withToken ? target.getSecurityToken() : null; + builder.append(new JSONObject().put("controllerId", target.getControllerId()) .put("description", target.getDescription()).put("name", target.getName()).put("createdAt", "0") .put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh").put("updatedBy", "fghdfkjghdfkjh") - .put("address", address).toString()); + .put("address", address).put("securityToken", token).toString()); } catch (final Exception e) { e.printStackTrace(); } From f2fc1aa91ac548ec63c2db21bb02d5dc8a07708f Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Fri, 1 Jul 2016 16:40:07 +0200 Subject: [PATCH 31/52] Simulator throughpout improvements. Signed-off-by: Kai Zimmermann --- .../simulator/DeviceSimulatorUpdater.java | 40 +++++++------------ 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java index 81237beb7..69ed4fd4a 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java @@ -10,8 +10,6 @@ package org.eclipse.hawkbit.simulator; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.security.DigestOutputStream; import java.security.KeyManagementException; @@ -34,6 +32,7 @@ import org.apache.http.conn.ssl.SSLContextBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.eclipse.hawkbit.dmf.json.model.Artifact; +import org.eclipse.hawkbit.dmf.json.model.Artifact.UrlProtocol; import org.eclipse.hawkbit.dmf.json.model.SoftwareModule; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus; @@ -59,7 +58,7 @@ import com.google.common.io.ByteStreams; public class DeviceSimulatorUpdater { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceSimulatorUpdater.class); - private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(4); + private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(8); @Autowired private SpSenderService spSenderService; @@ -198,18 +197,14 @@ public class DeviceSimulatorUpdater { private static void handleArtifacts(final String targetToken, final List status, final Artifact artifact) { - artifact.getUrls().entrySet().forEach(entry -> { - switch (entry.getKey()) { - case HTTP: - case HTTPS: - status.add(downloadUrl(entry.getValue(), targetToken, artifact.getHashes().getSha1(), - artifact.getSize())); - break; - default: - // not supported yet - break; - } - }); + + if (artifact.getUrls().containsKey(UrlProtocol.HTTPS)) { + status.add(downloadUrl(artifact.getUrls().get(UrlProtocol.HTTPS), targetToken, + artifact.getHashes().getSha1(), artifact.getSize())); + } else if (artifact.getUrls().containsKey(UrlProtocol.HTTP)) { + status.add(downloadUrl(artifact.getUrls().get(UrlProtocol.HTTP), targetToken, + artifact.getHashes().getSha1(), artifact.getSize())); + } } private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash, @@ -236,22 +231,15 @@ public class DeviceSimulatorUpdater { return new UpdateStatus(ResponseStatus.ERROR, message); } - final File tempFile = File.createTempFile("uploadFile", null); - // Exception squid:S2070 - not used for hashing sensitive // data @SuppressWarnings("squid:S2070") final MessageDigest md = MessageDigest.getInstance("SHA-1"); - try (final DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(tempFile), md)) { - try (final BufferedOutputStream bdos = new BufferedOutputStream(dos)) { - try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) { - overallread = ByteStreams.copy(bis, bdos); - } - } - } finally { - if (tempFile != null && !tempFile.delete()) { - LOGGER.error("Could not delete temporary file: {}", tempFile); + try (final BufferedOutputStream bdos = new BufferedOutputStream( + new DigestOutputStream(ByteStreams.nullOutputStream(), md))) { + try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) { + overallread = ByteStreams.copy(bis, bdos); } } From 227b93c5271a2ea28eec81fc3c12da6626b42cae Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 5 Jul 2016 17:41:08 +0200 Subject: [PATCH 32/52] Added artifact download traffic statistics. Signed-off-by: Kai Zimmermann --- .../DownloadIdCacheAutoConfiguration.java | 2 +- .../cache/eventbus/EventDistributorTest.java | 8 ++--- .../eventbus/event/DownloadProgressEvent.java | 13 ++++++- .../resource/DdiArtifactDownloadTest.java | 26 +++++++++++--- .../repository/ControllerManagement.java | 4 ++- .../hawkbit/repository/SystemManagement.java | 11 ++++-- .../repository/TenantStatsManagement.java | 20 ++++++----- .../repository/report/model/TenantUsage.java | 30 +++++++++++++--- .../RepositoryApplicationConfiguration.java | 10 +++++- .../jpa/JpaControllerManagement.java | 4 +-- .../repository/jpa/JpaSystemManagement.java | 2 +- .../jpa/JpaTenantStatsManagement.java | 34 +++++++++++++++++-- .../jpa/cache/CacheWriteNotify.java | 7 ++-- .../jpa/cache/CacheWriteNotifyTest.java | 2 +- .../test/util/AbstractIntegrationTest.java | 4 +++ .../util/RestResourceConversionHelper.java | 6 +++- 16 files changed, 147 insertions(+), 36 deletions(-) diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/cache/DownloadIdCacheAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/cache/DownloadIdCacheAutoConfiguration.java index 495200dec..134b50d90 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/cache/DownloadIdCacheAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/cache/DownloadIdCacheAutoConfiguration.java @@ -31,7 +31,7 @@ public class DownloadIdCacheAutoConfiguration { private CacheManager cacheManager; /** - * Bean for the downlod id cache. + * Bean for the download id cache. * * @return the cache */ diff --git a/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java b/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java index c1ff54961..4dbc3ec9a 100644 --- a/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java +++ b/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java @@ -56,7 +56,7 @@ public class EventDistributorTest { @Test public void distributeDistributedEventSendsToRedis() { - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); underTest.distribute(event); // origin node ID should be set by distributing the event @@ -67,7 +67,7 @@ public class EventDistributorTest { @Test public void dontDistributeDistributedEventIfSameNode() { final String knownNodeId = EventDistributor.getNodeId(); - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); event.setNodeId(knownNodeId); // test @@ -79,7 +79,7 @@ public class EventDistributorTest { @Test public void handleDistributedMessageFromRedis() { - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); final String knownChannel = "someChannel"; underTest.handleMessage(event, knownChannel); @@ -90,7 +90,7 @@ public class EventDistributorTest { @Test public void handleDistributedMessageFilteredIfSameNodeId() { - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); final String knownChannel = "someChannel"; event.setOriginNodeId(EventDistributor.getNodeId()); diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java index 74679f02e..a4be22f70 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java @@ -21,6 +21,7 @@ public class DownloadProgressEvent extends AbstractDistributedEvent { private final Long statusId; private final int progressPercent; + private final long shippedBytes; /** * Constructor. @@ -32,13 +33,15 @@ public class DownloadProgressEvent extends AbstractDistributedEvent { * @param progressPercent * number (1-100) */ - public DownloadProgressEvent(final String tenant, final Long statusId, final int progressPercent) { + public DownloadProgressEvent(final String tenant, final Long statusId, final int progressPercent, + final long shippedBytes) { // the revision of the DownloadProgressEvent is just equal the // progressPercentage due the // percentage is going from 0 to 100. super(statusId, tenant); this.statusId = statusId; this.progressPercent = progressPercent; + this.shippedBytes = shippedBytes; } /** @@ -54,4 +57,12 @@ public class DownloadProgressEvent extends AbstractDistributedEvent { public int getProgressPercent() { return progressPercent; } + + /** + * @return the shippedBytes + */ + public long getShippedBytes() { + return shippedBytes; + } + } diff --git a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java index 7f12b78ae..73b8d3f35 100644 --- a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java +++ b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java @@ -29,11 +29,11 @@ import org.apache.commons.lang3.RandomUtils; import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; -import org.eclipse.hawkbit.repository.test.util.WithUser; import org.eclipse.hawkbit.repository.model.Artifact; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.test.util.WithUser; import org.eclipse.hawkbit.rest.AbstractRestIntegrationTestWithMongoDB; import org.junit.Test; import org.slf4j.LoggerFactory; @@ -59,11 +59,14 @@ import ru.yandex.qatools.allure.annotations.Stories; @Stories("Artifact Download Resource") public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMongoDB { + private static final int ARTIFACT_SIZE = 5 * 1024 * 1024; + public DdiArtifactDownloadTest() { LOG = LoggerFactory.getLogger(DdiArtifactDownloadTest.class); } private volatile int downLoadProgress = 0; + private volatile long shippedBytes = 0; @Autowired private EventBus eventBus; @@ -236,6 +239,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong @Description("Tests valid downloads through the artifact resource by identifying the artifact not by ID but file name.") public void downloadArtifactThroughFileName() throws Exception { downLoadProgress = 1; + shippedBytes = 0; + tenantStatsManagement.resetTrafficStatsOfTenant(); eventBus.register(this); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); @@ -249,7 +254,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong final DistributionSet ds = testdataFactory.createDistributionSet(""); // create artifact - final byte random[] = RandomUtils.nextBytes(5 * 1024 * 1024); + final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE); final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), ds.findFirstModuleByType(osType).getId(), "file1", false); @@ -276,6 +281,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong // download complete assertThat(downLoadProgress).isEqualTo(10); + assertThat(shippedBytes).isEqualTo(ARTIFACT_SIZE) + .isEqualTo(tenantStatsManagement.getStatsOfTenant().getOverallArtifactTrafficInBytes()); } @Test @@ -313,6 +320,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong + "anonymous as authorization is notpossible, e.g. chekc if the controller has the artifact assigned.") public void downloadArtifactByNameFailsIfNotAuthenticated() throws Exception { downLoadProgress = 1; + shippedBytes = 0; + tenantStatsManagement.resetTrafficStatsOfTenant(); eventBus.register(this); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); @@ -327,7 +336,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong final DistributionSet ds = testdataFactory.createDistributionSet(""); // create artifact - final byte random[] = RandomUtils.nextBytes(5 * 1024); + final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE); final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false); @@ -335,6 +344,10 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong deploymentManagement.assignDistributionSet(ds, targets); mvc.perform(get("/controller/artifacts/v1/filename/{filename}", "file1.tar.bz2")) .andExpect(status().isNotFound()); + + assertThat(downLoadProgress).isEqualTo(1); + assertThat(shippedBytes).isEqualTo(0) + .isEqualTo(tenantStatsManagement.getStatsOfTenant().getOverallArtifactTrafficInBytes()); } @Test @@ -342,6 +355,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong @Description("Ensures that an authenticated and named controller is permitted to download.") public void downloadArtifactByNameByNamedController() throws Exception { downLoadProgress = 1; + shippedBytes = 0; + tenantStatsManagement.resetTrafficStatsOfTenant(); eventBus.register(this); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); @@ -356,7 +371,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong final DistributionSet ds = testdataFactory.createDistributionSet(""); // create artifact - final byte random[] = RandomUtils.nextBytes(5 * 1024 * 1024); + final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE); final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), ds.findFirstModuleByType(osType).getId(), "file1", false); @@ -389,6 +404,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong // download complete assertThat(downLoadProgress).isEqualTo(10); + assertThat(shippedBytes).isEqualTo(ARTIFACT_SIZE) + .isEqualTo(tenantStatsManagement.getStatsOfTenant().getOverallArtifactTrafficInBytes()); } @Test @@ -550,5 +567,6 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong @Subscribe public void listen(final DownloadProgressEvent event) { downLoadProgress++; + shippedBytes += event.getShippedBytes(); } } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java index 531da8819..0525bb201 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java @@ -65,9 +65,11 @@ public interface ControllerManagement { * the ID of the {@link ActionStatus} * @param progressPercent * the progress in percentage which must be between 0-100 + * @param shippedBytes + * since last event */ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) - void downloadProgressPercent(long statusId, int progressPercent); + void downloadProgressPercent(long statusId, int progressPercent, long shippedBytes); /** * Simple addition of a new {@link ActionStatus} entry to the {@link Action} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index 039e4ae13..8797ada5c 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -63,13 +63,18 @@ public interface SystemManagement { /** * @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} */ + // @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + + // SpringEvalExpressions.HAS_AUTH_OR + // + SpringEvalExpressions.HAS_AUTH_READ_TARGET + + // SpringEvalExpressions.HAS_AUTH_OR + // + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantMetaData getTenantMetadata(); /** * Returns {@link TenantMetaData} of given and current tenant. Creates for * new tenants also two {@link SoftwareModuleType} (os and app) and - * {@link RepositoryConstants#DEFAULT_DS_TYPES_IN_TENANT} {@link DistributionSetType}s - * (os and os_app). + * {@link RepositoryConstants#DEFAULT_DS_TYPES_IN_TENANT} + * {@link DistributionSetType}s (os and os_app). * * DISCLAIMER: this variant is used during initial login (where the tenant * is not yet in the session). Please user {@link #getTenantMetadata()} for @@ -79,6 +84,7 @@ public interface SystemManagement { * to retrieve data for * @return {@link TenantMetaData} of given tenant */ + // @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE) TenantMetaData getTenantMetadata(@NotNull String tenant); /** @@ -88,6 +94,7 @@ public interface SystemManagement { * to update * @return updated {@link TenantMetaData} entity */ + // @PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantMetaData updateTenantMetadata(@NotNull TenantMetaData metaData); } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java index 6d390c03c..48a012b06 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java @@ -16,19 +16,23 @@ import org.springframework.security.access.prepost.PreAuthorize; * Management service for statistics of a single tenant. * */ -@FunctionalInterface public interface TenantStatsManagement { /** - * Service for stats of a single tenant. Opens a new transaction and as a - * result can an be used for multiple tenants, i.e. to allow in one session - * to collect data of all tenants in the system. + * Service for stats of a single tenant. * - * @param tenant - * to collect for * @return collected statistics */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN) - TenantUsage getStatsOfTenant(String tenant); + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + TenantUsage getStatsOfTenant(); + + /** + * Resets {@link TenantUsage#getOverallArtifactTrafficInBytes()} to zero. + * + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + void resetTrafficStatsOfTenant(); } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/TenantUsage.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/TenantUsage.java index 5467099c4..76b2baaa0 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/TenantUsage.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/TenantUsage.java @@ -19,6 +19,7 @@ public class TenantUsage { private long artifacts; private long actions; private long overallArtifactVolumeInBytes; + private long overallArtifactTrafficInBytes; /** * Constructor. @@ -105,12 +106,28 @@ public class TenantUsage { return this; } + /** + * @return the overallArtifactTrafficInBytes + */ + public long getOverallArtifactTrafficInBytes() { + return overallArtifactTrafficInBytes; + } + + /** + * @param overallArtifactTrafficInBytes + * the overallArtifactTrafficInBytes to set + */ + public void setOverallArtifactTrafficInBytes(final long overallArtifactTrafficInBytes) { + this.overallArtifactTrafficInBytes = overallArtifactTrafficInBytes; + } + @Override - public int hashCode() { // NOSONAR - as this is generated code + public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (actions ^ (actions >>> 32)); result = prime * result + (int) (artifacts ^ (artifacts >>> 32)); + result = prime * result + (int) (overallArtifactTrafficInBytes ^ (overallArtifactTrafficInBytes >>> 32)); result = prime * result + (int) (overallArtifactVolumeInBytes ^ (overallArtifactVolumeInBytes >>> 32)); result = prime * result + (int) (targets ^ (targets >>> 32)); result = prime * result + ((tenantName == null) ? 0 : tenantName.hashCode()); @@ -118,8 +135,7 @@ public class TenantUsage { } @Override - public boolean equals(final Object obj) { // NOSONAR - as this is generated - // code + public boolean equals(final Object obj) { if (this == obj) { return true; } @@ -136,6 +152,9 @@ public class TenantUsage { if (artifacts != other.artifacts) { return false; } + if (overallArtifactTrafficInBytes != other.overallArtifactTrafficInBytes) { + return false; + } if (overallArtifactVolumeInBytes != other.overallArtifactVolumeInBytes) { return false; } @@ -154,8 +173,9 @@ public class TenantUsage { @Override public String toString() { - return "SystemUsage [tenantName=" + tenantName + ", targets=" + targets + ", artifacts=" + artifacts - + ", actions=" + actions + ", overallArtifactVolumeInBytes=" + overallArtifactVolumeInBytes + "]"; + return "TenantUsage [tenantName=" + tenantName + ", targets=" + targets + ", artifacts=" + artifacts + + ", actions=" + actions + ", overallArtifactVolumeInBytes=" + overallArtifactVolumeInBytes + + ", overallArtifactTrafficInBytes=" + overallArtifactTrafficInBytes + "]"; } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java index 217fe8801..7236cbe79 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java @@ -54,6 +54,7 @@ import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManage import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration; @@ -71,6 +72,8 @@ import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; +import com.google.common.eventbus.EventBus; + /** * General configuration for hawkBit's Repository. * @@ -85,6 +88,9 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess @EnableConfigurationProperties(RepositoryProperties.class) @EnableScheduling public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { + @Autowired + private EventBus eventBus; + /** * @return the {@link SystemSecurityContext} singleton bean which make it * accessible in beans which cannot access the service directly, @@ -249,7 +255,9 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { @Bean @ConditionalOnMissingBean public TenantStatsManagement tenantStatsManagement() { - return new JpaTenantStatsManagement(); + final TenantStatsManagement mgmt = new JpaTenantStatsManagement(); + eventBus.register(mgmt); + return mgmt; } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java index b9dfce105..eb494ab7a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java @@ -469,8 +469,8 @@ public class JpaControllerManagement implements ControllerManagement { } @Override - public void downloadProgressPercent(final long statusId, final int progressPercent) { - cacheWriteNotify.downloadProgressPercent(statusId, progressPercent); + public void downloadProgressPercent(final long statusId, final int progressPercent, final long shippedBytes) { + cacheWriteNotify.downloadProgressPercent(statusId, progressPercent, shippedBytes); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java index ea6c99708..1786dc976 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java @@ -147,7 +147,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst final List tenants = findTenants(); tenants.forEach(tenant -> tenantAware.runAsTenant(tenant, () -> { - report.addTenantData(systemStatsManagement.getStatsOfTenant(tenant)); + report.addTenantData(systemStatsManagement.getStatsOfTenant()); return null; })); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java index 75f99d886..ecae92c72 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java @@ -8,17 +8,23 @@ */ package org.eclipse.hawkbit.repository.jpa; +import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.repository.TenantStatsManagement; import org.eclipse.hawkbit.repository.report.model.TenantUsage; +import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import com.google.common.eventbus.Subscribe; + /** * Management service for statistics of a single tenant. * @@ -35,9 +41,16 @@ public class JpaTenantStatsManagement implements TenantStatsManagement { @Autowired private ActionRepository actionRepository; + @Autowired + private TenantAware tenantAware; + + private final Map traffic = new ConcurrentHashMap<>(); + @Override @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED) - public TenantUsage getStatsOfTenant(final String tenant) { + public TenantUsage getStatsOfTenant() { + final String tenant = tenantAware.getCurrentTenant(); + final TenantUsage result = new TenantUsage(tenant); result.setTargets(targetRepository.count()); @@ -51,9 +64,26 @@ public class JpaTenantStatsManagement implements TenantStatsManagement { } result.setActions(actionRepository.count()); + if (traffic.containsKey(tenant)) { + result.setOverallArtifactTrafficInBytes(traffic.get(tenant).get()); + } return result; } + @Override + public void resetTrafficStatsOfTenant() { + traffic.remove(tenantAware.getCurrentTenant()); + } + + @Subscribe + public void listen(final DownloadProgressEvent event) { + if (traffic.containsKey(event.getTenant())) { + traffic.get(event.getTenant()).addAndGet(event.getShippedBytes()); + } else { + traffic.put(event.getTenant(), new AtomicLong(event.getShippedBytes())); + } + } + } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java index fdaf868e8..1f186821c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java @@ -54,8 +54,10 @@ public class CacheWriteNotify { * the ID of the {@link ActionStatus} * @param progressPercent * the progress in percentage which must be between 0-100 + * @param shippedBytes + * since last event */ - public void downloadProgressPercent(final long statusId, final int progressPercent) { + public void downloadProgressPercent(final long statusId, final int progressPercent, final long shippedBytes) { final Cache cache = cacheManager.getCache(Action.class.getName()); final String cacheKey = CacheKeys.entitySpecificCacheKey(String.valueOf(statusId), @@ -69,7 +71,8 @@ public class CacheWriteNotify { cache.evict(cacheKey); } - eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, progressPercent)); + eventBus.post( + new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, progressPercent, shippedBytes)); } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java index 603af17c9..37538086d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java @@ -64,7 +64,7 @@ public class CacheWriteNotifyTest { when(cacheManagerMock.getCache(Action.class.getName())).thenReturn(cacheMock); when(tenantAwareMock.getCurrentTenant()).thenReturn("default"); - underTest.downloadProgressPercent(knownStatusId, knownPercentage); + underTest.downloadProgressPercent(knownStatusId, knownPercentage, 100L); verify(cacheManagerMock).getCache(eq(Action.class.getName())); verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, knownPercentage); diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index 3d09fabc3..63dcfaad0 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -23,6 +23,7 @@ import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.TenantStatsManagement; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.security.DosFilter; @@ -93,6 +94,9 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { @Autowired protected TargetManagement targetManagement; + @Autowired + protected TenantStatsManagement tenantStatsManagement; + @Autowired protected TargetFilterQueryManagement targetFilterQueryManagement; diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java index 875152e0e..53ed28d40 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java @@ -293,6 +293,7 @@ public final class RestResourceConversionHelper { long toRead = length; boolean toContinue = true; + long shippedSinceLastEvent = 0; while (toContinue) { final int r = from.read(buf); @@ -304,9 +305,11 @@ public final class RestResourceConversionHelper { if (toRead > 0) { to.write(buf, 0, r); total += r; + shippedSinceLastEvent += r; } else { to.write(buf, 0, (int) toRead + r); total += toRead + r; + shippedSinceLastEvent += toRead + r; toContinue = false; } @@ -316,7 +319,8 @@ public final class RestResourceConversionHelper { // every 10 percent an event if (newPercent == 100 || newPercent > progressPercent + 10) { progressPercent = newPercent; - controllerManagement.downloadProgressPercent(statusId, progressPercent); + controllerManagement.downloadProgressPercent(statusId, progressPercent, shippedSinceLastEvent); + shippedSinceLastEvent = 0; } } } From 3a72627940bcced491c168595515dcb95c19e18c Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 6 Jul 2016 09:17:31 +0200 Subject: [PATCH 33/52] Add traffic stats to mgmt API Signed-off-by: Kai Zimmermann --- .../systemmanagement/MgmtSystemTenantServiceUsage.java | 10 +++++++++- .../rest/resource/MgmtSystemManagementResource.java | 1 + .../hawkbit/repository/TenantStatsManagement.java | 6 ++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/systemmanagement/MgmtSystemTenantServiceUsage.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/systemmanagement/MgmtSystemTenantServiceUsage.java index 8cce4314b..8086323de 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/systemmanagement/MgmtSystemTenantServiceUsage.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/systemmanagement/MgmtSystemTenantServiceUsage.java @@ -25,6 +25,7 @@ public class MgmtSystemTenantServiceUsage { private long artifacts; private long actions; private long overallArtifactVolumeInBytes; + private long overallArtifactTrafficInBytes; /** * Constructor. @@ -32,10 +33,17 @@ public class MgmtSystemTenantServiceUsage { * @param tenantName */ public MgmtSystemTenantServiceUsage(final String tenantName) { - super(); this.tenantName = tenantName; } + public long getOverallArtifactTrafficInBytes() { + return overallArtifactTrafficInBytes; + } + + public void setOverallArtifactTrafficInBytes(final long overallArtifactTrafficInBytes) { + this.overallArtifactTrafficInBytes = overallArtifactTrafficInBytes; + } + public long getTargets() { return targets; } diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java index 3392d2659..d1586a299 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java @@ -87,6 +87,7 @@ public class MgmtSystemManagementResource implements MgmtSystemManagementRestApi result.setArtifacts(tenant.getArtifacts()); result.setOverallArtifactVolumeInBytes(tenant.getOverallArtifactVolumeInBytes()); result.setTargets(tenant.getTargets()); + result.setOverallArtifactTrafficInBytes(tenant.getOverallArtifactTrafficInBytes()); return result; } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java index 48a012b06..9811b3c1a 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java @@ -25,14 +25,16 @@ public interface TenantStatsManagement { */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.IS_SYSTEM_CODE) TenantUsage getStatsOfTenant(); /** * Resets {@link TenantUsage#getOverallArtifactTrafficInBytes()} to zero. * */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.IS_SYSTEM_CODE) void resetTrafficStatsOfTenant(); } \ No newline at end of file From 2dee45ca9c63994428c2cb6bda58795f26939a0f Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Thu, 7 Jul 2016 11:43:18 +0200 Subject: [PATCH 34/52] Fixed JavaDoc. Signed-off-by: Kai Zimmermann --- .../eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java index a4be22f70..0ecc13bbf 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java @@ -29,7 +29,7 @@ public class DownloadProgressEvent extends AbstractDistributedEvent { * @param tenant * the tenant for this event * @param statusId - * of {@link UpdateActionStatus} + * of {@link Action} * @param progressPercent * number (1-100) */ From a9204fe5ebe558221dffa629324672a5beaa08d5 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Thu, 7 Jul 2016 13:20:04 +0200 Subject: [PATCH 35/52] Removed commented code. Signed-off-by: kaizimmerm --- .../org/eclipse/hawkbit/repository/SystemManagement.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index 8797ada5c..76a48a173 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -63,11 +63,6 @@ public interface SystemManagement { /** * @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} */ - // @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + - // SpringEvalExpressions.HAS_AUTH_OR - // + SpringEvalExpressions.HAS_AUTH_READ_TARGET + - // SpringEvalExpressions.HAS_AUTH_OR - // + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantMetaData getTenantMetadata(); /** @@ -84,7 +79,6 @@ public interface SystemManagement { * to retrieve data for * @return {@link TenantMetaData} of given tenant */ - // @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE) TenantMetaData getTenantMetadata(@NotNull String tenant); /** @@ -94,7 +88,6 @@ public interface SystemManagement { * to update * @return updated {@link TenantMetaData} entity */ - // @PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantMetaData updateTenantMetadata(@NotNull TenantMetaData metaData); } \ No newline at end of file From 8fb2bd43224e79c5fc8aedfef95e6b27a5038ddd Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Thu, 7 Jul 2016 14:46:29 +0200 Subject: [PATCH 36/52] Fixed download progress event. Signed-off-by: kaizimmerm --- .../cache/eventbus/EventDistributorTest.java | 8 ++--- .../eventbus/event/DownloadProgressEvent.java | 30 +++++++++---------- .../resource/DdiArtifactStoreController.java | 10 +++---- .../ddi/rest/resource/DdiRootController.java | 10 +++---- .../resource/DdiArtifactDownloadTest.java | 24 +++++++-------- .../MgmtSystemTenantServiceUsage.java | 9 ------ .../MgmtSystemManagementResource.java | 1 - .../repository/ControllerManagement.java | 13 +++++--- .../repository/TenantStatsManagement.java | 8 ----- .../repository/report/model/TenantUsage.java | 25 ++-------------- .../jpa/JpaControllerManagement.java | 9 +++--- .../jpa/JpaTenantStatsManagement.java | 25 ---------------- .../jpa/cache/CacheWriteNotify.java | 14 +++++---- .../jpa/cache/CacheWriteNotifyTest.java | 8 ++--- .../util/RestResourceConversionHelper.java | 6 ++-- 15 files changed, 73 insertions(+), 127 deletions(-) diff --git a/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java b/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java index 4dbc3ec9a..1f5b41581 100644 --- a/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java +++ b/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java @@ -56,7 +56,7 @@ public class EventDistributorTest { @Test public void distributeDistributedEventSendsToRedis() { - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L); underTest.distribute(event); // origin node ID should be set by distributing the event @@ -67,7 +67,7 @@ public class EventDistributorTest { @Test public void dontDistributeDistributedEventIfSameNode() { final String knownNodeId = EventDistributor.getNodeId(); - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L); event.setNodeId(knownNodeId); // test @@ -79,7 +79,7 @@ public class EventDistributorTest { @Test public void handleDistributedMessageFromRedis() { - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L); final String knownChannel = "someChannel"; underTest.handleMessage(event, knownChannel); @@ -90,7 +90,7 @@ public class EventDistributorTest { @Test public void handleDistributedMessageFilteredIfSameNodeId() { - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L); final String knownChannel = "someChannel"; event.setOriginNodeId(EventDistributor.getNodeId()); diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java index 0ecc13bbf..81ee0468a 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java @@ -21,7 +21,8 @@ public class DownloadProgressEvent extends AbstractDistributedEvent { private final Long statusId; private final int progressPercent; - private final long shippedBytes; + private final long shippedBytesSinceLast; + private final long shippedBytesOverall; /** * Constructor. @@ -29,40 +30,39 @@ public class DownloadProgressEvent extends AbstractDistributedEvent { * @param tenant * the tenant for this event * @param statusId - * of {@link Action} + * of {@link ActionStatus} * @param progressPercent * number (1-100) + * @param shippedBytesSinceLast + * bytes since last event + * @param shippedBytesOverall + * on the download request */ public DownloadProgressEvent(final String tenant, final Long statusId, final int progressPercent, - final long shippedBytes) { + final long shippedBytesSinceLast, final long shippedBytesOverall) { // the revision of the DownloadProgressEvent is just equal the // progressPercentage due the // percentage is going from 0 to 100. super(statusId, tenant); this.statusId = statusId; this.progressPercent = progressPercent; - this.shippedBytes = shippedBytes; + this.shippedBytesSinceLast = shippedBytesSinceLast; + this.shippedBytesOverall = shippedBytesOverall; } - /** - * @return the statusId - */ public Long getStatusId() { return statusId; } - /** - * @return the progressPercent - */ public int getProgressPercent() { return progressPercent; } - /** - * @return the shippedBytes - */ - public long getShippedBytes() { - return shippedBytes; + public long getShippedBytesSinceLast() { + return shippedBytesSinceLast; } + public long getShippedBytesOverall() { + return shippedBytesOverall; + } } diff --git a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactStoreController.java b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactStoreController.java index 75d502c47..e2af0a873 100644 --- a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactStoreController.java +++ b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactStoreController.java @@ -93,12 +93,12 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR // we set a download status only if we are aware of the // targetid, i.e. authenticated and not anonymous if (targetid != null && !"anonymous".equals(targetid)) { - final Action action = checkAndReportDownloadByTarget( + final ActionStatus actionStatus = checkAndReportDownloadByTarget( requestResponseContextHolder.getHttpServletRequest(), targetid, artifact); result = RestResourceConversionHelper.writeFileResponse(artifact, requestResponseContextHolder.getHttpServletResponse(), requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement, - action.getId()); + actionStatus.getId()); } else { result = RestResourceConversionHelper.writeFileResponse(artifact, requestResponseContextHolder.getHttpServletResponse(), @@ -131,7 +131,7 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR return new ResponseEntity<>(HttpStatus.OK); } - private Action checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid, + private ActionStatus checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid, final LocalArtifact artifact) { final Target target = controllerManagement.updateLastTargetQuery(targetid, IpUtil.getClientIpFromRequest(request, securityProperties)); @@ -152,8 +152,8 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR actionStatus.addMessage( RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI()); } - controllerManagement.addInformationalActionStatus(actionStatus); - return action; + + return controllerManagement.addInformationalActionStatus(actionStatus); } } diff --git a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java index 120e6c246..9dd65d5fc 100644 --- a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java +++ b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java @@ -156,8 +156,8 @@ public class DdiRootController implements DdiRootControllerRestApi { if (ifMatch != null && !RestResourceConversionHelper.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) { result = new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED); } else { - final Action action = checkAndLogDownload(requestResponseContextHolder.getHttpServletRequest(), target, - module); + final ActionStatus action = checkAndLogDownload(requestResponseContextHolder.getHttpServletRequest(), + target, module); result = RestResourceConversionHelper.writeFileResponse(artifact, requestResponseContextHolder.getHttpServletResponse(), requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement, @@ -167,7 +167,7 @@ public class DdiRootController implements DdiRootControllerRestApi { return result; } - private Action checkAndLogDownload(final HttpServletRequest request, final Target target, + private ActionStatus checkAndLogDownload(final HttpServletRequest request, final Target target, final SoftwareModule module) { final Action action = controllerManagement .getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), module); @@ -185,8 +185,8 @@ public class DdiRootController implements DdiRootControllerRestApi { statusMessage.addMessage( RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads " + request.getRequestURI()); } - controllerManagement.addInformationalActionStatus(statusMessage); - return action; + + return controllerManagement.addInformationalActionStatus(statusMessage); } private static boolean checkModule(final String fileName, final SoftwareModule module) { diff --git a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java index 73b8d3f35..c878fa6a7 100644 --- a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java +++ b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java @@ -67,6 +67,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong private volatile int downLoadProgress = 0; private volatile long shippedBytes = 0; + private volatile long shippedBytesTotal = 0; @Autowired private EventBus eventBus; @@ -240,7 +241,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong public void downloadArtifactThroughFileName() throws Exception { downLoadProgress = 1; shippedBytes = 0; - tenantStatsManagement.resetTrafficStatsOfTenant(); + shippedBytesTotal = 0; eventBus.register(this); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); @@ -281,8 +282,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong // download complete assertThat(downLoadProgress).isEqualTo(10); - assertThat(shippedBytes).isEqualTo(ARTIFACT_SIZE) - .isEqualTo(tenantStatsManagement.getStatsOfTenant().getOverallArtifactTrafficInBytes()); + assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(ARTIFACT_SIZE); } @Test @@ -321,7 +321,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong public void downloadArtifactByNameFailsIfNotAuthenticated() throws Exception { downLoadProgress = 1; shippedBytes = 0; - tenantStatsManagement.resetTrafficStatsOfTenant(); + shippedBytesTotal = 0; eventBus.register(this); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); @@ -329,7 +329,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong // create target Target target = entityFactory.generateTarget("4712"); target = targetManagement.createTarget(target); - final List targets = new ArrayList(); + final List targets = new ArrayList<>(); targets.add(target); // create ds @@ -337,7 +337,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong // create artifact final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE); - final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), + artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false); // download fails as artifact is not yet assigned to target @@ -346,8 +346,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong .andExpect(status().isNotFound()); assertThat(downLoadProgress).isEqualTo(1); - assertThat(shippedBytes).isEqualTo(0) - .isEqualTo(tenantStatsManagement.getStatsOfTenant().getOverallArtifactTrafficInBytes()); + assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(0L); } @Test @@ -356,7 +355,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong public void downloadArtifactByNameByNamedController() throws Exception { downLoadProgress = 1; shippedBytes = 0; - tenantStatsManagement.resetTrafficStatsOfTenant(); + shippedBytesTotal = 0; eventBus.register(this); assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0); @@ -404,8 +403,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong // download complete assertThat(downLoadProgress).isEqualTo(10); - assertThat(shippedBytes).isEqualTo(ARTIFACT_SIZE) - .isEqualTo(tenantStatsManagement.getStatsOfTenant().getOverallArtifactTrafficInBytes()); + assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(ARTIFACT_SIZE); } @Test @@ -567,6 +565,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong @Subscribe public void listen(final DownloadProgressEvent event) { downLoadProgress++; - shippedBytes += event.getShippedBytes(); + shippedBytes += event.getShippedBytesSinceLast(); + shippedBytesTotal = event.getShippedBytesOverall(); + } } diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/systemmanagement/MgmtSystemTenantServiceUsage.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/systemmanagement/MgmtSystemTenantServiceUsage.java index 8086323de..c3e37421d 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/systemmanagement/MgmtSystemTenantServiceUsage.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/systemmanagement/MgmtSystemTenantServiceUsage.java @@ -25,7 +25,6 @@ public class MgmtSystemTenantServiceUsage { private long artifacts; private long actions; private long overallArtifactVolumeInBytes; - private long overallArtifactTrafficInBytes; /** * Constructor. @@ -36,14 +35,6 @@ public class MgmtSystemTenantServiceUsage { this.tenantName = tenantName; } - public long getOverallArtifactTrafficInBytes() { - return overallArtifactTrafficInBytes; - } - - public void setOverallArtifactTrafficInBytes(final long overallArtifactTrafficInBytes) { - this.overallArtifactTrafficInBytes = overallArtifactTrafficInBytes; - } - public long getTargets() { return targets; } diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java index d1586a299..3392d2659 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java @@ -87,7 +87,6 @@ public class MgmtSystemManagementResource implements MgmtSystemManagementRestApi result.setArtifacts(tenant.getArtifacts()); result.setOverallArtifactVolumeInBytes(tenant.getOverallArtifactVolumeInBytes()); result.setTargets(tenant.getTargets()); - result.setOverallArtifactTrafficInBytes(tenant.getOverallArtifactTrafficInBytes()); return result; } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java index 0525bb201..1b20c3bf8 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java @@ -65,11 +65,14 @@ public interface ControllerManagement { * the ID of the {@link ActionStatus} * @param progressPercent * the progress in percentage which must be between 0-100 - * @param shippedBytes - * since last event + * @param shippedBytesSinceLast + * since the last report + * @param shippedBytesOverall + * for the {@link ActionStatus} */ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) - void downloadProgressPercent(long statusId, int progressPercent, long shippedBytes); + void downloadProgressPercent(long statusId, int progressPercent, long shippedBytesSinceLast, + long shippedBytesOverall); /** * Simple addition of a new {@link ActionStatus} entry to the {@link Action} @@ -77,9 +80,11 @@ public interface ControllerManagement { * * @param statusMessage * to add to the action + * + * @return create {@link ActionStatus} entity */ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) - void addInformationalActionStatus(@NotNull ActionStatus statusMessage); + ActionStatus addInformationalActionStatus(@NotNull ActionStatus statusMessage); /** * Adds an {@link ActionStatus} entry for an update {@link Action} including diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java index 9811b3c1a..6430eb7c9 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java @@ -29,12 +29,4 @@ public interface TenantStatsManagement { + SpringEvalExpressions.IS_SYSTEM_CODE) TenantUsage getStatsOfTenant(); - /** - * Resets {@link TenantUsage#getOverallArtifactTrafficInBytes()} to zero. - * - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) - void resetTrafficStatsOfTenant(); - } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/TenantUsage.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/TenantUsage.java index 76b2baaa0..933ca564b 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/TenantUsage.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/TenantUsage.java @@ -19,7 +19,6 @@ public class TenantUsage { private long artifacts; private long actions; private long overallArtifactVolumeInBytes; - private long overallArtifactTrafficInBytes; /** * Constructor. @@ -106,28 +105,12 @@ public class TenantUsage { return this; } - /** - * @return the overallArtifactTrafficInBytes - */ - public long getOverallArtifactTrafficInBytes() { - return overallArtifactTrafficInBytes; - } - - /** - * @param overallArtifactTrafficInBytes - * the overallArtifactTrafficInBytes to set - */ - public void setOverallArtifactTrafficInBytes(final long overallArtifactTrafficInBytes) { - this.overallArtifactTrafficInBytes = overallArtifactTrafficInBytes; - } - @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (actions ^ (actions >>> 32)); result = prime * result + (int) (artifacts ^ (artifacts >>> 32)); - result = prime * result + (int) (overallArtifactTrafficInBytes ^ (overallArtifactTrafficInBytes >>> 32)); result = prime * result + (int) (overallArtifactVolumeInBytes ^ (overallArtifactVolumeInBytes >>> 32)); result = prime * result + (int) (targets ^ (targets >>> 32)); result = prime * result + ((tenantName == null) ? 0 : tenantName.hashCode()); @@ -142,7 +125,7 @@ public class TenantUsage { if (obj == null) { return false; } - if (getClass() != obj.getClass()) { + if (!(obj instanceof TenantUsage)) { return false; } final TenantUsage other = (TenantUsage) obj; @@ -152,9 +135,6 @@ public class TenantUsage { if (artifacts != other.artifacts) { return false; } - if (overallArtifactTrafficInBytes != other.overallArtifactTrafficInBytes) { - return false; - } if (overallArtifactVolumeInBytes != other.overallArtifactVolumeInBytes) { return false; } @@ -174,8 +154,7 @@ public class TenantUsage { @Override public String toString() { return "TenantUsage [tenantName=" + tenantName + ", targets=" + targets + ", artifacts=" + artifacts - + ", actions=" + actions + ", overallArtifactVolumeInBytes=" + overallArtifactVolumeInBytes - + ", overallArtifactTrafficInBytes=" + overallArtifactTrafficInBytes + "]"; + + ", actions=" + actions + ", overallArtifactVolumeInBytes=" + overallArtifactVolumeInBytes + "]"; } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java index eb494ab7a..f62335ec3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java @@ -451,8 +451,8 @@ public class JpaControllerManagement implements ControllerManagement { @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void addInformationalActionStatus(final ActionStatus statusMessage) { - actionStatusRepository.save((JpaActionStatus) statusMessage); + public ActionStatus addInformationalActionStatus(final ActionStatus statusMessage) { + return actionStatusRepository.save((JpaActionStatus) statusMessage); } @Override @@ -469,8 +469,9 @@ public class JpaControllerManagement implements ControllerManagement { } @Override - public void downloadProgressPercent(final long statusId, final int progressPercent, final long shippedBytes) { - cacheWriteNotify.downloadProgressPercent(statusId, progressPercent, shippedBytes); + public void downloadProgressPercent(final long statusId, final int progressPercent, + final long shippedBytesSinceLast, final long shippedBytesOverall) { + cacheWriteNotify.downloadProgressPercent(statusId, progressPercent, shippedBytesSinceLast, shippedBytesOverall); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java index ecae92c72..83f37304a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantStatsManagement.java @@ -8,12 +8,8 @@ */ package org.eclipse.hawkbit.repository.jpa; -import java.util.Map; import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; -import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.repository.TenantStatsManagement; import org.eclipse.hawkbit.repository.report.model.TenantUsage; import org.eclipse.hawkbit.tenancy.TenantAware; @@ -23,8 +19,6 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; -import com.google.common.eventbus.Subscribe; - /** * Management service for statistics of a single tenant. * @@ -44,8 +38,6 @@ public class JpaTenantStatsManagement implements TenantStatsManagement { @Autowired private TenantAware tenantAware; - private final Map traffic = new ConcurrentHashMap<>(); - @Override @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED) public TenantUsage getStatsOfTenant() { @@ -64,26 +56,9 @@ public class JpaTenantStatsManagement implements TenantStatsManagement { } result.setActions(actionRepository.count()); - if (traffic.containsKey(tenant)) { - result.setOverallArtifactTrafficInBytes(traffic.get(tenant).get()); - } return result; } - @Override - public void resetTrafficStatsOfTenant() { - traffic.remove(tenantAware.getCurrentTenant()); - } - - @Subscribe - public void listen(final DownloadProgressEvent event) { - if (traffic.containsKey(event.getTenant())) { - traffic.get(event.getTenant()).addAndGet(event.getShippedBytes()); - } else { - traffic.put(event.getTenant(), new AtomicLong(event.getShippedBytes())); - } - } - } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java index 1f186821c..3bcf8acc9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.repository.jpa.cache; import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent; -import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.tenancy.TenantAware; @@ -54,12 +53,15 @@ public class CacheWriteNotify { * the ID of the {@link ActionStatus} * @param progressPercent * the progress in percentage which must be between 0-100 - * @param shippedBytes + * @param shippedBytesSinceLast * since last event + * @param shippedBytesOverall + * for the download request */ - public void downloadProgressPercent(final long statusId, final int progressPercent, final long shippedBytes) { + public void downloadProgressPercent(final long statusId, final int progressPercent, + final long shippedBytesSinceLast, final long shippedBytesOverall) { - final Cache cache = cacheManager.getCache(Action.class.getName()); + final Cache cache = cacheManager.getCache(ActionStatus.class.getName()); final String cacheKey = CacheKeys.entitySpecificCacheKey(String.valueOf(statusId), CacheKeys.DOWNLOAD_PROGRESS_PERCENT); if (progressPercent < DOWNLOAD_PROGRESS_MAX) { @@ -71,8 +73,8 @@ public class CacheWriteNotify { cache.evict(cacheKey); } - eventBus.post( - new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, progressPercent, shippedBytes)); + eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, progressPercent, + shippedBytesSinceLast, shippedBytesOverall)); } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java index 37538086d..6a78852cb 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java @@ -14,7 +14,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; -import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.tenancy.TenantAware; import org.junit.Before; import org.junit.Test; @@ -61,12 +61,12 @@ public class CacheWriteNotifyTest { final long knownStatusId = 1; final int knownPercentage = 23; - when(cacheManagerMock.getCache(Action.class.getName())).thenReturn(cacheMock); + when(cacheManagerMock.getCache(ActionStatus.class.getName())).thenReturn(cacheMock); when(tenantAwareMock.getCurrentTenant()).thenReturn("default"); - underTest.downloadProgressPercent(knownStatusId, knownPercentage, 100L); + underTest.downloadProgressPercent(knownStatusId, knownPercentage, 100L, 500L); - verify(cacheManagerMock).getCache(eq(Action.class.getName())); + verify(cacheManagerMock).getCache(eq(ActionStatus.class.getName())); verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, knownPercentage); verify(eventBusMock).post(any(DownloadProgressEvent.class)); } diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java index 53ed28d40..bd0f8d007 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java @@ -23,6 +23,7 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.hawkbit.artifact.repository.model.DbArtifact; import org.eclipse.hawkbit.repository.ControllerManagement; +import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,7 +88,7 @@ public final class RestResourceConversionHelper { * @param controllerManagement * to write progress updates to * @param statusId - * of the UpdateActionStatus + * of the {@link ActionStatus} * * @return http code * @@ -319,7 +320,8 @@ public final class RestResourceConversionHelper { // every 10 percent an event if (newPercent == 100 || newPercent > progressPercent + 10) { progressPercent = newPercent; - controllerManagement.downloadProgressPercent(statusId, progressPercent, shippedSinceLastEvent); + controllerManagement.downloadProgressPercent(statusId, progressPercent, shippedSinceLastEvent, + total); shippedSinceLastEvent = 0; } } From 21bd2c33ace92acc20056524b4d1cf0f8e7f62f7 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 7 Jul 2016 16:45:07 +0200 Subject: [PATCH 37/52] Add IS_SYSTEM_CODE to all springEvalExpr and remove explicit usage Signed-off-by: Michael Hirsch --- .../repository/DeploymentManagement.java | 6 +- .../hawkbit/repository/RolloutManagement.java | 15 +- .../hawkbit/repository/SystemManagement.java | 10 +- .../TenantConfigurationManagement.java | 12 +- .../im/authentication/SpPermission.java | 133 +++++++++++------- 5 files changed, 96 insertions(+), 80 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index 9dc5f74c8..270de3e74 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -269,8 +269,7 @@ public interface DeploymentManagement { * @return the actions referring a specific rollout and a specific parent * rollout group in a specific status */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) List findActionsByRolloutGroupParentAndStatus(@NotNull Rollout rollout, @NotNull RolloutGroup rolloutGroupParent, @NotNull Action.Status actionStatus); @@ -496,8 +495,7 @@ public interface DeploymentManagement { * the action to start now. * @return the action which has been started */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) Action startScheduledAction(@NotNull Action action); /** diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java index 2c6e85dda..337475318 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java @@ -61,8 +61,7 @@ public interface RolloutManagement { * this check. This check is only applied if the last check is * less than (lastcheck-delay). */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) void checkRunningRollouts(long delayBetweenChecks); /** @@ -266,8 +265,7 @@ public interface RolloutManagement { * if given rollout is not in {@link RolloutStatus#RUNNING}. * Only running rollouts can be paused. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) void pauseRollout(@NotNull Rollout rollout); /** @@ -281,8 +279,7 @@ public interface RolloutManagement { * if given rollout is not in {@link RolloutStatus#PAUSED}. Only * paused rollouts can be resumed. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) void resumeRollout(@NotNull Rollout rollout); /** @@ -303,8 +300,7 @@ public interface RolloutManagement { * if given rollout is not in {@link RolloutStatus#READY}. Only * ready rollouts can be started. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) Rollout startRollout(@NotNull Rollout rollout); /** @@ -326,8 +322,7 @@ public interface RolloutManagement { * if given rollout is not in {@link RolloutStatus#READY}. Only * ready rollouts can be started. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) Rollout startRolloutAsync(@NotNull Rollout rollout); /** diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index 039e4ae13..a44b13d92 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -39,16 +39,14 @@ public interface SystemManagement { * @param tenant * to delete */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN) void deleteTenant(@NotNull String tenant); /** * * @return list of all tenant names in the system. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN) List findTenants(); /** @@ -68,8 +66,8 @@ public interface SystemManagement { /** * Returns {@link TenantMetaData} of given and current tenant. Creates for * new tenants also two {@link SoftwareModuleType} (os and app) and - * {@link RepositoryConstants#DEFAULT_DS_TYPES_IN_TENANT} {@link DistributionSetType}s - * (os and os_app). + * {@link RepositoryConstants#DEFAULT_DS_TYPES_IN_TENANT} + * {@link DistributionSetType}s (os and os_app). * * DISCLAIMER: this variant is used during initial login (where the tenant * is not yet in the session). Please user {@link #getTenantMetadata()} for diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 734704f05..9c467f9dd 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -54,8 +54,7 @@ public interface TenantConfigurationManagement { * @return if no default value is set and no database value available * or returns the tenant configuration value */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantConfigurationValue buildTenantConfigurationValueByKey(TenantConfigurationKey configurationKey, Class propertyType, TenantConfiguration tenantConfiguration); @@ -87,8 +86,7 @@ public interface TenantConfigurationManagement { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantConfigurationValue getConfigurationValue(TenantConfigurationKey configurationKey); /** @@ -114,8 +112,7 @@ public interface TenantConfigurationManagement { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantConfigurationValue getConfigurationValue(TenantConfigurationKey configurationKey, Class propertyType); @@ -139,7 +136,6 @@ public interface TenantConfigurationManagement { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) T getGlobalConfigurationValue(TenantConfigurationKey configurationKey, Class propertyType); } diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index 139954538..aace01248 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -224,8 +224,10 @@ public final class SpPermission { /* * Spring security eval expressions. */ - private static final String HAS_AUTH_PREFIX = "hasAuthority('"; - private static final String HAS_AUTH_SUFFIX = "')"; + private static final String BRACKET_OPEN = "("; + private static final String BRACKET_CLOSE = ")"; + private static final String HAS_AUTH_PREFIX = "hasAuthority" + BRACKET_OPEN + "'"; + private static final String HAS_AUTH_SUFFIX = "'" + BRACKET_CLOSE; private static final String HAS_AUTH_AND = " and "; /** @@ -258,81 +260,109 @@ public final class SpPermission { public static final String HAS_AUTH_OR = " or "; /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#UPDATE_TARGET}. + * Spring security eval hasAnyRole expression to check if the spring + * context contains system code role + * {@link SpringEvalExpressions#SYSTEM_ROLE}. */ - public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX; + public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SYSTEM_ROLE + HAS_AUTH_SUFFIX; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#SYSTEM_ADMIN}. + * context contains {@link SpPermission#UPDATE_TARGET} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_TARGET}. + * context contains {@link SpPermission#SYSTEM_ADMIN} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE;; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#CREATE_TARGET}. + * context contains {@link SpPermission#READ_TARGET} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + HAS_AUTH_OR + + IS_SYSTEM_CODE;; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#DELETE_TARGET}. + * context contains {@link SpPermission#CREATE_TARGET} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE;; + + /** + * Spring security eval hasAuthority expression to check if spring + * context contains {@link SpPermission#DELETE_TARGET} or + * {@link #IS_SYSTEM_CODE}. + */ + public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE;; /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#READ_REPOSITORY} and - * {@link SpPermission#UPDATE_TARGET}. + * {@link SpPermission#UPDATE_TARGET} or {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = HAS_AUTH_PREFIX + READ_REPOSITORY - + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX + + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#CREATE_REPOSITORY}. + * context contains {@link SpPermission#CREATE_REPOSITORY} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#DELETE_REPOSITORY}. + * context contains {@link SpPermission#DELETE_REPOSITORY} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_REPOSITORY}. + * context contains {@link SpPermission#READ_REPOSITORY} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#UPDATE_REPOSITORY}. + * context contains {@link SpPermission#UPDATE_REPOSITORY} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#READ_REPOSITORY} and - * {@link SpPermission#READ_TARGET}. + * {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = HAS_AUTH_PREFIX + READ_REPOSITORY - + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX + + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT}. + * context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT} or + * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + DOWNLOAD_REPOSITORY_ARTIFACT - + HAS_AUTH_SUFFIX; + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAnyRole expression to check if the spring @@ -350,57 +380,56 @@ public final class SpPermission { public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE + HAS_AUTH_SUFFIX; - /** - * Spring security eval hasAnyRole expression to check if the spring - * context contains system code role - * {@link SpringEvalExpressions#SYSTEM_ROLE}. - */ - public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SYSTEM_ROLE + HAS_AUTH_SUFFIX; - /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#CREATE_REPOSITORY} and - * {@link SpPermission#CREATE_TARGET}. + * {@link SpPermission#CREATE_TARGET} or {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_REPOSITORY - + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX + + CREATE_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} + * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} or + * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT - + HAS_AUTH_SUFFIX; + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and - * {@link SpPermission#READ_TARGET} + * {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = HAS_AUTH_PREFIX - + ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET - + HAS_AUTH_SUFFIX;; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX + + ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and - * {@link SpPermission#UPDATE_TARGET}. + * {@link SpPermission#UPDATE_TARGET} or {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT - + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = BRACKET_OPEN + HAS_AUTH_PREFIX + + ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + + HAS_AUTH_SUFFIX + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#TENANT_CONFIGURATION} + * context contains {@link SpPermission#TENANT_CONFIGURATION} or + * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION - + HAS_AUTH_SUFFIX; + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#SYSTEM_MONITOR} + * context contains {@link SpPermission#SYSTEM_MONITOR} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_SYSTEM_MONITOR = HAS_AUTH_PREFIX + SYSTEM_MONITOR + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_SYSTEM_MONITOR = HAS_AUTH_PREFIX + SYSTEM_MONITOR + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; private SpringEvalExpressions() { // utility class From c3586b02303570306a15cacc0ac557522a3f7cfb Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 8 Jul 2016 10:20:37 +0200 Subject: [PATCH 38/52] remove double ended semicolon Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/im/authentication/SpPermission.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index aace01248..7d52b7a01 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -280,7 +280,7 @@ public final class SpPermission { * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE;; + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring @@ -288,7 +288,7 @@ public final class SpPermission { * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + HAS_AUTH_OR - + IS_SYSTEM_CODE;; + + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring @@ -296,7 +296,7 @@ public final class SpPermission { * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE;; + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring @@ -304,7 +304,7 @@ public final class SpPermission { * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE;; + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring From 9a4903526aacc5b271326f6d26cb897d87efbebc Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Fri, 8 Jul 2016 13:00:47 +0200 Subject: [PATCH 39/52] Removed percentage from the event. Moved event into the repo API. Signed-off-by: kaizimmerm --- hawkbit-cache-redis/pom.xml | 6 ++++ .../cache/eventbus/EventDistributorTest.java | 10 +++--- .../resource/DdiArtifactDownloadTest.java | 2 +- .../repository/ControllerManagement.java | 13 ++++---- .../repository/TenantStatsManagement.java | 3 +- .../eventbus/event/DownloadProgressEvent.java | 33 +++++++++---------- .../hawkbit/repository/model/Action.java | 6 ---- .../repository/model/ActionStatus.java | 6 ++++ .../jpa/JpaControllerManagement.java | 6 ++-- .../jpa/cache/CacheWriteNotify.java | 25 +++++++------- .../repository/jpa/model/JpaAction.java | 19 ----------- .../repository/jpa/model/JpaActionStatus.java | 15 +++++++++ .../jpa/cache/CacheWriteNotifyTest.java | 7 ++-- .../test/util/AbstractIntegrationTest.java | 4 --- .../util/RestResourceConversionHelper.java | 3 +- 15 files changed, 78 insertions(+), 80 deletions(-) rename {hawkbit-core/src/main/java/org/eclipse/hawkbit => hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository}/eventbus/event/DownloadProgressEvent.java (68%) diff --git a/hawkbit-cache-redis/pom.xml b/hawkbit-cache-redis/pom.xml index 09567291b..637a6b49f 100644 --- a/hawkbit-cache-redis/pom.xml +++ b/hawkbit-cache-redis/pom.xml @@ -45,6 +45,12 @@ + + org.eclipse.hawkbit + hawkbit-repository-api + ${project.version} + test + org.springframework.boot spring-boot-starter-test diff --git a/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java b/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java index 1f5b41581..bebd82484 100644 --- a/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java +++ b/hawkbit-cache-redis/src/test/java/org/eclipse/hawkbit/cache/eventbus/EventDistributorTest.java @@ -16,8 +16,8 @@ import static org.mockito.Mockito.verify; import java.util.Collection; -import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.eventbus.event.EntityEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -56,7 +56,7 @@ public class EventDistributorTest { @Test public void distributeDistributedEventSendsToRedis() { - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L); underTest.distribute(event); // origin node ID should be set by distributing the event @@ -67,7 +67,7 @@ public class EventDistributorTest { @Test public void dontDistributeDistributedEventIfSameNode() { final String knownNodeId = EventDistributor.getNodeId(); - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L); event.setNodeId(knownNodeId); // test @@ -79,7 +79,7 @@ public class EventDistributorTest { @Test public void handleDistributedMessageFromRedis() { - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L); final String knownChannel = "someChannel"; underTest.handleMessage(event, knownChannel); @@ -90,7 +90,7 @@ public class EventDistributorTest { @Test public void handleDistributedMessageFilteredIfSameNodeId() { - final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10, 100L, 200L); + final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L); final String knownChannel = "someChannel"; event.setOriginNodeId(EventDistributor.getNodeId()); diff --git a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java index c878fa6a7..81be97b7c 100644 --- a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java +++ b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiArtifactDownloadTest.java @@ -26,7 +26,7 @@ import java.util.Arrays; import java.util.List; import org.apache.commons.lang3.RandomUtils; -import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.Artifact; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java index 1b20c3bf8..e5dcb8f74 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java @@ -14,8 +14,8 @@ import java.util.Map; import javax.validation.constraints.NotNull; -import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException; @@ -58,21 +58,20 @@ public interface ControllerManagement { Action addCancelActionStatus(@NotNull ActionStatus actionStatus); /** - * Sends the download progress in percentage and notifies the - * {@link EventBus} with a {@link DownloadProgressEvent}. + * Sends the download progress and notifies the {@link EventBus} with a + * {@link DownloadProgressEvent}. * * @param statusId * the ID of the {@link ActionStatus} - * @param progressPercent - * the progress in percentage which must be between 0-100 + * @param requestedBytes + * requested bytes of the request * @param shippedBytesSinceLast * since the last report * @param shippedBytesOverall * for the {@link ActionStatus} */ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) - void downloadProgressPercent(long statusId, int progressPercent, long shippedBytesSinceLast, - long shippedBytesOverall); + void downloadProgress(Long statusId, Long requestedBytes, Long shippedBytesSinceLast, Long shippedBytesOverall); /** * Simple addition of a new {@link ActionStatus} entry to the {@link Action} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java index 6430eb7c9..f041bc45f 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantStatsManagement.java @@ -16,10 +16,11 @@ import org.springframework.security.access.prepost.PreAuthorize; * Management service for statistics of a single tenant. * */ +@FunctionalInterface public interface TenantStatsManagement { /** - * Service for stats of a single tenant. + * Service for stats of the current tenant. * * @return collected statistics */ diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DownloadProgressEvent.java similarity index 68% rename from hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java rename to hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DownloadProgressEvent.java index 81ee0468a..6d145e0ae 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DownloadProgressEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DownloadProgressEvent.java @@ -6,13 +6,13 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.eventbus.event; +package org.eclipse.hawkbit.repository.eventbus.event; + +import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent; /** - * Event that contains an updated download progress for a given Action. - * - * - * + * Event that contains an updated download progress for a given ActionStatus + * that was written for a download request. * */ public class DownloadProgressEvent extends AbstractDistributedEvent { @@ -20,7 +20,7 @@ public class DownloadProgressEvent extends AbstractDistributedEvent { private static final long serialVersionUID = 1L; private final Long statusId; - private final int progressPercent; + private final long requestedBytes; private final long shippedBytesSinceLast; private final long shippedBytesOverall; @@ -30,22 +30,21 @@ public class DownloadProgressEvent extends AbstractDistributedEvent { * @param tenant * the tenant for this event * @param statusId - * of {@link ActionStatus} - * @param progressPercent - * number (1-100) + * of ActionStatus that was written for the download request + * @param requestedBytes + * bytes requested * @param shippedBytesSinceLast * bytes since last event * @param shippedBytesOverall * on the download request */ - public DownloadProgressEvent(final String tenant, final Long statusId, final int progressPercent, - final long shippedBytesSinceLast, final long shippedBytesOverall) { + public DownloadProgressEvent(final String tenant, final Long statusId, final Long requestedBytes, + final Long shippedBytesSinceLast, final Long shippedBytesOverall) { // the revision of the DownloadProgressEvent is just equal the - // progressPercentage due the - // percentage is going from 0 to 100. - super(statusId, tenant); + // shippedBytesOverall as this is a growing number. + super(shippedBytesOverall, tenant); this.statusId = statusId; - this.progressPercent = progressPercent; + this.requestedBytes = requestedBytes; this.shippedBytesSinceLast = shippedBytesSinceLast; this.shippedBytesOverall = shippedBytesOverall; } @@ -54,8 +53,8 @@ public class DownloadProgressEvent extends AbstractDistributedEvent { return statusId; } - public int getProgressPercent() { - return progressPercent; + public long getRequestedBytes() { + return requestedBytes; } public long getShippedBytesSinceLast() { diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Action.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Action.java index c2b96905e..98d101471 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Action.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Action.java @@ -39,12 +39,6 @@ public interface Action extends TenantAwareBaseEntity { return Status.CANCELING.equals(getStatus()) || Status.CANCELED.equals(getStatus()); } - /** - * @return current {@link Status#DOWNLOAD} progress if known by the update - * server. - */ - int getDownloadProgressPercent(); - /** * @return current {@link Status} of the {@link Action}. */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/ActionStatus.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/ActionStatus.java index f3ca66887..e83108fe8 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/ActionStatus.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/ActionStatus.java @@ -43,6 +43,12 @@ public interface ActionStatus extends TenantAwareBaseEntity { */ void addMessage(String message); + /** + * @return current {@link Status#DOWNLOAD} progress if known by the update + * server. + */ + int getDownloadProgressPercent(); + /** * @return list of message entries that can be added to the * {@link ActionStatus}. diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java index f62335ec3..b574d1452 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java @@ -469,9 +469,9 @@ public class JpaControllerManagement implements ControllerManagement { } @Override - public void downloadProgressPercent(final long statusId, final int progressPercent, - final long shippedBytesSinceLast, final long shippedBytesOverall) { - cacheWriteNotify.downloadProgressPercent(statusId, progressPercent, shippedBytesSinceLast, shippedBytesOverall); + public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast, + final Long shippedBytesOverall) { + cacheWriteNotify.downloadProgress(statusId, requestedBytes, shippedBytesSinceLast, shippedBytesOverall); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java index 3bcf8acc9..6dfdf157f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotify.java @@ -8,7 +8,9 @@ */ package org.eclipse.hawkbit.repository.jpa.cache; -import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; +import java.math.RoundingMode; + +import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent; import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.Rollout; @@ -19,6 +21,7 @@ import org.springframework.cache.CacheManager; import org.springframework.stereotype.Service; import com.google.common.eventbus.EventBus; +import com.google.common.math.DoubleMath; /** * An service which combines the functionality for functional use cases to write @@ -29,10 +32,6 @@ import com.google.common.eventbus.EventBus; */ @Service public class CacheWriteNotify { - - /** - * - */ private static final int DOWNLOAD_PROGRESS_MAX = 100; @Autowired @@ -45,25 +44,29 @@ public class CacheWriteNotify { private TenantAware tenantAware; /** - * writes the download progress in percentage into the cache + * writes the download progress into the cache * {@link CacheKeys#DOWNLOAD_PROGRESS_PERCENT} and notifies the * {@link EventBus} with a {@link DownloadProgressEvent}. * * @param statusId * the ID of the {@link ActionStatus} - * @param progressPercent - * the progress in percentage which must be between 0-100 + * @param requestedBytes + * requested bytes of the request * @param shippedBytesSinceLast * since last event * @param shippedBytesOverall * for the download request */ - public void downloadProgressPercent(final long statusId, final int progressPercent, - final long shippedBytesSinceLast, final long shippedBytesOverall) { + public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast, + final Long shippedBytesOverall) { final Cache cache = cacheManager.getCache(ActionStatus.class.getName()); final String cacheKey = CacheKeys.entitySpecificCacheKey(String.valueOf(statusId), CacheKeys.DOWNLOAD_PROGRESS_PERCENT); + + final int progressPercent = DoubleMath.roundToInt(shippedBytesOverall * 100.0 / requestedBytes, + RoundingMode.DOWN); + if (progressPercent < DOWNLOAD_PROGRESS_MAX) { cache.put(cacheKey, progressPercent); } else { @@ -73,7 +76,7 @@ public class CacheWriteNotify { cache.evict(cacheKey); } - eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, progressPercent, + eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, requestedBytes, shippedBytesSinceLast, shippedBytesOverall)); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java index 2b8744618..5fa2c3bed 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -27,10 +27,7 @@ import javax.persistence.NamedEntityGraphs; import javax.persistence.NamedSubgraph; import javax.persistence.OneToMany; import javax.persistence.Table; -import javax.persistence.Transient; -import org.eclipse.hawkbit.repository.jpa.cache.CacheField; -import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -89,13 +86,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) private JpaRollout rollout; - /** - * Note: filled only in {@link Status#DOWNLOAD}. - */ - @Transient - @CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT) - private int downloadProgressPercent; - @Override public DistributionSet getDistributionSet() { return distributionSet; @@ -120,15 +110,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio this.status = status; } - @Override - public int getDownloadProgressPercent() { - return downloadProgressPercent; - } - - public void setDownloadProgressPercent(final int downloadProgressPercent) { - this.downloadProgressPercent = downloadProgressPercent; - } - @Override public boolean isActive() { return active; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java index ef1ad3d1e..3a8cb8683 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java @@ -24,7 +24,10 @@ import javax.persistence.ManyToOne; import javax.persistence.NamedAttributeNode; import javax.persistence.NamedEntityGraph; import javax.persistence.Table; +import javax.persistence.Transient; +import org.eclipse.hawkbit.repository.jpa.cache.CacheField; +import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; @@ -63,6 +66,13 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements @Column(name = "detail_message", length = 512) private final List messages = new ArrayList<>(); + /** + * Note: filled only in {@link Status#DOWNLOAD}. + */ + @Transient + @CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT) + private int downloadProgressPercent; + /** * Creates a new {@link ActionStatus} object. * @@ -105,6 +115,11 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements // JPA default constructor. } + @Override + public int getDownloadProgressPercent() { + return downloadProgressPercent; + } + @Override public Long getOccurredAt() { return occurredAt; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java index 6a78852cb..1f6fbca6f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/cache/CacheWriteNotifyTest.java @@ -13,7 +13,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent; import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.tenancy.TenantAware; import org.junit.Before; @@ -59,15 +59,14 @@ public class CacheWriteNotifyTest { @Test public void downloadgProgressIsCachedAndEventSent() { final long knownStatusId = 1; - final int knownPercentage = 23; when(cacheManagerMock.getCache(ActionStatus.class.getName())).thenReturn(cacheMock); when(tenantAwareMock.getCurrentTenant()).thenReturn("default"); - underTest.downloadProgressPercent(knownStatusId, knownPercentage, 100L, 500L); + underTest.downloadProgress(knownStatusId, 500L, 100L, 100L); verify(cacheManagerMock).getCache(eq(ActionStatus.class.getName())); - verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, knownPercentage); + verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, 20); verify(eventBusMock).post(any(DownloadProgressEvent.class)); } diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index 63dcfaad0..3d09fabc3 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -23,7 +23,6 @@ import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.repository.TenantStatsManagement; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.security.DosFilter; @@ -94,9 +93,6 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { @Autowired protected TargetManagement targetManagement; - @Autowired - protected TenantStatsManagement tenantStatsManagement; - @Autowired protected TargetFilterQueryManagement targetFilterQueryManagement; diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java index bd0f8d007..0c9dd39c5 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java @@ -320,8 +320,7 @@ public final class RestResourceConversionHelper { // every 10 percent an event if (newPercent == 100 || newPercent > progressPercent + 10) { progressPercent = newPercent; - controllerManagement.downloadProgressPercent(statusId, progressPercent, shippedSinceLastEvent, - total); + controllerManagement.downloadProgress(statusId, length, shippedSinceLastEvent, total); shippedSinceLastEvent = 0; } } From d0cf8a40bd3de778db14327c5416397526c1726d Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 8 Jul 2016 13:32:02 +0200 Subject: [PATCH 40/52] fix javadoc link Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/im/authentication/SpPermission.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index 7d52b7a01..daf5f0dd9 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -367,7 +367,7 @@ public final class SpPermission { /** * Spring security eval hasAnyRole expression to check if the spring * context contains the anoynmous role or the controller specific role - * {@link SpPermission#CONTROLLER_ROLE}. + * {@link SpringEvalExpressions#CONTROLLER_ROLE}. */ public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE + "')"; @@ -375,7 +375,7 @@ public final class SpPermission { /** * Spring security eval hasAuthority expression to check if the spring * context contains the role to allow controllers to download specific - * role {@link SpPermission#CONTROLLER_DOWNLOAD_ROLE}. + * role {@link SpringEvalExpressions#CONTROLLER_DOWNLOAD_ROLE} */ public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE + HAS_AUTH_SUFFIX; From 2f9a9b456d43ee9aec67286024e27b0e12a717bf Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 13 Jul 2016 08:41:59 +0200 Subject: [PATCH 41/52] fix sonar critical issues Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/ui/common/CommonDialogWindow.java | 2 +- .../filterlayout/AbstractFilterMultiButtonClick.java | 3 ++- .../eclipse/hawkbit/ui/common/table/AbstractTable.java | 3 --- .../hawkbit/ui/common/tagdetails/AbstractTagToken.java | 8 ++------ .../ui/distributions/dstable/DistributionSetDetails.java | 2 +- .../ui/management/targettable/TargetBeanQuery.java | 2 +- 6 files changed, 7 insertions(+), 13 deletions(-) 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 index 725ff4b9b..a6b05e0a5 100644 --- 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 @@ -96,7 +96,7 @@ public class CommonDialogWindow extends Window implements Serializable { private final ClickListener close = event -> close(); - private final Map orginalValues; + private final transient Map orginalValues; private final List> allComponents; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterMultiButtonClick.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterMultiButtonClick.java index 8b3ac4cde..f7d3656b1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterMultiButtonClick.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterMultiButtonClick.java @@ -22,7 +22,8 @@ import com.vaadin.ui.Button.ClickEvent; */ public abstract class AbstractFilterMultiButtonClick extends AbstractFilterButtonClickBehaviour { - protected final Set