org.opentestsystem.authoring.testauth.validation.PerformanceLevelValidator.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.authoring.testauth.validation.PerformanceLevelValidator.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.authoring.testauth.validation;

import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;

import org.opentestsystem.authoring.testauth.domain.PerformanceLevel;
import org.opentestsystem.authoring.testauth.domain.PerformanceLevelValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Ordering;

@Component
public class PerformanceLevelValidator extends AbstractDomainValidator {
    private static final String ERROR_MSG_ROOT = "performanceLevel.";
    private static final String PERFORMANCE_LEVEL_VALUES = "performanceLevelValues";
    private static final String PERFORMANCE_LEVEL_VALUES_POSITION = PERFORMANCE_LEVEL_VALUES + ".level";

    private static final String EMPTY_LEVEL = "-1";

    private static final Function<PerformanceLevelValue, String> PERFORMANCE_LEVEL_TO_POSITION_TRANSFORMER = new Function<PerformanceLevelValue, String>() {
        @Override
        public String apply(final PerformanceLevelValue performanceLevelValue) {
            return performanceLevelValue == null ? EMPTY_LEVEL : performanceLevelValue.getLevel().toString();
        }
    };

    private static final Predicate<Entry<String, Collection<PerformanceLevelValue>>> PERFORMANCE_LEVEL_DUPLICATE_FILTER = new Predicate<Entry<String, Collection<PerformanceLevelValue>>>() {
        @Override
        public boolean apply(final Entry<String, Collection<PerformanceLevelValue>> entry) {
            return !EMPTY_LEVEL.equals(entry.getKey()) && entry.getValue().size() > 1;
        }
    };

    @Autowired
    @Qualifier("jsr303Validator")
    private Validator jsrValidator;

    @Autowired
    private PerformanceLevelValueValidator performanceLevelValueValidator;

    @Override
    public boolean supports(final Class<?> clazz) {
        return PerformanceLevel.class.equals(clazz);
    }

    @Override
    public void validate(final Object obj, final Errors errors) {
        // execute JSR-303 validations (annotations)
        this.jsrValidator.validate(obj, errors);

        final PerformanceLevel performanceLevel = (PerformanceLevel) obj;
        if (!errors.hasErrors() && !CollectionUtils.isEmpty(performanceLevel.getPerformanceLevelValues())) {

            // custom validation for each performanceLevelValue
            for (int i = 0; i < performanceLevel.getPerformanceLevelValues().size(); i++) {
                final PerformanceLevelValue nextValue = performanceLevel.getPerformanceLevelValues().get(i);
                try {
                    errors.pushNestedPath(PERFORMANCE_LEVEL_VALUES + "[" + i + "]");
                    ValidationUtils.invokeValidator(this.performanceLevelValueValidator, nextValue, errors);

                    if (nextValue.getLevel() > performanceLevel.getPerformanceLevelValues().size()) {
                        rejectValue(errors, "level",
                                getErrorMessageRoot() + PERFORMANCE_LEVEL_VALUES_POSITION + MSG_INVALID,
                                nextValue.getLevel());
                    }
                } finally {
                    errors.popNestedPath();
                }
            }

            // check for duplicate performanceLevelValue level
            final Map<String, Collection<PerformanceLevelValue>> duplicateLevels = Maps
                    .filterEntries(
                            Multimaps.index(performanceLevel.getPerformanceLevelValues(),
                                    PERFORMANCE_LEVEL_TO_POSITION_TRANSFORMER).asMap(),
                            PERFORMANCE_LEVEL_DUPLICATE_FILTER);

            if (!duplicateLevels.isEmpty()) {
                rejectValue(errors, PERFORMANCE_LEVEL_VALUES,
                        getErrorMessageRoot() + PERFORMANCE_LEVEL_VALUES_POSITION + MSG_DUPLICATES,
                        duplicateLevels.keySet().toString());
            } else if (!errors.hasErrors()) {
                performanceLevel.setPerformanceLevelValues(
                        Lists.newArrayList(Ordering.natural().onResultOf(PERFORMANCE_LEVEL_TO_POSITION_TRANSFORMER)
                                .sortedCopy(performanceLevel.getPerformanceLevelValues())));
            }
        }
    }

    @Override
    protected String getErrorMessageRoot() {
        return ERROR_MSG_ROOT;
    }
}