1 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 33 public class LiteralProcessor implements HqlSqlTokenTypes { 34 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 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 boolean isIdent = ( constant.getType() == IDENT || constant.getType() == WEIRD_IDENT ); 59 if ( isIdent && isAlias( constant.getText() ) ) { IdentNode ident = ( IdentNode ) constant; 61 ident.resolve(false, true); 63 } 64 else { Queryable queryable = walker.getSessionFactoryHelper().findQueryableUsingImports( constant.getText() ); 66 if ( isIdent && queryable != null ) { 67 constant.setText( queryable.getDiscriminatorSQLValue().toString() ); 68 } 69 else { 71 processLiteral( constant ); 72 } 73 } 74 } 75 76 public void lookupConstant(DotNode node) throws SemanticException { 77 String text = getText( node ); 78 Queryable persister = walker.getSessionFactoryHelper().findQueryableUsingImports( text ); 79 if ( persister != null ) { 80 final String 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 ); } 88 } 89 else { 90 Object 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 text, String value) { 101 if ( log.isDebugEnabled() ) { 102 log.debug( "setSQLValue() " + text + " -> " + value ); 103 } 104 node.setFirstChild( null ); node.setType( SqlTokenTypes.SQL_TOKEN ); 106 node.setText(value); 107 node.setResolvedConstant( text ); 108 } 109 110 private void setConstantValue(DotNode node, String text, Object value) { 111 if ( log.isDebugEnabled() ) { 112 log.debug( "setConstantValue() " + text + " -> " + value + " " + value.getClass().getName() ); 113 } 114 node.setFirstChild( null ); if ( value instanceof String ) { 116 node.setType( SqlTokenTypes.QUOTED_STRING ); 117 } 118 else if ( value instanceof Character ) { 119 node.setType( SqlTokenTypes.QUOTED_STRING ); 120 } 121 else if ( value instanceof Byte ) { 122 node.setType( SqlTokenTypes.NUM_INT ); 123 } 124 else if ( value instanceof Short ) { 125 node.setType( SqlTokenTypes.NUM_INT ); 126 } 127 else if ( value instanceof Integer ) { 128 node.setType( SqlTokenTypes.NUM_INT ); 129 } 130 else if ( value instanceof Long ) { 131 node.setType( SqlTokenTypes.NUM_LONG ); 132 } 133 else if ( value instanceof Double ) { 134 node.setType( SqlTokenTypes.NUM_DOUBLE ); 135 } 136 else if ( value instanceof Float ) { 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 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 getText(AST node) { 162 return ASTUtil.getPathText( node ); 163 } 164 165 public void processBoolean(AST constant) { 166 String replacement = ( String ) walker.getTokenReplacements().get( constant.getText() ); 169 if ( replacement != null ) constant.setText( replacement ); 170 } 171 172 private void processLiteral(AST constant) { 173 String replacement = ( String ) 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 |