1 package org.hibernate.hql.ast.util; 3 4 import java.util.ArrayList ; 5 import java.util.Iterator ; 6 import java.util.ListIterator ; 7 8 import org.hibernate.AssertionFailure; 9 import org.hibernate.engine.JoinSequence; 10 import org.hibernate.hql.antlr.SqlTokenTypes; 11 import org.hibernate.hql.ast.QueryTranslatorImpl; 12 import org.hibernate.hql.ast.tree.FromClause; 13 import org.hibernate.hql.ast.tree.FromElement; 14 import org.hibernate.hql.ast.tree.QueryNode; 15 import org.hibernate.sql.JoinFragment; 16 import org.hibernate.util.StringHelper; 17 18 import antlr.ASTFactory; 19 20 import org.apache.commons.logging.Log; 21 import org.apache.commons.logging.LogFactory; 22 23 30 public class JoinProcessor implements SqlTokenTypes { 31 32 private static final Log log = LogFactory.getLog( JoinProcessor.class ); 33 34 private QueryTranslatorImpl queryTranslatorImpl; 35 private SyntheticAndFactory andFactory; 36 37 43 public JoinProcessor(ASTFactory astFactory, QueryTranslatorImpl queryTranslatorImpl) { 44 this.andFactory = new SyntheticAndFactory( astFactory ); 45 this.queryTranslatorImpl = queryTranslatorImpl; 46 } 47 48 56 public static int toHibernateJoinType(int astJoinType) { 57 switch ( astJoinType ) { 58 case LEFT_OUTER: 59 return JoinFragment.LEFT_OUTER_JOIN; 60 case INNER: 61 return JoinFragment.INNER_JOIN; 62 case RIGHT_OUTER: 63 return JoinFragment.RIGHT_OUTER_JOIN; 64 default: 65 throw new AssertionFailure( "undefined join type " + astJoinType ); 66 } 67 } 68 69 public void processJoins(QueryNode query) { 70 final FromClause fromClause = query.getFromClause(); 71 72 ArrayList orderedFromElements = new ArrayList (); 78 ListIterator liter = fromClause.getFromElements().listIterator( fromClause.getFromElements().size() ); 79 while ( liter.hasPrevious() ) { 80 orderedFromElements.add( liter.previous() ); 81 } 82 83 Iterator iter = orderedFromElements.iterator(); 85 while ( iter.hasNext() ) { 86 final FromElement fromElement = ( FromElement ) iter.next(); 87 JoinSequence join = fromElement.getJoinSequence(); 88 join.setSelector( 89 new JoinSequence.Selector() { 90 public boolean includeSubclasses(String alias) { 91 boolean shallowQuery = queryTranslatorImpl.isShallowQuery(); 92 boolean containsTableAlias = fromClause.containsTableAlias( alias ); 93 boolean includeSubclasses = fromElement.isIncludeSubclasses(); 94 boolean subQuery = fromClause.isSubQuery(); 95 return includeSubclasses && containsTableAlias && !subQuery && !shallowQuery; 96 } 97 } 98 ); 99 addJoinNodes( query, join, fromElement ); 100 } 102 } 103 104 private void addJoinNodes(QueryNode query, JoinSequence join, FromElement fromElement) { 105 JoinFragment joinFragment = join.toJoinFragment( 107 queryTranslatorImpl.getEnabledFilters(), 108 fromElement.useFromFragment(), 109 fromElement.getAdHocOnClauseFragment() 110 ); 111 112 String frag = joinFragment.toFromFragmentString(); 113 String whereFrag = joinFragment.toWhereFragmentString(); 114 115 if ( fromElement.getType() == JOIN_FRAGMENT && 119 ( join.isThetaStyle() || StringHelper.isNotEmpty( whereFrag ) ) ) { 120 fromElement.setType( FROM_FRAGMENT ); 121 } 122 123 if ( fromElement.useFromFragment() ) { 125 String fromFragment = processFromFragment( frag, join ); 126 if ( log.isDebugEnabled() ) log.debug( "Using FROM fragment [" + fromFragment + "]" ); 127 fromElement.setText( fromFragment.trim() ); } 129 andFactory.addWhereFragment( joinFragment, whereFrag, query, fromElement ); 130 } 131 132 private String processFromFragment(String frag, JoinSequence join) { 133 String fromFragment = frag.trim(); 134 if ( fromFragment.startsWith( ", " ) ) { 136 fromFragment = fromFragment.substring( 2 ); 137 } 138 154 return fromFragment; 155 } 156 157 } 158 | Popular Tags |