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.
GPL_Project/doc/标注/210340054_金佳艺/TaskList.java

432 lines
16 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.
*/
//TaskList代码标注
//主要作用同步任务列表将Task组织成同步任务列表进行管理
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;
public class TaskList extends Node {//创建继承 Node的任务表类
private static final String TAG = TaskList.class.getSimpleName(); //tag标记
//调用getSimplename函数获取名字并赋值给TAG作为标记
private int mIndex; //当前TaskList的指针
private ArrayList<Task> mChildren; //类中主要的保存数据的单元用来实现一个以Task为元素的ArrayList
public TaskList() { //构造函数进行初始化
super(); //调用父类构造方法
mChildren = new ArrayList<Task>(); //声明数组
mIndex = 1;
}
/* (non-Javadoc)
* @see net.micode.notes.gtask.data.Node#getCreateAction(int)
* 生成并返回一个包含了一定数据的JSONObject实体
*/
public JSONObject getCreateAction(int actionId) {
JSONObject js = new JSONObject(); //直接构建即直接实例化一个JSONObject对象
try {
// action_type
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
//操作的是列表而不只是单个task了
// action_id
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// index
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex);
// entity_delta
// 新建一个 JSONObject 对象,名为实体,将 namecreator identity type 三个信息存在一起
JSONObject entity = new JSONObject(); //创建一个实体类并进行初始化
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
//getName是父类的一个函数
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");
//初始化id
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
//将实体类型设置为“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;
}
/* (non-Javadoc)
* @see net.micode.notes.gtask.data.Node#getUpdateAction(int)
* 生成并返回一个包含了一定数据的JSONObject实体
*/
public JSONObject getUpdateAction(int actionId) { //接受更新action返回jsonobject
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;
}
public void setContentByRemoteJSON(JSONObject js) {
//通过云端 JSON 数据设置实例化对象 js 的内容
if (js != null) {
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
//判断js对象是否为空如果为空即没有内容就不需要进行设置了
// last_modified
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
//调用JSONObject中的getLong函数得到last_modified的号并作为参数传给setLastModified函数父类函数进行设置
// name
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
} //对任务的name进行设置
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to get tasklist content from jsonobject");
}
}
}
public void setContentByLocalJSON(JSONObject js) { //通过本地 JSON 数据设置对象 js 内容
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) {
//若 js 创建失败或 js 中不存在 META_HEAD_NOTE信息
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
} //警告,没有可用资源
try {
JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
//NullPointerException这个异常出现在处理对象时对象不存在但又没有捕捉到进行处理的时候
if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) {
//对文件夹,设置文件名
String name = folder.getString(NoteColumns.SNIPPET);
//获取文件夹片段字符串作为文件夹名称
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + name);
//设置名称为MIUI系统文件夹前缀+文件夹名称
} 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);
//如果是根文件夹设置名称MIUI系统文件夹前缀+默认文件夹名称
else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER)
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX
+ GTaskStringUtils.FOLDER_CALL_NOTE);
//如果是通话文件夹设置名称MIUI系统文件夹前缀+通话便签文件夹名称
else
Log.e(TAG, "invalid system folder");
;//无效系统文件夹警告
} else {
Log.e(TAG, "error type");
//错误的文件夹类型
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
public JSONObject getLocalJSONFromContent() { //从content获取本地json
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);
//如果获取的文件夹名称是以[MIUI_Notes]开头,则文件夹名称应删掉前缀
if (folderName.equals(GTaskStringUtils.FOLDER_DEFAULT)
|| folderName.equals(GTaskStringUtils.FOLDER_CALL_NOTE))
folder.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
//这里与上一个函数setContentByRemoteJSON(JSONObject js)是一个逆过程可以参看上一个函数是如何构造出foldername的
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;
}
}
public int getSyncAction(Cursor c) { //获取同步信息
try {
if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) { //若本地修改未记录
// there is no local update
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
//记录最后一次修改
// no update both side
return SYNC_ACTION_NONE;
} else {
// apply remote to local
return SYNC_ACTION_UPDATE_LOCAL;
} //匹配失败,返回更新本地数据的同步行为
} else {
// validate 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()) {
// local modification only
return SYNC_ACTION_UPDATE_REMOTE;
//如果是最近一次修改的 id则返回云端更新的同步动作
} else {
// for folder conflicts, just apply local modification
return SYNC_ACTION_UPDATE_REMOTE;
}
}
} catch (Exception e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
return SYNC_ACTION_ERROR;
}
// @return
//功能获得TaskList的大小即mChildren的大小
public int getChildTaskCount() {
return mChildren.size();
}
//获得TaskList的大小即mChildren的大小mChildren 是TaskList 的一个实例
//@param task
//@return 返回值为是否成功添加任务。
//功能:在当前任务表末尾添加新的任务。
public boolean addChildTask(Task task) {
boolean ret = false;
if (task != null && !mChildren.contains(task)) { //任务非空且任务表中不存在该任务
ret = mChildren.add(task);
if (ret) {
// need to set prior sibling and parent
task.setPriorSibling(mChildren.isEmpty() ? null : mChildren
.get(mChildren.size() - 1));
task.setParent(this);
//ArrayList的每一次修改变化都要紧跟相关Task中PriorSibling的修改
}
}
return ret;
}
/**
* @param task
* @param index
* @return
* 功能:在当前任务表的指定位置添加新的任务。
*/
public boolean addChildTask(Task task, int index) {
if (index < 0 || index > mChildren.size()) {
Log.e(TAG, "add child task: invalid index");
return false;
}
//在当前任务表的指定位置添加新的任务index是指针
int pos = mChildren.indexOf(task);
if (task != null && pos == -1) {
mChildren.add(index, task);
//获取要添加的任务在列表中的位置,如果不在列表中则返回-1
// 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 返回删除是否成功
* 功能删除TaskList中的一个Task
*/
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); //删除成功task的上一个任务指针和父指针置空
// 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
* 功能将当前TaskList中含有的某个Task移到index位置
*/
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));
}
//利用已经实现好的功能完成当下功能
/**
* @param gid
* @return返回寻找结果
* 功能按gid寻找Task
*/
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
* 功能返回指定Task的index
*/
public int getChildTaskIndex(Task task) {
return mChildren.indexOf(task);
}
/**
* @param index
* @return
* 功能返回指定index的Task
*/
public Task getChildTaskByIndex(int index) {
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "getTaskByIndex: invalid index"); //如果指针不在范围内,无效索引
return null;
}
return mChildren.get(index);
}
/**
* @param gid
* @return
* 功能返回指定gid的Task
*/
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) { //ArrayList的遍历方法 //通过索引获取子任务
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;
} //获取任务索引
}