📄 fromparser.java
字号:
//$Id: FromParser.java,v 1.17.2.5 2003/11/09 15:42:48 oneovthafew Exp $package net.sf.hibernate.hql;import java.util.HashMap;import java.util.Map;import net.sf.hibernate.QueryException;import net.sf.hibernate.persister.Queryable;import net.sf.hibernate.sql.JoinFragment;import net.sf.hibernate.util.StringHelper;/** * Parses the from clause of a hibernate query, looking for tables and * aliases for the SQL query. */public class FromParser implements Parser { private final PathExpressionParser peParser = new FromPathExpressionParser(); private String entityName; private String alias; private boolean afterIn; private boolean afterAs; private boolean afterClass; private boolean expectingJoin; private boolean expectingIn; private boolean expectingAs; private boolean afterJoinType; private int joinType; private boolean afterFetch; private static final int NONE = -666; private static final Map JOIN_TYPES = new HashMap(); static { JOIN_TYPES.put( "left", new Integer(JoinFragment.LEFT_OUTER_JOIN) ); JOIN_TYPES.put( "right", new Integer(JoinFragment.RIGHT_OUTER_JOIN) ); JOIN_TYPES.put( "full", new Integer(JoinFragment.FULL_JOIN) ); JOIN_TYPES.put( "inner", new Integer(JoinFragment.INNER_JOIN) ); } public void token(String token, QueryTranslator q) throws QueryException { // start by looking for HQL keywords... String lcToken = token.toLowerCase(); if ( lcToken.equals(StringHelper.COMMA) ) { if ( !(expectingJoin|expectingAs) ) throw new QueryException("unexpected token: ,"); expectingJoin = false; expectingAs = false; } else if ( lcToken.equals("join") ) { if (!afterJoinType) { if ( !(expectingJoin|expectingAs) ) throw new QueryException("unexpected token: join"); // inner joins can be abbreviated to 'join' joinType = JoinFragment.INNER_JOIN; expectingJoin = false; expectingAs = false; } else { afterJoinType = false; } } else if ( lcToken.equals("fetch") ) { if ( q.isShallowQuery() ) throw new QueryException("fetch may not be used with scroll() or iterate()"); if (joinType==NONE) throw new QueryException("unexpected token: fetch"); if (joinType==JoinFragment.FULL_JOIN || joinType==JoinFragment.RIGHT_OUTER_JOIN) throw new QueryException("fetch may only be used with inner join or left outer join"); afterFetch = true; } else if ( lcToken.equals("outer") ) { // 'outer' is optional and is ignored if ( !afterJoinType || (joinType!=JoinFragment.LEFT_OUTER_JOIN && joinType!=JoinFragment.RIGHT_OUTER_JOIN) ) throw new QueryException("unexpected token: outer"); } else if ( JOIN_TYPES.containsKey(lcToken) ) { if ( !(expectingJoin|expectingAs) ) throw new QueryException("unexpected token: " + token); joinType = ( (Integer) JOIN_TYPES.get(lcToken) ).intValue(); afterJoinType = true; expectingJoin = false; expectingAs = false; } else if ( lcToken.equals("class") ) { if (!afterIn) throw new QueryException("unexpected token: class"); if (joinType!=NONE) throw new QueryException("outer or full join must be followed by path expression"); afterClass=true; } else if ( lcToken.equals("in") ) { if (!expectingIn) throw new QueryException("unexpected token: in"); afterIn = true; expectingIn = false; } else if ( lcToken.equals("as") ) { if (!expectingAs) throw new QueryException("unexpected token: as"); afterAs = true; expectingAs = false; } else { if (afterJoinType) throw new QueryException("join expected: " + token); if (expectingJoin) throw new QueryException("unexpected token: " + token); if (expectingIn) throw new QueryException("in expected: " + token); // now anything that is not a HQL keyword if ( afterAs || expectingAs ) { // (AS is always optional, for consistency with SQL/OQL) // process the "new" HQL style where aliases are assigned // _after_ the class name or path expression ie. using // the AS construction if (entityName!=null) { q.setAliasName(token, entityName); } else { throw new QueryException("unexpected: as " + token); } afterAs = false; expectingJoin = true; expectingAs = false; entityName = null; } else if (afterIn) { // process the "old" HQL style where aliases appear _first_ // ie. using the IN or IN CLASS constructions if (alias==null) throw new QueryException("alias not specified for: " + token); if (joinType!=NONE) throw new QueryException("outer or full join must be followed by path expression"); if (afterClass) { // treat it as a classname Queryable p = q.getPersisterUsingImports(token); if (p==null) throw new QueryException("persister not found: " + token); q.addFromClass(alias, p); } else { // treat it as a path expression peParser.setJoinType(JoinFragment.INNER_JOIN); peParser.setUseThetaStyleJoin(true); ParserHelper.parse(peParser, q.unalias(token), ParserHelper.PATH_SEPARATORS, q); if ( !peParser.isCollectionValued() ) throw new QueryException("path expression did not resolve to collection: " + token); String nm = peParser.addFromCollection(q); q.setAliasName(alias, nm); } alias = null; afterIn = false; afterClass = false; expectingJoin = true; } else { // handle a path expression or class name that // appears at the start, in the "new" HQL // style or an alias that appears at the start // in the "old" HQL style Queryable p = q.getPersisterUsingImports(token); if (p!=null) { // starts with the name of a mapped class (new style) if (joinType!=NONE) throw new QueryException("outer or full join must be followed by path expression"); entityName = q.createNameFor( p.getMappedClass() ); q.addFromClass(entityName, p); expectingAs = true; } else if ( token.indexOf('.') < 0 ) { // starts with an alias (old style) // semi-bad thing about this: can't re-alias another alias..... alias = token; expectingIn = true; } else { // starts with a path expression (new style) // force HQL style: from Person p inner join p.cars c //if (joinType==NONE) throw new QueryException("path expression must be preceded by full, left, right or inner join"); //allow ODMG OQL style: from Person p, p.cars c if (joinType!=NONE) { peParser.setJoinType(joinType); } else { peParser.setJoinType(JoinFragment.INNER_JOIN); } peParser.setUseThetaStyleJoin( q.isSubquery() ); ParserHelper.parse(peParser, q.unalias(token), ParserHelper.PATH_SEPARATORS, q); entityName = peParser.addFromAssociation(q); joinType = NONE; peParser.setJoinType(JoinFragment.INNER_JOIN); if (afterFetch) { peParser.fetch(q, entityName); afterFetch = false; } expectingAs = true; } } } } public void start(QueryTranslator q) { entityName = null; alias = null; afterIn = false; afterAs = false; afterClass = false; expectingJoin = false; expectingIn = false; expectingAs = false; joinType = NONE; } public void end(QueryTranslator q) { } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -