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.
software/Task.txt

455 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.text.TextUtils;
import android.util.Log;
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;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/*
* Task类表示一个任务继承自Node类。
* 该类包含了任务的各种属性和操作方法,如创建、更新、设置内容等。
*/
public class Task extends Node {
private static final String TAG = Task.class.getSimpleName();
private boolean mCompleted; // 任务是否已完成
private String mNotes; // 任务的备注
private JSONObject mMetaInfo; // 任务的元数据信息
private Task mPriorSibling; // 前一个兄弟任务
private TaskList mParent; // 父任务列表
/*
* 构造函数,初始化任务对象。
* 初始化任务的完成状态、备注、前一个兄弟任务、父任务列表和元数据信息。
*/
public Task() {
super(); // 调用父类Node的构造函数
mCompleted = false; // 初始化任务为未完成状态
mNotes = null; // 初始化备注为空
mPriorSibling = null; // 初始化前一个兄弟任务为空
mParent = null; // 初始化父任务列表为空
mMetaInfo = null; // 初始化元数据信息为空
}
/*
*生成创建任务的JSON对象。
* @param actionId 操作ID
* @return 包含创建任务信息的JSONObject
*/
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
// 设置操作ID
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// index
// 设置任务在父任务列表中的索引
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this));
// 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_TASK);
if (getNotes() != null) {
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes());
}
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
// parent_id
// 设置父任务列表的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
// 设置任务列表的ID
js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid());
// prior_sibling_id
// 设置前一个兄弟任务的ID
if (mPriorSibling != null) {
js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid());
}
} catch (JSONException e) {
// 捕获JSON异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
// 抛出自定义异常表示生成JSON对象失败
throw new ActionFailureException("fail to generate task-create jsonobject");
}
return js; // 返回包含创建任务信息的JSONObject
}
/*
* 生成更新任务的JSON对象。
* @param actionId 操作ID
* @return 包含更新任务信息的JSONObject
*/
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
// 设置操作ID
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// id
// 设置任务的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());
}
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) {
// 捕获JSON异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
// 抛出自定义异常表示生成JSON对象失败
throw new ActionFailureException("fail to generate task-update jsonobject");
}
return js; // 返回包含更新任务信息的JSONObject
}
/*
* 根据远程JSON对象设置任务的内容。
* @param js 包含任务信息的远程JSON对象
*/
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {
try {
// id
// 如果JSON对象中包含ID字段则设置任务的ID
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
// last_modified
// 如果JSON对象中包含最后修改时间字段则设置任务的最后修改时间
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// name
// 如果JSON对象中包含名称字段则设置任务的名称
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
}
// notes
// 如果JSON对象中包含备注字段则设置任务的备注
if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) {
setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES));
}
// deleted
// 如果JSON对象中包含删除状态字段则设置任务的删除状态
if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) {
setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED));
}
// completed
// 如果JSON对象中包含完成状态字段则设置任务的完成状态
if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) {
setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED));
}
} catch (JSONException e) {
// 捕获JSON异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
// 抛出自定义异常表示从JSON对象获取任务内容失败
throw new ActionFailureException("fail to get task content from jsonobject");
}
}
}
/*
* 根据本地JSON对象设置任务的内容。
* @param js 包含任务信息的本地JSON对象
*/
public void setContentByLocalJSON(JSONObject js) {
// 检查JSON对象是否为空或是否包含必要的字段
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)
|| !js.has(GTaskStringUtils.META_HEAD_DATA)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}
try {
// 获取笔记的元数据
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
// 获取数据数组
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
// 检查笔记的类型是否为普通笔记类型
if (note.getInt(NoteColumns.TYPE) != Notes.TYPE_NOTE) {
Log.e(TAG, "invalid type");
return;
}
// 遍历数据数组查找MIME类型为DataConstants.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;
}
}
} catch (JSONException e) {
// 捕获JSON异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
/*
* 根据任务内容生成本地JSON对象。
* @return 包含任务内容的本地JSON对象如果发生错误则返回null
*/
public JSONObject getLocalJSONFromContent() {
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;
}
// 创建一个新的JSON对象
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;
} else {
// synced task
// 如果是已同步的任务
JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
// 遍历数据数组,更新任务名称
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;
}
}
note.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
return mMetaInfo;
}
} catch (JSONException e) {
// 捕获JSON异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
return null;
}
}
/*
* 设置任务的元数据信息。
* @param metaData 包含元数据信息的MetaData对象
*/
public void setMetaInfo(MetaData metaData) {
// 检查MetaData对象是否为空并且是否包含笔记信息
if (metaData != null && metaData.getNotes() != null) {
try {
// 将笔记信息转换为JSONObject对象
mMetaInfo = new JSONObject(metaData.getNotes());
} catch (JSONException e) {
// 捕获JSON异常并记录警告日志
Log.w(TAG, e.toString());
mMetaInfo = null;
// 如果转换失败将mMetaInfo设置为null
}
}
}
/*
* 获取同步操作类型。
* @param c 包含本地笔记信息的Cursor对象
* @return 同步操作类型
*/
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);
}
// 如果笔记信息为空,表示笔记元数据已被删除
if (noteInfo == null) {
Log.w(TAG, "it seems that note meta has been deleted");
return SYNC_ACTION_UPDATE_REMOTE;
}
// 如果笔记信息中不包含ID字段表示远程笔记ID已被删除
if (!noteInfo.has(NoteColumns.ID)) {
Log.w(TAG, "remote note id seems to be deleted");
return SYNC_ACTION_UPDATE_LOCAL;
}
// validate the note id now
// 验证笔记ID是否匹配
if (c.getLong(SqlNote.ID_COLUMN) != noteInfo.getLong(NoteColumns.ID)) {
Log.w(TAG, "note id doesn't match");
return 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
// 如果没有更新返回SYNC_ACTION_NONE
return SYNC_ACTION_NONE;
} else {
// apply remote to local
// 应用远程更新到本地
return SYNC_ACTION_UPDATE_LOCAL;
}
} else {
// validate gtask id
// 验证Google任务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;
} else {
// 返回冲突更新
return SYNC_ACTION_UPDATE_CONFLICT;
}
}
} catch (Exception e) {
// 捕获异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
}
return SYNC_ACTION_ERROR; // 默认返回SYNC_ACTION_ERROR
}
/*
* 判断任务是否值得保存。
* @return 如果任务值得保存返回true否则返回false
*/
public boolean isWorthSaving() {
// 检查元数据信息是否存在,或者任务名称和备注是否不为空且不为空白字符串
return mMetaInfo != null || (getName() != null && getName().trim().length() > 0)
|| (getNotes() != null && getNotes().trim().length() > 0);
}
/*
* 设置任务的完成状态。
* @param completed 任务的完成状态true表示已完成false表示未完成
*/
public void setCompleted(boolean completed) {
this.mCompleted = completed;
}
/*
* 设置任务的备注。
* @param notes 任务的备注
*/
public void setNotes(String notes) {
this.mNotes = notes;
}
/*
* 设置前一个兄弟任务。
* @param priorSibling 前一个兄弟任务
*/
public void setPriorSibling(Task priorSibling) {
this.mPriorSibling = priorSibling;
}
/*
* 设置父任务列表。
* @param parent 父任务列表
*/
public void setParent(TaskList parent) {
this.mParent = parent;
}
/*
* 获取任务的完成状态。
* @return 任务的完成状态true表示已完成false表示未完成
*/
public boolean getCompleted() {
return this.mCompleted;
}
/*
* 获取任务的备注。
* @return 任务的备注
*/
public String getNotes() {
return this.mNotes;
}
/*
* 获取前一个兄弟任务。
* @return 前一个兄弟任务
*/
public Task getPriorSibling() {
return this.mPriorSibling;
}
/*
* 获取父任务列表。
* @return 父任务列表
*/
public TaskList getParent() {
return this.mParent;
}
}