1 16 package org.outerj.daisy.query.model; 17 18 import org.outerj.daisy.query.QueryContext; 19 import org.outerj.daisy.repository.query.QueryException; 20 import org.outerj.daisy.repository.query.EvaluationContext; 21 import org.outerj.daisy.repository.Document; 22 import org.outerj.daisy.repository.Version; 23 24 import java.sql.PreparedStatement ; 25 import java.sql.SQLException ; 26 27 public class Between extends AbstractPredicateExpr { 28 private final Identifier identifier; 29 private final ValueExpr valueExpr1; 30 private final ValueExpr valueExpr2; 31 private final boolean not; 32 private QValueType valueType; 33 34 public Between(boolean not, Identifier identifier, ValueExpr valueExpr1, ValueExpr valueExpr2) { 35 this.identifier = identifier; 36 this.valueExpr1 = valueExpr1; 37 this.valueExpr2 = valueExpr2; 38 this.not = not; 39 } 40 41 public void prepare(QueryContext context) throws QueryException { 42 identifier.prepare(context); 43 if (identifier.isSymbolicIdentifier()) 44 throw new QueryException("A symbolic identifier cannot be used with BETWEEN."); 45 if (!identifier.isComparable()) 46 throw new QueryException("A non-comparable identifier cannot be used with BETWEEN."); 47 if (identifier.isMultiValue()) 48 throw new QueryException("A multivalue expression cannot be used with BETWEEN."); 49 50 valueExpr1.prepare(context); 51 valueExpr2.prepare(context); 52 53 if (!isExprOkForComparison(valueExpr1, identifier.getValueType())) 54 throw new QueryException("BETWEEN used with an expression whose type does not correspond to the value being tested: " + valueExpr1.getExpression()); 55 if (!isExprOkForComparison(valueExpr2, identifier.getValueType())) 56 throw new QueryException("BETWEEN used with an expression whose type does not correspond to the value being tested: " + valueExpr2.getExpression()); 57 58 this.valueType = identifier.getValueType(); 59 } 60 61 private boolean isExprOkForComparison(ValueExpr expr, QValueType typeToBeComparedWith) { 62 return !((expr.getValueType() != typeToBeComparedWith && expr.getValueType() != QValueType.UNDEFINED) || expr.isSymbolicIdentifier() || expr.getValueType() == QValueType.BOOLEAN || expr.isMultiValue()); 63 } 64 65 public boolean evaluate(Document document, Version version, EvaluationContext evaluationContext) throws QueryException { 66 Comparable testValue = (Comparable )identifier.evaluate(valueType, document, version, evaluationContext); 67 68 if (testValue == null) 69 return false; 70 71 Object value1 = valueExpr1.evaluate(valueType, document, version, evaluationContext); 72 Object value2 = valueExpr2.evaluate(valueType, document, version, evaluationContext); 73 74 return evaluate(testValue, value1, value2); 75 } 76 77 private boolean evaluate(Comparable testValue, Object value1, Object value2) throws QueryException { 78 boolean result = testValue.compareTo(value1) >= 0 && testValue.compareTo(value2) <= 0; 79 return not? !result: result; 80 } 81 82 public AclConditionViolation isAclAllowed() { 83 return identifier.isAclAllowed(); 84 } 85 86 public Tristate appliesTo(Document document) throws QueryException { 87 return Tristate.MAYBE; 88 } 89 90 public void generateSql(StringBuffer sql, SqlGenerationContext context) throws QueryException { 91 sql.append(" ("); 92 93 String preCond = identifier.getSqlPreConditions(context); 94 if (preCond != null) 95 sql.append(preCond).append(" and "); 96 97 String valueExpr1PreCond = valueExpr1.getSqlPreConditions(context); 98 if (valueExpr1PreCond != null) 99 sql.append(valueExpr1PreCond).append(" and "); 100 101 String valueExpr2PreCond = valueExpr2.getSqlPreConditions(context); 102 if (valueExpr2PreCond != null) 103 sql.append(valueExpr2PreCond).append(" and "); 104 105 identifier.generateSqlValueExpr(sql, context); 106 sql.append(" BETWEEN "); 107 valueExpr1.generateSqlValueExpr(sql, context); 108 sql.append(" AND "); 109 valueExpr2.generateSqlValueExpr(sql, context); 110 sql.append(" ) "); 111 } 112 113 public int bindSql(PreparedStatement stmt, int bindPos, EvaluationContext evaluationContext) throws SQLException , QueryException { 114 bindPos = identifier.bindPreConditions(stmt, bindPos); 115 bindPos = valueExpr1.bindPreConditions(stmt, bindPos); 116 bindPos = valueExpr2.bindPreConditions(stmt, bindPos); 117 bindPos = identifier.bindValueExpr(stmt, bindPos, valueType, evaluationContext); 118 bindPos = valueExpr1.bindValueExpr(stmt, bindPos, valueType, evaluationContext); 119 bindPos = valueExpr2.bindValueExpr(stmt, bindPos, valueType, evaluationContext); 120 return bindPos; 121 } 122 } 123 | Popular Tags |