/****************************************************************************** * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is: Jsoda * The Initial Developer of the Original Code is: William Wong (williamw520@gmail.com) * Portions created by William Wong are Copyright (C) 2012 William Wong, All Rights Reserved. * ******************************************************************************/ package wwutil.jsoda; import java.util.*; import java.lang.reflect.*; import com.amazonaws.services.simpledb.util.SimpleDBUtils; /** * Filter condition for query. Helper class used in SdbQuery. */ class Filter { final static Set<String> UNARY_OPERATORS = new HashSet<String>(); final static Set<String> BINARY_OPERATORS = new HashSet<String>(); final static Set<String> TRINARY_OPERATORS = new HashSet<String>(); final static Set<String> LIST_OPERATORS = new HashSet<String>(); public final static String NULL = "is null"; public final static String NOT_NULL = "is not null"; public final static String EQ = "="; public final static String NE = "!="; public final static String LE = "<="; public final static String LT = "<"; public final static String GE = ">="; public final static String GT = ">"; public final static String LIKE = "like"; public final static String NOT_LIKE = "not like"; public final static String CONTAINS = "contains"; public final static String NOT_CONTAINS = "not contains"; public final static String BEGINS_WITH = "begins with"; public final static String EVERY = "every"; public final static String BETWEEN = "between"; public final static String IN = "in"; static { UNARY_OPERATORS.add(NULL); UNARY_OPERATORS.add(NOT_NULL); BINARY_OPERATORS.add(EQ); BINARY_OPERATORS.add(NE); BINARY_OPERATORS.add(LE); BINARY_OPERATORS.add(LT); BINARY_OPERATORS.add(GE); BINARY_OPERATORS.add(GT); BINARY_OPERATORS.add(LIKE); BINARY_OPERATORS.add(NOT_LIKE); BINARY_OPERATORS.add(CONTAINS); BINARY_OPERATORS.add(NOT_CONTAINS); BINARY_OPERATORS.add(BEGINS_WITH); TRINARY_OPERATORS.add(BETWEEN); LIST_OPERATORS.add(IN); } Field field; String fieldName; String attr; // quoted String operator; Object operand; Object operand2; List operands; Filter(Jsoda jsoda, String modelName, String fieldName, String operator) { jsoda.validateField(modelName, fieldName); jsoda.getDb(modelName).validateFilterOperator(operator); setField(jsoda, modelName, fieldName); this.operator = operator; } Filter(Jsoda jsoda, String modelName, String fieldName, String operator, Object operand) { jsoda.validateField(modelName, fieldName); jsoda.getDb(modelName).validateFilterOperator(operator); setField(jsoda, modelName, fieldName); this.operator = operator; this.operand = operand; } Filter(Jsoda jsoda, String modelName, String fieldName, String operator, Object operand, Object operand2) { jsoda.validateField(modelName, fieldName); jsoda.getDb(modelName).validateFilterOperator(operator); setField(jsoda, modelName, fieldName); this.operator = operator; this.operand = operand; this.operand2 = operand2; } Filter(Jsoda jsoda, String modelName, String fieldName, String operator, Object... operands) { jsoda.validateField(modelName, fieldName); jsoda.getDb(modelName).validateFilterOperator(operator); setField(jsoda, modelName, fieldName); this.operator = operator; this.operands = Arrays.asList(operands); } private void setField(Jsoda jsoda, String modelName, String fieldName2) { this.fieldName = fieldName2.trim(); this.field = jsoda.getField(modelName, this.fieldName); this.attr = jsoda.getDb(modelName).getFieldAttrName(modelName, this.fieldName); } void toSimpleDBConditionStr(StringBuilder sb) { if (BINARY_OPERATORS.contains(operator)) { if (operand == null) throw new IllegalArgumentException("Operand of a condition cannot be null."); if (!DataUtil.canBeEncoded(operand, field.getType())) throw new IllegalArgumentException("The value of field " + field.getName() + " has type " + field.getType() + " which cannot be used in a query condition."); sb.append(attr); sb.append(" ").append(operator).append(" "); sb.append(SimpleDBUtils.quoteValue(DataUtil.encodeValueToAttrStr(operand, field.getType()))); return; } if (UNARY_OPERATORS.contains(operator)) { sb.append(attr); sb.append(" ").append(operator).append(" "); return; } if (TRINARY_OPERATORS.contains(operator)) { if (operand == null || operand2 == null) throw new IllegalArgumentException("Operand of a condition cannot be null."); if (!DataUtil.canBeEncoded(operand, field.getType()) || !DataUtil.canBeEncoded(operand2, field.getType())) throw new IllegalArgumentException("The value of field " + field.getName() + " has type " + field.getType() + " which cannot be used in a query condition."); sb.append(attr); sb.append(" between "); sb.append(SimpleDBUtils.quoteValue(DataUtil.encodeValueToAttrStr(operand, field.getType()))); sb.append(" and "); sb.append(SimpleDBUtils.quoteValue(DataUtil.encodeValueToAttrStr(operand2, field.getType()))); return; } if (LIST_OPERATORS.contains(operator)) { sb.append(attr); sb.append(" ").append(operator).append(" "); sb.append("("); int index = 0; for (Object valueObj : operands) { if (!DataUtil.canBeEncoded(valueObj, field.getType())) throw new IllegalArgumentException("The value of field " + field.getName() + " has type " + field.getType() + " which cannot be used in a query condition."); sb.append(index++ == 0 ? "" : ", "); sb.append(SimpleDBUtils.quoteValue(DataUtil.encodeValueToAttrStr(valueObj, field.getType()))); } sb.append(")"); return; } throw new UnsupportedOperationException(operator); } }