// // Copyright 2011 Thomas Gumprecht, Robert Jacob, Thomas Pieronczyk // // 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 net.sourcewalker.garanbot.data; import java.io.File; import java.io.FileNotFoundException; import java.util.HashMap; import net.sourcewalker.garanbot.api.Item; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.os.ParcelFileDescriptor; import android.util.Log; /** * This content provider communicates with the local database, which stores the * garanbo items. * * @author pieronczyk */ public class GaranboItemsProvider extends ContentProvider { private static final Uri CONTENT_URI_BASE = Uri.parse("content://" + GaranbotDBMetaData.AUTHORITY); public static final Uri CONTENT_URI_ITEMS = Uri.withAppendedPath( CONTENT_URI_BASE, "items"); public static final Uri CONTENT_URI_ITEMS_ALL = Uri.withAppendedPath( CONTENT_URI_ITEMS, "all"); public static final Uri CONTENT_URI_IMAGES = Uri.withAppendedPath( CONTENT_URI_BASE, "images"); private static UriMatcher matcher; private GaranbotDBHelper dbHelper; private static final String TAG = "GaranbotProvider"; private static final HashMap<String, String> projectionMap; private static final int MATCH_LIST = 1; private static final int MATCH_LIST_ALL = 2; private static final int MATCH_ITEM = 3; private static final int MATCH_IMAGE = 4; static { matcher = new UriMatcher(UriMatcher.NO_MATCH); matcher.addURI(GaranbotDBMetaData.AUTHORITY, "items", MATCH_LIST); matcher.addURI(GaranbotDBMetaData.AUTHORITY, "items/all", MATCH_LIST_ALL); matcher.addURI(GaranbotDBMetaData.AUTHORITY, "items/#", MATCH_ITEM); matcher.addURI(GaranbotDBMetaData.AUTHORITY, "images/#", MATCH_IMAGE); projectionMap = new HashMap<String, String>(); for (String col : GaranbotDBMetaData.DEFAULT_PROJECTION) { projectionMap.put(col, col); } projectionMap.put(GaranbotDBMetaData.IMAGE_URI, "'" + CONTENT_URI_IMAGES + "/' || " + GaranbotDBMetaData._ID + " as image"); } @Override public int delete(Uri uri, String arg1, String[] arg2) { Log.d(TAG, "delete"); SQLiteDatabase db = dbHelper.getWritableDatabase(); int result; switch (matcher.match(uri)) { case MATCH_LIST: result = db.delete(GaranbotDBMetaData.TABLE_NAME, null, null); ImageCache.clearCache(getContext()); break; case MATCH_ITEM: result = db.delete(GaranbotDBMetaData.TABLE_NAME, GaranbotDBMetaData._ID + " == ?", new String[] { uri.getLastPathSegment() }); ImageCache .deleteImage(getContext(), (int) ContentUris.parseId(uri)); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return result; } @Override public String getType(Uri arg0) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri uri, ContentValues values) { Log.d(TAG, "insert"); switch (matcher.match(uri)) { case MATCH_LIST: if (values.containsKey(GaranbotDBMetaData._ID)) { long valuesId = values.getAsLong(GaranbotDBMetaData._ID); if (valuesId == Item.UNKNOWN_ID) { values.remove(GaranbotDBMetaData._ID); } } SQLiteDatabase db = dbHelper.getWritableDatabase(); long id = db.insert(GaranbotDBMetaData.TABLE_NAME, GaranbotDBMetaData.NAME, values); Uri numberUri = ContentUris.withAppendedId(CONTENT_URI_ITEMS, id); getContext().getContentResolver().notifyChange(numberUri, null); return numberUri; default: throw new IllegalArgumentException("Unknown URI: " + uri); } } @Override public boolean onCreate() { dbHelper = new GaranbotDBHelper(getContext()); return true; } /** * Queries the database for garanbo items and returns a cursor object which * points to the requested data. */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Log.d(TAG, "query"); // Build basic sql query SQLiteQueryBuilder query = new SQLiteQueryBuilder(); query.setTables(GaranbotDBMetaData.TABLE_NAME); query.setProjectionMap(projectionMap); if (sortOrder == null) { sortOrder = GaranbotDBMetaData.DEFAULT_SORT_ORDER; } SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor c; switch (matcher.match(uri)) { case MATCH_LIST_ALL: break; case MATCH_LIST: query.appendWhere("(" + GaranbotDBMetaData.LOCAL_STATE + " & " + LocalState.DELETED + ") == 0"); break; case MATCH_ITEM: query.appendWhere(GaranbotDBMetaData._ID + " == " + ContentUris.parseId(uri)); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } c = query.query(db, projection, selection, selectionArgs, null, null, sortOrder); c.setNotificationUri(getContext().getContentResolver(), uri); return c; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { Log.d(TAG, "update"); switch (matcher.match(uri)) { case MATCH_ITEM: values.remove(GaranbotDBMetaData._ID); SQLiteDatabase db = dbHelper.getWritableDatabase(); int result = db.update(GaranbotDBMetaData.TABLE_NAME, values, GaranbotDBMetaData._ID + " == ?", new String[] { uri.getLastPathSegment() }); getContext().getContentResolver().notifyChange(uri, null); return result; default: throw new IllegalArgumentException("Unknown URI: " + uri); } } /* * (non-Javadoc) * @see android.content.ContentProvider#openFile(android.net.Uri, * java.lang.String) */ @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (matcher.match(uri)) { case MATCH_IMAGE: long itemId = ContentUris.parseId(uri); File imageFile; if (itemId == Item.UNKNOWN_ID || !checkItemHasPicture(itemId)) { imageFile = ImageCache.getDefaultImageFile(getContext()); } else { imageFile = ImageCache.getFile(getContext(), itemId); if (!imageFile.exists()) { ImageDownloadService.downloadImage(getContext(), itemId); imageFile = ImageCache.getDefaultImageFile(getContext()); } } return ParcelFileDescriptor.open(imageFile, ParcelFileDescriptor.MODE_READ_ONLY); default: throw new IllegalArgumentException("Unknown URI: " + uri); } } /** * Returns true, if the item has a picture. * * @param itemId * ID of item to query for. * @return True, if picture is available. */ private boolean checkItemHasPicture(long itemId) { boolean result = false; SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = null; try { cursor = db.query(GaranbotDBMetaData.TABLE_NAME, new String[] { GaranbotDBMetaData.HASPICTURE }, GaranbotDBMetaData._ID + " == ?", new String[] { Long.toString(itemId) }, null, null, null); if (cursor.moveToFirst()) { result = cursor.getInt(0) > 0; } } finally { if (cursor != null) { cursor.close(); } } return result; } }