|
|
// 声明Task类的开始,继承自Node类
|
|
|
public class Task extends Node {
|
|
|
// 定义一个静态常量TAG用于日志记录
|
|
|
private static final String TAG = Task.class.getSimpleName();
|
|
|
|
|
|
// 定义一个布尔变量来表示任务是否完成
|
|
|
private boolean mCompleted;
|
|
|
|
|
|
// 定义一个字符串变量来存储与任务相关的笔记
|
|
|
private String mNotes;
|
|
|
|
|
|
// 定义一个JSONObject变量来存储任务的元数据
|
|
|
private JSONObject mMetaInfo;
|
|
|
|
|
|
// 定义一个Task变量来表示任务的前一个同级任务
|
|
|
private Task mPriorSibling;
|
|
|
|
|
|
// 定义一个TaskList变量来表示任务所属的父任务列表
|
|
|
private TaskList mParent;
|
|
|
|
|
|
// Task类的构造函数,初始化所有成员变量
|
|
|
public Task() {
|
|
|
super();
|
|
|
mCompleted = false; // 任务初始化为未完成状态
|
|
|
mNotes = null; // 笔记初始化为null
|
|
|
mPriorSibling = null; // 前一个同级任务初始化为null
|
|
|
mParent = null; // 父任务列表初始化为null
|
|
|
mMetaInfo = null; // 元数据初始化为null
|
|
|
}
|
|
|
|
|
|
// 获取创建任务的JSON对象的方法
|
|
|
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);
|
|
|
|
|
|
// 设置action_id
|
|
|
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
|
|
|
|
|
|
// 设置任务在其父列表中的索引位置
|
|
|
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this));
|
|
|
|
|
|
// 创建一个新的JSONObject对象来表示任务的实体信息
|
|
|
JSONObject entity = new JSONObject();
|
|
|
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); // 设置任务名称
|
|
|
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); // 设置创建者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); // 将实体信息添加到JSON对象中
|
|
|
|
|
|
// 设置父任务的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(); // 打印异常堆栈信息
|
|
|
throw new ActionFailureException("fail to generate task-create jsonobject"); // 抛出自定义异常
|
|
|
}
|
|
|
|
|
|
return js; // 返回创建的JSON对象
|
|
|
}
|
|
|
|
|
|
// 获取更新任务的JSON对象的方法
|
|
|
public JSONObject getUpdateAction(int actionId) {
|
|
|
JSONObject js = new JSONObject(); // 创建一个新的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());
|
|
|
|
|
|
// 创建一个新的JSONObject对象来表示任务的实体信息
|
|
|
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) { // 检查JSON对象是否为null
|
|
|
try {
|
|
|
// id
|
|
|
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { // 检查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) { // 捕获JSON解析异常
|
|
|
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)) { // 检查JSON对象是否为null或缺少必要的字段
|
|
|
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)) { // 检查MIME类型是否为笔记
|
|
|
setName(data.getString(DataColumns.CONTENT)); // 设置名称
|
|
|
break; // 找到后退出循环
|
|
|
}
|
|
|
}
|
|
|
|
|
|
} catch (JSONException e) { // 捕获JSON解析异常
|
|
|
Log.e(TAG, e.toString()); // 打印错误日志
|
|
|
e.printStackTrace(); // 打印堆栈跟踪
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 从内容获取本地JSON对象
|
|
|
public JSONObject getLocalJSONFromContent() {
|
|
|
String name = getName(); // 获取名称
|
|
|
try {
|
|
|
if (mMetaInfo == null) { // 检查元数据是否为null
|
|
|
// new task created from web
|
|
|
if (name == null) { // 检查名称是否为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 {
|
|
|
// 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)) { // 检查MIME类型是否为笔记
|
|
|
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; // 返回null
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 设置元数据
|
|
|
public void setMetaInfo(MetaData metaData) {
|
|
|
if (metaData != null && metaData.getNotes() != null) { // 检查MetaData对象和Notes字段是否为null
|
|
|
try {
|
|
|
mMetaInfo = new JSONObject(metaData.getNotes()); // 将Notes字段转换为JSON对象
|
|
|
} catch (JSONException e) { // 捕获JSON解析异常
|
|
|
Log.w(TAG, e.toString()); // 打印警告日志
|
|
|
mMetaInfo = null; // 将元数据设置为null
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// 定义一个方法,用于从Cursor中获取同步操作类型
|
|
|
public int getSyncAction(Cursor c) {
|
|
|
try {
|
|
|
// 初始化一个JSONObject用于存储笔记信息
|
|
|
JSONObject noteInfo = null;
|
|
|
// 检查是否存在元数据,并且元数据中包含笔记头部信息
|
|
|
if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) {
|
|
|
noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
|
|
|
}
|
|
|
|
|
|
// 如果noteInfo为空,表示笔记元数据已被删除
|
|
|
if (noteInfo == null) {
|
|
|
Log.w(TAG, "it seems that note meta has been deleted");
|
|
|
return SYNC_ACTION_UPDATE_REMOTE; // 返回更新远程的操作
|
|
|
}
|
|
|
|
|
|
// 检查noteInfo中是否包含笔记ID
|
|
|
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; // ID不匹配,返回更新本地的操作
|
|
|
}
|
|
|
|
|
|
// 检查本地是否有修改
|
|
|
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; // gtask ID不匹配,返回错误
|
|
|
}
|
|
|
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;
|
|
|
}
|
|
|
} |