package org.sana.android.db;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import org.sana.android.db.SanaDB.SoundSQLFormat;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.text.TextUtils;
import android.util.Log;
/**
* Content provider for audio content.
*
* @author Sana Development Team
*
*/
public class SoundProvider extends ContentProvider {
private static final String TAG = "SoundProvider";
private static final String SOUND_TABLE_NAME = "sounds";
public static final String SOUND_BUCKET_NAME = "/sdcard/dcim/sana/";
private static final int SOUNDS = 1;
private static final int SOUND_ID = 2;
private DatabaseHelper mOpenHelper;
private static final UriMatcher sUriMatcher;
private static HashMap<String,String> sSoundProjectionMap;
/** {@inheritDoc} */
@Override
public boolean onCreate() {
Log.i(TAG, "onCreate()");
mOpenHelper = new DatabaseHelper(getContext());
return true;
}
private String buildFilenameFromId(String soundId) {
return "/data/data/org.sana/files/sound_" + soundId;
}
private String buildFilenameFromUri(Uri uri) {
return buildFilenameFromId(uri.getPathSegments().get(1));
}
private boolean deleteFile(String soundId) {
String filename = buildFilenameFromId(soundId);
File f = new File(filename);
boolean result = f.delete();
Log.i(TAG, "Deleting file for id " + soundId + " : " + filename + " "
+ (result ? "succeeded" : "failed"));
return result;
}
private boolean deleteFile(Uri uri) {
String filename = buildFilenameFromUri(uri);
File f = new File(filename);
boolean result = f.delete();
Log.i(TAG, "Deleting file for " + uri + " : " + filename + " "
+ (result ? "succeeded" : "failed"));
return result;
}
/** {@inheritDoc} */
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws
FileNotFoundException
{
//String filename = SOUND_BUCKET_NAME + uri.getFragment();
String filename = buildFilenameFromUri(uri);
//String filename = "/data/data/org.sana/files/" + uri.getPathSegments().get(1);
Log.i(TAG, "openFile() for filename: " + filename);
File f = new File(filename);
int m = ParcelFileDescriptor.MODE_READ_ONLY;
if ("w".equals(mode)) {
m = ParcelFileDescriptor.MODE_WRITE_ONLY
| ParcelFileDescriptor.MODE_CREATE;
} else if("rw".equals(mode) || "rwt".equals(mode)) {
m = ParcelFileDescriptor.MODE_READ_WRITE;
}
return ParcelFileDescriptor.open(f,m);
}
/** {@inheritDoc} */
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
{
Log.i(TAG, "query() uri="+uri.toString() + " projection="
+ TextUtils.join(",",projection));
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(SOUND_TABLE_NAME);
switch(sUriMatcher.match(uri)) {
case SOUNDS:
break;
case SOUND_ID:
qb.appendWhere(SoundSQLFormat._ID + "="
+ uri.getPathSegments().get(1));
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
String orderBy;
if(TextUtils.isEmpty(sortOrder)) {
orderBy = SoundSQLFormat.DEFAULT_SORT_ORDER;
} else {
orderBy = sortOrder;
}
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs, null,
null, orderBy);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
/** {@inheritDoc} */
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count = 0;
switch(sUriMatcher.match(uri)) {
case SOUNDS:
count = db.update(SOUND_TABLE_NAME, values,selection,selectionArgs);
break;
case SOUND_ID:
String procedureId = uri.getPathSegments().get(1);
count = db.update(SOUND_TABLE_NAME, values, SoundSQLFormat._ID + "="
+ procedureId + (!TextUtils.isEmpty(selection)
? " AND (" + selection + ")" : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
/** {@inheritDoc} */
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri)) {
case SOUNDS:
//count = db.delete(SOUND_TABLE_NAME, selection, selectionArgs);
LinkedList<String> idList = new LinkedList<String>();
Cursor c = query(SoundSQLFormat.CONTENT_URI, new String[] {
SoundSQLFormat._ID }, selection, selectionArgs, null);
if(c.moveToFirst()) {
while(!c.isAfterLast()) {
String id = c.getString(c.getColumnIndex(SoundSQLFormat._ID));
idList.add(id);
c.moveToNext();
}
}
c.deactivate();
count = db.delete(SOUND_TABLE_NAME, selection, selectionArgs);
for(String id : idList) {
deleteFile(id);
}
break;
case SOUND_ID:
String soundId = uri.getPathSegments().get(1);
count = db.delete(SOUND_TABLE_NAME, SoundSQLFormat._ID + "="
+ soundId + (!TextUtils.isEmpty(selection) ? " AND ("
+ selection + ")" : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
/** {@inheritDoc} */
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
if (sUriMatcher.match(uri) != SOUNDS) {
throw new IllegalArgumentException("Unknown URI " + uri);
}
ContentValues values;
if(initialValues != null) {
values = new ContentValues(initialValues);
} else {
values = new ContentValues();
}
Long now = Long.valueOf(System.currentTimeMillis());
if(values.containsKey(SoundSQLFormat.CREATED_DATE) == false) {
values.put(SoundSQLFormat.CREATED_DATE, now);
}
if(values.containsKey(SoundSQLFormat.MODIFIED_DATE) == false) {
values.put(SoundSQLFormat.MODIFIED_DATE, now);
}
if(values.containsKey(SoundSQLFormat.ENCOUNTER_ID) == false) {
values.put(SoundSQLFormat.ENCOUNTER_ID, "");
}
if(values.containsKey(SoundSQLFormat.FILE_URI) == false) {
values.put(SoundSQLFormat.FILE_URI, "");
}
// if(values.containsKey(SoundSQLFormat.FILE_VALID) == false) {
// values.put(SoundSQLFormat.FILE_VALID, false);
// }
//
// if(values.containsKey(SoundSQLFormat.FILE_SIZE) == false) {
// values.put(SoundSQLFormat.FILE_SIZE, 0);
// }
if(values.containsKey(SoundSQLFormat.UPLOAD_PROGRESS) == false) {
values.put(SoundSQLFormat.UPLOAD_PROGRESS, 0);
}
if(values.containsKey(SoundSQLFormat.UPLOADED) == false) {
values.put(SoundSQLFormat.UPLOADED, false);
}
if(values.containsKey(SoundSQLFormat.ELEMENT_ID) == false) {
values.put(SoundSQLFormat.ELEMENT_ID, "");
}
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
long rowId = db.insert(SOUND_TABLE_NAME,
SoundSQLFormat.ENCOUNTER_ID, values);
if(rowId > 0) {
String filename = rowId + "";
try {
getContext().openFileOutput(filename,
Context.MODE_PRIVATE).close();
} catch (FileNotFoundException e) {
Log.e(TAG, "Couldn't make the file: " + e);
} catch (IOException e) {
Log.e(TAG, "Couldn't make the file: " + e);
}
String path =
getContext().getFileStreamPath(filename).getAbsolutePath();
Log.i(TAG, "File path is : " + path);
Uri noteUri = ContentUris.withAppendedId(SoundSQLFormat.CONTENT_URI,
rowId);
getContext().getContentResolver().notifyChange(noteUri, null);
return noteUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
/** {@inheritDoc} */
@Override
public String getType(Uri uri) {
Log.i(TAG, "getType(uri="+uri.toString()+")");
switch(sUriMatcher.match(uri)) {
case SOUNDS:
return SoundSQLFormat.CONTENT_TYPE;
case SOUND_ID:
return SoundSQLFormat.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
/**
* Creates the table.
* @param db the database to create the table in.
*/
public static void onCreateDatabase(SQLiteDatabase db) {
Log.i(TAG, "Creating Sound Table");
db.execSQL("CREATE TABLE " + SOUND_TABLE_NAME + " ("
+ SoundSQLFormat._ID + " INTEGER PRIMARY KEY,"
+ SoundSQLFormat.ENCOUNTER_ID + " TEXT,"
+ SoundSQLFormat.ELEMENT_ID + " TEXT,"
+ SoundSQLFormat.FILE_URI + " TEXT,"
// + SoundSQLFormat.FILE_VALID + " INTEGER,"
// + SoundSQLFormat.FILE_SIZE + " INTEGER,"
+ SoundSQLFormat.UPLOAD_PROGRESS + " INTEGER,"
+ SoundSQLFormat.UPLOADED + " INTEGER,"
+ SoundSQLFormat.CREATED_DATE + " INTEGER,"
+ SoundSQLFormat.MODIFIED_DATE + " INTEGER"
+ ");");
}
/**
* Updates this providers table
* @param db the db to update in
* @param oldVersion the current db version
* @param newVersion the new db version
*/
public static void onUpgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion);
if (oldVersion == 1 && newVersion == 2) {
// Do nothing
}
}
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(SanaDB.SOUND_AUTHORITY, "sounds", SOUNDS);
sUriMatcher.addURI(SanaDB.SOUND_AUTHORITY, "sounds/#", SOUND_ID);
sSoundProjectionMap = new HashMap<String, String>();
sSoundProjectionMap.put(SoundSQLFormat._ID, SoundSQLFormat._ID);
sSoundProjectionMap.put(SoundSQLFormat.ELEMENT_ID, SoundSQLFormat.ELEMENT_ID);
sSoundProjectionMap.put(SoundSQLFormat.ENCOUNTER_ID, SoundSQLFormat.ENCOUNTER_ID);
sSoundProjectionMap.put(SoundSQLFormat.FILE_URI, SoundSQLFormat.FILE_URI);
// sSoundProjectionMap.put(SoundSQLFormat.FILE_VALID, SoundSQLFormat.FILE_VALID);
// sSoundProjectionMap.put(SoundSQLFormat.FILE_SIZE, SoundSQLFormat.FILE_SIZE);
sSoundProjectionMap.put(SoundSQLFormat.UPLOADED, SoundSQLFormat.UPLOADED);
sSoundProjectionMap.put(SoundSQLFormat.UPLOAD_PROGRESS, SoundSQLFormat.UPLOAD_PROGRESS);
sSoundProjectionMap.put(SoundSQLFormat.CREATED_DATE, SoundSQLFormat.CREATED_DATE);
sSoundProjectionMap.put(SoundSQLFormat.MODIFIED_DATE, SoundSQLFormat.MODIFIED_DATE);
}
}