FileDocCategorySizeDatePackage
FromClause.javaAPI DocHibernate 3.2.511990Wed Jul 26 13:04:08 BST 2006org.hibernate.hql.ast.tree

FromClause

public class FromClause extends HqlSqlWalkerNode implements org.hibernate.hql.antlr.HqlSqlTokenTypes, DisplayableNode
Represents the 'FROM' part of a query or subquery, containing all mapped class references.
author
josh

Fields Summary
private static Log
log
public static final int
ROOT_LEVEL
private int
level
private Set
fromElements
private Map
fromElementByClassAlias
private Map
fromElementByTableAlias
private Map
fromElementsByPath
private Map
collectionJoinFromElementsByPath
All of the implicit FROM xxx JOIN yyy elements that are the destination of a collection. These are created from index operators on collection property references.
private FromClause
parentFromClause
Pointer to the parent FROM clause, if there is one.
private Set
childFromClauses
Collection of FROM clauses of which this is the parent.
private int
fromElementCounter
Counts the from elements as they are added.
private List
impliedElements
Implied FROM elements to add onto the end of the FROM clause.
private static ASTUtil.FilterPredicate
fromElementPredicate
private static ASTUtil.FilterPredicate
projectionListPredicate
private static ASTUtil.FilterPredicate
collectionFetchPredicate
private static ASTUtil.FilterPredicate
explicitFromPredicate
Constructors Summary
Methods Summary
private voidaddChild(org.hibernate.hql.ast.tree.FromClause fromClause)

		if ( childFromClauses == null ) {
			childFromClauses = new HashSet();
		}
		childFromClauses.add( fromClause );
	
voidaddCollectionJoinFromElementByPath(java.lang.String path, FromElement destination)

		if ( log.isDebugEnabled() ) {
			log.debug( "addCollectionJoinFromElementByPath() : " + path + " -> " + destination );
		}
		collectionJoinFromElementsByPath.put( path, destination );	// Add the new node to the map so that we don't create it twice.
	
voidaddDuplicateAlias(java.lang.String alias, FromElement element)

		fromElementByClassAlias.put( alias, element );
	
public FromElementaddFromElement(java.lang.String path, antlr.collections.AST alias)
Adds a new from element to the from node.

param
path The reference to the class.
param
alias The alias AST.
return
FromElement - The new FROM element.


	                             	 
	        
		// The path may be a reference to an alias defined in the parent query.
		String classAlias = ( alias == null ) ? null : alias.getText();
		checkForDuplicateClassAlias( classAlias );
		FromElementFactory factory = new FromElementFactory( this, null, path, classAlias, null, false );
		return factory.addFromElement();
	
public voidaddImpliedFromElement(FromElement element)

		impliedElements.add( element );
	
voidaddJoinByPathMap(java.lang.String path, FromElement destination)

		if ( log.isDebugEnabled() ) {
			log.debug( "addJoinByPathMap() : " + path + " -> " + destination );
		}
		fromElementsByPath.put( path, destination );
	
private voidcheckForDuplicateClassAlias(java.lang.String classAlias)

		if ( classAlias != null && fromElementByClassAlias.containsKey( classAlias ) ) {
			throw new SemanticException( "Duplicate definition of alias '"
					+ classAlias + "'" );
		}
	
public booleancontainsClassAlias(java.lang.String alias)
Returns true if the from node contains the class alias name.

param
alias The HQL class alias name.
return
true if the from node contains the class alias name.

		boolean isAlias = fromElementByClassAlias.containsKey( alias );
		if ( !isAlias && getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() ) {
			isAlias = findIntendedAliasedFromElementBasedOnCrazyJPARequirements( alias ) != null;
		}
		return isAlias;
	
public booleancontainsTableAlias(java.lang.String alias)
Returns true if the from node contains the table alias name.

param
alias The SQL table alias name.
return
true if the from node contains the table alias name.

		return fromElementByTableAlias.keySet().contains( alias );
	
FromElementfindCollectionJoin(java.lang.String path)


	   
		return ( FromElement ) collectionJoinFromElementsByPath.get( path );
	
private FromElementfindIntendedAliasedFromElementBasedOnCrazyJPARequirements(java.lang.String specifiedAlias)

		Iterator itr = fromElementByClassAlias.entrySet().iterator();
		while ( itr.hasNext() ) {
			Map.Entry entry = ( Map.Entry ) itr.next();
			String alias = ( String ) entry.getKey();
			if ( alias.equalsIgnoreCase( specifiedAlias ) ) {
				return ( FromElement ) entry.getValue();
			}
		}
		return null;
	
FromElementfindJoinByPath(java.lang.String path)
Look for an existing implicit or explicit join by the given path.

		FromElement elem = findJoinByPathLocal( path );
		if ( elem == null && parentFromClause != null ) {
			elem = parentFromClause.findJoinByPath( path );
		}
		return elem;
	
FromElementfindJoinByPathLocal(java.lang.String path)

		Map joinsByPath = fromElementsByPath;
		return ( FromElement ) joinsByPath.get( path );
	
public java.util.ListgetCollectionFetches()

		return ASTUtil.collectChildren( this, collectionFetchPredicate );
	
public java.lang.StringgetDisplayText()

		return "FromClause{" +
				"level=" + level +
				", fromElementCounter=" + fromElementCounter +
				", fromElements=" + fromElements.size() +
				", fromElementByClassAlias=" + fromElementByClassAlias.keySet() +
				", fromElementByTableAlias=" + fromElementByTableAlias.keySet() +
				", fromElementsByPath=" + fromElementsByPath.keySet() +
				", collectionJoinFromElementsByPath=" + collectionJoinFromElementsByPath.keySet() +
				", impliedElements=" + impliedElements +
				"}";
	
public java.util.ListgetExplicitFromElements()

		return ASTUtil.collectChildren( this, explicitFromPredicate );
	
public FromElementgetFromElement(java.lang.String aliasOrClassName)
Retreives the from-element represented by the given alias.

param
aliasOrClassName The alias by which to locate the from-element.
return
The from-element assigned the given alias, or null if none.

		FromElement fromElement = ( FromElement ) fromElementByClassAlias.get( aliasOrClassName );
		if ( fromElement == null && getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() ) {
			fromElement = findIntendedAliasedFromElementBasedOnCrazyJPARequirements( aliasOrClassName );
		}
		if ( fromElement == null && parentFromClause != null ) {
			fromElement = parentFromClause.getFromElement( aliasOrClassName );
		}
		return fromElement;
	
public FromElementgetFromElement()

		// TODO: not sure about this one
//		List fromElements = getFromElements();
//		if ( fromElements == null || fromElements.isEmpty() ) {
//			throw new QueryException( "Unable to locate from element" );
//		}
		return (FromElement) getFromElements().get(0);
	
public java.util.ListgetFromElements()
Returns the list of from elements in order.

return
the list of from elements (instances of FromElement).

		return ASTUtil.collectChildren( this, fromElementPredicate );
	
public intgetLevel()

		return level;
	
public org.hibernate.hql.ast.tree.FromClausegetParentFromClause()

		return parentFromClause;
	
public java.util.ListgetProjectionList()
Returns the list of from elements that will be part of the result set.

return
the list of from elements that will be part of the result set.

		return ASTUtil.collectChildren( this, projectionListPredicate );
	
public booleanhasCollectionFecthes()

		return getCollectionFetches().size() > 0;
	
public booleanisFromElementAlias(java.lang.String possibleAlias)
Convenience method to check whether a given token represents a from-element alias.

param
possibleAlias The potential from-element alias to check.
return
True if the possibleAlias is an alias to a from-element visible from this point in the query graph.

		boolean isAlias = containsClassAlias( possibleAlias );
		if ( !isAlias && parentFromClause != null ) {
			// try the parent FromClause...
			isAlias = parentFromClause.isFromElementAlias( possibleAlias );
		}
		return isAlias;
	
public booleanisSubQuery()

		// TODO : this is broke for subqueries in statements other than selects...
		return parentFromClause != null;
	
public org.hibernate.hql.ast.tree.FromClauselocateChildFromClauseWithJoinByPath(java.lang.String path)

		if ( childFromClauses != null && !childFromClauses.isEmpty() ) {
			Iterator children = childFromClauses.iterator();
			while ( children.hasNext() ) {
				FromClause child = ( FromClause ) children.next();
				if ( child.findJoinByPathLocal( path ) != null ) {
					return child;
				}
			}
		}
		return null;
	
public intnextFromElementCounter()

		return fromElementCounter++;
	
public voidpromoteJoin(FromElement elem)

		if ( log.isDebugEnabled() ) {
			log.debug( "Promoting [" + elem + "] to [" + this + "]" );
		}
		//TODO: implement functionality
		//  this might be painful to do here, as the "join post processing" for
		//  the subquery has already been performed (meaning that for
		//  theta-join dialects, the join conditions have already been moved
		//  over to the where clause).  A "simple" solution here might to
		//  perform "join post processing" once for the entire query (including
		//  any subqueries) at one fell swoop
	
voidregisterFromElement(FromElement element)

		fromElements.add( element );
		String classAlias = element.getClassAlias();
		if ( classAlias != null ) {
			// The HQL class alias refers to the class name.
			fromElementByClassAlias.put( classAlias, element );
		}
		// Associate the table alias with the element.
		String tableAlias = element.getTableAlias();
		if ( tableAlias != null ) {
			fromElementByTableAlias.put( tableAlias, element );
		}
	
public voidresolve()

		// Make sure that all from elements registered with this FROM clause are actually in the AST.
		ASTIterator iter = new ASTIterator( this.getFirstChild() );
		Set childrenInTree = new HashSet();
		while ( iter.hasNext() ) {
			childrenInTree.add( iter.next() );
		}
		for ( Iterator iterator = fromElements.iterator(); iterator.hasNext(); ) {
			FromElement fromElement = ( FromElement ) iterator.next();
			if ( !childrenInTree.contains( fromElement ) ) {
				throw new IllegalStateException( "Element not in AST: " + fromElement );
			}
		}
	
public voidsetParentFromClause(org.hibernate.hql.ast.tree.FromClause parentFromClause)

		this.parentFromClause = parentFromClause;
		if ( parentFromClause != null ) {
			level = parentFromClause.getLevel() + 1;
			parentFromClause.addChild( this );
		}
	
public java.lang.StringtoString()

		return "FromClause{" +
				"level=" + level +
				"}";