55
66package com .magento .idea .magento2plugin .actions .generation .dialog ;
77
8+ import com .intellij .openapi .util .Pair ;
9+ import com .magento .idea .magento2plugin .actions .generation .dialog .reflection .ExtractComponentFromFieldUtil ;
810import com .magento .idea .magento2plugin .actions .generation .dialog .util .DialogFieldErrorUtil ;
9- import com .magento .idea .magento2plugin .actions .generation .dialog .validator .annotation .FieldValidation ;
10- import com .magento .idea .magento2plugin .actions .generation .dialog .validator .annotation . FieldValidations ;
11+ import com .magento .idea .magento2plugin .actions .generation .dialog .validator .annotation .TypeFieldsRulesParser ;
12+ import com .magento .idea .magento2plugin .actions .generation .dialog .validator .data . FieldValidationData ;
1113import com .magento .idea .magento2plugin .actions .generation .dialog .validator .rule .ValidationRule ;
1214import com .magento .idea .magento2plugin .bundles .CommonBundle ;
1315import com .magento .idea .magento2plugin .bundles .ValidatorBundle ;
1416import java .awt .Container ;
1517import java .awt .Dimension ;
1618import java .awt .Toolkit ;
1719import java .lang .reflect .Field ;
18- import java .lang .reflect .InvocationTargetException ;
19- import java .util .ArrayList ;
20- import java .util .Arrays ;
21- import java .util .HashMap ;
22- import java .util .LinkedHashMap ;
2320import java .util .LinkedList ;
2421import java .util .List ;
25- import java .util .Map ;
2622import javax .swing .JComboBox ;
2723import javax .swing .JComponent ;
2824import javax .swing .JDialog ;
3531/**
3632 * All code generate dialog should extend this class.
3733 */
38- @ SuppressWarnings ({"PMD.ShortVariable" , "PMD.MissingSerialVersionUID" })
3934public abstract class AbstractDialog extends JDialog {
4035
4136 protected CommonBundle bundle ;
4237 protected final ValidatorBundle validatorBundle = new ValidatorBundle ();
38+ protected final List <FieldValidationData > fieldsValidationsList ;
4339 private final String errorTitle ;
44- private final Map <Field , List <ValidationRule >> textFieldValidationRuleMap ;
45- private final Map <Field , Map <ValidationRule , String >> errorMessageFieldValidationRuleMap ;
4640 private JTabbedPane tabbedPane ;
4741 private boolean isValidationErrorShown ;
48- private boolean dialogHasErrors ;
4942
5043 /**
5144 * Abstract Dialog Constructor.
@@ -54,15 +47,14 @@ public AbstractDialog() {
5447 super ();
5548 bundle = new CommonBundle ();
5649 errorTitle = bundle .message ("common.error" );
57- textFieldValidationRuleMap = new LinkedHashMap <>();
58- errorMessageFieldValidationRuleMap = new HashMap <>();
50+ fieldsValidationsList = new TypeFieldsRulesParser (this ).parseValidationRules ();
5951 }
6052
6153 protected void centerDialog (final AbstractDialog dialog ) {
6254 final Dimension screenSize = Toolkit .getDefaultToolkit ().getScreenSize ();
63- final int x = screenSize .width / 2 - dialog .getSize ().width / 2 ;
64- final int y = screenSize .height / 2 - dialog .getSize ().height / 2 ;
65- dialog .setLocation (x , y );
55+ final int coordinateX = screenSize .width / 2 - dialog .getSize ().width / 2 ;
56+ final int coordinateY = screenSize .height / 2 - dialog .getSize ().height / 2 ;
57+ dialog .setLocation (coordinateX , coordinateY );
6658 }
6759
6860 protected void onCancel () {
@@ -74,48 +66,62 @@ protected void onCancel() {
7466 *
7567 * @return boolean
7668 */
69+ @ SuppressWarnings ({"PMD.CyclomaticComplexity" , "PMD.AvoidDeeplyNestedIfStmts" })
7770 protected boolean validateFormFields () {
78- addValidationRulesFromAnnotations () ;
71+ boolean dialogHasErrors ;
7972 isValidationErrorShown = dialogHasErrors = false ;
73+ clearValidationHighlighting ();
8074
81- for (final Map .Entry <Field , List <ValidationRule >> entry
82- : textFieldValidationRuleMap .entrySet ()) {
83- final Field field = entry .getKey ();
84- final List <ValidationRule > rules = entry .getValue ();
75+ for (final FieldValidationData fieldValidationData : getFieldsToValidate ()) {
76+ final Field field = fieldValidationData .getField ();
77+ final List <Pair <ValidationRule , String >> rules = fieldValidationData .getRules ();
8578
86- for (final ValidationRule rule : rules ) {
79+ for (final Pair <ValidationRule , String > rulePair : rules ) {
80+ final ValidationRule rule = rulePair .getFirst ();
81+ final String message = rulePair .getSecond ();
8782 final String value = resolveFieldValueByComponentType (field );
8883
8984 if (value != null && !rule .check (value )) {
90- if (errorMessageFieldValidationRuleMap .containsKey (field )
91- && errorMessageFieldValidationRuleMap .get (field ).containsKey (rule )) {
92- if (!dialogHasErrors ) {
93- final JComponent component = getComponentForField (field );
85+ if (!dialogHasErrors ) {
86+ final JComponent component =
87+ ExtractComponentFromFieldUtil .extract (field , this );
9488
95- if (component != null && tabbedPane != null ) {
96- navigateToTabWithComponent (component );
97- }
89+ if (component != null && tabbedPane != null ) {
90+ navigateToTabWithComponent (component );
9891 }
99- dialogHasErrors = true ;
100- showErrorMessage (
101- field ,
102- errorMessageFieldValidationRuleMap .get (field ).get (rule )
103- );
10492 }
93+ dialogHasErrors = true ;
94+ showErrorMessage (field , message );
10595 break ;
10696 }
10797 }
10898 }
10999
110100 if (dialogHasErrors && !isValidationErrorShown ) {
111- showErrorMessage (
112- validatorBundle .message ("validator.someFieldsHaveErrors" )
113- );
101+ showErrorMessage (validatorBundle .message ("validator.someFieldsHaveErrors" ));
114102 }
115103
116104 return !dialogHasErrors ;
117105 }
118106
107+ /**
108+ * Reset highlighting for fields.
109+ */
110+ protected void clearValidationHighlighting () {
111+ for (final FieldValidationData fieldValidationData : fieldsValidationsList ) {
112+ DialogFieldErrorUtil .resetFieldHighlighting (fieldValidationData .getField (), this );
113+ }
114+ }
115+
116+ /**
117+ * Override this method to change which fields should or shouldn't be validated.
118+ *
119+ * @return List[FieldValidationData]
120+ */
121+ protected List <FieldValidationData > getFieldsToValidate () {
122+ return new LinkedList <>(fieldsValidationsList );
123+ }
124+
119125 /**
120126 * Tabbed pane should be registered to be possible navigate to the tab in which error occurred.
121127 *
@@ -162,130 +168,6 @@ protected void showErrorMessage(final String errorMessage) {
162168 isValidationErrorShown = true ;
163169 }
164170
165- /**
166- * Process validation rules from annotations.
167- */
168- private void addValidationRulesFromAnnotations () {
169- final Class <?> type = this .getClass ();
170- final List <FieldValidation > validations = new LinkedList <>();
171-
172- for (final Field field : type .getDeclaredFields ()) {
173- field .setAccessible (true );
174- validations .clear ();
175-
176- if (field .isAnnotationPresent (FieldValidation .class )) {
177- validations .add (field .getAnnotation (FieldValidation .class ));
178- }
179- if (field .isAnnotationPresent (FieldValidations .class )) {
180- validations .addAll (
181- Arrays .asList (field .getAnnotation (FieldValidations .class ).value ())
182- );
183- }
184-
185- for (final FieldValidation validation : validations ) {
186- try {
187- addValidationRuleToField (
188- field ,
189- getRuleFromAnnotation (validation ),
190- getMessageFromAnnotation (validation )
191- );
192- } catch (NoSuchMethodException | IllegalAccessException
193- | InvocationTargetException | InstantiationException exception ) {
194- return ;
195- } finally {
196- field .setAccessible (false );
197- }
198- }
199- field .setAccessible (false );
200- }
201- }
202-
203- /**
204- * Get error message from annotation.
205- *
206- * @param validation FieldValidation
207- *
208- * @return String
209- */
210- private String getMessageFromAnnotation (final FieldValidation validation ) {
211- String [] params ;
212- final int minMessageArrayLength = 1 ;
213-
214- if (validation .message ().length > minMessageArrayLength ) {
215- params = Arrays .copyOfRange (validation .message (), 1 , validation .message ().length );
216- } else {
217- params = new String []{};
218- }
219- return validatorBundle .message (validation .message ()[0 ], (Object []) params );
220- }
221-
222- /**
223- * Get validation rule from annotation.
224- *
225- * @param validation FieldValidation
226- *
227- * @return ValidationRule
228- */
229- private ValidationRule getRuleFromAnnotation (final FieldValidation validation )
230- throws NoSuchMethodException , IllegalAccessException , InvocationTargetException ,
231- InstantiationException {
232- final Class <?> ruleType = validation .rule ().getRule ();
233-
234- return (ValidationRule ) ruleType .getConstructor ().newInstance ();
235- }
236-
237- /**
238- * Add validation rule for field.
239- *
240- * @param field Field
241- * @param rule ValidationRule
242- * @param message String
243- */
244- protected void addValidationRuleToField (
245- final Field field ,
246- final ValidationRule rule ,
247- final String message
248- ) {
249- if (getComponentForField (field ) == null ) {
250- return ;
251- }
252- List <ValidationRule > rules ;
253-
254- if (textFieldValidationRuleMap .containsKey (field )) {
255- rules = textFieldValidationRuleMap .get (field );
256- } else {
257- rules = new ArrayList <>();
258- }
259-
260- if (!rules .contains (rule ) && rule != null ) {
261- addFieldValidationRuleMessageAssociation (field , rule , message );
262- rules .add (rule );
263- textFieldValidationRuleMap .put (field , rules );
264- }
265- }
266-
267- /**
268- * Associate validation rule with field.
269- *
270- * @param field Field
271- * @param rule ValidationRule
272- * @param message String
273- */
274- private void addFieldValidationRuleMessageAssociation (
275- final Field field ,
276- final ValidationRule rule ,
277- final String message
278- ) {
279- Map <ValidationRule , String > validationRuleErrorMessageMap ;
280- if (errorMessageFieldValidationRuleMap .containsKey (field )) {
281- validationRuleErrorMessageMap = errorMessageFieldValidationRuleMap .get (field );
282- } else {
283- validationRuleErrorMessageMap = new HashMap <>();
284- }
285- validationRuleErrorMessageMap .put (rule , message );
286- errorMessageFieldValidationRuleMap .put (field , validationRuleErrorMessageMap );
287- }
288-
289171 /**
290172 * Resolve value of stored component by field.
291173 *
@@ -294,7 +176,7 @@ private void addFieldValidationRuleMessageAssociation(
294176 * @return String
295177 */
296178 private String resolveFieldValueByComponentType (final Field field ) {
297- final JComponent component = getComponentForField (field );
179+ final JComponent component = ExtractComponentFromFieldUtil . extract (field , this );
298180
299181 if (component instanceof JTextField ) {
300182 return ((JTextField ) component ).isEditable ()
@@ -312,30 +194,6 @@ private String resolveFieldValueByComponentType(final Field field) {
312194 return null ;
313195 }
314196
315- /**
316- * Get JComponent for field.
317- *
318- * @param field Field
319- *
320- * @return JComponent
321- */
322- private JComponent getComponentForField (final @ NotNull Field field ) {
323- try {
324- field .setAccessible (true );
325- final Object component = field .get (this );
326-
327- if (component instanceof JComponent ) {
328- return (JComponent ) component ;
329- }
330- } catch (IllegalAccessException exception ) {
331- return null ;
332- } finally {
333- field .setAccessible (false );
334- }
335-
336- return null ;
337- }
338-
339197 /**
340198 * Navigate to tab with specified component.
341199 *
0 commit comments