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.
123xiaomi/TaskList.java

450 lines
13 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.

```java
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 类
* 它包含一个任务列表和相关的操作,如创建和更新任务列表的 JSON 对象
*/
public class TaskList extends Node {
private static final String TAG = TaskList.class.getSimpleName();
// 任务列表的索引
private int mIndex;
// 任务列表
private ArrayList<Task> mChildren;
/**
* TaskList 构造函数初始化任务列表和索引
*/
public TaskList() {
super();
mChildren = new ArrayList<Task>();
mIndex = 1;
}
/**
* 生成创建任务列表的 JSON 对象
*
* @param actionId 操作的 ID
* @return 创建操作的 JSON 对象
* @throws ActionFailureException 如果生成 JSON 对象失败
*/
public JSONObject getCreateAction(int actionId) {
JSONObject js = new JSONObject();
try {
// action_type
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
// action_id
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// index
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex);
// entity_delta
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 对象
*
* @param actionId 操作的 ID
* @return 更新操作的 JSON 对象
* @throws ActionFailureException 如果生成 JSON 对象失败
*/
public JSONObject getUpdateAction(int actionId) {
JSONObject js = new JSONObject();
try {
// action_type
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
// action_id
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// id
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
// entity_delta
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 对象设置任务列表的内容
*
* @param js 远程 JSON 对象
* @throws ActionFailureException 如果设置内容失败
*/
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
// last_modified
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// name
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 对象设置任务列表的内容
*
* @param js 本地 JSON 对象
* @throws ActionFailureException 如果设置内容失败
*/
public void setContentByLocalJSON(JSONObject js) {
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}
try {
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 内容
*
* 该方法构建一个表示本地笔记信息的 JSONObject包括文件夹名称和类型
* @return 包含本地笔记信息的 JSONObject如果发生异常则返回 null
*/
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);
js.put(GTaskStringUtils.META_HEAD_NOTE, folder);
return js;
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
return null;
}
}
/**
* 根据游标获取同步操作
*
* 根据游标信息确定本地和远程笔记之间的同步操作
* @param c 指向数据库记录的游标
* @return 同步操作常量之一
*/
public int getSyncAction(Cursor c) {
try {
if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) {
// 本地没有更新
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 不匹配");
return SYNC_ACTION_ERROR;
}
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;
}
/**
* 获取子任务的数量
*
* @return 子任务的数量
*/
public int getChildTaskCount() {
return mChildren.size();
}
/**
* 添加子任务
*
* 如果子任务列表中不存在该任务,则将其添加到子任务列表中
* @param task 要添加的任务
* @return 如果任务成功添加则返回 true否则返回 false
*/
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;
}
/**
* 在指定索引位置添加子任务
*
* 将任务添加到子任务列表的指定索引位置,并更新任务列表
* @param task 要添加的任务
* @param index 要添加任务的索引位置
* @return 如果任务成功添加则返回 true否则返回 false
*/
public boolean addChildTask(Task task, int index) {
if (index < 0 || index > mChildren.size()) {
Log.e(TAG, "添加子任务: 无效的索引");
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;
}
/**
* 移除子任务
*
* 从子任务列表中移除任务,并更新任务列表
* @param task 要移除的任务
* @return 如果任务成功移除则返回 true否则返回 false
*/
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;
}
/**
* 移动子任务到新的索引位置
*
* 将任务在子任务列表中移动到新的索引位置
* @param task 要移动的任务
* @param index 新的索引位置
* @return 如果任务成功移动则返回 true否则返回 false
*/
public boolean moveChildTask(Task task, int index) {
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "移动子任务: 无效的索引");
return false;
}
int pos = mChildren.indexOf(task);
if (pos == -1) {
Log.e(TAG, "移动子任务: 任务不在列表中");
return false;
}
if (pos == index)
return true;
return (removeChildTask(task) && addChildTask(task, index));
}
/**
* 通过 GID 查找子任务
*
* @param gid 要查找的任务的 GID
* @return 找到的任务,如果没有找到则返回 null
*/
public Task findChildTaskByGid(String gid) {
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
if (t.getGid().equals(gid)) {
return t;
}
}
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, "通过索引获取任务: 无效的索引");
return null;
}
return mChildren.get(index);
}
/**
* 通过 GID 查找子任务(替代方法)
*
* @param gid 要查找的任务的 GID
* @return 找到的任务,如果没有找到则返回 null
*/
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) {
if (task.getGid().equals(gid))
return task;
}
return null;
}
/**
* 获取子任务列表
*
* @return 子任务列表
*/
public ArrayList<Task> getChildTaskList() {
return this.mChildren;
}
/**
* 设置任务的索引
*
* @param index 任务的新索引
*/
public void setIndex(int index) {
this.mIndex = index;
}
/**
* 获取任务的索引
*
* @return 任务的索引
*/
public int getIndex() {
return this.mIndex;
}
}
```