/*
* Copyright (C) 2010 Josh Guilfoyle <jasta@devtcg.org>
*
* 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 2, 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.
*/
package org.devtcg.five.provider;
import java.io.File;
import org.devtcg.five.service.SyncContext;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
public abstract class AbstractSyncProvider extends ContentProvider
{
private boolean mIsTemporary;
private File mTemporaryPath;
protected final boolean isTemporary()
{
return mIsTemporary;
}
protected final File getTemporaryPath()
{
return mTemporaryPath;
}
public void onDestroySyncInstance()
{
mTemporaryPath.delete();
}
public abstract void close();
public abstract SQLiteDatabase getDatabase();
public abstract AbstractSyncAdapter getSyncAdapter();
public abstract AbstractSyncProvider getSyncInstance();
protected abstract Iterable<? extends AbstractTableMerger> getMergers();
public void merge(SyncContext syncContext, AbstractSyncProvider diffs)
{
SQLiteDatabase db = getDatabase();
db.beginTransaction();
try {
Iterable<? extends AbstractTableMerger> mergers = getMergers();
for (AbstractTableMerger merger: mergers)
{
merger.merge(getContext(), syncContext, diffs, null);
if (syncContext.hasCanceled() || syncContext.hasError())
break;
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
protected abstract Cursor queryInternal(Uri uri, String[] project, String selection,
String[] selectionArgs, String sortOrder);
protected abstract Uri insertInternal(Uri uri, ContentValues values);
protected abstract int updateInternal(Uri uri, ContentValues values, String selection,
String[] selectionArgs);
protected abstract int deleteInternal(Uri uri, String selection, String[] selectionArgs);
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder)
{
return queryInternal(uri, projection, selection, selectionArgs, sortOrder);
}
@Override
public Uri insert(Uri uri, ContentValues values)
{
SQLiteDatabase db = getDatabase();
db.beginTransaction();
try {
Uri ret = insertInternal(uri, values);
db.setTransactionSuccessful();
return ret;
} finally {
db.endTransaction();
}
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
{
SQLiteDatabase db = getDatabase();
db.beginTransaction();
try {
int ret = updateInternal(uri, values, selection, selectionArgs);
db.setTransactionSuccessful();
return ret;
} finally {
db.endTransaction();
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
SQLiteDatabase db = getDatabase();
db.beginTransaction();
try {
int ret = deleteInternal(uri, selection, selectionArgs);
db.setTransactionSuccessful();
return ret;
} finally {
db.endTransaction();
}
}
protected static abstract class Creator<T extends AbstractSyncProvider>
{
public abstract T newInstance();
public T getSyncInstance(File databasePath)
{
T instance = newInstance();
instance.mIsTemporary = true;
instance.mTemporaryPath = databasePath;
return instance;
}
}
}