alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (FromClause.java)

This example Hibernate source code file (FromClause.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

fromclause, fromclause, fromelement, fromelement, hashmap, hashset, iterator, list, map, map, override, set, string, string, util

The Hibernate FromClause.java source code

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Middleware LLC.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 *
 */
package org.hibernate.hql.internal.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.hibernate.internal.CoreMessageLogger;
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
import org.hibernate.hql.internal.ast.util.ASTIterator;
import org.hibernate.hql.internal.ast.util.ASTUtil;
import org.jboss.logging.Logger;
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 final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, FromClause.class.getName());
	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;
	}

	public FromElement findFromElementBySqlAlias(String sqlAlias) {
		FromElement fromElement = ( FromElement ) fromElementByTableAlias.get( sqlAlias );
		if ( fromElement == null && parentFromClause != null ) {
			fromElement = parentFromClause.getFromElement( sqlAlias );
		}
		return fromElement;
	}

	public FromElement findFromElementByUserOrSqlAlias(String userAlias, String sqlAlias) {
		FromElement fromElement = null;
		if ( userAlias != null ) {
			fromElement = getFromElement( userAlias );
		}

		if ( fromElement == null ) {
			fromElement = findFromElementBySqlAlias( sqlAlias );
		}

		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() {
		@Override
        public boolean include(AST node) {
			FromElement fromElement = ( FromElement ) node;
			return fromElement.isFromOrJoinFragment();
		}
	};

	private static ASTUtil.FilterPredicate projectionListPredicate = new ASTUtil.IncludePredicate() {
		@Override
        public boolean include(AST node) {
			FromElement fromElement = ( FromElement ) node;
			return fromElement.inProjectionList();
		}
	};

	private static ASTUtil.FilterPredicate collectionFetchPredicate = new ASTUtil.IncludePredicate() {
		@Override
        public boolean include(AST node) {
			FromElement fromElement = ( FromElement ) node;
			return fromElement.isFetch() && fromElement.getQueryableCollection() != null;
		}
	};

	private static ASTUtil.FilterPredicate explicitFromPredicate = new ASTUtil.IncludePredicate() {
		@Override
        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) {
        LOG.debugf("addJoinByPathMap() : %s -> %s", path, destination.getDisplayText());
		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) {
        LOG.debugf("Promoting [%s] to [%s]", elem, 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
		//  doAfterTransactionCompletion "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) {
        LOG.debugf("addCollectionJoinFromElementByPath() : %s -> %s", 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 );
	}

	@Override
    public String toString() {
		return "FromClause{" +
				"level=" + level +
				"}";
	}
}

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate FromClause.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.