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

📄 identnode.java

📁 一个Java持久层类库
💻 JAVA
字号:
// $Id: IdentNode.java 10059 2006-06-28 02:37:56Z steve.ebersole@jboss.com $package org.hibernate.hql.ast.tree;import antlr.SemanticException;import antlr.collections.AST;import org.hibernate.QueryException;import org.hibernate.dialect.function.SQLFunction;import org.hibernate.hql.antlr.SqlTokenTypes;import org.hibernate.hql.ast.util.ColumnHelper;import org.hibernate.persister.collection.QueryableCollection;import org.hibernate.persister.entity.Queryable;import org.hibernate.sql.JoinFragment;import org.hibernate.type.CollectionType;import org.hibernate.type.Type;import org.hibernate.util.StringHelper;import java.util.List;/** * Represents an identifier all by itself, which may be a function name, * a class alias, or a form of naked property-ref depending on the * context. * * @author josh Aug 16, 2004 7:20:55 AM */public class IdentNode extends FromReferenceNode implements SelectExpression {	private static final int UNKNOWN = 0;	private static final int PROPERTY_REF = 1;	private static final int COMPONENT_REF = 2;	private boolean nakedPropertyRef = false;	public void resolveIndex(AST parent) throws SemanticException {		// An ident node can represent an index expression if the ident		// represents a naked property ref		//      *Note: this makes the assumption (which is currently the case		//      in the hql-sql grammar) that the ident is first resolved		//      itself (addrExpr -> resolve()).  The other option, if that		//      changes, is to call resolve from here; but it is		//      currently un-needed overhead.		if (!(isResolved() && nakedPropertyRef)) {			throw new UnsupportedOperationException();		}		String propertyName = getOriginalText();		if (!getDataType().isCollectionType()) {			throw new SemanticException("Collection expected; [" + propertyName + "] does not refer to a collection property");		}		// TODO : most of below was taken verbatim from DotNode; should either delegate this logic or super-type it		CollectionType type = (CollectionType) getDataType();		String role = type.getRole();		QueryableCollection queryableCollection = getSessionFactoryHelper().requireQueryableCollection(role);		String alias = null;  // DotNode uses null here...		String columnTableAlias = getFromElement().getTableAlias();		int joinType = JoinFragment.INNER_JOIN;		boolean fetch = false;		FromElementFactory factory = new FromElementFactory(				getWalker().getCurrentFromClause(),				getFromElement(),				propertyName,				alias,				getFromElement().toColumns(columnTableAlias, propertyName, false),				true		);		FromElement elem = factory.createCollection(queryableCollection, role, joinType, fetch, true);		setFromElement(elem);		getWalker().addQuerySpaces(queryableCollection.getCollectionSpaces());	// Always add the collection's query spaces.	}	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) {		if (!isResolved()) {			if (getWalker().getCurrentFromClause().isFromElementAlias(getText())) {				if (resolveAsAlias()) {					setResolved();					// We represent a from-clause alias				}			}			else if (parent != null && parent.getType() == SqlTokenTypes.DOT) {				DotNode dot = (DotNode) parent;				if (parent.getFirstChild() == this) {					if (resolveAsNakedComponentPropertyRefLHS(dot)) {						// we are the LHS of the DOT representing a naked comp-prop-ref						setResolved();					}				}				else {					if (resolveAsNakedComponentPropertyRefRHS(dot)) {						// we are the RHS of the DOT representing a naked comp-prop-ref						setResolved();					}				}			}			else {				int result = resolveAsNakedPropertyRef();				if (result == PROPERTY_REF) {					// we represent a naked (simple) prop-ref					setResolved();				}				else if (result == COMPONENT_REF) {					// EARLY EXIT!!!  return so the resolve call explicitly coming from DotNode can					// resolve this...					return;				}			}			// if we are still not resolved, we might represent a constant.			//      needed to add this here because the allowance of			//      naked-prop-refs in the grammar collides with the			//      definition of literals/constants ("nondeterminism").			//      TODO: cleanup the grammar so that "processConstants" is always just handled from here			if (!isResolved()) {				try {					getWalker().getLiteralProcessor().processConstant(this, false);				}				catch (Throwable ignore) {					// just ignore it for now, it'll get resolved later...				}			}		}	}	private boolean resolveAsAlias() {		// This is not actually a constant, but a reference to FROM element.		FromElement element = getWalker().getCurrentFromClause().getFromElement(getText());		if (element != null) {			setFromElement(element);			setText(element.getIdentityColumn());			setType(SqlTokenTypes.ALIAS_REF);			return true;		}		return false;	}	private Type getNakedPropertyType(FromElement fromElement)	{		if (fromElement == null) {			return null;		}		String property = getOriginalText();		Type propertyType = null;		try {			propertyType = fromElement.getPropertyType(property, property);		}		catch (Throwable t) {		}		return propertyType;	}	private int resolveAsNakedPropertyRef() {		FromElement fromElement = locateSingleFromElement();		if (fromElement == null) {			return UNKNOWN;		}		Queryable persister = fromElement.getQueryable();		if (persister == null) {			return UNKNOWN;		}		Type propertyType = getNakedPropertyType(fromElement);		if (propertyType == null) {			// assume this ident's text does *not* refer to a property on the given persister			return UNKNOWN;		}		if ((propertyType.isComponentType() || propertyType.isAssociationType() )) {			return COMPONENT_REF;		}		setFromElement(fromElement);		String property = getText();		String[] columns = getWalker().isSelectStatement()				? persister.toColumns(fromElement.getTableAlias(), property)				: persister.toColumns(property);		String text = StringHelper.join(", ", columns);		setText(columns.length == 1 ? text : "(" + text + ")");		setType(SqlTokenTypes.SQL_TOKEN);		// these pieces are needed for usage in select clause		super.setDataType(propertyType);		nakedPropertyRef = true;		return PROPERTY_REF;	}	private boolean resolveAsNakedComponentPropertyRefLHS(DotNode parent) {		FromElement fromElement = locateSingleFromElement();		if (fromElement == null) {			return false;		}		Type componentType = getNakedPropertyType(fromElement);		if ( componentType == null ) {			throw new QueryException( "Unable to resolve path [" + parent.getPath() + "], unexpected token [" + getOriginalText() + "]" );		}		if (!componentType.isComponentType()) {			throw new QueryException("Property '" + getOriginalText() + "' is not a component.  Use an alias to reference associations or collections.");		}		Type propertyType = null;  // used to set the type of the parent dot node		String propertyPath = getText() + "." + getNextSibling().getText();		try {			// check to see if our "propPath" actually			// represents a property on the persister			propertyType = fromElement.getPropertyType(getText(), propertyPath);		}		catch (Throwable t) {			// assume we do *not* refer to a property on the given persister			return false;		}		setFromElement(fromElement);		parent.setPropertyPath(propertyPath);		parent.setDataType(propertyType);		return true;	}	private boolean resolveAsNakedComponentPropertyRefRHS(DotNode parent) {		FromElement fromElement = locateSingleFromElement();		if (fromElement == null) {			return false;		}		Type propertyType = null;		String propertyPath = parent.getLhs().getText() + "." + getText();		try {			// check to see if our "propPath" actually			// represents a property on the persister			propertyType = fromElement.getPropertyType(getText(), propertyPath);		}		catch (Throwable t) {			// assume we do *not* refer to a property on the given persister			return false;		}		setFromElement(fromElement);		// this piece is needed for usage in select clause		super.setDataType(propertyType);		nakedPropertyRef = true;		return true;	}	private FromElement locateSingleFromElement() {		List fromElements = getWalker().getCurrentFromClause().getFromElements();		if (fromElements == null || fromElements.size() != 1) {			// TODO : should this be an error?			return null;		}		FromElement element = (FromElement) fromElements.get(0);		if (element.getClassAlias() != null) {			// naked property-refs cannot be used with an aliased from element			return null;		}		return element;	}	public Type getDataType() {		Type type = super.getDataType();		if (type != null) return type;		FromElement fe = getFromElement();		if (fe != null) return fe.getDataType();		SQLFunction sf = getWalker().getSessionFactoryHelper().findSQLFunction(getText());		return sf == null ? null : sf.getReturnType(null, null);	}	public void setScalarColumnText(int i) throws SemanticException {		if (nakedPropertyRef) {			// do *not* over-write the column text, as that has already been			// "rendered" during resolve			ColumnHelper.generateSingleScalarColumn(this, i);		}		else {			FromElement fe = getFromElement();			if (fe != null) {				setText(fe.renderScalarIdentifierSelect(i));			}			else {				ColumnHelper.generateSingleScalarColumn(this, i);			}		}	}	public String getDisplayText() {		StringBuffer buf = new StringBuffer();		if (getType() == SqlTokenTypes.ALIAS_REF) {			buf.append("{alias=").append(getOriginalText());			if (getFromElement() == null) {				buf.append(", no from element");			}			else {				buf.append(", className=").append(getFromElement().getClassName());				buf.append(", tableAlias=").append(getFromElement().getTableAlias());			}			buf.append("}");		}		else {			buf.append("{originalText=" + getOriginalText()).append("}");		}		return buf.toString();	}}

⌨️ 快捷键说明

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