gov.nih.nci.caarray.services.data.DataRetrievalServiceBean.java Source code

Java tutorial

Introduction

Here is the source code for gov.nih.nci.caarray.services.data.DataRetrievalServiceBean.java

Source

//======================================================================================
// Copyright 5AM Solutions Inc, Yale University
//
// Distributed under the OSI-approved BSD 3-Clause License.
// See http://ncip.github.com/caarray/LICENSE.txt for details.
//======================================================================================
package gov.nih.nci.caarray.services.data;

import gov.nih.nci.caarray.dao.SearchDao;
import gov.nih.nci.caarray.domain.data.AbstractArrayData;
import gov.nih.nci.caarray.domain.data.DataRetrievalRequest;
import gov.nih.nci.caarray.domain.data.DataSet;
import gov.nih.nci.caarray.domain.data.DerivedArrayData;
import gov.nih.nci.caarray.domain.data.DesignElementList;
import gov.nih.nci.caarray.domain.data.HybridizationData;
import gov.nih.nci.caarray.domain.data.QuantitationType;
import gov.nih.nci.caarray.domain.data.RawArrayData;
import gov.nih.nci.caarray.domain.hybridization.Hybridization;
import gov.nih.nci.caarray.injection.InjectionInterceptor;
import gov.nih.nci.caarray.services.AuthorizationInterceptor;
import gov.nih.nci.caarray.services.HibernateSessionInterceptor;
import gov.nih.nci.caarray.services.StorageInterceptor;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.security.PermitAll;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.interceptor.Interceptors;

import org.apache.commons.collections.ListUtils;
import org.apache.log4j.Logger;
import org.jboss.ejb3.annotation.TransactionTimeout;

import com.google.inject.Inject;

/**
 * Implementation for remote API data retrieval.
 */
@Remote(DataRetrievalService.class)
@Stateless
@PermitAll
/*
 * Transaction required for these "getter" methods because database changes may occur as a side effect.
 */
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@TransactionTimeout(DataRetrievalServiceBean.TIMEOUT_SECONDS)
@Interceptors({ AuthorizationInterceptor.class, HibernateSessionInterceptor.class,
        DataSetConfiguringInterceptor.class, InjectionInterceptor.class, StorageInterceptor.class })
public class DataRetrievalServiceBean implements DataRetrievalService {
    private static final Logger LOG = Logger.getLogger(DataRetrievalServiceBean.class);

    static final int TIMEOUT_SECONDS = 1800;
    private SearchDao searchDao;

    /**
     * 
     * @param searchDao the SearchDao dependency
     */
    @Inject
    public void setSearchDao(SearchDao searchDao) {
        this.searchDao = searchDao;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public DataSet getDataSet(DataRetrievalRequest request) {
        LOG.info("Received data retrieval request");
        checkRequest(request);
        final List<DataSet> dataSets = getDataSets(request);
        final DataSet mergedDataSet = createMergedDataSet(dataSets, request);
        LOG.info("Retrieved " + mergedDataSet.getHybridizationDataList().size() + " hybridization data elements, "
                + mergedDataSet.getQuantitationTypes().size() + " quant types");
        return mergedDataSet;
    }

    private List<DataSet> getDataSets(DataRetrievalRequest request) {
        final List<AbstractArrayData> arrayDatas = getArrayDatas(request);
        final List<DataSet> dataSets = new ArrayList<DataSet>(arrayDatas.size());
        for (final AbstractArrayData data : arrayDatas) {
            dataSets.add(data.getDataSet());
        }
        return dataSets;
    }

    private DataSet createMergedDataSet(List<DataSet> dataSets, DataRetrievalRequest request) {
        final DataSet dataSet = new DataSet();
        dataSet.getQuantitationTypes().addAll(request.getQuantitationTypes());
        addDesignElementList(dataSet, dataSets);
        addHybridizationDatas(dataSet, dataSets, request);
        return dataSet;
    }

    private void addDesignElementList(DataSet dataSet, List<DataSet> dataSets) {
        if (dataSets.isEmpty()) {
            dataSet.setDesignElementList(new DesignElementList());
        } else if (allDesignElementListsAreConsistent(dataSets)) {
            dataSet.setDesignElementList(dataSets.get(0).getDesignElementList());
        } else {
            throw new IllegalArgumentException("The DataSet requested data from inconsistent design elements");
        }
    }

    private boolean allDesignElementListsAreConsistent(List<DataSet> dataSets) {
        final DesignElementList firstList = dataSets.get(0).getDesignElementList();
        for (int i = 1; i < dataSets.size(); i++) {
            final DesignElementList nextList = dataSets.get(i).getDesignElementList();
            if (!ListUtils.isEqualList(firstList.getDesignElements(), nextList.getDesignElements())) {
                return false;
            }
        }
        return true;
    }

    private void addHybridizationDatas(DataSet dataSet, List<DataSet> dataSets, DataRetrievalRequest request) {
        for (final DataSet nextDataSet : dataSets) {
            for (final HybridizationData nextHybridizationData : nextDataSet.getHybridizationDataList()) {
                addHybridizationData(dataSet, nextHybridizationData, request);
            }
        }
    }

    private void addHybridizationData(DataSet dataSet, HybridizationData copyFromHybridizationData,
            DataRetrievalRequest request) {
        final HybridizationData hybridizationData = new HybridizationData();
        hybridizationData.setHybridization(copyFromHybridizationData.getHybridization());
        hybridizationData.setId(copyFromHybridizationData.getId());
        dataSet.getHybridizationDataList().add(hybridizationData);
        copyColumns(hybridizationData, copyFromHybridizationData, request.getQuantitationTypes());
        hybridizationData.setDataSet(dataSet);
    }

    private void copyColumns(HybridizationData hybridizationData, HybridizationData copyFromHybridizationData,
            List<QuantitationType> quantitationTypes) {
        for (final QuantitationType type : quantitationTypes) {
            hybridizationData.getColumns().add(copyFromHybridizationData.getColumn(type));
        }
    }

    private void checkRequest(DataRetrievalRequest request) {
        if (request == null) {
            throw new IllegalArgumentException("DataRetrievalRequest was null");
        } else if (request.getHybridizations().isEmpty()) {
            throw new IllegalArgumentException("DataRetrievalRequest didn't specify Hybridizations");
        } else if (request.getQuantitationTypes().isEmpty()) {
            throw new IllegalArgumentException("DataRetrievalRequest didn't specify QuantitationTypes");
        } else if (request.getHybridizations().contains(null)) {
            throw new IllegalArgumentException("DataRetrievalRequest Hybridizations included a null value");
        } else if (request.getQuantitationTypes().contains(null)) {
            throw new IllegalArgumentException("DataRetrievalRequest QuantitationTypes included a null value");
        }
    }

    private List<AbstractArrayData> getArrayDatas(DataRetrievalRequest request) {
        final List<Hybridization> hybridizations = getHybridizations(request);
        return getArrayDatas(hybridizations, request.getQuantitationTypes());
    }

    private List<AbstractArrayData> getArrayDatas(List<Hybridization> hybridizations,
            List<QuantitationType> quantitationTypes) {
        final List<AbstractArrayData> arrayDatas = new ArrayList<AbstractArrayData>(hybridizations.size());
        for (final Hybridization hybridization : hybridizations) {
            addArrayDatas(arrayDatas, hybridization, quantitationTypes);
        }
        return arrayDatas;
    }

    private void addArrayDatas(List<AbstractArrayData> arrayDatas, Hybridization hybridization,
            List<QuantitationType> quantitationTypes) {
        for (final RawArrayData rawArrayData : hybridization.getRawDataCollection()) {
            if (shouldAddData(arrayDatas, rawArrayData, quantitationTypes)) {
                arrayDatas.add(rawArrayData);
            }
        }
        for (final DerivedArrayData derivedArrayData : hybridization.getDerivedDataCollection()) {
            if (shouldAddData(arrayDatas, derivedArrayData, quantitationTypes)) {
                arrayDatas.add(derivedArrayData);
            }
        }
    }

    private boolean shouldAddData(List<AbstractArrayData> arrayDatas, AbstractArrayData arrayData,
            List<QuantitationType> quantitationTypes) {
        return arrayData != null && !arrayDatas.contains(arrayData)
                && containsAllTypes(arrayData, quantitationTypes);
    }

    private boolean containsAllTypes(AbstractArrayData arrayData, List<QuantitationType> quantitationTypes) {
        return arrayData.getDataSet() != null
                && arrayData.getDataSet().getQuantitationTypes().containsAll(quantitationTypes);
    }

    private List<Hybridization> getHybridizations(DataRetrievalRequest request) {
        final List<Hybridization> hybridizations = new ArrayList<Hybridization>(request.getHybridizations().size());
        for (final Hybridization hybridization : request.getHybridizations()) {
            hybridizations.add(this.searchDao.retrieve(Hybridization.class, hybridization.getId()));
        }
        return hybridizations;
    }
}