1
votes

In JSR-303, is there any way to change the value while validating?

public class MyEntity {

    public String getName() {
        return name;
    }

    // is it true that JSF/JAXB/JPA will always use this setter method?
    public void setName(final String name) {
        if (name == null) {
            throw new NullPointerException("null name");
        }
        final String collapsed = new CollapsedStringAdapter().unmarshal(name);
        if (collapsed.length() < NAME_SIZE_MIN) {
            throw new IllegalArgumentException("too short");
        }
        if (collapsed.length() > NAME_SIZE_MAX) {
            throw new IllegalArgumentException("too long");
        }
        this.name = collapsed;
    }

    @NotNull
    @Size(min = 1, max = 40)
    @CollapsedStringSize(min = 1, max = 40) // xs:token
    private String name;

    @NotNull
    @Size(min = 0, max = 255)
    @NormalizedStringSize(min = 0, max = 255) // xs:normalizedString
    private String description;
}

Say, I'm going to make a custom validator something look like

@Constraint(validatedBy = CollapsedStringSizeValidator.class)
public @interface CollapsedStringSize {
    int min() default 0;
    int max() default Integer.MAX_VALUE;
}

public class CollapsedStringSizeValidator
    implements ConstraintValidator<CollapsedStringSize, String> {

    @Override
    public boolean isValid(String object,
                           ConstraintValidatorContext constraintContext) {

        if (object == null) {
            return true;
        }

        final String collapsed = new CollapsedStringAdapter().unmarshal(object);

        // how can I get the min/mix anyway?

        return collapsed.length() >= min && collapsed.length() <= max;
    }
}

Is there any way to change the value before or while a validator validate/validating?
Do I have to stuck with the setter?

1
May I ask why you want to change the value while the engine is validating? Could your describe more information about your case? - Mike Lue
actually my original concern is keeping the value as a valid form (collapsed/normalized) before marshalling to XML or before persisting to DB. - Jin Kwon
Well, if your can figure out the "valid form" of input data automatically, using setter is possible before the data is persisted into database. The main use of validation framework is to validate data, which can't be corrected automatically, without complicating your code of business logic. Moreover, validation framework let you just write the validation logic at a testable unit. - Mike Lue

1 Answers

1
votes

In your example, the setName() should be:

public void setName(final String name) {
    if (name == null) {
        this.name = null;
        return;
    }
    this.name = new CollapsedStringAdapter().unmarshal(name);
}

As above modification, you don't have to use @CollapsedStringSize anymore. The @Size is sufficient for your validation.

In JPA, if you want to process data after the JPA engine has loaded data into your entity object, you may try @PostLoad.