package com.mygeopay.wallet;
/*
* Copyright 2011-2014 the original author or authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import com.mygeopay.core.coins.CoinType;
import org.bitcoinj.core.Address;
import java.util.List;
import javax.annotation.Nonnull;
/**
* @author Andreas Schildbach
* @author John L. Jegutanis
*/
public class AddressBookProvider extends ContentProvider {
private static final String DATABASE_TABLE = "address_book";
public static final String KEY_ROWID = "_id";
public static final String KEY_COIN_ID = "coin_id";
public static final String KEY_ADDRESS = "address";
public static final String KEY_LABEL = "label";
public static final String SELECTION_QUERY = "q";
public static final String SELECTION_IN = "in";
public static final String SELECTION_NOTIN = "notin";
public static Uri contentUri(@Nonnull final String packageName) {
return contentUri(packageName, "");
}
public static Uri contentUri(@Nonnull final String packageName, @Nonnull final CoinType type) {
return contentUri(packageName, type.getId());
}
private static Uri contentUri(@Nonnull final String packageName, @Nonnull final String coinId) {
return Uri.parse("content://" + packageName + '.' + DATABASE_TABLE + "/" + coinId);
}
public static String resolveLabel(final Context context, final Address address) {
return resolveLabel(context, (CoinType) address.getParameters(), address.toString());
}
public static String resolveLabel(final Context context, @Nonnull CoinType type,
@Nonnull final String address) {
String label = null;
if (context != null) {
final Uri uri = contentUri(context.getPackageName(), type).buildUpon().appendPath(address).build();
final Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
label = cursor.getString(cursor.getColumnIndexOrThrow(AddressBookProvider.KEY_LABEL));
}
cursor.close();
}
}
return label;
}
private Helper helper;
@Override
public boolean onCreate() {
helper = new Helper(getContext());
return true;
}
@Override
public String getType(final Uri uri) {
throw new UnsupportedOperationException();
}
@Override
public Uri insert(final Uri uri, final ContentValues values) {
final List<String> pathSegments = getPathSegments(uri);
final String coinId = pathSegments.get(0);
final String address = pathSegments.get(1);
values.put(KEY_COIN_ID, coinId);
values.put(KEY_ADDRESS, address);
long rowId = helper.getWritableDatabase().insertOrThrow(DATABASE_TABLE, null, values);
final Uri rowUri = contentUri(getContext().getPackageName(), coinId).buildUpon()
.appendPath(address).appendPath(Long.toString(rowId)).build();
getContext().getContentResolver().notifyChange(rowUri, null);
return rowUri;
}
private List<String> getPathSegments(Uri uri) {
final List<String> pathSegments = uri.getPathSegments();
if (pathSegments.size() != 2)
throw new IllegalArgumentException(uri.toString());
return pathSegments;
}
@Override
public int update(final Uri uri, final ContentValues values, final String selection, final String[] selectionArgs) {
final List<String> pathSegments = getPathSegments(uri);
final String coinId = pathSegments.get(0);
final String address = pathSegments.get(1);
values.put(KEY_COIN_ID, coinId);
values.put(KEY_ADDRESS, address);
final int count = helper.getWritableDatabase().update(DATABASE_TABLE, values,
KEY_COIN_ID + "=? AND " + KEY_ADDRESS + "=?", new String[]{coinId, address});
if (count > 0)
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int delete(final Uri uri, final String selection, final String[] selectionArgs) {
final List<String> pathSegments = getPathSegments(uri);
final String coinId = pathSegments.get(0);
final String address = pathSegments.get(1);
final int count = helper.getWritableDatabase().delete(DATABASE_TABLE,
KEY_COIN_ID + "=? AND " + KEY_ADDRESS + "=?", new String[]{coinId, address});
if (count > 0)
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public Cursor query(final Uri uri, final String[] projection, final String originalSelection,
final String[] originalSelectionArgs, final String sortOrder) {
final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(DATABASE_TABLE);
final List<String> pathSegments = uri.getPathSegments();
if (pathSegments.size() < 1 || pathSegments.size() > 2)
throw new IllegalArgumentException(uri.toString());
String selection = null;
String[] selectionArgs = null;
final String coinId = pathSegments.get(0);
qb.appendWhere(KEY_COIN_ID + "=");
qb.appendWhereEscapeString(coinId);
if (pathSegments.size() == 2) {
final String address = pathSegments.get(1);
qb.appendWhere(" AND " + KEY_ADDRESS + "=");
qb.appendWhereEscapeString(address);
} else if (SELECTION_IN.equals(originalSelection)) {
final String[] addresses = originalSelectionArgs[0].trim().split(",");
qb.appendWhere(" AND " + KEY_ADDRESS + " IN (");
appendAddresses(qb, addresses);
qb.appendWhere(")");
} else if (SELECTION_NOTIN.equals(originalSelection)) {
final String[] addresses = originalSelectionArgs[0].trim().split(",");
qb.appendWhere(" AND " + KEY_ADDRESS + " NOT IN (");
appendAddresses(qb, addresses);
qb.appendWhere(")");
} else if (SELECTION_QUERY.equals(originalSelection)) {
final String query = '%' + originalSelectionArgs[0].trim() + '%';
selection = KEY_ADDRESS + " LIKE ? OR " + KEY_LABEL + " LIKE ?";
selectionArgs = new String[]{query, query};
}
final Cursor cursor = qb.query(helper.getReadableDatabase(), projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
private static void appendAddresses(@Nonnull final SQLiteQueryBuilder qb, @Nonnull final String[] addresses) {
for (final String address : addresses) {
qb.appendWhereEscapeString(address.trim());
if (!address.equals(addresses[addresses.length - 1]))
qb.appendWhere(",");
}
}
private static class Helper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "address_book";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE = "CREATE TABLE " + DATABASE_TABLE + " (" //
+ KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " //
+ KEY_COIN_ID + " TEXT NOT NULL, " //
+ KEY_ADDRESS + " TEXT NOT NULL, " //
+ KEY_LABEL + " TEXT NULL);";
public Helper(final Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(final SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
db.beginTransaction();
try {
for (int v = oldVersion; v < newVersion; v++)
upgrade(db, v);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
private void upgrade(final SQLiteDatabase db, final int oldVersion) {
if (oldVersion == 1) {
// future
} else {
throw new UnsupportedOperationException("old=" + oldVersion);
}
}
}
}