KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > hql > ast > SqlGenerator


1 // $Id: SqlGenerator.java,v 1.26 2005/07/16 17:28:40 epbernard Exp $
2
package org.hibernate.hql.ast;
3
4 import java.util.ArrayList JavaDoc;
5 import java.util.LinkedList JavaDoc;
6 import java.util.List JavaDoc;
7
8 import antlr.RecognitionException;
9 import antlr.collections.AST;
10 import org.hibernate.QueryException;
11 import org.hibernate.dialect.function.SQLFunction;
12 import org.hibernate.engine.SessionFactoryImplementor;
13 import org.hibernate.hql.antlr.SqlGeneratorBase;
14 import org.hibernate.hql.ast.tree.MethodNode;
15
16 /**
17  * Generates SQL by overriding callback methods in the base class, which does
18  * the actual SQL AST walking.
19  *
20  * @author josh Jun 23, 2004 6:49:55 AM
21  */

22 public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
23     /**
24      * Handles parser errors.
25      */

26     private ParseErrorHandler parseErrorHandler;
27
28     /**
29      * all append invocations on the buf should go through this Output instance variable.
30      * The value of this variable may be temporarily substitued by sql function processing code
31      * to catch generated arguments.
32      * This is because sql function templates need arguments as seperate string chunks
33      * that will be assembled into the target dialect-specific function call.
34      */

35     private SqlWriter writer = new DefaultWriter();
36
37     private SessionFactoryImplementor sessionFactory;
38
39     private LinkedList JavaDoc outputStack = new LinkedList JavaDoc();
40
41     protected void out(String JavaDoc s) {
42         writer.clause( s );
43     }
44
45     protected void commaBetweenParameters(String JavaDoc comma) {
46         writer.commaBetweenParameters( comma );
47     }
48
49     public void reportError(RecognitionException e) {
50         parseErrorHandler.reportError( e ); // Use the delegate.
51
}
52
53     public void reportError(String JavaDoc s) {
54         parseErrorHandler.reportError( s ); // Use the delegate.
55
}
56
57     public void reportWarning(String JavaDoc s) {
58         parseErrorHandler.reportWarning( s );
59     }
60
61     public ParseErrorHandler getParseErrorHandler() {
62         return parseErrorHandler;
63     }
64
65     public SqlGenerator(SessionFactoryImplementor sfi) {
66         super();
67         parseErrorHandler = new ErrorCounter();
68         sessionFactory = sfi;
69     }
70
71     public String JavaDoc getSQL() {
72         return getStringBuffer().toString();
73     }
74
75     protected void optionalSpace() {
76         int c = getLastChar();
77         switch ( c ) {
78             case -1:
79                 return;
80             case ' ':
81                 return;
82             case ')':
83                 return;
84             case '(':
85                 return;
86             default:
87                 out( " " );
88         }
89     }
90
91     protected void beginFunctionTemplate(AST m, AST i) {
92         MethodNode methodNode = ( MethodNode ) m;
93         SQLFunction template = methodNode.getSQLFunction();
94         if ( template == null ) {
95             // if template is null we just write the function out as it appears in the hql statement
96
super.beginFunctionTemplate( m, i );
97         }
98         else {
99             // this function has a template -> redirect output and catch the arguments
100
outputStack.addFirst( writer );
101             writer = new FunctionArguments();
102         }
103     }
104
105     protected void endFunctionTemplate(AST m) {
106         MethodNode methodNode = ( MethodNode ) m;
107         SQLFunction template = methodNode.getSQLFunction();
108         if ( template == null ) {
109             super.endFunctionTemplate( m );
110         }
111         else {
112             // this function has a template -> restore output, apply the template and write the result out
113
FunctionArguments functionArguments = ( FunctionArguments ) writer; // TODO: Downcast to avoid using an interface? Yuck.
114
writer = ( SqlWriter ) outputStack.removeFirst();
115             out( template.render( functionArguments.getArgs(), sessionFactory ) );
116         }
117     }
118
119     // --- Inner classes (moved here from sql-gen.g) ---
120

121     /**
122      * Writes SQL fragments.
123      */

124     interface SqlWriter {
125         void clause(String JavaDoc clause);
126
127         /**
128          * todo remove this hack
129          * The parameter is either ", " or " , ". This is needed to pass sql generating tests as the old
130          * sql generator uses " , " in the WHERE and ", " in SELECT.
131          *
132          * @param comma either " , " or ", "
133          */

134         void commaBetweenParameters(String JavaDoc comma);
135     }
136
137     /**
138      * SQL function processing code redirects generated SQL output to an instance of this class
139      * which catches function arguments.
140      */

141     class FunctionArguments implements SqlWriter {
142         private int argInd;
143         private final List JavaDoc args = new ArrayList JavaDoc( 3 );
144
145         public void clause(String JavaDoc clause) {
146             if ( argInd == args.size() ) {
147                 args.add( clause );
148             }
149             else {
150                 args.set( argInd, args.get( argInd ) + clause );
151             }
152         }
153
154         public void commaBetweenParameters(String JavaDoc comma) {
155             ++argInd;
156         }
157
158         public List JavaDoc getArgs() {
159             return args;
160         }
161     }
162
163     /**
164      * The default SQL writer.
165      */

166     class DefaultWriter implements SqlWriter {
167         public void clause(String JavaDoc clause) {
168             getStringBuffer().append( clause );
169         }
170
171         public void commaBetweenParameters(String JavaDoc comma) {
172             getStringBuffer().append( comma );
173         }
174     }
175
176     public static void panic() {
177         throw new QueryException( "TreeWalker: panic" );
178     }
179 }
180
Popular Tags