MultiSourceCorpus.java revision 96c7058210699c82445169048b7c0fdfb16f59ee
1/* 2 * Copyright (C) 2010 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 19 20import com.android.quicksearchbox.util.BarrierConsumer; 21 22import android.content.Context; 23 24import java.util.ArrayList; 25import java.util.Collection; 26import java.util.List; 27import java.util.concurrent.Executor; 28 29/** 30 * Base class for corpora backed by multiple sources. 31 */ 32public abstract class MultiSourceCorpus extends AbstractCorpus { 33 34 private final Executor mExecutor; 35 36 private final ArrayList<Source> mSources; 37 38 public MultiSourceCorpus(Context context, Config config, 39 Executor executor, Source... sources) { 40 super(context, config); 41 mExecutor = executor; 42 43 mSources = new ArrayList<Source>(); 44 for (Source source : sources) { 45 if (source != null) { 46 mSources.add(source); 47 } 48 } 49 } 50 51 public Collection<Source> getSources() { 52 return mSources; 53 } 54 55 /** 56 * Creates a corpus result object for a set of source results. 57 * This method should not call {@link Result#fill}. 58 * 59 * @param query The query text. 60 * @param results The results of the queries. 61 * @param latency Latency in milliseconds of the suggestion queries. 62 * @return An instance of {@link Result} or a subclass of it. 63 */ 64 protected Result createResult(String query, ArrayList<SourceResult> results, int latency) { 65 return new Result(query, results, latency); 66 } 67 68 /** 69 * Gets the sources to query for the given input. 70 * 71 * @param query The current input. 72 * @return The sources to query. 73 */ 74 protected List<Source> getSourcesToQuery(String query) { 75 return mSources; 76 } 77 78 public CorpusResult getSuggestions(String query, int queryLimit) { 79 LatencyTracker latencyTracker = new LatencyTracker(); 80 List<Source> sources = getSourcesToQuery(query); 81 BarrierConsumer<SourceResult> consumer = 82 new BarrierConsumer<SourceResult>(sources.size()); 83 for (Source source : sources) { 84 QueryTask<SourceResult> task = new QueryTask<SourceResult>(query, queryLimit, 85 source, null, consumer); 86 mExecutor.execute(task); 87 } 88 ArrayList<SourceResult> results = consumer.getValues(); 89 int latency = latencyTracker.getLatency(); 90 Result result = createResult(query, results, latency); 91 result.fill(); 92 return result; 93 } 94 95 /** 96 * Base class for results returned by {@link MultiSourceCorpus#getSuggestions}. 97 * Subclasses of {@link MultiSourceCorpus} should override 98 * {@link MultiSourceCorpus#createResult} and return an instance of this class or a 99 * subclass. 100 */ 101 protected class Result extends ListSuggestionCursor implements CorpusResult { 102 103 private final ArrayList<SourceResult> mResults; 104 105 private final int mLatency; 106 107 public Result(String userQuery, ArrayList<SourceResult> results, int latency) { 108 super(userQuery); 109 mResults = results; 110 mLatency = latency; 111 } 112 113 protected ArrayList<SourceResult> getResults() { 114 return mResults; 115 } 116 117 /** 118 * Fills the list of suggestions using the list of results. 119 * The default implementation concatenates the results. 120 */ 121 public void fill() { 122 for (SourceResult result : getResults()) { 123 int count = result.getCount(); 124 for (int i = 0; i < count; i++) { 125 result.moveTo(i); 126 add(new SuggestionPosition(result)); 127 } 128 } 129 } 130 131 public Corpus getCorpus() { 132 return MultiSourceCorpus.this; 133 } 134 135 public int getLatency() { 136 return mLatency; 137 } 138 139 @Override 140 public void close() { 141 super.close(); 142 for (SourceResult result : mResults) { 143 result.close(); 144 } 145 } 146 147 @Override 148 public String toString() { 149 return getCorpus() + "[" + getUserQuery() + "]"; 150 } 151 } 152 153} 154