zhangying
git1 7 hours ago
parent 3de7521689
commit 8ad87c46db

@ -0,0 +1,747 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.data;
// 引入 Android 数据库操作类Cursor 用于处理数据库查询结果
import android.database.Cursor;
// 引入 Android 的日志工具类
import android.util.Log;
// 引入自定义的 Notes 数据模型,特别是 NoteColumns 类,包含笔记相关的列名
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
// 引入 GTask 的异常处理类,用于处理 GTask 相关操作失败的情况
import net.micode.notes.gtask.exception.ActionFailureException;
// 引入 GTask 的字符串工具类,可能提供与 GTask 数据同步的字符串处理功能
import net.micode.notes.tool.GTaskStringUtils;
// 引入 JSON 处理库,处理 JSON 格式的数据
import org.json.JSONException;
import org.json.JSONObject;
// 引入 ArrayList 类,用于存储动态大小的列表
import java.util.ArrayList;
/*
private static final String TAG = TaskList.class.getSimpleName();
TAG便getSimpleName() TaskList
private int mIndex;
mIndex
1
private ArrayList<Task> mChildren;
mChildren ArrayList
public TaskList()
TaskList Node super(),
mChildren ArrayList
mIndex 1*/
public class TaskList extends Node {
// 用于日志记录的 TAG便于调试时查看输出
private static final String TAG = TaskList.class.getSimpleName();
// 任务列表的索引,用于区分不同的任务列表
private int mIndex;
// 存储任务列表中所有任务对象的 ArrayList
private ArrayList<Task> mChildren;
// 构造函数,初始化任务列表对象
public TaskList() {
// 调用父类 Node 的构造函数
super();
// 初始化任务列表
mChildren = new ArrayList<Task>();
// 设置默认索引为 1
mIndex = 1;
}
/*
public JSONObject getCreateAction(int actionId)
JSON JSON GTask
actionId ID
JSONObject js = new JSONObject();
JSONObject
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
JSON action_type "create"
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
JSON action_id actionId ID
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex);
JSON index mIndex
JSONObject entity = new JSONObject();
JSONObject
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
getName() Node
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");
ID使 "null"
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE, GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
"group"
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
entity JSON JSON js entity_delta
JSON JSONException
ActionFailureException
return js;
JSON
*/
/**
* JSON
*
* @param actionId ID
* @return JSONObject JSON
*/
public JSONObject getCreateAction(int actionId) {
// 创建一个新的 JSON 对象,用于存储创建任务列表的相关数据
JSONObject js = new JSONObject();
try {
// 设置 action_type 为 "create",表示这是一个创建任务列表的动作
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
// 设置 action_id表示这次创建任务的唯一标识符
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// 设置任务列表的索引,这个索引用于区分任务列表
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex);
// 创建一个子 JSON 对象,表示任务实体的变动信息
JSONObject entity = new JSONObject();
// 设置任务列表的名称
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
// 设置任务列表的创建者 ID这里使用 "null" 字符串表示未知或没有指定创建者
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");
// 设置任务实体的类型,这里是任务列表组的类型
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
// 将任务实体信息放入 JSON 对象中
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) {
// 捕获 JSON 异常,打印错误日志并抛出自定义异常
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate tasklist-create jsonobject");
}
// 返回生成的 JSON 对象
return js;
}
}
/*js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
JSON action_type "update"
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
action_id actionId
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
idgetGid()
JSONObject entity = new JSONObject();
JSONObject
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
entity JSON getName()
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
entity JSON getDeleted()
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
entity JSON js entity_delta
JSON JSONException ActionFailureException
JSON
JSON js*/
public JSONObject getUpdateAction(int actionId) {
// 创建一个空的 JSON 对象,用于存放更新请求的数据
JSONObject js = new JSONObject();
try {
// 设置 JSON 中的 action_type 字段,表示这是一个更新操作
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
// 设置 JSON 中的 action_id 字段,表示此次更新操作的唯一标识符
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// 设置任务列表的唯一标识符 id
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
// 创建一个新的 JSON 对象表示任务实体的变动信息entity_delta
JSONObject entity = new JSONObject();
// 设置任务列表的名称,使用当前对象的 `getName()` 方法获取任务列表名称
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
// 设置任务列表的删除状态,使用当前对象的 `getDeleted()` 方法获取删除状态
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
// 将包含任务实体信息的 `entity` 对象放入主 JSON 对象中
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) {
// 捕获 JSON 处理过程中的异常,打印错误信息并抛出自定义的 ActionFailureException
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate tasklist-update jsonobject");
}
// 返回生成的 JSON 对象,包含了更新任务列表所需的所有信息
return js;
}
/* if (js != null)
JSON js
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); }
JSON id setGid() ID JSON ID
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); }
JSON last_modified setLastModified() JSON last_modified
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); }
JSON name setName() JSON name
JSON JSONException ActionFailureException JSON
setGidsetLastModified setName */
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) { // 确保传入的 JSON 对象不为空
try {
// 如果 JSON 中包含任务列表的唯一标识符 (id),则更新当前对象的 GID
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
// 如果 JSON 中包含任务列表的最后修改时间 (last_modified),则更新当前对象的最后修改时间
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// 如果 JSON 中包含任务列表的名称 (name),则更新当前对象的名称
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
}
} catch (JSONException e) {
// 捕获 JSON 处理过程中的异常,打印错误信息并抛出自定义的 ActionFailureException
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to get tasklist content from jsonobject");
}
}
}
/* JSON
JSONObject js folder
getName() folderName
MIUI
MIUI MIUI_FOLDER_PREFFIX
SNIPPET
folderName folder JSON "SNIPPET"
folderName Notes.TYPE_SYSTEM
Notes.TYPE_FOLDER
JSON
folder js META_HEAD_NOTE JSON
JSON JSONException null*/
public JSONObject getLocalJSONFromContent() {
try {
// 创建一个空的 JSON 对象,用于存放结果数据
JSONObject js = new JSONObject();
// 创建一个空的 JSON 对象,用于存放文件夹信息
JSONObject folder = new JSONObject();
// 获取当前任务列表的名称
String folderName = getName();
// 如果任务列表名称以 MIUI 文件夹前缀开头,则去除前缀
if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX))
folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(),
folderName.length());
// 将任务列表名称作为文件夹的“SNIPPET”字段放入 folder 对象中
folder.put(NoteColumns.SNIPPET, folderName);
// 判断任务列表名称,如果是默认文件夹或电话笔记文件夹,则设置类型为系统类型
if (folderName.equals(GTaskStringUtils.FOLDER_DEFAULT)
|| folderName.equals(GTaskStringUtils.FOLDER_CALL_NOTE))
// 类型为系统
folder.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
else
// 否则类型为普通文件夹
folder.put(NoteColumns.TYPE, Notes.TYPE_FOLDER);
// 将 folder 对象放入主 JSON 对象中,键为 "META_HEAD_NOTE"
js.put(GTaskStringUtils.META_HEAD_NOTE, folder);
// 返回构建好的 JSON 对象
return js;
} catch (JSONException e) {
// 捕获 JSON 处理中的异常,打印错误日志并返回 null
Log.e(TAG, e.toString());
e.printStackTrace();
return null;
}
}
/*
LOCAL_MODIFIED_COLUMN 0
LOCAL_MODIFIED_COLUMN == 0 SYNC_ID_COLUMN ID
getLastModified()
SYNC_ACTION_NONE
SYNC_ACTION_UPDATE_LOCAL
LOCAL_MODIFIED_COLUMN != 0 GTask ID (GTASK_ID_COLUMN)
GTask ID
SYNC_ACTION_ERROR ID
GTask ID ID
ID SYNC_ACTION_UPDATE_REMOTE
SYNC_ACTION_UPDATE_REMOTE
SYNC_ACTION_ERROR */
public int getSyncAction(Cursor c) {
try {
// 如果数据库中没有本地修改LOCAL_MODIFIED_COLUMN == 0
if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) {
// 如果本地和远程的同步 ID 相同(没有更新)
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
// 本地和远程都没有更新,不需要同步
return SYNC_ACTION_NONE;
} else {
// 远程数据有更新,需要将远程数据同步到本地
return SYNC_ACTION_UPDATE_LOCAL;
}
} else {
// 如果有本地修改
// 检查 GTask ID 是否匹配
if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) {
Log.e(TAG, "gtask id doesn't match");
// 如果 GTask ID 不匹配,返回错误
return SYNC_ACTION_ERROR;
}
// 如果同步 ID 与本地修改时间相同,说明只有本地修改
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
// 本地修改需要更新远程数据
return SYNC_ACTION_UPDATE_REMOTE;
} else {
// 对于文件夹冲突的情况,选择应用本地修改
return SYNC_ACTION_UPDATE_REMOTE;
}
}
} catch (Exception e) {
// 捕获任何异常,打印日志并返回错误
Log.e(TAG, e.toString());
e.printStackTrace();
}
// 默认返回错误,表示同步操作失败
return SYNC_ACTION_ERROR;
}
// mChildren 是一个存储子任务的集合(通常是 List<Task> 类型),该方法返回其当前大小(即子任务的数量)。
public int getChildTaskCount() {
// 返回子任务的数量,即 mChildren 列表的元素数量
return mChildren.size();
}
/*
task mChildren
mChildren.add(task) mChildren ret
priorSibling:
mChildren mChildren
parent
ret
*/
public boolean addChildTask(Task task) {
boolean ret = false;
// 确保任务不为空且尚未添加到子任务列表中
if (task != null && !mChildren.contains(task)) {
// 添加任务到子任务列表
ret = mChildren.add(task);
if (ret) {
// 如果添加成功,需要设置该任务的 priorSibling前置兄弟任务和 parent父任务
// 设置前置兄弟任务
task.setPriorSibling(mChildren.isEmpty() ? null : mChildren.get(mChildren.size() - 1));
// 设置当前任务作为任务的父任务
task.setParent(this);
}
}
// 返回添加任务是否成功
return ret;
}
/*
index 0 mChildren
false
task mChildren task pos == -1
mChildren.add(index, task)
0
true
*/
public boolean addChildTask(Task task, int index) {
// 检查索引是否合法
if (index < 0 || index > mChildren.size()) {
// 如果索引不合法,打印错误日志
Log.e(TAG, "add child task: invalid index");
// 返回 false表示添加失败
return false;
}
// 查找任务在当前子任务列表中的位置
int pos = mChildren.indexOf(task);
// 确保任务不为空,并且任务不在列表中
if (task != null && pos == -1) {
// 在指定索引位置添加任务
mChildren.add(index, task);
// 更新前置任务和后置任务
Task preTask = null;
Task afterTask = null;
// 如果索引不是 0则获取前一个任务
if (index != 0)
preTask = mChildren.get(index - 1);
// 如果索引不是最后一个,则获取下一个任务
if (index != mChildren.size() - 1)
afterTask = mChildren.get(index + 1);
// 设置当前任务的前置兄弟任务
task.setPriorSibling(preTask);
// 如果存在后置任务,设置后置任务的前置兄弟为当前任务
if (afterTask != null)
afterTask.setPriorSibling(task);
}
// 返回 true表示任务成功添加
return true;
}
/*
使 mChildren.indexOf(task)
mChildren.remove(task)
priorSibling parent null
priorSibling使
true false
*/
public boolean removeChildTask(Task task) {
boolean ret = false;
// 查找任务在子任务列表中的索引
int index = mChildren.indexOf(task);
// 如果任务存在于子任务列表中
if (index != -1) {
// 移除该任务
ret = mChildren.remove(task);
// 如果移除成功
if (ret) {
// 重置任务的 priorSibling前置兄弟任务和 parent父任务
task.setPriorSibling(null);
task.setParent(null);
// 更新任务列表中的其他任务
// 如果移除的任务不是最后一个
if (index != mChildren.size()) {
mChildren.get(index).setPriorSibling(
// 更新后续任务的前置兄弟任务
index == 0 ? null : mChildren.get(index - 1));
}
}
}
// 返回任务是否成功移除
return ret;
}
/*
使 mChildren.indexOf(task)
true
removeChildTask(task) addChildTask(task, index)
true false
*/
public boolean moveChildTask(Task task, int index) {
// 检查索引是否有效
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "move child task: invalid index");
// 如果索引无效,打印错误日志并返回 false
return false;
}
// 查找任务在子任务列表中的位置
int pos = mChildren.indexOf(task);
// 如果任务不在列表中
if (pos == -1) {
Log.e(TAG, "move child task: the task should in the list");
// 返回 false
return false;
}
// 如果任务已经在目标位置
if (pos == index)
// 不需要移动,直接返回 true
return true;
// 移除任务并将其添加到新的索引位置
// 调用 removeChildTask 和 addChildTask 方法进行移动
return (removeChildTask(task) && addChildTask(task, index));
}
/*
使 for mChildren
t.getGid().equals(gid) gid gid
null
*/
public Task findChildTaskByGid(String gid) {
// 遍历子任务列表
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
// 如果任务的 gid 与指定的 gid 匹配
if (t.getGid().equals(gid)) {
// 返回找到的任务
return t;
}
}
// 如果没有找到,返回 null
return null;
}
/*
mChildren.indexOf(task)
*/
public int getChildTaskIndex(Task task) {
// 返回任务在子任务列表中的索引
return mChildren.indexOf(task);
}
/*
mChildren.get(index) null
*/
public Task getChildTaskByIndex(int index) {
// 检查索引是否有效
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "getTaskByIndex: invalid index");
// 如果索引无效,返回 null
return null;
}
// 返回指定索引位置的任务
return mChildren.get(index);
}
/*
使 for-each mChildren
gid gid
null
*/
public Task getChilTaskByGid(String gid) {
// 遍历子任务列表
for (Task task : mChildren) {
// 如果任务的 gid 匹配
if (task.getGid().equals(gid))
// 返回匹配的任务
return task;
}
// 如果没有找到,返回 null
return null;
}
//返回子任务列表:直接返回存储子任务的 mChildren 列表。
public ArrayList<Task> getChildTaskList() {
// 返回子任务列表
return this.mChildren;
}
//设置索引:将传入的 index 值设置为当前任务的索引。
public void setIndex(int index) {
// 设置当前任务的索引
this.mIndex = index;
}
//返回索引:返回当前任务的 mIndex 值。
public int getIndex() {
// 返回当前任务的索引
return this.mIndex;
}
}
Loading…
Cancel
Save