/* * EuroCarbDB, a framework for carbohydrate bioinformatics * * Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * A copy of this license accompanies this distribution in the file LICENSE.txt. * * This program 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 Lesser General Public License * for more details. * * Last commit: $Rev: 1541 $ by $Author: glycoslave $ on $Date:: 2009-07-17 #$ */ package org.eurocarbdb.dataaccess.indexes; // stdlib imports import java.util.Map; import java.util.List; import java.util.HashMap; import java.util.ArrayList; import java.util.Comparator; import java.util.Collections; // 3rd party imports // eurocarb imports import org.eurocarbdb.dataaccess.Contributed; import org.eurocarbdb.dataaccess.EurocarbObject; import org.eurocarbdb.dataaccess.core.GlycanSequence; import org.eurocarbdb.dataaccess.core.GlycanSequenceEvidence; import org.hibernate.Criteria; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.CriteriaQuery; import org.hibernate.transform.PassThroughResultTransformer; // static imports import static org.hibernate.criterion.CriteriaSpecification.LEFT_JOIN; import static org.eurocarbdb.dataaccess.Eurocarb.getEntityManager; import static org.eurocarbdb.dataaccess.hibernate.HibernateUtils.RETURN_FIRST_COLUMN_ONLY; /** * Allows the sorting and comparison of {@link GlycanSequence}s by least/most * items of associated {@link Evidence}. * * @see GlycanSequence.getEvidenceCount * @see GlycanSequenceEvidence * * @author mjh * @version $Rev: 1541 $ */ public class IndexByMostEvidence<T extends GlycanSequence> implements Index<T> { public void apply( Criteria query ) { /* * the query for this index requires a horrible hibernate hack. * basically, the incoming Criteria query depends on an SQL * 'group by', which, due to Hibernate limitations, screws over * the select clause. So, we attach a results transformer to the * query that post-processes the result set from a list of * GlycanSequence ids into GlycanSequence objects through a * separate query. */ query .createAlias("glycanEvidence", "gs2ev", LEFT_JOIN ) .setProjection( Projections.projectionList() .add( Projections.groupProperty("glycanSequenceId") ) .add( Projections.count( "gs2ev.evidence" ).as( "ev" ) ) ) .addOrder( Order.desc("ev") ) .setResultTransformer( new PassThroughResultTransformer() { public List transformList( List results ) { if ( results == null || results.size() == 0 ) return results; List<Object[]> rows = (List<Object[]>) results; // the lookup hash Map<Integer,GlycanSequence> hash = new HashMap<Integer,GlycanSequence>( results.size() ); // gather the sequence ids List<Integer> ids = new ArrayList<Integer>( results.size() ); for ( Object[] columns : rows ) ids.add( (Integer) columns[0] ); // look them up List<GlycanSequence> seqs = (List<GlycanSequence>) getEntityManager() .createQuery( GlycanSequence.class ) .add( Restrictions.in( "glycanSequenceId", ids ) ) .setFetchSize( ids.size() ) // .setCacheable( true ) .list() ; for ( GlycanSequence seq : seqs ) hash.put( seq.getGlycanSequenceId(), seq ); seqs.clear(); for ( Integer id : ids ) seqs.add( hash.get( id ) ); return seqs; } /* public Object transformTuple( Object[] tuple, String[] aliases ) { int id = (Integer) tuple[0]; return getEntityManager().lookup( GlycanSequence.class, id ); } */ } ) ; /* // attempt 2 query .createAlias("glycanEvidence", "gs2ev", LEFT_JOIN ) .addOrder( new Order( "irrelevant", false ) { public final String toSqlString( Criteria c, CriteriaQuery q ) { // return "count( gs2ev.evidence_id ) desc"; return "count( " + "gs2ev1_"//q.getSQLAlias( query, "glycanEvidence" ) + ".evidence_id ) desc"; } } ) ; */ /* // attempt 3 query .createAlias("glycanEvidence", "gs2ev", LEFT_JOIN ) .setProjection( Projections.groupProperty("glycanSequenceId").as("glycanSequenceId") ) .addOrder( new Order( "irrelevant", false ) { public final String toSqlString( Criteria c, CriteriaQuery q ) { // return "count( gs2ev.evidence_id ) desc"; return "count( " + "gs2ev1_"//q.getSQLAlias( query, "glycanEvidence" ) + ".evidence_id ) desc"; } } ) .setResultTransformer( org.hibernate.transform.Transformers.aliasToBean( GlycanSequence.class ) ) ; */ } public void apply( List<T> results ) { Collections.sort( results, this ); } public int compare( T seq1, T seq2 ) { int i1 = seq1.getEvidenceCount(); int i2 = seq2.getEvidenceCount(); return (i1 > i2) ? 1 : (i1 < i2) ? -1 : 0; } public Class<GlycanSequence> getIndexableType() { return GlycanSequence.class; } /** Returns "evidence". */ public String getName() { return "evidence"; } /** Returns "Amount of evidence". */ public String getTitle() { return "Amount of evidence"; } public String getDescription() { return "Orders results by most to least items of evidence"; } }