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

📄 fromelementfactory.java

📁 好东西,hibernate-3.2.0,他是一开元的树杖hibernate-3.2.0
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// $Id: FromElementFactory.java 9586 2006-03-09 21:11:44Z steve.ebersole@jboss.com $
package org.hibernate.hql.ast.tree;

import org.hibernate.engine.JoinSequence;
import org.hibernate.hql.antlr.SqlTokenTypes;
import org.hibernate.hql.ast.util.ASTUtil;
import org.hibernate.hql.ast.util.AliasGenerator;
import org.hibernate.hql.ast.util.PathHelper;
import org.hibernate.hql.ast.util.SessionFactoryHelper;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Joinable;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.sql.JoinFragment;
import org.hibernate.type.AssociationType;
import org.hibernate.type.CollectionType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.util.StringHelper;

import antlr.ASTFactory;
import antlr.SemanticException;
import antlr.collections.AST;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Encapsulates the creation of FromElements and JoinSequences.
 *
 * @author josh Oct 12, 2004 4:54:25 AM
 */
class FromElementFactory implements SqlTokenTypes {

	private static final Log log = LogFactory.getLog( FromElementFactory.class );

	private FromClause fromClause;
	private FromElement origin;
	private String path;

	private String classAlias;
	private String[] columns;
	private boolean implied;
	private boolean inElementsFunction;
	private boolean collection;
	private QueryableCollection queryableCollection;
	private CollectionType collectionType;

	/**
	 * Creates entity from elements.
	 */
	public FromElementFactory(FromClause fromClause, FromElement origin, String path) {
		this.fromClause = fromClause;
		this.origin = origin;
		this.path = path;
		collection = false;
	}

	/**
	 * Creates collection from elements.
	 */
	public FromElementFactory(
	        FromClause fromClause,
	        FromElement origin,
	        String path,
	        String classAlias,
	        String[] columns,
	        boolean implied) {
		this( fromClause, origin, path );
		this.classAlias = classAlias;
		this.columns = columns;
		this.implied = implied;
		collection = true;
	}

	FromElement addFromElement() throws SemanticException {
		FromClause parentFromClause = fromClause.getParentFromClause();
		if ( parentFromClause != null ) {
			// Look up class name using the first identifier in the path.
			String pathAlias = PathHelper.getAlias( path );
			FromElement parentFromElement = parentFromClause.getFromElement( pathAlias );
			if ( parentFromElement != null ) {
				return createFromElementInSubselect( path, pathAlias, parentFromElement, classAlias );
			}
		}

		EntityPersister entityPersister = fromClause.getSessionFactoryHelper().requireClassPersister( path );

		FromElement elem = createAndAddFromElement( path,
				classAlias,
				entityPersister,
				( EntityType ) ( ( Queryable ) entityPersister ).getType(),
				null );

		// Add to the query spaces.
		fromClause.getWalker().addQuerySpaces( entityPersister.getQuerySpaces() );

		return elem;
	}

	private FromElement createFromElementInSubselect(
	        String path,
	        String pathAlias,
	        FromElement parentFromElement,
	        String classAlias) throws SemanticException {
		if ( log.isDebugEnabled() ) {
			log.debug( "createFromElementInSubselect() : path = " + path );
		}
		// Create an DotNode AST for the path and resolve it.
		FromElement fromElement = evaluateFromElementPath( path, classAlias );
		EntityPersister entityPersister = fromElement.getEntityPersister();

		// If the first identifier in the path referrs to the class alias (not the class name), then this
		// is a correlated subselect.  If it's a correlated sub-select, use the existing table alias.  Otherwise
		// generate a new one.
		String tableAlias = null;
		boolean correlatedSubselect = pathAlias.equals( parentFromElement.getClassAlias() );
		if ( correlatedSubselect ) {
			tableAlias = fromElement.getTableAlias();
		}
		else {
			tableAlias = null;
		}

		// If the from element isn't in the same clause, create a new from element.
		if ( fromElement.getFromClause() != fromClause ) {
			if ( log.isDebugEnabled() ) {
				log.debug( "createFromElementInSubselect() : creating a new FROM element..." );
			}
			fromElement = createFromElement( entityPersister );
			initializeAndAddFromElement( fromElement,
					path,
					classAlias,
					entityPersister,
					( EntityType ) ( ( Queryable ) entityPersister ).getType(),
					tableAlias
			);
		}
		if ( log.isDebugEnabled() ) {
			log.debug( "createFromElementInSubselect() : " + path + " -> " + fromElement );
		}
		return fromElement;
	}

	private FromElement evaluateFromElementPath(String path, String classAlias) throws SemanticException {
		ASTFactory factory = fromClause.getASTFactory();
		FromReferenceNode pathNode = ( FromReferenceNode ) PathHelper.parsePath( path, factory );
		pathNode.recursiveResolve( FromReferenceNode.ROOT_LEVEL, // This is the root level node.
				false, // Generate an explicit from clause at the root.
				classAlias,
		        null
		);
		if ( pathNode.getImpliedJoin() != null ) {
			return pathNode.getImpliedJoin();
		}
		else {
			return pathNode.getFromElement();
		}
	}

	FromElement createCollectionElementsJoin(
	        QueryableCollection queryableCollection,
	        String collectionName) throws SemanticException {
		JoinSequence collectionJoinSequence = fromClause.getSessionFactoryHelper()
		        .createCollectionJoinSequence( queryableCollection, collectionName );
		this.queryableCollection = queryableCollection;
		return createCollectionJoin( collectionJoinSequence, null );
	}

	FromElement createCollection(
	        QueryableCollection queryableCollection,
	        String role,
	        int joinType,
	        boolean fetchFlag,
	        boolean indexed)
			throws SemanticException {
		if ( !collection ) {
			throw new IllegalStateException( "FromElementFactory not initialized for collections!" );
		}
		this.inElementsFunction = indexed;
		FromElement elem;
		this.queryableCollection = queryableCollection;
		collectionType = queryableCollection.getCollectionType();
		String roleAlias = fromClause.getAliasGenerator().createName( role );

		// Correlated subqueries create 'special' implied from nodes
		// because correlated subselects can't use an ANSI-style join
		boolean explicitSubqueryFromElement = fromClause.isSubQuery() && !implied;
		if ( explicitSubqueryFromElement ) {
			String pathRoot = StringHelper.root( path );
			FromElement origin = fromClause.getFromElement( pathRoot );
			if ( origin == null || origin.getFromClause() != fromClause ) {
				implied = true;
			}
		}

		// super-duper-classic-parser-regression-testing-mojo-magic...
		if ( explicitSubqueryFromElement && DotNode.useThetaStyleImplicitJoins ) {
			implied = true;
		}

		Type elementType = queryableCollection.getElementType();
		if ( elementType.isEntityType() ) { 			// A collection of entities...
			elem = createEntityAssociation( role, roleAlias, joinType );
		}
		else if ( elementType.isComponentType() ) {		// A collection of components...
			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
			elem = createCollectionJoin( joinSequence, roleAlias );
		}
		else {											// A collection of scalar elements...
			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
			elem = createCollectionJoin( joinSequence, roleAlias );
		}

		elem.setRole( role );
		elem.setQueryableCollection( queryableCollection );
		// Don't include sub-classes for implied collection joins or subquery joins.
		if ( implied ) {
			elem.setIncludeSubclasses( false );
		}

		if ( explicitSubqueryFromElement ) {
			elem.setInProjectionList( true );	// Treat explict from elements in sub-queries properly.
		}

		if ( fetchFlag ) {
			elem.setFetch( true );
		}
		return elem;
	}

	FromElement createEntityJoin(
	        String entityClass,
	        String tableAlias,
	        JoinSequence joinSequence,
	        boolean fetchFlag,
	        boolean inFrom,
	        EntityType type) throws SemanticException {
		FromElement elem = createJoin( entityClass, tableAlias, joinSequence, type, false );
		elem.setFetch( fetchFlag );
		EntityPersister entityPersister = elem.getEntityPersister();
		int numberOfTables = entityPersister.getQuerySpaces().length;
		if ( numberOfTables > 1 && implied && !elem.useFromFragment() ) {
			if ( log.isDebugEnabled() ) {
				log.debug( "createEntityJoin() : Implied multi-table entity join" );
			}
			elem.setUseFromFragment( true );
		}

		// If this is an implied join in a FROM clause, then use ANSI-style joining, and set the
		// flag on the FromElement that indicates that it was implied in the FROM clause itself.

⌨️ 快捷键说明

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