Open Source Repository

Home /hibernate/hibernate-3.2.4.ga | Repository Home


org/hibernate/criterion/SubqueryExpression.java
//$Id: SubqueryExpression.java 7365 2005-07-04 02:40:29Z oneovthafew $
package org.hibernate.criterion;

import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.TypedValue;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.loader.criteria.CriteriaQueryTranslator;
import org.hibernate.persister.entity.OuterJoinLoadable;
import org.hibernate.sql.Select;
import org.hibernate.type.Type;

/**
 @author Gavin King
 */
public abstract class SubqueryExpression implements Criterion {
  
  private CriteriaImpl criteriaImpl;
  private String quantifier;
  private String op;
  private QueryParameters params;
  private Type[] types;
  
  protected Type[] getTypes() {
    return types;
  }
  
  protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc) {
    this.criteriaImpl = dc.getCriteriaImpl();
    this.quantifier = quantifier;
    this.op = op;
  }
  
  protected abstract String toLeftSqlString(Criteria criteria, CriteriaQuery outerQuery);

  public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
  throws HibernateException {
    
    final SessionImplementor session = ( (CriteriaImplcriteria ).getSession()//ugly!
    final SessionFactoryImplementor factory = session.getFactory();
    
    final OuterJoinLoadable persister = (OuterJoinLoadablefactory.getEntityPersistercriteriaImpl.getEntityOrClassName() );
    CriteriaQueryTranslator innerQuery = new CriteriaQueryTranslator
        factory, 
        criteriaImpl, 
        criteriaImpl.getEntityOrClassName()//implicit polymorphism not supported (would need a union) 
        criteriaQuery.generateSQLAlias(),
        criteriaQuery
      );
    
    params = innerQuery.getQueryParameters()//TODO: bad lifecycle....
    types = innerQuery.getProjectedTypes();
    
    //String filter = persister.filterFragment( innerQuery.getRootSQLALias(), session.getEnabledFilters() );
    
    String sql = new Selectfactory.getDialect() )
      .setWhereClauseinnerQuery.getWhereCondition() )
      .setGroupByClauseinnerQuery.getGroupBy() )
      .setSelectClauseinnerQuery.getSelect() )
      .setFromClause(
          persister.fromTableFragmentinnerQuery.getRootSQLALias() ) +   
          persister.fromJoinFragmentinnerQuery.getRootSQLALias(), true, false )
        )
      .toStatementString();
    
    final StringBuffer buf = new StringBuffer()
      .appendtoLeftSqlString(criteria, criteriaQuery) );
    if (op!=nullbuf.append(' ').append(op).append(' ');
    if (quantifier!=nullbuf.append(quantifier).append(' ');
    return buf.append('(').append(sql).append(')')
      .toString();
  }

  public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery
  throws HibernateException {
    Type[] types = params.getPositionalParameterTypes();
    Object[] values = params.getPositionalParameterValues();
    TypedValue[] tv = new TypedValue[types.length];
    for int i=0; i<types.length; i++ ) {
      tv[inew TypedValuetypes[i], values[i], EntityMode.POJO );
    }
    return tv;
  }

}