diff --git a/validator/src/main/java/io/smallrye/config/validator/BeanValidationConfigValidator.java b/validator/src/main/java/io/smallrye/config/validator/BeanValidationConfigValidator.java index b21f7f443..8f8f31a42 100644 --- a/validator/src/main/java/io/smallrye/config/validator/BeanValidationConfigValidator.java +++ b/validator/src/main/java/io/smallrye/config/validator/BeanValidationConfigValidator.java @@ -152,6 +152,35 @@ default void validateProperty( throw new UndeclaredThrowableException(t2); } } + } else if (mapProperty.getValueProperty().isCollection()) { + try { + CollectionProperty collectionProperty = mapProperty.getValueProperty().asCollection(); + if (collectionProperty.getElement().isGroup()) { + Map map = (Map) property.getMethod().invoke(mappingObject); + for (Map.Entry entry : map.entrySet()) { + Collection elements = (Collection) entry.getValue(); + int i = 0; + for (Object element : elements) { + validateMappingInterface(collectionProperty.getElement().asGroup().getGroupType(), + appendPropertyName(currentPath, property) + "." + entry.getKey() + "[" + i + "]", + namingStrategy, element, problems); + i++; + } + } + } else if (collectionProperty.getElement().isLeaf()) { + validatePropertyValue(property, currentPath, namingStrategy, mappingObject, problems); + } + } catch (IllegalAccessException e) { + throw new IllegalAccessError(e.getMessage()); + } catch (InvocationTargetException e) { + try { + throw e.getCause(); + } catch (RuntimeException | Error e2) { + throw e2; + } catch (Throwable t2) { + throw new UndeclaredThrowableException(t2); + } + } } else if (mapProperty.getValueProperty().isLeaf()) { validatePropertyValue(property, currentPath, namingStrategy, mappingObject, problems); } @@ -224,6 +253,6 @@ default String interpolateMessage( } } } - return propertyName.toString() + " " + violation.getMessage(); + return propertyName + " " + violation.getMessage(); } } diff --git a/validator/src/test/java/io/smallrye/config/validator/ValidateConfigTest.java b/validator/src/test/java/io/smallrye/config/validator/ValidateConfigTest.java index 4a6aaf165..6f9eccfb1 100644 --- a/validator/src/test/java/io/smallrye/config/validator/ValidateConfigTest.java +++ b/validator/src/test/java/io/smallrye/config/validator/ValidateConfigTest.java @@ -47,7 +47,10 @@ void validateConfigMapping() { "server.info.name", "Bond", "server.info.code", "007", "server.info.alias[0]", "James", - "server.info.admins.root.username", "root")) + "server.info.admins.root[0].username", "root", + "server.info.admins.root[1].username", "admin", + "server.info.firewall.accepted[0]", "127.0.0.1", + "server.info.firewall.accepted[1]", "8.8.8")) .withMapping(Server.class, "server") .build(); @@ -57,6 +60,7 @@ void validateConfigMapping() { for (int i = 0; i < validationException.getProblemCount(); i++) { validations.add(validationException.getProblem(i).getMessage()); } + assertEquals(14, validations.size()); assertTrue(validations.contains("server.port must be less than or equal to 10")); assertTrue(validations.contains("server.log.days must be less than or equal to 15")); assertTrue(validations.contains("server.proxy.timeout must be less than or equal to 10")); @@ -69,7 +73,8 @@ void validateConfigMapping() { assertTrue(validations.contains("server.info.name size must be between 0 and 3")); assertTrue(validations.contains("server.info.code must be less than or equal to 3")); assertTrue(validations.contains("server.info.alias[0] size must be between 0 and 3")); - assertTrue(validations.contains("server.info.admins.root.username size must be between 0 and 3")); + assertTrue(validations.contains("server.info.admins.root[1].username size must be between 0 and 4")); + assertTrue(validations.contains("server.info.firewall.accepted[1] size must be between 8 and 15")); } @Test @@ -173,10 +178,12 @@ interface Info { Optional> alias(); - Map admins(); + Map> admins(); + + Map> firewall(); interface Admin { - @Size(max = 3) + @Size(max = 4) String username(); } }