package org.webinos.android.impl.mediacontent; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.webinos.api.DeviceAPIError; import org.webinos.android.impl.mediacontent.Mapping.CompositeDbField; import org.webinos.android.impl.mediacontent.Mapping.DbField; import org.webinos.android.impl.mediacontent.Mapping.SingleDbField; public class QueryBuilder { private static Map<String, String> selectStrings = new HashMap<String, String>(); static { selectStrings.put(AttributeFilter.FILTER_MATCH_EXACTLY, "%s = ?"); selectStrings.put(AttributeFilter.FILTER_MATCH_FULLSTRING, "%s LIKE ?"); selectStrings.put(AttributeFilter.FILTER_MATCH_CONTAINS, "%s LIKE %?%"); selectStrings.put(AttributeFilter.FILTER_MATCH_STARTSWITH, "%s LIKE ?%"); selectStrings.put(AttributeFilter.FILTER_MATCH_ENDSWITH, "%s LIKE %?"); selectStrings.put(AttributeFilter.FILTER_MATCH_EXISTS, "%s NOT NULL"); } public static SelectStatement getSelect(AbstractFilter filter) { if (filter instanceof AttributeFilter) { return getSelect((AttributeFilter)filter); } else if (filter instanceof AttributeRangeFilter) { return getSelect((AttributeRangeFilter)filter); } else if (filter instanceof CompositeFilter) { return getSelect((CompositeFilter)filter); } return null; } public static SelectStatement getSelect(AttributeFilter filter) { DbField dbField = Mapping.getDbField(filter.attributeName); if ((filter.matchFlag.equals(AttributeFilter.FILTER_MATCH_FULLSTRING) || filter.matchFlag.equals(AttributeFilter.FILTER_MATCH_CONTAINS) || filter.matchFlag.equals(AttributeFilter.FILTER_MATCH_STARTSWITH) || filter.matchFlag.equals(AttributeFilter.FILTER_MATCH_ENDSWITH)) && !dbField.getAttributeType().equals(String.class)) { throw new DeviceAPIError(DeviceAPIError.INVALID_VALUES_ERR); } SelectStatement resultStmt = null; if (dbField instanceof SingleDbField) { SingleDbField singleDbField = (SingleDbField) dbField; String stmtStr = String.format(selectStrings.get(filter.matchFlag), singleDbField.getName()); String dbMatchValue = null; if (singleDbField.getTranslator() != null) { dbMatchValue = singleDbField.getTranslator().getDbValue(filter.matchValue) .toString(); } else { dbMatchValue = filter.matchValue.toString(); } resultStmt = new SelectStatement(stmtStr, new String[] { dbMatchValue }); } else if (dbField instanceof CompositeDbField) { CompositeDbField compositeDbField = (CompositeDbField) dbField; if (compositeDbField.getCompositeHandler() != null) { String stmtStr = null; Object[] parts = (Object[]) compositeDbField.getCompositeHandler().getParts(filter.matchValue); String[] dbMatchValues = new String[parts.length]; for (int i = 0; i < compositeDbField.getDbFields().length; i++) { SingleDbField singleDbField = compositeDbField.getDbFields()[i]; if (i > 0) { stmtStr += " AND "; } stmtStr += String.format(selectStrings.get(filter.matchFlag), singleDbField); if (singleDbField.getTranslator() != null) { dbMatchValues[i] = singleDbField.getTranslator().getDbValue(parts[i]).toString(); } else { dbMatchValues[i] = parts[i].toString(); } } resultStmt = new SelectStatement(stmtStr, dbMatchValues); } else { throw new DeviceAPIError(DeviceAPIError.INVALID_ERROR); } } return resultStmt; } public static SelectStatement getSelect(CompositeFilter filter) { SelectStatement resultStmt = null; String operator = null; if (CompositeFilter.COMPOSITE_TYPE_UNION.equals(filter.type)) { operator = " OR "; } else if (CompositeFilter.COMPOSITE_TYPE_INTERSECTION.equals(filter.type)) { operator = " AND "; } else { throw new DeviceAPIError(DeviceAPIError.INVALID_VALUES_ERR); } List<String> stmtArgs = new ArrayList<String>(); if (filter.filters.length > 0) { String stmtStr = getSelect(filter.filters[0]).getStatement(); for (String arg : getSelect(filter.filters[0]).getArgs()) { stmtArgs.add(arg); } for (int i = 1; i < filter.filters.length; i++) { stmtStr += operator + getSelect(filter.filters[i]); for (String arg : getSelect(filter.filters[i]).getArgs()) { stmtArgs.add(arg); } } resultStmt = new SelectStatement(stmtStr, stmtArgs.toArray(new String[stmtArgs.size()])); } return resultStmt; } public static SelectStatement getSelect(AttributeRangeFilter filter) { DbField dbField = Mapping.getDbField(filter.attributeName); if (!dbField.getAttributeType().isAssignableFrom(Number.class)) { throw new DeviceAPIError(DeviceAPIError.INVALID_VALUES_ERR); } if (dbField instanceof SingleDbField) { SingleDbField singleDbField = (SingleDbField) dbField; String stmtStr = String.format("%s >= ? AND %s <= ?", singleDbField.getName(), singleDbField.getName()); String dbStartValue = null; String dbEndValue = null; if (singleDbField.getTranslator() != null) { dbStartValue = singleDbField.getTranslator().getDbValue(filter.initialValue) .toString(); dbEndValue = singleDbField.getTranslator().getDbValue(filter.endValue) .toString(); } else { dbStartValue = filter.initialValue.toString(); dbEndValue = filter.endValue.toString(); } return new SelectStatement(stmtStr, new String[] { dbStartValue, dbEndValue}); } else { throw new DeviceAPIError(DeviceAPIError.INVALID_VALUES_ERR); } } }