1 package org.hibernate.hql.classic; 3 4 import org.hibernate.QueryException; 5 import org.hibernate.hql.QueryTranslator; 6 import org.hibernate.persister.entity.Queryable; 7 import org.hibernate.sql.JoinFragment; 8 9 import java.util.HashMap ; 10 import java.util.Map ; 11 12 16 17 public class FromParser implements Parser { 18 19 private final PathExpressionParser peParser = new FromPathExpressionParser(); 20 private String entityName; 21 private String alias; 22 private boolean afterIn; 23 private boolean afterAs; 24 private boolean afterClass; 25 private boolean expectingJoin; 26 private boolean expectingIn; 27 private boolean expectingAs; 28 private boolean afterJoinType; 29 private int joinType; 30 private boolean afterFetch; 31 32 private static final int NONE = -666; 33 34 private static final Map JOIN_TYPES = new HashMap (); 35 36 static { 37 JOIN_TYPES.put( "left", new Integer ( JoinFragment.LEFT_OUTER_JOIN ) ); 38 JOIN_TYPES.put( "right", new Integer ( JoinFragment.RIGHT_OUTER_JOIN ) ); 39 JOIN_TYPES.put( "full", new Integer ( JoinFragment.FULL_JOIN ) ); 40 JOIN_TYPES.put( "inner", new Integer ( JoinFragment.INNER_JOIN ) ); 41 } 42 43 public void token(String token, QueryTranslatorImpl q) throws QueryException { 44 45 String lcToken = token.toLowerCase(); 47 if ( lcToken.equals( "," ) ) { 48 if ( !( expectingJoin | expectingAs ) ) throw new QueryException( "unexpected token: ," ); 49 expectingJoin = false; 50 expectingAs = false; 51 } 52 else if ( lcToken.equals( "join" ) ) { 53 if ( !afterJoinType ) { 54 if ( !( expectingJoin | expectingAs ) ) throw new QueryException( "unexpected token: join" ); 55 joinType = JoinFragment.INNER_JOIN; 57 expectingJoin = false; 58 expectingAs = false; 59 } 60 else { 61 afterJoinType = false; 62 } 63 } 64 else if ( lcToken.equals( "fetch" ) ) { 65 if ( q.isShallowQuery() ) throw new QueryException( QueryTranslator.ERROR_CANNOT_FETCH_WITH_ITERATE ); 66 if ( joinType == NONE ) throw new QueryException( "unexpected token: fetch" ); 67 if ( joinType == JoinFragment.FULL_JOIN || joinType == JoinFragment.RIGHT_OUTER_JOIN ) { 68 throw new QueryException( "fetch may only be used with inner join or left outer join" ); 69 } 70 afterFetch = true; 71 } 72 else if ( lcToken.equals( "outer" ) ) { 73 if ( !afterJoinType || 75 ( joinType != JoinFragment.LEFT_OUTER_JOIN && joinType != JoinFragment.RIGHT_OUTER_JOIN ) 76 ) { 77 throw new QueryException( "unexpected token: outer" ); 78 } 79 } 80 else if ( JOIN_TYPES.containsKey( lcToken ) ) { 81 if ( !( expectingJoin | expectingAs ) ) throw new QueryException( "unexpected token: " + token ); 82 joinType = ( ( Integer ) JOIN_TYPES.get( lcToken ) ).intValue(); 83 afterJoinType = true; 84 expectingJoin = false; 85 expectingAs = false; 86 } 87 else if ( lcToken.equals( "class" ) ) { 88 if ( !afterIn ) throw new QueryException( "unexpected token: class" ); 89 if ( joinType != NONE ) throw new QueryException( "outer or full join must be followed by path expression" ); 90 afterClass = true; 91 } 92 else if ( lcToken.equals( "in" ) ) { 93 if ( !expectingIn ) throw new QueryException( "unexpected token: in" ); 94 afterIn = true; 95 expectingIn = false; 96 } 97 else if ( lcToken.equals( "as" ) ) { 98 if ( !expectingAs ) throw new QueryException( "unexpected token: as" ); 99 afterAs = true; 100 expectingAs = false; 101 } 102 else { 103 104 if ( afterJoinType ) throw new QueryException( "join expected: " + token ); 105 if ( expectingJoin ) throw new QueryException( "unexpected token: " + token ); 106 if ( expectingIn ) throw new QueryException( "in expected: " + token ); 107 108 110 if ( afterAs || expectingAs ) { 111 112 114 118 if ( entityName != null ) { 119 q.setAliasName( token, entityName ); 120 } 121 else { 122 throw new QueryException( "unexpected: as " + token ); 123 } 124 afterAs = false; 125 expectingJoin = true; 126 expectingAs = false; 127 entityName = null; 128 129 } 130 else if ( afterIn ) { 131 132 135 if ( alias == null ) throw new QueryException( "alias not specified for: " + token ); 136 137 if ( joinType != NONE ) throw new QueryException( "outer or full join must be followed by path expression" ); 138 139 if ( afterClass ) { 140 Queryable p = q.getEntityPersisterUsingImports( token ); 142 if ( p == null ) throw new QueryException( "persister not found: " + token ); 143 q.addFromClass( alias, p ); 144 } 145 else { 146 peParser.setJoinType( JoinFragment.INNER_JOIN ); 148 peParser.setUseThetaStyleJoin( true ); 149 ParserHelper.parse( peParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q ); 150 if ( !peParser.isCollectionValued() ) throw new QueryException( "path expression did not resolve to collection: " + token ); 151 String nm = peParser.addFromCollection( q ); 152 q.setAliasName( alias, nm ); 153 } 154 155 alias = null; 156 afterIn = false; 157 afterClass = false; 158 expectingJoin = true; 159 } 160 else { 161 162 167 Queryable p = q.getEntityPersisterUsingImports( token ); 168 if ( p != null ) { 169 if ( joinType != NONE ) throw new QueryException( "outer or full join must be followed by path expression" ); 171 entityName = q.createNameFor( p.getEntityName() ); 172 q.addFromClass( entityName, p ); 173 expectingAs = true; 174 } 175 else if ( token.indexOf( '.' ) < 0 ) { 176 alias = token; 179 expectingIn = true; 180 } 181 else { 182 183 185 188 if ( joinType != NONE ) { 190 peParser.setJoinType( joinType ); 191 } 192 else { 193 peParser.setJoinType( JoinFragment.INNER_JOIN ); 194 } 195 peParser.setUseThetaStyleJoin( q.isSubquery() ); 196 197 ParserHelper.parse( peParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q ); 198 entityName = peParser.addFromAssociation( q ); 199 200 joinType = NONE; 201 peParser.setJoinType( JoinFragment.INNER_JOIN ); 202 203 if ( afterFetch ) { 204 peParser.fetch( q, entityName ); 205 afterFetch = false; 206 } 207 208 expectingAs = true; 209 210 } 211 } 212 } 213 214 } 215 216 public void start(QueryTranslatorImpl q) { 217 entityName = null; 218 alias = null; 219 afterIn = false; 220 afterAs = false; 221 afterClass = false; 222 expectingJoin = false; 223 expectingIn = false; 224 expectingAs = false; 225 joinType = NONE; 226 } 227 228 public void end(QueryTranslatorImpl q) { 229 } 230 231 } 232 | Popular Tags |