package com.smartandroid.sa.sql.content;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.util.SparseArray;
import com.smartandroid.sa.sql.ActiveAndroid;
import com.smartandroid.sa.sql.Cache;
import com.smartandroid.sa.sql.Configuration;
import com.smartandroid.sa.sql.Model;
import com.smartandroid.sa.sql.TableInfo;
public class ContentProvider extends android.content.ContentProvider {
// ////////////////////////////////////////////////////////////////////////////////////
// PRIVATE CONSTANTS
// ////////////////////////////////////////////////////////////////////////////////////
private static final UriMatcher URI_MATCHER = new UriMatcher(
UriMatcher.NO_MATCH);
private static final SparseArray<Class<? extends Model>> TYPE_CODES = new SparseArray<Class<? extends Model>>();
// ////////////////////////////////////////////////////////////////////////////////////
// PRIVATE MEMBERS
// ////////////////////////////////////////////////////////////////////////////////////
private static String sAuthority;
private static SparseArray<String> sMimeTypeCache = new SparseArray<String>();
// ////////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
// ////////////////////////////////////////////////////////////////////////////////////
@Override
public boolean onCreate() {
ActiveAndroid.initialize(getConfiguration());
sAuthority = getAuthority();
final List<TableInfo> tableInfos = new ArrayList<TableInfo>(
Cache.getTableInfos());
final int size = tableInfos.size();
for (int i = 0; i < size; i++) {
final TableInfo tableInfo = tableInfos.get(i);
final int tableKey = (i * 2) + 1;
final int itemKey = (i * 2) + 2;
// content://<authority>/<table>
URI_MATCHER.addURI(sAuthority, tableInfo.getTableName()
.toLowerCase(), tableKey);
TYPE_CODES.put(tableKey, tableInfo.getType());
// content://<authority>/<table>/<id>
URI_MATCHER.addURI(sAuthority, tableInfo.getTableName()
.toLowerCase() + "/#", itemKey);
TYPE_CODES.put(itemKey, tableInfo.getType());
}
return true;
}
@Override
public String getType(Uri uri) {
final int match = URI_MATCHER.match(uri);
String cachedMimeType = sMimeTypeCache.get(match);
if (cachedMimeType != null) {
return cachedMimeType;
}
final Class<? extends Model> type = getModelType(uri);
final boolean single = ((match % 2) == 0);
StringBuilder mimeType = new StringBuilder();
mimeType.append("vnd");
mimeType.append(".");
mimeType.append(sAuthority);
mimeType.append(".");
mimeType.append(single ? "item" : "dir");
mimeType.append("/");
mimeType.append("vnd");
mimeType.append(".");
mimeType.append(sAuthority);
mimeType.append(".");
mimeType.append(Cache.getTableName(type));
sMimeTypeCache.append(match, mimeType.toString());
return mimeType.toString();
}
// SQLite methods
@Override
public Uri insert(Uri uri, ContentValues values) {
final Class<? extends Model> type = getModelType(uri);
final Long id = Cache.openDatabase().insert(Cache.getTableName(type),
null, values);
if (id != null && id > 0) {
Uri retUri = createUri(type, id);
notifyChange(retUri);
return retUri;
}
return null;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
final Class<? extends Model> type = getModelType(uri);
final int count = Cache.openDatabase().update(Cache.getTableName(type),
values, selection, selectionArgs);
notifyChange(uri);
return count;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
final Class<? extends Model> type = getModelType(uri);
final int count = Cache.openDatabase().delete(Cache.getTableName(type),
selection, selectionArgs);
notifyChange(uri);
return count;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
final Class<? extends Model> type = getModelType(uri);
final Cursor cursor = Cache.openDatabase().query(
Cache.getTableName(type), projection, selection, selectionArgs,
null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
// ////////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
// ////////////////////////////////////////////////////////////////////////////////////
public static Uri createUri(Class<? extends Model> type, Long id) {
final StringBuilder uri = new StringBuilder();
uri.append("content://");
uri.append(sAuthority);
uri.append("/");
uri.append(Cache.getTableName(type).toLowerCase());
if (id != null) {
uri.append("/");
uri.append(id.toString());
}
return Uri.parse(uri.toString());
}
// ////////////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
// ////////////////////////////////////////////////////////////////////////////////////
protected String getAuthority() {
return getContext().getPackageName();
}
protected Configuration getConfiguration() {
return new Configuration.Builder(getContext()).create();
}
// ////////////////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
// ////////////////////////////////////////////////////////////////////////////////////
private Class<? extends Model> getModelType(Uri uri) {
final int code = URI_MATCHER.match(uri);
if (code != UriMatcher.NO_MATCH) {
return TYPE_CODES.get(code);
}
return null;
}
private void notifyChange(Uri uri) {
getContext().getContentResolver().notifyChange(uri, null);
}
}