4

We are migrating from Grails 2.5.4 to Grails 3.3.10. Among the many road blocks, one is our Registered Custom Constaints no longer work. Upon some research, we found that there is a new way in Grails 3.3.10 to declare as well as register these Constraints.

Even after following those steps, it seems like these constraints are simply being ignored. Am I missing something here?

The Custom Constraint Class:

    package com.simpleinteract.constraints

import com.simpleinteract.utils.SimpleInteractDateUtils
import org.grails.datastore.gorm.validation.constraints.AbstractConstraint
import org.springframework.context.MessageSource
import org.springframework.validation.Errors

class DateOfBirthConstraint extends AbstractConstraint {

    static final String CONSTRAINT_NAME = "dob"
    static final IntRange YEAR_RANGE = (1890..(SimpleInteractDateUtils.currentYear))
    static final String DEFAULT_CODE = "invalid"
    static final String DEFAULT_MESSAGE_CODE = "default.dateOfBirth.invalid.message"

    private final boolean dob;

    public DateOfBirthConstraint(Class<?> constraintOwningClass, String constraintPropertyName, Object constraintParameter, MessageSource messageSource) {
        super(constraintOwningClass, constraintPropertyName, constraintParameter, messageSource);
        this.dob = (boolean) this.constraintParameter;
    }

    /* (non-Javadoc)
     * @see org.grails.validation.Constraint#supports(java.lang.Class)
     */
    @SuppressWarnings("rawtypes")
    public boolean supports(Class type) {
        return type != null && String.class.isAssignableFrom(type);
    }

    @Override
    protected Object validateParameter(Object constraintParameter) {
        if (!(constraintParameter instanceof Boolean)) {
            throw new IllegalArgumentException("Parameter for constraint [" +
                    dob + "] of property [" +
                    constraintPropertyName + "] of class [" + constraintOwningClass +
                    "] must be a boolean value");
        }

        return constraintParameter;
    }


    public String getName() {
        return CONSTRAINT_NAME;
    }

    @Override
    protected void processValidate(Object target, Object propertyValue, Errors errors) {
        if (!dob) {
            return;
        }

        Object[] args = [constraintPropertyName, constraintOwningClass, propertyValue]

        if (isValid(propertyValue)) {
            rejectValue(target, errors, DEFAULT_MESSAGE_CODE,
                    CONSTRAINT_NAME + DEFAULT_CODE, args);
        }
    }

    protected void isValid(propertyValue) {
        !(propertyValue && propertyValue instanceof Date && (!YEAR_RANGE?.contains(SimpleInteractDateUtils.getYear(propertyValue)) || propertyValue >= new Date()?.clearTime()))
    }

}

I am registering this Constraint in the init block of Bootstrap.groovy as follows:

    ValidatorRegistry gormValidatorRegistry
    gormValidatorRegistry.addConstraint(DateOfBirthConstraint)

I can see that this constraint has been added to the Registry, as follows:

ctx.gormValidatorRegistry.findConstraintFactories(DateOfBirthConstraint)*.properties

I have used this constraint as follows in a validateable class:

class IdentityCO implements Validateable{
    Date dateOfBirth

    IdentityCO() {}

    static constraints = {
        dateOfBirth nullable: false, dob: true
    }
}

0 Answers0