org.opentestsystem.ap.ivs.service.ValidationUtility.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.ap.ivs.service.ValidationUtility.java

Source

/*
 * Copyright 2017 Regents of the University of California. Licensed under the Educational Community License, Version
 * 2.0 (the "license"); you may not use this file except in compliance with the License. You may obtain a copy of the
 * license at
 *
 * https://opensource.org/licenses/ECL-2.0
 *
 * Unless required under applicable law or agreed to in writing, software distributed under the License is distributed
 * in an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for
 * specific language governing permissions and limitations under the license.
 */
package org.opentestsystem.ap.ivs.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.opentestsystem.ap.common.config.ItemBankProperties;
import org.opentestsystem.ap.common.exception.SystemException;
import org.opentestsystem.ap.common.model.Item;
import org.opentestsystem.ap.common.model.ItemConstants;
import org.opentestsystem.ap.common.model.ItemContext;
import org.opentestsystem.ap.common.repository.RepositoryUtil;
import org.opentestsystem.ap.ivs.config.IvsProperties;
import org.opentestsystem.ap.ivs.models.ErrorReport;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;

import static org.opentestsystem.ap.common.model.ItemConstants.ItemType.TYPE_STIM;
import static org.opentestsystem.ap.common.model.ItemConstants.ItemType.TYPE_TUT;

@Slf4j
@Component
public class ValidationUtility {

    private static final String ITEMS_DIR = "Items";

    private static final String STIMULI_DIR = "Stimuli";

    private static final String manifestFile = "imsmanifest.xml";

    private static final String validationRootChildName = "validation";

    private final ItemBankProperties itemBankProperties;

    private final IvsProperties ivsProperties;

    public ValidationUtility(final ItemBankProperties itemBankProperties, final IvsProperties ivsProperties) {
        this.itemBankProperties = itemBankProperties;
        this.ivsProperties = ivsProperties;
    }

    public Path initializeValidationStructure(final Path destinationRootPath) {
        final Path validationRootChild = destinationRootPath.resolve(validationRootChildName);
        try {
            FileUtils.write(validationRootChild.resolve(manifestFile).toFile(), "<manifest/>", "UTF-8");
        } catch (IOException e) {
            throw new SystemException(e);
        }
        return validationRootChild;
    }

    public Path mapItemToValidationStructure(final ItemContext itemContext, final Path validationRootChild) {
        return Objects.nonNull(itemContext)
                ? mapToValidationStructure(itemContext, validationRootChild.resolve(ITEMS_DIR),
                        mapItemFolderName(itemContext.getItemId()))
                : null;
    }

    public Path mapStimulusToValidationStructure(ItemContext stimulusContext, Path validationRootChild) {
        return Objects.nonNull(stimulusContext)
                ? mapToValidationStructure(stimulusContext, validationRootChild.resolve(STIMULI_DIR),
                        mapStimFolderName(stimulusContext.getItemId()))
                : null;
    }

    /**
     * Map an item's local glossary to the validation structure.  The glossary lives in the 'Items' folder.  It sits
     * sibling to other glossaries and items.  Stimulus live in the 'Stimuli' folder.  The item context passed in can be
     * either an item or a stimulus.  The glossary for it is what gets mapped to the validation structure.
     *
     * @param itemContext  An item or stimulus context.
     * @param validationRootChild The root folder of the validation structure.
     * @return
     */
    public Path mapGlossaryToValidationStructure(final ItemContext itemContext, final Path validationRootChild) {
        Path glossaryValidationRepoPath = null;

        if (itemContext != null) {
            final Path itemGlossaryFilePath = itemContext.getLocalGlossaryFilePath();

            if (itemGlossaryFilePath.toFile().exists()) {

                final String glossaryId = RepositoryUtil.getGlossaryId(itemContext.getItemId());

                final String baseName = mapItemFolderName(glossaryId);

                final Path itemsPath = validationRootChild.resolve(ITEMS_DIR);
                glossaryValidationRepoPath = itemsPath.resolve(baseName);

                final Path glossaryValidationFilePath = glossaryValidationRepoPath.resolve(mapFileName(glossaryId));
                final Path glossaryValidationAdjustedFilePath = glossaryValidationRepoPath
                        .resolve(mapFileName(baseName));

                try {
                    // copy the item's glossary folder to the local glossary repository folder
                    FileUtils.copyDirectory(itemContext.getLocalGlossaryFolderPath().toFile(),
                            glossaryValidationRepoPath.toFile());

                    // confirm the glossary's SAAIF file exists
                    if (glossaryValidationFilePath.toFile().exists()) {
                        glossaryValidationFilePath.toFile().renameTo(glossaryValidationAdjustedFilePath.toFile());
                    }
                } catch (IOException e) {
                    throw new SystemException(
                            "Error mapping glossary " + glossaryId + " to the validation structure", e);
                }
            }
        }

        return glossaryValidationRepoPath;
    }

    public List<ErrorReport> parseErrorReport(final Path reportFolder) {
        final Path errorFilePath = reportFolder.resolve(this.ivsProperties.getErrorReportFileName());
        try {
            final MappingIterator<ErrorReport> results = new CsvMapper().readerWithTypedSchemaFor(ErrorReport.class)
                    .readValues(errorFilePath.toFile());
            return results.readAll();
        } catch (IOException e) {
            throw new SystemException("Error converting item history list to CSV", e);
        }
    }

    public boolean isStim(final Item item) {
        return item != null ? TYPE_STIM.equalsIgnoreCase(item.getType()) : false;
    }

    public boolean isTutorial(final Item item) {
        return item != null ? TYPE_TUT.equalsIgnoreCase(item.getType()) : false;
    }

    // ------------------------------------------------------------------------
    // Helper Methods
    // ------------------------------------------------------------------------

    private Path mapToValidationStructure(final ItemContext itemContext, final Path itemValidationParent,
            final String baseFolderName) {
        final String itemId = itemContext.getItemId();

        final Path itemValidationRepoPath = itemValidationParent.resolve(baseFolderName);

        final Path itemValidationFilePath = itemValidationRepoPath.resolve(mapFileName(itemId));
        final Path itemValidationAdjustedFilePath = itemValidationRepoPath.resolve(mapFileName(baseFolderName));

        try {
            FileUtils.copyDirectory(itemContext.getLocalRepositoryPath().toFile(), itemValidationRepoPath.toFile());
            itemValidationFilePath.toFile().renameTo(itemValidationAdjustedFilePath.toFile());
        } catch (IOException e) {
            throw new SystemException("Error copying item " + itemId + " for validation", e);
        }
        return itemValidationRepoPath;
    }

    private String mapItemFolderName(final String itemId) {
        return String.format("item-%s-%s", this.itemBankProperties.getBankKey(), itemId);
    }

    private String mapStimFolderName(final String itemId) {
        return String.format("stim-%s-%s", this.itemBankProperties.getBankKey(), itemId);
    }

    private String mapFileName(final String baseName) {
        return String.format("%s.xml", baseName);
    }
}