From ac1fb8fc2fffd34e6ae59766ca095cf4f105c73f Mon Sep 17 00:00:00 2001 From: Sam Bosley Date: Thu, 17 Jan 2013 13:48:15 -0800 Subject: [PATCH] Implement UserData message --- api/src/com/todoroo/astrid/data/User.java | 8 ++ .../messages/JSONChangeToPropertyVisitor.java | 97 +++++++++++++++++++ .../actfm/sync/messages/MakeChanges.java | 84 ---------------- .../astrid/actfm/sync/messages/NameMaps.java | 32 +++++- .../sync/messages/ServerToClientMessage.java | 3 + .../astrid/actfm/sync/messages/UserData.java | 57 +++++++++++ .../src/com/todoroo/astrid/dao/Database.java | 2 + 7 files changed, 195 insertions(+), 88 deletions(-) create mode 100644 astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/JSONChangeToPropertyVisitor.java create mode 100644 astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/UserData.java diff --git a/api/src/com/todoroo/astrid/data/User.java b/api/src/com/todoroo/astrid/data/User.java index 55ffa2e4c..452a0e20c 100644 --- a/api/src/com/todoroo/astrid/data/User.java +++ b/api/src/com/todoroo/astrid/data/User.java @@ -46,6 +46,14 @@ public final class User extends RemoteModel { public static final StringProperty NAME = new StringProperty( TABLE, "name"); + /** User first name */ + public static final StringProperty FIRST_NAME = new StringProperty( + TABLE, "first_name"); + + /** User last name */ + public static final StringProperty LAST_NAME = new StringProperty( + TABLE, "last_name"); + /** User Email */ public static final StringProperty EMAIL = new StringProperty( TABLE, "email"); diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/JSONChangeToPropertyVisitor.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/JSONChangeToPropertyVisitor.java new file mode 100644 index 000000000..246ec4161 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/JSONChangeToPropertyVisitor.java @@ -0,0 +1,97 @@ +package com.todoroo.astrid.actfm.sync.messages; + +import org.json.JSONException; +import org.json.JSONObject; + +import android.util.Log; + +import com.todoroo.andlib.data.AbstractModel; +import com.todoroo.andlib.data.Property; +import com.todoroo.andlib.data.Property.DoubleProperty; +import com.todoroo.andlib.data.Property.IntegerProperty; +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.utility.DateUtilities; +import com.todoroo.astrid.actfm.sync.ActFmPreferenceService; +import com.todoroo.astrid.data.Task; + + +@SuppressWarnings("nls") +public class JSONChangeToPropertyVisitor implements PropertyVisitor { + + private static final String ERROR_TAG = "actfm-make-changes"; + + private final AbstractModel model; + private final JSONObject data; + + public JSONChangeToPropertyVisitor(AbstractModel model, JSONObject data) { + this.model = model; + this.data = data; + } + + @Override + public Void visitInteger(Property property, String key) { + try { + int value = data.getInt(key); + model.setValue((IntegerProperty) property, value); + } catch (JSONException e) { + Log.e(ERROR_TAG, "Error reading int value with key " + key + " from JSON " + data, e); + } + return null; + } + + @Override + public Void visitLong(Property property, String key) { + try { + long value = data.optLong(key, 0); + if (property.checkFlag(Property.PROP_FLAG_USER_ID) && value == ActFmPreferenceService.userId()) + value = 0; + else if (property.checkFlag(Property.PROP_FLAG_DATE)) { + String valueString = data.getString(key); + try { + value = DateUtilities.parseIso8601(valueString).getTime(); + if (Task.DUE_DATE.equals(property)) { + boolean hasDueTime = valueString.endsWith("Z"); + value = Task.createDueDate(hasDueTime ? Task.URGENCY_SPECIFIC_DAY_TIME : Task.URGENCY_SPECIFIC_DAY, value); + } + } catch (Exception e){ + value = 0; + } + } + model.setValue((LongProperty) property, value); + } catch (JSONException e) { + Log.e(ERROR_TAG, "Error reading long value with key " + key + " from JSON " + data, e); + } + return null; + } + + @Override + public Void visitDouble(Property property, String key) { + try { + double value = data.getDouble(key); + model.setValue((DoubleProperty) property, value); + } catch (JSONException e) { + Log.e(ERROR_TAG, "Error reading double value with key " + key + " from JSON " + data, e); + } + return null; + } + + @Override + public Void visitString(Property property, String key) { + try { + String value = data.getString(key); + model.setValue((StringProperty) property, value); + } catch (JSONException e) { + try { + JSONObject object = data.getJSONObject(key); + if (object != null) + model.setValue((StringProperty) property, object.toString()); + } catch (JSONException e2) { + Log.e(ERROR_TAG, "Error reading JSON value with key " + key + " from JSON " + data, e); + } + Log.e(ERROR_TAG, "Error reading string value with key " + key + " from JSON " + data, e); + } + return null; + } +} diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/MakeChanges.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/MakeChanges.java index 9987dcf2a..638749bfa 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/MakeChanges.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/MakeChanges.java @@ -1,28 +1,18 @@ package com.todoroo.astrid.actfm.sync.messages; -import java.text.ParseException; import java.util.Iterator; -import org.json.JSONException; import org.json.JSONObject; import android.text.TextUtils; import android.util.Log; -import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.Property; -import com.todoroo.andlib.data.Property.DoubleProperty; -import com.todoroo.andlib.data.Property.IntegerProperty; -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.utility.DateUtilities; import com.todoroo.andlib.utility.Preferences; -import com.todoroo.astrid.actfm.sync.ActFmPreferenceService; import com.todoroo.astrid.dao.RemoteModelDao; import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.SyncFlags; -import com.todoroo.astrid.data.Task; @SuppressWarnings("nls") public class MakeChanges extends ServerToClientMessage { @@ -140,79 +130,5 @@ public class MakeChanges extends ServerToClientMessage } - private static class JSONChangeToPropertyVisitor implements PropertyVisitor { - private final AbstractModel model; - private final JSONObject data; - - public JSONChangeToPropertyVisitor(AbstractModel model, JSONObject data) { - this.model = model; - this.data = data; - } - - @Override - public Void visitInteger(Property property, String key) { - try { - int value = data.getInt(key); - model.setValue((IntegerProperty) property, value); - } catch (JSONException e) { - Log.e(ERROR_TAG, "Error reading int value with key " + key + " from JSON " + data, e); - } - return null; - } - - @Override - public Void visitLong(Property property, String key) { - try { - long value = data.optLong(key, 0); - if (property.checkFlag(Property.PROP_FLAG_USER_ID) && value == ActFmPreferenceService.userId()) - value = 0; - else if (property.checkFlag(Property.PROP_FLAG_DATE)) { - String valueString = data.getString(key); - try { - value = DateUtilities.parseIso8601(valueString).getTime(); - if (Task.DUE_DATE.equals(property)) { - boolean hasDueTime = valueString.endsWith("Z"); - value = Task.createDueDate(hasDueTime ? Task.URGENCY_SPECIFIC_DAY_TIME : Task.URGENCY_SPECIFIC_DAY, value); - } - } catch (ParseException e){ - value = 0; - } - } - model.setValue((LongProperty) property, value); - } catch (JSONException e) { - Log.e(ERROR_TAG, "Error reading long value with key " + key + " from JSON " + data, e); - } - return null; - } - - @Override - public Void visitDouble(Property property, String key) { - try { - double value = data.getDouble(key); - model.setValue((DoubleProperty) property, value); - } catch (JSONException e) { - Log.e(ERROR_TAG, "Error reading double value with key " + key + " from JSON " + data, e); - } - return null; - } - - @Override - public Void visitString(Property property, String key) { - try { - String value = data.getString(key); - model.setValue((StringProperty) property, value); - } catch (JSONException e) { - try { - JSONObject object = data.getJSONObject(key); - if (object != null) - model.setValue((StringProperty) property, object.toString()); - } catch (JSONException e2) { - Log.e(ERROR_TAG, "Error reading JSON value with key " + key + " from JSON " + data, e); - } - Log.e(ERROR_TAG, "Error reading string value with key " + key + " from JSON " + data, e); - } - return null; - } - } } diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/NameMaps.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/NameMaps.java index 522e53341..570c741d6 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/NameMaps.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/NameMaps.java @@ -122,12 +122,36 @@ public class NameMaps { TAG_DATA_PROPERTIES_SERVER_TO_LOCAL = AndroidUtilities.reverseMap(TAG_DATA_PROPERTIES_LOCAL_TO_SERVER); } - private static B mapColumnName(String table, String col, Map taskMap, Map tagMap) { + private static final Map, String> USER_PROPERTIES_LOCAL_TO_SERVER; + private static final Map> USER_COLUMN_NAMES_TO_PROPERTIES; + private static final Map USER_COLUMNS_LOCAL_TO_SERVER; + private static final Map> USER_PROPERTIES_SERVER_TO_LOCAL; + + static { + USER_PROPERTIES_LOCAL_TO_SERVER = new HashMap, String>(); + USER_COLUMN_NAMES_TO_PROPERTIES = new HashMap>(); + USER_COLUMNS_LOCAL_TO_SERVER = new HashMap(); + + putPropertyToServerName(User.UUID, "uuid", USER_PROPERTIES_LOCAL_TO_SERVER, USER_COLUMN_NAMES_TO_PROPERTIES, USER_COLUMNS_LOCAL_TO_SERVER, null, true); + putPropertyToServerName(User.EMAIL, "email", USER_PROPERTIES_LOCAL_TO_SERVER, USER_COLUMN_NAMES_TO_PROPERTIES, USER_COLUMNS_LOCAL_TO_SERVER, null, true); + putPropertyToServerName(User.PICTURE, "picture", USER_PROPERTIES_LOCAL_TO_SERVER, USER_COLUMN_NAMES_TO_PROPERTIES, USER_COLUMNS_LOCAL_TO_SERVER, null, true); + putPropertyToServerName(User.PUSHED_AT, "pushed_at", USER_PROPERTIES_LOCAL_TO_SERVER, USER_COLUMN_NAMES_TO_PROPERTIES, USER_COLUMNS_LOCAL_TO_SERVER, null, true); + putPropertyToServerName(User.FIRST_NAME, "first_name", USER_PROPERTIES_LOCAL_TO_SERVER, USER_COLUMN_NAMES_TO_PROPERTIES, USER_COLUMNS_LOCAL_TO_SERVER, null, true); + putPropertyToServerName(User.LAST_NAME, "last_name", USER_PROPERTIES_LOCAL_TO_SERVER, USER_COLUMN_NAMES_TO_PROPERTIES, USER_COLUMNS_LOCAL_TO_SERVER, null, true); + + + // Reverse the mapping to construct the server to local map + USER_PROPERTIES_SERVER_TO_LOCAL = AndroidUtilities.reverseMap(USER_PROPERTIES_LOCAL_TO_SERVER); + } + + private static B mapColumnName(String table, String col, Map taskMap, Map tagMap, Map userMap) { Map map = null; if (TABLE_ID_TASKS.equals(table)) map = taskMap; else if (TABLE_ID_TAGS.equals(table)) map = tagMap; + else if (TABLE_ID_USERS.equals(table)) + map = userMap; if (map == null) return null; @@ -147,15 +171,15 @@ public class NameMaps { } public static String localColumnNameToServerColumnName(String table, String localColumn) { - return mapColumnName(table, localColumn, TASK_COLUMNS_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER); + return mapColumnName(table, localColumn, TASK_COLUMNS_LOCAL_TO_SERVER, TAG_DATA_COLUMNS_LOCAL_TO_SERVER, USER_COLUMNS_LOCAL_TO_SERVER); } public static Property localColumnNameToProperty(String table, String localColumn) { - return mapColumnName(table, localColumn, TASK_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES); + return mapColumnName(table, localColumn, TASK_COLUMN_NAMES_TO_PROPERTIES, TAG_DATA_COLUMN_NAMES_TO_PROPERTIES, USER_COLUMN_NAMES_TO_PROPERTIES); } public static Property serverColumnNameToLocalProperty(String table, String serverColumn) { - return mapColumnName(table, serverColumn, TASK_PROPERTIES_SERVER_TO_LOCAL, TAG_DATA_PROPERTIES_SERVER_TO_LOCAL); + return mapColumnName(table, serverColumn, TASK_PROPERTIES_SERVER_TO_LOCAL, TAG_DATA_PROPERTIES_SERVER_TO_LOCAL, USER_PROPERTIES_SERVER_TO_LOCAL); } } diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/ServerToClientMessage.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/ServerToClientMessage.java index b9d940b14..062fdfa2d 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/ServerToClientMessage.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/ServerToClientMessage.java @@ -13,6 +13,7 @@ public abstract class ServerToClientMessage { public abstract void processMessage(); public static final String TYPE_MAKE_CHANGES = "MakeChanges"; + public static final String TYPE_USER_DATA = "UserData"; public static final String TYPE_ACKNOWLEDGE_CHANGE = "AcknowledgeChange"; public static final String TYPE_DOUBLE_CHECK = "DoubleCheck"; public static final String TYPE_DEBUG = "Debug"; @@ -29,6 +30,8 @@ public abstract class ServerToClientMessage { return instantiateMakeChanges(json); else if (TYPE_ACKNOWLEDGE_CHANGE.equals(type)) return new AcknowledgeChange(json); + else if (TYPE_USER_DATA.equals(type)) + return new UserData(json); else if (TYPE_DOUBLE_CHECK.equals(json)) return new DoubleCheck(json); else if (TYPE_DEBUG.equals(json)) diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/UserData.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/UserData.java new file mode 100644 index 000000000..252f68ac6 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/UserData.java @@ -0,0 +1,57 @@ +package com.todoroo.astrid.actfm.sync.messages; + +import java.util.Iterator; + +import org.json.JSONException; +import org.json.JSONObject; + +import android.util.Log; + +import com.todoroo.andlib.data.Property; +import com.todoroo.andlib.data.Property.StringProperty; +import com.todoroo.astrid.core.PluginServices; +import com.todoroo.astrid.dao.UserDao; +import com.todoroo.astrid.data.RemoteModel; +import com.todoroo.astrid.data.SyncFlags; +import com.todoroo.astrid.data.User; + +public class UserData extends ServerToClientMessage { + + private static final String ERROR_TAG = "actfm-user-data"; //$NON-NLS-1$ + + public UserData(JSONObject json) { + super(json); + } + + @Override + public void processMessage() { + UserDao userDao = PluginServices.getUserDao(); + try { + String uuid = json.getString("uuid"); //$NON-NLS-1$ + User model = new User(); + JSONChangeToPropertyVisitor visitor = new JSONChangeToPropertyVisitor(model, json); + Iterator keys = json.keys(); + while (keys.hasNext()) { + String column = keys.next(); + Property property = NameMaps.serverColumnNameToLocalProperty(NameMaps.TABLE_ID_USERS, column); + if (property != null) { // Unsupported property + property.accept(visitor, column); + } + } + + StringProperty uuidProperty = (StringProperty) NameMaps.serverColumnNameToLocalProperty(NameMaps.TABLE_ID_USERS, "uuid"); //$NON-NLS-1$ + if (!model.getSetValues().containsKey(uuidProperty.name)) + model.setValue(uuidProperty, uuid); + + if (model.getSetValues().size() > 0) { + if (userDao.update(RemoteModel.UUID_PROPERTY.eq(uuid), model) <= 0) { // If update doesn't update rows. create a new model + model.putTransitory(SyncFlags.ACTFM_SUPPRESS_OUTSTANDING_ENTRIES, true); + userDao.createNew(model); + } + } + } catch (JSONException e) { + Log.e(ERROR_TAG, "Error parsing UserData JSON " + json, e); //$NON-NLS-1$ + } + } + +} diff --git a/astrid/src/com/todoroo/astrid/dao/Database.java b/astrid/src/com/todoroo/astrid/dao/Database.java index 7555731ca..3f8a0a6ed 100644 --- a/astrid/src/com/todoroo/astrid/dao/Database.java +++ b/astrid/src/com/todoroo/astrid/dao/Database.java @@ -370,6 +370,8 @@ public class Database extends AbstractDatabase { database.execSQL(addColumnSql(Metadata.TABLE, Metadata.DELETION_DATE, visitor, "0")); database.execSQL(addColumnSql(User.TABLE, User.PUSHED_AT, visitor, null)); database.execSQL(addColumnSql(User.TABLE, User.UUID, visitor, null)); + database.execSQL(addColumnSql(User.TABLE, User.FIRST_NAME, visitor, null)); + database.execSQL(addColumnSql(User.TABLE, User.LAST_NAME, visitor, null)); } catch (SQLiteException e) { Log.e("astrid", "db-upgrade-" + oldVersion + "-" + newVersion, e); }