Complete the avatar provider to support insert update and delete.
authorDa Risk <da_risk@beem-project.com>
Thu, 26 Jan 2012 23:54:46 +0100
changeset 985 24474027eb45
parent 984 f27ce0166608
child 986 89dbb4bee206
Complete the avatar provider to support insert update and delete. It is now usable following the standard Android interface.
src/com/beem/project/beem/providers/AvatarProvider.java
src/com/beem/project/beem/service/BeemAvatarCache.java
--- a/src/com/beem/project/beem/providers/AvatarProvider.java	Tue Feb 21 21:07:42 2012 +0100
+++ b/src/com/beem/project/beem/providers/AvatarProvider.java	Thu Jan 26 23:54:46 2012 +0100
@@ -43,6 +43,10 @@
 */
 package com.beem.project.beem.providers;
 
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
 import android.content.ContentProvider;
 import android.content.ContentValues;
 import android.content.UriMatcher;
@@ -53,8 +57,6 @@
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
-import java.io.File;
-import java.io.FileNotFoundException;
 
 /**
  * A simple content provider we expose the differents avatar downloaded.
@@ -66,19 +68,17 @@
     public static final Uri CONTENT_URI =
 	Uri.parse("content://com.beem.project.beem.providers.avatarprovider");
 
+    /** The MIME type of a CONTENT_URI directory of Beem avatars.  */
+    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.beem.project.beem.avatar";
+
+    /** The MIME type of a CONTENT_URI subdirectory of a single Beem avatar.  */
+    public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.beem.project.beem.avatar";
+
+
     private static final String TAG = AvatarProvider.class.getSimpleName();
     private static final String AUTHORITY = "com.beem.project.beem.providers.avatarprovider";
 
-    /**
-     * The differents columns available in the AvatarProvider.
-     */
-    public static interface Columns {
-
-	/** The id of the avatar. */
-	String ID = "_id";
-    }
-
-    private static String[] columnNames = new String[] {Columns.ID };
+    private static String[] columnNames = new String[] {Columns.ID, Columns.DATA};
 
     private static final int AVATAR = 1;
     private static final int AVATAR_ID = 2;
@@ -99,40 +99,6 @@
     public AvatarProvider() {
     }
 
-    /**
-     * Translate the mode passed to {@link #openFile} into mode passed to {@link ParcelFileDescriptor#open}.
-     *
-     * @param uri the uri to open
-     * @param mode the mode
-     * @return the mode
-     * @throws FileNotFoundException if the mode passed is illegal
-     */
-    public static int modeToMode(Uri uri, String mode) throws FileNotFoundException {
-	int modeBits;
-	if ("r".equals(mode)) {
-	    modeBits = ParcelFileDescriptor.MODE_READ_ONLY;
-	} else if ("w".equals(mode) || "wt".equals(mode)) {
-	    modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY
-		| ParcelFileDescriptor.MODE_CREATE
-		| ParcelFileDescriptor.MODE_TRUNCATE;
-	} else if ("wa".equals(mode)) {
-	    modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY
-		| ParcelFileDescriptor.MODE_CREATE
-		| ParcelFileDescriptor.MODE_APPEND;
-	} else if ("rw".equals(mode)) {
-	    modeBits = ParcelFileDescriptor.MODE_READ_WRITE
-		| ParcelFileDescriptor.MODE_CREATE;
-	} else if ("rwt".equals(mode)) {
-	    modeBits = ParcelFileDescriptor.MODE_READ_WRITE
-		| ParcelFileDescriptor.MODE_CREATE
-		| ParcelFileDescriptor.MODE_TRUNCATE;
-	} else {
-	    throw new FileNotFoundException("Bad mode for " + uri + ": "
-		    + mode);
-	}
-	return modeBits;
-    }
-
     @Override
     public boolean onCreate() {
 	File cacheDir = Environment.getExternalStorageDirectory();
@@ -145,10 +111,7 @@
     @Override
     public ParcelFileDescriptor openFile(Uri uri, String mode)
 	throws FileNotFoundException {
-	String id = uri.getPath();
-	File data = new File(mDataPath, id);
-	int modeBits = AvatarProvider.modeToMode(uri, mode);
-	return ParcelFileDescriptor.open(data, modeBits);
+    	return openFileHelper(uri, mode);
     }
 
     @Override
@@ -160,7 +123,7 @@
 		File[] files = new File(mDataPath).listFiles();
 		if (files != null) {
 		    for (File f : files) {
-			c.newRow().add(f.getName());
+			c.newRow().add(f.getName()).add(f.getAbsolutePath());
 		    }
 		}
 		break;
@@ -168,37 +131,135 @@
 		String id = uri.getPathSegments().get(0);
 		File f = new File(mDataPath, id);
 		if (f.exists())
-			c.newRow().add(f.getName());
+			c.newRow().add(f.getName()).add(f.getAbsolutePath());
 		break;
 	    default:
 		Log.w(TAG, "Unsupported uri for query match = " + match);
 	}
+	if (c != null)
+		c.setNotificationUri(getContext().getContentResolver(), uri);
 	return c;
     }
 
     @Override
     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+	int match = URIMATCHER.match(uri);
+	String id = null;
+	switch (match) {
+	    case AVATAR_ID:
+		id = uri.getPathSegments().get(0);
+		break;
+	    default:
+		Log.w(TAG, "Unsupported uri for query match = " + match);
+	}
+
+	if (id == null)
+	    return 0;
+
+	File f = new File(mDataPath, id);
+	try {
+	    f.createNewFile();
+	    getContext().getContentResolver().notifyChange(uri, null);
+	    return 1;
+	} catch (IOException e) {
+	    Log.e(TAG, "Error while creating file", e);
+	}
 	return 0;
     }
 
     @Override
     public int delete(Uri uri, String selection, String[] selectionArgs) {
 	int res = 0;
-	String id = uri.getPath();
-	File data = new File(mDataPath, id);
-	if (data.exists() && data.delete()) {
-	    res++;
+	boolean all = false;
+	String id = null;
+	int match = URIMATCHER.match(uri);
+	switch (match) {
+	    case AVATAR_ID:
+		id = uri.getPathSegments().get(0);
+		break;
+	    case AVATAR:
+		all = true;
+		break;
+	    default:
+		Log.w(TAG, "Unsupported uri for query match = " + match);
 	}
+	File[] list = null;
+	if (id != null) {
+	    list = new File[] {new File(mDataPath, id) };
+	} else if (all) {
+	    list = new File(mDataPath).listFiles();
+	}
+
+	if (list == null)
+	    return res;
+	for (File data : list) {
+	    if (data.exists() && data.delete())
+		res++;
+	}
+	if (res > 0)
+	    getContext().getContentResolver().notifyChange(uri, null);
 	return res;
     }
 
     @Override
     public Uri insert(Uri uri, ContentValues values) {
+	int match = URIMATCHER.match(uri);
+	String id = null;
+	Uri result = null;
+	switch (match) {
+	    case AVATAR:
+		id = values.getAsString(Columns.ID);
+		result = Uri.withAppendedPath(uri, id);
+		break;
+	    case AVATAR_ID:
+		id = uri.getPathSegments().get(0);
+		result = uri;
+		break;
+	    default:
+		Log.w(TAG, "Unsupported uri for query match = " + match);
+	}
+	if (id == null)
+	    return null;
+
+	File f = new File(mDataPath, id);
+	try {
+	    f.createNewFile();
+	    if (result != null)
+		getContext().getContentResolver().notifyChange(result, null);
+	    return result;
+	} catch (IOException e) {
+	    Log.e(TAG, "Error while creating file", e);
+	}
 	return null;
     }
 
     @Override
     public String getType(Uri uri) {
+    	int match = URIMATCHER.match(uri);
+    	switch (match) {
+    	    case AVATAR:
+    		return CONTENT_TYPE;
+    	    case AVATAR_ID:
+    		return CONTENT_ITEM_TYPE;
+    	    default:
+    		Log.w(TAG, "Unsupported uri for query match = " + match);
+    	}
 	return null;
     }
+
+    /**
+     * The differents columns available in the AvatarProvider.
+     */
+    public interface Columns {
+
+	/** The id of the avatar.
+	 * type: string */
+	String ID = "_id";
+
+	/** The path of the avatar file.
+	 * type: string
+	 * This field is readonly */
+	String DATA = "_data";
+    }
+
 }
--- a/src/com/beem/project/beem/service/BeemAvatarCache.java	Tue Feb 21 21:07:42 2012 +0100
+++ b/src/com/beem/project/beem/service/BeemAvatarCache.java	Thu Jan 26 23:54:46 2012 +0100
@@ -43,6 +43,13 @@
 */
 package com.beem.project.beem.service;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
 import android.content.ContentResolver;
 import android.content.Context;
 
@@ -53,12 +60,6 @@
 import com.beem.project.beem.providers.AvatarProvider;
 import com.beem.project.beem.smack.avatar.AvatarCache;
 
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.OutputStream;
 
 /**
  * An implementation of an AvatarCache which store the data of the filesystem.
@@ -84,6 +85,7 @@
     @Override
     public void put(String key, byte[] data) throws IOException {
 	Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(key).build();
+	mContentResolver.insert(uri, null);
 	OutputStream os = new BufferedOutputStream(mContentResolver.openOutputStream(uri));
 	try {
 	    os.write(data);
@@ -95,6 +97,7 @@
     @Override
     public void put(String key, InputStream in) throws IOException {
 	Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(key).build();
+	mContentResolver.insert(uri, null);
 	OutputStream os = new BufferedOutputStream(mContentResolver.openOutputStream(uri));
 	try {
 	    byte[] data = new byte[1024];