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

Java tutorial

Introduction

Here is the source code for org.opentestsystem.authoring.testauth.service.impl.FormPartitionServiceImpl.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 java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.opentestsystem.authoring.testauth.domain.Form;
import org.opentestsystem.authoring.testauth.domain.FormPartition;
import org.opentestsystem.authoring.testauth.domain.Item;
import org.opentestsystem.authoring.testauth.domain.ItemGroup;
import org.opentestsystem.authoring.testauth.domain.ItemLocation;
import org.opentestsystem.authoring.testauth.domain.ItemSelectionAlgorithmType;
import org.opentestsystem.authoring.testauth.domain.Segment;
import org.opentestsystem.authoring.testauth.domain.search.FormPartitionSearchRequest;
import org.opentestsystem.authoring.testauth.persistence.FormPartitionRepository;
import org.opentestsystem.authoring.testauth.persistence.FormRepository;
import org.opentestsystem.authoring.testauth.service.FormPartitionService;
import org.opentestsystem.authoring.testauth.service.FormService;
import org.opentestsystem.authoring.testauth.service.ItemGroupService;
import org.opentestsystem.authoring.testauth.service.ItemService;
import org.opentestsystem.authoring.testauth.service.SegmentService;
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.ImmutableMap;
import com.google.common.collect.Lists;

@Service
public class FormPartitionServiceImpl extends AssessmentChildHelper implements FormPartitionService {

    @Autowired
    private transient FormPartitionRepository formPartitionRepository;

    @Autowired
    private transient FormRepository formRepository;

    @Autowired
    private transient SegmentService segmentService;

    @Autowired
    private transient FormService formService;

    @Autowired
    private transient ItemService itemService;

    @Autowired
    private transient ItemGroupService itemGroupService;

    @Override
    public FormPartition saveFormPartition(final String formPartitionId, final FormPartition formPartition) {
        // updating correct formPartition?
        if (formPartitionId != null && (formPartition == null || StringUtils.isEmpty(formPartition.getId())
                || !formPartitionId.equals(formPartition.getId()))) {
            throw new LocalizedException("formPartition.invalid.id");
        }

        validateFormPartition(formPartition);

        checkForLockedAssessment(formPartition.getAssessmentId());

        // save formPartition
        if (formPartitionId != null) {
            return updateExistingFormPartition(formPartition);
        }
        return saveNewFormPartition(formPartition);
    }

    private FormPartition saveNewFormPartition(final FormPartition formPartition) {
        FormPartition savedFormPartition = null;
        try {
            savedFormPartition = this.formPartitionRepository.save(formPartition);
        } catch (final DuplicateKeyException dke) {
            if (StringUtils.contains(dke.getMessage(), FormPartition.SEGMENT_INDEX_NAME)) {
                throw new LocalizedException("formPartition.already.exists.segment",
                        new String[] { formPartition.getFormId(), formPartition.getSegmentId() }, dke);
            } else {
                throw new LocalizedException("formPartition.already.exists.name",
                        new String[] { formPartition.getFormId(), formPartition.getName() }, dke);
            }
        }
        return savedFormPartition;
    }

    // find the existing partition and if the segment value has changed, attempt to find another partition using that segment, swap out the segment values, and save both
    // if the existing partition's segment value has not been changed, or no other partition using that segment can be found, just save the existing partition
    private FormPartition updateExistingFormPartition(final FormPartition formPartition) {
        final List<FormPartition> formPartitionsToSave = Lists.newArrayList(formPartition);
        final FormPartition currentValuePartition = getFormPartition(formPartition.getId());
        if (!currentValuePartition.getSegmentId().equals(formPartition.getSegmentId())) {
            FormPartition rivalFormPartition = null;
            final SearchResponse<FormPartition> searchResponse = searchFormPartitions(
                    ImmutableMap.of("formId", new String[] { formPartition.getFormId() }, "segmentId",
                            new String[] { formPartition.getSegmentId() }));
            if (searchResponse.getReturnCount() > 0) {
                rivalFormPartition = searchResponse.getSearchResults().get(0);
                rivalFormPartition.setSegmentId(currentValuePartition.getSegmentId());
                formPartitionsToSave.add(rivalFormPartition);
                removeFormPartition(rivalFormPartition.getId());
            }
        }
        List<FormPartition> savedFormPartition = null;
        try {
            savedFormPartition = this.formPartitionRepository.save(formPartitionsToSave);
        } catch (final DuplicateKeyException dke) {
            if (StringUtils.contains(dke.getMessage(), FormPartition.SEGMENT_INDEX_NAME)) {
                throw new LocalizedException("formPartition.already.exists.segment",
                        new String[] { formPartition.getFormId(), formPartition.getSegmentId() }, dke);
            } else {
                throw new LocalizedException("formPartition.already.exists.name",
                        new String[] { formPartition.getFormId(), formPartition.getName() }, dke);
            }
        }
        return savedFormPartition.get(0);
    }

    private void validateFormPartition(final FormPartition formPartition) {
        final BindingResult bindingResult = new BeanPropertyBindingResult(formPartition, "formPartition");

        if (formPartition.getFormId() != null) {
            final Form form = this.formRepository.findOne(formPartition.getFormId());
            if (form == null) {
                final String messageCode = "formPartition.formId.notfound";
                bindingResult.addError(new FieldError("formPartition", "formId", null, false,
                        new String[] { messageCode }, new String[] { formPartition.getSegmentId() }, messageCode));
            }
        } else {
            final String messageCode = "formPartition.formId.required";
            bindingResult.addError(new FieldError("formPartition", "formId", null, false,
                    new String[] { messageCode }, new String[] { formPartition.getSegmentId() }, messageCode));
        }

        if (formPartition.getSegmentId() == null) {
            final String messageCode = "formPartition.segmentId.required";
            bindingResult.addError(new FieldError("formPartition", "segmentId", null, false,
                    new String[] { messageCode }, new String[] { formPartition.getSegmentId() }, messageCode));
        } else {
            final Segment segment = this.segmentService.getSegment(formPartition.getSegmentId());
            if (segment == null) {
                final String messageCode = "formPartition.segmentId.notfound";
                bindingResult.addError(new FieldError("formPartition", "segmentId", null, false,
                        new String[] { messageCode }, new String[] { formPartition.getSegmentId() }, messageCode));
            } else {
                if (segment.getItemSelectionAlgorithm()
                        .getItemSelectionAlgorithmType() != ItemSelectionAlgorithmType.FIXEDFORM) {
                    final String messageCode = "formPartition.segmentId.notfixed";
                    bindingResult.addError(
                            new FieldError("formPartition", "segmentId", null, false, new String[] { messageCode },
                                    new String[] { formPartition.getSegmentId() }, messageCode));
                }
            }
        }

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

    @Override
    public void removeFormPartition(final String formPartitionId) {
        final FormPartition formPartition = this.formPartitionRepository.findOne(formPartitionId);
        if (formPartitionId == null || formPartition == null) {
            throw new LocalizedException("formPartition.invalid.id");
        }
        checkForLockedAssessment(formPartition.getAssessmentId());
        // remove items and itemgroups belonging to this form partition
        removeItemsByPartition(formPartitionId);
        removeItemGroupsByPartition(formPartitionId);
        this.formPartitionRepository.delete(formPartitionId);
    }

    @Override
    public void removeFormPartitionsByFormId(final String formId) {
        final List<FormPartition> formPartitions = this.formPartitionRepository.findAllByFormId(formId);
        for (final FormPartition formPartition : formPartitions) {
            removeFormPartition(formPartition.getId());
        }
    }

    @Override
    public void removeFormPartitionsByAssessmentId(final String assessmentId) {
        this.formPartitionRepository.delete(this.formPartitionRepository.findAllByAssessmentId(assessmentId));
    }

    @Override
    public FormPartition getFormPartition(final String formPartitionId) {
        return this.formPartitionRepository.findOne(formPartitionId);
    }

    @Override
    public List<FormPartition> getFormPartitionsByFormId(final String formId) {
        return this.formPartitionRepository.findAllByFormId(formId);
    }

    @Override
    public List<FormPartition> getFormPartitionsBySegmentId(final String segmentId) {
        return this.formPartitionRepository.findAllBySegmentId(segmentId);
    }

    @Override
    public SearchResponse<FormPartition> searchFormPartitions(final Map<String, String[]> requestMap) {
        final FormPartitionSearchRequest searchRequest = new FormPartitionSearchRequest(requestMap);
        if (searchRequest.isValid()) {
            return this.formPartitionRepository.search(searchRequest);
        } else {
            throw new RestException("formPartition.search.invalidSearchCriteria");
        }
    }

    @Override
    public void populateReferenceData(final List<FormPartition> formPartitions) {
        for (final FormPartition formPartition : formPartitions) {
            populateReferenceData(formPartition);
        }
    }

    @Override
    public void populateReferenceData(final FormPartition formPartition) {
        if (formPartition != null && formPartition.getSegmentId() != null) {
            formPartition.setSegment(this.segmentService.getSegment(formPartition.getSegmentId()));
        }
        if (formPartition != null && formPartition.getFormId() != null) {
            formPartition.setForm(this.formService.getForm(formPartition.getFormId()));
        }
    }

    private void removeItemsByPartition(final String partitionId) {
        final List<Item> items = this.itemService.getItemsByFormPartitionId(partitionId);
        for (final Item item : items) {
            ItemLocation removeMe = null;
            for (final ItemLocation location : item.getItemLocation()) {
                if (partitionId.equals(location.getFormPartitionId())) {
                    removeMe = location;
                }
            }
            if (removeMe != null) {
                item.getItemLocation().remove(removeMe);
                if (item.getItemLocation().size() == 0) {
                    this.itemService.removeItem(item.getId());
                } else {
                    this.itemService.saveItem(item);
                }
            }
        }
    }

    private void removeItemGroupsByPartition(final String partitionId) {
        final List<ItemGroup> itemGroups = this.itemGroupService.getItemGroupsFormPartition(partitionId);
        for (final ItemGroup itemGroup : itemGroups) {
            this.itemGroupService.removeItemGroup(itemGroup.getId());
        }
    }

    @Override
    public List<FormPartition> getFormPartitionsByAssessmentId(final String assessmentId) {
        return this.formPartitionRepository.findAllByAssessmentId(assessmentId);
    }

    @Override
    public List<FormPartition> saveFormPartitionList(final List<FormPartition> formPartitionList) {
        return this.formPartitionRepository.save(formPartitionList);
    }
}