Retain transitories across the api dao/content resolver boundary

pull/14/head
Sam Bosley 13 years ago
parent 6654ac0a9e
commit 551542e8a7

@ -11,6 +11,8 @@ import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import android.content.ContentValues;
import android.os.Parcel;
@ -48,6 +50,9 @@ public abstract class AbstractModel implements Parcelable, Cloneable {
/** sentinel for objects without an id */
public static final long NO_ID = 0;
/** prefix for transitories retained in content values */
public static final String RETAIN_TRANSITORY_PREFIX = "retain-trans-"; //$NON-NLS-1$
// --- abstract methods
/** Get the default values for this object */
@ -313,6 +318,7 @@ public abstract class AbstractModel implements Parcelable, Cloneable {
public synchronized <TYPE> void mergeWith(ContentValues other) {
if (setValues == null)
setValues = new ContentValues();
restoreTransitories(other);
setValues.putAll(other);
}
@ -371,6 +377,74 @@ public abstract class AbstractModel implements Parcelable, Cloneable {
return transitoryData.remove(key);
}
/**
* Move transitory values (those that can be saved) to setValues,
* to be restored later. This is useful for the api daos that go
* through the content provider
*/
public synchronized void retainTransitories() {
if (transitoryData == null)
return;
if (setValues == null)
setValues = new ContentValues();
Set<String> keys = transitoryData.keySet();
for (String key : keys) {
String newKey = RETAIN_TRANSITORY_PREFIX + key;
Object value = transitoryData.get(key);
putObjectInContentValues(newKey, value, setValues);
}
}
/**
* Read keys from ContentValues. Remove those that match the
* RETAIN_TRANSITORY_PREFIX pattern and set those values
* on transitory data
* @param cv
*/
private void restoreTransitories(ContentValues cv) {
if (transitoryData == null)
transitoryData = new HashMap<String, Object>();
Set<String> keys = cv.keySet();
Set<String> keysToRemove = new HashSet<String>();
for (String key : keys) {
if (key.startsWith(RETAIN_TRANSITORY_PREFIX)) {
String newKey = key.substring(RETAIN_TRANSITORY_PREFIX.length());
Object value = cv.get(key);
transitoryData.put(newKey, value);
keysToRemove.add(key);
}
}
for (String key : keysToRemove) {
cv.remove(key);
}
}
/**
* If value is of a type that is puttable in ContentValues, cast and put it
* @param key
* @param value
* @param cv
*/
private void putObjectInContentValues(String key, Object value, ContentValues cv) {
if (value instanceof Boolean)
cv.put(key, (Boolean) value);
if (value instanceof Byte)
cv.put(key, (Byte) value);
if (value instanceof Double)
cv.put(key, (Double) value);
if (value instanceof Float)
cv.put(key, (Float) value);
if (value instanceof Integer)
cv.put(key, (Integer) value);
if (value instanceof Long)
cv.put(key, (Long) value);
if (value instanceof Short)
cv.put(key, (Short) value);
if (value instanceof String)
cv.put(key, (String) value);
}
// --- Convenience wrappers for using transitories as flags
public boolean checkTransitory(String flag) {

@ -91,12 +91,17 @@ public class ContentResolverDao<TYPE extends AbstractModel> {
* @return true if data was written to the db, false otherwise
*/
public boolean save(TYPE model) {
boolean retainedTransitories = false;
if(model.isSaved()) {
if(model.getSetValues() == null)
return false;
model.retainTransitories();
retainedTransitories = true;
if(cr.update(uriWithId(model.getId()), model.getSetValues(), null, null) != 0)
return true;
}
if (!retainedTransitories)
model.retainTransitories();
Uri uri = cr.insert(baseUri, model.getMergedValues());
long id = Long.parseLong(uri.getLastPathSegment());
model.setId(id);

Loading…
Cancel
Save