55
66package com .magento .idea .magento2plugin .actions .generation .dialog ;
77
8- import com .magento .idea .magento2plugin .actions .generation .dialog .util .HighlightDialogFieldOnErrorUtil ;
8+ import com .magento .idea .magento2plugin .actions .generation .dialog .util .DialogFieldErrorUtil ;
99import com .magento .idea .magento2plugin .actions .generation .dialog .validator .annotation .FieldValidation ;
1010import com .magento .idea .magento2plugin .actions .generation .dialog .validator .annotation .FieldValidations ;
1111import com .magento .idea .magento2plugin .actions .generation .dialog .validator .rule .ValidationRule ;
2828import javax .swing .JOptionPane ;
2929import javax .swing .JTextArea ;
3030import javax .swing .JTextField ;
31+ import org .jetbrains .annotations .NotNull ;
3132
3233/**
3334 * All code generate dialog should extend this class.
3435 */
3536@ SuppressWarnings ({"PMD.ShortVariable" , "PMD.MissingSerialVersionUID" })
3637public abstract class AbstractDialog extends JDialog {
38+
3739 protected CommonBundle bundle ;
3840 protected final ValidatorBundle validatorBundle = new ValidatorBundle ();
3941 private final String errorTitle ;
40- private final Map <Object , List <ValidationRule >> textFieldValidationRuleMap ;
41- private final Map <Object , Map <ValidationRule , String >> errorMessageFieldValidationRuleMap ;
42+ private final Map <Field , List <ValidationRule >> textFieldValidationRuleMap ;
43+ private final Map <Field , Map <ValidationRule , String >> errorMessageFieldValidationRuleMap ;
44+ private boolean isValidationErrorShown ;
45+ private boolean dialogHasErrors ;
4246
4347 /**
4448 * Abstract Dialog Constructor.
@@ -62,11 +66,18 @@ protected void onCancel() {
6266 this .setVisible (false );
6367 }
6468
69+ /**
70+ * Validate all form fields.
71+ *
72+ * @return boolean
73+ */
6574 protected boolean validateFormFields () {
6675 addValidationRulesFromAnnotations ();
67- for (final Map .Entry <Object , List <ValidationRule >> entry
76+ isValidationErrorShown = dialogHasErrors = false ;
77+
78+ for (final Map .Entry <Field , List <ValidationRule >> entry
6879 : textFieldValidationRuleMap .entrySet ()) {
69- final Object field = entry .getKey ();
80+ final Field field = entry .getKey ();
7081 final List <ValidationRule > rules = entry .getValue ();
7182
7283 for (final ValidationRule rule : rules ) {
@@ -75,25 +86,66 @@ protected boolean validateFormFields() {
7586 if (value != null && !rule .check (value )) {
7687 if (errorMessageFieldValidationRuleMap .containsKey (field )
7788 && errorMessageFieldValidationRuleMap .get (field ).containsKey (rule )) {
78- showErrorMessage (errorMessageFieldValidationRuleMap .get (field ).get (rule ));
79- highlightFieldWithErrorStyle (field );
89+ dialogHasErrors = true ;
90+ showErrorMessage (
91+ field ,
92+ errorMessageFieldValidationRuleMap .get (field ).get (rule )
93+ );
8094 }
81- return false ;
95+ break ;
8296 }
8397 }
8498 }
85- return true ;
99+
100+ if (dialogHasErrors && !isValidationErrorShown ) {
101+ showErrorMessage (
102+ validatorBundle .message ("validator.someFieldsHaveErrors" )
103+ );
104+ }
105+
106+ return !dialogHasErrors ;
86107 }
87108
109+ /**
110+ * Show error message for field.
111+ *
112+ * @param field Field
113+ * @param errorMessage String
114+ */
115+ protected void showErrorMessage (
116+ final @ NotNull Field field ,
117+ final @ NotNull String errorMessage
118+ ) {
119+ final boolean isMessageShown =
120+ DialogFieldErrorUtil .showErrorMessageForField (this , field , errorMessage );
121+
122+ if (!isMessageShown ) {
123+ showErrorMessage (errorMessage );
124+ DialogFieldErrorUtil .highlightField (this , field );
125+ }
126+ }
127+
128+ /**
129+ * Show error message in dialog.
130+ *
131+ * @param errorMessage String
132+ */
88133 protected void showErrorMessage (final String errorMessage ) {
134+ if (isValidationErrorShown ) {
135+ return ;
136+ }
89137 JOptionPane .showMessageDialog (
90138 null ,
91139 errorMessage ,
92140 errorTitle ,
93141 JOptionPane .ERROR_MESSAGE
94142 );
143+ isValidationErrorShown = true ;
95144 }
96145
146+ /**
147+ * Process validation rules from annotations.
148+ */
97149 private void addValidationRulesFromAnnotations () {
98150 final Class <?> type = this .getClass ();
99151 final List <FieldValidation > validations = new LinkedList <>();
@@ -114,18 +166,28 @@ private void addValidationRulesFromAnnotations() {
114166 for (final FieldValidation validation : validations ) {
115167 try {
116168 addValidationRuleToField (
117- field . get ( this ) ,
169+ field ,
118170 getRuleFromAnnotation (validation ),
119171 getMessageFromAnnotation (validation )
120172 );
121- } catch (Exception exception ) { // NOPMD
122- // We don't need to cover this case.
173+ } catch (NoSuchMethodException | IllegalAccessException
174+ | InvocationTargetException | InstantiationException exception ) {
175+ return ;
176+ } finally {
177+ field .setAccessible (false );
123178 }
124179 }
125180 field .setAccessible (false );
126181 }
127182 }
128183
184+ /**
185+ * Get error message from annotation.
186+ *
187+ * @param validation FieldValidation
188+ *
189+ * @return String
190+ */
129191 private String getMessageFromAnnotation (final FieldValidation validation ) {
130192 String [] params ;
131193 final int minMessageArrayLength = 1 ;
@@ -138,22 +200,38 @@ private String getMessageFromAnnotation(final FieldValidation validation) {
138200 return validatorBundle .message (validation .message ()[0 ], (Object []) params );
139201 }
140202
203+ /**
204+ * Get validation rule from annotation.
205+ *
206+ * @param validation FieldValidation
207+ *
208+ * @return ValidationRule
209+ */
141210 private ValidationRule getRuleFromAnnotation (final FieldValidation validation )
142- throws NoSuchMethodException ,
143- IllegalAccessException , InvocationTargetException , InstantiationException {
211+ throws NoSuchMethodException , IllegalAccessException , InvocationTargetException ,
212+ InstantiationException {
144213 final Class <?> ruleType = validation .rule ().getRule ();
145214
146215 return (ValidationRule ) ruleType .getConstructor ().newInstance ();
147216 }
148217
218+ /**
219+ * Add validation rule for field.
220+ *
221+ * @param field Field
222+ * @param rule ValidationRule
223+ * @param message String
224+ */
149225 protected void addValidationRuleToField (
150- final Object field ,
226+ final Field field ,
151227 final ValidationRule rule ,
152- final String message ) {
153- if (!(field instanceof JComponent )) {
228+ final String message
229+ ) {
230+ if (getComponentForField (field ) == null ) {
154231 return ;
155232 }
156233 List <ValidationRule > rules ;
234+
157235 if (textFieldValidationRuleMap .containsKey (field )) {
158236 rules = textFieldValidationRuleMap .get (field );
159237 } else {
@@ -167,10 +245,18 @@ protected void addValidationRuleToField(
167245 }
168246 }
169247
248+ /**
249+ * Associate validation rule with field.
250+ *
251+ * @param field Field
252+ * @param rule ValidationRule
253+ * @param message String
254+ */
170255 private void addFieldValidationRuleMessageAssociation (
171- final Object field ,
256+ final Field field ,
172257 final ValidationRule rule ,
173- final String message ) {
258+ final String message
259+ ) {
174260 Map <ValidationRule , String > validationRuleErrorMessageMap ;
175261 if (errorMessageFieldValidationRuleMap .containsKey (field )) {
176262 validationRuleErrorMessageMap = errorMessageFieldValidationRuleMap .get (field );
@@ -181,31 +267,53 @@ private void addFieldValidationRuleMessageAssociation(
181267 errorMessageFieldValidationRuleMap .put (field , validationRuleErrorMessageMap );
182268 }
183269
184- private String resolveFieldValueByComponentType (final Object field ) {
185- if (field instanceof JTextField ) {
186- return ((JTextField ) field ).isEditable () ? ((JTextField ) field ).getText () : null ;
187- } else if (field instanceof JComboBox ) {
188- if (((JComboBox <?>) field ).getSelectedIndex () == -1 ) {
270+ /**
271+ * Resolve value of stored component by field.
272+ *
273+ * @param field Field
274+ *
275+ * @return String
276+ */
277+ private String resolveFieldValueByComponentType (final Field field ) {
278+ final JComponent component = getComponentForField (field );
279+
280+ if (component instanceof JTextField ) {
281+ return ((JTextField ) component ).isEditable ()
282+ ? ((JTextField ) component ).getText () : null ;
283+ } else if (component instanceof JComboBox ) {
284+ if (((JComboBox <?>) component ).getSelectedIndex () == -1 ) {
189285 return "" ;
190286 } else {
191- return ((JComboBox ) field ).getSelectedItem ().toString ();
287+ return ((JComboBox ) component ).getSelectedItem ().toString ();
192288 }
193- } else if (field instanceof JTextArea ) {
194- return ((JTextArea ) field ).getText ();
289+ } else if (component instanceof JTextArea ) {
290+ return ((JTextArea ) component ).getText ();
195291 }
292+
196293 return null ;
197294 }
198295
199296 /**
200- * Highlight field with error style.
297+ * Get JComponent for field.
298+ *
299+ * @param field Field
201300 *
202- * @param field Object
301+ * @return JComponent
203302 */
204- private void highlightFieldWithErrorStyle (final Object field ) {
205- if (field instanceof JTextField ) {
206- HighlightDialogFieldOnErrorUtil .execute ((JTextField ) field );
207- } else if (field instanceof JComboBox ) {
208- HighlightDialogFieldOnErrorUtil .execute ((JComboBox ) field );
303+ private JComponent getComponentForField (final @ NotNull Field field ) {
304+ try {
305+ field .setAccessible (true );
306+ final Object component = field .get (this );
307+
308+ if (component instanceof JComponent ) {
309+ return (JComponent ) component ;
310+ }
311+ } catch (IllegalAccessException exception ) {
312+ return null ;
313+ } finally {
314+ field .setAccessible (false );
209315 }
316+
317+ return null ;
210318 }
211319}
0 commit comments