ListSuggestionCursorNoDuplicates.java revision 93bd2e70b8b08da1ec37fd0e990dac05551d2e90
1/* 2 * Copyright (C) 2009 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 17package com.android.quicksearchbox; 18 19import android.util.Log; 20 21import java.util.HashSet; 22 23/** 24 * A SuggestionCursor that is backed by a list of SuggestionPosition objects 25 * and doesn't allow duplicate suggestions. 26 */ 27public class ListSuggestionCursorNoDuplicates extends ListSuggestionCursor { 28 29 private static final boolean DBG = false; 30 private static final String TAG = "QSB.ListSuggestionCursorNoDuplicates"; 31 32 private final HashSet<String> mSuggestionKeys; 33 34 public ListSuggestionCursorNoDuplicates(String userQuery) { 35 super(userQuery); 36 mSuggestionKeys = new HashSet<String>(); 37 } 38 39 @Override 40 public boolean add(Suggestion suggestion) { 41 String key = getSuggestionKey(suggestion); 42 if (mSuggestionKeys.add(key)) { 43 return super.add(suggestion); 44 } else { 45 if (DBG) Log.d(TAG, "Rejecting duplicate " + key); 46 return false; 47 } 48 } 49 50 /** 51 * Gets a unique key that identifies a suggestion. This is used to avoid 52 * duplicate suggestions in the promoted list. 53 */ 54 private String getSuggestionKey(Suggestion suggestion) { 55 String action = makeKeyComponent(suggestion.getSuggestionIntentAction()); 56 String data = makeKeyComponent(normalizeUrl(suggestion.getSuggestionIntentDataString())); 57 String query = makeKeyComponent(normalizeUrl(suggestion.getSuggestionQuery())); 58 // calculating accurate size of string builder avoids an allocation vs starting with 59 // the default size and having to expand. 60 int size = action.length() + 2 + data.length() + query.length(); 61 return new StringBuilder(size) 62 .append(action) 63 .append('#') 64 .append(data) 65 .append('#') 66 .append(query) 67 .toString(); 68 } 69 70 private String makeKeyComponent(String str) { 71 return str == null ? "" : str; 72 } 73 74 /** Simple url normalization that strips http:// and empty paths, i.e., 75 * http://www.google.com/ -> www.google.com. Used to prevent obvious 76 * duplication of nav suggestions, bookmarks and urls entered by the user. 77 */ 78 private static String normalizeUrl(String url) { 79 if (url != null && url.startsWith("http://")) { 80 int start = 7; // length of http:// 81 int end = url.length(); 82 if (url.indexOf('/', start) == end - 1) { 83 end--; 84 } 85 return url.substring(start, end); 86 } 87 return url; 88 } 89 90} 91