How to make Custom Constraints work in Grails 3.3.10?

179 views Asked by At

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

There are 0 answers