Author: ste...@jb...
Date: 2006-07-06 10:59:36 -0400 (Thu, 06 Jul 2006)
New Revision: 10088
Added:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractPropertyPathHandler.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClausePropertyPathHandler.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalPropertyPathHandler.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/OnFragmentPropertyPathHandler.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyPathHandler.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/WithFragmentPropertyPathHandler.java
Removed:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractImplicitJoinContext.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClauseImplicitJoinContext.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ImplicitJoinContext.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/NormalImplicitJoinContext.java
Modified:
branches/HQL_ANTLR_2/Hibernate3/g2/parse.g
branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java
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/JoinNode.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/PersisterReferenceBuilder.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/StatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/util/ASTPrinter.java
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java
Log:
implemented handling of both on and with fragments
Modified: branches/HQL_ANTLR_2/Hibernate3/g2/parse.g
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/g2/parse.g 2006-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/g2/parse.g 2006-07-06 14:59:36 UTC (rev 10088)
@@ -198,6 +198,10 @@
return node.getText();
}
+ public boolean isEntityName(AST node) {
+ return false;
+ }
+
public boolean isJavaConstant() throws RecognitionException, TokenStreamException {
return false;
}
@@ -286,7 +290,6 @@
: c:path { weakKeywords(); } (a:asAlias)? (p:propertyFetch)? {
String entityName = extractEntityName( #c );
AST en = #( [ENTITY_NAME, entityName] );
- en.initialize( #c );
#fromClassOrOuterQueryPath = #([RANGE, "RANGE"], [ENTITY_NAME, entityName], #a, #p);
}
;
@@ -313,10 +316,37 @@
//fromJoin
// : ( ( ( LEFT | RIGHT ) (OUTER)? ) | FULL | INNER )? JOIN^ (FETCH)? path (asAlias)? (propertyFetch)? (withClause)?
// ;
+//fromJoin!
+// : (jt:joinType)? j:JOIN (f:FETCH)? p:path (a:asAlias)? (pf:propertyFetch)? (w:withClause)? {
+// #fromJoin = #( #j, #jt, #f, #a, #pf, #p, #w );
+// }
+// ;
+
fromJoin!
- : (jt:joinType)? j:JOIN (f:FETCH)? p:path (a:asAlias)? (pf:propertyFetch)? (w:withClause)? {
- #fromJoin = #( #j, #jt, #f, #a, #pf, #p, #w );
- }
+ : (jt:joinType)? j:JOIN (f:FETCH)? p:path (a:asAlias)?
+ (
+ // try to use the ON keyword to disambiguate
+ o:onFragment {
+ if ( #f != null ) {
+ throw new org.hibernate.QueryException( "Cannot use fetch keyword in conjunction with an ad hoc join" );
+ }
+ String entityName = extractEntityName( #p );
+ AST en = #( [ENTITY_NAME, entityName] );
+ #fromJoin = #( #j, #jt, #en, #a, #o );
+ }
+ // otherwise, we need to actually check the recognized path
+ | { isEntityName( #p ) }? {
+ if ( #f != null ) {
+ throw new org.hibernate.QueryException( "Cannot use fetch keyword in conjunction with an ad hoc join" );
+ }
+ String entityName = extractEntityName( #p );
+ AST en = #( [ENTITY_NAME, entityName] );
+ #fromJoin = #( #j, #jt, #en, #a );
+ }
+ | (pf:propertyFetch)? (w:withClause)? {
+ #fromJoin = #( #j, #jt, #f, #a, #pf, #p, #w );
+ }
+ )
;
joinType
@@ -329,6 +359,9 @@
: WITH^ logicalExpression
;
+onFragment
+ : ON^ logicalExpression
+ ;
// Alias rule - Parses the optional 'as' token and forces an AST identifier node.
asAlias
Modified: branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g 2006-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g 2006-07-06 14:59:36 UTC (rev 10088)
@@ -60,23 +60,39 @@
}
- // implicit join context pushing/popping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ // property-path context pushing/popping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- protected void pushExplicitJoinContext(AST joinType, AST fetch, AST alias, AST propertyFetch) {
+ protected void pushFromClausePropertyPathContext(AST joinType, AST fetch, AST alias, AST propertyFetch) {
}
- protected void popExplicitJoinContext() {
+ protected void popFromClausePropertyPathContext() {
}
+ protected void pushOnFragmentPropertyPathContext(AST rhsPersisterReference) {
+ }
+
+ protected void popOnFragmentPropertyPathContext() {
+ }
+
+ protected void pushWithFragmentPropertyPathContext(AST rhsPersisterReference) {
+ }
+
+ protected void popWithFragmentPropertyPathContext() {
+ }
+
+
// persister reference handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected AST buildEntityPersisterReference(AST entityName, AST alias, AST propertyFetch) {
return null;
}
- protected void handleAdHocJoinNode(AST persisterReference, AST joinType, AST onClause) {
+ protected AST buildAdHocJoinNode(AST persisterReference, AST joinType, AST withFragment) {
+ return null;
}
+ protected void applyWithFragment(AST withFragment) {
+ }
// property reference handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -133,12 +149,12 @@
fromClause
- : #( f:FROM range ( explicitJoin | range )* )
+ : #( f:FROM rootFromElement ( explicitJoin | rootFromElement )* )
;
-range!
+rootFromElement!
: #( RANGE e:entityPersisterReference ) {
- #range = #e;
+ #rootFromElement = #e;
}
;
@@ -149,18 +165,22 @@
;
explicitJoin!
- : #(JOIN (jt:joinType)? joinRhs[jt] )
+ : #(
+ j:JOIN (jt:joinType)?
+ (
+ e:entityPersisterReference (on:onFragment[#e])? {
+ buildAdHocJoinNode( #e, #jt, #on );
+ if ( on != null ) {
+ popOnFragmentPropertyPathContext();
+ }
+ }
+ | (f:FETCH)? (a:ALIAS)? (pf:PROP_FETCH)? { pushFromClausePropertyPathContext( jt, #f, #a, #pf ); } prop:propertyPath (with:withFragment[#prop])? {
+ popFromClausePropertyPathContext();
+ }
+ )
+ )
;
-joinRhs! [AST joinType]
- : e:entityPersisterReference (on:ON)? {
- handleAdHocJoinNode( #e, joinType, on );
- }
- | (f:FETCH)? (a:ALIAS)? (pf:PROP_FETCH)? { pushExplicitJoinContext( joinType, #f, #a, #pf ); } prop:propertyPath (with:WITH)? {
- popExplicitJoinContext();
- }
- ;
-
// TODO : still need to account for index operators in this series of rules...
propertyPath
: singlePartPropertyPath
@@ -202,6 +222,21 @@
| INNER
;
+onFragment[ AST rhsPersisterReference ]
+ : #( o:ON { pushOnFragmentPropertyPathContext( rhsPersisterReference ); } le:logicalExpr ) {
+ #onFragment = #( o, le );
+ }
+ ;
+
+withFragment[ AST rhsPropertyReference ]
+ : #( w:WITH { pushWithFragmentPropertyPathContext( rhsPropertyReference ); } le:logicalExpr ) {
+ #withFragment = #( w, le );
+ applyWithFragment( #withFragment );
+ popWithFragmentPropertyPathContext();
+ }
+ ;
+
+
intoClause
: #(i:INTO (subtree)* )
;
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractImplicitJoinContext.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractImplicitJoinContext.java 2006-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractImplicitJoinContext.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -1,49 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Provides basic templating around how the two {@link org.hibernate.hql.ast.resolve.ImplicitJoinContext}
- * method calls need to be interpreted and handled in different scenarios.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractImplicitJoinContext implements ImplicitJoinContext {
-
- public static final Log log = LogFactory.getLog( AbstractImplicitJoinContext.class );
-
- private PropertyPathPart prior;
-
- protected abstract PropertyPathPart handleRoot(String rootPathPart);
- protected abstract PropertyReference handleRootAsTerminus(String pathPart);
-
- public final void handleIntermediatePathPart(String pathPart) {
- if ( prior == null ) {
- prior = handleRoot( pathPart );
- }
- else {
- prior = prior.handleIntermediatePathPart( pathPart );
- }
- }
-
- public final PropertyReference handleTerminalPathPart(String pathPart) {
- try {
- if ( prior == null ) {
- return handleRootAsTerminus( pathPart );
- }
- else {
- return prior.handleTerminalPathPart( pathPart );
- }
- }
- finally {
- // clear our processing state in preparation for any future path expression
- prior = null;
- }
- }
-
- protected static interface PropertyPathPart {
- public PropertyPathPart handleIntermediatePathPart(String name);
- public PropertyReference handleTerminalPathPart(String name);
- }
-}
Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractPropertyPathHandler.java (from rev 10070, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractImplicitJoinContext.java)
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractImplicitJoinContext.java 2006-06-30 05:55:55 UTC (rev 10070)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractPropertyPathHandler.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -0,0 +1,72 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.hql.antlr.ResolveTokenTypes;
+import antlr.collections.AST;
+import antlr.ASTFactory;
+
+/**
+ * Provides basic templating around how the two {@link org.hibernate.hql.ast.resolve.PropertyPathHandler}
+ * method calls need to be interpreted and handled in different scenarios.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractPropertyPathHandler implements PropertyPathHandler {
+
+ public static final Log log = LogFactory.getLog( AbstractPropertyPathHandler.class );
+
+ private PropertyPathPart prior;
+
+ protected abstract PropertyPathPart handleRoot(String rootPathPart);
+ protected abstract PropertyReference handleRootAsTerminus(String pathPart);
+
+ protected void cleanup() {
+ }
+
+ public final void handleIntermediatePathPart(String pathPart) {
+ if ( prior == null ) {
+ prior = handleRoot( pathPart );
+ }
+ else {
+ prior = prior.handleIntermediatePathPart( pathPart );
+ }
+ }
+
+ public final PropertyReference handleTerminalPathPart(String pathPart) {
+ try {
+ if ( prior == null ) {
+ return handleRootAsTerminus( pathPart );
+ }
+ else {
+ return prior.handleTerminalPathPart( pathPart );
+ }
+ }
+ finally {
+ // clear our processing state in preparation for any future path expression
+ prior = null;
+ cleanup();
+ }
+ }
+
+
+ protected final PropertyReference generatePropertyReference(
+ PersisterReference persisterReference,
+ String propertyName,
+ ASTFactory astFactory) {
+ PropertyReference propertyReferenceNode = ( PropertyReference ) astFactory.create( ResolveTokenTypes.PROPERTY_REF, persisterReference.getAlias() + "." + propertyName );
+
+ AST aliasNode = astFactory.create( ResolveTokenTypes.ALIAS, persisterReference.getAlias() );
+ propertyReferenceNode.addChild( aliasNode );
+
+ AST propertyNameNode = astFactory.create( ResolveTokenTypes.IDENT, propertyName );
+ propertyReferenceNode.addChild( propertyNameNode );
+
+ return propertyReferenceNode;
+ }
+
+ protected static interface PropertyPathPart {
+ public PropertyPathPart handleIntermediatePathPart(String name);
+ public PropertyReference handleTerminalPathPart(String name);
+ }
+}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java 2006-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -47,18 +47,26 @@
}
public Type getPropertyType(String propertyName) {
- return getEntityPersister().getPropertyType( propertyName );
- }
-
- public boolean containsProperty(String propertyName) {
try {
- return getPropertyType( propertyName ) != null;
+ return getEntityPersister().getPropertyType( propertyName );
}
catch( Throwable t ) {
- return false;
+ return null;
}
}
+ protected PersisterReference producePersisterReference(
+ String propertyName,
+ String alias,
+ boolean propertyFetching,
+ PersisterReferenceBuilder builder) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean containsProperty(String propertyName) {
+ return getPropertyType( propertyName ) != null;
+ }
+
public String toString() {
return "EntityPersisterReference {entity-name=" + entityName + ", alias=" + alias + "}";
}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClauseImplicitJoinContext.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClauseImplicitJoinContext.java 2006-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClauseImplicitJoinContext.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -1,98 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.hibernate.QueryException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * todo: describe FromClauseImplicitJoinContext
- *
- * @author Steve Ebersole
- */
-public class FromClauseImplicitJoinContext extends AbstractImplicitJoinContext {
-
- public static final Log log = LogFactory.getLog( FromClauseImplicitJoinContext.class );
-
- private final PersisterReferenceContext persisterReferenceContext;
- private final PersisterReferenceBuilder persisterReferenceBuilder;
-
- private final JoinType joinType;
- private final String alias;
- private final boolean fetching;
- private final boolean propertyFetching;
-
- public FromClauseImplicitJoinContext(
- PersisterReferenceContext persisterReferenceContext,
- PersisterReferenceBuilder persisterReferenceBuilder,
- JoinType joinType,
- String alias,
- boolean fetching,
- boolean propertyFetching) {
- this.persisterReferenceContext = persisterReferenceContext;
- this.persisterReferenceBuilder = persisterReferenceBuilder;
- this.joinType = joinType;
- this.alias = alias;
- this.fetching = fetching;
- this.propertyFetching = propertyFetching;
- }
-
- protected PropertyPathPart handleRoot(String rootPathPart) {
- log.debug( "attempting to resolve [" + rootPathPart + "] as alias" );
- PersisterReference ref = persisterReferenceContext.locatePersisterReferenceByAlias( rootPathPart );
- if ( ref == null ) {
- log.debug( "attempting to resolve [" + rootPathPart + "] as unqualified property reference" );
- ref = persisterReferenceContext.locatePersisterReferenceExposingProperty( rootPathPart );
- if ( ref == null ) {
- throw new QueryException( "unable to resolve path expression root [" + rootPathPart + "]" );
- }
- else {
- ref = ( PersisterReference ) persisterReferenceBuilder
- .buildPropertyJoin( ref, rootPathPart, joinType, null, fetching, false )
- .getFirstChild();
- }
- }
- return new PathPart( ref );
- }
-
- protected PropertyReference handleRootAsTerminus(String pathPart) {
- // this should only ever mean that we have a simple unqualified property reference
- log.debug( "attempting to resolve [" + pathPart + "] as unqualified property reference" );
- PersisterReference ref = persisterReferenceContext.locatePersisterReferenceExposingProperty( pathPart );
- if ( ref == null ) {
- throw new QueryException( "unable to resolve unqualified property reference [" + pathPart + "]" );
- }
- persisterReferenceBuilder.buildPropertyJoin( ref, pathPart, joinType, alias, fetching, propertyFetching );
-
- // for joins in the from clause, we dont care about the property ref...
- return null;
- }
-
- private class PathPart implements PropertyPathPart {
- private final PersisterReference persisterReference;
-
- public PathPart(PersisterReference persisterReference) {
- this.persisterReference = persisterReference;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- return new PathPart( ( PersisterReference ) buildJoin( name, null, false ).getFirstChild() );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- buildJoin( name, alias, propertyFetching );
- // for joins in the from clause, we dont care about the property ref...
- return null;
- }
-
- private JoinNode buildJoin(String name, String alias, boolean propertyFetching) {
- return persisterReferenceBuilder.buildPropertyJoin(
- persisterReference,
- name,
- joinType,
- alias,
- fetching,
- propertyFetching
- );
- }
- }
-}
Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClausePropertyPathHandler.java (from rev 10070, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClauseImplicitJoinContext.java)
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClauseImplicitJoinContext.java 2006-06-30 05:55:55 UTC (rev 10070)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClausePropertyPathHandler.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -0,0 +1,134 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.QueryException;
+import org.hibernate.type.Type;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * todo: describe FromClausePropertyPathHandler
+ *
+ * @author Steve Ebersole
+ */
+public class FromClausePropertyPathHandler extends AbstractPropertyPathHandler {
+
+ public static final Log log = LogFactory.getLog( FromClausePropertyPathHandler.class );
+
+ private final PersisterReferenceContext persisterReferenceContext;
+ private final PersisterReferenceBuilder persisterReferenceBuilder;
+
+ private final JoinType joinType;
+ private final String alias;
+ private final boolean fetching;
+ private final boolean propertyFetching;
+
+ public FromClausePropertyPathHandler(
+ PersisterReferenceContext persisterReferenceContext,
+ PersisterReferenceBuilder persisterReferenceBuilder,
+ JoinType joinType,
+ String alias,
+ boolean fetching,
+ boolean propertyFetching) {
+ this.persisterReferenceContext = persisterReferenceContext;
+ this.persisterReferenceBuilder = persisterReferenceBuilder;
+ this.joinType = joinType;
+ this.alias = alias;
+ this.fetching = fetching;
+ this.propertyFetching = propertyFetching;
+ }
+
+ protected PropertyPathPart handleRoot(String rootPathPart) {
+ log.debug( "attempting to resolve [" + rootPathPart + "] as alias" );
+ PersisterReference ref = persisterReferenceContext.locatePersisterReferenceByAlias( rootPathPart );
+ if ( ref == null ) {
+ log.debug( "attempting to resolve [" + rootPathPart + "] as unqualified property reference" );
+ ref = persisterReferenceContext.locatePersisterReferenceExposingProperty( rootPathPart );
+ if ( ref == null ) {
+ throw new QueryException( "unable to resolve path expression root [" + rootPathPart + "]" );
+ }
+ else {
+ ref = ( PersisterReference ) persisterReferenceBuilder
+ .buildPropertyJoin( ref, rootPathPart, joinType, null, fetching, false )
+ .getFirstChild();
+ }
+ }
+ return new PathPart( ref );
+ }
+
+ protected PropertyReference handleRootAsTerminus(String pathPart) {
+ // this should only ever mean that we have a simple unqualified property reference
+ log.debug( "attempting to resolve [" + pathPart + "] as unqualified property reference" );
+ PersisterReference ref = persisterReferenceContext.locatePersisterReferenceExposingProperty( pathPart );
+ if ( ref == null ) {
+ throw new QueryException( "unable to resolve unqualified property reference [" + pathPart + "]" );
+ }
+ JoinNode join = persisterReferenceBuilder.buildPropertyJoin( ref, pathPart, joinType, alias, fetching, propertyFetching );
+
+ return new PropertyReferenceAdapter( ref, pathPart, join.getRhs() );
+ }
+
+ private class PathPart implements PropertyPathPart {
+ private final PersisterReference persisterReference;
+
+ public PathPart(PersisterReference persisterReference) {
+ this.persisterReference = persisterReference;
+ }
+
+ public PropertyPathPart handleIntermediatePathPart(String name) {
+ return new PathPart( ( PersisterReference ) buildJoin( name, null, false ).getFirstChild() );
+ }
+
+ public PropertyReference handleTerminalPathPart(String name) {
+ JoinNode join = buildJoin( name, alias, propertyFetching );
+ return new PropertyReferenceAdapter( persisterReference, name, join.getRhs() );
+ }
+
+ private JoinNode buildJoin(String name, String alias, boolean propertyFetching) {
+ return persisterReferenceBuilder.buildPropertyJoin(
+ persisterReference,
+ name,
+ joinType,
+ alias,
+ fetching,
+ propertyFetching
+ );
+ }
+ }
+
+ public static class PropertyReferenceAdapter extends PropertyReference {
+
+ private final PersisterReference lhs;
+ private final String propertyName;
+ private final PersisterReference rhs;
+
+ public PropertyReferenceAdapter(PersisterReference lhs, String propertyName, PersisterReference rhs) {
+ this.lhs = lhs;
+ this.propertyName = propertyName;
+ this.rhs = rhs;
+ }
+
+ public String getOriginationAlias() {
+ return lhs.getAlias();
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public PersisterReference getOrigination() {
+ return lhs;
+ }
+
+ public Type getPropertyType() {
+ return lhs.getPropertyType( propertyName );
+ }
+
+ public PersisterReference getRhs() {
+ return rhs;
+ }
+
+ public String getDisplayText() {
+ return " ADPATER : SHOULD NEVER END UP IN TREE {origin=" + getOrigination().getText() + ", name=" + getPropertyName() + ", type=" + getPropertyType().getName() + "}";
+ }
+ }
+}
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-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -1,6 +1,8 @@
package org.hibernate.hql.ast.resolve;
import org.hibernate.hql.antlr.GeneratedHqlResolver;
+import org.hibernate.hql.antlr.ResolveTokenTypes;
+import org.hibernate.hql.ast.util.ASTPrinter;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.QueryException;
@@ -8,6 +10,7 @@
import org.apache.commons.logging.LogFactory;
import antlr.collections.AST;
+import antlr.Token;
import java.util.LinkedList;
@@ -18,24 +21,26 @@
* @author Joshua Davis
* @author Steve Ebersole
*/
-public class HqlResolver extends GeneratedHqlResolver implements HqlResolverASTFactory.Context {
+public class HqlResolver extends GeneratedHqlResolver
+ implements HqlResolverASTFactory.InjectionContext, PersisterReferenceBuilder.Listener {
private static Log log = LogFactory.getLog( HqlResolver.class );
+ private static final ASTPrinter printer = new ASTPrinter( ResolveTokenTypes.class ).setShowClassNames( false );
private final SessionFactoryImplementor sessionFactory;
private final PersisterReferenceBuilder persisterReferenceBuilder;
private StatementNode currentStatement;
- private ImplicitJoinContextTracker implicitJoinContextTracker = new ImplicitJoinContextTracker();
+ private PropertyPathHandlerStack propertyPathHandlerStack = new PropertyPathHandlerStack();
public HqlResolver(SessionFactoryImplementor sessionFactory) {
super();
this.sessionFactory = sessionFactory;
setASTFactory( new HqlResolverASTFactory( this ) );
- persisterReferenceBuilder = new PersisterReferenceBuilder( getASTFactory(), sessionFactory );
+ persisterReferenceBuilder = new PersisterReferenceBuilder( getASTFactory(), sessionFactory, this );
}
- // HqlResolverASTFactory.Context implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ // HqlResolverASTFactory.InjectionContext implementation ~~~~~~~~~~~~~~~~~~
public SessionFactoryImplementor getSessionFactory() {
return sessionFactory;
@@ -46,6 +51,13 @@
}
+ // PersisterReferenceBuilder.Listener implementation ~~~~~~~~~~~~~~~~~~~~~~
+
+ public void persisterReferenceBuilt(PersisterReference persisterReference) {
+ currentStatement.registerPersisterReference( persisterReference );
+ }
+
+
// semantic action implementations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
@@ -56,9 +68,8 @@
protected void pushStatement(AST statementNode) {
log.trace( "pushing new statement context : " + currentStatement + " -> " + statementNode );
StatementNode statement = ( StatementNode ) statementNode;
- statement.setPersisterReferenceBuilder( persisterReferenceBuilder );
- implicitJoinContextTracker.push(
- new NormalImplicitJoinContext( statement, persisterReferenceBuilder, getASTFactory() )
+ propertyPathHandlerStack.push(
+ new NormalPropertyPathHandler( statement, persisterReferenceBuilder, getASTFactory() )
);
if ( currentStatement != null ) {
currentStatement.pushChild( statement );
@@ -72,13 +83,13 @@
protected void popStatement() {
log.trace( "popping statement context : " + currentStatement + " -> " + currentStatement.getParentStatement() );
currentStatement = currentStatement.getParentStatement();
- implicitJoinContextTracker.pop();
+ propertyPathHandlerStack.pop( NormalPropertyPathHandler.class );
}
- protected void pushExplicitJoinContext(AST joinTypeNode, AST fetch, AST alias, AST propertyFetch) {
- log.debug( "pushing explicit (from-clause) implicit join context" );
- implicitJoinContextTracker.push(
- new FromClauseImplicitJoinContext(
+ protected void pushFromClausePropertyPathContext(AST joinTypeNode, AST fetch, AST alias, AST propertyFetch) {
+ log.debug( "pushing explicit (from clause) property path context" );
+ propertyPathHandlerStack.push(
+ new FromClausePropertyPathHandler(
currentStatement,
persisterReferenceBuilder,
resolveJoinType( joinTypeNode ),
@@ -89,11 +100,49 @@
);
}
- protected void popExplicitJoinContext() {
- log.debug( "popping implicit join context" );
- implicitJoinContextTracker.pop();
+ protected void popFromClausePropertyPathContext() {
+ log.debug( "popping explicit (from clause) property path context" );
+ propertyPathHandlerStack.pop( FromClausePropertyPathHandler.class );
}
+ protected void pushOnFragmentPropertyPathContext(AST rhsPersisterReference) {
+ propertyPathHandlerStack.push(
+ new OnFragmentPropertyPathHandler(
+ currentStatement,
+ ( PersisterReference ) rhsPersisterReference,
+ astFactory,
+ sessionFactory
+ )
+ );
+ log.debug( "pushing on-fragment path handler [rhs=" + rhsPersisterReference.getText() + "]" );
+ }
+
+ protected void popOnFragmentPropertyPathContext() {
+ log.debug( "popping on-fragment path handler" );
+ propertyPathHandlerStack.pop( OnFragmentPropertyPathHandler.class );
+ }
+
+ protected void pushWithFragmentPropertyPathContext(AST rhsPropertyReference) {
+ // can only be used in conjunction with property reference generated
+ // directly from FromClausePropertyPathHandler...
+ FromClausePropertyPathHandler.PropertyReferenceAdapter propertyReference = ( FromClausePropertyPathHandler.PropertyReferenceAdapter ) rhsPropertyReference;
+ propertyPathHandlerStack.push(
+ new WithFragmentPropertyPathHandler(
+ currentStatement,
+ propertyReference.getOrigination(),
+ propertyReference.getRhs(),
+ astFactory,
+ sessionFactory
+ )
+ );
+ log.debug( "pushing with-fragment path handler" );
+ }
+
+ protected void popWithFragmentPropertyPathContext() {
+ log.debug( "popping on-fragment path handler" );
+ propertyPathHandlerStack.pop( WithFragmentPropertyPathHandler.class );
+ }
+
/**
* Semantic action called to perform generation of an {@link EntityPersisterReference}
* representing a "root" persister reference.
@@ -117,34 +166,40 @@
return node == null ? null : node.getText();
}
- private JoinNode createJoinNode(JoinType type, JoinSource source, boolean fetch, PersisterReference rhs) {
+ private JoinNode createJoinNode(JoinType type, String propertyName, boolean fetch, PersisterReference lhs) {
JoinNode node = ( JoinNode ) getASTFactory().create( JOIN, "join" );
- node.initialize( type, source, fetch, rhs );
- rhs.addChild( node );
+ node.initialize( type, propertyName, fetch, lhs );
+ lhs.addChild( node );
return node;
}
protected void handleIntermediatePathPart(AST name) {
log.debug( "handling intermediate path part [" + name.getText() + "]" );
- implicitJoinContextTracker.getCurrent().handleIntermediatePathPart( name.getText() );
+ propertyPathHandlerStack.getCurrent().handleIntermediatePathPart( name.getText() );
}
protected AST handleTerminalPathPart(AST name) {
log.debug( "handling terminal path part [" + name.getText() + "]" );
- return implicitJoinContextTracker.getCurrent().handleTerminalPathPart( name.getText() );
+ return propertyPathHandlerStack.getCurrent().handleTerminalPathPart( name.getText() );
}
- protected void handleAdHocJoinNode(AST persisterReference, AST joinType, AST onClause) {
- // todo : need to be able to resolve the lhs join operand
- EntityPersisterReference other = null;
- JoinNode join = createJoinNode( resolveJoinType( joinType ), JoinSource.AD_HOC, false, other );
- join.setFirstChild( persisterReference );
- if ( onClause != null ) {
- join.addChild( onClause );
- }
+ protected AST buildAdHocJoinNode(AST rhs, AST joinTypeNode, AST onClause) {
+ log.debug( printer.showAsString( onClause, "ON fragment for ad hoc join building" ) );
+ JoinType joinType = resolveJoinType( joinTypeNode );
+ OnFragmentPropertyPathHandler handler = ( OnFragmentPropertyPathHandler ) propertyPathHandlerStack.getCurrent();
+ EntityPersisterReference lhs = ( EntityPersisterReference ) handler.getDiscoveredLhs();
+ JoinNode join = createJoinNode( joinType, null, false, lhs );
+ join.setFirstChild( rhs );
+ join.applyExplicitJoinConditions( onClause );
+ return join;
}
+ protected void applyWithFragment(AST withFragment) {
+ WithFragmentPropertyPathHandler handler = ( WithFragmentPropertyPathHandler ) propertyPathHandlerStack.getCurrent();
+ handler.applyWithFragment( withFragment );
+ }
+
private JoinType resolveJoinType(AST joinType) {
int joinTypeType = joinType == null ? INNER : joinType.getType();
switch ( joinTypeType ) {
@@ -173,22 +228,30 @@
return buffer.toString();
}
- private class ImplicitJoinContextTracker {
+ private class PropertyPathHandlerStack {
private LinkedList stack = new LinkedList();
- public ImplicitJoinContextTracker() {
+ public PropertyPathHandlerStack() {
}
- public void push(ImplicitJoinContext context) {
+ public void push(PropertyPathHandler context) {
stack.addFirst( context );
}
- public void pop() {
- stack.removeFirst();
+ public void pop(Class expectedCurrentHandlerClass) {
+ PropertyPathHandler handler = ( PropertyPathHandler ) stack.removeFirst();
+ if ( !expectedCurrentHandlerClass.isInstance( handler ) ) {
+ throw new IllegalStateException(
+ "INTERNAL PARSER ERROR : unexpected property path handler type encountered on pop" +
+ " [expecting=" + expectedCurrentHandlerClass.getName() +
+ ", encountered=" + handler.getClass().getName() + "]"
+ );
+ }
+ log.debug( "popped path handler; current now : " + ( stack.isEmpty() ? null : getCurrent() ) );
}
- public ImplicitJoinContext getCurrent() {
- return ( ImplicitJoinContext ) stack.getFirst();
+ public PropertyPathHandler getCurrent() {
+ return ( PropertyPathHandler ) stack.getFirst();
}
}
}
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-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -17,14 +17,14 @@
*/
public class HqlResolverASTFactory extends HqlASTFactory implements ResolveTokenTypes {
- public static interface Context {
+ public static interface InjectionContext {
public SessionFactoryImplementor getSessionFactory();
public PersisterReferenceContext getPersisterReferenceContext();
}
- private final Context context;
+ private final InjectionContext context;
- public HqlResolverASTFactory(Context context) {
+ public HqlResolverASTFactory(InjectionContext context) {
this.context = context;
}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ImplicitJoinContext.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ImplicitJoinContext.java 2006-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ImplicitJoinContext.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -1,11 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-/**
- * Contract for how implicit joins are handled.
- *
- * @author Steve Ebersole
- */
-public interface ImplicitJoinContext {
- public void handleIntermediatePathPart(String pathPart);
- public PropertyReference handleTerminalPathPart(String pathPart);
-}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -1,6 +1,7 @@
package org.hibernate.hql.ast.resolve;
import antlr.Token;
+import antlr.collections.AST;
import org.hibernate.hql.ast.tree.Node;
import org.hibernate.hql.ast.tree.DisplayableNode;
@@ -18,7 +19,7 @@
// to both the left-hand and right-hand persister references
private JoinType joinType;
- private JoinSource source;
+ private String propertyName;
private boolean fetch;
private PersisterReference lhs;
@@ -26,14 +27,9 @@
super.setText( "join" );
}
- public JoinNode(Token tok) {
- super( tok );
- super.setText( "join" );
- }
-
- public void initialize(JoinType joinType, JoinSource source, boolean fetch, PersisterReference lhs) {
+ public void initialize(JoinType joinType, String propertyName, boolean fetch, PersisterReference lhs) {
this.joinType = joinType;
- this.source = source;
+ this.propertyName = propertyName;
this.fetch = fetch;
this.lhs = lhs;
}
@@ -46,14 +42,6 @@
this.joinType = joinType;
}
- public JoinSource getSource() {
- return source;
- }
-
- public void setSource(JoinSource source) {
- this.source = source;
- }
-
public boolean isFetch() {
return fetch;
}
@@ -62,8 +50,27 @@
this.fetch = fetch;
}
+ public PersisterReference getLhs() {
+ return lhs;
+ }
+
+ public PersisterReference getRhs() {
+ return ( PersisterReference ) getFirstChild();
+ }
+
+ public AST getExplicitJoinConditions() {
+ return getFirstChild().getNextSibling();
+ }
+
+ public void applyExplicitJoinConditions(AST conditions) {
+ getFirstChild().setNextSibling( conditions );
+ }
+
public String getDisplayText() {
- return "{" + "type=" + joinType + ", source=" + source + ", fetch=" + fetch + ", lhs=" + lhs.getAlias() + "}";
+ return "{" + "type=" + joinType +
+ ", fetch=" + fetch +
+ ", lhs=" + ( lhs == null ? "???" : lhs.getAlias() ) +
+ ", property=" + ( propertyName == null ? "n/a" : propertyName ) + "}";
}
public String toString() {
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinSource.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinSource.java 2006-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinSource.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -1,55 +0,0 @@
-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 );
- }
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalImplicitJoinContext.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalImplicitJoinContext.java 2006-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalImplicitJoinContext.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -1,236 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.hql.antlr.ResolveTokenTypes;
-import org.hibernate.hql.CollectionProperties;
-import org.hibernate.QueryException;
-import org.hibernate.type.Type;
-import org.hibernate.type.ComponentType;
-import antlr.ASTFactory;
-import antlr.collections.AST;
-
-/**
- * Defines the behavior of how implicit joins are normally handled.
- * <p/>
- * All other implementations of {@link org.hibernate.hql.ast.resolve.ImplicitJoinContext} are
- * considered special cases.
- *
- * @author Steve Ebersole
- */
-public class NormalImplicitJoinContext extends AbstractImplicitJoinContext {
-
- public static final Log log = LogFactory.getLog( NormalImplicitJoinContext.class );
-
- private final PersisterReferenceContext persisterReferenceContext;
- private final PersisterReferenceBuilder persisterReferenceBuilder;
- private final ASTFactory astFactory;
-
- private PropertyPathPart prior;
-
- public NormalImplicitJoinContext(
- PersisterReferenceContext persisterReferenceContext,
- PersisterReferenceBuilder persisterReferenceBuilder,
- ASTFactory astFactory) {
- this.persisterReferenceContext = persisterReferenceContext;
- this.persisterReferenceBuilder = persisterReferenceBuilder;
- this.astFactory = astFactory;
- }
-
- protected PropertyPathPart handleRoot(String pathPart) {
- PersisterReference persisterReference = resolveAsAlias( pathPart );
- if ( persisterReference != null ) {
- return new PropertyPathRoot( ( EntityPersisterReference ) persisterReference );
- }
-
- persisterReference = resolveAsUnqualified( pathPart );
- if ( persisterReference != null ) {
- return new EntityPropertyReference( ( EntityPersisterReference ) persisterReference, pathPart, false );
- }
-
- throw new QueryException( "unable to resolve path expression root [" + pathPart + "]" );
- }
-
- protected PropertyReference handleRootAsTerminus(String pathPart) {
- PersisterReference ref = resolveAsUnqualified( pathPart );
- return generatePropertyReference( ref, pathPart );
- }
-
-
-
-
- private PropertyReference generatePropertyReference(PersisterReference persisterReference, String propertyName) {
- PropertyReference propertyReferenceNode = ( PropertyReference ) astFactory.create( ResolveTokenTypes.PROPERTY_REF, persisterReference.getAlias() + "." + propertyName );
-
- AST aliasNode = astFactory.create( ResolveTokenTypes.ALIAS, persisterReference.getAlias() );
- propertyReferenceNode.addChild( aliasNode );
-
- AST propertyNameNode = astFactory.create( ResolveTokenTypes.IDENT, propertyName );
- propertyReferenceNode.addChild( propertyNameNode );
-
- return propertyReferenceNode;
- }
-
- private EntityPersisterReference resolveAsAlias(String name) {
- return ( EntityPersisterReference ) persisterReferenceContext.locatePersisterReferenceByAlias( name );
- }
-
- private EntityPersisterReference resolveAsUnqualified(String firstPathExpression) {
- return persisterReferenceContext.locatePersisterReferenceExposingProperty( firstPathExpression );
- }
-
- private PropertyPathPart determineAppropriatePartType(EntityPersisterReference origin, String propertyName) {
- Type propertyType = origin.getPropertyType( propertyName );
- if ( propertyType.isComponentType() ) {
- return new ComponentPropertyReference( origin, propertyName, ( ComponentType ) propertyType );
- }
- else if ( propertyType.isEntityType() ) {
- return new EntityPropertyReference( origin, propertyName, false );
- }
- else if ( propertyType.isCollectionType() ) {
- return new CollectionPropertyReference( origin, propertyName );
- }
- else {
- return new SimplePropertyReference( origin, propertyName );
- }
- }
-
- private int locateComponentPropertyIndex(ComponentType componentType, String subPropertyName) {
- String[] componentPropertyNames = componentType.getPropertyNames();
- for ( int i = 0; i < componentPropertyNames.length; i++ ) {
- if ( componentPropertyNames[i].equals( subPropertyName ) ) {
- return i;
- }
- }
- throw new QueryException( "could not locate component property [" + subPropertyName + "]" );
- }
-
- private class PropertyPathRoot implements PropertyPathPart {
- private final EntityPersisterReference persisterReference;
-
- public PropertyPathRoot(EntityPersisterReference persisterReference) {
- this.persisterReference = persisterReference;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- return determineAppropriatePartType( persisterReference, name );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- // todo : this really needs to consider whether a join might be needed
- // based on the property type and type of clause
- return generatePropertyReference( persisterReference, name );
- }
-
- }
-
- private class SimplePropertyReference implements PropertyPathPart {
- private final EntityPersisterReference origin;
- private final String propertyName;
-
- public SimplePropertyReference(EntityPersisterReference origin, String propertyName) {
- this.origin = origin;
- this.propertyName = propertyName;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- throw new QueryException( "cannot perform implicit join based on simple property" );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- throw new QueryException( "cannot perform implicit join based on simple property" );
- }
- }
-
- private class ComponentPropertyReference implements PropertyPathPart {
- private final EntityPersisterReference origin;
- private final String componentPropertyName;
- private final ComponentType componentType;
-
- public ComponentPropertyReference(EntityPersisterReference origin, String componentPropertyName) {
- this( origin, componentPropertyName, ( ComponentType ) origin.getPropertyType( componentPropertyName ) );
- }
-
- public ComponentPropertyReference(EntityPersisterReference origin, String componentPropertyName, ComponentType componentType) {
- this.origin = origin;
- this.componentPropertyName = componentPropertyName;
- this.componentType = componentType;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String propertyName) {
- int index = locateComponentPropertyIndex( componentType, propertyName );
- String path = buildDerefPath( propertyName );
- Type propertyType = componentType.getSubtypes()[index];
- if ( propertyType.isComponentType() ) {
- return new ComponentPropertyReference( origin, path, ( ComponentType ) propertyType );
- }
- else if ( propertyType.isEntityType() ) {
- return new EntityPropertyReference( origin, path, false );
- }
- else {
- return new SimplePropertyReference( origin, path );
- }
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- return generatePropertyReference( origin, buildDerefPath( name ) );
- }
-
- private String buildDerefPath(String subPropertyName) {
- return componentPropertyName + "." + subPropertyName;
- }
- }
-
- private class EntityPropertyReference implements PropertyPathPart {
- private final EntityPersisterReference origin;
- private final String propertyName;
-
- private boolean joined;
-
- public EntityPropertyReference(EntityPersisterReference origin, String propertyName, boolean joined) {
- this.origin = origin;
- this.propertyName = propertyName;
- this.joined = joined;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- EntityPersisterReference joinedPersister = ( EntityPersisterReference ) buildPropertyJoin( origin, propertyName );
- return determineAppropriatePartType( joinedPersister, name );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- // not always needed (i.e. : .id)
- EntityPersisterReference joinedPersister = ( EntityPersisterReference ) buildPropertyJoin( origin, propertyName );
- return generatePropertyReference( joinedPersister, name );
- }
- }
-
- private class CollectionPropertyReference implements PropertyPathPart {
- private final EntityPersisterReference origin;
- private final String collectionPropertyName;
-
- public CollectionPropertyReference(EntityPersisterReference origin, String collectionPropertyName) {
- this.origin = origin;
- this.collectionPropertyName = collectionPropertyName;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- throw new QueryException( "illegal attempt to perform implicit join across collection property" );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- if ( CollectionProperties.isAnyCollectionProperty( name ) ) {
- CollectionPersisterReference joinedPersister = ( CollectionPersisterReference ) buildPropertyJoin( origin, collectionPropertyName );
- return generatePropertyReference( joinedPersister, name );
- }
- throw new QueryException( "illegal attempt to perform implicit join across collection property" );
- }
- }
-
-
- private PersisterReference buildPropertyJoin(EntityPersisterReference origin, String propertyName) {
- return ( PersisterReference ) persisterReferenceBuilder
- .buildPropertyJoin( origin, propertyName, JoinType.INNER, null, false, false )
- .getFirstChild();
- }
-}
Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalPropertyPathHandler.java (from rev 10070, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalImplicitJoinContext.java)
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalImplicitJoinContext.java 2006-06-30 05:55:55 UTC (rev 10070)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalPropertyPathHandler.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -0,0 +1,218 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.hql.CollectionProperties;
+import org.hibernate.QueryException;
+import org.hibernate.type.Type;
+import org.hibernate.type.ComponentType;
+import antlr.ASTFactory;
+
+/**
+ * Defines the behavior of how implicit joins are normally handled.
+ * <p/>
+ * All other implementations of {@link org.hibernate.hql.ast.resolve.PropertyPathHandler} are
+ * considered special cases.
+ *
+ * @author Steve Ebersole
+ */
+public class NormalPropertyPathHandler extends AbstractPropertyPathHandler {
+
+ public static final Log log = LogFactory.getLog( NormalPropertyPathHandler.class );
+
+ private final PersisterReferenceContext persisterReferenceContext;
+ private final PersisterReferenceBuilder persisterReferenceBuilder;
+ private final ASTFactory astFactory;
+
+ public NormalPropertyPathHandler(
+ PersisterReferenceContext persisterReferenceContext,
+ PersisterReferenceBuilder persisterReferenceBuilder,
+ ASTFactory astFactory) {
+ this.persisterReferenceContext = persisterReferenceContext;
+ this.persisterReferenceBuilder = persisterReferenceBuilder;
+ this.astFactory = astFactory;
+ }
+
+ protected PropertyPathPart handleRoot(String pathPart) {
+ PersisterReference persisterReference = resolveAsAlias( pathPart );
+ if ( persisterReference != null ) {
+ return new PropertyPathRoot( ( EntityPersisterReference ) persisterReference );
+ }
+
+ persisterReference = resolveAsUnqualified( pathPart );
+ if ( persisterReference != null ) {
+ return new EntityPropertyReference( ( EntityPersisterReference ) persisterReference, pathPart, false );
+ }
+
+ throw new QueryException( "unable to resolve path expression root [" + pathPart + "]" );
+ }
+
+ protected PropertyReference handleRootAsTerminus(String pathPart) {
+ PersisterReference ref = resolveAsUnqualified( pathPart );
+ return generatePropertyReference( ref, pathPart, astFactory );
+ }
+
+
+ private EntityPersisterReference resolveAsAlias(String name) {
+ return ( EntityPersisterReference ) persisterReferenceContext.locatePersisterReferenceByAlias( name );
+ }
+
+ private EntityPersisterReference resolveAsUnqualified(String firstPathExpression) {
+ return persisterReferenceContext.locatePersisterReferenceExposingProperty( firstPathExpression );
+ }
+
+ private PropertyPathPart determineAppropriatePartType(EntityPersisterReference origin, String propertyName) {
+ Type propertyType = origin.getPropertyType( propertyName );
+ if ( propertyType.isComponentType() ) {
+ return new ComponentPropertyReference( origin, propertyName, ( ComponentType ) propertyType );
+ }
+ else if ( propertyType.isEntityType() ) {
+ return new EntityPropertyReference( origin, propertyName, false );
+ }
+ else if ( propertyType.isCollectionType() ) {
+ return new CollectionPropertyReference( origin, propertyName );
+ }
+ else {
+ return new SimplePropertyReference( origin, propertyName );
+ }
+ }
+
+ private int locateComponentPropertyIndex(ComponentType componentType, String subPropertyName) {
+ String[] componentPropertyNames = componentType.getPropertyNames();
+ for ( int i = 0; i < componentPropertyNames.length; i++ ) {
+ if ( componentPropertyNames[i].equals( subPropertyName ) ) {
+ return i;
+ }
+ }
+ throw new QueryException( "could not locate component property [" + subPropertyName + "]" );
+ }
+
+ private class PropertyPathRoot implements PropertyPathPart {
+ private final EntityPersisterReference persisterReference;
+
+ public PropertyPathRoot(EntityPersisterReference persisterReference) {
+ this.persisterReference = persisterReference;
+ }
+
+ public PropertyPathPart handleIntermediatePathPart(String name) {
+ return determineAppropriatePartType( persisterReference, name );
+ }
+
+ public PropertyReference handleTerminalPathPart(String name) {
+ // todo : this really needs to consider whether a join might be needed
+ // based on the property type and type of clause
+ return generatePropertyReference( persisterReference, name, astFactory );
+ }
+
+ }
+
+ private class SimplePropertyReference implements PropertyPathPart {
+ private final EntityPersisterReference origin;
+ private final String propertyName;
+
+ public SimplePropertyReference(EntityPersisterReference origin, String propertyName) {
+ this.origin = origin;
+ this.propertyName = propertyName;
+ }
+
+ public PropertyPathPart handleIntermediatePathPart(String name) {
+ throw new QueryException( "cannot perform implicit join based on simple property" );
+ }
+
+ public PropertyReference handleTerminalPathPart(String name) {
+ throw new QueryException( "cannot perform implicit join based on simple property" );
+ }
+ }
+
+ private class ComponentPropertyReference implements PropertyPathPart {
+ private final EntityPersisterReference origin;
+ private final String componentPropertyName;
+ private final ComponentType componentType;
+
+ public ComponentPropertyReference(EntityPersisterReference origin, String componentPropertyName) {
+ this( origin, componentPropertyName, ( ComponentType ) origin.getPropertyType( componentPropertyName ) );
+ }
+
+ public ComponentPropertyReference(EntityPersisterReference origin, String componentPropertyName, ComponentType componentType) {
+ this.origin = origin;
+ this.componentPropertyName = componentPropertyName;
+ this.componentType = componentType;
+ }
+
+ public PropertyPathPart handleIntermediatePathPart(String propertyName) {
+ int index = locateComponentPropertyIndex( componentType, propertyName );
+ String path = buildDerefPath( propertyName );
+ Type propertyType = componentType.getSubtypes()[index];
+ if ( propertyType.isComponentType() ) {
+ return new ComponentPropertyReference( origin, path, ( ComponentType ) propertyType );
+ }
+ else if ( propertyType.isEntityType() ) {
+ return new EntityPropertyReference( origin, path, false );
+ }
+ else {
+ return new SimplePropertyReference( origin, path );
+ }
+ }
+
+ public PropertyReference handleTerminalPathPart(String name) {
+ return generatePropertyReference( origin, buildDerefPath( name ), astFactory );
+ }
+
+ private String buildDerefPath(String subPropertyName) {
+ return componentPropertyName + "." + subPropertyName;
+ }
+ }
+
+ private class EntityPropertyReference implements PropertyPathPart {
+ private final EntityPersisterReference origin;
+ private final String propertyName;
+
+ private boolean joined;
+
+ public EntityPropertyReference(EntityPersisterReference origin, String propertyName, boolean joined) {
+ this.origin = origin;
+ this.propertyName = propertyName;
+ this.joined = joined;
+ }
+
+ public PropertyPathPart handleIntermediatePathPart(String name) {
+ EntityPersisterReference joinedPersister = ( EntityPersisterReference ) buildPropertyJoin( origin, propertyName );
+ return determineAppropriatePartType( joinedPersister, name );
+ }
+
+ public PropertyReference handleTerminalPathPart(String name) {
+ // not always needed (i.e. : .id)
+ EntityPersisterReference joinedPersister = ( EntityPersisterReference ) buildPropertyJoin( origin, propertyName );
+ return generatePropertyReference( joinedPersister, name, astFactory );
+ }
+ }
+
+ private class CollectionPropertyReference implements PropertyPathPart {
+ private final EntityPersisterReference origin;
+ private final String collectionPropertyName;
+
+ public CollectionPropertyReference(EntityPersisterReference origin, String collectionPropertyName) {
+ this.origin = origin;
+ this.collectionPropertyName = collectionPropertyName;
+ }
+
+ public PropertyPathPart handleIntermediatePathPart(String name) {
+ throw new QueryException( "illegal attempt to perform implicit join across collection property" );
+ }
+
+ public PropertyReference handleTerminalPathPart(String name) {
+ if ( CollectionProperties.isAnyCollectionProperty( name ) ) {
+ CollectionPersisterReference joinedPersister = ( CollectionPersisterReference ) buildPropertyJoin( origin, collectionPropertyName );
+ return generatePropertyReference( joinedPersister, name, astFactory );
+ }
+ throw new QueryException( "illegal attempt to perform implicit join across collection property" );
+ }
+ }
+
+
+ private PersisterReference buildPropertyJoin(EntityPersisterReference origin, String propertyName) {
+ return ( PersisterReference ) persisterReferenceBuilder
+ .buildPropertyJoin( origin, propertyName, JoinType.INNER, null, false, false )
+ .getFirstChild();
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/OnFragmentPropertyPathHandler.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/OnFragmentPropertyPathHandler.java 2006-07-06 12:21:30 UTC (rev 10087)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/OnFragmentPropertyPathHandler.java 2006-07-06 14:59:36 UTC (rev 10088)
@@ -0,0 +1,159 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.type.Type;
+import org.hibernate.QueryException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import antlr.ASTFactory;
+
+/**
+ * todo: describe OnFragmentPropertyPathHandler
+ *
+ * @author Steve Ebersole
+ */
+public class OnFragmentPropertyPathHandler extends AbstractPropertyPathHandler {
+
+ public static final Log log = LogFactory.getLog( OnFragmentPropertyPathHandler.class );
+
+ private final PersisterReferenceContext persisterReferenceContext;
+ private final PersisterReference joinRhs;
+ private final ASTFactory astFactory;
+ private final SessionFactoryImplementor sessionFactory;
+
+ private PersisterReference joinLhs;
+
+ public OnFragmentPropertyPathHandler(
+ PersisterReferenceContext persisterReferenceContext,
+ PersisterReference joinRhs,
+ ASTFactory astFactory,
+ SessionFactoryImplementor sessionFactory) {
+ this.astFactory = astFactory;
+ this.persisterReferenceContext = persisterReferenceContext;
+ this.joinRhs = joinRhs;
+ this.sessionFactory = sessionFactory;
+ }
+
+ public PersisterReference getDiscoveredLhs() {
+ return joinLhs;
+ }
+
+ protected PropertyPathPart handleRoot(String rootPathPart) {
+ // might indicte a number of situations:
+ // 1) alias to joinRhs
+ // 2) unq...
[truncated message content] |