package com.arconus.dicecommander.provider; import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.provider.BaseColumns; import android.util.Log; public class DCProvider extends ContentProvider { private static final String TAG = DCProvider.class.getSimpleName(); private static final String TYPE_CURSOR_ITEM = "vnd.android.cursor.item/"; private static final String TYPE_CURSOR_DIR = "vnd.android.cursor.dir/"; public static final String AUTHORITY = "com.arconus.dicecommander.provider"; public static final String CONTENT_URI_BASE = "content://" + AUTHORITY; public static final String QUERY_NOTIFY = "QUERY_NOTIFY"; public static final String QUERY_GROUP_BY = "QUERY_GROUP_BY"; private static final int URI_TYPE_CHARPOWER = 0; private static final int URI_TYPE_CHARPOWER_ID = 1; private static final int URI_TYPE_DICEFORMULA = 2; private static final int URI_TYPE_DICEFORMULA_ID = 3; private static final int URI_TYPE_GAMECHARACTER = 4; private static final int URI_TYPE_GAMECHARACTER_ID = 5; private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); static { URI_MATCHER.addURI(AUTHORITY, CharpowerColumns.TABLE_NAME, URI_TYPE_CHARPOWER); URI_MATCHER.addURI(AUTHORITY, CharpowerColumns.TABLE_NAME + "/#", URI_TYPE_CHARPOWER_ID); URI_MATCHER.addURI(AUTHORITY, DiceformulaColumns.TABLE_NAME, URI_TYPE_DICEFORMULA); URI_MATCHER.addURI(AUTHORITY, DiceformulaColumns.TABLE_NAME + "/#", URI_TYPE_DICEFORMULA_ID); URI_MATCHER.addURI(AUTHORITY, GamecharacterColumns.TABLE_NAME, URI_TYPE_GAMECHARACTER); URI_MATCHER.addURI(AUTHORITY, GamecharacterColumns.TABLE_NAME + "/#", URI_TYPE_GAMECHARACTER_ID); } private DCSQLiteOpenHelper mDCSQLiteOpenHelper; @Override public boolean onCreate() { mDCSQLiteOpenHelper = new DCSQLiteOpenHelper(getContext()); return true; } @Override public String getType(Uri uri) { final int match = URI_MATCHER.match(uri); switch (match) { case URI_TYPE_CHARPOWER: return TYPE_CURSOR_DIR + CharpowerColumns.TABLE_NAME; case URI_TYPE_CHARPOWER_ID: return TYPE_CURSOR_ITEM + CharpowerColumns.TABLE_NAME; case URI_TYPE_DICEFORMULA: return TYPE_CURSOR_DIR + DiceformulaColumns.TABLE_NAME; case URI_TYPE_DICEFORMULA_ID: return TYPE_CURSOR_ITEM + DiceformulaColumns.TABLE_NAME; case URI_TYPE_GAMECHARACTER: return TYPE_CURSOR_DIR + GamecharacterColumns.TABLE_NAME; case URI_TYPE_GAMECHARACTER_ID: return TYPE_CURSOR_ITEM + GamecharacterColumns.TABLE_NAME; } return null; } @Override public Uri insert(Uri uri, ContentValues values) { Log.d(TAG, "insert uri=" + uri + " values=" + values); final String table = uri.getLastPathSegment(); final long rowId = mDCSQLiteOpenHelper.getWritableDatabase().insert(table, null, values); String notify; if (rowId != -1 && ((notify = uri.getQueryParameter(QUERY_NOTIFY)) == null || "true".equals(notify))) { getContext().getContentResolver().notifyChange(uri, null); } return uri.buildUpon().appendEncodedPath(String.valueOf(rowId)).build(); } @Override public int bulkInsert(Uri uri, ContentValues[] values) { Log.d(TAG, "bulkInsert uri=" + uri + " values.length=" + values.length); final String table = uri.getLastPathSegment(); final SQLiteDatabase db = mDCSQLiteOpenHelper.getWritableDatabase(); int res = 0; db.beginTransaction(); try { for (final ContentValues v : values) { final long id = db.insert(table, null, v); if (id != -1) { res++; } } db.setTransactionSuccessful(); } finally { db.endTransaction(); } String notify; if (res != 0 && ((notify = uri.getQueryParameter(QUERY_NOTIFY)) == null || "true".equals(notify))) { getContext().getContentResolver().notifyChange(uri, null); } return res; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { Log.d(TAG, "update uri=" + uri + " values=" + values + " selection=" + selection); final QueryParams queryParams = getQueryParams(uri, selection, false); final int res = mDCSQLiteOpenHelper.getWritableDatabase().update(queryParams.table, values, queryParams.whereClause, selectionArgs); String notify; if (res != 0 && ((notify = uri.getQueryParameter(QUERY_NOTIFY)) == null || "true".equals(notify))) { getContext().getContentResolver().notifyChange(uri, null); } return res; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { Log.d(TAG, "delete uri=" + uri + " selection=" + selection); final QueryParams queryParams = getQueryParams(uri, selection, false); final int res = mDCSQLiteOpenHelper.getWritableDatabase().delete(queryParams.table, queryParams.whereClause, selectionArgs); String notify; if (res != 0 && ((notify = uri.getQueryParameter(QUERY_NOTIFY)) == null || "true".equals(notify))) { getContext().getContentResolver().notifyChange(uri, null); } return res; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { final String groupBy = uri.getQueryParameter(QUERY_GROUP_BY); Log.d(TAG, "query uri=" + uri + " selection=" + selection + " sortOrder=" + sortOrder + " groupBy=" + groupBy); final QueryParams queryParams = getQueryParams(uri, selection, true); final Cursor res = mDCSQLiteOpenHelper.getReadableDatabase().query(queryParams.tableWithJoins, projection, queryParams.whereClause, selectionArgs, groupBy, null, sortOrder == null ? queryParams.orderBy : sortOrder); res.setNotificationUri(getContext().getContentResolver(), uri); return res; } private static class QueryParams { public String table; public String tableWithJoins; public String whereClause; public String orderBy; } private QueryParams getQueryParams(Uri uri, String selection, boolean isQuery) { final QueryParams res = new QueryParams(); String id = null; final int matchedId = URI_MATCHER.match(uri); switch (matchedId) { case URI_TYPE_CHARPOWER: case URI_TYPE_CHARPOWER_ID: res.table = res.tableWithJoins = CharpowerColumns.TABLE_NAME; res.orderBy = CharpowerColumns.DEFAULT_ORDER; break; case URI_TYPE_DICEFORMULA: case URI_TYPE_DICEFORMULA_ID: res.table = res.tableWithJoins = DiceformulaColumns.TABLE_NAME; res.orderBy = DiceformulaColumns.DEFAULT_ORDER; break; case URI_TYPE_GAMECHARACTER: case URI_TYPE_GAMECHARACTER_ID: res.table = res.tableWithJoins = GamecharacterColumns.TABLE_NAME; res.orderBy = GamecharacterColumns.DEFAULT_ORDER; break; default: throw new IllegalArgumentException("The uri '" + uri + "' is not supported by this ContentProvider"); } switch (matchedId) { case URI_TYPE_CHARPOWER_ID: case URI_TYPE_DICEFORMULA_ID: case URI_TYPE_GAMECHARACTER_ID: id = uri.getLastPathSegment(); } if (id != null) { if (selection != null) { res.whereClause = BaseColumns._ID + "=" + id + " and (" + selection + ")"; } else { res.whereClause = BaseColumns._ID + "=" + id; } } else { res.whereClause = selection; } return res; } public static Uri notify(Uri uri, boolean notify) { return uri.buildUpon().appendQueryParameter(QUERY_NOTIFY, String.valueOf(notify)).build(); } public static Uri groupBy(Uri uri, String groupBy) { return uri.buildUpon().appendQueryParameter(QUERY_GROUP_BY, groupBy).build(); } }