Jin Kwon
Jin Kwon

Reputation: 21978

JSR-303 Bean Validation changing the value while validating

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?

Upvotes: 1

Views: 2417

Answers (1)

Mike Lue
Mike Lue

Reputation: 839

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.

Upvotes: 1

Related Questions