Java tutorial
/******************************************************************************* * Copyright (c) 2011 University of Western Australia. All rights reserved. * * This file is part of The Ark. * * The Ark is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * The Ark is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package au.org.theark.lims.model.dao; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.commons.lang.StringUtils; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.StatelessSession; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Property; import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Subqueries; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import au.org.theark.core.dao.HibernateSessionDao; import au.org.theark.core.exception.ArkSystemException; import au.org.theark.core.exception.EntityNotFoundException; import au.org.theark.core.model.lims.entity.BioCollection; import au.org.theark.core.model.lims.entity.BioCollectionCustomFieldData; import au.org.theark.core.model.lims.entity.BioCollectionUidTemplate; import au.org.theark.core.model.lims.entity.BioSampletype; import au.org.theark.core.model.lims.entity.BioTransaction; import au.org.theark.core.model.lims.entity.Biospecimen; import au.org.theark.core.model.lims.entity.InvCell; import au.org.theark.core.model.study.entity.ArkFunction; import au.org.theark.core.model.study.entity.CustomField; import au.org.theark.core.model.study.entity.CustomFieldDisplay; import au.org.theark.core.model.study.entity.LinkSubjectStudy; import au.org.theark.core.model.study.entity.Study; import au.org.theark.lims.util.UniqueIdGenerator; @SuppressWarnings("unchecked") @Repository("bioCollectionDao") public class BioCollectionDao extends HibernateSessionDao implements IBioCollectionDao { private static Logger log = LoggerFactory.getLogger(BioCollection.class); private BioCollectionUidGenerator bioCollectionUidGenerator; @Autowired public void setBioCollectionUidGenerator(BioCollectionUidGenerator bioCollectionUidGenerator) { this.bioCollectionUidGenerator = bioCollectionUidGenerator; } public BioCollection getBioCollection(Long id) throws EntityNotFoundException { Criteria criteria = getSession().createCriteria(BioCollection.class); criteria.add(Restrictions.eq("id", id)); BioCollection bioCollection = (BioCollection) criteria.uniqueResult(); if (bioCollection == null) { throw new EntityNotFoundException("The BioCollection entity cannot be found."); } return bioCollection; } public java.util.List<BioCollection> searchBioCollection(BioCollection bioCollection) throws ArkSystemException { Criteria criteria = getSession().createCriteria(BioCollection.class); if (bioCollection.getId() != null) criteria.add(Restrictions.eq("id", bioCollection.getId())); if (bioCollection.getBiocollectionUid() != null) criteria.add(Restrictions.eq("biocollectionUid", bioCollection.getBiocollectionUid())); if (bioCollection.getName() != null) criteria.add(Restrictions.eq("name", bioCollection.getName())); if (bioCollection.getLinkSubjectStudy() != null) criteria.add(Restrictions.eq("linkSubjectStudy", bioCollection.getLinkSubjectStudy())); if (bioCollection.getStudy() != null) criteria.add(Restrictions.eq("study", bioCollection.getStudy())); if (bioCollection.getCollectionDate() != null) criteria.add(Restrictions.eq("collectionDate", bioCollection.getCollectionDate())); if (bioCollection.getSurgeryDate() != null) criteria.add(Restrictions.eq("surgeryDate", bioCollection.getSurgeryDate())); List<BioCollection> list = criteria.list(); return list; } public boolean doesSomeoneElseHaveThisUid(String biocollectionUid, final Study study, Long idToExcludeFromSearch) { Criteria criteria = getSession().createCriteria(BioCollection.class); criteria.add(Restrictions.eq("biocollectionUid", biocollectionUid)); if (idToExcludeFromSearch != null) { criteria.add(Restrictions.ne("id", idToExcludeFromSearch)); } if (study != null) { criteria.add(Restrictions.eq("study", study)); } return (criteria.list().size() > 0); } public BioCollection createBioCollection(au.org.theark.core.model.lims.entity.BioCollection biocollection) throws ArkSystemException { Study study = biocollection.getStudy(); String biocollectionUid = null; if (study != null && study.getAutoGenerateBiocollectionUid()) { biocollectionUid = getNextGeneratedBiCollectionUID(biocollection.getStudy()); } else { biocollectionUid = biocollection.getBiocollectionUid(); } if (biocollectionUid.isEmpty()) { biocollectionUid = UniqueIdGenerator.generateUniqueId(); } if (doesSomeoneElseHaveThisUid(biocollectionUid, study, biocollection.getId())) { throw new ArkSystemException("The biocollection UID " + biocollectionUid + " is currently used by another existing biocollection within this study. Please select a unique identifier instead"); } biocollection.setBiocollectionUid(biocollectionUid); getSession().save(biocollection); getSession().refresh(biocollection); return biocollection; } private String getNextGeneratedBiCollectionUID(Study study) { Study studyToUse = null; if (study.getParentStudy() != null) { studyToUse = study.getParentStudy(); } else { studyToUse = study; } BioCollectionUidTemplate biocollectionUidTemplate = getBioCollectionUidTemplate(studyToUse); String bioCollectionUidPrefix = new String(""); String bioCollectionUidToken = new String(""); String bioCollectionUidPaddedIncrementor = new String(""); String bioCollectionUidPadChar = new String("0"); StringBuilder nextIncrementedBioCollectionUid = new StringBuilder(""); StringBuilder biospecimenUid = new StringBuilder(); if (biocollectionUidTemplate != null) { if (biocollectionUidTemplate.getBioCollectionUidPrefix() != null) bioCollectionUidPrefix = biocollectionUidTemplate.getBioCollectionUidPrefix(); if (biocollectionUidTemplate.getBioCollectionUidToken() != null && biocollectionUidTemplate.getBioCollectionUidToken().getName() != null) { bioCollectionUidToken = biocollectionUidTemplate.getBioCollectionUidToken().getName(); } if (biocollectionUidTemplate.getBioCollectionUidPadChar() != null && biocollectionUidTemplate.getBioCollectionUidPadChar().getName() != null) { bioCollectionUidPadChar = biocollectionUidTemplate.getBioCollectionUidPadChar().getName().trim(); } int incrementedValue = getNextUidSequence(studyToUse).intValue(); nextIncrementedBioCollectionUid = nextIncrementedBioCollectionUid.append(incrementedValue); int size = Integer.parseInt(bioCollectionUidPadChar); bioCollectionUidPaddedIncrementor = StringUtils.leftPad(nextIncrementedBioCollectionUid.toString(), size, "0"); biospecimenUid.append(bioCollectionUidPrefix); biospecimenUid.append(bioCollectionUidToken); biospecimenUid.append(bioCollectionUidPaddedIncrementor); } else { biospecimenUid = null; } // handle for a null BiospecimenUID if (biospecimenUid == null || biospecimenUid.length() == 0) { String uid = "" + getNextUidSequence(studyToUse); //UniqueIdGenerator.generateUniqueId(); biospecimenUid = new StringBuilder(); biospecimenUid.append(uid); log.error("Biocollection Template is not defined for the Study: " + studyToUse.getName()); } return biospecimenUid.toString(); } public Integer getNextUidSequence(Study study) { Integer result = null; if (study == null) { log.error("Error in Biospecimen insertion - Study was null"); } else if (study.getName() == null) { log.error("Error in Biospecimen insertion - Study name was null"); } else { result = (Integer) bioCollectionUidGenerator.getId(study.getName()); } return result; } public BioCollectionUidTemplate getBioCollectionUidTemplate(Study study) { Criteria criteria = getSession().createCriteria(BioCollectionUidTemplate.class); criteria.add(Restrictions.eq("study", study)); BioCollectionUidTemplate biocollectionUidTemplate = (BioCollectionUidTemplate) criteria.uniqueResult(); return biocollectionUidTemplate; } public void deleteBioCollection(au.org.theark.core.model.lims.entity.BioCollection bioCollection) { getSession().delete(bioCollection); } public void updateBioCollection(au.org.theark.core.model.lims.entity.BioCollection bioCollection) throws ArkSystemException { if (doesSomeoneElseHaveThisUid(bioCollection.getBiocollectionUid(), bioCollection.getStudy(), bioCollection.getId())) { throw new ArkSystemException("The biocollectionUid '" + bioCollection.getBiocollectionUid() + "' already exists within this study. Please give this biocollection a unique UID"); } getSession().update(bioCollection); } public List<BioSampletype> getSampleTypes() { Criteria criteria = getStatelessSession().createCriteria(BioSampletype.class); criteria.addOrder(Order.asc("orderId")); List<BioSampletype> list = criteria.list(); return list; } public Boolean hasBioCollections(LinkSubjectStudy linkSubjectStudy) { // Use WHERE EXIST to optimise query even further StatelessSession session = getStatelessSession(); Criteria criteria = session.createCriteria(LinkSubjectStudy.class, "lss"); DetachedCriteria sizeCriteria = DetachedCriteria.forClass(BioCollection.class, "bc"); criteria.add(Restrictions.eq("lss.id", linkSubjectStudy.getId())); sizeCriteria.add(Property.forName("lss.id").eqProperty("bc.linkSubjectStudy.id")); criteria.add(Subqueries.exists(sizeCriteria.setProjection(Projections.property("bc.id")))); criteria.setProjection(Projections.rowCount()); Boolean result = ((Long) criteria.uniqueResult()) > 0L; session.close(); return result; } public Boolean hasBiospecimens(BioCollection bioCollection) { // Use WHERE EXIST to optimise query even further StatelessSession session = getStatelessSession(); Criteria criteria = session.createCriteria(BioCollection.class, "bc"); DetachedCriteria sizeCriteria = DetachedCriteria.forClass(Biospecimen.class, "b"); criteria.add(Restrictions.eq("bc.id", bioCollection.getId())); sizeCriteria.add(Property.forName("bc.id").eqProperty("b.bioCollection.id")); criteria.add(Subqueries.exists(sizeCriteria.setProjection(Projections.property("b.id")))); criteria.setProjection(Projections.rowCount()); Boolean result = ((Long) criteria.uniqueResult()) > 0L; session.close(); return result; } public long getBioCollectionCount(BioCollection bioCollectionCriteria) { // Handle for study not in context if (bioCollectionCriteria.getStudy() == null) { return 0; } Criteria criteria = buildBioCollectionCriteria(bioCollectionCriteria); criteria.setProjection(Projections.rowCount()); Long totalCount = (Long) criteria.uniqueResult(); return totalCount; } public List<BioCollection> searchPageableBioCollections(BioCollection bioCollectionCriteria, int first, int count) { Criteria criteria = buildBioCollectionCriteria(bioCollectionCriteria); criteria.setFirstResult(first); criteria.setMaxResults(count); List<BioCollection> list = criteria.list(); return list; } protected Criteria buildBioCollectionCriteria(BioCollection bioCollectionCriteria) { Criteria criteria = getSession().createCriteria(BioCollection.class); if (bioCollectionCriteria.getId() != null) { criteria.add(Restrictions.eq("id", bioCollectionCriteria.getId())); } if (bioCollectionCriteria.getBiocollectionUid() != null) { criteria.add(Restrictions.eq("biocollectionUid", bioCollectionCriteria.getBiocollectionUid())); } if (bioCollectionCriteria.getName() != null) { criteria.add(Restrictions.eq("name", bioCollectionCriteria.getName())); } if (bioCollectionCriteria.getLinkSubjectStudy() != null) { criteria.add(Restrictions.eq("linkSubjectStudy", bioCollectionCriteria.getLinkSubjectStudy())); } if (bioCollectionCriteria.getStudy() != null) { criteria.add(Restrictions.eq("study", bioCollectionCriteria.getStudy())); } if (bioCollectionCriteria.getCollectionDate() != null) { criteria.add(Restrictions.eq("collectionDate", bioCollectionCriteria.getCollectionDate())); } if (bioCollectionCriteria.getSurgeryDate() != null) { criteria.add(Restrictions.eq("surgeryDate", bioCollectionCriteria.getSurgeryDate())); } return criteria; } /** * This count can be based on CustomFieldDisplay alone (i.e. does not need left join to BioCollectionCustomFieldData) */ public long getBioCollectionCustomFieldDataCount(BioCollection bioCollectionCriteria, ArkFunction arkFunction) { Criteria criteria = getSession().createCriteria(CustomFieldDisplay.class); criteria.createAlias("customField", "cfield"); // criteria.add(Restrictions.eq("cfield.study", bioCollectionCriteria.getStudy())); // Added to allow child studies to inherit parent defined custom fields List studyList = new ArrayList(); studyList.add(bioCollectionCriteria.getStudy()); if (bioCollectionCriteria.getStudy().getParentStudy() != null && bioCollectionCriteria.getStudy().getParentStudy() != bioCollectionCriteria.getStudy()) { studyList.add(bioCollectionCriteria.getStudy().getParentStudy()); } criteria.add(Restrictions.in("cfield.study", studyList)); criteria.add(Restrictions.eq("cfield.arkFunction", arkFunction)); criteria.setProjection(Projections.rowCount()); return (Long) criteria.uniqueResult(); } public List<BioCollectionCustomFieldData> getBioCollectionCustomFieldDataList( BioCollection bioCollectionCriteria, ArkFunction arkFunction, int first, int count) { List<BioCollectionCustomFieldData> bioCollectionCustomFieldDataList = new ArrayList<BioCollectionCustomFieldData>(); StringBuffer sb = new StringBuffer(); sb.append(" FROM CustomFieldDisplay AS cfd "); sb.append("LEFT JOIN cfd.bioCollectionCustomFieldData as fieldList "); sb.append(" with fieldList.bioCollection.id = :bioCollectionId "); sb.append(" WHERE cfd.customField.study.id IN (:studyId)"); sb.append(" AND cfd.customField.arkFunction.id = :functionId"); sb.append(" ORDER BY cfd.sequence"); Query query = getSession().createQuery(sb.toString()); query.setParameter("bioCollectionId", bioCollectionCriteria.getId()); // Allow child studies to inherit parent defined custom fields List studyList = new ArrayList(); studyList.add(bioCollectionCriteria.getStudy().getId()); if (bioCollectionCriteria.getStudy().getParentStudy() != null && bioCollectionCriteria.getStudy().getParentStudy() != bioCollectionCriteria.getStudy()) { studyList.add(bioCollectionCriteria.getStudy().getParentStudy().getId()); } query.setParameterList("studyId", studyList); query.setParameter("functionId", arkFunction.getId()); query.setFirstResult(first); query.setMaxResults(count); List<Object[]> listOfObjects = query.list(); for (Object[] objects : listOfObjects) { CustomFieldDisplay cfd = new CustomFieldDisplay(); BioCollectionCustomFieldData bccfd = new BioCollectionCustomFieldData(); if (objects.length > 0 && objects.length >= 1) { cfd = (CustomFieldDisplay) objects[0]; if (objects[1] != null) { bccfd = (BioCollectionCustomFieldData) objects[1]; } else { bccfd.setCustomFieldDisplay(cfd); } bioCollectionCustomFieldDataList.add(bccfd); } } return bioCollectionCustomFieldDataList; } public BioCollectionCustomFieldData getBioCollectionCustomFieldData(BioCollection bioCollectionCriteria, ArkFunction arkFunction, String customFieldName) { StringBuffer sb = new StringBuffer(); sb.append(" FROM CustomFieldDisplay AS cfd "); sb.append("LEFT JOIN cfd.bioCollectionCustomFieldData as fieldList "); sb.append(" WITH fieldList.bioCollection.id = :bioCollectionId "); sb.append(" WHERE cfd.customField.study.id IN (:studyId)"); sb.append(" AND cfd.customField.arkFunction.id = :functionId"); sb.append(" AND cfd.customField.name = :customFieldName"); sb.append(" ORDER BY cfd.sequence"); Query query = getSession().createQuery(sb.toString()); query.setParameter("bioCollectionId", bioCollectionCriteria.getId()); // Allow child studies to inherit parent defined custom fields List studyList = new ArrayList(); studyList.add(bioCollectionCriteria.getStudy().getId()); if (bioCollectionCriteria.getStudy().getParentStudy() != null && bioCollectionCriteria.getStudy().getParentStudy() != bioCollectionCriteria.getStudy()) { studyList.add(bioCollectionCriteria.getStudy().getParentStudy().getId()); } query.setParameterList("studyId", studyList); query.setParameter("functionId", arkFunction.getId()); query.setParameter("customFieldName", customFieldName); BioCollectionCustomFieldData bccfd = new BioCollectionCustomFieldData(); List<Object[]> listOfObjects = query.list(); for (Object[] objects : listOfObjects) { CustomFieldDisplay cfd = new CustomFieldDisplay(); if (objects.length > 0 && objects.length >= 1) { cfd = (CustomFieldDisplay) objects[0]; if (objects[1] != null) { bccfd = (BioCollectionCustomFieldData) objects[1]; } else { bccfd.setCustomFieldDisplay(cfd); } } } return bccfd; } public void createBioCollectionCustomFieldData(BioCollectionCustomFieldData bioCollectionCFData) { getSession().save(bioCollectionCFData); } public void updateBioCollectionCustomFieldData(BioCollectionCustomFieldData bioCollectionCFData) { getSession().update(bioCollectionCFData); } public void deleteBioCollectionCustomFieldData(BioCollectionCustomFieldData bioCollectionCFData) { getSession().delete(bioCollectionCFData); } public Long isCustomFieldUsed(BioCollectionCustomFieldData bioCollectionCFData) { Long count = new Long("0"); CustomField customField = bioCollectionCFData.getCustomFieldDisplay().getCustomField(); // The Study try { Long id = bioCollectionCFData.getBioCollection().getId(); BioCollection bioCollection = getBioCollection(id); //Study subjectStudy = bioCollection.getStudy(); ArkFunction arkFunction = customField.getArkFunction(); StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(" SELECT COUNT(*) FROM BioCollectionCustomFieldData AS bccfd WHERE EXISTS "); stringBuffer.append(" ( "); stringBuffer.append(" SELECT cfd.id "); stringBuffer.append(" FROM CustomFieldDisplay AS cfd "); stringBuffer.append(" WHERE cfd.customField.study IN (:studyId)"); stringBuffer.append( " AND cfd.customField.arkFunction.id = :functionId AND bccfd.customFieldDisplay.id = :customFieldDisplayId"); stringBuffer.append(" )"); String theHQLQuery = stringBuffer.toString(); Query query = getSession().createQuery(theHQLQuery); //query.setParameter("studyId", subjectStudy.getId()); List studyList = new ArrayList(); studyList.add(bioCollection.getStudy()); if (bioCollection.getStudy().getParentStudy() != null && bioCollection.getStudy().getParentStudy() != bioCollection.getStudy()) { studyList.add(bioCollection.getStudy().getParentStudy()); } query.setParameterList("studyId", studyList); query.setParameter("functionId", arkFunction.getId()); query.setParameter("customFieldDisplayId", bioCollectionCFData.getCustomFieldDisplay().getId()); count = (Long) query.uniqueResult(); } catch (EntityNotFoundException e) { //The given BioCollection is not available, this should not happen since the person is editing custom fields for the LIMS collection e.printStackTrace(); } return count; } public BioCollection getBioCollectionByUID(final String biocollectionUid, final Long studyId, final String subjectUID) { String GET_BIO_COLLECTION_BY_UID_AND_STUDY_ID_AND_SUBJECTUID = "select bio from BioCollection as bio " + "left outer join bio.linkSubjectStudy as linkStudy " + "left outer join linkStudy.study as study " + "where bio.biocollectionUid = :biocollectionUid " + "and study.id = :studyId " + " and linkStudy.subjectUID = :subjectUID"; Query query = getSession().createQuery(GET_BIO_COLLECTION_BY_UID_AND_STUDY_ID_AND_SUBJECTUID); query.setString("biocollectionUid", biocollectionUid); query.setLong("studyId", studyId); query.setString("subjectUID", subjectUID); BioCollection bioCollection = (BioCollection) query.uniqueResult(); return bioCollection; } public List<String> getAllBiocollectionUIDs(Study study) { String queryString = "select bio.biocollectionUid " + "from BioCollection bio " + "where study =:study " + "order by biocollectionUid "; Query query = getSession().createQuery(queryString); query.setParameter("study", study); return query.list(); } public BioCollection getBioCollectionForStudySubjectByUID(String biocollectionUid, Study study, LinkSubjectStudy linkSubjectStudy) { Criteria criteria = getSession().createCriteria(BioCollection.class, "biocollection"); criteria.add(Restrictions.eq("biocollection.biocollectionUid", biocollectionUid)); criteria.add(Restrictions.eq("study", study)); criteria.add(Restrictions.eq("linkSubjectStudy", linkSubjectStudy)); return (BioCollection) criteria.uniqueResult(); } /** * Insert bio collections in a batch. * @param insertBioCollections */ public void batchInsertBiocollections(Collection<BioCollection> insertBioCollections) { for (BioCollection biocollection : insertBioCollections) { getSession().save(biocollection); } } /** * Update bio collections in batch. * @param updateBiospecimens */ public void batchUpdateBiocollections(Collection<BioCollection> updateBioCollections) { for (BioCollection biocollection : updateBioCollections) { getSession().update(biocollection); } } public boolean hasBiocllectionGotCustomFieldData(BioCollection bioCollection) { Criteria criteria = getSession().createCriteria(BioCollectionCustomFieldData.class); criteria.add(Restrictions.eq("bioCollection", bioCollection)); List<BioCollectionCustomFieldData> list = (List<BioCollectionCustomFieldData>) criteria.list(); return (list.size() > 0); } }