Use visitors when processing ChangesHappened or MakeChanges to ensure types are correct; started working on ReplayOutstandingEntries

pull/14/head
Sam Bosley 12 years ago
parent 184972f246
commit a4405481f7

@ -14,12 +14,17 @@ import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.astrid.actfm.sync.messages.BriefMe; import com.todoroo.astrid.actfm.sync.messages.BriefMe;
import com.todoroo.astrid.actfm.sync.messages.ClientToServerMessage; import com.todoroo.astrid.actfm.sync.messages.ClientToServerMessage;
import com.todoroo.astrid.actfm.sync.messages.ReplayOutstandingEntries;
import com.todoroo.astrid.actfm.sync.messages.ServerToClientMessage; import com.todoroo.astrid.actfm.sync.messages.ServerToClientMessage;
import com.todoroo.astrid.core.PluginServices; import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.dao.TagDataDao; import com.todoroo.astrid.dao.TagDataDao;
import com.todoroo.astrid.dao.TagOutstandingDao;
import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.dao.TaskOutstandingDao;
import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.TagOutstanding;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.TaskOutstanding;
public class ActFmSyncThread { public class ActFmSyncThread {
@ -35,6 +40,18 @@ public class ActFmSyncThread {
@Autowired @Autowired
private ActFmPreferenceService actFmPreferenceService; private ActFmPreferenceService actFmPreferenceService;
@Autowired
private TaskDao taskDao;
@Autowired
private TaskOutstandingDao taskOutstandingDao;
@Autowired
private TagDataDao tagDataDao;
@Autowired
private TagOutstandingDao tagOutstandingDao;
private String token; private String token;
public static enum ModelType { public static enum ModelType {
@ -172,8 +189,8 @@ public class ActFmSyncThread {
// Reapplies changes still in the outstanding tables to the local database // Reapplies changes still in the outstanding tables to the local database
// Called after a batch has finished processing // Called after a batch has finished processing
private void replayOutstandingChanges() { private void replayOutstandingChanges() {
// TODO: Replay existing outstanding changes new ReplayOutstandingEntries<Task, TaskOutstanding>(Task.class, taskDao, taskOutstandingDao).execute();
new ReplayOutstandingEntries<TagData, TagOutstanding>(TagData.class, tagDataDao, tagOutstandingDao).execute();
} }
private boolean timeForBackgroundSync() { private boolean timeForBackgroundSync() {

@ -9,8 +9,8 @@ import org.json.JSONObject;
import android.util.Log; import android.util.Log;
import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.Property; import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.Property.PropertyVisitor;
import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Order; import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.sql.Query;
@ -53,7 +53,7 @@ public class ChangesHappened<TYPE extends RemoteModel, OE extends OutstandingEnt
OutstandingEntryDao<OE> outstandingDao) { OutstandingEntryDao<OE> outstandingDao) {
super(id, modelClass, modelDao); super(id, modelClass, modelDao);
this.outstandingClass = getOutstandingClass(modelClass); this.outstandingClass = DaoReflectionHelpers.getOutstandingClass(modelClass);
this.changes = new ArrayList<OE>(); this.changes = new ArrayList<OE>();
if (!RemoteModel.NO_UUID.equals(uuid)) if (!RemoteModel.NO_UUID.equals(uuid))
@ -81,17 +81,23 @@ public class ChangesHappened<TYPE extends RemoteModel, OE extends OutstandingEnt
private JSONArray changesToJSON() { private JSONArray changesToJSON() {
JSONArray array = new JSONArray(); JSONArray array = new JSONArray();
PropertyToJSONVisitor visitor = new PropertyToJSONVisitor();
for (OE change : changes) { for (OE change : changes) {
try { try {
String localColumn = change.getValue(OutstandingEntry.COLUMN_STRING_PROPERTY); String localColumn = change.getValue(OutstandingEntry.COLUMN_STRING_PROPERTY);
Property<?> localProperty = NameMaps.localColumnNameToProperty(table, localColumn);
if (localProperty == null)
throw new RuntimeException("No local property found for local column " + localColumn + " in table " + table);
String serverColumn = NameMaps.localColumnNameToServerColumnName(table, localColumn); String serverColumn = NameMaps.localColumnNameToServerColumnName(table, localColumn);
if (serverColumn == null) if (serverColumn == null)
throw new RuntimeException("No server column found for local column " + localColumn + " in table " + table); throw new RuntimeException("No server column found for local column " + localColumn + " in table " + table);
JSONObject changeJson = new JSONObject(); JSONObject changeJson = new JSONObject();
changeJson.put("id", change.getId()); changeJson.put("id", change.getId());
changeJson.put("column", serverColumn); changeJson.put("column", serverColumn);
changeJson.put("value", change.getValue(OutstandingEntry.VALUE_STRING_PROPERTY)); changeJson.put("value", localProperty.accept(visitor, change));
array.put(changeJson); array.put(changeJson);
} catch (JSONException e) { } catch (JSONException e) {
@ -102,7 +108,7 @@ public class ChangesHappened<TYPE extends RemoteModel, OE extends OutstandingEnt
} }
private void populateChanges(OutstandingEntryDao<OE> outstandingDao) { private void populateChanges(OutstandingEntryDao<OE> outstandingDao) {
TodorooCursor<OE> cursor = outstandingDao.query(Query.select(getModelProperties(outstandingClass)) TodorooCursor<OE> cursor = outstandingDao.query(Query.select(DaoReflectionHelpers.getModelProperties(outstandingClass))
.where(OutstandingEntry.ENTITY_ID_PROPERTY.eq(id)).orderBy(Order.asc(OutstandingEntry.CREATED_AT_PROPERTY))); .where(OutstandingEntry.ENTITY_ID_PROPERTY.eq(id)).orderBy(Order.asc(OutstandingEntry.CREATED_AT_PROPERTY)));
try { try {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
@ -121,11 +127,47 @@ public class ChangesHappened<TYPE extends RemoteModel, OE extends OutstandingEnt
} }
} }
private Class<OE> getOutstandingClass(Class<? extends RemoteModel> model) { private class PropertyToJSONVisitor implements PropertyVisitor<Object, OE> {
return DaoReflectionHelpers.getStaticFieldByReflection(model, Class.class, "OUTSTANDING_MODEL");
} private String getAsString(OE data) {
return data.getValue(OutstandingEntry.VALUE_STRING_PROPERTY);
}
@Override
public Object visitInteger(Property<Integer> property, OE data) {
Integer i = data.getMergedValues().getAsInteger(OutstandingEntry.VALUE_STRING_PROPERTY.name);
if (i != null) {
return i.intValue();
} else {
return getAsString(data);
}
}
@Override
public Object visitLong(Property<Long> property, OE data) {
Long l = data.getMergedValues().getAsLong(OutstandingEntry.VALUE_STRING_PROPERTY.name);
if (l != null) {
return l.longValue();
} else {
return getAsString(data);
}
}
@Override
public Object visitDouble(Property<Double> property, OE data) {
Double d = data.getMergedValues().getAsDouble(OutstandingEntry.VALUE_STRING_PROPERTY.name);
if (d != null) {
return d.doubleValue();
} else {
return getAsString(data);
}
}
@Override
public Object visitString(Property<String> property, OE data) {
return getAsString(data);
}
private Property<?>[] getModelProperties(Class<? extends AbstractModel> model) {
return DaoReflectionHelpers.getStaticFieldByReflection(model, Property[].class, "PROPERTIES");
} }
} }

@ -12,6 +12,7 @@ import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.Property.DoubleProperty; import com.todoroo.andlib.data.Property.DoubleProperty;
import com.todoroo.andlib.data.Property.IntegerProperty; import com.todoroo.andlib.data.Property.IntegerProperty;
import com.todoroo.andlib.data.Property.LongProperty; import com.todoroo.andlib.data.Property.LongProperty;
import com.todoroo.andlib.data.Property.PropertyVisitor;
import com.todoroo.andlib.data.Property.StringProperty; import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.astrid.dao.RemoteModelDao; import com.todoroo.astrid.dao.RemoteModelDao;
import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.RemoteModel;
@ -40,12 +41,13 @@ public class MakeChanges<TYPE extends RemoteModel> extends ServerToClientMessage
TYPE model = dao.getModelClass().newInstance(); TYPE model = dao.getModelClass().newInstance();
JSONArray keys = changes.names(); JSONArray keys = changes.names();
if (keys != null) { if (keys != null) {
JSONToPropertyVisitor visitor = new JSONToPropertyVisitor(changes, model);
for (int i = 0; i < keys.length(); i++) { for (int i = 0; i < keys.length(); i++) {
String col = keys.optString(i); String col = keys.optString(i);
if (!TextUtils.isEmpty(col)) { if (!TextUtils.isEmpty(col)) {
Property<?> property = NameMaps.serverColumnNameToLocalProperty(table, col); Property<?> property = NameMaps.serverColumnNameToLocalProperty(table, col);
if (property != null) { // Unsupported property if (property != null) { // Unsupported property
setPropertyFromJSON(model, property, changes, col); property.accept(visitor, col);
} }
} }
} }
@ -66,36 +68,60 @@ public class MakeChanges<TYPE extends RemoteModel> extends ServerToClientMessage
} }
} }
private static void setPropertyFromJSON(AbstractModel model, Property<?> property, JSONObject json, String jsonKey) {
if (property instanceof LongProperty) { private static class JSONToPropertyVisitor implements PropertyVisitor<Void, String> {
private final JSONObject json;
private final AbstractModel model;
public JSONToPropertyVisitor(JSONObject json, AbstractModel model) {
this.json = json;
this.model = model;
}
@Override
public Void visitInteger(Property<Integer> property, String data) {
try { try {
long value = json.getLong(jsonKey); int value = json.getInt(data);
model.setValue((LongProperty) property, value); model.setValue((IntegerProperty) property, value);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(ERROR_TAG, "Error reading long from JSON " + json + " with key " + jsonKey, e); Log.e(ERROR_TAG, "Error reading int from JSON " + json + " with key " + data, e);
} }
} else if (property instanceof StringProperty) { return null;
}
@Override
public Void visitLong(Property<Long> property, String data) {
try { try {
String value = json.getString(jsonKey); long value = json.getLong(data);
model.setValue((StringProperty) property, value); model.setValue((LongProperty) property, value);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(ERROR_TAG, "Error reading string from JSON " + json + " with key " + jsonKey, e); Log.e(ERROR_TAG, "Error reading long from JSON " + json + " with key " + data, e);
} }
} else if (property instanceof IntegerProperty) { return null;
}
@Override
public Void visitDouble(Property<Double> property, String data) {
try { try {
int value = json.getInt(jsonKey); double value = json.getDouble(data);
model.setValue((IntegerProperty) property, value); model.setValue((DoubleProperty) property, value);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(ERROR_TAG, "Error reading int from JSON " + json + " with key " + jsonKey, e); Log.e(ERROR_TAG, "Error reading double from JSON " + json + " with key " + data, e);
} }
} else if (property instanceof DoubleProperty) { return null;
}
@Override
public Void visitString(Property<String> property, String data) {
try { try {
double value = json.getDouble(jsonKey); String value = json.getString(data);
model.setValue((DoubleProperty) property, value); model.setValue((StringProperty) property, value);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(ERROR_TAG, "Error reading double from JSON " + json + " with key " + jsonKey, e); Log.e(ERROR_TAG, "Error reading string from JSON " + json + " with key " + data, e);
} }
return null;
} }
}
}
} }

@ -47,39 +47,44 @@ public class NameMaps {
// ---- Column name mappings ------- // ---- Column name mappings -------
// -------------------------------- // --------------------------------
private static final Map<Property<?>, String> TASK_PROPERTIES_LOCAL_TO_SERVER; private static final Map<Property<?>, String> TASK_PROPERTIES_LOCAL_TO_SERVER;
private static final Map<String, Property<?>> TASK_COLUMN_NAMES_TO_PROPERTIES;
private static final Map<String, String> TASK_COLUMNS_LOCAL_TO_SERVER; private static final Map<String, String> TASK_COLUMNS_LOCAL_TO_SERVER;
private static final Map<String, Property<?>> TASK_PROPERTIES_SERVER_TO_LOCAL; private static final Map<String, Property<?>> TASK_PROPERTIES_SERVER_TO_LOCAL;
private static void putPropertyToServerName(Property<?> property, String serverName, private static void putPropertyToServerName(Property<?> property, String serverName,
Map<Property<?>, String> propertyMap, Map<String, String> nameMap) { Map<Property<?>, String> propertyMap, Map<String, Property<?>> localNameMap, Map<String, String> serverNameMap) {
propertyMap.put(property, serverName); propertyMap.put(property, serverName);
nameMap.put(property.name, serverName); localNameMap.put(property.name, property);
serverNameMap.put(property.name, serverName);
} }
static { static {
// Hardcoded local columns mapped to corresponding server names // Hardcoded local columns mapped to corresponding server names
TASK_PROPERTIES_LOCAL_TO_SERVER = new HashMap<Property<?>, String>(); TASK_PROPERTIES_LOCAL_TO_SERVER = new HashMap<Property<?>, String>();
TASK_COLUMNS_LOCAL_TO_SERVER = new HashMap<String, String>(); TASK_COLUMNS_LOCAL_TO_SERVER = new HashMap<String, String>();
putPropertyToServerName(Task.TITLE, "title", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); TASK_COLUMN_NAMES_TO_PROPERTIES = new HashMap<String, Property<?>>();
putPropertyToServerName(Task.IMPORTANCE, "importance", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.DUE_DATE, "due", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.TITLE, "title", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.HIDE_UNTIL, "hide_until", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.IMPORTANCE, "importance", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.COMPLETION_DATE, "completed_at", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.DUE_DATE, "due", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.DELETION_DATE, "deleted_at", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.HIDE_UNTIL, "hide_until", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.NOTES, "notes", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.COMPLETION_DATE, "completed_at", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.RECURRENCE, "repeat", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.DELETION_DATE, "deleted_at", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.USER_ID, "user_id", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.NOTES, "notes", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.USER, "user", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.RECURRENCE, "repeat", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.CREATOR_ID, "creator_id", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.USER_ID, "user_id", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.UUID, "uuid", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.USER, "user", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.PROOF_TEXT, "proof_text", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.CREATOR_ID, "creator_id", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.PUSHED_AT, "pushed_at", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(Task.UUID, "uuid", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.PROOF_TEXT, "proof_text", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(Task.PUSHED_AT, "pushed_at", TASK_PROPERTIES_LOCAL_TO_SERVER, TASK_COLUMN_NAMES_TO_PROPERTIES, TASK_COLUMNS_LOCAL_TO_SERVER);
TASK_PROPERTIES_SERVER_TO_LOCAL = AndroidUtilities.reverseMap(TASK_PROPERTIES_LOCAL_TO_SERVER); TASK_PROPERTIES_SERVER_TO_LOCAL = AndroidUtilities.reverseMap(TASK_PROPERTIES_LOCAL_TO_SERVER);
} }
private static final Map<Property<?>, String> TAG_DATA_PROPERTIES_LOCAL_TO_SERVER; private static final Map<Property<?>, String> TAG_DATA_PROPERTIES_LOCAL_TO_SERVER;
private static final Map<String, Property<?>> TAG_DATA_COLUMN_NAMES_TO_PROPERTIES;
private static final Map<String, String> TAG_DATA_COLUMNS_LOCAL_TO_SERVER; private static final Map<String, String> TAG_DATA_COLUMNS_LOCAL_TO_SERVER;
private static final Map<String, Property<?>> TAG_DATA_PROPERTIES_SERVER_TO_LOCAL; private static final Map<String, Property<?>> TAG_DATA_PROPERTIES_SERVER_TO_LOCAL;
@ -87,47 +92,48 @@ public class NameMaps {
// Hardcoded local columns mapped to corresponding server names // Hardcoded local columns mapped to corresponding server names
TAG_DATA_PROPERTIES_LOCAL_TO_SERVER = new HashMap<Property<?>, String>(); TAG_DATA_PROPERTIES_LOCAL_TO_SERVER = new HashMap<Property<?>, String>();
TAG_DATA_COLUMNS_LOCAL_TO_SERVER = new HashMap<String, String>(); TAG_DATA_COLUMNS_LOCAL_TO_SERVER = new HashMap<String, String>();
TAG_DATA_COLUMN_NAMES_TO_PROPERTIES = new HashMap<String, Property<?>>();
putPropertyToServerName(TagData.USER_ID, "user_id", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(TagData.USER, "user", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); //TODO: NOT CORRECT putPropertyToServerName(TagData.USER_ID, "user_id", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(TagData.NAME, "name", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(TagData.USER, "user", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); //TODO: NOT CORRECT
putPropertyToServerName(TagData.PICTURE, "picture_id", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); //TODO: NOT CORRECT putPropertyToServerName(TagData.NAME, "name", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(TagData.MEMBERS, "members", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); //TODO: NOT CORRECT putPropertyToServerName(TagData.PICTURE, "picture_id", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); //TODO: NOT CORRECT
putPropertyToServerName(TagData.CREATION_DATE, "created_at", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(TagData.MEMBERS, "members", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); //TODO: NOT CORRECT
putPropertyToServerName(TagData.DELETION_DATE, "deleted_at", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(TagData.CREATION_DATE, "created_at", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(TagData.UUID, "uuid", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(TagData.DELETION_DATE, "deleted_at", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(TagData.PROOF_TEXT, "proof_text", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(TagData.UUID, "uuid", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(TagData.TAG_ORDERING, "tag_ordering", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); //TODO: NOT CORRECT putPropertyToServerName(TagData.PROOF_TEXT, "proof_text", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER);
putPropertyToServerName(TagData.PUSHED_AT, "pushed_at", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); putPropertyToServerName(TagData.TAG_ORDERING, "tag_ordering", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); //TODO: NOT CORRECT
putPropertyToServerName(TagData.PUSHED_AT, "pushed_at", TAG_DATA_PROPERTIES_LOCAL_TO_SERVER, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMNS_LOCAL_TO_SERVER);
// Reverse the mapping to construct the server to local map // Reverse the mapping to construct the server to local map
TAG_DATA_PROPERTIES_SERVER_TO_LOCAL = AndroidUtilities.reverseMap(TAG_DATA_PROPERTIES_LOCAL_TO_SERVER); TAG_DATA_PROPERTIES_SERVER_TO_LOCAL = AndroidUtilities.reverseMap(TAG_DATA_PROPERTIES_LOCAL_TO_SERVER);
} }
public static String localColumnNameToServerColumnName(String table, String localColumn) { private static <A, B> B mapColumnName(String table, String col, Map<A, B> taskMap, Map<A, B> tagMap) {
Map<String, String> map = null; Map<A, B> map = null;
if (SERVER_TABLE_TASKS.equals(table)) if (SERVER_TABLE_TASKS.equals(table))
map = TASK_COLUMNS_LOCAL_TO_SERVER; map = taskMap;
else if (SERVER_TABLE_TAGS.equals(table)) else if (SERVER_TABLE_TAGS.equals(table))
map = TAG_DATA_COLUMNS_LOCAL_TO_SERVER; map = tagMap;
if (map == null) if (map == null)
return null; return null;
return map.get(localColumn); return map.get(col);
} }
public static Property<?> serverColumnNameToLocalProperty(String table, String serverColumn) { public static String localColumnNameToServerColumnName(String table, String localColumn) {
Map<String, Property<?>> map = null; return mapColumnName(table, localColumn, TASK_COLUMNS_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER);
if (SERVER_TABLE_TASKS.equals(table)) }
map = TASK_PROPERTIES_SERVER_TO_LOCAL;
else if (SERVER_TABLE_TAGS.equals(table))
map = TAG_DATA_PROPERTIES_SERVER_TO_LOCAL;
if (map == null) public static Property<?> localColumnNameToProperty(String table, String localColumn) {
return null; return mapColumnName(table, localColumn, TASK_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES);
}
return map.get(serverColumn); public static Property<?> serverColumnNameToLocalProperty(String table, String serverColumn) {
return mapColumnName(table, serverColumn, TASK_PROPERTIES_SERVER_TO_LOCAL, TAG_DATA_PROPERTIES_SERVER_TO_LOCAL);
} }
} }

@ -0,0 +1,36 @@
package com.todoroo.astrid.actfm.sync.messages;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.dao.DaoReflectionHelpers;
import com.todoroo.astrid.dao.OutstandingEntryDao;
import com.todoroo.astrid.dao.RemoteModelDao;
import com.todoroo.astrid.data.OutstandingEntry;
import com.todoroo.astrid.data.RemoteModel;
public class ReplayOutstandingEntries<T extends RemoteModel, OE extends OutstandingEntry<T>> {
private final Class<T> modelClass;
private final Class<OE> outstandingClass;
private final RemoteModelDao<T> dao;
private final OutstandingEntryDao<OE> outstandingDao;
public ReplayOutstandingEntries(Class<T> modelClass, RemoteModelDao<T> dao, OutstandingEntryDao<OE> outstandingDao) {
this.modelClass = modelClass;
this.outstandingClass = DaoReflectionHelpers.getOutstandingClass(modelClass);
this.dao = dao;
this.outstandingDao = outstandingDao;
}
public void execute() {
TodorooCursor<OE> outstanding = outstandingDao.query(Query.select(DaoReflectionHelpers.getModelProperties(outstandingClass))
.orderBy(Order.asc(OutstandingEntry.ENTITY_ID_PROPERTY), Order.asc(OutstandingEntry.CREATED_AT_PROPERTY)));
try {
// Do and apply
} finally {
outstanding.close();
}
}
}

@ -2,6 +2,10 @@ package com.todoroo.astrid.dao;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.Property;
import com.todoroo.astrid.data.RemoteModel;
@SuppressWarnings("nls") @SuppressWarnings("nls")
public class DaoReflectionHelpers { public class DaoReflectionHelpers {
@ -22,4 +26,12 @@ public class DaoReflectionHelpers {
} }
} }
public static Property<?>[] getModelProperties(Class<? extends AbstractModel> model) {
return getStaticFieldByReflection(model, Property[].class, "PROPERTIES");
}
public static <OE> Class<OE> getOutstandingClass(Class<? extends RemoteModel> model) {
return DaoReflectionHelpers.getStaticFieldByReflection(model, Class.class, "OUTSTANDING_MODEL");
}
} }

@ -5,7 +5,6 @@ import org.json.JSONObject;
import com.todoroo.astrid.actfm.sync.ActFmSyncThread.ModelType; import com.todoroo.astrid.actfm.sync.ActFmSyncThread.ModelType;
import com.todoroo.astrid.actfm.sync.messages.ChangesHappened; import com.todoroo.astrid.actfm.sync.messages.ChangesHappened;
import com.todoroo.astrid.actfm.sync.messages.ClientToServerMessage;
import com.todoroo.astrid.actfm.sync.messages.NameMaps; import com.todoroo.astrid.actfm.sync.messages.NameMaps;
import com.todoroo.astrid.actfm.sync.messages.ServerToClientMessage; import com.todoroo.astrid.actfm.sync.messages.ServerToClientMessage;
import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.RemoteModel;
@ -16,7 +15,7 @@ public class SyncMessageTest extends NewSyncTestCase {
public void testTaskChangesHappenedConstructor() { public void testTaskChangesHappenedConstructor() {
Task t = createTask(); Task t = createTask();
try { try {
ChangesHappened<?, ?> changes = ClientToServerMessage.instantiateChangesHappened(t.getId(), ModelType.TYPE_TASK); ChangesHappened<?, ?> changes = ChangesHappened.instantiateChangesHappened(t.getId(), ModelType.TYPE_TASK);
assertTrue(changes.numChanges() > 0); assertTrue(changes.numChanges() > 0);
assertFalse(RemoteModel.NO_UUID.equals(changes.getUUID())); assertFalse(RemoteModel.NO_UUID.equals(changes.getUUID()));
assertEquals(t.getValue(Task.UUID), changes.getUUID()); assertEquals(t.getValue(Task.UUID), changes.getUUID());

Loading…
Cancel
Save