Open Source Repository

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


org/hibernate/hql/classic/ClauseParser.java
//$Id: ClauseParser.java 4907 2004-12-08 00:24:14Z oneovthafew $
package org.hibernate.hql.classic;

import org.hibernate.QueryException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Parses the Hibernate query into its constituent clauses.
 */
public class ClauseParser implements Parser {

  private Parser child;
  private List selectTokens;
  private boolean cacheSelectTokens = false;
  private boolean byExpected = false;
  private int parenCount = 0;

  public void token(String token, QueryTranslatorImpl qthrows QueryException {
    String lcToken = token.toLowerCase();

    if "(".equalstoken ) ) {
      parenCount++;
    }
    else if ")".equalstoken ) ) {
      parenCount--;
    }

    if byExpected && !lcToken.equals"by" ) ) {
      throw new QueryException"BY expected after GROUP or ORDER: " + token );
    }

    boolean isClauseStart = parenCount == 0//ignore subselect keywords

    if isClauseStart ) {
      if lcToken.equals"select" ) ) {
        selectTokens = new ArrayList();
        cacheSelectTokens = true;
      }
      else if lcToken.equals"from" ) ) {
        child = new FromParser();
        child.start);
        cacheSelectTokens = false;
      }
      else if lcToken.equals"where" ) ) {
        endChild);
        child = new WhereParser();
        child.start);
      }
      else if lcToken.equals"order" ) ) {
        endChild);
        child = new OrderByParser();
        byExpected = true;
      }
      else if lcToken.equals"having" ) ) {
        endChild);
        child = new HavingParser();
        child.start);
      }
      else if lcToken.equals"group" ) ) {
        endChild);
        child = new GroupByParser();
        byExpected = true;
      }
      else if lcToken.equals"by" ) ) {
        if !byExpected throw new QueryException"GROUP or ORDER expected before BY" );
        child.start);
        byExpected = false;
      }
      else {
        isClauseStart = false;
      }
    }

    if !isClauseStart ) {
      if cacheSelectTokens ) {
        selectTokens.addtoken );
      }
      else {
        if child == null ) {
          throw new QueryException"query must begin with SELECT or FROM: " + token );
        }
        else {
          child.tokentoken, q );
        }
      }
    }

  }

  private void endChild(QueryTranslatorImpl qthrows QueryException {
    if child == null ) {
      //null child could occur for no from clause in a filter
      cacheSelectTokens = false;
    }
    else {
      child.end);
    }
  }

  public void start(QueryTranslatorImpl q) {
  }

  public void end(QueryTranslatorImpl qthrows QueryException {
    endChild);
    if selectTokens != null ) {
      child = new SelectParser();
      child.start);
      Iterator iter = selectTokens.iterator();
      while iter.hasNext() ) {
        token( ( String iter.next(), q );
      }
      child.end);
    }
    byExpected = false;
    parenCount = 0;
    cacheSelectTokens = false;
  }

}