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/标注/210340061_林亭旭/Task.java

397 lines
20 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;
//包含了一些用于处理GTaskGoogle Task相关数据的类。具体来说这些类实现了将本地笔记同步到Google Task中以及从Google Task中同步笔记到本地的功能。
import android.database.Cursor;//引入Android类cursor为Android提供接口用于访问数据源中的数据并支持对数据进行查询、排序、更新等操作。
import android.text.TextUtils;// 引入Android类TextUtilsAndroid提供的一个工具类包含了一些字符串处理相关的方法如检查字符串是否为空、去除字符串两端的空格等
import android.util.Log;//引入Android类Log是Android提供的一个工具类用于在开发和调试过程中输出日志信息
import net.micode.notes.data.Notes;//是该应用程序中的一个关键类,定义了笔记和数据表的结构
import net.micode.notes.data.Notes.DataColumns;//笔记表子类,定义了笔记表中的各个字段
import net.micode.notes.data.Notes.DataConstants;//是一个接口,定义了一些常量,如便签类型、便签状态等
import net.micode.notes.data.Notes.NoteColumns;//笔记表子类,定义了笔记表中的各个字段
import net.micode.notes.gtask.exception.ActionFailureException;//是自定义异常类,表示某个操作失败了
import net.micode.notes.tool.GTaskStringUtils;//是一个字符串处理工具类定义了一些与Google Task有关的字符串处理方法
import org.json.JSONArray;//是一个表示JSON数组的类可以方便地读取和操作JSON数组中的元素。
import org.json.JSONException;//是一个异常类表示在解析JSON数据时发生了错误。
import org.json.JSONObject;//是一个表示JSON对象的类可以方便地读取和操作JSON对象中的属性和值。
public class Task extends Node//定义了一个Task类继承自Node类
{
private static final String TAG = Task.class.getSimpleName();
private boolean mCompleted;//表示任务是否已完成
private String mNotes;//表示任务的注释信息
private JSONObject mMetaInfo;//表示任务的元信息是一个JSONObject对象
private Task mPriorSibling;//表示该任务在同级任务中的前一个任务对象
private TaskList mParent;//表示该任务所属的任务列表对象
public Task() {
super();
mCompleted = false;
mNotes = null;
mPriorSibling = null;
mParent = null;
mMetaInfo = null;
}//无参构造函数初始化所有属性值均为null或false
public JSONObject getCreateAction(int actionId)
//getCreateAction方法接收一个整型参数actionId将该参数作为返回JSONObject对象的action_id属性值。
{
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, mParent.getChildTaskIndex(this));
// entity_delta一个JSONObject对象
JSONObject entity = new JSONObject();
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());//得到任务名
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");//对任务创建者id进行判空操作
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,//实体类数据task
GTaskStringUtils.GTASK_JSON_TYPE_TASK);
if (getNotes() != null)
//如果任务有注释则设置notes属性表示任务注释信息。
{
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes());
}
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
// parent_id
js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid());
// dest_parent_type
js.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
// list_id
js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid());
// prior_sibling_id
if (mPriorSibling != null) {
js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid());
}
//如果该任务在兄弟任务中不是第一个则设置prior_sibling_id属性值为前一个兄弟任务的gid。
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate task-create jsonobject");
}
//如果在生成JSONObject对象时发生异常则会抛出一个自定义异常ActionFailureException。
return js;
}
public JSONObject getUpdateAction(int actionId)
//getUpdateAction方法接收一个整型参数actionId将该参数作为返回JSONObject对象的action_id属性值
{
JSONObject js = new JSONObject();
try {
// action_type
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
//action_type属性值为update表示更新操作
// action_id
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
//id属性值为该任务的gid。
// id
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
// entity_delta
JSONObject entity = new JSONObject();
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());//任务名称
if (getNotes() != null) {
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes());
}//如果该任务有注释则设置notes属性表示任务注释信息
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
}//deleted属性表示任务是否被删除如果该值为true则该任务会被移除
catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate task-update jsonobject");
}//如果在生成JSONObject对象时发生异常则会抛出一个自定义异常ActionFailureException。
return js;
}
public void setContentByRemoteJSON(JSONObject js)
//定义了一个setContentByRemoteJSON方法该方法从远程JSON对象中获取任务的属性值并将这些属性值设置到本地任务对象中
//表示从远程服务器获取的任务信息
{
if (js != null) //首先检查传入的JSON对象是否为空如果不是空对象则依次从JSON对象中获取以下属性值
{
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID))
//id属性值并调用setGid方法将其赋值给本地任务对象的gid属性
{
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));
}//last_modified属性值并调用setLastModified方法将其赋值给本地任务对象的lastModified属性
// name
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
}//name属性值并调用setName方法将其赋值给本地任务对象的name属性
// notes
if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) {
setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES));
}//notes属性值并调用setNotes方法将其赋值给本地任务对象的notes属性
// deleted
if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) {
setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED));
}//deleted属性值并调用setDeleted方法将其赋值给本地任务对象的deleted属性
// completed
if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) {
setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED));
}//completed属性值并调用setCompleted方法将其赋值给本地任务对象的completed属性
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to get task content from jsonobject");
}//如果在解析JSON对象时发生异常则会抛出一个自定义异常ActionFailureException
}
}
public void setContentByLocalJSON(JSONObject js)
//定义了一个setContentByLocalJSON方法该方法从本地JSON对象中获取任务的属性值并将这些属性值设置到本地任务对象中
//setContentByLocalJSON方法接收一个JSONObject参数js用来表示本地存储的任务信息
{
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)
|| !js.has(GTaskStringUtils.META_HEAD_DATA)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}//该方法首先检查传入的JSON对象是否为空以及是否包含必要属性。如果不满足这些条件则打印一条警告日志并退出方法
try {
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
//从JSON对象中获取META_HEAD_NOTE和META_HEAD_DATA属性的值并分别赋给变量note和dataArray
if (note.getInt(NoteColumns.TYPE) != Notes.TYPE_NOTE) {
Log.e(TAG, "invalid type");
return;
}
//该方法检查获取到的note对象的type属性是否为Notes.TYPE_NOTE如果不是则打印一条错误日志并退出方法
for (int i = 0; i < dataArray.length(); i++) {
JSONObject data = dataArray.getJSONObject(i);
if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) {
setName(data.getString(DataColumns.CONTENT));
break;
}
}//该方法遍历dataArray数组中的每个元素找到mime_type属性为DataConstants.NOTE的元素并将其content属性值赋给本地任务对象的name属性
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}//如果在解析JSON对象时发生异常则会打印一条错误日志
}
public JSONObject getLocalJSONFromContent()
//定义了一个getLocalJSONFromContent方法该方法从本地任务对象中获取任务的属性值并将这些属性值构造成JSON对象返回
{
String name = getName();
try {
if (mMetaInfo == null)//获取任务的名称
{
// new task created from web
if (name == null) {
Log.w(TAG, "the note seems to be an empty one");
return null;
}
//根据任务的元信息即mMetaInfo属性判断任务是从Web端创建还是同步而来。如果任务的元信息为空则认为该任务是从Web端创建的。
JSONObject js = new JSONObject();
JSONObject note = new JSONObject();
JSONArray dataArray = new JSONArray();
JSONObject data = new JSONObject();
data.put(DataColumns.CONTENT, name);
dataArray.put(data);
js.put(GTaskStringUtils.META_HEAD_DATA, dataArray);
note.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
js.put(GTaskStringUtils.META_HEAD_NOTE, note);
return js;//对于从Web端创建的任务如果任务名称为空则会打印一条警告日志并返回null。
// 否则该方法构造一个JSONObject对象其中包含META_HEAD_DATA和META_HEAD_NOTE两个属性
// 并将任务的名称设置为META_HEAD_DATA属性所表示的JSONArray对象中的data属性值
} else {
// synced task
JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
//对于同步而来的任务该方法首先获取任务的META_HEAD_DATA和META_HEAD_NOTE属性的值
for (int i = 0; i < dataArray.length(); i++) {
JSONObject data = dataArray.getJSONObject(i);
if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) {
data.put(DataColumns.CONTENT, getName());
break;
}
}//遍历META_HEAD_DATA属性值所表示的JSONArray对象中的所有元素找到mime_type属性为DataConstants.NOTE的元素并将其content属性值设置为本地任务对象的名称
note.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
return mMetaInfo;
}//最后该方法将note对象的type属性设置为Notes.TYPE_NOTE并返回元信息对应的JSONObject对象
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
return null;
}//如果在构造JSON对象时发生异常则会打印一条错误日志并返回null
}
public void setMetaInfo(MetaData metaData) //用于设置mMetaInfo属性
//接收一个MetaData对象参数metaData
{
if (metaData != null && metaData.getNotes() != null) {
try {
mMetaInfo = new JSONObject(metaData.getNotes());
}
//metaData不为空并且其notes属性不为空字符串则将notes属性值解析为JSON对象并将其赋给mMetaInfo属性
catch (JSONException e) {
Log.w(TAG, e.toString());
mMetaInfo = null;
}//如果在解析JSON对象时发生异常则会打印一条警告日志并将mMetaInfo属性赋为null
}//如果metaData对象或者其notes属性为空则不会对mMetaInfo属性做任何更改
}
public int getSyncAction(Cursor c)
//用于返回同步任务的操作类型
{
try {
JSONObject noteInfo = null;
if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) {
noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
}//mMetaInfo属性,中获取与任务相关联的笔记信息
if (noteInfo == null) {
Log.w(TAG, "it seems that note meta has been deleted");
return SYNC_ACTION_UPDATE_REMOTE;
}//// 如果不存在则会打印一条警告日志并返回SYNC_ACTION_UPDATE_REMOTE操作类型
if (!noteInfo.has(NoteColumns.ID)) {
Log.w(TAG, "remote note id seems to be deleted");
return SYNC_ACTION_UPDATE_LOCAL;
}//检查笔记信息中是否存在NoteColumns.ID属性
// 如果不存在则会打印一条警告日志并返回SYNC_ACTION_UPDATE_LOCAL操作类型
// validate the note id now
if (c.getLong(SqlNote.ID_COLUMN) != noteInfo.getLong(NoteColumns.ID)) {
Log.w(TAG, "note id doesn't match");
return SYNC_ACTION_UPDATE_LOCAL;
}//获取查询结果集c中的本地笔记的id属性值并将其与笔记信息中的NoteColumns.ID属性值进行比较。
// 如果两者不相等则会打印一条警告日志并返回SYNC_ACTION_UPDATE_LOCAL操作类型。
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;
}//根据本地笔记对象的LOCAL_MODIFIED_COLUMN属性值是否为0来确定是否存在本地更新。如果该属性值为0则表示没有本地更新。
// 如果本地笔记对象的SYNC_ID_COLUMN属性值等于当前任务对象的最后修改时间则表示两者都没有更新
// 返回SYNC_ACTION_NONE操作类型否则返回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;
}
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
// local modification only
return SYNC_ACTION_UPDATE_REMOTE;
} else {
return SYNC_ACTION_UPDATE_CONFLICT;
}//如果本地笔记对象的LOCAL_MODIFIED_COLUMN属性值不为0则表示存在本地更新。
// 此时检查SqlNote.GTASK_ID_COLUMN属性值是否与当前任务对象的Google Task ID相等。
// 如果不相等打印一条错误日志并返回SYNC_ACTION_ERROR操作类型。
// 接着比较本地笔记对象的SYNC_ID_COLUMN属性值与getLastModified()方法返回值是否相等。
// 如果相等则表示只存在本地更新返回SYNC_ACTION_UPDATE_REMOTE操作类型
// 否则返回SYNC_ACTION_UPDATE_CONFLICT操作类型
}
} catch (Exception e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
return SYNC_ACTION_ERROR;
}//如果在执行过程中发生异常则会打印一条错误日志并返回SYNC_ACTION_ERROR操作类型。
public boolean isWorthSaving() {
return mMetaInfo != null || (getName() != null && getName().trim().length() > 0)
|| (getNotes() != null && getNotes().trim().length() > 0);
}//isWorthSaving()方法用于判断当前任务对象是否值得保存,返回一个布尔值。
//该方法会判断以下三种情况只要其中任意一种情况成立则返回true表示该任务对象值得保存
//mMetaInfo属性不为null即当前任务对象存在元信息。
//getName()方法返回值不为null且去除空格后长度大于0表示当前任务对象的名称不为空。
//getNotes()方法返回值不为null且去除空格后长度大于0表示当前任务对象的笔记内容不为空。
//如果上述所有条件都不成立则返回false表示当前任务对象不值得保存
public void setCompleted(boolean completed) {
this.mCompleted = completed;
}
public void setNotes(String notes) {
this.mNotes = notes;
}
public void setPriorSibling(Task priorSibling) {
this.mPriorSibling = priorSibling;
}
public void setParent(TaskList parent) {
this.mParent = parent;
}
public boolean getCompleted() {
return this.mCompleted;
}
public String getNotes() {
return this.mNotes;
}
public Task getPriorSibling() {
return this.mPriorSibling;
}
public TaskList getParent() {
return this.mParent;
}
}