Home | History | Annotate | Download | only in quicksearchbox
      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 
     17 package com.android.quicksearchbox;
     18 
     19 import com.google.common.annotations.VisibleForTesting;
     20 
     21 import android.database.DataSetObservable;
     22 import android.database.DataSetObserver;
     23 
     24 import java.util.ArrayList;
     25 import java.util.Collection;
     26 import java.util.HashSet;
     27 
     28 /**
     29  * A SuggestionCursor that is backed by a list of Suggestions.
     30  */
     31 public class ListSuggestionCursor extends AbstractSuggestionCursorWrapper {
     32 
     33     private static final int DEFAULT_CAPACITY = 16;
     34 
     35     private final DataSetObservable mDataSetObservable = new DataSetObservable();
     36 
     37     private final ArrayList<Entry> mSuggestions;
     38 
     39     private HashSet<String> mExtraColumns;
     40 
     41     private int mPos = 0;
     42 
     43     public ListSuggestionCursor(String userQuery) {
     44         this(userQuery, DEFAULT_CAPACITY);
     45     }
     46 
     47     @VisibleForTesting
     48     public ListSuggestionCursor(String userQuery, Suggestion...suggestions) {
     49         this(userQuery, suggestions.length);
     50         for (Suggestion suggestion : suggestions) {
     51             add(suggestion);
     52         }
     53     }
     54 
     55     public ListSuggestionCursor(String userQuery, int capacity) {
     56         super(userQuery);
     57         mSuggestions = new ArrayList<Entry>(capacity);
     58     }
     59 
     60     /**
     61      * Adds a suggestion from another suggestion cursor.
     62      *
     63      * @return {@code true} if the suggestion was added.
     64      */
     65     public boolean add(Suggestion suggestion) {
     66         mSuggestions.add(new Entry(suggestion));
     67         return true;
     68     }
     69 
     70     public void close() {
     71         mSuggestions.clear();
     72     }
     73 
     74     public int getPosition() {
     75         return mPos;
     76     }
     77 
     78     public void moveTo(int pos) {
     79         mPos = pos;
     80     }
     81 
     82     public boolean moveToNext() {
     83         int size = mSuggestions.size();
     84         if (mPos >= size) {
     85             // Already past the end
     86             return false;
     87         }
     88         mPos++;
     89         return mPos < size;
     90     }
     91 
     92     public void removeRow() {
     93         mSuggestions.remove(mPos);
     94     }
     95 
     96     public void replaceRow(Suggestion suggestion) {
     97         mSuggestions.set(mPos, new Entry(suggestion));
     98     }
     99 
    100     public int getCount() {
    101         return mSuggestions.size();
    102     }
    103 
    104     @Override
    105     protected Suggestion current() {
    106         return mSuggestions.get(mPos).get();
    107     }
    108 
    109     @Override
    110     public String toString() {
    111         return getClass().getSimpleName() + "{[" + getUserQuery() + "] " + mSuggestions + "}";
    112     }
    113 
    114     /**
    115      * Register an observer that is called when changes happen to this data set.
    116      *
    117      * @param observer gets notified when the data set changes.
    118      */
    119     public void registerDataSetObserver(DataSetObserver observer) {
    120         mDataSetObservable.registerObserver(observer);
    121     }
    122 
    123     /**
    124      * Unregister an observer that has previously been registered with
    125      * {@link #registerDataSetObserver(DataSetObserver)}
    126      *
    127      * @param observer the observer to unregister.
    128      */
    129     public void unregisterDataSetObserver(DataSetObserver observer) {
    130         mDataSetObservable.unregisterObserver(observer);
    131     }
    132 
    133     protected void notifyDataSetChanged() {
    134         mDataSetObservable.notifyChanged();
    135     }
    136 
    137     @Override
    138     public SuggestionExtras getExtras() {
    139         // override with caching to avoid re-parsing the extras
    140         return mSuggestions.get(mPos).getExtras();
    141     }
    142 
    143    public Collection<String> getExtraColumns() {
    144         if (mExtraColumns == null) {
    145             mExtraColumns = new HashSet<String>();
    146             for (Entry e : mSuggestions) {
    147                 SuggestionExtras extras = e.getExtras();
    148                 Collection<String> extraColumns = extras == null ? null
    149                         : extras.getExtraColumnNames();
    150                 if (extraColumns != null) {
    151                     for (String column : extras.getExtraColumnNames()) {
    152                         mExtraColumns.add(column);
    153                     }
    154                 }
    155             }
    156         }
    157         return mExtraColumns.isEmpty() ? null : mExtraColumns;
    158     }
    159 
    160     /**
    161      * This class exists purely to cache the suggestion extras.
    162      */
    163     private static class Entry {
    164         private final Suggestion mSuggestion;
    165         private SuggestionExtras mExtras;
    166         public Entry(Suggestion s) {
    167             mSuggestion = s;
    168         }
    169         public Suggestion get() {
    170             return mSuggestion;
    171         }
    172         public SuggestionExtras getExtras() {
    173             if (mExtras == null) {
    174                 mExtras = mSuggestion.getExtras();
    175             }
    176             return mExtras;
    177         }
    178     }
    179 
    180 }
    181