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.

435 lines
18 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; // 声明包路径net.micode.notes.gtask.data
import android.database.Cursor; // 导入android.database.Cursor类
import android.util.Log; // 导入android.util.Log类
import net.micode.notes.data.Notes; // 导入net.micode.notes.data.Notes类
import net.micode.notes.data.Notes.NoteColumns; // 导入net.micode.notes.data.Notes.NoteColumns类
import net.micode.notes.gtask.exception.ActionFailureException; // 导入net.micode.notes.gtask.exception.ActionFailureException类
import net.micode.notes.tool.GTaskStringUtils; // 导入net.micode.notes.tool.GTaskStringUtils类
import org.json.JSONException; // 导入org.json.JSONException类
import org.json.JSONObject; // 导入org.json.JSONObject类
import java.util.ArrayList; // 导入java.util.ArrayList类
public class TaskList extends Node { // 定义一个继承自Node的类TaskList
private static final String TAG = TaskList.class.getSimpleName(); // 声明TAG常量并赋值
private int mIndex; // 声明整型变量mIndex
private ArrayList<Task> mChildren; // 声明ArrayList<Task>类型变量mChildren
public TaskList() { // 定义TaskList构造方法
super(); // 调用父类构造方法
mChildren = new ArrayList<Task>(); // 实例化mChildren为一个新的ArrayList<Task>
mIndex = 1; // 将mIndex初始化为1
}
public JSONObject getCreateAction(int actionId) { // 定义一个返回JSONObject类型的方法getCreateAction参数为actionId
JSONObject js = new JSONObject(); // 创建一个新的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); // 设置动作ID
// index
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex); // 设置索引
// entity_delta
JSONObject entity = new JSONObject(); // 创建实体变化的JSONObject对象
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); // 设置实体名
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); // 设置创建者ID
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE, // 设置实体类型
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); // 将实体变化添加到JSONObject中
} catch (JSONException e) { // 捕获JSONException异常
Log.e(TAG, e.toString()); // 输出错误日志
e.printStackTrace(); // 打印异常堆栈信息
throw new ActionFailureException("fail to generate tasklist-create jsonobject"); // 抛出ActionFailureException异常
}
return js; // 返回JSONObject对象
}
public JSONObject getUpdateAction(int actionId) { // 定义一个返回JSONObject类型的方法getUpdateAction参数为actionId
JSONObject js = new JSONObject(); // 创建一个新的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
// id
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid()); // 设置ID
// entity_delta
JSONObject entity = new JSONObject(); // 创建实体变化的JSONObject对象
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); // 设置实体名
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted()); // 设置是否已删除
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); // 将实体变化添加到JSONObject中
} catch (JSONException e) { // 捕获JSONException异常
Log.e(TAG, e.toString()); // 输出错误日志
e.printStackTrace(); // 打印异常堆栈信息
throw new ActionFailureException("fail to generate tasklist-update jsonobject"); // 抛出ActionFailureException异常
}
return js; // 返回JSONObject对象
}
/**
* 根据远程JSON设置内容
* @param js 远程JSON对象
*/
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { // 检查JSON对象中是否包含id字段
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); // 设置id属性值为JSON中id字段的值
}
// last_modified
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { // 检查JSON对象中是否包含last_modified字段
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); // 设置last_modified属性值为JSON中last_modified字段的长整型值
}
// name
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { // 检查JSON对象中是否包含name字段
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); // 设置name属性值为JSON中name字段的值
}
} catch (JSONException e) { // 捕获JSON异常
Log.e(TAG, e.toString()); // 记录异常日志
e.printStackTrace(); // 打印异常堆栈信息
throw new ActionFailureException("fail to get tasklist content from jsonobject"); // 抛出自定义异常
}
}
}
/**
* 根据本地JSON设置内容
* @param js 本地JSON对象
*/
public void setContentByLocalJSON(JSONObject js) {
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) { // 如果JSON对象为空或者不包含META_HEAD_NOTE字段
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); // 记录警告日志
}
try {
JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); // 获取JSON对象中的META_HEAD_NOTE字段作为文件夹对象
if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { // 如果文件夹类型为普通类型
String name = folder.getString(NoteColumns.SNIPPET); // 获取文件夹名称
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + name); // 设置name属性值为MIUI_FOLDER_PREFFIX和文件夹名称的组合
} else if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { // 如果文件夹类型为系统类型
if (folder.getLong(NoteColumns.ID) == Notes.ID_ROOT_FOLDER) // 如果文件夹ID为根目录ID
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT); // 设置name属性值为MIUI_FOLDER_PREFFIX和默认文件夹名称的组合
else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER) // 如果文件夹ID为通话记录文件夹ID
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_CALL_NOTE); // 设置name属性值为MIUI_FOLDER_PREFFIX和通话记录文件夹名称的组合
else
Log.e(TAG, "invalid system folder"); // 记录错误日志
} else {
Log.e(TAG, "error type"); // 记录错误日志
}
} catch (JSONException e) { // 捕获JSON异常
Log.e(TAG, e.toString()); // 记录异常日志
e.printStackTrace(); // 打印异常堆栈信息
}
}
/**
* 从内容中获取本地JSON对象
*
* @return 本地JSON对象
*/
public JSONObject getLocalJSONFromContent() {
try {
JSONObject js = new JSONObject(); // 创建一个新的JSON对象
JSONObject folder = new JSONObject(); // 创建一个新的文件夹JSON对象
String folderName = getName(); // 获取任务名称
if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX)) { // 如果任务名称以MIUI_FOLDER_PREFFIX开头
folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(),
folderName.length()); // 使用剩余的部分作为文件夹名称
}
folder.put(NoteColumns.SNIPPET, folderName); // 将文件夹名称放入文件夹JSON对象中
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对象放入本地JSON对象中
return js; // 返回本地JSON对象
} catch (JSONException e) { // 捕获JSON异常
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 doesn't match"); // 记录错误日志
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 是否成功添加子任务
*/
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 是否成功添加子任务
*/
public boolean addChildTask(Task task, int index) {
if (index < 0 || index > mChildren.size()) { // 如果位置索引小于0或大于子任务列表的大小
Log.e(TAG, "add child task: invalid index"); // 记录错误日志
return false; // 返回添加失败
}
int pos = mChildren.indexOf(task); // 获取任务在子任务列表中的位置
if (task != null && pos == -1) { // 如果任务不为空且不在列表中
mChildren.add(index, task); // 在指定位置添加任务
// update the task list
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 是否成功移除子任务
*/
public boolean removeChildTask(Task task) {
boolean ret = false; // 默认移除子任务失败
int index = mChildren.indexOf(task); // 获取任务在子任务列表中的位置
if (index != -1) { // 如果任务在列表中
ret = mChildren.remove(task); // 从列表中移除任务
if (ret) {
// reset prior sibling and parent
task.setPriorSibling(null); // 重置前一个兄弟任务
task.setParent(null); // 重置父任务
// update the task list
if (index != mChildren.size()) {
mChildren.get(index).setPriorSibling(
index == 0 ? null : mChildren.get(index - 1)); // 更新任务列表中其他任务的前一个兄弟任务
}
}
}
return ret; // 返回是否成功移除子任务
}
/**
* 移动子任务到指定位置
*
* @param task 要移动的子任务
* @param index 目标位置
* @return 是否成功移动子任务
*/
public boolean moveChildTask(Task task, int index) {
if (index < 0 || index >= mChildren.size()) { // 如果目标位置索引小于0或大于等于子任务列表的大小
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 gid
* @return 子任务
*/
public Task findChildTaskByGid(String gid) {
for (int i = 0; i < mChildren.size(); i++) { // 循环遍历子任务列表
Task t = mChildren.get(i); // 获取当前子任务
if (t.getGid().equals(gid)) { // 如果子任务的gid与指定的相同
return t; // 返回该子任务
}
}
return null; // 如果未找到匹配的子任务则返回null
}
/**
* 获取子任务在列表中的索引
*
* @param task 子任务
* @return 索引
*/
public int getChildTaskIndex(Task task) {
return mChildren.indexOf(task); // 返回子任务在列表中的索引
}
/**
* 根据索引获取子任务
*
* @param index 索引
* @return 子任务
*/
public Task getChildTaskByIndex(int index) {
if (index < 0 || index >= mChildren.size()) { // 如果索引小于0或大于等于子任务列表的大小
Log.e(TAG, "getTaskByIndex: invalid index"); // 记录错误日志
return null; // 返回null
}
return mChildren.get(index); // 返回对应索引处的子任务
}
/**
* 根据gid获取子任务
*
* @param gid gid
* @return 子任务
*/
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) { // 遍历子任务列表
if (task.getGid().equals(gid)) // 如果子任务的gid与指定的相同
return task; // 返回该子任务
}
return null; // 如果未找到匹配的子任务则返回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; // 返回索引
}
}