org.opentestsystem.authoring.testauth.service.impl.PerformanceLevelServiceImpl.java Source code

Java tutorial

Introduction

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

import static org.opentestsystem.authoring.testauth.config.TestAuthUtil.paramArray;

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

import org.apache.commons.lang.StringUtils;
import org.opentestsystem.authoring.testauth.domain.AffinityGroup;
import org.opentestsystem.authoring.testauth.domain.Assessment;
import org.opentestsystem.authoring.testauth.domain.BlueprintElement;
import org.opentestsystem.authoring.testauth.domain.BlueprintReference;
import org.opentestsystem.authoring.testauth.domain.BlueprintReferenceType;
import org.opentestsystem.authoring.testauth.domain.PerformanceLevel;
import org.opentestsystem.authoring.testauth.domain.Segment;
import org.opentestsystem.authoring.testauth.domain.search.PerformanceLevelSearchRequest;
import org.opentestsystem.authoring.testauth.persistence.PerformanceLevelRepository;
import org.opentestsystem.authoring.testauth.service.AffinityGroupService;
import org.opentestsystem.authoring.testauth.service.AssessmentService;
import org.opentestsystem.authoring.testauth.service.BlueprintElementService;
import org.opentestsystem.authoring.testauth.service.PerformanceLevelService;
import org.opentestsystem.authoring.testauth.service.SegmentService;
import org.opentestsystem.authoring.testauth.validation.PerformanceLevelValidator;
import org.opentestsystem.authoring.testauth.validation.ValidationHelper;
import org.opentestsystem.shared.exception.LocalizedException;
import org.opentestsystem.shared.exception.RestException;
import org.opentestsystem.shared.search.domain.SearchResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;

import com.google.common.collect.Maps;

@Service
public class PerformanceLevelServiceImpl extends AssessmentChildHelper implements PerformanceLevelService {

    private static final String BPREF_TYPE_KEY = "blueprintReferenceType";

    @Autowired
    private transient PerformanceLevelRepository performanceLevelRepository;

    @Autowired
    private transient AssessmentService assessmentService;

    @Autowired
    private transient SegmentService segmentService;

    @Autowired
    private transient AffinityGroupService affinityGroupService;

    @Autowired
    private transient BlueprintElementService blueprintElementService;

    @Autowired
    private transient PerformanceLevelValidator performanceLevelValidator;

    @Override
    public PerformanceLevel getPerformanceLevel(final String performanceLevelId) {
        return this.performanceLevelRepository.findOne(performanceLevelId);
    }

    @Override
    public List<PerformanceLevel> getPerformanceLevels() {
        return this.performanceLevelRepository.findAll();
    }

    @Override
    public List<PerformanceLevel> getPerformanceLevelsByAssessmentId(final String assessmentId) {
        return this.performanceLevelRepository.findAllByAssessmentId(assessmentId);
    }

    @Override
    public List<PerformanceLevel> getPerformanceLevelsByReferenceId(final String blueprintReferenceId) {
        return this.performanceLevelRepository.findAllByBlueprintReferenceId(blueprintReferenceId);
    }

    @Override
    public SearchResponse<PerformanceLevel> searchPerformanceLevels(final Map<String, String[]> parameterMap) {
        final Map<String, String[]> paramMap = reviseMapParams(parameterMap);
        final PerformanceLevelSearchRequest searchRequest = new PerformanceLevelSearchRequest(paramMap);
        if (searchRequest.isValid()) {
            final SearchResponse<PerformanceLevel> searchResponse = this.performanceLevelRepository
                    .search(searchRequest);
            if (searchResponse.getTotalCount() > 0) {
                for (final PerformanceLevel performanceLevel : searchResponse.getSearchResults()) {
                    populateReferenceData(performanceLevel);
                }
            }
            return searchResponse;
        }
        throw new RestException("performanceLevel.search.invalidSearchCriteria");
    }

    @Override
    public List<BlueprintReference> getBlueprintReferences(final Map<String, String[]> parameterMap) {
        final List<BlueprintReference> bpReferenceList = new ArrayList<BlueprintReference>();
        final Map<String, String[]> aMap = new HashMap<String, String[]>();
        aMap.put("pageSize", new String[] { "1000" });
        aMap.put("assessmentId", parameterMap.get("assessmentId"));
        final SearchResponse<PerformanceLevel> perfLevels = searchPerformanceLevels(aMap);
        for (final PerformanceLevel pl : perfLevels.getSearchResults()) {
            switch (pl.getBlueprintReferenceType()) {
            case AFFINITY_GROUP:
                final AffinityGroup affinityGroup = this.affinityGroupService
                        .getAffinityGroup(pl.getBlueprintReferenceId());
                bpReferenceList.add(new BlueprintReference(affinityGroup.getId(), affinityGroup.getGroupName(),
                        BlueprintReferenceType.AFFINITY_GROUP));
                break;
            case SEGMENT:
                final Segment segment = this.segmentService.getSegment(pl.getBlueprintReferenceId());
                bpReferenceList.add(new BlueprintReference(segment.getId(),
                        segment.getPosition() + " - " + segment.getLabel(), BlueprintReferenceType.SEGMENT));
                break;
            case STANDARD:
                final BlueprintElement blueprintElement = this.blueprintElementService
                        .getBlueprintElement(pl.getBlueprintReferenceId());
                bpReferenceList.add(new BlueprintReference(blueprintElement.getId(),
                        blueprintElement.getStandardKey(), BlueprintReferenceType.STANDARD));
                break;
            case TEST:
                final Assessment assessment = this.assessmentService.getAssessment(pl.getBlueprintReferenceId());
                bpReferenceList.add(new BlueprintReference(assessment.getId(), assessment.getName(),
                        BlueprintReferenceType.TEST));
                break;
            default:
                break;
            }
        }
        Collections.sort(bpReferenceList);
        return bpReferenceList;
    }

    // compensate for opting to use @JsonValue in enum for pretty dropdown choices
    private Map<String, String[]> reviseMapParams(final Map<String, String[]> parameterMap) {
        final Map<String, String[]> paramMap = Maps.newHashMap(parameterMap);
        if (paramMap.containsKey(BPREF_TYPE_KEY) && paramMap.get(BPREF_TYPE_KEY)[0] != null) {
            final BlueprintReferenceType blueprintReferenceType = BlueprintReferenceType
                    .fromTitle(paramMap.get(BPREF_TYPE_KEY)[0]);
            if (blueprintReferenceType != null) {
                paramMap.put(BPREF_TYPE_KEY, paramArray(blueprintReferenceType.name()));
            } else {
                paramMap.remove(BPREF_TYPE_KEY);
            }
        }
        return paramMap;
    }

    @Override
    public PerformanceLevel savePerformanceLevel(final String performanceLevelId,
            final PerformanceLevel performanceLevel) {
        if (performanceLevelId != null && (performanceLevel == null || StringUtils.isEmpty(performanceLevel.getId())
                || !performanceLevelId.equals(performanceLevel.getId()))) {
            throw new LocalizedException("performanceLevel.invalid.id");
        }
        checkForLockedAssessment(performanceLevel.getAssessmentId());
        validatePerformanceLevel(performanceLevel);
        PerformanceLevel savedPerformanceLevel = null;
        try {
            savedPerformanceLevel = this.performanceLevelRepository.save(performanceLevel);
        } catch (final DuplicateKeyException dke) {
            // this is done only to get blueprint reference name from id
            populateReferenceData(performanceLevel);
            throw new LocalizedException("performanceLevel.already.exists",
                    paramArray(performanceLevel.getBlueprintReferenceName()), dke);
        }
        return savedPerformanceLevel;
    }

    @Override
    public void removePerformanceLevel(final String performanceLevelId) {
        final PerformanceLevel performanceLevelToDelete = this.performanceLevelRepository
                .findOne(performanceLevelId);
        if (performanceLevelToDelete == null) {
            throw new LocalizedException("performanceLevel.invalid.id", paramArray(performanceLevelId));
        }

        checkForLockedAssessment(performanceLevelToDelete.getAssessmentId());
        this.performanceLevelRepository.delete(performanceLevelId);
    }

    @Override
    public void removeByAssessmentId(final String assessmentId) {
        checkForLockedAssessment(assessmentId);
        this.performanceLevelRepository.delete(getPerformanceLevelsByAssessmentId(assessmentId));
    }

    @Override
    public void removeByReferenceId(final String blueprintReferenceId) {
        this.performanceLevelRepository.delete(getPerformanceLevelsByReferenceId(blueprintReferenceId));
    }

    private void validatePerformanceLevel(final PerformanceLevel performanceLevel) {
        final BindingResult bindingResult = new BeanPropertyBindingResult(performanceLevel, "performanceLevel");
        this.performanceLevelValidator.validate(performanceLevel, bindingResult);

        if (!bindingResult.hasErrors()) {
            switch (performanceLevel.getBlueprintReferenceType()) {
            case TEST:
                if (!performanceLevel.getBlueprintReferenceId().equals(performanceLevel.getAssessmentId())) {
                    formatReferenceIdMessage(bindingResult, performanceLevel);
                }
                break;
            case SEGMENT:
                final Segment segment = this.segmentService.getSegment(performanceLevel.getBlueprintReferenceId());
                if (segment == null) {
                    formatReferenceIdMessage(bindingResult, performanceLevel);
                }
                break;
            case AFFINITY_GROUP:
                final AffinityGroup affinityGroup = this.affinityGroupService
                        .getAffinityGroup(performanceLevel.getBlueprintReferenceId());
                if (affinityGroup == null) {
                    formatReferenceIdMessage(bindingResult, performanceLevel);
                }
                break;
            case STANDARD:
                final BlueprintElement blueprintElement = this.blueprintElementService
                        .getBlueprintElement(performanceLevel.getBlueprintReferenceId());
                if (blueprintElement == null) {
                    formatReferenceIdMessage(bindingResult, performanceLevel);
                }
                break;
            default:
                // do nothing, cannot enter here if prior validation passed
                break;
            }
        }

        if (bindingResult.hasErrors()) {
            throw ValidationHelper.convertErrorsToConstraintException(performanceLevel, bindingResult);
        }
    }

    private void formatReferenceIdMessage(final BindingResult bindingResult,
            final PerformanceLevel performanceLevel) {
        bindingResult.addError(new FieldError("performanceLevel", // objectName
                "blueprintReferenceId", // field
                null, // rejectedValue
                false, // bindingFailure
                paramArray("blueprintReferenceId.notfound"), // messageCode
                paramArray(// arguments
                        performanceLevel.getBlueprintReferenceType().name(),
                        performanceLevel.getBlueprintReferenceId(),
                        performanceLevel.getBlueprintReferenceType().getTitle(),
                        performanceLevel.getAssessmentId()),
                "blueprintReferenceId.notfound")); // defaultMessage

    }

    private void populateReferenceData(final PerformanceLevel performanceLevel) {
        if (performanceLevel != null && performanceLevel.getBlueprintReferenceType() != null) {
            switch (performanceLevel.getBlueprintReferenceType()) {
            case TEST:
                final Assessment assessment = this.assessmentService
                        .getAssessment(performanceLevel.getBlueprintReferenceId());
                performanceLevel.setBlueprintReferenceName(assessment == null ? null : assessment.getName());
                break;
            case SEGMENT:
                final Segment segment = this.segmentService.getSegment(performanceLevel.getBlueprintReferenceId());
                performanceLevel.setBlueprintReferenceName(
                        segment == null ? null : segment.getPosition() + " - " + segment.getLabel());
                break;
            case AFFINITY_GROUP:
                final AffinityGroup affinityGroup = this.affinityGroupService
                        .getAffinityGroup(performanceLevel.getBlueprintReferenceId());
                performanceLevel
                        .setBlueprintReferenceName(affinityGroup == null ? null : affinityGroup.getGroupName());
                break;
            case STANDARD:
                final BlueprintElement blueprintElement = this.blueprintElementService
                        .getBlueprintElement(performanceLevel.getBlueprintReferenceId());
                performanceLevel.setBlueprintReferenceName(
                        blueprintElement == null ? null : blueprintElement.getStandardKey());
                break;
            default:
                // do nothing, cannot enter here if prior validation passed
                break;
            }
        }
    }

    @Override
    public List<PerformanceLevel> savePerformanceLevelList(final List<PerformanceLevel> performanceLevelList) {
        return this.performanceLevelRepository.save(performanceLevelList);
    }
}