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.

335 lines
14 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;
// 任务的元数据信息以JSON对象形式存储
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();
try {
// 设置操作类型为创建
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
// 设置操作ID
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// 设置任务在父任务列表中的索引
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this));
// 设置任务实体的变更信息
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);
// 设置父任务的ID
js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid());
// 设置目标父任务类型为组
js.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
// 设置任务列表的ID与父任务ID相同
js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid());
// 如果有前一个兄弟任务设置其ID
if (mPriorSibling!= null) {
js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid());
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
// 如果生成JSON对象失败抛出异常
throw new ActionFailureException("fail to generate task-create jsonobject");
}
return js;
}
// 获取更新任务的操作信息以JSON对象形式返回
public JSONObject getUpdateAction(int actionId) {
JSONObject js = new JSONObject();
try {
// 设置操作类型为更新
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
// 设置操作ID
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// 设置任务的ID
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
// 设置任务实体的变更信息
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) {
Log.e(TAG, e.toString());
e.printStackTrace();
// 如果生成JSON对象失败抛出异常
throw new ActionFailureException("fail to generate task-update jsonobject");
}
return js;
}
// 根据远程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));
}
// 设置任务的最后修改时间
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// 设置任务的名称
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
}
// 设置任务的备注信息
if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) {
setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES));
}
// 设置任务是否已删除
if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) {
setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED));
}
// 设置任务是否已完成
if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) {
setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED));
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
// 如果从JSON对象获取任务内容失败抛出异常
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 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;
}
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数据根据任务的元数据情况生成相应的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;
}
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 {
// 如果是已同步的任务
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;
}
}
// 设置任务的元数据信息
public void setMetaInfo(MetaData metaData) {
if (metaData!= null && metaData.getNotes()!= null) {
try {
mMetaInfo = new JSONObject(metaData.getNotes());
} 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)) {
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()) {
// 双方都没有更新
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_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);
}
// 设置任务是否已完成
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;
}
}