1 16 package org.outerj.daisy.query.model; 17 18 import org.outerj.daisy.repository.Document; 19 import org.outerj.daisy.repository.Version; 20 import org.outerj.daisy.repository.query.QueryException; 21 import org.outerj.daisy.repository.query.EvaluationContext; 22 import org.outerj.daisy.query.QueryContext; 23 24 import java.util.Iterator ; 25 import java.sql.PreparedStatement ; 26 import java.sql.SQLException ; 27 28 public class HasAll extends AbstractMultiArgPredicate { 29 private boolean exactCount; 30 private Identifier valueCountIdentifier = null; 31 private Identifier[] identifierPerLiteral; 32 33 public HasAll(Identifier identifier, boolean exactCount) { 34 super(identifier); 35 this.exactCount = exactCount; 36 } 37 38 public void prepare(QueryContext context) throws QueryException { 39 super.prepare(context); 40 if (!identifier.isMultiValue()) 41 throw new QueryException("The HAS ALL or HAS EXACT condition can only be used with multivalue fields, which " + identifier.getExpression() + " is not."); 42 } 43 44 public boolean evaluate(Document document, Version version, EvaluationContext evaluationContext) throws QueryException { 45 Object [] values = (Object [])identifier.evaluate(valueType, document, version, evaluationContext); 46 if (values == null) 47 return false; 48 49 if (!exactCount) { 50 Iterator literalIt = literals.iterator(); 51 while (literalIt.hasNext()) { 52 Literal literal = (Literal)literalIt.next(); 53 Object value = literal.evaluate(valueType); 54 boolean valueFound = false; 55 for (int i = 0; i < values.length; i++) { 56 if (value.equals(values[i])) { 57 valueFound = true; 58 break; 59 } 60 } 61 if (!valueFound) 62 return false; 63 } 64 return true; 65 } else { 66 if (values.length != literals.size()) 67 return false; 68 boolean[] matches = new boolean[values.length]; 69 Iterator literalIt = literals.iterator(); 70 while (literalIt.hasNext()) { 71 Literal literal = (Literal)literalIt.next(); 72 Object value = literal.evaluate(valueType); 73 boolean valueFound = false; 74 for (int i = 0; i < values.length; i++) { 75 if (!matches[i] && value.equals(values[i])) { 76 valueFound = true; 77 matches[i] = true; 78 break; 79 } 80 } 81 if (!valueFound) 82 return false; 83 } 84 return true; 85 } 86 } 87 88 public void generateSql(StringBuffer sql, SqlGenerationContext context) throws QueryException { 89 identifierPerLiteral = new Identifier[literals.size()]; 90 sql.append(" ("); 91 for (int i = 0; i < literals.size(); i++) { 92 if (i > 0) 93 sql.append(" and "); 94 95 identifierPerLiteral[i] = (Identifier)identifier.clone(); 96 String preCond = identifierPerLiteral[i].getSqlPreConditions(context); 97 if (preCond != null) 98 sql.append(preCond).append(" and "); 99 identifierPerLiteral[i].generateSqlValueExpr(sql, context); 100 sql.append(" = ?"); 101 } 102 sql.append(" ) "); 103 104 if (exactCount) { 105 valueCountIdentifier = identifier.getValueCountIdentifier(); 106 sql.append(" and "); 107 String preCond = valueCountIdentifier.getSqlPreConditions(context); 108 if (preCond != null) 109 sql.append(preCond).append(" and "); 110 valueCountIdentifier.generateSqlValueExpr(sql, context); 111 sql.append(" = ").append(literals.size()).append(" "); 112 } 113 } 114 115 public int bindSql(PreparedStatement stmt, int bindPos, EvaluationContext evaluationContext) throws SQLException , QueryException { 116 for (int i = 0; i < literals.size(); i++) { 117 Literal literal = (Literal)literals.get(i); 118 bindPos = identifierPerLiteral[i].bindPreConditions(stmt, bindPos); 119 bindPos = identifierPerLiteral[i].bindValueExpr(stmt, bindPos, valueType, evaluationContext); 120 if (identifierPerLiteral[i].isSymbolicIdentifier()) { 121 Object value = identifierPerLiteral[i].translateSymbolic(literal, evaluationContext); 122 bindPos = Literal.bindLiteral(stmt, bindPos, valueType, value); 123 } else { 124 bindPos = literal.bindValueExpr(stmt, bindPos, valueType, evaluationContext); 125 } 126 } 127 128 if (valueCountIdentifier != null) { 129 bindPos = valueCountIdentifier.bindPreConditions(stmt, bindPos); 130 bindPos = valueCountIdentifier.bindValueExpr(stmt, bindPos, null, evaluationContext); 131 } 132 133 return bindPos; 134 } 135 136 public AclConditionViolation isAclAllowed() { 137 return null; 138 } 139 140 public Tristate appliesTo(Document document) { 141 return Tristate.MAYBE; 142 } 143 } | Popular Tags |