diff --git a/src/net/micode/notes/gtask/data/Node.java b/src/net/micode/notes/gtask/data/Node.java index 63950e0..f505e6c 100644 --- a/src/net/micode/notes/gtask/data/Node.java +++ b/src/net/micode/notes/gtask/data/Node.java @@ -19,8 +19,21 @@ package net.micode.notes.gtask.data; import android.database.Cursor; import org.json.JSONObject; - +/** + * Node 是一个抽象类,作为数据节点的基类,用于同步本地和远程数据。 + * 它定义了通用的同步操作和字段,并提供了需要子类实现的抽象方法。 + */ public abstract class Node { + +/** + * 同步动作类型常量,表示不同场景下的同步操作: + * - NONE: 无需同步 + * - ADD_REMOTE/LOCAL: 添加操作(远程/本地) + * - DEL_REMOTE/LOCAL: 删除操作(远程/本地) + * - UPDATE_REMOTE/LOCAL: 更新操作(远程/本地) + * - UPDATE_CONFLICT: 数据冲突 + * - ERROR: 同步错误 + */ public static final int SYNC_ACTION_NONE = 0; public static final int SYNC_ACTION_ADD_REMOTE = 1; @@ -38,37 +51,78 @@ public abstract class Node { public static final int SYNC_ACTION_UPDATE_CONFLICT = 7; public static final int SYNC_ACTION_ERROR = 8; +/** 节点在远程服务器上的唯一标识符 */ +private String mGid; - private String mGid; - - private String mName; - - private long mLastModified; - - private boolean mDeleted; - - public Node() { - mGid = null; - mName = ""; - mLastModified = 0; - mDeleted = false; - } +/** 节点名称 */ +private String mName; - public abstract JSONObject getCreateAction(int actionId); +/** 最后修改时间戳 */ +private long mLastModified; - public abstract JSONObject getUpdateAction(int actionId); +/** 是否被标记为删除 */ +private boolean mDeleted; +/** + * 默认构造函数,初始化节点的基本属性值。 + */ +public Node() { + mGid = null; + mName = ""; + mLastModified = 0; + mDeleted = false; +} +/** + * 获取创建操作的 JSON 对象,供同步使用。 + * + * @param actionId 操作 ID + * @return 创建操作的 JSON 对象 + */ +public abstract JSONObject getCreateAction(int actionId); - public abstract void setContentByRemoteJSON(JSONObject js); +/** + * 获取更新操作的 JSON 对象,供同步使用。 + * + * @param actionId 操作 ID + * @return 更新操作的 JSON 对象 + */ +public abstract JSONObject getUpdateAction(int actionId); - public abstract void setContentByLocalJSON(JSONObject js); +/** + * 从远程 JSON 设置节点内容。 + * + * @param js 远程 JSON 数据 + */ +public abstract void setContentByRemoteJSON(JSONObject js); - public abstract JSONObject getLocalJSONFromContent(); +/** + * 从本地 JSON 设置节点内容。 + * + * @param js 本地 JSON 数据 + */ +public abstract void setContentByLocalJSON(JSONObject js); - public abstract int getSyncAction(Cursor c); +/** + * 将当前节点内容转换为本地 JSON 数据。 + * + * @return 本地 JSON 数据 + */ +public abstract JSONObject getLocalJSONFromContent(); - public void setGid(String gid) { - this.mGid = gid; - } +/** + * 根据数据库游标获取同步操作类型。 + * + * @param c 数据库游标 + * @return 同步操作类型 + */ +public abstract int getSyncAction(Cursor c); +/** + * 设置远程唯一标识符 GID。 + * + * @param gid 新的 GID 值 + */ +public void setGid(String gid) { + this.mGid = gid; +} public void setName(String name) { this.mName = name; @@ -81,10 +135,14 @@ public abstract class Node { public void setDeleted(boolean deleted) { this.mDeleted = deleted; } - - public String getGid() { - return this.mGid; - } +/** + * 获取远程唯一标识符 GID。 + * + * @return mGid 当前节点的 GID + */ +public String getGid() { + return this.mGid; +} public String getName() { return this.mName; diff --git a/src/net/micode/notes/gtask/data/SqlData.java b/src/net/micode/notes/gtask/data/SqlData.java index d3ec3be..b96c2c2 100644 --- a/src/net/micode/notes/gtask/data/SqlData.java +++ b/src/net/micode/notes/gtask/data/SqlData.java @@ -33,18 +33,24 @@ import net.micode.notes.gtask.exception.ActionFailureException; import org.json.JSONException; import org.json.JSONObject; - - +/** + * SqlData 是用于操作 SQLite 数据库中的数据对象,支持从 JSON 设置内容、提交更改到数据库等功能。 + * 它主要用于本地与远程数据同步时的数据持久化操作。 + */ public class SqlData { - private static final String TAG = SqlData.class.getSimpleName(); +/** 日志标签,标识当前类名 */ +private static final String TAG = SqlData.class.getSimpleName(); - private static final int INVALID_ID = -99999; +/** 表示无效的 ID 值 */ +private static final int INVALID_ID = -99999; - public static final String[] PROJECTION_DATA = new String[] { - DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, - DataColumns.DATA3 - }; +/** 查询语句中使用的列投影 */ +public static final String[] PROJECTION_DATA = new String[] { + DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, + DataColumns.DATA3 +}; +/** 列索引常量 */ public static final int DATA_ID_COLUMN = 0; public static final int DATA_MIME_TYPE_COLUMN = 1; @@ -55,22 +61,34 @@ public class SqlData { public static final int DATA_CONTENT_DATA_3_COLUMN = 4; + /** 内容解析器,用于访问 ContentProvider */ private ContentResolver mContentResolver; + /** 是否是新建的数据项 */ private boolean mIsCreate; + /** 数据项 ID */ private long mDataId; + /** 数据项 MIME 类型 */ private String mDataMimeType; + /** 数据内容 */ private String mDataContent; + /** 数据字段 DATA1 的值 */ private long mDataContentData1; + /** 数据字段 DATA3 的值 */ private String mDataContentData3; + /** 存储差异内容的 ContentValues 对象 */ private ContentValues mDiffDataValues; - + /** + * 创建一个新的 SqlData 实例,用于插入新数据。 + * + * @param context 上下文对象 + */ public SqlData(Context context) { mContentResolver = context.getContentResolver(); mIsCreate = true; @@ -81,7 +99,12 @@ public class SqlData { mDataContentData3 = ""; mDiffDataValues = new ContentValues(); } - + /** + * 从游标创建一个 SqlData 实例,用于更新已有数据。 + * + * @param context 上下文对象 + * @param c 数据库游标 + */ public SqlData(Context context, Cursor c) { mContentResolver = context.getContentResolver(); mIsCreate = false; @@ -96,7 +119,12 @@ public class SqlData { mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); } - +/** + * 从 JSON 对象加载数据到当前 SqlData 实例。 + * + * @param js JSON 数据源 + * @throws JSONException 如果解析失败 + */ public void setContent(JSONObject js) throws JSONException { long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; if (mIsCreate || mDataId != dataId) { @@ -129,7 +157,12 @@ public class SqlData { } mDataContentData3 = dataContentData3; } - +/** + * 将当前 SqlData 的内容转换为 JSON 对象。 + * + * @return 包含数据的 JSON 对象 + * @throws JSONException 如果转换失败 + */ public JSONObject getContent() throws JSONException { if (mIsCreate) { Log.e(TAG, "it seems that we haven't created this in database yet"); @@ -143,7 +176,13 @@ public class SqlData { js.put(DataColumns.DATA3, mDataContentData3); return js; } - +/** + * 提交数据变更到数据库。 + * + * @param noteId 笔记 ID + * @param validateVersion 是否验证版本号 + * @param version 版本号 + */ public void commit(long noteId, boolean validateVersion, long version) { if (mIsCreate) { diff --git a/src/net/micode/notes/gtask/data/SqlNote.java b/src/net/micode/notes/gtask/data/SqlNote.java index 79a4095..24f893b 100644 --- a/src/net/micode/notes/gtask/data/SqlNote.java +++ b/src/net/micode/notes/gtask/data/SqlNote.java @@ -37,12 +37,18 @@ import org.json.JSONObject; import java.util.ArrayList; - +/** + * SqlNote 是用于操作 SQLite 数据库中的笔记数据对象,支持从 JSON 设置内容、提交更改到数据库等功能。 + * 它主要用于本地与远程数据同步时的数据持久化操作。 + */ public class SqlNote { - private static final String TAG = SqlNote.class.getSimpleName(); + /** 日志标签,标识当前类名 */ +private static final String TAG = SqlNote.class.getSimpleName(); - private static final int INVALID_ID = -99999; +/** 表示无效的 ID 值 */ +private static final int INVALID_ID = -99999; +/** 查询语句中使用的列投影数组 */ public static final String[] PROJECTION_NOTE = new String[] { NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID, NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE, @@ -86,42 +92,64 @@ public class SqlNote { public static final int VERSION_COLUMN = 16; - private Context mContext; - - private ContentResolver mContentResolver; + /** 上下文对象 */ +private Context mContext; - private boolean mIsCreate; +/** 内容解析器,用于访问 ContentProvider */ +private ContentResolver mContentResolver; - private long mId; +/** 是否是新建的笔记项 */ +private boolean mIsCreate; - private long mAlertDate; +/** 笔记 ID */ +private long mId; - private int mBgColorId; +/** 警告时间 */ +private long mAlertDate; - private long mCreatedDate; +/** 背景颜色 ID */ +private int mBgColorId; - private int mHasAttachment; +/** 创建时间 */ +private long mCreatedDate; - private long mModifiedDate; +/** 是否有附件 */ +private int mHasAttachment; - private long mParentId; +/** 最后修改时间 */ +private long mModifiedDate; - private String mSnippet; +/** 父节点 ID */ +private long mParentId; - private int mType; +/** 摘要内容 */ +private String mSnippet; - private int mWidgetId; +/** 类型(如普通笔记、文件夹等) */ +private int mType; - private int mWidgetType; +/** 小部件 ID */ +private int mWidgetId; - private long mOriginParent; +/** 小部件类型 */ +private int mWidgetType; - private long mVersion; +/** 原始父节点 ID */ +private long mOriginParent; - private ContentValues mDiffNoteValues; +/** 版本号,用于同步控制 */ +private long mVersion; - private ArrayList mDataList; +/** 存储差异内容的 ContentValues 对象 */ +private ContentValues mDiffNoteValues; +/** 当前笔记包含的数据列表 */ +private ArrayList mDataList; +/** + * 创建一个新的 SqlNote 实例,用于插入新笔记。 + * + * @param context 上下文对象 + */ public SqlNote(Context context) { mContext = context; mContentResolver = context.getContentResolver(); @@ -142,7 +170,12 @@ public class SqlNote { mDiffNoteValues = new ContentValues(); mDataList = new ArrayList(); } - +/** + * 从游标创建一个 SqlNote 实例,用于更新已有笔记。 + * + * @param context 上下文对象 + * @param c 数据库游标 + */ public SqlNote(Context context, Cursor c) { mContext = context; mContentResolver = context.getContentResolver(); @@ -165,7 +198,11 @@ public class SqlNote { mDiffNoteValues = new ContentValues(); } - +/** + * 从游标加载笔记数据。 + * + * @param c 数据库游标 + */ private void loadFromCursor(long id) { Cursor c = null; try { @@ -184,7 +221,11 @@ public class SqlNote { c.close(); } } - +/** + * 从指定 ID 加载笔记数据。 + * + * @param id 笔记 ID + */ private void loadFromCursor(Cursor c) { mId = c.getLong(ID_COLUMN); mAlertDate = c.getLong(ALERTED_DATE_COLUMN); @@ -225,7 +266,12 @@ public class SqlNote { c.close(); } } - +/** + * 从 JSON 设置笔记内容,包括元信息和子数据。 + * + * @param js JSON 数据源 + * @return 是否设置成功 + */ public boolean setContent(JSONObject js) { try { JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); diff --git a/src/net/micode/notes/gtask/data/Task.java b/src/net/micode/notes/gtask/data/Task.java index 6a19454..69b571b 100644 --- a/src/net/micode/notes/gtask/data/Task.java +++ b/src/net/micode/notes/gtask/data/Task.java @@ -30,30 +30,44 @@ import net.micode.notes.tool.GTaskStringUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; - - +/** + * Task 是 Node 的子类,表示一个任务条目,用于同步本地和远程的任务数据。 + * 它实现了 Node 中定义的抽象方法,并提供了与任务相关的功能如完成状态、备注等。 + */ public class Task extends Node { - private static final String TAG = Task.class.getSimpleName(); - - private boolean mCompleted; - - private String mNotes; +/** 日志标签,标识当前类名 */ +private static final String TAG = Task.class.getSimpleName(); + /** 是否已完成 */ +private boolean mCompleted; - private JSONObject mMetaInfo; +/** 备注信息 */ +private String mNotes; - private Task mPriorSibling; +/** 元数据信息(JSON 格式) */ +private JSONObject mMetaInfo; - private TaskList mParent; - - public Task() { - super(); - mCompleted = false; - mNotes = null; - mPriorSibling = null; - mParent = null; - mMetaInfo = null; - } +/** 上一个同级任务 */ +private Task mPriorSibling; +/** 父任务列表 */ +private TaskList mParent; + /** + * 创建一个新的 Task 实例,初始化默认值。 + */ +public Task() { + super(); + mCompleted = false; + mNotes = null; + mPriorSibling = null; + mParent = null; + mMetaInfo = null; +} +/** + * 生成创建任务的远程同步操作 JSON 对象。 + * + * @param actionId 操作 ID + * @return 包含创建操作信息的 JSON 对象 + */ public JSONObject getCreateAction(int actionId) { JSONObject js = new JSONObject(); @@ -102,7 +116,12 @@ public class Task extends Node { return js; } - +/** + * 生成更新任务的远程同步操作 JSON 对象。 + * + * @param actionId 操作 ID + * @return 包含更新操作信息的 JSON 对象 + */ public JSONObject getUpdateAction(int actionId) { JSONObject js = new JSONObject(); @@ -257,6 +276,12 @@ public class Task extends Node { } } } + /** + * 根据游标判断当前任务需要执行的同步动作类型。 + * + * @param c 数据库游标 + * @return 同步动作类型(SYNC_ACTION_XXX) + */ public int getSyncAction(Cursor c) { try { @@ -310,7 +335,11 @@ public class Task extends Node { return SYNC_ACTION_ERROR; } - +/** + * 判断该任务是否值得保存(非空任务)。 + * + * @return 是否值得保存 + */ public boolean isWorthSaving() { return mMetaInfo != null || (getName() != null && getName().trim().length() > 0) || (getNotes() != null && getNotes().trim().length() > 0); diff --git a/src/net/micode/notes/gtask/data/TaskList.java b/src/net/micode/notes/gtask/data/TaskList.java index 4ea21c5..09045ca 100644 --- a/src/net/micode/notes/gtask/data/TaskList.java +++ b/src/net/micode/notes/gtask/data/TaskList.java @@ -29,14 +29,21 @@ import org.json.JSONObject; import java.util.ArrayList; - +/** + * TaskList 是 Node 的子类,表示一个任务列表(即任务组),用于同步本地和远程的任务列表数据。 + * 它管理一组 Task 子项,并提供了添加、删除、移动任务的方法。 + */ public class TaskList extends Node { - private static final String TAG = TaskList.class.getSimpleName(); - - private int mIndex; - - private ArrayList mChildren; - + /** 日志标签,标识当前类名 */ +private static final String TAG = TaskList.class.getSimpleName(); +/** 列表在远程服务器上的索引位置 */ +private int mIndex; + +/** 当前任务列表中的子任务集合 */ +private ArrayList mChildren; +/** + * 创建一个新的 TaskList 实例,初始化子任务列表和索引。 + */ public TaskList() { super(); mChildren = new ArrayList(); @@ -73,7 +80,12 @@ public class TaskList extends Node { return js; } - +/** + * 生成更新任务列表的远程同步操作 JSON 对象。 + * + * @param actionId 操作 ID + * @return 包含更新操作信息的 JSON 对象 + */ public JSONObject getUpdateAction(int actionId) { JSONObject js = new JSONObject(); @@ -102,7 +114,11 @@ public class TaskList extends Node { return js; } - +/** + * 从远程 JSON 设置任务列表内容(如名称、ID、最后修改时间等)。 + * + * @param js 远程 JSON 数据 + */ public void setContentByRemoteJSON(JSONObject js) { if (js != null) { try { @@ -128,7 +144,11 @@ public class TaskList extends Node { } } } - +/** + * 从本地 JSON 设置任务列表内容(通常从数据库加载)。 + * + * @param js 本地 JSON 数据 + */ public void setContentByLocalJSON(JSONObject js) { if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) { Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); @@ -156,7 +176,11 @@ public class TaskList extends Node { e.printStackTrace(); } } - +/** + * 将当前任务列表内容转换为本地 JSON 格式,用于存储或同步。 + * + * @return 包含任务列表内容的 JSON 对象 + */ public JSONObject getLocalJSONFromContent() { try { JSONObject js = new JSONObject(); @@ -182,7 +206,12 @@ public class TaskList extends Node { return null; } } - +/** + * 根据游标判断当前任务列表需要执行的同步动作类型。 + * + * @param c 数据库游标 + * @return 同步动作类型(SYNC_ACTION_XXX) + */ public int getSyncAction(Cursor c) { try { if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) { @@ -219,7 +248,12 @@ public class TaskList extends Node { public int getChildTaskCount() { return mChildren.size(); } - +/** + * 添加一个子任务到任务列表末尾,并设置其父级和前一兄弟节点。 + * + * @param task 要添加的任务 + * @return 是否成功添加 + */ public boolean addChildTask(Task task) { boolean ret = false; if (task != null && !mChildren.contains(task)) { @@ -233,7 +267,13 @@ public class TaskList extends Node { } return ret; } - +/** + * 在指定位置插入一个子任务,并调整兄弟节点关系。 + * + * @param task 要添加的任务 + * @param index 插入的位置 + * @return 是否成功插入 + */ public boolean addChildTask(Task task, int index) { if (index < 0 || index > mChildren.size()) { Log.e(TAG, "add child task: invalid index"); @@ -280,7 +320,13 @@ public class TaskList extends Node { } return ret; } - +/** + * 将指定任务移动到新的位置。 + * + * @param task 要移动的任务 + * @param index 新的位置 + * @return 是否成功移动 + */ public boolean moveChildTask(Task task, int index) { if (index < 0 || index >= mChildren.size()) { @@ -308,11 +354,21 @@ public class TaskList extends Node { } return null; } - +/** + * 获取指定任务在子任务列表中的索引。 + * + * @param task 子任务 + * @return 索引位置,若未找到则返回 -1 + */ public int getChildTaskIndex(Task task) { return mChildren.indexOf(task); } - +/** + * 根据索引获取子任务。 + * + * @param index 索引位置 + * @return 子任务对象,若索引无效则返回 null + */ public Task getChildTaskByIndex(int index) { if (index < 0 || index >= mChildren.size()) { Log.e(TAG, "getTaskByIndex: invalid index"); @@ -321,6 +377,11 @@ public class TaskList extends Node { return mChildren.get(index); } +/** + * 获取所有子任务的列表。 + * + * @return 子任务集合 + */ public Task getChilTaskByGid(String gid) { for (Task task : mChildren) { if (task.getGid().equals(gid))