1
// $Id: SqlASTFactory.java 10060 2006-06-28 02:53:39Z steve.ebersole@jboss.com $
2
package org.hibernate.hql.ast;
4
import antlr.ASTFactory;
6
import antlr.collections.AST;
7
import org.hibernate.hql.antlr.HqlSqlTokenTypes;
8
import org.hibernate.hql.ast.tree.AggregateNode;
9
import org.hibernate.hql.ast.tree.BinaryArithmeticOperatorNode;
10
import org.hibernate.hql.ast.tree.BinaryLogicOperatorNode;
11
import org.hibernate.hql.ast.tree.Case2Node;
12
import org.hibernate.hql.ast.tree.CaseNode;
13
import org.hibernate.hql.ast.tree.CollectionFunction;
14
import org.hibernate.hql.ast.tree.ConstructorNode;
15
import org.hibernate.hql.ast.tree.CountNode;
16
import org.hibernate.hql.ast.tree.DeleteStatement;
17
import org.hibernate.hql.ast.tree.DotNode;
18
import org.hibernate.hql.ast.tree.FromClause;
19
import org.hibernate.hql.ast.tree.FromElement;
20
import org.hibernate.hql.ast.tree.IdentNode;
21
import org.hibernate.hql.ast.tree.ImpliedFromElement;
22
import org.hibernate.hql.ast.tree.IndexNode;
23
import org.hibernate.hql.ast.tree.InitializeableNode;
24
import org.hibernate.hql.ast.tree.InsertStatement;
25
import org.hibernate.hql.ast.tree.IntoClause;
26
import org.hibernate.hql.ast.tree.LiteralNode;
27
import org.hibernate.hql.ast.tree.MethodNode;
28
import org.hibernate.hql.ast.tree.OrderByClause;
29
import org.hibernate.hql.ast.tree.ParameterNode;
30
import org.hibernate.hql.ast.tree.QueryNode;
31
import org.hibernate.hql.ast.tree.SelectClause;
32
import org.hibernate.hql.ast.tree.SelectExpressionImpl;
33
import org.hibernate.hql.ast.tree.SqlFragment;
34
import org.hibernate.hql.ast.tree.SqlNode;
35
import org.hibernate.hql.ast.tree.UnaryArithmeticNode;
36
import org.hibernate.hql.ast.tree.UpdateStatement;
37
import org.hibernate.hql.ast.tree.BetweenOperatorNode;
38
import org.hibernate.hql.ast.tree.UnaryLogicOperatorNode;
39
import org.hibernate.hql.ast.tree.InLogicOperatorNode;
40
import org.hibernate.hql.ast.tree.JavaConstantNode;
41
import org.hibernate.hql.ast.tree.SessionFactoryAwareNode;
42
import org.hibernate.hql.ast.tree.BooleanLiteralNode;
44
import java.lang.reflect.Constructor;
47
* Custom AST factory the intermediate tree that causes ANTLR to create specialized
48
* AST nodes, given the AST node type (from HqlSqlTokenTypes). HqlSqlWalker registers
49
* this factory with itself when it is initialized.
53
public class SqlASTFactory extends ASTFactory implements HqlSqlTokenTypes {
54
private HqlSqlWalker walker;
57
* Create factory with a specific mapping from token type
58
* to Java AST node type. Your subclasses of ASTFactory
59
* can override and reuse the map stuff.
61
public SqlASTFactory(HqlSqlWalker walker) {
67
* Returns the class for a given token type (a.k.a. AST node type).
69
* @param tokenType The token type.
70
* @return Class - The AST node class to instantiate.
72
public Class getASTNodeType(int tokenType) {
73
switch ( tokenType ) {
76
return QueryNode.class;
78
return UpdateStatement.class;
80
return DeleteStatement.class;
82
return InsertStatement.class;
84
return IntoClause.class;
86
return FromClause.class;
88
return FromElement.class;
90
return ImpliedFromElement.class;
94
return IndexNode.class;
95
// Alias references and identifiers use the same node class.
98
return IdentNode.class;
100
return SqlFragment.class;
102
return MethodNode.class;
105
return CollectionFunction.class;
107
return SelectClause.class;
109
return SelectExpressionImpl.class;
111
return AggregateNode.class;
113
return CountNode.class;
115
return ConstructorNode.class;
121
return LiteralNode.class;
124
return BooleanLiteralNode.class;
126
return JavaConstantNode.class;
128
return OrderByClause.class;
133
return BinaryArithmeticOperatorNode.class;
136
return UnaryArithmeticNode.class;
138
return Case2Node.class;
140
return CaseNode.class;
143
return ParameterNode.class;
152
return BinaryLogicOperatorNode.class;
155
return InLogicOperatorNode.class;
158
return BetweenOperatorNode.class;
162
return UnaryLogicOperatorNode.class;
164
return SqlNode.class;
168
protected AST createUsingCtor(Token token, String className) {
172
c = Class.forName( className );
173
Class[] tokenArgType = new Class[]{antlr.Token.class};
174
Constructor ctor = c.getConstructor( tokenArgType );
175
if ( ctor != null ) {
176
t = ( AST ) ctor.newInstance( new Object[]{token} ); // make a new one
177
initializeSqlNode( t );
180
// just do the regular thing if you can't find the ctor
181
// Your AST must have default ctor to use this.
185
catch ( Exception e ) {
186
throw new IllegalArgumentException( "Invalid class or can't make instance, " + className );
191
private void initializeSqlNode(AST t) {
192
// Initialize SQL nodes here.
193
if ( t instanceof InitializeableNode ) {
194
InitializeableNode initializeableNode = ( InitializeableNode ) t;
195
initializeableNode.initialize( walker );
197
if ( t instanceof SessionFactoryAwareNode ) {
198
( ( SessionFactoryAwareNode ) t ).setSessionFactory( walker.getSessionFactoryHelper().getFactory() );
203
* Actually instantiate the AST node.
205
* @param c The class to instantiate.
206
* @return The instantiated and initialized node.
208
protected AST create(Class c) {
211
t = ( AST ) c.newInstance(); // make a new one
212
initializeSqlNode( t );
214
catch ( Exception e ) {
215
error( "Can't create AST Node " + c.getName() );