Java tutorial
/* * The Gemma project * * Copyright (c) 2008 University of British Columbia * * Licensed under the Apache 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package ubic.gemma.persistence.util; import org.apache.commons.collections.ListUtils; import org.apache.commons.lang3.time.StopWatch; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.*; import org.hibernate.persister.entity.SingleTableEntityPersister; import org.hibernate.type.LongType; import ubic.gemma.model.expression.arrayDesign.ArrayDesign; import ubic.gemma.model.expression.arrayDesign.ArrayDesignValueObject; import ubic.gemma.model.expression.designElement.CompositeSequence; import ubic.gemma.model.expression.experiment.ExpressionExperiment; import ubic.gemma.model.genome.Gene; import java.util.*; /** * Contains methods to perform 'common' queries that are needed across DAOs. * * @author paul */ public class CommonQueries { private static final Log log = LogFactory.getLog(CommonQueries.class.getName()); /** * @param ees collection of expression experiments. * @param session session * @return map of array designs to the experiments they were used in. */ public static Map<ArrayDesign, Collection<Long>> getArrayDesignsUsed(Collection<Long> ees, Session session) { Map<ArrayDesign, Collection<Long>> eeAdMap = new HashMap<>(); // Safety 1st.... if (ees == null || ees.isEmpty()) return eeAdMap; final String eeAdQuery = "select distinct ee.id,ad from ExpressionExperiment as ee inner join " + "ee.bioAssays b inner join b.arrayDesignUsed ad fetch all properties where ee.id in (:ees)"; org.hibernate.Query queryObject = session.createQuery(eeAdQuery); queryObject.setParameterList("ees", ees); queryObject.setReadOnly(true); queryObject.setFlushMode(FlushMode.MANUAL); List<?> qr = queryObject.list(); for (Object o : qr) { Object[] ar = (Object[]) o; Long ee = (Long) ar[0]; ArrayDesign ad = (ArrayDesign) ar[1]; if (!eeAdMap.containsKey(ad)) { eeAdMap.put(ad, new HashSet<Long>()); } eeAdMap.get(ad).add(ee); } return eeAdMap; } /** * @param ees experiments * @param session session * @return map of experiment to collection of array design ids. If any of the ids given are for subsets, then the * key in the return value will be for the subset, not the source experiment (so it is consistent with the * input) */ public static Map<Long, Collection<Long>> getArrayDesignsUsedEEMap(Collection<Long> ees, Session session) { Map<Long, Collection<Long>> ee2ads = new HashMap<>(); if (ees == null || ees.isEmpty()) return ee2ads; final String eeAdQuery = "select distinct ee.id,ad.id from ExpressionExperiment as ee inner join " + "ee.bioAssays b inner join b.arrayDesignUsed ad where ee.id in (:ees)"; org.hibernate.Query queryObject = session.createQuery(eeAdQuery); queryObject.setParameterList("ees", ees); queryObject.setReadOnly(true); queryObject.setFlushMode(FlushMode.MANUAL); List<?> qr = queryObject.list(); ee2ads = CommonQueries.addAllAds(ee2ads, qr); if (ee2ads.size() < ees.size()) { // ids might be invalid, but also might be subsets. Note that the output key is for the subset, not the // source. String subsetQuery = "select distinct ees.id,ad.id from ExpressionExperimentSubSet as ees join ees.sourceExperiment ee " + " join ee.bioAssays b join b.arrayDesignUsed ad where ees.id in (:ees)"; //noinspection unchecked Collection<Long> possibleEEsubsets = ListUtils.removeAll(ees, ee2ads.keySet()); // note: CollectionUtils.removeAll has a bug. qr = session.createQuery(subsetQuery).setParameterList("ees", possibleEEsubsets).list(); ee2ads = CommonQueries.addAllAds(ee2ads, qr); } return ee2ads; } private static Map<Long, Collection<Long>> addAllAds(Map<Long, Collection<Long>> ee2ads, List<?> qr) { for (Object o : qr) { Object[] ar = (Object[]) o; Long ee = (Long) ar[0]; Long ad = (Long) ar[1]; if (!ee2ads.containsKey(ee)) { ee2ads.put(ee, new HashSet<Long>()); } ee2ads.get(ee).add(ad); } return ee2ads; } /** * @param session session * @param ee experiment * @return list of array designs used in given expression experiment */ public static Collection<ArrayDesign> getArrayDesignsUsed(ExpressionExperiment ee, Session session) { if (ee == null) { return null; } return CommonQueries.getArrayDesignsUsed(ee.getId(), session); } /** * @param session session * @param eeId experiment id * @return list of array designs used in given expression experiment */ @SuppressWarnings("unchecked") private static Collection<ArrayDesign> getArrayDesignsUsed(Long eeId, Session session) { List<?> list = CommonQueries.createGetADsUsedQueryObject(eeId, session).list(); /* * Thaw the TT. */ for (ArrayDesign ad : (Collection<ArrayDesign>) list) { //noinspection ResultOfMethodCallIgnored // Only thawing ad.getTechnologyType(); } return (Collection<ArrayDesign>) list; } @SuppressWarnings("unchecked") public static Collection<ArrayDesignValueObject> getArrayDesignsUsedVOs(Long eeId, Session session) { List<?> list = CommonQueries.createGetADsUsedQueryObject(eeId, session).list(); Collection<ArrayDesignValueObject> vos = new LinkedList<>(); //noinspection unchecked for (ArrayDesign ad : (Collection<ArrayDesign>) list) { vos.add(new ArrayDesignValueObject(ad)); } return vos; } /** * @param session session * @param eeId experiment id * @return list of array designs IDs used in given expression experiment */ @SuppressWarnings("unchecked") public static Collection<Long> getArrayDesignIdsUsed(Long eeId, Session session) { final String eeAdQuery = "select distinct ad.id from ExpressionExperiment as ee inner join " + "ee.bioAssays b inner join b.arrayDesignUsed ad where ee.id = :eeId"; org.hibernate.Query queryObject = session.createQuery(eeAdQuery); queryObject.setCacheable(true); queryObject.setParameter("eeId", eeId); queryObject.setReadOnly(true); queryObject.setFlushMode(FlushMode.MANUAL); List<?> list = queryObject.list(); return (Collection<Long>) list; } /** * Given a gene, get all the composite sequences that map to it. * * @param session session * @param gene gene * @return composite sequences */ public static Collection<CompositeSequence> getCompositeSequences(Gene gene, Session session) { final String csQueryString = "select distinct cs from Gene as gene" + " join gene.products gp, BioSequence2GeneProduct ba, CompositeSequence cs " + " where ba.bioSequence.id=cs.biologicalCharacteristic.id and ba.geneProduct.id = gp.id and gene.id = :gene "; org.hibernate.Query queryObject = session.createQuery(csQueryString); queryObject.setParameter("gene", gene.getId(), LongType.INSTANCE); queryObject.setReadOnly(true); queryObject.setFlushMode(FlushMode.MANUAL); //noinspection unchecked return queryObject.list(); } private static Query createGetADsUsedQueryObject(Long eeId, Session session) { final String eeAdQuery = "select distinct ad from ExpressionExperiment as ee inner join " + "ee.bioAssays b inner join b.arrayDesignUsed ad inner join ad.primaryTaxon fetch all properties where ee.id = :eeId"; Query queryObject = session.createQuery(eeAdQuery); queryObject.setCacheable(true); queryObject.setParameter("eeId", eeId); queryObject.setReadOnly(true); queryObject.setFlushMode(FlushMode.MANUAL); return queryObject; } private static void addGeneIds(Map<Long, Collection<Long>> cs2genes, ScrollableResults results) { while (results.next()) { Long csid = results.getLong(0); Long geneId = results.getLong(1); if (!cs2genes.containsKey(csid)) { cs2genes.put(csid, new HashSet<Long>()); } cs2genes.get(csid).add(geneId); } } /** * @param session session * @param genes genes * @param arrayDesigns array design * @return map of probe IDs to collections of gene IDs. */ public static Map<Long, Collection<Long>> getCs2GeneIdMap(Collection<Long> genes, Collection<Long> arrayDesigns, Session session) { Map<Long, Collection<Long>> cs2genes = new HashMap<>(); String queryString = "SELECT CS AS csid, GENE AS geneId FROM GENE2CS g WHERE g.GENE IN (:geneIds) AND g.AD IN (:ads)"; SQLQuery queryObject = session.createSQLQuery(queryString); queryObject.addScalar("csid", LongType.INSTANCE); queryObject.addScalar("geneId", LongType.INSTANCE); queryObject.setParameterList("ads", arrayDesigns); queryObject.setParameterList("geneIds", genes); queryObject.setReadOnly(true); queryObject.setFlushMode(FlushMode.MANUAL); ScrollableResults results = queryObject.scroll(ScrollMode.FORWARD_ONLY); CommonQueries.addGeneIds(cs2genes, results); results.close(); return cs2genes; } public static Map<CompositeSequence, Collection<Gene>> getCs2GeneMap(Collection<Gene> genes, Collection<ArrayDesign> arrayDesigns, Session session) { StopWatch timer = new StopWatch(); timer.start(); final String csQueryString = "select distinct cs, gene from Gene as gene" + " inner join gene.products gp, BioSequence2GeneProduct ba, CompositeSequence cs " + " where ba.bioSequence=cs.biologicalCharacteristic and ba.geneProduct = gp" + " and gene in (:genes) and cs.arrayDesign in (:ads) "; Map<CompositeSequence, Collection<Gene>> cs2gene = new HashMap<>(); Query queryObject = session.createQuery(csQueryString); queryObject.setCacheable(true); queryObject.setParameterList("genes", genes); queryObject.setParameterList("ads", arrayDesigns); queryObject.setReadOnly(true); queryObject.setFlushMode(FlushMode.MANUAL); ScrollableResults results = queryObject.scroll(ScrollMode.FORWARD_ONLY); CommonQueries.addGenes(cs2gene, results); results.close(); if (timer.getTime() > 200) { CommonQueries.log.info("Get cs2gene for " + genes.size() + " :" + timer.getTime() + "ms"); } return cs2gene; } /** * @param genes genes * @param session session * @return map of probes to input genes they map to. Other genes those probes might detect are not included. */ public static Map<CompositeSequence, Collection<Gene>> getCs2GeneMap(Collection<Gene> genes, Session session) { StopWatch timer = new StopWatch(); timer.start(); final String csQueryString = "select distinct cs, gene from Gene as gene" + " inner join gene.products gp, BioSequence2GeneProduct ba, CompositeSequence cs " + " where ba.bioSequence=cs.biologicalCharacteristic and ba.geneProduct = gp" + " and gene in (:genes) "; Map<CompositeSequence, Collection<Gene>> cs2gene = new HashMap<>(); org.hibernate.Query queryObject = session.createQuery(csQueryString); queryObject.setCacheable(true); queryObject.setParameterList("genes", genes); queryObject.setReadOnly(true); queryObject.setFlushMode(FlushMode.MANUAL); ScrollableResults results = queryObject.scroll(ScrollMode.FORWARD_ONLY); CommonQueries.addGenes(cs2gene, results); results.close(); if (timer.getTime() > 200) { CommonQueries.log.info("Get cs2gene for " + genes.size() + " :" + timer.getTime() + "ms"); } return cs2gene; } private static void addGenes(Map<CompositeSequence, Collection<Gene>> cs2gene, ScrollableResults results) { while (results.next()) { CompositeSequence cs = (CompositeSequence) results.get(0); Gene g = (Gene) results.get(1); if (!cs2gene.containsKey(cs)) { cs2gene.put(cs, new HashSet<Gene>()); } cs2gene.get(cs).add(g); } } public static void addSubclasses(List<String> classes, SingleTableEntityPersister classMetadata) { if (classMetadata.hasSubclasses()) { String[] subclasses = classMetadata.getSubclassClosure(); // this includes the superclass, fully qualified // names. classes.clear(); for (String string : subclasses) { string = string.replaceFirst(".+\\.", ""); classes.add(string); } } } /** * @param session session * @param probes probes * @return map of probes to all the genes 'detected' by those probes. Probes that don't map to genes will have an * empty gene collection. */ public static Map<Long, Collection<Long>> getCs2GeneMapForProbes(Collection<Long> probes, Session session) { if (probes.isEmpty()) return new HashMap<>(); Map<Long, Collection<Long>> cs2genes = new HashMap<>(); String queryString = "SELECT CS AS csid, GENE AS geneId FROM GENE2CS g WHERE g.CS IN (:probes) "; org.hibernate.SQLQuery queryObject = session.createSQLQuery(queryString); queryObject.addScalar("csid", LongType.INSTANCE); queryObject.addScalar("geneId", LongType.INSTANCE); queryObject.setParameterList("probes", probes, LongType.INSTANCE); queryObject.setReadOnly(true); queryObject.setFlushMode(FlushMode.MANUAL); ScrollableResults results = queryObject.scroll(ScrollMode.FORWARD_ONLY); CommonQueries.addGeneIds(cs2genes, results); results.close(); return cs2genes; } public static Collection<Long> filterProbesByPlatform(Collection<Long> probes, Collection<Long> arrayDesignIds, Session session) { assert probes != null && !probes.isEmpty(); assert arrayDesignIds != null && !arrayDesignIds.isEmpty(); String queryString = "SELECT CS AS csid FROM GENE2CS WHERE AD IN (:adids) AND CS IN (:probes)"; org.hibernate.SQLQuery queryObject = session.createSQLQuery(queryString); queryObject.addScalar("csid", LongType.INSTANCE); queryObject.setParameterList("probes", probes, LongType.INSTANCE); queryObject.setParameterList("adids", arrayDesignIds, LongType.INSTANCE); ScrollableResults results = queryObject.scroll(ScrollMode.FORWARD_ONLY); List<Long> r = new ArrayList<>(); while (results.next()) { r.add(results.getLong(0)); } results.close(); return r; } }