You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xiaomi/TaskList.java

381 lines
14 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) 2010 - 2011, The MiCode Open Source Community (www.micode.net)
*
* 遵循 Apache 许可证 2.0 版(“许可证”);
* 除非遵守许可证,否则不得使用此文件。
* 你可以在以下网址获取许可证副本:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 除非适用法律要求或书面同意,
* 根据许可证分发的软件按“原样”分发,
* 不附带任何明示或暗示的保证或条件。
* 请参阅许可证,了解具体的权限和限制。
*/
package net.micode.notes.gtask.data;
import android.database.Cursor;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.gtask.exception.ActionFailureException;
import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
// TaskList 类继承自 Node 类,用于表示任务列表相关的数据和操作
public class TaskList extends Node {
// 用于日志记录的标签,使用类的简单名称
private static final String TAG = TaskList.class.getSimpleName();
// 任务列表的索引
private int mIndex;
// 存储任务列表中的任务
private ArrayList<Task> mChildren;
// 构造函数,初始化任务列表
public TaskList() {
super(); // 调用父类的构造函数
mChildren = new ArrayList<Task>(); // 初始化任务列表
mIndex = 1; // 设置默认索引为 1
}
// 获取用于创建任务列表的 JSON 对象
public JSONObject getCreateAction(int actionId) {
JSONObject js = new JSONObject();
try {
// 设置操作类型为创建
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
// 设置操作 ID
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// 设置任务列表的索引
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex);
// 设置任务列表实体的变化信息
JSONObject entity = new JSONObject();
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate tasklist-create jsonobject");
}
return js;
}
// 获取用于更新任务列表的 JSON 对象
public JSONObject getUpdateAction(int actionId) {
JSONObject js = new JSONObject();
try {
// 设置操作类型为更新
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
// 设置操作 ID
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// 设置任务列表的 ID
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
// 设置任务列表实体的变化信息
JSONObject entity = new JSONObject();
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate tasklist-update jsonobject");
}
return js;
}
// 根据远程 JSON 数据设置任务列表的内容
public void setContentByRemoteJSON(JSONObject js) {
if (js!= null) {
try {
// 如果 JSON 数据包含任务列表 ID设置任务列表 ID
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
// 如果 JSON 数据包含最后修改时间,设置最后修改时间
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// 如果 JSON 数据包含任务列表名称,设置任务列表名称
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to get tasklist content from jsonobject");
}
}
}
// 根据本地 JSON 数据设置任务列表的内容
public void setContentByLocalJSON(JSONObject js) {
if (js == null ||!js.has(GTaskStringUtils.META_HEAD_NOTE)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}
try {
// 获取 JSON 数据中的文件夹信息
JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
// 如果文件夹类型是普通文件夹
if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) {
// 获取文件夹摘要信息并设置任务列表名称
String name = folder.getString(NoteColumns.SNIPPET);
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + name);
}
// 如果文件夹类型是系统文件夹
else if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) {
// 如果是根文件夹
if (folder.getLong(NoteColumns.ID) == Notes.ID_ROOT_FOLDER)
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT);
// 如果是通话记录文件夹
else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER)
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX
+ GTaskStringUtils.FOLDER_CALL_NOTE);
else
Log.e(TAG, "invalid system folder");
} else {
Log.e(TAG, "error type");
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
// 从任务列表内容中获取本地 JSON 对象
public JSONObject getLocalJSONFromContent() {
try {
JSONObject js = new JSONObject();
JSONObject folder = new JSONObject();
// 获取任务列表名称
String folderName = getName();
// 如果名称以特定前缀开头,去掉前缀
if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX))
folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(),
folderName.length());
// 设置文件夹摘要信息
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);
// 将文件夹信息放入 JSON 对象
js.put(GTaskStringUtils.META_HEAD_NOTE, folder);
return js;
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
return null;
}
}
// 根据数据库游标获取任务列表的同步操作类型
public int getSyncAction(Cursor c) {
try {
// 如果本地没有修改
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");
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;
}
// 获取任务列表中任务的数量
public int getChildTaskCount() {
return mChildren.size();
}
// 向任务列表中添加一个任务
public boolean addChildTask(Task task) {
boolean ret = false;
// 如果任务不为空且任务列表中不包含该任务
if (task!= null &&!mChildren.contains(task)) {
// 将任务添加到任务列表
ret = mChildren.add(task);
if (ret) {
// 设置任务的前一个兄弟任务和所属任务列表
task.setPriorSibling(mChildren.isEmpty()? null : mChildren
.get(mChildren.size() - 1));
task.setParent(this);
}
}
return ret;
}
// 在指定索引位置向任务列表中添加一个任务
public boolean addChildTask(Task task, int index) {
if (index < 0 || index > mChildren.size()) {
Log.e(TAG, "add child task: invalid index");
return false;
}
int pos = mChildren.indexOf(task);
// 如果任务不为空且任务列表中不包含该任务
if (task!= null && pos == -1) {
// 在指定索引位置添加任务
mChildren.add(index, task);
// 更新任务列表中的任务关系
Task preTask = null;
Task afterTask = null;
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);
}
return true;
}
// 从任务列表中移除一个任务
public boolean removeChildTask(Task task) {
boolean ret = false;
// 获取任务在任务列表中的索引
int index = mChildren.indexOf(task);
// 如果任务存在于任务列表中
if (index!= -1) {
// 从任务列表中移除任务
ret = mChildren.remove(task);
if (ret) {
// 重置任务的前一个兄弟任务和所属任务列表
task.setPriorSibling(null);
task.setParent(null);
// 更新任务列表中的任务关系
if (index!= mChildren.size()) {
mChildren.get(index).setPriorSibling(
index == 0? null : mChildren.get(index - 1));
}
}
}
return ret;
}
// 在任务列表中移动一个任务到指定索引位置
public boolean moveChildTask(Task task, int index) {
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "move child task: invalid index");
return false;
}
int pos = mChildren.indexOf(task);
// 如果任务不存在于任务列表中
if (pos == -1) {
Log.e(TAG, "move child task: the task should in the list");
return false;
}
// 如果任务当前位置和目标位置相同,直接返回 true
if (pos == index)
return true;
// 先移除任务,再在指定位置添加任务
return (removeChildTask(task) && addChildTask(task, index));
}
// 根据任务的 GID 在任务列表中查找任务
public Task findChildTaskByGid(String gid) {
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
// 如果找到匹配 GID 的任务,返回该任务
if (t.getGid().equals(gid)) {
return t;
}
}
return null;
}
// 获取任务在任务列表中的索引
public int getChildTaskIndex(Task task) {
return mChildren.indexOf(task);
}
// 根据索引获取任务列表中的任务
public Task getChildTaskByIndex(int index) {
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "getTaskByIndex: invalid index");
return null;
}
// 返回指定索引位置的任务
return mChildren.get(index);
}
// 根据任务的 GID 获取任务列表中的任务(方法名拼写错误,应为 getChildTaskByGid
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) {
// 如果找到匹配 GID 的任务,返回该任务
if (task.getGid().equals(gid))
return task;
}
return null;
}
// 获取任务列表中的所有任务
public ArrayList<Task> getChildTaskList() {
return this.mChildren;
}
// 设置任务列表的索引
public void setIndex(int index) {
this.mIndex = index;
}
// 获取任务列表的索引
public int getIndex() {
return this.mIndex;
}
}