Java tutorial
/** * * Copyright 2010 Matthew Z DeMaere. * * This file is part of SHAP. * * SHAP 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. * * SHAP 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 SHAP. If not, see <http://www.gnu.org/licenses/>. * */ package org.mzd.shap.domain.dao; import java.io.Serializable; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.hibernate.Criteria; import org.hibernate.FetchMode; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.criterion.Disjunction; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.search.FullTextQuery; import org.hibernate.transform.Transformers; import org.mzd.shap.analysis.Annotator; import org.mzd.shap.analysis.Detector; import org.mzd.shap.domain.Feature; import org.mzd.shap.domain.FeatureException; import org.mzd.shap.domain.FeatureType; import org.mzd.shap.domain.Location; import org.mzd.shap.domain.Project; import org.mzd.shap.domain.Sample; import org.mzd.shap.domain.Sequence; import org.mzd.shap.domain.Taxonomy; import org.mzd.shap.domain.authentication.User; import org.mzd.shap.spring.orm.BaseDaoSpringHibernate; import org.springframework.orm.hibernate3.HibernateCallback; public class FeatureDaoSpringHibernate extends BaseDaoSpringHibernate<Feature, Integer> implements FeatureDao { public FeatureDaoSpringHibernate() { super(Feature.class); } @SuppressWarnings("unchecked") public List<Feature> findByFullText(String queryText, User user) { FullTextQuery query = findByFullText(queryText, new String[] { "id", "confidence", "partial", "type", "location.start", "location.end", "location.length", "location.strand", "location.frame", "annotations.accession", "annotations.description", "annotations.annotator" }); query.enableFullTextFilter("featureUser").setParameter("value", user.getId()); return query.list(); } public List<Feature> findUnprocessed(Sequence sequence) { return findByCriteria(null, Restrictions.eq("sequence", sequence), Restrictions.isEmpty("annotations")); } protected void addOrders(Criteria crit, Order... orders) { if (orders != null) { for (Order o : orders) { crit.addOrder(o); } } else { crit.addOrder(Order.asc("id")); } } public List<Feature> findMarkers(final Order order, final String[] markerNames) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) { // Or all specified marker names together Disjunction disj = Restrictions.disjunction(); for (String mn : markerNames) { disj.add(Restrictions.like("description", "%" + mn + "%")); } Criteria crit = session.createCriteria(getPersistentClass()).createCriteria("annotations") .add(disj); if (order != null) { crit.addOrder(order); } return crit.list(); } }); } public Feature findBySequenceAndId(Sequence sequence, Integer id) { return findUniqueByCriteria(Restrictions.eq("sequence", sequence), Restrictions.idEq(id)); } public List<Feature> findByProjectAndType(final Project project, final FeatureType type, final boolean minimal) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) throws HibernateException, SQLException { if (minimal) { return session.createCriteria(getPersistentClass()) .setProjection(Projections.projectionList().add(Projections.id(), "id") .add(Projections.property("version"), "version")) .add(Restrictions.eq("type", type)).createCriteria("sequence").createCriteria("sample") .add(Restrictions.eq("project", project)) .setResultTransformer(Transformers.aliasToBean(getPersistentClass())).list(); } else { return session.createCriteria(getPersistentClass()).add(Restrictions.eq("type", type)) .createCriteria("sequence").createCriteria("sample") .add(Restrictions.eq("project", project)).list(); } } }); } public List<Feature> findByProjectAndType(final Project project, final FeatureType type) { return findByProjectAndType(project, type, false); } public List<Feature> findBySampleAndType(final Sample sample, final FeatureType type, final boolean minimal) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) throws HibernateException, SQLException { if (minimal) { return session.createCriteria(getPersistentClass()) .setProjection(Projections.projectionList().add(Projections.id(), "id") .add(Projections.property("version"), "version")) .add(Restrictions.eq("type", type)).createCriteria("sequence") .add(Restrictions.eq("sample", sample)) .setResultTransformer(Transformers.aliasToBean(getPersistentClass())).list(); } else { return session.createCriteria(getPersistentClass()).add(Restrictions.eq("type", type)) .createCriteria("sequence").add(Restrictions.eq("sample", sample)).list(); } } }); } public List<Feature> pageBySample(final int firstElement, final int maxResults, final Sample sample, final FeatureType type, final Collection<Taxonomy> excludedTaxa) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) throws HibernateException, SQLException { Criteria crit = session.createCriteria(getPersistentClass()).setFirstResult(firstElement) .setMaxResults(maxResults).addOrder(Order.asc("id")).add(Restrictions.eq("type", type)) .createAlias("sequence", "seq").add(Restrictions.eq("seq.sample", sample)); if (excludedTaxa != null && excludedTaxa.size() > 0) { crit.add(Restrictions.not(Restrictions.in("seq.taxonomy", excludedTaxa))); } return crit.list(); } }); } public List<Feature> pageBySample(final int firstElement, final int maxResults, final Sample sample, final FeatureType type) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) throws HibernateException, SQLException { return session.createCriteria(getPersistentClass()).setFirstResult(firstElement) .setMaxResults(maxResults).addOrder(Order.asc("id")).add(Restrictions.eq("type", type)) .createAlias("sequence", "seq").add(Restrictions.eq("seq.sample", sample)).list(); } }); } public List<Feature> pageBySample(final int firstElement, final int maxResults, final Sample sample) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) throws HibernateException, SQLException { return session.createCriteria(getPersistentClass()).setFirstResult(firstElement) .setMaxResults(maxResults).addOrder(Order.asc("id")).createCriteria("sequence") .add(Restrictions.eq("sample", sample)).list(); } }); } public Long countBySample(final Sample sample) { return getHibernateTemplate().execute(new HibernateCallback<Long>() { public Long doInHibernate(Session session) throws HibernateException, SQLException { return (Long) session.createCriteria(getPersistentClass()).setProjection(Projections.rowCount()) .createCriteria("sequence").add(Restrictions.eq("sample", sample)).uniqueResult(); } }); } public Long countBySample(final Sample sample, final FeatureType type, final Collection<Taxonomy> excludedTaxa) { return getHibernateTemplate().execute(new HibernateCallback<Long>() { public Long doInHibernate(Session session) throws HibernateException, SQLException { Criteria crit = session.createCriteria(getPersistentClass()).setProjection(Projections.rowCount()) .add(Restrictions.eq("type", type)).createCriteria("sequence") .add(Restrictions.eq("sample", sample)); if (excludedTaxa != null && excludedTaxa.size() > 0) { crit.add(Restrictions.not(Restrictions.in("taxonomy", excludedTaxa))); } return (Long) crit.uniqueResult(); } }); } public Long countBySampleAndType(final Sample sample, final FeatureType type) { return getHibernateTemplate().execute(new HibernateCallback<Long>() { public Long doInHibernate(Session session) throws HibernateException, SQLException { return (Long) session.createCriteria(getPersistentClass()).setProjection(Projections.rowCount()) .add(Restrictions.eq("type", type)).createCriteria("sequence") .add(Restrictions.eq("sample", sample)).uniqueResult(); } }); } public List<Feature> pageBySequence(final int firstElement, final int maxResults, final Sequence sequence, final Order... order) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) throws HibernateException, SQLException { Criteria crit = session.createCriteria(getPersistentClass()) .add(Restrictions.eq("sequence", sequence)).setFirstResult(firstElement) .setMaxResults(maxResults); addOrders(crit, order); return crit.list(); } }); } public List<Feature> pageBySequenceAndType(final int firstElement, final int maxResults, final Sequence sequence, final FeatureType type) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) throws HibernateException, SQLException { return session.createCriteria(getPersistentClass()).add(Restrictions.eq("sequence", sequence)) .add(Restrictions.eq("type", type)).setFirstResult(firstElement).setMaxResults(maxResults) .addOrder(Order.asc("id")).list(); } }); } public List<Feature> findBySequence(final Sequence sequence, final Order... order) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) throws HibernateException, SQLException { Criteria crit = session.createCriteria(getPersistentClass()) .add(Restrictions.eq("sequence", sequence)); addOrders(crit, order); return crit.list(); } }); } public List<Feature> findBySequenceAndType(final Sequence sequence, final FeatureType type, final boolean minimal) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) throws HibernateException, SQLException { Criteria crit = session.createCriteria(getPersistentClass()) .add(Restrictions.eq("sequence", sequence)).add(Restrictions.eq("type", type)); if (minimal) { crit.setProjection(Projections.projectionList().add(Projections.id(), "id") .add(Projections.property("version"), "version")) .setResultTransformer(Transformers.aliasToBean(getPersistentClass())); } return crit.list(); } }); } public Feature findBySequenceAndLocus(final Sequence sequence, String locusTag, final boolean minimal) throws FeatureException { Pattern p = Pattern.compile("^\\D+(\\d+)$"); Matcher m = p.matcher(locusTag); if (!m.matches()) { throw new FeatureException("LocusTag [" + locusTag + "] does not conform to pattern [\\D+\\d+]"); } final Integer rank = Integer.parseInt(m.group(1)) - 1; return getHibernateTemplate().execute(new HibernateCallback<Feature>() { public Feature doInHibernate(Session session) throws HibernateException, SQLException { Criteria crit = session.createCriteria(getPersistentClass()) .add(Restrictions.eq("sequence", sequence)).add(Restrictions.eq("rank", rank)); if (minimal) { crit.setProjection(Projections.projectionList().add(Projections.id(), "id") .add(Projections.property("version"), "version")) .setResultTransformer(Transformers.aliasToBean(getPersistentClass())); } return (Feature) crit.uniqueResult(); } }); } public Long countBySequence(final Sequence sequence) { return getHibernateTemplate().execute(new HibernateCallback<Long>() { public Long doInHibernate(Session session) throws HibernateException, SQLException { return (Long) session.createCriteria(getPersistentClass()) .add(Restrictions.eq("sequence", sequence)).setProjection(Projections.rowCount()) .uniqueResult(); } }); } public Long countBySequence(final Integer sequenceId) { return getHibernateTemplate().execute(new HibernateCallback<Long>() { public Long doInHibernate(Session session) throws HibernateException, SQLException { return (Long) session.createCriteria(getPersistentClass()).createAlias("sequence", "seq") .add(Restrictions.eq("seq.id", sequenceId)).setProjection(Projections.rowCount()) .uniqueResult(); } }); } public Long countBySequenceAndType(final Sequence sequence, final FeatureType type) { Object count = getHibernateTemplate().execute(new HibernateCallback<Long>() { public Long doInHibernate(Session session) throws HibernateException, SQLException { return (Long) session.createCriteria(getPersistentClass()) .add(Restrictions.eq("sequence", sequence)).add(Restrictions.eq("type", type)) .setProjection(Projections.rowCount()).uniqueResult(); } }); return (Long) count; } public Feature findByOldId(Integer oldId) { return findUniqueByCriteria(Restrictions.eq("oldId", oldId)); } public void saveIfNew(final Sequence sequence, final Feature feature) { getHibernateTemplate().execute(new HibernateCallback<Object>() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Location l = feature.getLocation(); Long count = (Long) session.createCriteria(getPersistentClass()) .add(Restrictions.eq("sequence", sequence)) .add(Restrictions.eq("location.start", l.getStart())) .add(Restrictions.eq("location.end", l.getEnd())) .add(Restrictions.eq("location.frame", l.getFrame())) .add(Restrictions.eq("location.strand", l.getStrand())) .setProjection(Projections.rowCount()).uniqueResult(); if (count == 0) { feature.setSequence(sequence); saveOrUpdate(feature); } return null; } }); } public Feature loadWithData(final Integer id) { return getHibernateTemplate().execute(new HibernateCallback<Feature>() { public Feature doInHibernate(Session session) throws HibernateException, SQLException { return (Feature) session.createCriteria(getPersistentClass()).setFetchMode("data", FetchMode.JOIN) .add(Restrictions.idEq(id)).uniqueResult(); } }); } public List<Feature> loadWithData(final List<Feature> features) { return getHibernateTemplate().execute(new HibernateCallback<List<Feature>>() { @SuppressWarnings("unchecked") public List<Feature> doInHibernate(Session session) throws HibernateException, SQLException { List<Integer> ids = new ArrayList<Integer>(); for (Feature f : features) { Integer id = f.getId(); ids.add(id); } return session.createCriteria(getPersistentClass()).setFetchMode("data", FetchMode.JOIN) .add(Restrictions.in("id", ids)).list(); } }); } @SuppressWarnings("unchecked") public List<Feature> findBySampleAndAnnotator(final Sample sample, final Annotator annotator) { Object result = getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { return session.createCriteria(getPersistentClass()).createAlias("annotations", "an") .createAlias("sequence", "seq").add(Restrictions.eq("seq.sample", sample)) .add(Restrictions.eq("an.annotator", annotator)) .add(Restrictions.isNotNull("an.description")).list(); } }); return (List<Feature>) result; } @SuppressWarnings("unchecked") public List<Feature> findOnlyNew(final Collection<Feature> features) { Object result = getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { List<Feature> newFeatures = new ArrayList<Feature>(); for (Feature f : features) { Location loc = f.getLocation(); Long count = (Long) session.createCriteria(getPersistentClass()) .add(Restrictions.eq("sequence", f.getSequence())) .add(Restrictions.eq("location.start", loc.getStart())) .add(Restrictions.eq("location.end", loc.getEnd())) .add(Restrictions.eq("location.strand", loc.getStrand())) .add(Restrictions.eq("location.frame", loc.getFrame())) .setProjection(Projections.rowCount()).uniqueResult(); if (count == 0) { newFeatures.add(f); } } return newFeatures; } }); return (List<Feature>) result; } /** * Build a list of Features for each FeatureType where only independent features * are reported. Here, independent features of a given type are those from different * detectors which do not possess any overlap in genomic coordinates. Conflicts * are resolved by consideration of the assigned rank of each detector for * a given FeatureType. */ @SuppressWarnings("unchecked") public List<Feature> findResolvedSet(final Sequence sequence, final FeatureType restrictedToType) { Object result = getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { List<Feature> features = new ArrayList<Feature>(); /* Get the list of FeatureTypes contained in this sequence, * subsequent processing will be done per type. */ Criteria crit = session.createCriteria(getPersistentClass()) .add(Restrictions.eq("sequence", sequence)) .setProjection(Projections.projectionList().add(Projections.groupProperty("type"))); if (restrictedToType != null) { crit.add(Restrictions.eq("type", restrictedToType)); } List<FeatureType> featTypes = (List<FeatureType>) crit.list(); for (FeatureType ft : featTypes) { /* For the given FeatureType, get the list of detectors * that have been used on this sequence and order them * by assigned rank. Higher rank == higher precedence. * In cases where ranks are equal, it is resolved by * alphabetic reference to their unique names. */ List<Object[]> detectors = (List<Object[]>) session.createCriteria(getPersistentClass()) .createAlias("detector", "det").setFetchMode("detector", FetchMode.JOIN) .add(Restrictions.eq("sequence", sequence)).add(Restrictions.eq("type", ft)) .addOrder(Order.desc("det.rank")).addOrder(Order.asc("det.name")) .setProjection(Projections.projectionList().add(Projections.groupProperty("detector")) .add(Projections.groupProperty("det.name")) .add(Projections.groupProperty("det.rank"))) .list(); List<Feature> independentFeaturesOfType = new ArrayList<Feature>(); for (Object[] row : detectors) { /* Get the features determined by the given detector. We * add the FeatureType here since there might be a case * where a detector can generate multiple FeatureTypes. * * This possibility becomes more likely when there are * many finely grained types. */ Detector detector = (Detector) row[0]; List<Feature> featuresOfDetector = (List<Feature>) session .createCriteria(getPersistentClass()).add(Restrictions.eq("sequence", sequence)) .add(Restrictions.eq("detector", detector)).add(Restrictions.eq("type", ft)).list(); for (Feature df : featuresOfDetector) { boolean independent = true; for (Feature ndf : independentFeaturesOfType) { if (!df.getDetector().equals(ndf.getDetector()) && !df.getLocation().independent(ndf.getLocation())) { independent = false; break; } } if (independent) { independentFeaturesOfType.add(df); } } } features.addAll(independentFeaturesOfType); } return Feature.sortAscendingStart(features); } }); return (List<Feature>) result; } public List<Object[]> findPageRowsBySequence(final int sequenceId, final int firstResult, final int maxResults, final int sortFieldIndex, final String sortDirection) { return getHibernateTemplate().execute(new HibernateCallback<List<Object[]>>() { @SuppressWarnings("unchecked") public List<Object[]> doInHibernate(Session session) throws HibernateException, SQLException { return session.createQuery( " SELECT f.id, f.location.start, f.location.end, f.location.strand, f.location.frame, f.partial, f.confidence, f.type, " + " f.location.length, (SELECT count(*) from f.annotations) " + " FROM Feature f " + " WHERE " + " f.sequence.id = :sequenceId" + " ORDER BY " + String.format("col_%d_0_ %s", sortFieldIndex, sortDirection)) .setFirstResult(firstResult).setMaxResults(maxResults) .setParameter("sequenceId", sequenceId).list(); } }); } public static class FeatureBreakdownDTO implements Serializable { private static final long serialVersionUID = -26450120355021044L; private FeatureType type; private Long count; public FeatureType getType() { return type; } public void setType(FeatureType type) { this.type = type; } public Long getCount() { return count; } public void setCount(Long count) { this.count = count; } } public List<FeatureBreakdownDTO> findTypeBreakdown(final Integer sequenceId) { return getHibernateTemplate().execute(new HibernateCallback<List<FeatureBreakdownDTO>>() { @SuppressWarnings("unchecked") public List<FeatureBreakdownDTO> doInHibernate(Session session) throws HibernateException, SQLException { return session.createCriteria(getPersistentClass()).createAlias("sequence", "seq") .add(Restrictions.eq("seq.id", sequenceId)) .setProjection(Projections.projectionList().add(Projections.groupProperty("type"), "type") .add(Projections.rowCount(), "count")) .addOrder(Order.asc("type")) .setResultTransformer(Transformers.aliasToBean(FeatureBreakdownDTO.class)).list(); } }); } }