Search code examples
oval

Index of an invalid object within a list


Is there an equivalent to the getPropertyPath method in the Oval validation framework?

The example code below prints the properties of all nested invalid values of an object. I'd like to also print the index of the invalid object within the list but I'm not sure how this can be done in Oval.

With javax.validation, I can call ConstraintViolation#getPropertyPath but there doesn't seem to be an equivalent in Oval. Am I missing something?

The output is

list[].value: example.ValidationDemo$Child.value cannot be null
list[].value: example.ValidationDemo$Child.value cannot be null

Here's the code:

package example;

import java.util.List;

import net.sf.oval.ConstraintViolation;
import net.sf.oval.Validator;
import net.sf.oval.constraint.AssertValid;
import net.sf.oval.constraint.NotNull;
import net.sf.oval.context.FieldContext;

public class ValidationDemo {
    public static void main(String[] args) {
        Validator validator = new Validator();
        validator.validate(new Parent())
                .forEach(ValidationDemo::printViolation);
    }

    private static void printViolation(ConstraintViolation violation) {
        printViolation(violation, "");
    }

    private static void printViolation(ConstraintViolation violation, String property) {
        FieldContext fieldContext = (FieldContext) violation.getContext();

        if (!property.isEmpty()) {
            property += ".";
        }

        property += fieldContext.getField().getName();

        if (List.class.isAssignableFrom(fieldContext.getField().getType())) {
            property += "[]"; // How do I find the index of violation.getInvalidValue() within the list?
        }

        if (violation.getCauses() == null) {
            System.out.format("%s: %s\n", property, violation.getMessage());
        } else {
            for (ConstraintViolation cause : violation.getCauses()) {
                printViolation(cause, property);
            }
        }
    }

    public static class Parent {
        @AssertValid
        public final List<Child> list = List.of(new Child("value"),
                new Child(null), new Child(null));
    }

    public static class Child {
        @NotNull
        public final String value;

        public Child(String value) {
            this.value = value;
        }
    }
}

Solution

  • This is currently not possible. This code part would need to be extended to keep track of the index.