From fc408078779a7c45ab37206f5d39c3ba9bffbfd9 Mon Sep 17 00:00:00 2001 From: bohdan-harniuk Date: Fri, 2 Apr 2021 13:55:49 +0300 Subject: [PATCH 1/2] Enhabced validation, added filtering for fields to validate on entity creator form --- .../generation/dialog/AbstractDialog.java | 222 +++--------------- .../generation/dialog/NewEntityDialog.java | 34 ++- .../ExtractComponentFromFieldUtil.java | 40 ++++ .../reflection/GetReflectionFieldUtil.java | 30 +++ .../dialog/util/DialogFieldErrorUtil.java | 33 +-- .../validator/annotation/FieldValidation.java | 2 +- .../annotation/TypeFieldsRulesParser.java | 75 ++++++ .../ValidationMessageExtractorUtil.java | 37 +++ .../ValidationRuleExtractorUtil.java | 39 +++ .../validator/data/FieldValidationData.java | 45 ++++ .../NewEntityGeneratorsProviderUtil.java | 3 +- 11 files changed, 341 insertions(+), 219 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/actions/generation/dialog/reflection/ExtractComponentFromFieldUtil.java create mode 100644 src/com/magento/idea/magento2plugin/actions/generation/dialog/reflection/GetReflectionFieldUtil.java create mode 100644 src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/TypeFieldsRulesParser.java create mode 100644 src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/ValidationMessageExtractorUtil.java create mode 100644 src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/ValidationRuleExtractorUtil.java create mode 100644 src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/data/FieldValidationData.java diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/AbstractDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/AbstractDialog.java index c8a65b1fc..79f8f64a7 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/AbstractDialog.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/AbstractDialog.java @@ -5,9 +5,11 @@ package com.magento.idea.magento2plugin.actions.generation.dialog; +import com.intellij.openapi.util.Pair; +import com.magento.idea.magento2plugin.actions.generation.dialog.reflection.ExtractComponentFromFieldUtil; import com.magento.idea.magento2plugin.actions.generation.dialog.util.DialogFieldErrorUtil; -import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation; -import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidations; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.TypeFieldsRulesParser; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.data.FieldValidationData; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.ValidationRule; import com.magento.idea.magento2plugin.bundles.CommonBundle; import com.magento.idea.magento2plugin.bundles.ValidatorBundle; @@ -15,14 +17,8 @@ import java.awt.Dimension; import java.awt.Toolkit; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; -import java.util.Map; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; @@ -35,17 +31,14 @@ /** * All code generate dialog should extend this class. */ -@SuppressWarnings({"PMD.ShortVariable", "PMD.MissingSerialVersionUID"}) public abstract class AbstractDialog extends JDialog { protected CommonBundle bundle; protected final ValidatorBundle validatorBundle = new ValidatorBundle(); + protected final List fieldsValidationsList; private final String errorTitle; - private final Map> textFieldValidationRuleMap; - private final Map> errorMessageFieldValidationRuleMap; private JTabbedPane tabbedPane; private boolean isValidationErrorShown; - private boolean dialogHasErrors; /** * Abstract Dialog Constructor. @@ -54,15 +47,14 @@ public AbstractDialog() { super(); bundle = new CommonBundle(); errorTitle = bundle.message("common.error"); - textFieldValidationRuleMap = new LinkedHashMap<>(); - errorMessageFieldValidationRuleMap = new HashMap<>(); + fieldsValidationsList = new TypeFieldsRulesParser(this).parseValidationRules(); } protected void centerDialog(final AbstractDialog dialog) { final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - final int x = screenSize.width / 2 - dialog.getSize().width / 2; - final int y = screenSize.height / 2 - dialog.getSize().height / 2; - dialog.setLocation(x, y); + final int cordX = screenSize.width / 2 - dialog.getSize().width / 2; + final int cordY = screenSize.height / 2 - dialog.getSize().height / 2; + dialog.setLocation(cordX, cordY); } protected void onCancel() { @@ -74,48 +66,52 @@ protected void onCancel() { * * @return boolean */ + @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.AvoidDeeplyNestedIfStmts"}) protected boolean validateFormFields() { - addValidationRulesFromAnnotations(); + boolean dialogHasErrors; isValidationErrorShown = dialogHasErrors = false; - for (final Map.Entry> entry - : textFieldValidationRuleMap.entrySet()) { - final Field field = entry.getKey(); - final List rules = entry.getValue(); + for (final FieldValidationData fieldValidationData : getFieldsToValidate()) { + final Field field = fieldValidationData.getField(); + final List> rules = fieldValidationData.getRules(); - for (final ValidationRule rule : rules) { + for (final Pair rulePair : rules) { + final ValidationRule rule = rulePair.getFirst(); + final String message = rulePair.getSecond(); final String value = resolveFieldValueByComponentType(field); if (value != null && !rule.check(value)) { - if (errorMessageFieldValidationRuleMap.containsKey(field) - && errorMessageFieldValidationRuleMap.get(field).containsKey(rule)) { - if (!dialogHasErrors) { - final JComponent component = getComponentForField(field); + if (!dialogHasErrors) { + final JComponent component = + ExtractComponentFromFieldUtil.extract(field, this); - if (component != null && tabbedPane != null) { - navigateToTabWithComponent(component); - } + if (component != null && tabbedPane != null) { + navigateToTabWithComponent(component); } - dialogHasErrors = true; - showErrorMessage( - field, - errorMessageFieldValidationRuleMap.get(field).get(rule) - ); } + dialogHasErrors = true; + showErrorMessage(field, message); break; } } } if (dialogHasErrors && !isValidationErrorShown) { - showErrorMessage( - validatorBundle.message("validator.someFieldsHaveErrors") - ); + showErrorMessage(validatorBundle.message("validator.someFieldsHaveErrors")); } return !dialogHasErrors; } + /** + * Override this method to change which fields should or shouldn't be validated. + * + * @return List[FieldValidationData] + */ + protected List getFieldsToValidate() { + return new LinkedList<>(fieldsValidationsList); + } + /** * Tabbed pane should be registered to be possible navigate to the tab in which error occurred. * @@ -162,130 +158,6 @@ protected void showErrorMessage(final String errorMessage) { isValidationErrorShown = true; } - /** - * Process validation rules from annotations. - */ - private void addValidationRulesFromAnnotations() { - final Class type = this.getClass(); - final List validations = new LinkedList<>(); - - for (final Field field : type.getDeclaredFields()) { - field.setAccessible(true); - validations.clear(); - - if (field.isAnnotationPresent(FieldValidation.class)) { - validations.add(field.getAnnotation(FieldValidation.class)); - } - if (field.isAnnotationPresent(FieldValidations.class)) { - validations.addAll( - Arrays.asList(field.getAnnotation(FieldValidations.class).value()) - ); - } - - for (final FieldValidation validation : validations) { - try { - addValidationRuleToField( - field, - getRuleFromAnnotation(validation), - getMessageFromAnnotation(validation) - ); - } catch (NoSuchMethodException | IllegalAccessException - | InvocationTargetException | InstantiationException exception) { - return; - } finally { - field.setAccessible(false); - } - } - field.setAccessible(false); - } - } - - /** - * Get error message from annotation. - * - * @param validation FieldValidation - * - * @return String - */ - private String getMessageFromAnnotation(final FieldValidation validation) { - String[] params; - final int minMessageArrayLength = 1; - - if (validation.message().length > minMessageArrayLength) { - params = Arrays.copyOfRange(validation.message(), 1, validation.message().length); - } else { - params = new String[]{}; - } - return validatorBundle.message(validation.message()[0], (Object[]) params); - } - - /** - * Get validation rule from annotation. - * - * @param validation FieldValidation - * - * @return ValidationRule - */ - private ValidationRule getRuleFromAnnotation(final FieldValidation validation) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, - InstantiationException { - final Class ruleType = validation.rule().getRule(); - - return (ValidationRule) ruleType.getConstructor().newInstance(); - } - - /** - * Add validation rule for field. - * - * @param field Field - * @param rule ValidationRule - * @param message String - */ - protected void addValidationRuleToField( - final Field field, - final ValidationRule rule, - final String message - ) { - if (getComponentForField(field) == null) { - return; - } - List rules; - - if (textFieldValidationRuleMap.containsKey(field)) { - rules = textFieldValidationRuleMap.get(field); - } else { - rules = new ArrayList<>(); - } - - if (!rules.contains(rule) && rule != null) { - addFieldValidationRuleMessageAssociation(field, rule, message); - rules.add(rule); - textFieldValidationRuleMap.put(field, rules); - } - } - - /** - * Associate validation rule with field. - * - * @param field Field - * @param rule ValidationRule - * @param message String - */ - private void addFieldValidationRuleMessageAssociation( - final Field field, - final ValidationRule rule, - final String message - ) { - Map validationRuleErrorMessageMap; - if (errorMessageFieldValidationRuleMap.containsKey(field)) { - validationRuleErrorMessageMap = errorMessageFieldValidationRuleMap.get(field); - } else { - validationRuleErrorMessageMap = new HashMap<>(); - } - validationRuleErrorMessageMap.put(rule, message); - errorMessageFieldValidationRuleMap.put(field, validationRuleErrorMessageMap); - } - /** * Resolve value of stored component by field. * @@ -294,7 +166,7 @@ private void addFieldValidationRuleMessageAssociation( * @return String */ private String resolveFieldValueByComponentType(final Field field) { - final JComponent component = getComponentForField(field); + final JComponent component = ExtractComponentFromFieldUtil.extract(field, this); if (component instanceof JTextField) { return ((JTextField) component).isEditable() @@ -312,30 +184,6 @@ private String resolveFieldValueByComponentType(final Field field) { return null; } - /** - * Get JComponent for field. - * - * @param field Field - * - * @return JComponent - */ - private JComponent getComponentForField(final @NotNull Field field) { - try { - field.setAccessible(true); - final Object component = field.get(this); - - if (component instanceof JComponent) { - return (JComponent) component; - } - } catch (IllegalAccessException exception) { - return null; - } finally { - field.setAccessible(false); - } - - return null; - } - /** * Navigate to tab with specified component. * diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewEntityDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewEntityDialog.java index 3860ca220..2658a72c1 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewEntityDialog.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewEntityDialog.java @@ -16,10 +16,12 @@ import com.magento.idea.magento2plugin.actions.generation.data.dialog.EntityCreatorContextData; import com.magento.idea.magento2plugin.actions.generation.data.dialog.NewEntityDialogData; import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; +import com.magento.idea.magento2plugin.actions.generation.dialog.reflection.GetReflectionFieldUtil; import com.magento.idea.magento2plugin.actions.generation.dialog.util.ClassPropertyFormatterUtil; import com.magento.idea.magento2plugin.actions.generation.dialog.util.ProcessWorker; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.RuleRegistry; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.data.FieldValidationData; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AclResourceIdRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AlphanumericRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AlphanumericWithUnderscoreRule; @@ -57,6 +59,7 @@ import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -249,8 +252,9 @@ public void windowClosing(final WindowEvent event) { onCancel(); } + @SuppressWarnings("PMD.AccessorMethodGeneration") @Override - public void windowOpened(WindowEvent e) { + public void windowOpened(final WindowEvent event) { entityName.requestFocus(); } }); @@ -300,6 +304,34 @@ public static void open(final Project project, final PsiDirectory directory) { dialog.setVisible(true); } + /** + * Filter fields to validate if createUiComponent checkbox isn't selected. + * + * @return List[FieldValidationData] + */ + @Override + protected List getFieldsToValidate() { + final List filteredFields = new LinkedList<>(); + + if (createUiComponent.isSelected()) { + filteredFields.addAll(super.getFieldsToValidate()); + } else { + final List fieldsToIgnore = new ArrayList<>(); + fieldsToIgnore.add(GetReflectionFieldUtil.getByName("route", this.getClass())); + fieldsToIgnore.add(GetReflectionFieldUtil.getByName("formName", this.getClass())); + fieldsToIgnore.add(GetReflectionFieldUtil.getByName("gridName", this.getClass())); + + for (final FieldValidationData fieldData : super.getFieldsToValidate()) { + if (fieldsToIgnore.contains(fieldData.getField())) { + continue; + } + filteredFields.add(fieldData); + } + } + + return filteredFields; + } + /** * Initialize combobox sources. */ diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/reflection/ExtractComponentFromFieldUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/reflection/ExtractComponentFromFieldUtil.java new file mode 100644 index 000000000..925cb13b3 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/reflection/ExtractComponentFromFieldUtil.java @@ -0,0 +1,40 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.reflection; + +import java.lang.reflect.Field; +import javax.swing.JComponent; +import org.jetbrains.annotations.NotNull; + +public final class ExtractComponentFromFieldUtil { + + private ExtractComponentFromFieldUtil() {} + + /** + * Get JComponent value for field. + * + * @param field Field + * @param object Object + * + * @return JComponent + */ + public static JComponent extract(final @NotNull Field field, final @NotNull Object object) { + try { + field.setAccessible(true); + final Object component = field.get(object); + + if (component instanceof JComponent) { + return (JComponent) component; + } + } catch (IllegalAccessException exception) { + return null; + } finally { + field.setAccessible(false); + } + + return null; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/reflection/GetReflectionFieldUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/reflection/GetReflectionFieldUtil.java new file mode 100644 index 000000000..4880a3abc --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/reflection/GetReflectionFieldUtil.java @@ -0,0 +1,30 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.reflection; + +import java.lang.reflect.Field; +import org.jetbrains.annotations.NotNull; + +public final class GetReflectionFieldUtil { + + private GetReflectionFieldUtil() {} + + /** + * Get field by its name for specified type. + * + * @param name String + * @param type Class + * + * @return Field + */ + public static Field getByName(final @NotNull String name, final @NotNull Class type) { + try { + return type.getDeclaredField(name); + } catch (NoSuchFieldException | SecurityException exception) { + return null; + } + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java index 302209a43..3a55ab114 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java @@ -14,6 +14,8 @@ import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JLabel; + +import com.magento.idea.magento2plugin.actions.generation.dialog.reflection.ExtractComponentFromFieldUtil; import org.jetbrains.annotations.NotNull; public final class DialogFieldErrorUtil { @@ -34,7 +36,7 @@ public static void highlightField( final @NotNull AbstractDialog dialog, final @NotNull Field field ) { - final JComponent fieldComponent = getComponentForField(dialog, field); + final JComponent fieldComponent = ExtractComponentFromFieldUtil.extract(field, dialog); if (fieldComponent != null) { highlightField(fieldComponent); @@ -82,7 +84,7 @@ public static boolean showErrorMessageForField( final @NotNull String message ) { final JLabel messageHolder = getMessageHolderForField(dialog, field); - final JComponent fieldComponent = getComponentForField(dialog, field); + final JComponent fieldComponent = ExtractComponentFromFieldUtil.extract(field, dialog); if (messageHolder == null || fieldComponent == null) { return false; @@ -139,31 +141,4 @@ private static JLabel getMessageHolderForField( return null; } - - /** - * Get JComponent for field. - * - * @param field Field - * - * @return JComponent - */ - private static JComponent getComponentForField( - final @NotNull AbstractDialog dialog, - final @NotNull Field field - ) { - try { - field.setAccessible(true); - final Object component = field.get(dialog); - - if (component instanceof JComponent) { - return (JComponent) component; - } - } catch (IllegalAccessException exception) { - return null; - } finally { - field.setAccessible(false); - } - - return null; - } } diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/FieldValidation.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/FieldValidation.java index 0303e35ce..b015a0b68 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/FieldValidation.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/FieldValidation.java @@ -26,7 +26,7 @@ /** * Get specified in the annotation message array. * The first element of array is a bundle message identifier, - * туче elements are the arguments for the bundle message. + * next elements are the arguments for the bundle message. * * @return String[] */ diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/TypeFieldsRulesParser.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/TypeFieldsRulesParser.java new file mode 100644 index 000000000..d5ffcd79f --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/TypeFieldsRulesParser.java @@ -0,0 +1,75 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation; + +import com.intellij.openapi.util.Pair; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.data.FieldValidationData; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.ValidationRule; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import org.jetbrains.annotations.NotNull; + +public final class TypeFieldsRulesParser { + + private final Class type; + private List fieldValidationList; + + /** + * Type fields rules parser. + * + * @param object Object + */ + public TypeFieldsRulesParser(final @NotNull Object object) { + type = object.getClass(); + } + + /** + * Parse validation rules for type. + * + * @return List[FieldValidationData] + */ + public List parseValidationRules() { + if (fieldValidationList == null) { + fieldValidationList = new LinkedList<>(); + final List annotations = new LinkedList<>(); + final List> rulePairList = new LinkedList<>(); + + for (final Field field : type.getDeclaredFields()) { + annotations.clear(); + field.setAccessible(true); + + if (field.isAnnotationPresent(FieldValidation.class)) { + annotations.add(field.getAnnotation(FieldValidation.class)); + } + + if (field.isAnnotationPresent(FieldValidations.class)) { + annotations.addAll( + Arrays.asList(field.getAnnotation(FieldValidations.class).value()) + ); + } + field.setAccessible(false); + rulePairList.clear(); + + for (final FieldValidation annotation : annotations) { + final ValidationRule rule = ValidationRuleExtractorUtil.extract(annotation); + final String message = ValidationMessageExtractorUtil.extract(annotation); + + if (rule != null) { + rulePairList.add(new Pair<>(rule, message)); + } + } + + if (!rulePairList.isEmpty()) { + fieldValidationList.add(new FieldValidationData(field, rulePairList)); + } + } + } + + return fieldValidationList; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/ValidationMessageExtractorUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/ValidationMessageExtractorUtil.java new file mode 100644 index 000000000..8d66d46ae --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/ValidationMessageExtractorUtil.java @@ -0,0 +1,37 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation; + +import com.magento.idea.magento2plugin.bundles.ValidatorBundle; +import java.util.Arrays; +import org.jetbrains.annotations.NotNull; + +public final class ValidationMessageExtractorUtil { + + private static final int MIN_MESSAGE_ARRAY_LENGTH = 1; + private static final ValidatorBundle VALIDATOR_BUNDLE = new ValidatorBundle(); + + private ValidationMessageExtractorUtil() {} + + /** + * Extract validation message from validation annotation. + * + * @param annotation FieldValidation + * + * @return String + */ + public static String extract(final @NotNull FieldValidation annotation) { + String[] params; + + if (annotation.message().length > MIN_MESSAGE_ARRAY_LENGTH) { + params = Arrays.copyOfRange(annotation.message(), 1, annotation.message().length); + } else { + params = new String[]{}; + } + + return VALIDATOR_BUNDLE.message(annotation.message()[0], (Object[]) params); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/ValidationRuleExtractorUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/ValidationRuleExtractorUtil.java new file mode 100644 index 000000000..d6d15826c --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/ValidationRuleExtractorUtil.java @@ -0,0 +1,39 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation; + +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.ValidationRule; +import java.lang.reflect.InvocationTargetException; +import org.jetbrains.annotations.NotNull; + +public final class ValidationRuleExtractorUtil { + + private ValidationRuleExtractorUtil() {} + + /** + * Extract validation rule from validation annotation. + * + * @param annotation FieldValidation + * + * @return ValidationRule + */ + public static ValidationRule extract(final @NotNull FieldValidation annotation) { + ValidationRule rule; + final Class ruleType = annotation.rule().getRule(); + + try { + rule = (ValidationRule) ruleType.getConstructor().newInstance(); + } catch (NoSuchMethodException + | IllegalAccessException + | InvocationTargetException + | InstantiationException exception + ) { + return null; + } + + return rule; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/data/FieldValidationData.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/data/FieldValidationData.java new file mode 100644 index 000000000..6a106ebbf --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/data/FieldValidationData.java @@ -0,0 +1,45 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.validator.data; + +import com.intellij.openapi.util.Pair; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.ValidationRule; +import java.lang.reflect.Field; +import java.util.LinkedList; +import java.util.List; +import org.jetbrains.annotations.NotNull; + +public class FieldValidationData { + + private final Field field; + private final List> rules; + + public FieldValidationData( + final @NotNull Field field, + final @NotNull List> rules + ) { + this.field = field; + this.rules = new LinkedList<>(rules); + } + + /** + * Get field. + * + * @return Field + */ + public Field getField() { + return field; + } + + /** + * Get validation rules. + * + * @return List + */ + public List> getRules() { + return new LinkedList<>(rules); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/pool/provider/NewEntityGeneratorsProviderUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/pool/provider/NewEntityGeneratorsProviderUtil.java index d28a7307a..5e8b7e890 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/generator/pool/provider/NewEntityGeneratorsProviderUtil.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/pool/provider/NewEntityGeneratorsProviderUtil.java @@ -117,7 +117,8 @@ public static void initializeGenerators( ) .addNext( RoutesXmlGeneratorHandler.class, - new RoutesXmlDtoConverter(context, dialogData) + new RoutesXmlDtoConverter(context, dialogData), + dialogData::hasAdminUiComponents ) .addNext( AclXmlGeneratorHandler.class, From 8a6846b318e7c8f74c7b63c1370763d7e8cf81a1 Mon Sep 17 00:00:00 2001 From: bohdan-harniuk Date: Fri, 2 Apr 2021 16:33:19 +0300 Subject: [PATCH 2/2] Added highlighting reseting before validation --- .../generation/dialog/AbstractDialog.java | 16 ++++- .../dialog/util/DialogFieldErrorUtil.java | 68 ++++++++++++++++--- 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/AbstractDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/AbstractDialog.java index 79f8f64a7..66379034f 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/AbstractDialog.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/AbstractDialog.java @@ -52,9 +52,9 @@ public AbstractDialog() { protected void centerDialog(final AbstractDialog dialog) { final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - final int cordX = screenSize.width / 2 - dialog.getSize().width / 2; - final int cordY = screenSize.height / 2 - dialog.getSize().height / 2; - dialog.setLocation(cordX, cordY); + final int coordinateX = screenSize.width / 2 - dialog.getSize().width / 2; + final int coordinateY = screenSize.height / 2 - dialog.getSize().height / 2; + dialog.setLocation(coordinateX, coordinateY); } protected void onCancel() { @@ -70,6 +70,7 @@ protected void onCancel() { protected boolean validateFormFields() { boolean dialogHasErrors; isValidationErrorShown = dialogHasErrors = false; + clearValidationHighlighting(); for (final FieldValidationData fieldValidationData : getFieldsToValidate()) { final Field field = fieldValidationData.getField(); @@ -103,6 +104,15 @@ protected boolean validateFormFields() { return !dialogHasErrors; } + /** + * Reset highlighting for fields. + */ + protected void clearValidationHighlighting() { + for (final FieldValidationData fieldValidationData : fieldsValidationsList) { + DialogFieldErrorUtil.resetFieldHighlighting(fieldValidationData.getField(), this); + } + } + /** * Override this method to change which fields should or shouldn't be validated. * diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java index 3a55ab114..80c12d54a 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java @@ -7,15 +7,18 @@ import com.intellij.util.ui.UIUtil; import com.magento.idea.magento2plugin.actions.generation.dialog.AbstractDialog; +import com.magento.idea.magento2plugin.actions.generation.dialog.reflection.ExtractComponentFromFieldUtil; import java.awt.Color; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.lang.reflect.Field; import javax.swing.BorderFactory; +import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; - -import com.magento.idea.magento2plugin.actions.generation.dialog.reflection.ExtractComponentFromFieldUtil; +import javax.swing.JTextField; +import javax.swing.UIManager; +import javax.swing.border.Border; import org.jetbrains.annotations.NotNull; public final class DialogFieldErrorUtil { @@ -49,26 +52,75 @@ public static void highlightField( * @param fieldComponent JComponent */ public static void highlightField(final @NotNull JComponent fieldComponent) { - final Color defaultBackgroundColor = fieldComponent.getBackground(); - fieldComponent.setBorder(BorderFactory.createLineBorder(ERROR_COLOR)); fieldComponent.setBackground(ERROR_BACKGROUND_COLOR); fieldComponent.addFocusListener(new FocusListener() { @Override public void focusGained(final FocusEvent event) { - fieldComponent.setBorder(null); - fieldComponent.setBackground(defaultBackgroundColor); + resetComponentHighlighting(fieldComponent); } @Override public void focusLost(final FocusEvent event) { - fieldComponent.setBorder(null); - fieldComponent.setBackground(defaultBackgroundColor); + resetComponentHighlighting(fieldComponent); } }); } + /** + * Reset field highlighting. + * + * @param field Field + * @param dialog AbstractDialog + */ + public static void resetFieldHighlighting( + final @NotNull Field field, + final @NotNull AbstractDialog dialog + ) { + final JComponent fieldComponent = ExtractComponentFromFieldUtil.extract(field, dialog); + + if (fieldComponent == null) { + return; + } + + resetComponentHighlighting(fieldComponent); + final JLabel messageHolder = getMessageHolderForField(dialog, field); + + if (messageHolder == null) { + return; + } + + messageHolder.setVisible(false); + messageHolder.setText(""); + } + + /** + * Reset component highlighting. + * + * @param fieldComponent JComponent + */ + public static void resetComponentHighlighting( + final @NotNull JComponent fieldComponent + ) { + Color defaultBackgroundColor; + Border defaultBorder; + + if (fieldComponent instanceof JTextField) { + defaultBackgroundColor = UIManager.getColor("TextField.background"); + defaultBorder = UIManager.getBorder("TextField.border"); + } else if (fieldComponent instanceof JComboBox) { + defaultBackgroundColor = UIManager.getColor("ComboBox.background"); + defaultBorder = UIManager.getBorder("ComboBox.border"); + } else { + defaultBackgroundColor = UIManager.getColor("TextField.background"); + defaultBorder = UIManager.getBorder("TextField.border"); + } + + fieldComponent.setBackground(defaultBackgroundColor); + fieldComponent.setBorder(defaultBorder); + } + /** * Show error message for field. *