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.

361 lines
15 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;
import java.util.ArrayList;
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(); // 调用父类构造函数
mCompleted = false; // 默认未完成
mNotes = null; // 初始化备注为空
mPriorSibling = null; // 初始化前一个兄弟任务为空
mParent = null; // 初始化父任务列表为空
mMetaInfo = null; // 初始化元信息为空
}
// 获取创建任务的JSON对象
public JSONObject getCreateAction(int actionId) {
JSONObject js = new JSONObject(); // 创建JSON对象
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, mParent.getChildTaskIndex(this)); // 设置任务在父任务列表中的索引
// entity_delta
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,
GTaskStringUtils.GTASK_JSON_TYPE_TASK); // 设置实体类型为任务
if (getNotes() != null) {
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); // 设置备注
}
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); // 将实体对象添加到JSON对象
// parent_id
js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid()); // 设置父任务ID
// 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()); // 设置任务列表ID
// prior_sibling_id
if (mPriorSibling != null) {
js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid()); // 设置前一个兄弟任务ID
}
} catch (JSONException e) {
Log.e(TAG, e.toString()); // 记录错误
e.printStackTrace(); // 打印堆栈跟踪
throw new ActionFailureException("fail to generate task-create jsonobject"); // 抛出异常
}
return js; // 返回创建任务的JSON对象
}
// 获取更新任务的JSON对象
public JSONObject getUpdateAction(int actionId) {
JSONObject js = new JSONObject(); // 创建JSON对象
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(); // 创建实体对象
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); // 将实体对象添加到JSON对象
} catch (JSONException e) {
Log.e(TAG, e.toString()); // 记录错误
e.printStackTrace(); // 打印堆栈跟踪
throw new ActionFailureException("fail to generate task-update jsonobject"); // 抛出异常
}
return js; // 返回更新任务的JSON对象
}
// 从远程JSON设置内容
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); // 设置任务ID
}
// last_modified
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); // 设置最后修改时间
}
// name
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); // 设置任务名称
}
// notes
if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) {
setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES)); // 设置备注
}
// deleted
if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) {
setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED)); // 设置删除标志
}
// completed
if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) {
setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED)); // 设置完成标志
}
} catch (JSONException e) {
Log.e(TAG, e.toString()); // 记录错误
e.printStackTrace(); // 打印堆栈跟踪
throw new ActionFailureException("fail to get task content from jsonobject"); // 抛出异常
}
}
}
// 从本地JSON设置内容
public void setContentByLocalJSON(JSONObject js) {
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)
|| !js.has(GTaskStringUtils.META_HEAD_DATA)) {
Log.w(TAG, "setContentByLocalJSON: nothing is available"); // 记录警告
}
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; // 返回
}
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) {
Log.e(TAG, e.toString()); // 记录错误
e.printStackTrace(); // 打印堆栈跟踪
}
}
// 从内容生成本地JSON对象
public JSONObject getLocalJSONFromContent() {
String name = getName(); // 获取任务名称
try {
if (mMetaInfo == null) { // 如果元信息为空
// 从网络创建的新任务
if (name == null) {
Log.w(TAG, "the note seems to be an empty one"); // 记录警告
return null; // 返回null
}
JSONObject js = new JSONObject(); // 创建JSON对象
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); // 将数据数组添加到JSON对象
note.put(NoteColumns.TYPE, Notes.TYPE_NOTE); // 设置类型为笔记
js.put(GTaskStringUtils.META_HEAD_NOTE, note); // 将笔记对象添加到JSON对象
return js; // 返回JSON对象
} else {
// 同步的任务
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) {
Log.e(TAG, e.toString()); // 记录错误
e.printStackTrace(); // 打印堆栈跟踪
return null; // 返回null
}
}
// 设置元信息
public void setMetaInfo(MetaData metaData) {
if (metaData != null && metaData.getNotes() != null) {
try {
mMetaInfo = new JSONObject(metaData.getNotes()); // 将元数据转换为JSON对象
} catch (JSONException e) {
Log.w(TAG, e.toString()); // 记录警告
mMetaInfo = null; // 设置元信息为空
}
}
}
// 获取同步操作
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; // 返回更新远程操作
}
if (!noteInfo.has(NoteColumns.ID)) { // 如果笔记ID不存在
Log.w(TAG, "remote note id seems to be deleted"); // 记录警告
return SYNC_ACTION_UPDATE_LOCAL; // 返回更新本地操作
}
// 验证笔记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) { // 如果没有本地更新
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { // 如果同步ID未改变
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()) { // 如果同步ID未改变
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; // 返回错误操作
}
// 检查任务是否值得保存
public boolean isWorthSaving() {
return mMetaInfo != null || (getName() != null && getName().trim().length() > 0)
|| (getNotes() != null && getNotes().trim().length() > 0); // 如果有元信息或名称或备注不为空返回true
}
// 设置任务完成状态
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; // 返回父任务列表
}
}