org.opentestsystem.delivery.testreg.persistence.criteria.Sb11FormatValidatorInvoker.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.delivery.testreg.persistence.criteria.Sb11FormatValidatorInvoker.java

Source

/*******************************************************************************
 * Educational Online Test Delivery System
 * Copyright (c) 2013 American Institutes for Research
 * 
 * Distributed under the AIR Open Source License, Version 1.0
 * See accompanying file AIR-License-1_0.txt or at
 * http://www.smarterapp.org/documents/American_Institutes_for_Research_Open_Source_Software_License.pdf
 ******************************************************************************/

package org.opentestsystem.delivery.testreg.persistence.criteria;

import java.lang.reflect.InvocationTargetException;
import java.util.Set;

import javax.validation.ConstraintViolation;

import org.apache.commons.beanutils.BeanUtils;
import org.opentestsystem.delivery.testreg.domain.FormatType;
import org.opentestsystem.delivery.testreg.domain.TestRegistrationBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;

@Component
public class Sb11FormatValidatorInvoker implements ValidatorInvoker {

    @Autowired
    private javax.validation.Validator validator; // jsr303

    public boolean invokeValidator(final TestRegistrationBase sb11Entity, final Errors errors,
            final Object... hints) {
        return processConstraintViolations(sb11Entity.getFormatType(),
                validator.validate(sb11Entity, (Class<?>) hints[0]), errors);
    }

    private boolean processConstraintViolations(final FormatType format,
            final Set<ConstraintViolation<TestRegistrationBase>> violations, final Errors errors) {
        boolean hasErrors = false;
        for (ConstraintViolation<TestRegistrationBase> violation : violations) {
            ((BindingResult) errors).addError(new FieldError(format.name(), violation.getPropertyPath().toString(),
                    getInvalidValue(violation), false, null, null, violation.getMessage()));
            hasErrors = true;
        }
        return hasErrors;
    }

    /**
     * This method lookups the invalid value thru the field name where the violation occurred. The reason for that is
     * constraint violations can occur at all levels namely field, method or class. For Class level violations bean
     * validation implementation will always return the whole object as invalid value. Since our usecases are at the
     * field level, this behavior is customized to lookup a specific field when a violation occurs.
     * 
     * @param violation
     *            ConstraintViolation object
     * 
     * @return Invalid Value of the field where the violation occurred.
     */
    private String getInvalidValue(final ConstraintViolation<TestRegistrationBase> violation) {
        try {
            return BeanUtils.getProperty(violation.getRootBean(), violation.getPropertyPath().toString());
        } catch (InvocationTargetException ite) {//Get the invalid value when not possible due to enum conversion issues
            return violation.getInvalidValue() == null ? "" : violation.getInvalidValue().toString();
        } catch (IllegalAccessException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

}