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.
5._Open-source-software-rea.../src/gtask/data/TaskList.java

464 lines
17 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)
*
* 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;
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;
/**
* 任务列表类继承自Node类。用于管理一组任务Task对象。
*/
public class TaskList extends Node {
// 日志标签
private static final String TAG = TaskList.class.getSimpleName();
// 列表中的任务索引
private int mIndex;
// 存储子任务的列表
private ArrayList<Task> mChildren;
/**
* 构造函数,初始化任务列表。
*/
public TaskList() {
super(); // 调用父类Node构造函数
mChildren = new ArrayList<Task>(); // 初始化子任务列表
mIndex = 1; // 默认索引设置为1
}
/**
* 生成创建任务列表的动作JSON对象。
*
* @param actionId 动作标识符
* @return 包含创建任务列表动作的JSON对象
* @throws ActionFailureException 如果生成JSON对象失败则抛出异常
*/
public JSONObject getCreateAction(int actionId) throws ActionFailureException {
JSONObject js = new JSONObject();
try {
// 设置动作类型为创建
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
// 设置动作标识符
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); // 将任务列表实体信息加入JSON
} catch (JSONException e) {
Log.e(TAG, e.toString()); // 记录错误日志
e.printStackTrace();
throw new ActionFailureException("fail to generate tasklist-create jsonobject"); // 抛出异常表示JSON生成失败
}
return js; // 返回生成的JSON对象
}
/**
* 生成更新任务列表的动作JSON对象。
*
* @param actionId 动作标识符
* @return 包含更新任务列表动作的JSON对象
* @throws ActionFailureException 如果生成JSON对象失败则抛出异常
*/
public JSONObject getUpdateAction(int actionId) throws ActionFailureException {
JSONObject js = new JSONObject();
try {
// 设置动作类型为更新
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
// 设置动作标识符
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); // 将实体信息加入JSON
} catch (JSONException e) {
Log.e(TAG, e.toString()); // 记录错误日志
e.printStackTrace();
throw new ActionFailureException("fail to generate tasklist-update jsonobject"); // 抛出异常表示JSON生成失败
}
return js; // 返回生成的JSON对象
}
/**
* 根据远程JSON对象设置任务列表的内容。
*
* @param js 远程获取的JSON对象
* @throws ActionFailureException 如果从JSON对象中获取内容失败则抛出异常
*/
public void setContentByRemoteJSON(JSONObject js) throws ActionFailureException {
if (js != null) {
try {
// 设置ID
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); // 设置任务列表ID
}
// 设置最后修改时间
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// 设置名称
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 如果从JSON对象中获取内容失败则抛出异常
*/
public void setContentByLocalJSON(JSONObject js) throws ActionFailureException {
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) {
Log.w(TAG, "setContentByLocalJSON: nothing is available"); // 记录警告,无有效内容
return;
}
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();
throw new ActionFailureException("fail to set tasklist content from local json object"); // 抛出异常,表示设置内容失败
}
}
/**
* 从任务列表内容生成本地JSON对象。
*
* @return 本地JSON对象代表的任务列表内容
*/
public JSONObject getLocalJSONFromContent() {
try {
JSONObject js = new JSONObject(); // 创建新的JSON对象
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); // 添加任务列表信息到JSON
return js; // 返回生成的JSON对象
} catch (JSONException e) {
Log.e(TAG, e.toString()); // 记录错误日志
e.printStackTrace();
return null; // 生成失败返回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 doesn't match"); // 记录错误ID不匹配
return SYNC_ACTION_ERROR; // 返回错误状态
}
// 对于文件夹情况,应该的返回逻辑
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, "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; // 添加成功
}
/**
* 从列表中移除一个子任务。
*
* @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, "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;
}
if (pos == index)
return true; // 位置未变,返回成功
return (removeChildTask(task) && addChildTask(task, index)); // 移除后再添加
}
/**
* 根据全局标识符(gid)查找子任务。
*
* @param gid 要查找的子任务的全局标识符
* @return 如果找到匹配的子任务则返回该任务对象否则返回null。
*/
public Task findChildTaskByGid(String gid) {
// 遍历子任务列表查找gid匹配的子任务
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
if (t.getGid().equals(gid)) {
return t; // 返回找到的任务
}
}
return null; // 未找到则返回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"); // 记录错误,索引无效
return null;
}
return mChildren.get(index); // 返回子任务
}
/**
* 通过遍历子任务列表查找并返回匹配指定gid的子任务。
*
* @param gid 要查找的子任务的全局标识符
* @return 如果找到匹配的子任务则返回该任务对象否则返回null。
*/
public Task getChildTaskByGid(String gid) {
// 遍历子任务列表查找gid匹配的子任务
for (Task task : mChildren) {
if (task.getGid().equals(gid))
return task; // 返回找到的任务
}
return null; // 未找到则返回null
}
/**
* 获取所有子任务的列表。
*
* @return 子任务列表作为一个ArrayList<Task>返回。
*/
public ArrayList<Task> getChildTaskList() {
// 返回存储子任务的列表
return this.mChildren;
}
/**
* 设置当前任务的索引。
*
* @param index 要设置的索引值。
*/
public void setIndex(int index) {
this.mIndex = index; // 设置任务列表索引
}
/**
* 获取当前任务的索引。
*
* @return 当前任务的索引值。
*/
public int getIndex() {
return this.mIndex; // 返回当前任务索引
}
}