com.epam.catgenome.dao.BiologicalDataItemDao.java Source code

Java tutorial

Introduction

Here is the source code for com.epam.catgenome.dao.BiologicalDataItemDao.java

Source

/*
 * MIT License
 *
 * Copyright (c) 2016 EPAM Systems
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.epam.catgenome.dao;

import static com.epam.catgenome.dao.BiologicalDataItemDao.BiologicalDataItemParameters.getRowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import com.epam.catgenome.component.MessageHelper;
import com.epam.catgenome.constant.MessagesConstants;
import com.epam.catgenome.entity.BiologicalDataItem;
import com.epam.catgenome.entity.BiologicalDataItemFormat;
import com.epam.catgenome.entity.BiologicalDataItemResourceType;
import com.epam.catgenome.entity.FeatureFile;
import com.epam.catgenome.entity.bam.BamFile;
import com.epam.catgenome.entity.bed.BedFile;
import com.epam.catgenome.entity.externaldb.ExternalDB;
import com.epam.catgenome.entity.externaldb.ExternalDBType;
import com.epam.catgenome.entity.gene.GeneFile;
import com.epam.catgenome.entity.maf.MafFile;
import com.epam.catgenome.entity.reference.Reference;
import com.epam.catgenome.entity.seg.SegFile;
import com.epam.catgenome.entity.vcf.VcfFile;
import com.epam.catgenome.entity.wig.WigFile;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * Source:      BiologicalDataItemDao
 * Created:     17.12.15, 13:12
 * Project:     CATGenome Browser
 * Make:        IntelliJ IDEA 14.1.4, JDK 1.8
 *
 * <p>
 * A DAO class, managing BiologicalDataItem entities and containing common logic for it's ancestors retrieval
 * </p>
 */
public class BiologicalDataItemDao extends NamedParameterJdbcDaoSupport {
    private String biologicalDataItemSequenceName;
    private String insertBiologicalDataItemQuery;
    private String loadBiologicalDataItemsByIdsQuery;
    private String deleteBiologicalDataItemQuery;
    private String loadBiologicalDataItemsByNameStrictQuery;
    private String loadBiologicalDataItemsByNamesStrictQuery;
    private String loadBiologicalDataItemsByNameQuery;

    @Autowired
    private DaoHelper daoHelper;

    /**
     * Persists a BiologicalDataItem instance into the database
     * @param item BiologicalDataItem to persist
     */
    @Transactional(propagation = Propagation.MANDATORY)
    public void createBiologicalDataItem(BiologicalDataItem item) {
        if (!item.getFormat().isIndex() || (item.getFormat().isIndex() && !StringUtils.isEmpty(item.getName()))) {

            Assert.isTrue(!StringUtils.isEmpty(item.getName()), "File name is required for registration.");
            List<BiologicalDataItem> items = loadFilesByNameStrict(item.getName());
            Assert.isTrue(items.isEmpty(),
                    MessageHelper.getMessage(MessagesConstants.ERROR_FILE_NAME_EXISTS, item.getName()));
            item.setId(daoHelper.createId(biologicalDataItemSequenceName));
        } else {
            item.setId(daoHelper.createId(biologicalDataItemSequenceName));
            item.setName("INDEX " + item.getId());
        }

        final MapSqlParameterSource params = new MapSqlParameterSource();

        params.addValue(BiologicalDataItemParameters.BIO_DATA_ITEM_ID.name(), item.getId());
        params.addValue(BiologicalDataItemParameters.NAME.name(), item.getName());
        params.addValue(BiologicalDataItemParameters.TYPE.name(), item.getType().getId());
        params.addValue(BiologicalDataItemParameters.PATH.name(), item.getPath());
        params.addValue(BiologicalDataItemParameters.FORMAT.name(), item.getFormat().getId());
        params.addValue(BiologicalDataItemParameters.CREATED_DATE.name(), item.getCreatedDate());
        params.addValue(BiologicalDataItemParameters.CREATED_BY.name(), item.getCreatedBy());
        params.addValue(BiologicalDataItemParameters.BUCKET_ID.name(), item.getBucketId());
        params.addValue(BiologicalDataItemParameters.PRETTY_NAME.name(), item.getPrettyName());

        getNamedParameterJdbcTemplate().update(insertBiologicalDataItemQuery, params);
    }

    /**
     * Loads a List of BiologicalDataItem from the database by their IDs
     * @param ids List of IDs of BiologicalDataItem instances
     * @return List of BiologicalDataItem, matching specified IDs
     */
    @Transactional(propagation = Propagation.MANDATORY)
    public List<BiologicalDataItem> loadBiologicalDataItemsByIds(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return Collections.emptyList();
        }

        Long listId = daoHelper.createTempLongList(ids);

        final MapSqlParameterSource params = new MapSqlParameterSource();
        params.addValue(BiologicalDataItemParameters.BIO_DATA_ITEM_ID.name(), listId);

        List<BiologicalDataItem> items = getNamedParameterJdbcTemplate().query(loadBiologicalDataItemsByIdsQuery,
                params, getRowMapper());

        daoHelper.clearTempList(listId);

        return items;
    }

    @Transactional(propagation = Propagation.MANDATORY)
    public Long createBioItemId() {
        return daoHelper.createId(biologicalDataItemSequenceName);
    }

    /**
     * Deletes a BiologicalDataItem instance from the database by it's ID
     * @param bioDataItemId ID of BiologicalDataItem instance to delete
     */
    @Transactional(propagation = Propagation.MANDATORY)
    public void deleteBiologicalDataItem(final long bioDataItemId) {
        getJdbcTemplate().update(deleteBiologicalDataItemQuery, bioDataItemId);
    }

    /**
     * An enum of BiologicalDataItem's ancestor's fields
     */
    /**
     * Finds files with a specified file name, checks name for strict, case sensitive equality
     * @param name search query
     * @return {@code List} of files with a matching name
     */
    @Transactional(propagation = Propagation.MANDATORY)
    public List<BiologicalDataItem> loadFilesByNameStrict(final String name) {
        final MapSqlParameterSource params = new MapSqlParameterSource();
        params.addValue(BiologicalDataItemParameters.NAME.name(), name);
        return getNamedParameterJdbcTemplate().query(loadBiologicalDataItemsByNameStrictQuery, params,
                getRowMapper());
    }

    @Transactional(propagation = Propagation.MANDATORY)
    public List<BiologicalDataItem> loadFilesByNamesStrict(final List<String> names) {
        if (CollectionUtils.isEmpty(names)) {
            return Collections.emptyList();
        }

        long listId = daoHelper.createTempStringList(names);

        List<BiologicalDataItem> items = getJdbcTemplate().query(loadBiologicalDataItemsByNamesStrictQuery,
                getRowMapper(), listId);

        daoHelper.clearTempStringList(listId);
        return items;
    }

    /**
     * Finds files with names matching a specified file name, performs substring, case insensitive search
     * @param name search query
     * @return {@code List} of files with a matching name
     */
    @Transactional(propagation = Propagation.MANDATORY)
    public List<BiologicalDataItem> loadFilesByName(final String name) {
        final MapSqlParameterSource params = new MapSqlParameterSource();
        params.addValue(BiologicalDataItemParameters.NAME.name(), "%" + name.toLowerCase() + "%");
        return getNamedParameterJdbcTemplate().query(loadBiologicalDataItemsByNameQuery, params, getRowMapper());
    }

    public enum BiologicalDataItemParameters {
        BIO_DATA_ITEM_ID, NAME, TYPE, PATH, FORMAT, CREATED_BY, CREATED_DATE, BUCKET_ID, PRETTY_NAME,

        VCF_ID, VCF_REFERENCE_GENOME_ID, VCF_COMPRESSED,

        GENE_ITEM_ID, GENE_REFERENCE_GENOME_ID, GENE_COMPRESSED, GENE_EXTERNAL_DB_TYPE_ID, GENE_EXTERNAL_DB_ID, GENE_EXTERNAL_DB_ORGANISM,

        REFERENCE_GENOME_ID, REFERENCE_GENOME_SIZE, REFERENCE_GENE_ITEM_ID, REFERENCE_GENE_ITEM_NAME, REFERENCE_GENE_BIO_DATA_ITEM_ID, REFERENCE_GENE_TYPE, REFERENCE_GENE_PATH, REFERENCE_GENE_FORMAT, REFERENCE_GENE_CREATED_BY, REFERENCE_GENE_CREATED_DATE, REFERENCE_GENE_REFERENCE_GENOME_ID, REFERENCE_GENE_COMPRESSED,

        BAM_ID, BAM_REFERENCE_GENOME_ID,

        BED_GRAPH_ID, BED_GRAPH_REFERENCE_GENOME_ID,

        BED_ID, BED_REFERENCE_GENOME_ID, BED_COMPRESSED,

        SEG_ID, SEG_REFERENCE_GENOME_ID, SEG_COMPRESSED,

        MAF_ID, MAF_REFERENCE_GENOME_ID, MAF_COMPRESSED, MAF_REAL_PATH,

        VG_ID, VG_REFERENCE_GENOME_ID, VG_REAL_PATH,

        INDEX_ID, INDEX_NAME, INDEX_TYPE, INDEX_PATH, INDEX_FORMAT, INDEX_CREATED_BY, INDEX_BUCKET_ID, INDEX_CREATED_DATE;

        /**
         * Returns a universal row mapper for all BiologicalDataItem's ancestor entities
         * @return a universal row mapper
         */
        public static RowMapper<BiologicalDataItem> getRowMapper() {
            return (rs, rowNum) -> mapRow(rs, true);
        }

        public static RowMapper<BiologicalDataItem> getRowMapper(final boolean loadIndex) {
            return (rs, rowNum) -> mapRow(rs, loadIndex);
        }

        private static BiologicalDataItem mapRow(ResultSet rs, boolean loadIndex) throws SQLException {
            long longVal = rs.getLong(FORMAT.name());
            BiologicalDataItemFormat format = rs.wasNull() ? null : BiologicalDataItemFormat.getById(longVal);

            BiologicalDataItem index = null;
            if (loadIndex) {
                long indexId = rs.getLong(INDEX_ID.name());
                if (!rs.wasNull()) {
                    index = new BiologicalDataItem();
                    index.setId(indexId);
                    index.setName(rs.getString(INDEX_NAME.name()));
                    index.setType(BiologicalDataItemResourceType.getById(rs.getLong(INDEX_TYPE.name())));
                    index.setPath(rs.getString(INDEX_PATH.name()));
                    index.setFormat(BiologicalDataItemFormat.getById(rs.getLong(INDEX_FORMAT.name())));
                    index.setCreatedBy(rs.getLong(CREATED_BY.name()));
                    index.setCreatedDate(new Date(rs.getTimestamp(INDEX_CREATED_DATE.name()).getTime()));
                }
            }

            BiologicalDataItem dataItem;
            if (format != null) {
                dataItem = mapSpecialFields(rs, format, index);
            } else {
                dataItem = mapBioDataItem(rs);
            }

            dataItem.setName(rs.getString(NAME.name()));

            longVal = rs.getLong(TYPE.name());
            dataItem.setType(rs.wasNull() ? null : BiologicalDataItemResourceType.getById(longVal));

            dataItem.setPath(rs.getString(PATH.name()));
            dataItem.setFormat(format);
            dataItem.setCreatedBy(rs.getLong(CREATED_BY.name()));
            dataItem.setCreatedDate(new Date(rs.getTimestamp(CREATED_DATE.name()).getTime()));
            dataItem.setPrettyName(rs.getString(PRETTY_NAME.name()));

            return dataItem;
        }

        @NotNull
        private static BiologicalDataItem mapSpecialFields(ResultSet rs, BiologicalDataItemFormat format,
                BiologicalDataItem index) throws SQLException {
            BiologicalDataItem dataItem;
            switch (format) {
            case REFERENCE:
                dataItem = mapReference(rs);
                break;
            case VCF:
                dataItem = mapVcfFile(rs, index);
                break;
            case GENE:
                dataItem = mapGeneFile(rs, index);
                break;
            case BAM:
                dataItem = mapBamFile(rs, index);
                break;
            case WIG:
                dataItem = mapWigFile(rs);
                break;
            case BED:
                dataItem = mapBedFile(rs, index);
                break;
            case SEG:
                dataItem = mapSegFile(rs, index);
                break;
            case MAF:
                dataItem = mapMafFile(rs, index);
                break;
            default:
                dataItem = mapBioDataItem(rs);
            }
            return dataItem;
        }

        private static BiologicalDataItem mapBioDataItem(ResultSet rs) throws SQLException {
            BiologicalDataItem dataItem = new BiologicalDataItem();
            dataItem.setId(rs.getLong(BIO_DATA_ITEM_ID.name()));
            return dataItem;
        }

        @NotNull
        private static BiologicalDataItem mapMafFile(ResultSet rs, BiologicalDataItem index) throws SQLException {
            MafFile mafFile = new MafFile();
            mafFile.setId(rs.getLong(MAF_ID.name()));
            mafFile.setBioDataItemId(rs.getLong(BIO_DATA_ITEM_ID.name()));
            mafFile.setCompressed(rs.getBoolean(MAF_COMPRESSED.name()));
            mafFile.setReferenceId(rs.getLong(MAF_REFERENCE_GENOME_ID.name()));
            mafFile.setRealPath(rs.getString(MAF_REAL_PATH.name()));
            mafFile.setIndex(index);

            return mafFile;
        }

        @NotNull
        private static BiologicalDataItem mapSegFile(ResultSet rs, BiologicalDataItem index) throws SQLException {
            SegFile segFile = new SegFile();
            segFile.setId(rs.getLong(SEG_ID.name()));
            segFile.setBioDataItemId(rs.getLong(BIO_DATA_ITEM_ID.name()));
            segFile.setCompressed(rs.getBoolean(SEG_COMPRESSED.name()));
            segFile.setReferenceId(rs.getLong(SEG_REFERENCE_GENOME_ID.name()));
            segFile.setIndex(index);

            return segFile;
        }

        @NotNull
        private static BiologicalDataItem mapBedFile(ResultSet rs, BiologicalDataItem index) throws SQLException {
            BedFile bedFile = new BedFile();
            bedFile.setId(rs.getLong(BED_ID.name()));
            bedFile.setBioDataItemId(rs.getLong(BIO_DATA_ITEM_ID.name()));
            bedFile.setCompressed(rs.getBoolean(BED_COMPRESSED.name()));
            bedFile.setReferenceId(rs.getLong(BED_REFERENCE_GENOME_ID.name()));
            bedFile.setIndex(index);

            return bedFile;
        }

        @NotNull
        private static BiologicalDataItem mapWigFile(ResultSet rs) throws SQLException {
            WigFile wigFile = new WigFile();
            wigFile.setId(rs.getLong(BED_GRAPH_ID.name()));
            wigFile.setBioDataItemId(rs.getLong(BIO_DATA_ITEM_ID.name()));
            wigFile.setReferenceId(rs.getLong(BED_GRAPH_REFERENCE_GENOME_ID.name()));

            return wigFile;
        }

        @NotNull
        private static BiologicalDataItem mapBamFile(ResultSet rs, BiologicalDataItem index) throws SQLException {
            BamFile bamFile = new BamFile();
            bamFile.setId(rs.getLong(BAM_ID.name()));
            bamFile.setBioDataItemId(rs.getLong(BIO_DATA_ITEM_ID.name()));
            bamFile.setReferenceId(rs.getLong(BAM_REFERENCE_GENOME_ID.name()));
            bamFile.setIndex(index);

            return bamFile;
        }

        @NotNull
        private static BiologicalDataItem mapGeneFile(ResultSet rs, BiologicalDataItem index) throws SQLException {
            GeneFile geneFile = new GeneFile();
            geneFile.setId(rs.getLong(GENE_ITEM_ID.name()));
            geneFile.setBioDataItemId(rs.getLong(BIO_DATA_ITEM_ID.name()));
            geneFile.setCompressed(rs.getBoolean(GENE_COMPRESSED.name()));
            geneFile.setReferenceId(rs.getLong(GENE_REFERENCE_GENOME_ID.name()));

            long longVal = rs.getLong(GENE_EXTERNAL_DB_TYPE_ID.name());
            if (!rs.wasNull()) {
                geneFile.setExternalDBType(ExternalDBType.getById(longVal));
            }

            longVal = rs.getLong(GENE_EXTERNAL_DB_ID.name());
            if (!rs.wasNull()) {
                geneFile.setExternalDB(ExternalDB.getById(longVal));
            }

            geneFile.setExternalDBOrganism(rs.getString(GENE_EXTERNAL_DB_ORGANISM.name()));
            geneFile.setIndex(index);

            return geneFile;
        }

        @NotNull
        private static BiologicalDataItem mapVcfFile(ResultSet rs, BiologicalDataItem index) throws SQLException {
            VcfFile vcfFile = new VcfFile();
            vcfFile.setId(rs.getLong(VCF_ID.name()));
            vcfFile.setBioDataItemId(rs.getLong(BIO_DATA_ITEM_ID.name()));
            vcfFile.setCompressed(rs.getBoolean(VCF_COMPRESSED.name()));
            vcfFile.setReferenceId(rs.getLong(VCF_REFERENCE_GENOME_ID.name()));
            vcfFile.setIndex(index);

            return vcfFile;
        }

        @NotNull
        private static BiologicalDataItem mapReference(ResultSet rs) throws SQLException {
            Reference reference = new Reference();
            reference.setBioDataItemId(rs.getLong(BIO_DATA_ITEM_ID.name()));
            reference.setSize(rs.getLong(REFERENCE_GENOME_SIZE.name()));
            reference.setId(rs.getLong(REFERENCE_GENOME_ID.name()));

            long longVal = rs.getLong(REFERENCE_GENE_ITEM_ID.name());
            if (!rs.wasNull()) {
                GeneFile geneFile = new GeneFile();
                geneFile.setId(longVal);
                geneFile.setName(rs.getString(REFERENCE_GENE_ITEM_NAME.name()));
                geneFile.setBioDataItemId(rs.getLong(REFERENCE_GENE_BIO_DATA_ITEM_ID.name()));

                longVal = rs.getLong(REFERENCE_GENE_TYPE.name());
                geneFile.setType(rs.wasNull() ? null : BiologicalDataItemResourceType.getById(longVal));

                geneFile.setPath(rs.getString(REFERENCE_GENE_PATH.name()));

                longVal = rs.getLong(REFERENCE_GENE_FORMAT.name());
                geneFile.setFormat(rs.wasNull() ? null : BiologicalDataItemFormat.getById(longVal));

                geneFile.setCreatedBy(rs.getLong(REFERENCE_GENE_CREATED_BY.name()));
                geneFile.setCreatedDate(new Date(rs.getTimestamp(REFERENCE_GENE_CREATED_DATE.name()).getTime()));
                geneFile.setReferenceId(rs.getLong(REFERENCE_GENE_REFERENCE_GENOME_ID.name()));
                geneFile.setCompressed(rs.getBoolean(REFERENCE_GENE_COMPRESSED.name()));
                reference.setGeneFile(geneFile);
            }

            return reference;
        }
    }

    /**
     * Enum, containing common FeatureFile's ancestor's fields
     */
    public enum FeatureFileParameters {
        REFERENCE_GENOME_ID, INDEX_ID, COMPRESSED, EXTERNAL_DB_TYPE_ID, EXTERNAL_DB_ID, EXTERNAL_DB_ORGANISM;

        /**
         * Creates a MapSqlParameterSource with common FeatureFile's ancestor's fields for future use in DB queries
         * @param idFieldName a name of ID fields of FeatureFile's ancestor's
         * @param featureFile a FeatureFile's ancestor's entity, which fields to add to parameters
         * @return a MapSqlParameterSource with common FeatureFile's ancestor's fields
         */
        public static MapSqlParameterSource getLinkedTableParameters(String idFieldName, FeatureFile featureFile) {
            MapSqlParameterSource params = new MapSqlParameterSource();

            params.addValue(idFieldName, featureFile.getId());
            params.addValue(BiologicalDataItemParameters.BIO_DATA_ITEM_ID.name(), featureFile.getBioDataItemId());
            params.addValue(REFERENCE_GENOME_ID.name(), featureFile.getReferenceId());
            params.addValue(INDEX_ID.name(),
                    featureFile.getIndex() != null ? featureFile.getIndex().getId() : null);
            params.addValue(COMPRESSED.name(), featureFile.getCompressed());

            if (featureFile instanceof GeneFile) {
                GeneFile geneFile = (GeneFile) featureFile;
                params.addValue(EXTERNAL_DB_TYPE_ID.name(),
                        geneFile.getExternalDBType() != null ? geneFile.getExternalDBType().getId() : null);
                params.addValue(EXTERNAL_DB_ID.name(),
                        geneFile.getExternalDB() != null ? geneFile.getExternalDB().getId() : null);
                params.addValue(EXTERNAL_DB_ORGANISM.name(), geneFile.getExternalDBOrganism());
            }

            return params;
        }
    }

    @Required
    public void setInsertBiologicalDataItemQuery(String insertBiologicalDataItemQuery) {
        this.insertBiologicalDataItemQuery = insertBiologicalDataItemQuery;
    }

    @Required
    public void setLoadBiologicalDataItemsByIdsQuery(String loadBiologicalDataItemsByIdsQuery) {
        this.loadBiologicalDataItemsByIdsQuery = loadBiologicalDataItemsByIdsQuery;
    }

    @Required
    public void setBiologicalDataItemSequenceName(String biologicalDataItemSequenceName) {
        this.biologicalDataItemSequenceName = biologicalDataItemSequenceName;
    }

    @Required
    public void setDeleteBiologicalDataItemQuery(String deleteBiologicalDataItemQuery) {
        this.deleteBiologicalDataItemQuery = deleteBiologicalDataItemQuery;
    }

    @Required
    public void setLoadBiologicalDataItemsByNameStrictQuery(String loadBiologicalDataItemsByNameStrictQuery) {
        this.loadBiologicalDataItemsByNameStrictQuery = loadBiologicalDataItemsByNameStrictQuery;
    }

    @Required
    public void setLoadBiologicalDataItemsByNameQuery(String loadBiologicalDataItemsByNameQuery) {
        this.loadBiologicalDataItemsByNameQuery = loadBiologicalDataItemsByNameQuery;
    }

    @Required
    public void setLoadBiologicalDataItemsByNamesStrictQuery(String loadBiologicalDataItemsByNamesStrictQuery) {
        this.loadBiologicalDataItemsByNamesStrictQuery = loadBiologicalDataItemsByNamesStrictQuery;
    }
}