org.opentestsystem.delivery.testreg.rest.ValidationHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.delivery.testreg.rest.ValidationHelper.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.rest;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.opentestsystem.delivery.testreg.rest.ValidationMessage.ValidationMessageType;
import org.opentestsystem.delivery.testreg.upload.RowMetadata;
import org.opentestsystem.delivery.testreg.upload.RowMetadataImpl.RowErrorType;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

/**
 * Helper class for transforming spring binding errors into list of validation result objects.
 */
public final class ValidationHelper {

    private static final String GLOBAL_ERROR = "GLOBAL";

    private ValidationHelper() {
        // singleton
    }

    /**
     * Transforms binding result errors into validation messages.
     * 
     * @param result contains global and field errors
     * @return List of FileValidationResult
     */
    public static List<FileValidationResult> transform(final BindingResult result, final int errorCountThreshold) {

        final Map<String, List<ValidationMessage>> errorMap = new TreeMap<String, List<ValidationMessage>>();
        if (result.hasGlobalErrors()) {
            errorMap.putAll(transformGlobalErrors(result.getGlobalErrors()));
        }
        if (result.hasFieldErrors()) {
            final Map<String, List<ValidationMessage>> fieldErrors = transformFieldErrors(result.getFieldErrors());
            for (final String key : fieldErrors.keySet()) {
                if (errorMap.containsKey(key)) {
                    errorMap.get(key).addAll(fieldErrors.get(key));
                } else {
                    errorMap.put(key, fieldErrors.get(key));
                }
            }
        }
        return buildValidationResult(errorMap, errorCountThreshold);
    }

    /**
     * Transform global errors.
     * 
     * @param errors global errors
     * @return Map of validation messages for each worksheet
     */
    private static Map<String, List<ValidationMessage>> transformGlobalErrors(final List<ObjectError> errors) {
        final Map<String, List<ValidationMessage>> errorMap = new TreeMap<String, List<ValidationMessage>>();
        for (final ObjectError error : errors) {
            final ValidationMessage message = new ValidationMessage();
            message.setEntityName(GLOBAL_ERROR);
            message.setMessage(error.getDefaultMessage());
            message.setType(ValidationMessageType.FATAL_ERROR);
            addToErrorMap(errorMap, message);
        }
        return errorMap;
    }

    /**
     * Transform field errors.
     * 
     * @param errors field errors
     * @return Map of validation messages for each worksheet
     */
    private static Map<String, List<ValidationMessage>> transformFieldErrors(final List<FieldError> errors) {
        final Map<String, List<ValidationMessage>> errorMap = new TreeMap<String, List<ValidationMessage>>();
        for (final FieldError error : errors) {
            final ValidationMessage message = new ValidationMessage();
            message.setEntityName(error.getObjectName());
            message.setFieldName(error.getField());
            message.setFieldValue(String.valueOf(error.getRejectedValue()));
            message.setMessage(error.getDefaultMessage());
            final RowMetadata rowMetadata = (RowMetadata) error.getArguments()[0];
            message.setRecordNumber(rowMetadata.getRowNum());
            if (rowMetadata.getErrorType() == RowErrorType.FATAL_ERROR) {
                message.setType(ValidationMessageType.FATAL_ERROR);
            } else if (rowMetadata.getErrorType() == RowErrorType.RECORD_ERROR) {
                message.setType(ValidationMessageType.FATAL_ERROR);
            } else {
                message.setType(ValidationMessageType.WARNING);
            }
            addToErrorMap(errorMap, message);
        }

        return errorMap;
    }

    private static void addToErrorMap(final Map<String, List<ValidationMessage>> errorMap,
            final ValidationMessage message) {
        List<ValidationMessage> messages = errorMap.get(message.getEntityName());
        if (messages == null) {
            messages = new ArrayList<ValidationMessage>();
            messages.add(message);
            errorMap.put(message.getEntityName(), messages);
        } else {
            messages.add(message);
        }
    }

    private static List<FileValidationResult> buildValidationResult(
            final Map<String, List<ValidationMessage>> errorMap, final int errorCountThreshold) {
        final List<FileValidationResult> validationResults = new ArrayList<FileValidationResult>();
        for (final Map.Entry<String, List<ValidationMessage>> entry : errorMap.entrySet()) {
            final FileValidationResult validationResult = new FileValidationResult();
            validationResult.setFormatType(entry.getKey().toUpperCase());
            Collections.sort(entry.getValue());
            for (final ValidationMessage message : entry.getValue()) {
                validationResult.addError(message);
            }
            if (!CollectionUtils.isEmpty(validationResult.getFatalErrors())
                    && validationResult.getFatalErrors().size() > errorCountThreshold) {
                validationResult.setFatalErrorsTotalCount(validationResult.getFatalErrors().size());
                validationResult.setFatalErrors(Lists
                        .newArrayList(Iterables.limit(validationResult.getFatalErrors(), errorCountThreshold)));
            }
            if (!CollectionUtils.isEmpty(validationResult.getRecordErrors())
                    && validationResult.getRecordErrors().size() > errorCountThreshold) {
                validationResult.setRecordErrorsTotalCount(validationResult.getRecordErrors().size());
                validationResult.setRecordErrors(Lists
                        .newArrayList(Iterables.limit(validationResult.getRecordErrors(), errorCountThreshold)));
            }
            if (!CollectionUtils.isEmpty(validationResult.getWarnings())
                    && validationResult.getWarnings().size() > errorCountThreshold) {
                validationResult.setWarningsTotalCount(validationResult.getWarnings().size());
                validationResult.setWarnings(
                        Lists.newArrayList(Iterables.limit(validationResult.getWarnings(), errorCountThreshold)));
            }
            validationResults.add(validationResult);
        }
        return validationResults;
    }
}