1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.voicemail.common.core; 18 19 import static com.example.android.voicemail.common.utils.DbQueryUtils.concatenateClausesWithAnd; 20 import static com.example.android.voicemail.common.utils.DbQueryUtils.concatenateClausesWithOr; 21 import static com.example.android.voicemail.common.utils.DbQueryUtils.getEqualityClause; 22 23 import android.provider.VoicemailContract.Voicemails; 24 import android.text.TextUtils; 25 26 import java.util.ArrayList; 27 import java.util.List; 28 29 /** 30 * Factory class to create {@link VoicemailFilter} objects for various filtering needs. 31 * <p> 32 * Factory methods like {@link #createWithReadStatus(boolean)} and 33 * {@link #createWithMatchingFields(Voicemail)} can be used to create a voicemail filter that 34 * matches the value of the specific field. 35 * <p> 36 * It is possible to combine multiple filters with OR or AND operation using the methods 37 * {@link #createWithOrOf(VoicemailFilter...)} and {@link #createWithAndOf(VoicemailFilter...)} 38 * respectively. 39 * <p> 40 * {@link #createWithWhereClause(String)} can be used to create an arbitrary filter for a specific 41 * where clause. Using this method requires the knowledge of the name of columns used in voicemail 42 * content provider database and is therefore less recommended. 43 */ 44 public class VoicemailFilterFactory { 45 /** 46 * Creates a voicemail filter with the specified where clause. Use this method only if you know 47 * and want to directly use the column names of the content provider. For most of the usages 48 * one of the other factory methods should be good enough. 49 */ 50 public static VoicemailFilter createWithWhereClause(final String whereClause) { 51 return new VoicemailFilter() { 52 @Override 53 public String getWhereClause() { 54 return TextUtils.isEmpty(whereClause) ? null : whereClause; 55 } 56 @Override 57 public String toString() { 58 return getWhereClause(); 59 } 60 }; 61 } 62 63 /** Creates a filter with fields matching the ones set in the supplied voicemail object. */ 64 public static VoicemailFilter createWithMatchingFields(Voicemail fieldMatch) { 65 if (fieldMatch == null) { 66 throw new IllegalArgumentException("Cannot create filter null fieldMatch"); 67 } 68 return VoicemailFilterFactory.createWithWhereClause( 69 getWhereClauseForMatchingFields(fieldMatch)); 70 } 71 72 /** Creates a voicemail filter with the specified read status. */ 73 public static VoicemailFilter createWithReadStatus(boolean isRead) { 74 return createWithMatchingFields( 75 VoicemailImpl.createEmptyBuilder().setIsRead(isRead).build()); 76 } 77 78 /** Combine multiple filters with OR clause. */ 79 public static VoicemailFilter createWithAndOf(VoicemailFilter... filters) { 80 return createWithWhereClause(concatenateClausesWithAnd(getClauses(filters))); 81 } 82 83 /** Combine multiple filters with AND clause. */ 84 public static VoicemailFilter createWithOrOf(VoicemailFilter... filters) { 85 return createWithWhereClause(concatenateClausesWithOr(getClauses(filters))); 86 } 87 88 private static String[] getClauses(VoicemailFilter[] filters) { 89 String[] clauses = new String[filters.length]; 90 for (int i = 0; i < filters.length; ++i) { 91 clauses[i] = filters[i].getWhereClause(); 92 } 93 return clauses; 94 } 95 96 private static String getWhereClauseForMatchingFields(Voicemail fieldMatch) { 97 List<String> clauses = new ArrayList<String>(); 98 if (fieldMatch.hasRead()) { 99 clauses.add(getEqualityClause(Voicemails.IS_READ, fieldMatch.isRead() ? "1" : "0")); 100 } 101 if (fieldMatch.hasNumber()) { 102 clauses.add(getEqualityClause(Voicemails.NUMBER, fieldMatch.getNumber())); 103 } 104 if (fieldMatch.hasSourcePackage()) { 105 clauses.add(getEqualityClause(Voicemails.SOURCE_PACKAGE, 106 fieldMatch.getSourcePackage())); 107 } 108 if (fieldMatch.hasSourceData()) { 109 clauses.add(getEqualityClause(Voicemails.SOURCE_DATA, fieldMatch.getSourceData())); 110 } 111 if (fieldMatch.hasDuration()) { 112 clauses.add(getEqualityClause(Voicemails.DURATION, 113 Long.toString(fieldMatch.getDuration()))); 114 } 115 if (fieldMatch.hasTimestampMillis()) { 116 clauses.add(getEqualityClause(Voicemails.DATE, 117 Long.toString(fieldMatch.getTimestampMillis()))); 118 } 119 // Empty filter. 120 if (clauses.size() == 0) { 121 return null; 122 } 123 return concatenateClausesWithAnd(clauses.toArray(new String[0])); 124 } 125 } 126