⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fromclause.java

📁 一个Java持久层类库
💻 JAVA
字号:
// $Id: FromClause.java 10172 2006-07-26 18:01:49Z steve.ebersole@jboss.com $package org.hibernate.hql.ast.tree;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Set;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.hibernate.hql.antlr.HqlSqlTokenTypes;import org.hibernate.hql.ast.util.ASTIterator;import org.hibernate.hql.ast.util.ASTUtil;import antlr.SemanticException;import antlr.collections.AST;/** * Represents the 'FROM' part of a query or subquery, containing all mapped class references. * * @author josh */public class FromClause extends HqlSqlWalkerNode implements HqlSqlTokenTypes, DisplayableNode {	private static Logger log = LoggerFactory.getLogger( FromClause.class );	public static final int ROOT_LEVEL = 1;	private int level = ROOT_LEVEL;	private Set fromElements = new HashSet();	private Map fromElementByClassAlias = new HashMap();	private Map fromElementByTableAlias = new HashMap();	private Map fromElementsByPath = new HashMap();	/**	 * 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 Map collectionJoinFromElementsByPath = new HashMap();	/**	 * Pointer to the parent FROM clause, if there is one.	 */	private FromClause parentFromClause;	/**	 * Collection of FROM clauses of which this is the parent.	 */	private Set childFromClauses;	/**	 * Counts the from elements as they are added.	 */	private int fromElementCounter = 0;	/**	 * Implied FROM elements to add onto the end of the FROM clause.	 */	private List impliedElements = new LinkedList();	/**	 * 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.	 */	public FromElement addFromElement(String path, AST alias) throws SemanticException {		// 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();	}	void registerFromElement(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 );		}	}	void addDuplicateAlias(String alias, FromElement element) {		if ( alias != null ) {			fromElementByClassAlias.put( alias, element );		}	}	private void checkForDuplicateClassAlias(String classAlias) throws SemanticException {		if ( classAlias != null && fromElementByClassAlias.containsKey( classAlias ) ) {			throw new SemanticException( "Duplicate definition of alias '" + classAlias + "'" );		}	}	/**	 * 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.	 */	public FromElement getFromElement(String aliasOrClassName) {		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;	}	private FromElement findIntendedAliasedFromElementBasedOnCrazyJPARequirements(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;	}	/**	 * 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.	 */	public boolean isFromElementAlias(String possibleAlias) {		boolean isAlias = containsClassAlias( possibleAlias );		if ( !isAlias && parentFromClause != null ) {			// try the parent FromClause...			isAlias = parentFromClause.isFromElementAlias( possibleAlias );		}		return isAlias;	}	/**	 * Returns the list of from elements in order.	 *	 * @return the list of from elements (instances of FromElement).	 */	public List getFromElements() {		return ASTUtil.collectChildren( this, fromElementPredicate );	}		public FromElement getFromElement() {		// 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);	}	/**	 * 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.	 */	public List getProjectionList() {		return ASTUtil.collectChildren( this, projectionListPredicate );	}	public List getCollectionFetches() {		return ASTUtil.collectChildren( this, collectionFetchPredicate );	}	public boolean hasCollectionFecthes() {		return getCollectionFetches().size() > 0;	}	public List getExplicitFromElements() {		return ASTUtil.collectChildren( this, explicitFromPredicate );	}	private static ASTUtil.FilterPredicate fromElementPredicate = new ASTUtil.IncludePredicate() {		public boolean include(AST node) {			FromElement fromElement = ( FromElement ) node;			return fromElement.isFromOrJoinFragment();		}	};	private static ASTUtil.FilterPredicate projectionListPredicate = new ASTUtil.IncludePredicate() {		public boolean include(AST node) {			FromElement fromElement = ( FromElement ) node;			return fromElement.inProjectionList();		}	};	private static ASTUtil.FilterPredicate collectionFetchPredicate = new ASTUtil.IncludePredicate() {		public boolean include(AST node) {			FromElement fromElement = ( FromElement ) node;			return fromElement.isFetch() && fromElement.getQueryableCollection() != null;		}	};	private static ASTUtil.FilterPredicate explicitFromPredicate = new ASTUtil.IncludePredicate() {		public boolean include(AST node) {			final FromElement fromElement = ( FromElement ) node;			return !fromElement.isImplied();		}	};	FromElement findCollectionJoin(String path) {		return ( FromElement ) collectionJoinFromElementsByPath.get( path );	}	/**	 * Look for an existing implicit or explicit join by the	 * given path.	 */	FromElement findJoinByPath(String path) {		FromElement elem = findJoinByPathLocal( path );		if ( elem == null && parentFromClause != null ) {			elem = parentFromClause.findJoinByPath( path );		}		return elem;	}	FromElement findJoinByPathLocal(String path) {		Map joinsByPath = fromElementsByPath;		return ( FromElement ) joinsByPath.get( path );	}	void addJoinByPathMap(String path, FromElement destination) {		if ( log.isDebugEnabled() ) {			log.debug( "addJoinByPathMap() : " + path + " -> " + destination );		}		fromElementsByPath.put( path, destination );	}	/**	 * 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.	 */	public boolean containsClassAlias(String alias) {		boolean isAlias = fromElementByClassAlias.containsKey( alias );		if ( !isAlias && getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() ) {			isAlias = findIntendedAliasedFromElementBasedOnCrazyJPARequirements( alias ) != null;		}		return isAlias;	}	/**	 * 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.	 */	public boolean containsTableAlias(String alias) {		return fromElementByTableAlias.keySet().contains( alias );	}	public String getDisplayText() {		return "FromClause{" +				"level=" + level +				", fromElementCounter=" + fromElementCounter +				", fromElements=" + fromElements.size() +				", fromElementByClassAlias=" + fromElementByClassAlias.keySet() +				", fromElementByTableAlias=" + fromElementByTableAlias.keySet() +				", fromElementsByPath=" + fromElementsByPath.keySet() +				", collectionJoinFromElementsByPath=" + collectionJoinFromElementsByPath.keySet() +				", impliedElements=" + impliedElements +				"}";	}	public void setParentFromClause(FromClause parentFromClause) {		this.parentFromClause = parentFromClause;		if ( parentFromClause != null ) {			level = parentFromClause.getLevel() + 1;			parentFromClause.addChild( this );		}	}	private void addChild(FromClause fromClause) {		if ( childFromClauses == null ) {			childFromClauses = new HashSet();		}		childFromClauses.add( fromClause );	}	public FromClause locateChildFromClauseWithJoinByPath(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 void promoteJoin(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	}	public boolean isSubQuery() {		// TODO : this is broke for subqueries in statements other than selects...		return parentFromClause != null;	}	void addCollectionJoinFromElementByPath(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.	}	public FromClause getParentFromClause() {		return parentFromClause;	}	public int getLevel() {		return level;	}	public int nextFromElementCounter() {		return fromElementCounter++;	}	public void resolve() {		// 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 void addImpliedFromElement(FromElement element) {		impliedElements.add( element );	}	public String toString() {		return "FromClause{" +				"level=" + level +				"}";	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -