@@ -97,7 +97,7 @@ public static Validator getValidator(Class<?> type){
9797 Validator validator = validators .get (type );
9898 if (validator == null ){
9999 validator = new Validator ();
100- getClassRules (type ).forEach (validator ::rule );
100+ getClassRules (null , type ).forEach (validator ::rule );
101101 validators .put (type , validator );
102102 }
103103 return validator ;
@@ -115,14 +115,19 @@ public static <T> T map(Class<T> type, AbstractElement element){
115115 return map (type , element , new AbstractMapper ());
116116 }
117117
118- private final Map <String [], List < ValidationRule > > rules = new HashMap <>();
118+ private final Map <String [], ValidationConfig > rules = new HashMap <>();
119119
120120 public Validator rule (String [] key , ValidationRule ... rules ){
121121 return rule (key , Arrays .asList (rules ));
122122 }
123123
124124 public Validator rule (String [] key , List <ValidationRule > rules ){
125- this .rules .put (key , rules );
125+ this .rules .put (key , new ValidationConfig (null , rules ));
126+ return this ;
127+ }
128+
129+ private Validator rule (String [] key , ValidationConfig config ){
130+ this .rules .put (key , config );
126131 return this ;
127132 }
128133
@@ -142,11 +147,12 @@ public ValidationResult validate(AbstractElement rootElement){
142147 return new ValidationResult (errors );
143148 }
144149
145- private Map <String [], List <String >> check (Map <String [], List < ValidationRule > > rules , String [] keyPrefix , String [] resolvedKeyPrefix , String [] key , AbstractElement element ){
150+ private Map <String [], List <String >> check (Map <String [], ValidationConfig > rules , String [] keyPrefix , String [] resolvedKeyPrefix , String [] key , AbstractElement element ){
146151 if (key .length == 0 ){
147152 Map <String [], List <String >> errors = new HashMap <>();
148- for (ValidationRule rule : getMapValue (rules , keyPrefix )){
149- String error = rule .validate (this , element );
153+ ValidationConfig config = getMapValue (rules , keyPrefix );
154+ for (ValidationRule rule : config .rules ){
155+ String error = rule .validate (this , config .field , element );
150156 if (error != null ){
151157 if (!errors .containsKey (resolvedKeyPrefix ))
152158 errors .put (resolvedKeyPrefix , new ArrayList <>());
@@ -220,7 +226,7 @@ private static <V> V getMapValue(Map<String[], V> map, String[] key){
220226 return null ;
221227 }
222228
223- private static <V > void putMapValue (Map <String [], Object > map , String [] key , Object value ){
229+ private static <V > void putValidationConfigMapValue (Map <String [], ValidationConfig > map , String [] key , ValidationConfig value ) {
224230 for (String [] k : map .keySet ()){
225231 if (stringArrayEqual (k , key )){
226232 map .put (k , value );
@@ -230,12 +236,12 @@ private static <V> void putMapValue(Map<String[], Object> map, String[] key, Obj
230236 map .put (key , value );
231237 }
232238
233- private static < V > void addMapListEntryValue ( Map map , String [] key , List values ) {
234- List < Object > list = ( List < Object >) getMapValue (map , key );
235- if (list == null )
236- list = new ArrayList <>();
237- list . addAll (values );
238- putMapValue (map , key , list );
239+ private static void addMapRules ( Field field , Map < String [], ValidationConfig > map , String [] key , List < ValidationRule > rules ) {
240+ ValidationConfig config = getMapValue (map , key );
241+ if (config == null )
242+ config = new ValidationConfig ( field , new ArrayList <>() );
243+ config . rules . addAll (rules );
244+ putValidationConfigMapValue (map , key , config );
239245 }
240246
241247 private static String toSnakeCase (String source ){
@@ -260,55 +266,64 @@ private static String getFieldName(Field field){
260266 return toSnakeCase (field .getName ());
261267 }
262268
263- private static Map <String [], List <ValidationRule >> getClassRules (Class <?> type ){
264- Map <String [], List <ValidationRule >> rules = new HashMap <>();
269+ private static class ValidationConfig {
270+ private final Field field ;
271+ private final List <ValidationRule > rules ;
272+ public ValidationConfig (Field field , List <ValidationRule > rules ) {
273+ this .field = field ;
274+ this .rules = rules ;
275+ }
276+ }
277+
278+ private static Map <String [], ValidationConfig > getClassRules (Field field , Class <?> type ){
279+ Map <String [], ValidationConfig > rules = new HashMap <>();
265280 if (type .isAnnotation ())
266281 return rules ;
267282 if (type .equals (String .class ))
268283 return rules ;
269284 if (type .equals (Timestamp .class ) || type .equals (java .util .Date .class )){
270- rules .put (new String [0 ], Collections .singletonList (new DateRule (new String []{})));
285+ rules .put (new String [0 ], new ValidationConfig ( field , Collections .singletonList (new DateRule (new String []{}) )));
271286 return rules ;
272287 }
273288 if (type .equals (Date .class )){
274- rules .put (new String [0 ], Collections .singletonList (new DateRule (new String []{"date" })));
289+ rules .put (new String [0 ], new ValidationConfig ( field , Collections .singletonList (new DateRule (new String []{"date" }) )));
275290 return rules ;
276291 }
277292 if (type .equals (Boolean .class )){
278- rules .put (new String [0 ], Collections .singletonList (new BooleanRule ()));
293+ rules .put (new String [0 ], new ValidationConfig ( field , Collections .singletonList (new BooleanRule () )));
279294 return rules ;
280295 }
281296 if (type .equals (Integer .class )){
282- rules .put (new String [0 ], Collections .singletonList (new IntegerRule (Integer .MIN_VALUE , Integer .MAX_VALUE )));
297+ rules .put (new String [0 ], new ValidationConfig ( field , Collections .singletonList (new IntegerRule (Integer .MIN_VALUE , Integer .MAX_VALUE ) )));
283298 return rules ;
284299 }
285300 if (type .equals (UUID .class )){
286- rules .put (new String [0 ], Collections .singletonList (new UUIDRule ()));
301+ rules .put (new String [0 ], new ValidationConfig ( field , Collections .singletonList (new UUIDRule () )));
287302 return rules ;
288303 }
289304 if (type .isEnum ()){
290- rules .put (new String [0 ], Collections .singletonList (new EnumRule ((Class <? extends Enum <?>>) type )));
305+ rules .put (new String [0 ], new ValidationConfig ( field , Collections .singletonList (new EnumRule ((Class <? extends Enum <?>>) type ) )));
291306 return rules ;
292307 }
293308 if (type .isArray ()){
294- getClassRules (type .getComponentType ()).forEach ((key , validators ) -> {
309+ getClassRules (null , type .getComponentType ()).forEach ((key , validators ) -> {
295310 String [] actualKey = new String [key .length +1 ];
296311 actualKey [0 ] = "*" ;
297312 System .arraycopy (key , 0 , actualKey , 1 , key .length );
298- addMapListEntryValue ( rules , actualKey , validators );
313+ addMapRules ( null , rules , actualKey , validators . rules );
299314 });
300315 return rules ;
301316 }
302- for (Field field : getFieldsRecursive (type )){
303- String name = getFieldName (field );
304- getClassRules (field .getType ()).forEach ((key , validators ) -> {
317+ for (Field f : getFieldsRecursive (type )){
318+ String name = getFieldName (f );
319+ getClassRules (f , f .getType ()).forEach ((key , validators ) -> {
305320 String [] actualKey = new String [key .length +1 ];
306321 actualKey [0 ] = name ;
307322 System .arraycopy (key , 0 , actualKey , 1 , key .length );
308- addMapListEntryValue ( rules , actualKey , validators );
323+ addMapRules ( f , rules , actualKey , validators . rules );
309324 });
310- field .setAccessible (true );
311- Rule [] ruleAnnotations = field .getDeclaredAnnotationsByType (Rule .class );
325+ f .setAccessible (true );
326+ Rule [] ruleAnnotations = f .getDeclaredAnnotationsByType (Rule .class );
312327 if (ruleAnnotations .length > 0 ){
313328 List <ValidationRule > r = new ArrayList <>();
314329 for (String source : ruleAnnotations [0 ].value ()){
@@ -317,7 +332,7 @@ private static Map<String[], List<ValidationRule>> getClassRules(Class<?> type){
317332 r .add (rule );
318333 }
319334 if (r .size () > 0 )
320- addMapListEntryValue ( rules , new String []{name }, r );
335+ addMapRules ( f , rules , new String []{name }, r );
321336 }
322337 }
323338 return rules ;
0 commit comments