Code example for Uri

Methods: getPathSegmentsgetQueryParametertoString

0
        return true; 
    } 
 
    private static int matchUri(final Uri uri) {
        int protocolVersion = 1;
        final String protocolVersionArg = uri.getQueryParameter(QUERY_PARAMETER_PROTOCOL_VERSION);
        if ("2".equals(protocolVersionArg)) protocolVersion = 2;
        switch (protocolVersion) {
            case 1: return sUriMatcherV1.match(uri);
            case 2: return sUriMatcherV2.match(uri);
            default: return NO_MATCH;
        } 
    } 
 
    private static String getClientId(final Uri uri) {
        int protocolVersion = 1;
        final String protocolVersionArg = uri.getQueryParameter(QUERY_PARAMETER_PROTOCOL_VERSION);
        if ("2".equals(protocolVersionArg)) protocolVersion = 2;
        switch (protocolVersion) {
            case 1: return null; // In protocol 1, the client ID is always null. 
            case 2: return uri.getPathSegments().get(0);
            default: return null; 
        } 
    } 
 
    /** 
     * Returns the MIME type of the content associated with an Uri 
     * 
     * @see android.content.ContentProvider#getType(android.net.Uri) 
     * 
     * @param uri the URI of the content the type of which should be returned. 
     * @return the MIME type, or null if the URL is not recognized. 
     */ 
    @Override 
    public String getType(final Uri uri) {
        PrivateLog.log("Asked for type of : " + uri);
        final int match = matchUri(uri);
        switch (match) {
            case NO_MATCH: return null;
            case DICTIONARY_V1_WHOLE_LIST:
            case DICTIONARY_V1_DICT_INFO:
            case DICTIONARY_V2_WHOLE_LIST:
            case DICTIONARY_V2_DICT_INFO: return DICT_LIST_MIME_TYPE;
            case DICTIONARY_V2_DATAFILE: return DICT_DATAFILE_MIME_TYPE;
            default: return null; 
        } 
    } 
 
    /** 
     * Query the provider for dictionary files. 
     * 
     * This version dispatches the query according to the protocol version found in the 
     * ?protocol= query parameter. If absent or not well-formed, it defaults to 1. 
     * @see android.content.ContentProvider#query(Uri, String[], String, String[], String) 
     * 
     * @param uri a content uri (see sUriMatcherV{1,2} at the top of this file for format) 
     * @param projection ignored. All columns are always returned. 
     * @param selection ignored. 
     * @param selectionArgs ignored. 
     * @param sortOrder ignored. The results are always returned in no particular order. 
     * @return a cursor matching the uri, or null if the URI was not recognized. 
     */ 
    @Override 
    public Cursor query(final Uri uri, final String[] projection, final String selection,
            final String[] selectionArgs, final String sortOrder) {
        Utils.l("Uri =", uri);
        PrivateLog.log("Query : " + uri);
        final String clientId = getClientId(uri);
        final int match = matchUri(uri);
        switch (match) {
            case DICTIONARY_V1_WHOLE_LIST:
            case DICTIONARY_V2_WHOLE_LIST:
                final Cursor c = MetadataDbHelper.queryDictionaries(getContext(), clientId);
                Utils.l("List of dictionaries with count", c.getCount());
                PrivateLog.log("Returned a list of " + c.getCount() + " items");
                return c;
            case DICTIONARY_V2_DICT_INFO:
                // In protocol version 2, we return null if the client is unknown. Otherwise 
                // we behave exactly like for protocol 1. 
                if (!MetadataDbHelper.isClientKnown(getContext(), clientId)) return null;
                // Fall through 
            case DICTIONARY_V1_DICT_INFO:
                final String locale = uri.getLastPathSegment();
                // If LatinIME does not have a dictionary for this locale at all, it will 
                // send us true for this value. In this case, we may prompt the user for 
                // a decision about downloading a dictionary even over a metered connection. 
                final String mayPromptValue =
                        uri.getQueryParameter(QUERY_PARAMETER_MAY_PROMPT_USER);
                final boolean mayPrompt = QUERY_PARAMETER_TRUE.equals(mayPromptValue);
                final Collection<WordListInfo> dictFiles =
                        getDictionaryWordListsForLocale(clientId, locale, mayPrompt);
                // TODO: pass clientId to the following function 
                DictionaryService.updateNowIfNotUpdatedInAVeryLongTime(getContext());
                if (null != dictFiles && dictFiles.size() > 0) {
                    PrivateLog.log("Returned " + dictFiles.size() + " files");
                    return new ResourcePathCursor(dictFiles);
                } else { 
                    PrivateLog.log("No dictionary files for this URL"); 
                    return new ResourcePathCursor(Collections.<WordListInfo>emptyList());
                } 
            // V2_METADATA and V2_DATAFILE are not supported for query() 
            default: 
                return null; 
        } 
    } 
 
    /** 
     * Helper method to get the wordlist metadata associated with a wordlist ID. 
     * 
     * @param clientId the ID of the client 
     * @param wordlistId the ID of the wordlist for which to get the metadata. 
     * @return the metadata for this wordlist ID, or null if none could be found. 
     */ 
    private ContentValues getWordlistMetadataForWordlistId(final String clientId,
            final String wordlistId) {
        final Context context = getContext();
        if (TextUtils.isEmpty(wordlistId)) return null;
        final SQLiteDatabase db = MetadataDbHelper.getDb(context, clientId);
        return MetadataDbHelper.getInstalledOrDeletingWordListContentValuesByWordListId( 
                db, wordlistId);
    } 
 
    /** 
     * Opens an asset file for an URI. 
     * 
     * Called by {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)} or 
     * {@link android.content.ContentResolver#openInputStream(Uri)} from a client requesting a 
     * dictionary. 
     * @see android.content.ContentProvider#openAssetFile(Uri, String) 
     * 
     * @param uri the URI the file is for. 
     * @param mode the mode to read the file. MUST be "r" for readonly. 
     * @return the descriptor, or null if the file is not found or if mode is not equals to "r". 
     */ 
    @Override 
    public AssetFileDescriptor openAssetFile(final Uri uri, final String mode) {
        if (null == mode || !"r".equals(mode)) return null;
 
        final int match = matchUri(uri);
        if (DICTIONARY_V1_DICT_INFO != match && DICTIONARY_V2_DATAFILE != match) {
            // Unsupported URI for openAssetFile 
            Log.w(TAG, "Unsupported URI for openAssetFile : " + uri);
            return null; 
        } 
        final String wordlistId = uri.getLastPathSegment();
        final String clientId = getClientId(uri);
        final ContentValues wordList = getWordlistMetadataForWordlistId(clientId, wordlistId);
 
        if (null == wordList) return null;
 
        try { 
            final int status = wordList.getAsInteger(MetadataDbHelper.STATUS_COLUMN);
            if (MetadataDbHelper.STATUS_DELETING == status) {
                // This will return an empty file (R.raw.empty points at an empty dictionary) 
                // This is how we "delete" the files. It allows Android Keyboard to fake deleting 
                // a default dictionary - which is actually in its assets and can't be really 
                // deleted. 
                final AssetFileDescriptor afd = getContext().getResources().openRawResourceFd(
                        R.raw.empty); 
                return afd;
            } else { 
                final String localFilename =
                        wordList.getAsString(MetadataDbHelper.LOCAL_FILENAME_COLUMN);
                final File f = getContext().getFileStreamPath(localFilename);
                final ParcelFileDescriptor pfd =
                        ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
                return new AssetFileDescriptor(pfd, 0, pfd.getStatSize());
            } 
        } catch (FileNotFoundException e) {
            // No file : fall through and return null 
        } 
        return null; 
    } 
 
    /** 
     * Reads the metadata and returns the collection of dictionaries for a given locale. 
     * 
     * Word list IDs are expected to be in the form category:manual_id. This method 
     * will select only one word list for each category: the one with the most specific 
     * locale matching the locale specified in the URI. The manual id serves only to 
     * distinguish a word list from another for the purpose of updating, and is arbitrary 
     * but may not contain a colon. 
     * 
     * @param clientId the ID of the client requesting the list 
     * @param locale the locale for which we want the list, as a String 
     * @param mayPrompt true if we are allowed to prompt the user for arbitration via notification 
     * @return a collection of ids. It is guaranteed to be non-null, but may be empty. 
     */ 
    private Collection<WordListInfo> getDictionaryWordListsForLocale(final String clientId,
            final String locale, final boolean mayPrompt) {
        final Context context = getContext();
        final Cursor results =
                MetadataDbHelper.queryInstalledOrDeletingOrAvailableDictionaryMetadata(context,
                        clientId);
        if (null == results) {
            return Collections.<WordListInfo>emptyList();
        } else { 
            final HashMap<String, WordListInfo> dicts = new HashMap<String, WordListInfo>();
            final int idIndex = results.getColumnIndex(MetadataDbHelper.WORDLISTID_COLUMN);
            final int localeIndex = results.getColumnIndex(MetadataDbHelper.LOCALE_COLUMN);
            final int localFileNameIndex =
                    results.getColumnIndex(MetadataDbHelper.LOCAL_FILENAME_COLUMN);
            final int statusIndex = results.getColumnIndex(MetadataDbHelper.STATUS_COLUMN);
            if (results.moveToFirst()) {
                do { 
                    final String wordListId = results.getString(idIndex);
                    if (TextUtils.isEmpty(wordListId)) continue;
                    final String[] wordListIdArray =
                            TextUtils.split(wordListId, ID_CATEGORY_SEPARATOR);
                    final String wordListCategory;
                    if (2 == wordListIdArray.length) {
                        // This is at the category:manual_id format. 
                        wordListCategory = wordListIdArray[0];
                        // We don't need to read wordListIdArray[1] here, because it's irrelevant to 
                        // word list selection - it's just a name we use to identify which data file 
                        // is a newer version of which word list. We do however return the full id 
                        // string for each selected word list, so in this sense we are 'using' it. 
                    } else { 
                        // This does not contain a colon, like the old format does. Old-format IDs 
                        // always point to main dictionaries, so we force the main category upon it. 
                        wordListCategory = UpdateHandler.MAIN_DICTIONARY_CATEGORY;
                    } 
                    final String wordListLocale = results.getString(localeIndex);
                    final String wordListLocalFilename = results.getString(localFileNameIndex);
                    final int wordListStatus = results.getInt(statusIndex);
                    // Test the requested locale against this wordlist locale. The requested locale 
                    // has to either match exactly or be more specific than the dictionary - a 
                    // dictionary for "en" would match both a request for "en" or for "en_US", but a 
                    // dictionary for "en_GB" would not match a request for "en_US". Thus if all 
                    // three of "en" "en_US" and "en_GB" dictionaries are installed, a request for 
                    // "en_US" would match "en" and "en_US", and a request for "en" only would only 
                    // match the generic "en" dictionary. For more details, see the documentation 
                    // for LocaleUtils#getMatchLevel. 
                    final int matchLevel = LocaleUtils.getMatchLevel(wordListLocale, locale);
                    if (!LocaleUtils.isMatch(matchLevel)) {
                        // The locale of this wordlist does not match the required locale. 
                        // Skip this wordlist and go to the next. 
                        continue; 
                    } 
                    if (MetadataDbHelper.STATUS_INSTALLED == wordListStatus) {
                        // If the file does not exist, it has been deleted and the IME should 
                        // already have it. Do not return it. However, this only applies if the 
                        // word list is INSTALLED, for if it is DELETING we should return it always 
                        // so that Android Keyboard can perform the actual deletion. 
                        final File f = getContext().getFileStreamPath(wordListLocalFilename);
                        if (!f.isFile()) {
                            continue; 
                        } 
                    } else if (MetadataDbHelper.STATUS_AVAILABLE == wordListStatus) {
                        // The locale is the id for the main dictionary. 
                        UpdateHandler.installIfNeverRequested(context, clientId, wordListId,
                                mayPrompt);
                        continue; 
                    } 
                    final WordListInfo currentBestMatch = dicts.get(wordListCategory);
                    if (null == currentBestMatch
                            || currentBestMatch.mMatchLevel < matchLevel) {
                        dicts.put(wordListCategory,
                                new WordListInfo(wordListId, wordListLocale, matchLevel));
                    } 
                } while (results.moveToNext());
            } 
            results.close();
            return Collections.unmodifiableCollection(dicts.values());
        } 
    } 
 
    /** 
     * Deletes the file pointed by Uri, as returned by openAssetFile. 
     * 
     * @param uri the URI the file is for. 
     * @param selection ignored 
     * @param selectionArgs ignored 
     * @return the number of files deleted (0 or 1 in the current implementation) 
     * @see android.content.ContentProvider#delete(Uri, String, String[]) 
     */ 
    @Override 
    public int delete(final Uri uri, final String selection, final String[] selectionArgs)
            throws UnsupportedOperationException { 
        final int match = matchUri(uri);
        if (DICTIONARY_V1_DICT_INFO == match || DICTIONARY_V2_DATAFILE == match) {
            return deleteDataFile(uri);
        } 
        if (DICTIONARY_V2_METADATA == match) {
            if (MetadataDbHelper.deleteClient(getContext(), getClientId(uri))) {
                return 1; 
            } 
            return 0; 
        } 
        // Unsupported URI for delete 
        return 0; 
    } 
 
    private int deleteDataFile(final Uri uri) {
        final String wordlistId = uri.getLastPathSegment();
        final String clientId = getClientId(uri);
        final ContentValues wordList = getWordlistMetadataForWordlistId(clientId, wordlistId);
        if (null == wordList) return 0;
        final int status = wordList.getAsInteger(MetadataDbHelper.STATUS_COLUMN);
        final int version = wordList.getAsInteger(MetadataDbHelper.VERSION_COLUMN);
        if (MetadataDbHelper.STATUS_DELETING == status) {
            UpdateHandler.markAsDeleted(getContext(), clientId, wordlistId, version, status);
            return 1; 
        } else if (MetadataDbHelper.STATUS_INSTALLED == status) {
            final String result = uri.getQueryParameter(QUERY_PARAMETER_DELETE_RESULT);
            if (QUERY_PARAMETER_FAILURE.equals(result)) {
                UpdateHandler.markAsBroken(getContext(), clientId, wordlistId, version);
            } 
            final String localFilename =
                    wordList.getAsString(MetadataDbHelper.LOCAL_FILENAME_COLUMN);
            final File f = getContext().getFileStreamPath(localFilename);
            // f.delete() returns true if the file was successfully deleted, false otherwise 
            if (f.delete()) {
                return 1; 
            } else { 
                return 0; 
            } 
        } else { 
            Log.e(TAG, "Attempt to delete a file whose status is " + status);
            return 0; 
        } 
    } 
 
    /** 
     * Insert data into the provider. May be either a metadata source URL or some dictionary info. 
     * 
     * @param uri the designated content URI. See sUriMatcherV{1,2} for available URIs. 
     * @param values the values to insert for this content uri 
     * @return the URI for the newly inserted item. May be null if arguments don't allow for insert 
     */ 
    @Override 
    public Uri insert(final Uri uri, final ContentValues values)
            throws UnsupportedOperationException { 
        if (null == uri || null == values) return null; // Should never happen but let's be safe
        PrivateLog.log("Insert, uri = " + uri.toString());
        final String clientId = getClientId(uri);
        switch (matchUri(uri)) {
            case DICTIONARY_V2_METADATA:
                // The values should contain a valid client ID and a valid URI for the metadata. 
                // The client ID may not be null, nor may it be empty because the empty client ID 
Stop searching for code, let great code find you!  Add Codota to your java IDE