KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > hql > ast > util > LiteralProcessor


1 // $Id: LiteralProcessor.java,v 1.1 2005/07/12 20:27:22 steveebersole Exp $
2
package org.hibernate.hql.ast.util;
3
4 import org.hibernate.MappingException;
5 import org.hibernate.QueryException;
6 import org.hibernate.hql.QueryTranslator;
7 import org.hibernate.hql.antlr.HqlSqlTokenTypes;
8 import org.hibernate.hql.antlr.SqlTokenTypes;
9 import org.hibernate.hql.ast.HqlSqlWalker;
10 import org.hibernate.hql.ast.InvalidPathException;
11 import org.hibernate.hql.ast.tree.DotNode;
12 import org.hibernate.hql.ast.tree.FromClause;
13 import org.hibernate.hql.ast.tree.IdentNode;
14 import org.hibernate.persister.entity.Queryable;
15 import org.hibernate.sql.InFragment;
16 import org.hibernate.type.LiteralType;
17 import org.hibernate.type.Type;
18 import org.hibernate.type.TypeFactory;
19 import org.hibernate.util.ReflectHelper;
20
21 import antlr.SemanticException;
22 import antlr.collections.AST;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 /**
28  * A delegate that handles literals and constants for HqlSqlWalker, performing the token replacement functions and
29  * classifying literals.
30  *
31  * @author josh Sep 2, 2004 7:15:30 AM
32  */

33 public class LiteralProcessor implements HqlSqlTokenTypes {
34     /**
35      * A logger for this class.
36      */

37     private static final Log log = LogFactory.getLog( LiteralProcessor.class );
38
39     private HqlSqlWalker walker;
40
41     public LiteralProcessor(HqlSqlWalker hqlSqlWalker) {
42         this.walker = hqlSqlWalker;
43     }
44     
45     public boolean isAlias(String JavaDoc alias) {
46         FromClause from = walker.getCurrentFromClause();
47         while ( from.isSubQuery() ) {
48             if ( from.containsClassAlias(alias) ) {
49                 return true;
50             }
51             from = from.getParentFromClause();
52         }
53         return from.containsClassAlias(alias);
54     }
55
56     public void processConstant(AST constant) throws SemanticException {
57         // If the constant is an IDENT, figure out what it means...
58
boolean isIdent = ( constant.getType() == IDENT || constant.getType() == WEIRD_IDENT );
59         if ( isIdent && isAlias( constant.getText() ) ) { // IDENT is a class alias in the FROM.
60
IdentNode ident = ( IdentNode ) constant;
61             // Resolve to an identity column.
62
ident.resolve(false, true);
63         }
64         else { // IDENT might be the name of a class.
65
Queryable queryable = walker.getSessionFactoryHelper().findQueryableUsingImports( constant.getText() );
66             if ( isIdent && queryable != null ) {
67                 constant.setText( queryable.getDiscriminatorSQLValue().toString() );
68             }
69             // Otherwise, it's a literal.
70
else {
71                 processLiteral( constant );
72             }
73         }
74     }
75
76     public void lookupConstant(DotNode node) throws SemanticException {
77         String JavaDoc text = getText( node );
78         Queryable persister = walker.getSessionFactoryHelper().findQueryableUsingImports( text );
79         if ( persister != null ) {
80             // the name of an entity class
81
final String JavaDoc discrim = persister.getDiscriminatorSQLValue();
82             if ( InFragment.NULL.equals(discrim) || InFragment.NOT_NULL.equals(discrim) ) {
83                 throw new InvalidPathException( "subclass test not allowed for null or not null discriminator: '" + text + "'" );
84             }
85             else {
86                 setSQLValue( node, text, discrim ); //the class discriminator value
87
}
88         }
89         else {
90             Object JavaDoc value = ReflectHelper.getConstantValue( text );
91             if ( value == null ) {
92                 throw new InvalidPathException( "Invalid path: '" + text + "'" );
93             }
94             else {
95                 setConstantValue( node, text, value );
96             }
97         }
98     }
99     
100     private void setSQLValue(DotNode node, String JavaDoc text, String JavaDoc value) {
101         if ( log.isDebugEnabled() ) {
102             log.debug( "setSQLValue() " + text + " -> " + value );
103         }
104         node.setFirstChild( null ); // Chop off the rest of the tree.
105
node.setType( SqlTokenTypes.SQL_TOKEN );
106         node.setText(value);
107         node.setResolvedConstant( text );
108     }
109
110     private void setConstantValue(DotNode node, String JavaDoc text, Object JavaDoc value) {
111         if ( log.isDebugEnabled() ) {
112             log.debug( "setConstantValue() " + text + " -> " + value + " " + value.getClass().getName() );
113         }
114         node.setFirstChild( null ); // Chop off the rest of the tree.
115
if ( value instanceof String JavaDoc ) {
116             node.setType( SqlTokenTypes.QUOTED_STRING );
117         }
118         else if ( value instanceof Character JavaDoc ) {
119             node.setType( SqlTokenTypes.QUOTED_STRING );
120         }
121         else if ( value instanceof Byte JavaDoc ) {
122             node.setType( SqlTokenTypes.NUM_INT );
123         }
124         else if ( value instanceof Short JavaDoc ) {
125             node.setType( SqlTokenTypes.NUM_INT );
126         }
127         else if ( value instanceof Integer JavaDoc ) {
128             node.setType( SqlTokenTypes.NUM_INT );
129         }
130         else if ( value instanceof Long JavaDoc ) {
131             node.setType( SqlTokenTypes.NUM_LONG );
132         }
133         else if ( value instanceof Double JavaDoc ) {
134             node.setType( SqlTokenTypes.NUM_DOUBLE );
135         }
136         else if ( value instanceof Float JavaDoc ) {
137             node.setType( SqlTokenTypes.NUM_FLOAT );
138         }
139         else {
140             node.setType( SqlTokenTypes.CONSTANT );
141         }
142         Type type;
143         try {
144             type = TypeFactory.heuristicType( value.getClass().getName() );
145         }
146         catch ( MappingException me ) {
147             throw new QueryException( me );
148         }
149         if ( type == null ) throw new QueryException( QueryTranslator.ERROR_CANNOT_DETERMINE_TYPE + node.getText() );
150         try {
151             LiteralType literalType = ( LiteralType ) type;
152             node.setText( literalType.objectToSQLString( value ) );
153         }
154         catch ( Exception JavaDoc e ) {
155             throw new QueryException( QueryTranslator.ERROR_CANNOT_FORMAT_LITERAL + node.getText(), e );
156         }
157         node.setDataType( type );
158         node.setResolvedConstant( text );
159     }
160
161     private String JavaDoc getText(AST node) {
162         return ASTUtil.getPathText( node );
163     }
164
165     public void processBoolean(AST constant) {
166         // TODO: something much better - look at the type of the other expression!
167
// TODO: Have comparisonExpression and/or arithmeticExpression rules complete the resolution of boolean nodes.
168
String JavaDoc replacement = ( String JavaDoc ) walker.getTokenReplacements().get( constant.getText() );
169         if ( replacement != null ) constant.setText( replacement );
170     }
171
172     private void processLiteral(AST constant) {
173         String JavaDoc replacement = ( String JavaDoc ) walker.getTokenReplacements().get( constant.getText() );
174         if ( replacement != null ) {
175             if ( log.isDebugEnabled() ) {
176                 log.debug( "processConstant() : Replacing '" + constant.getText() + "' with '" + replacement + "'" );
177             }
178             constant.setText( replacement );
179         }
180     }
181
182 }
183
Popular Tags