package edu.ualberta.med.biobank.validator.constraint.impl; import java.util.List; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import org.hibernate.Criteria; import org.hibernate.EntityMode; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.metadata.ClassMetadata; import org.hibernate.util.StringHelper; import edu.ualberta.med.biobank.validator.EventSourceAwareConstraintValidator; import edu.ualberta.med.biobank.validator.constraint.NotUsed; public class NotUsedValidator extends EventSourceAwareConstraintValidator<Object> implements ConstraintValidator<NotUsed, Object> { private Class<?> by; private String property; @Override public void initialize(NotUsed annotation) { this.by = annotation.by(); this.property = annotation.property(); } @Override public boolean isValidInEventSource(Object value, ConstraintValidatorContext context) { if (value == null) { return true; } boolean unused = countRows(value, property) == 0; if (!unused) { overrideEmptyMessageTemplate(value, context); } return unused; } private void overrideEmptyMessageTemplate(Object value, ConstraintValidatorContext context) { String defaultTemplate = context.getDefaultConstraintMessageTemplate(); if (defaultTemplate.isEmpty()) { ClassMetadata meta = getEventSource().getSessionFactory() .getClassMetadata(value.getClass()); StringBuilder template = new StringBuilder(); template.append("{"); template.append(meta.getMappedClass(EntityMode.POJO).getName()); template.append("."); template.append(NotUsed.class.getSimpleName()); template.append("."); template.append(by.getSimpleName()); template.append("."); template.append(property); template.append("}"); context.disableDefaultConstraintViolation(); context.buildConstraintViolationWithTemplate(template.toString()) .addConstraintViolation(); } } private int countRows(Object value, String property) { Criteria criteria = getEventSource().createCriteria(by); String association = StringHelper.root(property); while (!association.equals(property)) { criteria = criteria.createCriteria(association); property = StringHelper.unroot(property); association = StringHelper.root(property); } List<?> results = criteria .add(Restrictions.eq(property, value)) .setProjection(Projections.rowCount()) .list(); Number count = (Number) results.iterator().next(); return count.intValue(); } }