package org.genedb.db.domain.hibernateImpls; import org.genedb.db.domain.objects.BasicGene; import org.genedb.db.domain.objects.Chromosome; import org.genedb.db.domain.objects.Exon; import org.genedb.db.domain.objects.Gap; import org.genedb.db.domain.objects.Gene; import org.genedb.db.domain.objects.Transcript; import org.genedb.db.domain.objects.TranscriptComponent; import org.genedb.db.domain.services.BasicGeneService; import org.gmod.schema.mapped.CvTerm; import org.gmod.schema.mapped.Feature; import org.gmod.schema.mapped.FeatureCvTerm; import org.gmod.schema.mapped.FeatureLoc; import org.gmod.schema.mapped.FeatureRelationship; import org.gmod.schema.mapped.FeatureSynonym; import org.apache.log4j.Logger; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.SessionFactory; import org.hibernate.criterion.CriteriaSpecification; import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; public class BasicGeneServiceImpl implements BasicGeneService { protected SessionFactory sessionFactory; protected static final Logger log = Logger.getLogger(BasicGeneServiceImpl.class); protected Feature findGeneFeatureByUniqueName(String name) { // Fetch all the data we're going to need in a single query Query query = sessionFactory.getCurrentSession().createQuery( "select gene from Feature gene" +" left join fetch gene.featureLocs" +" left join fetch gene.featureSynonyms feature_synonym" +" left join fetch feature_synonym.synonym synonym" +" left join fetch synonym.type" +" inner join fetch gene.featureRelationshipsForObjectId gene_transcript" +" inner join fetch gene_transcript.subjectFeature transcript" +" inner join fetch transcript.featureRelationshipsForObjectId transcript_exon" +" inner join fetch transcript_exon.subjectFeature exon" +" where gene.uniqueName=:name and gene.type.name='gene'") .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); @SuppressWarnings("unchecked") List<Feature> features = query.setString("name", name).list(); if (features.size() == 0) return null; else return features.get(0); } public BasicGene findGeneByUniqueName(String name) { return geneFromFeature(findGeneFeatureByUniqueName(name)); } protected BasicGene geneFromFeature(Feature feat) { BasicGene ret = new Gene(); ret.setUniqueName(feat.getUniqueName()); ret.setFeatureId(feat.getFeatureId()); List<String> synonyms = new ArrayList<String>(); for (FeatureSynonym fs : feat.getFeatureSynonyms()) { String type = fs.getSynonym().getType().getName(); if (type.equals("synonym")) { synonyms.add(fs.getSynonym().getName()); } } ret.setSynonyms(synonyms); if (StringUtils.hasText(feat.getName())) { ret.setName(feat.getName()); } for (FeatureRelationship fr : feat.getFeatureRelationshipsForObjectId()) { Feature otherFeat = fr.getSubjectFeature(); if (otherFeat instanceof org.gmod.schema.feature.Transcript) { ret.addTranscript(makeTranscript(otherFeat)); } } ret.setOrganism(feat.getOrganism().getCommonName()); FeatureLoc loc = feat.getRankZeroFeatureLoc(); Feature chromosomeFeature = loc.getSourceFeature(); Chromosome chromosome = new Chromosome(chromosomeFeature.getDisplayName(), chromosomeFeature.getFeatureId(), chromosomeFeature.getSeqLen()); ret.setChromosome(chromosome); ret.setStrand(loc.getStrand()); ret.setFmin(loc.getFmin()); ret.setFmax(loc.getFmax()); return ret; } protected List<BasicGene> genesFromFeatures(List<Feature> features) { List<BasicGene> ret = new ArrayList<BasicGene>(); for(Feature feature: features) { ret.add(geneFromFeature(feature)); } return ret; } protected Gap gapFromFeature(Feature feat) { FeatureLoc loc = feat.getRankZeroFeatureLoc(); return new Gap(feat.getUniqueName(), loc.getFmin(), loc.getFmax()); } protected List<Gap> gapsFromFeatures(List<Feature> features) { List<Gap> ret = new ArrayList<Gap>(); for(Feature feature: features) { ret.add(gapFromFeature(feature)); } return ret; } private static Transcript makeTranscript(Feature feature) { Transcript transcript = new Transcript(); transcript.setFmin(feature.getRankZeroFeatureLoc().getFmin()); transcript.setFmax(feature.getRankZeroFeatureLoc().getFmax()); transcript.setUniqueName(feature.getDisplayName()); Set<TranscriptComponent> exons = new HashSet<TranscriptComponent> (); for (FeatureRelationship fr : feature.getFeatureRelationshipsForObjectId()) { Feature relatedFeature = fr.getSubjectFeature(); String relatedFeatureName = relatedFeature.getType().getName(); if (relatedFeatureName.equals("polypeptide")) { transcript.setProtein(relatedFeature); } else if (relatedFeatureName.equals("exon")) { FeatureLoc otherFeatLoc = relatedFeature.getRankZeroFeatureLoc(); exons.add(new Exon(otherFeatLoc.getFmin(), otherFeatLoc.getFmax())); } } transcript.setComponents(exons); Feature protein = transcript.getProtein(); if (protein != null) { List<String> products = new ArrayList<String>(); for (FeatureCvTerm fcvt : protein.getFeatureCvTerms()) { CvTerm featCvTerm = fcvt.getType(); if (featCvTerm.getCv().getName().equals("genedb_products")) { products.add(featCvTerm.getName()); } } transcript.setProducts(products); } return transcript; } public List<String> findGeneNamesByPartialName(String partialName) { @SuppressWarnings("unchecked") List<String> names = sessionFactory.getCurrentSession().createQuery( "select f.uniqueName" +"from Feature f" +"where f.uniqueName like '%' || :partialName || '%'" +"and f.type.name='gene'") .setString("partialName", partialName) .list(); if (names.size() == 0) return Collections.emptyList(); else return names; } public Collection<BasicGene> findGenesOverlappingRange(String organismCommonName, String chromosomeUniqueName, int strand, long locMin, long locMax) { assert strand == 1 || strand == -1; @SuppressWarnings("unchecked") List<Feature> geneFeatures = sessionFactory.getCurrentSession().createQuery( "select f from Feature f" +" inner join f.featureLocs fl" +" with fl.rank = 0" +" where fl.fmax >= :locMin and fl.fmin < :locMax" +" and fl.strand = :strand" +" and fl.sourceFeature.uniqueName = :chr" +" and f.organism.commonName = :org" +" and f.type.name='gene'") .setLong ("locMin", locMin) .setLong ("locMax", locMax) .setInteger("strand", strand) .setString ("chr", chromosomeUniqueName) .setString ("org", organismCommonName) .list(); return genesFromFeatures(geneFeatures); } public Collection<Gap> findGapsOverlappingRange(String organismCommonName, String chromosomeUniqueName, long locMin, long locMax) { @SuppressWarnings("unchecked") List<Feature> gaps = sessionFactory.getCurrentSession().createQuery( "select f from Gap f" +" inner join f.featureLocs fl" +" with fl.rank = 0" +" where fl.fmax >= :locMin and fl.fmin < :locMax" +" and fl.sourceFeature.uniqueName = :chr" +" and f.organism.commonName = :org") .setLong ("locMin", locMin) .setLong ("locMax", locMax) .setString ("chr", chromosomeUniqueName) .setString ("org", organismCommonName) .list(); return gapsFromFeatures(gaps); } public Collection<Gap> findGapsOnChromosome(String organismCommonName, String chromosomeUniqueName) { @SuppressWarnings("unchecked") List<Feature> gaps = sessionFactory.getCurrentSession().createQuery( "select f from Gap f" +" inner join f.featureLocs fl" +" with fl.rank = 0" +" and fl.sourceFeature.uniqueName = :chr" +" and f.organism.commonName = :org") .setString ("chr", chromosomeUniqueName) .setString ("org", organismCommonName) .list(); return gapsFromFeatures(gaps); } public Collection<BasicGene> findGenesExtendingIntoRange(String organismCommonName, String chromosomeUniqueName, int strand, long locMin, long locMax) { assert strand == 1 || strand == -1; @SuppressWarnings("unchecked") List<Feature> geneFeatures = sessionFactory.getCurrentSession().createQuery( "select f from Feature f" +" inner join f.featureLocs fl" +" with fl.rank = 0" +" where fl.fmax >= :locMin and fl.fmax < :locMax" // <- this line differs from above! +" and fl.strand = :strand" +" and fl.sourceFeature.uniqueName = :chr" +" and f.organism.commonName = :org" +" and f.type.name='gene'") .setLong ("locMin", locMin) .setLong ("locMax", locMax) .setInteger("strand", strand) .setString ("chr", chromosomeUniqueName) .setString ("org", organismCommonName) .list(); return genesFromFeatures(geneFeatures); } public Collection<BasicGene> findGenesOnStrand(String organismCommonName, String chromosomeUniqueName, int strand) { assert strand == 1 || strand == -1; @SuppressWarnings("unchecked") List<Feature> geneFeatures = sessionFactory.getCurrentSession().createQuery( "select f from Feature f" +" inner join f.featureLocs fl" +" with fl.rank = 0" +" where fl.strand = :strand" +" and fl.sourceFeature.uniqueName = :chr" +" and f.organism.commonName = :org" +" and f.type.name='gene'") .setInteger("strand", strand) .setString ("chr", chromosomeUniqueName) .setString ("org", organismCommonName) .list(); return genesFromFeatures(geneFeatures); } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } }