org.opentestsystem.delivery.testreg.persistence.criteria.verifiers.accommodation.AccommodationOptionsCodeVerifier.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.delivery.testreg.persistence.criteria.verifiers.accommodation.AccommodationOptionsCodeVerifier.java

Source

/*************************************************************************
 * Educational Online Test Delivery System
 * Copyright (c) 2015 American Institutes for Research
 *
 * Distributed under the AIR Open Source License, Version 1.0
 * See accompanying file AIR-License-1_0.txt or at 
 * https://bitbucket.org/sbacoss/eotds/wiki/AIR_Open_Source_License
 *************************************************************************/

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

import static org.opentestsystem.delivery.testreg.persistence.criteria.verifiers.VerifierUtils.addFieldError;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.beanutils.PropertyUtils;
import org.opentestsystem.delivery.testreg.domain.Accommodation;
import org.opentestsystem.delivery.testreg.domain.AccommodationResourceType;
import org.opentestsystem.delivery.testreg.domain.FormatType;
import org.opentestsystem.delivery.testreg.domain.Student;
import org.opentestsystem.delivery.testreg.persistence.Verifier;
import org.opentestsystem.delivery.testreg.service.AccommodationCacheService;
import org.opentestsystem.delivery.testreg.service.MasterResourceAccommodationService;
import org.opentestsystem.delivery.testreg.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.FieldError;

@Component
public class AccommodationOptionsCodeVerifier implements Verifier<Accommodation> {
    @Autowired
    private MasterResourceAccommodationService masterResourceService;

    @Resource(name = "templateDownloadMap")
    private Map<String, List<String>> templateDownloadMap;

    @Autowired
    private StudentService studentService;

    @Autowired
    private AccommodationCacheService accommodationCacheService;

    @Resource(name = "gradeLevel")
    private Map<String, String> gradeLevel;

    @Override
    public List<FieldError> verify(final Accommodation accommodation) {
        /*
         * we are verfiying 
         * 1)whether their are any duplicate codes in accommodation
          *      
          * 2)if multi-valued resource in accommodation has default value then other options are not compatible with that default value 
          *
         * 3) check the options user enter for each accesiblity resource some options may not be available based on subject and grade
          */
        List<FieldError> errors = new ArrayList<FieldError>();

        List<String> excludeHeaders = new ArrayList<String>();
        excludeHeaders.add("StudentIdentifier");
        excludeHeaders.add("StateAbbreviation");
        excludeHeaders.add("Subject");

        Student student = studentService.findByStudentIdAndStateAbbreviation(accommodation.getStudentId(),
                accommodation.getStateAbbreviation());
        HashMap<String, List<String>> accOptions = accommodationCacheService
                .getResourceOptionCodes(accommodation.getSubject(), student.getGrade());
        HashMap<String, List<String>> masterResourceOptionsCode = masterResourceService.getMasterResourceOptions();

        List<String> headerCodes = templateDownloadMap.get(FormatType.DESIGNATEDSUPPORTSANDACCOMMODATIONS);

        try {
            //colorCodes,AmericanSignLanguage,..
            for (String headerCode : headerCodes) {
                if (!excludeHeaders.contains(headerCode)) {
                    String heaerProperty = getHeaderPropertyName(headerCode);
                    Object value = PropertyUtils.getProperty(accommodation, heaerProperty);

                    if (value != null) {

                        List<String> options = accOptions.get(headerCode);
                        AccommodationResourceType resourceType = masterResourceService.getResourceType(headerCode);
                        List<String> masterOptions = masterResourceOptionsCode.get(headerCode);
                        switch (resourceType) {
                        case MultiSelectResource:

                            List<String> loadedOptions = convertOptionsToList(value);
                            String defaultOptionValue = masterResourceService.getDefaultOption(headerCode);
                            if (value != null & value.toString().length() > 0
                                    && !options.containsAll(loadedOptions)) {
                                addFieldError(errors, accommodation, headerCode, value.toString(), headerCode
                                        + " some of these options are not available for this combination of subject and grade");
                            }

                            if (loadedOptions != null && !masterOptions.containsAll(loadedOptions)) {
                                final String message = "Invalid value for " + headerCode + " accommodation ";
                                addFieldError(errors, accommodation, headerCode, value.toString(), message);
                            }

                            final Set<String> duplicates = findDuplicateCodes(loadedOptions);
                            if (!CollectionUtils.isEmpty(duplicates)) {
                                for (final String dupCodes : duplicates) {
                                    final String message = "Duplicate code " + dupCodes + " in accommodation";
                                    addFieldError(errors, accommodation, headerCode, dupCodes, message);
                                }
                            }

                            if (loadedOptions != null && loadedOptions.contains(defaultOptionValue)
                                    && loadedOptions.size() > 0) {
                                final String message = " : Incompatible option combination with"
                                        + defaultOptionValue;
                                addFieldError(errors, accommodation, headerCode, value.toString(),
                                        headerCode + message);
                            }
                            break;
                        case EditResource:
                            //No Validation required.
                            break;
                        case SingleSelectResource:
                            if (value != null && value.toString().length() > 0 && !options.contains(value)
                                    && masterOptions.contains(value)) {
                                addFieldError(errors, accommodation, headerCode, value.toString(), headerCode
                                        + " option is not available for this combination of subject and grade");
                            }

                            if (value != null && value.toString().length() > 0 && !masterOptions.contains(value)) {
                                final String message = "Invalid value for " + headerCode + " accommodation ";
                                addFieldError(errors, accommodation, headerCode, value.toString(), message);
                            }
                            break;
                        default:
                            //do nothing
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return errors;
    }

    /**
     * @param value
     * @return
     */
    private List<String> convertOptionsToList(Object value) {
        List<String> values = (ArrayList<String>) value;
        List<String> loadedOptions = new ArrayList<String>();
        for (int i = 0; i < values.size(); i++) {
            loadedOptions.add(values.get(i).toString());
        }
        return loadedOptions;
    }

    /**
     * we need to match header names of accommodation template/UI with accommodation properties 
     * @param headerCode
     * @return
     */
    private String getHeaderPropertyName(String headerCode) {
        String headerAlias = null;
        switch (headerCode) {
        case "Zoom":
            headerAlias = "printSize";
            break;
        case "ColorChoices":
            headerAlias = "colorContrast";
            break;
        case "TexttoSpeech":
            headerAlias = "textToSpeech";
        default:
            break;
        }
        if (headerAlias != null) {
            return headerAlias;
        }

        char c[] = headerCode.toCharArray();
        String headerProperty = Character.toLowerCase(c[0]) + headerCode.substring(1);
        return headerProperty;
    }

    private Set<String> findDuplicateCodes(List<String> codes) {
        final Set<String> code = new HashSet<String>();
        final Set<String> duplicates = new HashSet<String>();
        for (String option : codes) {
            if (code.contains(option)) {
                duplicates.add(option);
            } else {
                code.add(option);
            }
        }
        return duplicates;
    }
}