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

📄 pathexpressionparser.java

📁 一个Java持久层类库
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
//$Id: PathExpressionParser.java 10830 2006-11-16 20:22:07Z steve.ebersole@jboss.com $package org.hibernate.hql.classic;import java.util.LinkedList;import java.util.Map;import org.hibernate.MappingException;import org.hibernate.QueryException;import org.hibernate.engine.JoinSequence;import org.hibernate.hql.CollectionSubqueryFactory;import org.hibernate.persister.collection.CollectionPropertyMapping;import org.hibernate.persister.collection.QueryableCollection;import org.hibernate.persister.entity.EntityPersister;import org.hibernate.persister.entity.PropertyMapping;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.type.TypeFactory;/** * Parses an expression of the form foo.bar.baz and builds up an expression * involving two less table joins than there are path components. */public class PathExpressionParser implements Parser {	//TODO: this class does too many things! we need a different	//kind of path expression parser for each of the diffferent	//ways in which path expressions can occur	//We should actually rework this class to not implement Parser	//and just process path expressions in the most convenient way.	//The class is now way to complex!	private int dotcount;	private String currentName;	private String currentProperty;	private String oneToOneOwnerName;	private AssociationType ownerAssociationType;	private String[] columns;	private String collectionName;	private String collectionOwnerName;	private String collectionRole;	private final StringBuffer componentPath = new StringBuffer();	private Type type;	private final StringBuffer path = new StringBuffer();	private boolean ignoreInitialJoin;	private boolean continuation;	private int joinType = JoinFragment.INNER_JOIN; //default mode	private boolean useThetaStyleJoin = true;	private PropertyMapping currentPropertyMapping;	private JoinSequence joinSequence;	private boolean expectingCollectionIndex;	private LinkedList collectionElements = new LinkedList();	void setJoinType(int joinType) {		this.joinType = joinType;	}	void setUseThetaStyleJoin(boolean useThetaStyleJoin) {		this.useThetaStyleJoin = useThetaStyleJoin;	}	private void addJoin(String name, AssociationType joinableType) throws QueryException {		try {			joinSequence.addJoin( joinableType, name, joinType, currentColumns() );		}		catch ( MappingException me ) {			throw new QueryException( me );		}	}	private void addJoin(String name, AssociationType joinableType, String[] foreignKeyColumns) throws QueryException {		try {			joinSequence.addJoin( joinableType, name, joinType, foreignKeyColumns );		}		catch ( MappingException me ) {			throw new QueryException( me );		}	}	String continueFromManyToMany(String entityName, String[] joinColumns, QueryTranslatorImpl q) throws QueryException {		start( q );		continuation = true;		currentName = q.createNameFor( entityName );		q.addType( currentName, entityName );		Queryable classPersister = q.getEntityPersister( entityName );		//QueryJoinFragment join = q.createJoinFragment(useThetaStyleJoin);		addJoin( currentName, TypeFactory.manyToOne( entityName ), joinColumns );		currentPropertyMapping = classPersister;		return currentName;	}	public void ignoreInitialJoin() {		ignoreInitialJoin = true;	}	public void token(String token, QueryTranslatorImpl q) throws QueryException {		if ( token != null ) path.append( token );		String alias = q.getPathAlias( path.toString() );		if ( alias != null ) {			reset( q ); //reset the dotcount (but not the path)			currentName = alias; //after reset!			currentPropertyMapping = q.getPropertyMapping( currentName );			if ( !ignoreInitialJoin ) {				JoinSequence ojf = q.getPathJoin( path.toString() );				try {					joinSequence.addCondition( ojf.toJoinFragment( q.getEnabledFilters(), true ).toWhereFragmentString() ); //after reset!				}				catch ( MappingException me ) {					throw new QueryException( me );				}				// we don't need to worry about any condition in the ON clause				// here (toFromFragmentString), since anything in the ON condition				// is already applied to the whole query			}		}		else if ( ".".equals( token ) ) {			dotcount++;		}		else {			if ( dotcount == 0 ) {				if ( !continuation ) {					if ( !q.isName( token ) ) throw new QueryException( "undefined alias: " + token );					currentName = token;					currentPropertyMapping = q.getPropertyMapping( currentName );				}			}			else if ( dotcount == 1 ) {				if ( currentName != null ) {					currentProperty = token;				}				else if ( collectionName != null ) {					//processCollectionProperty(token, q.getCollectionPersister(collectionRole), collectionName);					continuation = false;				}				else {					throw new QueryException( "unexpected" );				}			}			else { // dotcount>=2				// Do the corresponding RHS				Type propertyType = getPropertyType();				if ( propertyType == null ) {					throw new QueryException( "unresolved property: " + path );				}				if ( propertyType.isComponentType() ) {					dereferenceComponent( token );				}				else if ( propertyType.isEntityType() ) {					if ( !isCollectionValued() ) dereferenceEntity( token, ( EntityType ) propertyType, q );				}				else if ( propertyType.isCollectionType() ) {					dereferenceCollection( token, ( ( CollectionType ) propertyType ).getRole(), q );				}				else {					if ( token != null ) throw new QueryException( "dereferenced: " + path );				}			}		}	}	private void dereferenceEntity(String propertyName, EntityType propertyType, QueryTranslatorImpl q)			throws QueryException {		//NOTE: we avoid joining to the next table if the named property is just the foreign key value		//if its "id"		boolean isIdShortcut = EntityPersister.ENTITY_ID.equals( propertyName ) &&				propertyType.isReferenceToPrimaryKey();		//or its the id property name		final String idPropertyName;		try {			idPropertyName = propertyType.getIdentifierOrUniqueKeyPropertyName( q.getFactory() );		}		catch ( MappingException me ) {			throw new QueryException( me );		}		boolean isNamedIdPropertyShortcut = idPropertyName != null				&& idPropertyName.equals( propertyName )				&& propertyType.isReferenceToPrimaryKey();		if ( isIdShortcut || isNamedIdPropertyShortcut ) {			// special shortcut for id properties, skip the join!			// this must only occur at the _end_ of a path expression			if ( componentPath.length() > 0 ) componentPath.append( '.' );			componentPath.append( propertyName );		}		else {			String entityClass = propertyType.getAssociatedEntityName();			String name = q.createNameFor( entityClass );			q.addType( name, entityClass );			addJoin( name, propertyType );			if ( propertyType.isOneToOne() ) oneToOneOwnerName = currentName;			ownerAssociationType = propertyType;			currentName = name;			currentProperty = propertyName;			q.addPathAliasAndJoin( path.substring( 0, path.toString().lastIndexOf( '.' ) ), name, joinSequence.copy() );			componentPath.setLength( 0 );			currentPropertyMapping = q.getEntityPersister( entityClass );		}	}	private void dereferenceComponent(String propertyName) {		if ( propertyName != null ) {			if ( componentPath.length() > 0 ) componentPath.append( '.' );			componentPath.append( propertyName );		}	}	private void dereferenceCollection(String propertyName, String role, QueryTranslatorImpl q) throws QueryException {		collectionRole = role;		QueryableCollection collPersister = q.getCollectionPersister( role );		String name = q.createNameForCollection( role );		addJoin( name, collPersister.getCollectionType() );		//if ( collPersister.hasWhere() ) join.addCondition( collPersister.getSQLWhereString(name) );		collectionName = name;		collectionOwnerName = currentName;		currentName = name;		currentProperty = propertyName;		componentPath.setLength( 0 );		currentPropertyMapping = new CollectionPropertyMapping( collPersister );	}	private String getPropertyPath() {		if ( currentProperty == null ) {			return EntityPersister.ENTITY_ID;		}		else {			if ( componentPath.length() > 0 ) {				return new StringBuffer()						.append( currentProperty )						.append( '.' )						.append( componentPath.toString() )						.toString();			}			else {				return currentProperty;			}		}	}

⌨️ 快捷键说明

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