/*
** Copyright 2012, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

package com.android.commands.content;

import android.app.ActivityManager;
import android.app.ContentProviderHolder;
import android.app.IActivityManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.IContentProvider;
import android.database.Cursor;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Pair;

import java.io.FileDescriptor;
import java.util.ArrayList;
import java.util.List;

/**
 * This class is a command line utility for manipulating content. A client
 * can insert, update, and remove records in a content provider. For example,
 * some settings may be configured before running the CTS tests, etc.
 * <p>
 * Examples:
 * <ul>
 * <li>
 * # Add "new_setting" secure setting with value "new_value".</br>
 * adb shell content insert --uri content://settings/secure --bind name:s:new_setting
 *  --bind value:s:new_value
 * </li>
 * <li>
 * # Change "new_setting" secure setting to "newer_value" (You have to escape single quotes in
 * the where clause).</br>
 * adb shell content update --uri content://settings/secure --bind value:s:newer_value
 *  --where "name=\'new_setting\'"
 * </li>
 * <li>
 * # Remove "new_setting" secure setting.</br>
 * adb shell content delete --uri content://settings/secure --where "name=\'new_setting\'"
 * </li>
 * <li>
 * # Query \"name\" and \"value\" columns from secure settings where \"name\" is equal to"
 *    \"new_setting\" and sort the result by name in ascending order.\n"
 * adb shell content query --uri content://settings/secure --projection name:value
 *  --where "name=\'new_setting\'" --sort \"name ASC\"
 * </li>
 * </ul>
 * </p>
 */
public class Content {

    private static final String USAGE =
            "usage: adb shell content [subcommand] [options]\n"
                    + "\n"
                    + "usage: adb shell content insert --uri <URI> [--user <USER_ID>]"
                    + " --bind <BINDING> [--bind <BINDING>...] [--extra <BINDING>...]\n"
                    + "  <URI> a content provider URI.\n"
                    + "  <BINDING> binds a typed value to a column and is formatted:\n"
                    + "  <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n"
                    + "  <TYPE> specifies data type such as:\n"
                    + "  b - boolean, s - string, i - integer, l - long, f - float, d - double, n - null\n"
                    + "  Note: Omit the value for passing an empty string, e.g column:s:\n"
                    + "  Example:\n"
                    + "  # Add \"new_setting\" secure setting with value \"new_value\".\n"
                    + "  adb shell content insert --uri content://settings/secure --bind name:s:new_setting"
                    + " --bind value:s:new_value\n"
                    + "\n"
                    + "usage: adb shell content update --uri <URI> [--user <USER_ID>]"
                    + " [--where <WHERE>] [--extra <BINDING>...]\n"
                    + "  <WHERE> is a SQL style where clause in quotes (You have to escape single quotes"
                    + " - see example below).\n"
                    + "  Example:\n"
                    + "  # Change \"new_setting\" secure setting to \"newer_value\".\n"
                    + "  adb shell content update --uri content://settings/secure --bind"
                    + " value:s:newer_value --where \"name=\'new_setting\'\"\n"
                    + "\n"
                    + "usage: adb shell content delete --uri <URI> [--user <USER_ID>] --bind <BINDING>"
                    + " [--bind <BINDING>...] [--where <WHERE>] [--extra <BINDING>...]\n"
                    + "  Example:\n"
                    + "  # Remove \"new_setting\" secure setting.\n"
                    + "  adb shell content delete --uri content://settings/secure "
                    + "--where \"name=\'new_setting\'\"\n"
                    + "\n"
                    + "usage: adb shell content query --uri <URI> [--user <USER_ID>]"
                    + " [--projection <PROJECTION>] [--where <WHERE>] [--sort <SORT_ORDER>]"
                    + " [--extra <BINDING>...]\n"
                    + "  <PROJECTION> is a list of colon separated column names and is formatted:\n"
                    + "  <COLUMN_NAME>[:<COLUMN_NAME>...]\n"
                    + "  <SORT_ORDER> is the order in which rows in the result should be sorted.\n"
                    + "  Example:\n"
                    + "  # Select \"name\" and \"value\" columns from secure settings where \"name\" is "
                    + "equal to \"new_setting\" and sort the result by name in ascending order.\n"
                    + "  adb shell content query --uri content://settings/secure --projection name:value"
                    + " --where \"name=\'new_setting\'\" --sort \"name ASC\"\n"
                    + "\n"
                    + "usage: adb shell content call --uri <URI> --method <METHOD> [--arg <ARG>]\n"
                    + "       [--extra <BINDING> ...]\n"
                    + "  <METHOD> is the name of a provider-defined method\n"
                    + "  <ARG> is an optional string argument\n"
                    + "  <BINDING> is like --bind above, typed data of the form <KEY>:{b,s,i,l,f,d}:<VAL>\n"
                    + "\n"
                    + "usage: adb shell content read --uri <URI> [--user <USER_ID>]\n"
                    + "  Example:\n"
                    + "  adb shell 'content read --uri content://settings/system/ringtone_cache' > host.ogg\n"
                    + "\n"
                    + "usage: adb shell content write --uri <URI> [--user <USER_ID>]\n"
                    + "  Example:\n"
                    + "  adb shell 'content write --uri content://settings/system/ringtone_cache' < host.ogg\n"
                    + "\n"
                    + "usage: adb shell content gettype --uri <URI> [--user <USER_ID>]\n"
                    + "  Example:\n"
                    + "  adb shell content gettype --uri content://media/internal/audio/media/\n"
                    + "\n";

    private static class Parser {
        private static final String ARGUMENT_INSERT = "insert";
        private static final String ARGUMENT_DELETE = "delete";
        private static final String ARGUMENT_UPDATE = "update";
        private static final String ARGUMENT_QUERY = "query";
        private static final String ARGUMENT_CALL = "call";
        private static final String ARGUMENT_READ = "read";
        private static final String ARGUMENT_WRITE = "write";
        private static final String ARGUMENT_GET_TYPE = "gettype";
        private static final String ARGUMENT_WHERE = "--where";
        private static final String ARGUMENT_BIND = "--bind";
        private static final String ARGUMENT_URI = "--uri";
        private static final String ARGUMENT_USER = "--user";
        private static final String ARGUMENT_PROJECTION = "--projection";
        private static final String ARGUMENT_SORT = "--sort";
        private static final String ARGUMENT_METHOD = "--method";
        private static final String ARGUMENT_ARG = "--arg";
        private static final String ARGUMENT_EXTRA = "--extra";
        private static final String TYPE_BOOLEAN = "b";
        private static final String TYPE_STRING = "s";
        private static final String TYPE_INTEGER = "i";
        private static final String TYPE_LONG = "l";
        private static final String TYPE_FLOAT = "f";
        private static final String TYPE_DOUBLE = "d";
        private static final String TYPE_NULL = "n";
        private static final String COLON = ":";
        private static final String ARGUMENT_PREFIX = "--";

        private final Tokenizer mTokenizer;

        public Parser(String[] args) {
            mTokenizer = new Tokenizer(args);
        }

        public Command parseCommand() {
            try {
                String operation = mTokenizer.nextArg();
                if (ARGUMENT_INSERT.equals(operation)) {
                    return parseInsertCommand();
                } else if (ARGUMENT_DELETE.equals(operation)) {
                    return parseDeleteCommand();
                } else if (ARGUMENT_UPDATE.equals(operation)) {
                    return parseUpdateCommand();
                } else if (ARGUMENT_QUERY.equals(operation)) {
                    return parseQueryCommand();
                } else if (ARGUMENT_CALL.equals(operation)) {
                    return parseCallCommand();
                } else if (ARGUMENT_READ.equals(operation)) {
                    return parseReadCommand();
                } else if (ARGUMENT_WRITE.equals(operation)) {
                    return parseWriteCommand();
                } else if (ARGUMENT_GET_TYPE.equals(operation)) {
                    return parseGetTypeCommand();
                } else {
                    throw new IllegalArgumentException("Unsupported operation: " + operation);
                }
            } catch (IllegalArgumentException iae) {
                System.out.println(USAGE);
                System.out.println("[ERROR] " + iae.getMessage());
                return null;
            }
        }

        private InsertCommand parseInsertCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_SYSTEM;
            ContentValues values = new ContentValues();
            Bundle extras = new Bundle();
            for (String argument; (argument = mTokenizer.nextArg()) != null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else if (ARGUMENT_BIND.equals(argument)) {
                    parseBindValue(values);
                } else if (ARGUMENT_EXTRA.equals(argument)) {
                    parseBindValue(extras);
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            if (values.size() == 0) {
                throw new IllegalArgumentException("Bindings not specified."
                        + " Did you specify --bind argument(s)?");
            }
            return new InsertCommand(uri, userId, values, extras);
        }

        private DeleteCommand parseDeleteCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_SYSTEM;
            Bundle extras = new Bundle();
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else if (ARGUMENT_WHERE.equals(argument)) {
                    extras.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
                            argumentValueRequired(argument));
                } else if (ARGUMENT_EXTRA.equals(argument)) {
                    parseBindValue(extras);
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            return new DeleteCommand(uri, userId, extras);
        }

        private UpdateCommand parseUpdateCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_SYSTEM;
            ContentValues values = new ContentValues();
            Bundle extras = new Bundle();
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else if (ARGUMENT_WHERE.equals(argument)) {
                    extras.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
                            argumentValueRequired(argument));
                } else if (ARGUMENT_BIND.equals(argument)) {
                    parseBindValue(values);
                } else if (ARGUMENT_EXTRA.equals(argument)) {
                    parseBindValue(extras);
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            if (values.size() == 0) {
                throw new IllegalArgumentException("Bindings not specified."
                        + " Did you specify --bind argument(s)?");
            }
            return new UpdateCommand(uri, userId, values, extras);
        }

        public CallCommand parseCallCommand() {
            String method = null;
            int userId = UserHandle.USER_SYSTEM;
            String arg = null;
            Uri uri = null;
            Bundle extras = new Bundle();
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else if (ARGUMENT_METHOD.equals(argument)) {
                    method = argumentValueRequired(argument);
                } else if (ARGUMENT_ARG.equals(argument)) {
                    arg = argumentValueRequired(argument);
                } else if (ARGUMENT_EXTRA.equals(argument)) {
                    parseBindValue(extras);
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            if (method == null) {
                throw new IllegalArgumentException("Content provider method not specified.");
            }
            return new CallCommand(uri, userId, method, arg, extras);
        }

        private GetTypeCommand parseGetTypeCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_SYSTEM;

            for (String argument; (argument = mTokenizer.nextArg()) != null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            return new GetTypeCommand(uri, userId);
        }

        private ReadCommand parseReadCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_SYSTEM;
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            return new ReadCommand(uri, userId);
        }

        private WriteCommand parseWriteCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_SYSTEM;
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            return new WriteCommand(uri, userId);
        }

        public QueryCommand parseQueryCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_SYSTEM;
            String[] projection = null;
            Bundle extras = new Bundle();
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else if (ARGUMENT_WHERE.equals(argument)) {
                    extras.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
                            argumentValueRequired(argument));
                } else if (ARGUMENT_SORT.equals(argument)) {
                    extras.putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER,
                            argumentValueRequired(argument));
                } else if (ARGUMENT_PROJECTION.equals(argument)) {
                    projection = argumentValueRequired(argument).split("[\\s]*:[\\s]*");
                } else if (ARGUMENT_EXTRA.equals(argument)) {
                    parseBindValue(extras);
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            return new QueryCommand(uri, userId, projection, extras);
        }

        private List<String> splitWithEscaping(String argument, char splitChar) {
            final List<String> res = new ArrayList<>();
            final StringBuilder cur = new StringBuilder();
            for (int i = 0; i < argument.length(); i++) {
                char c = argument.charAt(i);
                if (c == '\\') {
                    if (++i == argument.length()) {
                        throw new IllegalArgumentException("Invalid escaping");
                    } else {
                        // Skip escaping char and insert next
                        c = argument.charAt(i);
                        cur.append(c);
                    }
                } else if (c == splitChar) {
                    // Splitting char means next string
                    res.add(cur.toString());
                    cur.setLength(0);
                } else {
                    // Copy non-escaping and non-splitting char
                    cur.append(c);
                }
            }
            res.add(cur.toString());
            return res;
        }

        private Pair<String, Object> parseBindValue() {
            String argument = mTokenizer.nextArg();
            if (TextUtils.isEmpty(argument)) {
                throw new IllegalArgumentException("Binding not well formed: " + argument);
            }
            final List<String> split = splitWithEscaping(argument, COLON.charAt(0));
            if (split.size() != 3) {
                throw new IllegalArgumentException("Binding not well formed: " + argument);
            }
            String column = split.get(0);
            String type = split.get(1);
            String value = split.get(2);
            if (TYPE_STRING.equals(type)) {
                return Pair.create(column, value);
            } else if (TYPE_BOOLEAN.equalsIgnoreCase(type)) {
                return Pair.create(column, Boolean.parseBoolean(value));
            } else if (TYPE_INTEGER.equalsIgnoreCase(type)) {
                return Pair.create(column, Integer.parseInt(value));
            } else if (TYPE_LONG.equalsIgnoreCase(type)) {
                return Pair.create(column, Long.parseLong(value));
            } else if (TYPE_FLOAT.equalsIgnoreCase(type)) {
                return Pair.create(column, Float.parseFloat(value));
            } else if (TYPE_DOUBLE.equalsIgnoreCase(type)) {
                return Pair.create(column, Double.parseDouble(value));
            } else if (TYPE_NULL.equalsIgnoreCase(type)) {
                return Pair.create(column, null);
            } else {
                throw new IllegalArgumentException("Unsupported type: " + type);
            }
        }

        private void parseBindValue(ContentValues values) {
            final Pair<String, Object> columnValue = parseBindValue();
            values.putObject(columnValue.first, columnValue.second);
        }

        private void parseBindValue(Bundle extras) {
            final Pair<String, Object> columnValue = parseBindValue();
            extras.putObject(columnValue.first, columnValue.second);
        }

        private String argumentValueRequired(String argument) {
            String value = mTokenizer.nextArg();
            if (TextUtils.isEmpty(value) || value.startsWith(ARGUMENT_PREFIX)) {
                throw new IllegalArgumentException("No value for argument: " + argument);
            }
            return value;
        }
    }

    private static class Tokenizer {
        private final String[] mArgs;
        private int mNextArg;

        public Tokenizer(String[] args) {
            mArgs = args;
        }

        private String nextArg() {
            if (mNextArg < mArgs.length) {
                return mArgs[mNextArg++];
            } else {
                return null;
            }
        }
    }

    private static abstract class Command {
        final Uri mUri;
        final int mUserId;

        public Command(Uri uri, int userId) {
            mUri = uri;
            mUserId = userId;
        }

        public final void execute() {
            String providerName = mUri.getAuthority();
            try {
                IActivityManager activityManager = ActivityManager.getService();
                IContentProvider provider = null;
                IBinder token = new Binder();
                try {
                    ContentProviderHolder holder = activityManager.getContentProviderExternal(
                            providerName, mUserId, token, "*cmd*");
                    if (holder == null) {
                        throw new IllegalStateException("Could not find provider: " + providerName);
                    }
                    provider = holder.provider;
                    onExecute(provider);
                } finally {
                    if (provider != null) {
                        activityManager.removeContentProviderExternalAsUser(
                                providerName, token, mUserId);
                    }
                }
            } catch (Exception e) {
                System.err.println("Error while accessing provider:" + providerName);
                e.printStackTrace();
            }
        }

        public static String resolveCallingPackage() {
            switch (Process.myUid()) {
                case Process.ROOT_UID: {
                    return "root";
                }

                case Process.SHELL_UID: {
                    return "com.android.shell";
                }

                default: {
                    return null;
                }
            }
        }

        protected abstract void onExecute(IContentProvider provider) throws Exception;
    }

    private static class InsertCommand extends Command {
        final ContentValues mContentValues;
        final Bundle mExtras;

        public InsertCommand(Uri uri, int userId, ContentValues contentValues, Bundle extras) {
            super(uri, userId);
            mContentValues = contentValues;
            mExtras = extras;
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            provider.insert(resolveCallingPackage(), null, mUri, mContentValues, mExtras);
        }
    }

    private static class DeleteCommand extends Command {
        final Bundle mExtras;

        public DeleteCommand(Uri uri, int userId, Bundle extras) {
            super(uri, userId);
            mExtras = extras;
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            provider.delete(resolveCallingPackage(), null, mUri, mExtras);
        }
    }

    private static class CallCommand extends Command {
        final String mMethod, mArg;
        final Bundle mExtras;

        public CallCommand(Uri uri, int userId, String method, String arg, Bundle extras) {
            super(uri, userId);
            mMethod = method;
            mArg = arg;
            mExtras = extras;
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            Bundle result = provider.call(null, null, mUri.getAuthority(), mMethod, mArg, mExtras);
            if (result != null) {
                result.size(); // unpack
            }
            System.out.println("Result: " + result);
        }
    }

    private static class GetTypeCommand extends Command {
        public GetTypeCommand(Uri uri, int userId) {
            super(uri, userId);
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            String type = provider.getType(mUri);
            System.out.println("Result: " + type);
        }
    }

    private static class ReadCommand extends Command {
        public ReadCommand(Uri uri, int userId) {
            super(uri, userId);
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            try (ParcelFileDescriptor fd = provider.openFile(null, null, mUri, "r", null, null)) {
                FileUtils.copy(fd.getFileDescriptor(), FileDescriptor.out);
            }
        }
    }

    private static class WriteCommand extends Command {
        public WriteCommand(Uri uri, int userId) {
            super(uri, userId);
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            try (ParcelFileDescriptor fd = provider.openFile(null, null, mUri, "w", null, null)) {
                FileUtils.copy(FileDescriptor.in, fd.getFileDescriptor());
            }
        }
    }

    private static class QueryCommand extends Command {
        final String[] mProjection;
        final Bundle mExtras;

        public QueryCommand(Uri uri, int userId, String[] projection, Bundle extras) {
            super(uri, userId);
            mProjection = projection;
            mExtras = extras;
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            Cursor cursor = provider.query(resolveCallingPackage(), null, mUri, mProjection,
                    mExtras, null);
            if (cursor == null) {
                System.out.println("No result found.");
                return;
            }
            try {
                if (cursor.moveToFirst()) {
                    int rowIndex = 0;
                    StringBuilder builder = new StringBuilder();
                    do {
                        builder.setLength(0);
                        builder.append("Row: ").append(rowIndex).append(" ");
                        rowIndex++;
                        final int columnCount = cursor.getColumnCount();
                        for (int i = 0; i < columnCount; i++) {
                            if (i > 0) {
                                builder.append(", ");
                            }
                            String columnName = cursor.getColumnName(i);
                            String columnValue = null;
                            final int columnIndex = cursor.getColumnIndex(columnName);
                            final int type = cursor.getType(columnIndex);
                            switch (type) {
                                case Cursor.FIELD_TYPE_FLOAT:
                                    columnValue = String.valueOf(cursor.getFloat(columnIndex));
                                    break;
                                case Cursor.FIELD_TYPE_INTEGER:
                                    columnValue = String.valueOf(cursor.getLong(columnIndex));
                                    break;
                                case Cursor.FIELD_TYPE_STRING:
                                    columnValue = cursor.getString(columnIndex);
                                    break;
                                case Cursor.FIELD_TYPE_BLOB:
                                    columnValue = "BLOB";
                                    break;
                                case Cursor.FIELD_TYPE_NULL:
                                    columnValue = "NULL";
                                    break;
                            }
                            builder.append(columnName).append("=").append(columnValue);
                        }
                        System.out.println(builder);
                    } while (cursor.moveToNext());
                } else {
                    System.out.println("No result found.");
                }
            } finally {
                cursor.close();
            }
        }
    }

    private static class UpdateCommand extends Command {
        final ContentValues mValues;
        final Bundle mExtras;

        public UpdateCommand(Uri uri, int userId, ContentValues values, Bundle extras) {
            super(uri, userId);
            mValues = values;
            mExtras = extras;
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            provider.update(resolveCallingPackage(), null, mUri, mValues, mExtras);
        }
    }

    public static void main(String[] args) {
        Parser parser = new Parser(args);
        Command command = parser.parseCommand();
        if (command != null) {
            command.execute();
        }
    }
}
