Home | History | Annotate | Download | only in searchabledict
      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 
     17 package com.example.android.searchabledict;
     18 
     19 import android.app.SearchManager;
     20 import android.content.ContentProvider;
     21 import android.content.ContentResolver;
     22 import android.content.ContentValues;
     23 import android.content.UriMatcher;
     24 import android.database.Cursor;
     25 import android.net.Uri;
     26 import android.provider.BaseColumns;
     27 
     28 /**
     29  * Provides access to the dictionary database.
     30  */
     31 public class DictionaryProvider extends ContentProvider {
     32     String TAG = "DictionaryProvider";
     33 
     34     public static String AUTHORITY = "com.example.android.searchabledict.DictionaryProvider";
     35     public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/dictionary");
     36 
     37     // MIME types used for searching words or looking up a single definition
     38     public static final String WORDS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +
     39                                                   "/vnd.example.android.searchabledict";
     40     public static final String DEFINITION_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE +
     41                                                        "/vnd.example.android.searchabledict";
     42 
     43     private DictionaryDatabase mDictionary;
     44 
     45     // UriMatcher stuff
     46     private static final int SEARCH_WORDS = 0;
     47     private static final int GET_WORD = 1;
     48     private static final int SEARCH_SUGGEST = 2;
     49     private static final int REFRESH_SHORTCUT = 3;
     50     private static final UriMatcher sURIMatcher = buildUriMatcher();
     51 
     52     /**
     53      * Builds up a UriMatcher for search suggestion and shortcut refresh queries.
     54      */
     55     private static UriMatcher buildUriMatcher() {
     56         UriMatcher matcher =  new UriMatcher(UriMatcher.NO_MATCH);
     57         // to get definitions...
     58         matcher.addURI(AUTHORITY, "dictionary", SEARCH_WORDS);
     59         matcher.addURI(AUTHORITY, "dictionary/#", GET_WORD);
     60         // to get suggestions...
     61         matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
     62         matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
     63 
     64         /* The following are unused in this implementation, but if we include
     65          * {@link SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} as a column in our suggestions table, we
     66          * could expect to receive refresh queries when a shortcutted suggestion is displayed in
     67          * Quick Search Box, in which case, the following Uris would be provided and we
     68          * would return a cursor with a single item representing the refreshed suggestion data.
     69          */
     70         matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT, REFRESH_SHORTCUT);
     71         matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/*", REFRESH_SHORTCUT);
     72         return matcher;
     73     }
     74 
     75     @Override
     76     public boolean onCreate() {
     77         mDictionary = new DictionaryDatabase(getContext());
     78         return true;
     79     }
     80 
     81     /**
     82      * Handles all the dictionary searches and suggestion queries from the Search Manager.
     83      * When requesting a specific word, the uri alone is required.
     84      * When searching all of the dictionary for matches, the selectionArgs argument must carry
     85      * the search query as the first element.
     86      * All other arguments are ignored.
     87      */
     88     @Override
     89     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
     90                         String sortOrder) {
     91 
     92         // Use the UriMatcher to see what kind of query we have and format the db query accordingly
     93         switch (sURIMatcher.match(uri)) {
     94             case SEARCH_SUGGEST:
     95                 if (selectionArgs == null) {
     96                   throw new IllegalArgumentException(
     97                       "selectionArgs must be provided for the Uri: " + uri);
     98                 }
     99                 return getSuggestions(selectionArgs[0]);
    100             case SEARCH_WORDS:
    101                 if (selectionArgs == null) {
    102                   throw new IllegalArgumentException(
    103                       "selectionArgs must be provided for the Uri: " + uri);
    104                 }
    105                 return search(selectionArgs[0]);
    106             case GET_WORD:
    107                 return getWord(uri);
    108             case REFRESH_SHORTCUT:
    109                 return refreshShortcut(uri);
    110             default:
    111                 throw new IllegalArgumentException("Unknown Uri: " + uri);
    112         }
    113     }
    114 
    115     private Cursor getSuggestions(String query) {
    116       query = query.toLowerCase();
    117       String[] columns = new String[] {
    118           BaseColumns._ID,
    119           DictionaryDatabase.KEY_WORD,
    120           DictionaryDatabase.KEY_DEFINITION,
    121        /* SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
    122                         (only if you want to refresh shortcuts) */
    123           SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
    124 
    125       return mDictionary.getWordMatches(query, columns);
    126     }
    127 
    128     private Cursor search(String query) {
    129       query = query.toLowerCase();
    130       String[] columns = new String[] {
    131           BaseColumns._ID,
    132           DictionaryDatabase.KEY_WORD,
    133           DictionaryDatabase.KEY_DEFINITION};
    134 
    135       return mDictionary.getWordMatches(query, columns);
    136     }
    137 
    138     private Cursor getWord(Uri uri) {
    139       String rowId = uri.getLastPathSegment();
    140       String[] columns = new String[] {
    141           DictionaryDatabase.KEY_WORD,
    142           DictionaryDatabase.KEY_DEFINITION};
    143 
    144       return mDictionary.getWord(rowId, columns);
    145     }
    146 
    147     private Cursor refreshShortcut(Uri uri) {
    148       /* This won't be called with the current implementation, but if we include
    149        * {@link SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} as a column in our suggestions table, we
    150        * could expect to receive refresh queries when a shortcutted suggestion is displayed in
    151        * Quick Search Box. In which case, this method will query the table for the specific
    152        * word, using the given item Uri and provide all the columns originally provided with the
    153        * suggestion query.
    154        */
    155       String rowId = uri.getLastPathSegment();
    156       String[] columns = new String[] {
    157           BaseColumns._ID,
    158           DictionaryDatabase.KEY_WORD,
    159           DictionaryDatabase.KEY_DEFINITION,
    160           SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
    161           SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
    162 
    163       return mDictionary.getWord(rowId, columns);
    164     }
    165 
    166     /**
    167      * This method is required in order to query the supported types.
    168      * It's also useful in our own query() method to determine the type of Uri received.
    169      */
    170     @Override
    171     public String getType(Uri uri) {
    172         switch (sURIMatcher.match(uri)) {
    173             case SEARCH_WORDS:
    174                 return WORDS_MIME_TYPE;
    175             case GET_WORD:
    176                 return DEFINITION_MIME_TYPE;
    177             case SEARCH_SUGGEST:
    178                 return SearchManager.SUGGEST_MIME_TYPE;
    179             case REFRESH_SHORTCUT:
    180                 return SearchManager.SHORTCUT_MIME_TYPE;
    181             default:
    182                 throw new IllegalArgumentException("Unknown URL " + uri);
    183         }
    184     }
    185 
    186     // Other required implementations...
    187 
    188     @Override
    189     public Uri insert(Uri uri, ContentValues values) {
    190         throw new UnsupportedOperationException();
    191     }
    192 
    193     @Override
    194     public int delete(Uri uri, String selection, String[] selectionArgs) {
    195         throw new UnsupportedOperationException();
    196     }
    197 
    198     @Override
    199     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    200         throw new UnsupportedOperationException();
    201     }
    202 
    203 }
    204