From: <hib...@li...> - 2006-04-20 21:29:22
|
Author: ste...@jb... Date: 2006-04-20 17:26:31 -0400 (Thu, 20 Apr 2006) New Revision: 9773 Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinSource.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SessionFactoryAwareNode.java Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/RangeNode.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContext.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContextImpl.java Log: refactor to PersisterReference stuff Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java 2006-04-20 17:43:46 UTC (rev 9772) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -0,0 +1,34 @@ +package org.hibernate.hql.ast.resolve; + +import org.hibernate.type.AssociationType; +import org.hibernate.hql.ast.tree.Node; + +/** + * @author Steve Ebersole + */ +public class CollectionPersisterReference extends Node implements PersisterReference { + // TODO : implement + public String getName() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public String getAlias() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public AssociationType getPersisterType() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public boolean containsProperty(String propertyName) { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + public PropertyReference retrievePropertyReference(String propertyName) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public String getDisplayText() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } +} Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java (from rev 9747, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/EntityPersisterReference.java) =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/EntityPersisterReference.java 2006-04-13 12:14:07 UTC (rev 9747) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -0,0 +1,74 @@ +package org.hibernate.hql.ast.resolve; + +import org.hibernate.type.AssociationType; +import org.hibernate.persister.entity.Queryable; +import org.hibernate.hql.antlr.HqlRTokenTypes; +import org.hibernate.hql.ast.tree.Node; +import org.hibernate.engine.SessionFactoryImplementor; + +/** + * @author Steve Ebersole + */ +public class EntityPersisterReference extends Node implements PersisterReference, SessionFactoryAwareNode { + private String entityName; + private String alias; + private SessionFactoryImplementor sessionFactory; + private transient Queryable persister; + + public EntityPersisterReference() { + super(); + super.setType( HqlRTokenTypes.ENTITY_PERSISTER_REF ); + } + + public void initialize(String entityName, String alias) { + this.entityName = entityName; + this.alias = alias; + } + + public Queryable getPersister() { + if ( persister == null ) { + persister = ( Queryable ) sessionFactory.getEntityPersister( entityName ); + } + return persister; + } + + public String getName() { + return alias == null ? entityName : entityName + " (" + alias + ")"; + } + + public String getAlias() { + return alias; + } + + public AssociationType getPersisterType() { + return ( AssociationType ) persister.getType(); + } + + public boolean containsProperty(String propertyName) { + try { + return persister.getPropertyType( propertyName ) != null; + } + catch( Throwable t ) { + return false; + } + } + + public PropertyReference retrievePropertyReference(String propertyName) { + return null; + } + + public String getDisplayText() { + return "{" + + "entityName='" + entityName + '\'' + + ", alias='" + alias + '\'' + + '}'; + } + + public String toString() { + return "EntityPersisterReference" + getDisplayText(); + } + + public void setSessionFactory(SessionFactoryImplementor sessionFactory) { + this.sessionFactory = sessionFactory; + } +} Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-04-20 17:43:46 UTC (rev 9772) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -1,6 +1,8 @@ package org.hibernate.hql.ast.resolve; import org.hibernate.hql.antlr.HqlBaseResolver; +import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.QueryException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -18,14 +20,18 @@ public class HqlResolver extends HqlBaseResolver { private static Log log = LogFactory.getLog( HqlResolver.class ); + private final SessionFactoryImplementor sessionFactory; + private final ResolverContext resolverContext; + private int level = 0; private List inputContext = new ArrayList(); private List outputContext = new ArrayList(); - private ResolverContext context; // Provides acces to the session factory via an interface. - public HqlResolver() { + public HqlResolver(SessionFactoryImplementor sessionFactory) { super(); - setASTFactory(new HqlResolverASTFactory()); // Create nodes that track line and column number. + this.sessionFactory = sessionFactory; + setASTFactory( new HqlResolverASTFactory( sessionFactory ) ); + this.resolverContext = new ResolverContextImpl( sessionFactory, getASTFactory() ); } @@ -57,12 +63,74 @@ protected void defineRange(AST range, String path, AST alias, AST fetch) { RangeNode r = (RangeNode) range; r.setPath(path); - r.setPersister(context.lookupPersister(path)); + r.setPersisterReference( resolverContext.getEntityPersisterReference( path, alias == null ? null : alias.getText() ) ); r.setFetch(fetch != null); r.setAlias(alias != null ? alias.getText() : null); } - public void initialize(ResolverContext resolverContext) { - context = resolverContext; + protected AST buildEntityPersisterReference(String entityName, AST alias) { + return resolverContext.getEntityPersisterReference( entityName, alias == null ? null : alias.getText() ); } + + protected AST buildThetaJoinNode(AST persisterReference) { + JoinNode join = createJoinNode( JoinType.FULL, JoinSource.THETA, false ); + join.setFirstChild( persisterReference ); + return join; + } + + private JoinNode createJoinNode(JoinType type, JoinSource source, boolean fetch) { + JoinNode node = ( JoinNode ) getASTFactory().create( JOIN, "join" ); + node.initialize( type, source, fetch ); + return node; + } + + protected AST buildExplicitPropertyJoinNode( + AST propertyReference, + AST alias, + AST joinType, + AST fetch, + AST propertyFetch, + AST withClause) { + JoinNode join = createJoinNode( resolveJoinType( joinType ), JoinSource.EXPLICIT, fetch != null ); + join.setFirstChild( propertyReference ); + if ( withClause != null ) { + join.addChild( withClause ); + } + return join; + } + + protected AST buildAdHocJoinNode(AST persisterReference, AST joinType, AST onClause) { + JoinNode join = createJoinNode( resolveJoinType( joinType ), JoinSource.AD_HOC, false ); + join.setFirstChild( persisterReference ); + if ( onClause != null ) { + join.addChild( onClause ); + } + return join; + } + + private JoinType resolveJoinType(AST joinType) { + if ( joinType.getType() == LEFT ) { + return JoinType.LEFT; + } + else if ( joinType.getType() == RIGHT ) { + return JoinType.RIGHT; + } + else if ( joinType.getType() == FULL ) { + return JoinType.FULL; + } + else { + throw new QueryException( "Unrecognized join type [" + joinType.getText() + "]" ); + } + } + + protected boolean isEntityName(String test) { + try { + return sessionFactory.getEntityPersister( test ) != null; + } + catch( Throwable t ) { + // ignore it... + } + return false; + } + } Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-04-20 17:43:46 UTC (rev 9772) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -2,6 +2,9 @@ import org.hibernate.hql.antlr.HqlRTokenTypes; import org.hibernate.hql.ast.HqlASTFactory; +import org.hibernate.engine.SessionFactoryImplementor; +import antlr.collections.AST; +import antlr.Token; /** * AST factory for the resolver phase. @@ -10,6 +13,12 @@ * Time: 7:58:16 AM */ public class HqlResolverASTFactory extends HqlASTFactory implements HqlRTokenTypes { + private final SessionFactoryImplementor factory; + + public HqlResolverASTFactory(SessionFactoryImplementor factory) { + this.factory = factory; + } + public Class getASTNodeType(int tokenType) { // Statement nodes: switch (tokenType) { @@ -20,7 +29,31 @@ return StatementNode.class; case RANGE: return RangeNode.class; + case ENTITY_PERSISTER_REF: + return EntityPersisterReference.class; + case COLLECTION_PERSISTER_REF: + return CollectionPersisterReference.class; + case JOIN: + return JoinNode.class; } return super.getASTNodeType(tokenType); } + + protected AST createUsingCtor(Token token, String string) { + AST node = super.createUsingCtor( token, string ); + prepare( node ); + return node; + } + + protected AST create(Class aClass) { + AST node = super.create( aClass ); + prepare( node ); + return node; + } + + private void prepare(AST node) { + if ( node instanceof SessionFactoryAwareNode ) { + ( ( SessionFactoryAwareNode ) node ).setSessionFactory( factory ); + } + } } Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java (from rev 9747, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/JoinNode.java) =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/JoinNode.java 2006-04-13 12:14:07 UTC (rev 9747) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -0,0 +1,69 @@ +package org.hibernate.hql.ast.resolve; + +import antlr.Token; +import org.hibernate.hql.ast.tree.Node; +import org.hibernate.hql.ast.tree.DisplayableNode; + +/** + * Represents an HQL join. The coneptualization here is strictly that of + * the join in terms of the context of the HQL query which may or may not have + * direct correlation to any SQL join. + * + * @author Steve Ebersole + */ +public class JoinNode extends Node implements DisplayableNode { + + // todo : we need to decide the tree structure of a join subtree. + // based on that decision, we may need to have references here + // to both the left-hand and right-hand persister references + + private JoinType joinType; + private JoinSource source; + private boolean fetch; + + public JoinNode() { + } + + public JoinNode(Token tok) { + super( tok ); + } + + public void initialize(JoinType joinType, JoinSource source, boolean fetch) { + this.joinType = joinType; + this.source = source; + this.fetch = fetch; + super.setText( "join" ); + } + + public JoinType getJoinType() { + return joinType; + } + + public void setJoinType(JoinType joinType) { + this.joinType = joinType; + } + + public JoinSource getSource() { + return source; + } + + public void setSource(JoinSource source) { + this.source = source; + } + + public boolean isFetch() { + return fetch; + } + + public void setFetch(boolean fetch) { + this.fetch = fetch; + } + + public String getDisplayText() { + return "{" + "type=" + joinType + ", source=" + source + "fetch=" + fetch + "}"; + } + + public String toString() { + return "JoinNode" + getDisplayText(); + } +} Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinSource.java (from rev 9747, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/JoinSource.java) =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/JoinSource.java 2006-04-13 12:14:07 UTC (rev 9747) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinSource.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -0,0 +1,55 @@ +package org.hibernate.hql.ast.resolve; + +import java.util.HashMap; +import java.io.Serializable; + +/** + * Represents the source of a join, in the context of the HQL query. + * + * @author Steve Ebersole + */ +public class JoinSource implements Serializable { + + /** + * Indicates a join using the HQL explicit join syntax (i.e. the join keyword). + */ + public static final JoinSource EXPLICIT = new JoinSource( "explicit" ); + /** + * Indicates a join defined by implicit syntax (i.e. a path expression). + */ + public static final JoinSource IMPLICIT = new JoinSource( "implicit" ); + /** + * Indicates a join that is the result of an indexed operation (i.e. []) + * on an indexed or keyed collection (list or map). + */ + public static final JoinSource INDEXED = new JoinSource( "indexed" ); + /** + * Indicates a theta-style join (i.e. from A a, B b where a.id = b.id...) + */ + public static final JoinSource THETA = new JoinSource( "theta" ); + + public static final JoinSource AD_HOC = new JoinSource( "ad_hoc" ); + + private static final HashMap INSTANCES = new HashMap(); + static { + INSTANCES.put( EXPLICIT.name, EXPLICIT ); + INSTANCES.put( IMPLICIT.name, IMPLICIT ); + INSTANCES.put( INDEXED.name, INDEXED ); + INSTANCES.put( THETA.name, THETA ); + INSTANCES.put( AD_HOC.name, AD_HOC ); + } + + private final String name; + + private JoinSource(String name) { + this.name = name; + } + + public String toString() { + return name; + } + + private Object readResolve() { + return INSTANCES.get( name ); + } +} Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java (from rev 9747, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/JoinType.java) =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/JoinType.java 2006-04-13 12:14:07 UTC (rev 9747) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -0,0 +1,62 @@ +package org.hibernate.hql.ast.resolve; + +import java.io.Serializable; +import java.util.HashMap; + +/** + * Represents a canonical join type. + * <p/> + * Note that currently HQL really only supports inner and left outer joins + * (though cross joins can also be achieved). This is because joins in HQL + * are always defined in relation to a mapped association. However, when we + * start allowing users to specify ad-hoc joins this may need to change to + * allow the full spectrum of join types. Thus the others are provided here + * currently just for completeness and for future expansion. + * + * @author Steve Ebersole + */ +public class JoinType implements Serializable { + /** + * Represents an inner join. + */ + public static final JoinType INNER = new JoinType( "inner" ); + /** + * Represents a left outer join. + */ + public static final JoinType LEFT = new JoinType( "left outer" ); + /** + * Represents a right outer join. + */ + public static final JoinType RIGHT = new JoinType( "right outer" ); + /** + * Represents a cross join (aka a cartesian product). + */ + public static final JoinType CROSS = new JoinType( "cross" ); + /** + * Represents a full join. + */ + public static final JoinType FULL = new JoinType( "full" ); + + private static final HashMap INSTANCES = new HashMap(); + static { + INSTANCES.put( INNER.name, INNER ); + INSTANCES.put( LEFT.name, LEFT ); + INSTANCES.put( RIGHT.name, RIGHT ); + INSTANCES.put( CROSS.name, CROSS ); + INSTANCES.put( FULL.name, FULL ); + } + + private final String name; + + private JoinType(String name) { + this.name = name; + } + + public String toString() { + return name; + } + + private Object readResolve() { + return INSTANCES.get( name ); + } +} Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java (from rev 9747, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PersisterReference.java) =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PersisterReference.java 2006-04-13 12:14:07 UTC (rev 9747) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -0,0 +1,19 @@ +package org.hibernate.hql.ast.resolve; + +import org.hibernate.type.AssociationType; +import org.hibernate.hql.ast.tree.DisplayableNode; + +/** + * Represents a reference to a persister (either entity or collection) within + * an HQL statement. + * + * @author Steve Ebersole + */ +public interface PersisterReference extends DisplayableNode { + public String getName(); + public String getAlias(); + public AssociationType getPersisterType(); + + public boolean containsProperty(String propertyName); + public PropertyReference retrievePropertyReference(String propertyName); +} Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java (from rev 9747, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PropertyReference.java) =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PropertyReference.java 2006-04-13 12:14:07 UTC (rev 9747) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -0,0 +1,16 @@ +package org.hibernate.hql.ast.resolve; + +import org.hibernate.type.Type; +import org.hibernate.hql.ast.tree.DisplayableNode; + +/** + * Represents a reference to a particular persister-managed property; also + * some special cases such as a collection property reference (e.g., size). + * + * @author Steve Ebersole + */ +public interface PropertyReference extends DisplayableNode { + public String getPropertyName(); + public Type getPropertyType(); + public PersisterReference getPersisterReference(); +} Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/RangeNode.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/RangeNode.java 2006-04-20 17:43:46 UTC (rev 9772) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/RangeNode.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -2,18 +2,23 @@ import org.hibernate.hql.ast.tree.Node; import org.hibernate.hql.ast.tree.DisplayableNode; -import org.hibernate.persister.entity.EntityPersister; /** - * Represents an element of a FROM clause, e.g. "from Animal a" - * <br>User: Joshua Davis - * Date: Apr 12, 2006 - * Time: 7:31:17 AM + * Represents a "top-level" element in a FROM clause (e.g. "from Animal a"). These + * "top-level" nodes are then contained in a RANGE node within the FROM node. + * + * + * @author Joshua Davis */ public class RangeNode extends Node implements DisplayableNode { + // TODO : would like to remove this range concept; + // a "range" is really just a series of full joins (unless further + // qualified in the where-clause, in which case they'd become inner + // joins) specified using old "theta join" syntax from SQL, so + // represent them as join structures private String path; private String alias; - private EntityPersister persister; + private EntityPersisterReference persisterReference; private boolean fetch = false; public String getPath() { @@ -24,12 +29,12 @@ this.path = path; } - public EntityPersister getPersister() { - return persister; + public EntityPersisterReference getPersisterReference() { + return persisterReference; } - public void setPersister(EntityPersister persister) { - this.persister = persister; + public void setPersisterReference(EntityPersisterReference persisterReference) { + this.persisterReference = persisterReference; } public boolean isFetch() { @@ -51,11 +56,11 @@ public String toString() { return "RangeNode{" + - "path='" + path + '\'' + - ", alias='" + alias + '\'' + - ", persister=" + persister + - ", fetch=" + fetch + - '}'; + "path='" + path + '\'' + + ", alias='" + alias + '\'' + + ", reference=" + persisterReference + + ", fetch=" + fetch + + '}'; } public String getDisplayText() { Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContext.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContext.java 2006-04-20 17:43:46 UTC (rev 9772) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContext.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -2,6 +2,8 @@ import org.hibernate.persister.entity.EntityPersister; +import java.util.List; + /** * Looks up persisters and other things by name. * <br>User: Joshua Davis @@ -9,5 +11,9 @@ * Time: 7:34:11 AM */ public interface ResolverContext { - EntityPersister lookupPersister(String path); + public EntityPersister lookupPersister(String path); + public PersisterReference locatePersisterReferenceByAlias(String alias); + public List collectPersisterReferences(); + public EntityPersisterReference getEntityPersisterReference(String entityName, String alias); + public CollectionPersisterReference getCollectionPersisterReference(String collectionRole, String alias); } Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContextImpl.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContextImpl.java 2006-04-20 17:43:46 UTC (rev 9772) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolverContextImpl.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -2,8 +2,17 @@ import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.MappingException; +import org.hibernate.hql.antlr.HqlRTokenTypes; import org.hibernate.persister.entity.EntityPersister; +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; + +import antlr.ASTFactory; + /** * Implements the resolver's context with a session factory. * <br>User: Joshua Davis @@ -11,26 +20,55 @@ * Time: 7:35:31 AM */ public class ResolverContextImpl implements ResolverContext { - private SessionFactoryImplementor sfi; + private Map persisterReferencesByAlias = new HashMap(); + private List persisterReferences = new ArrayList(); + private final SessionFactoryImplementor sessionFactory; + private final ASTFactory astFactory; - public ResolverContextImpl(SessionFactoryImplementor sfi) { - this.sfi = sfi; + public ResolverContextImpl(SessionFactoryImplementor sessionFactory, ASTFactory astFactory) { + this.sessionFactory = sessionFactory; + this.astFactory = astFactory; } public EntityPersister lookupPersister(String name) { // First, try to get the persister using the class name directly. try { - return sfi.getEntityPersister( name ); + return sessionFactory.getEntityPersister( name ); } catch ( MappingException ignore ) { // unable to locate it using this name } // If that didn't work, try using the 'import' name. - String importedClassName = sfi.getImportedClassName( name ); + String importedClassName = sessionFactory.getImportedClassName( name ); if ( importedClassName == null ) { return null; } - return sfi.getEntityPersister( importedClassName ); + return sessionFactory.getEntityPersister( importedClassName ); } + + public PersisterReference locatePersisterReferenceByAlias(String alias) { + return ( PersisterReference ) persisterReferencesByAlias.get( alias ); + } + + public List collectPersisterReferences() { + return Collections.unmodifiableList( persisterReferences ); + } + + public EntityPersisterReference getEntityPersisterReference(String entityName, String alias) { + EntityPersister persister = lookupPersister( entityName ); + EntityPersisterReference persisterReference = ( EntityPersisterReference ) astFactory.create( HqlRTokenTypes.ENTITY_PERSISTER_REF, persister.getEntityName() ); + persisterReference.initialize( persister.getEntityName(), alias ); + persisterReferences.add( persisterReference ); + if ( alias != null ) { + persisterReferencesByAlias.put( alias, persisterReference ); + } + return persisterReference; + } + + public CollectionPersisterReference getCollectionPersisterReference(String collectionRole, String alias) { + // TODO : implement; for now returns null... + return null; + } + } Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SessionFactoryAwareNode.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SessionFactoryAwareNode.java 2006-04-20 17:43:46 UTC (rev 9772) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SessionFactoryAwareNode.java 2006-04-20 21:26:31 UTC (rev 9773) @@ -0,0 +1,18 @@ +package org.hibernate.hql.ast.resolve; + +import org.hibernate.engine.SessionFactoryImplementor; + +/** + * Interface for nodes which wish to be injected with a reference to the + * current session factory. + * + * @author Steve Ebersole + */ +public interface SessionFactoryAwareNode { + /** + * Used to inject a reference to the current session factory. + * + * @param factory The session factory. + */ + public void setSessionFactory(SessionFactoryImplementor factory); +} |