From b8beeef5aee1fc92f56cf3a034275ee4f35c1722 Mon Sep 17 00:00:00 2001 From: jinjiayi <2590141031@qq.com> Date: Thu, 20 Apr 2023 21:59:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/标注/210340054_金佳艺/Task.java | 365 ++++++++++++++++ doc/标注/210340054_金佳艺/TaskList.java | 431 +++++++++++++++++++ 2 files changed, 796 insertions(+) create mode 100644 doc/标注/210340054_金佳艺/Task.java create mode 100644 doc/标注/210340054_金佳艺/TaskList.java diff --git a/doc/标注/210340054_金佳艺/Task.java b/doc/标注/210340054_金佳艺/Task.java new file mode 100644 index 0000000..fd99fe7 --- /dev/null +++ b/doc/标注/210340054_金佳艺/Task.java @@ -0,0 +1,365 @@ +/* + * 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. + */ + //Task代码注释 + //主要作用:同步任务,将创建、更新和同步动作包装成JSON对象,同时使用本地和远程的JSON对结点内容进行设置,从而获取同步信息,实现本地和远程的信息同步 +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; + + +public class Task extends Node { //定义一个Task类,继承Node类 + private static final String TAG = Task.class.getSimpleName(); + //调用函数得到类简写名称并存入字符串TAG内 + private boolean mCompleted; //判断当前任务是否完成 + + private String mNotes; //在实例中存储数据的类型,表示任务的注释信息 + + private JSONObject mMetaInfo; //将在实例中存储数据的类型 + + private Task mPriorSibling; //对应的优先兄弟Task的指针 + + private TaskList mParent; //所在的任务列表的指针 + + public Task() { + super(); + mCompleted = false; + mNotes = null; + mPriorSibling = null; //TaskList中当前Task前面的Task的指针 + mParent = null; //当前Task所在的TaskList + mMetaInfo = null; + } + + public JSONObject getCreateAction(int actionId) { + //getCreateAction方法接收一个整型参数actionId,将该参数作为返回JSONObject对象的action_id属性值。 + JSONObject js = new JSONObject(); + + try { + // action_type + js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, //存入当前task指针 + GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE); + //发送对actiontype的请求 + // action_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"); //对任务创建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); //讲实体存入js + + // 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); //所在列表的id存入父id + + // 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 + //将其优先存入ID序列中 + } catch (JSONException e) { + Log.e(TAG, e.toString()); //e.toString()获取异常类型和异常详细消息 + e.printStackTrace(); + throw new ActionFailureException("fail to generate task-create jsonobject"); + } //抛出异常处理机制 + + return js; + } + + public JSONObject getUpdateAction(int actionId) { //更新action + //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 + 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 中 + 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"); + } //生成任务更新的数据传输失败 + + return js; + } + + public void setContentByRemoteJSON(JSONObject js) //通过云端传输数据设置内容 + //定义了一个setContentByRemoteJSON方法,该方法从远程JSON对象中获取任务的属性值,并将这些属性值设置到本地任务对象中 + //表示从远程服务器获取的任务信息 + + { + if (js != null) { + try { + // id + if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { //如果js指针指向的目标存在 + setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); //利用类自身的set函数,并且使用了JSONObject的get类型函数 + } //判断记录是否被删除 + + // 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"); + } + } + } + + public void setContentByLocalJSON(JSONObject js) { //通过本地的jsonobject获取内容 + if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE) + || !js.has(GTaskStringUtils.META_HEAD_DATA)) { //如果js不存在或者js没有元数据的开头或者js指针没有元数据 + 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) { //note类型不匹配 + Log.e(TAG, "invalid type"); //无效 + return; + } + + for (int i = 0; i < dataArray.length(); i++) { + //遍历 dataArray 查找与数据库中DataConstants.NOTE 记录信息一致的 data + 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(); + } + } + + public JSONObject getLocalJSONFromContent() { //从content获取本地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; + } + //若命名为空则创建一个新的 + + 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; + } + }//通过循环查找与数据库中DataConstants.NOTE 记录信息一致的 data + + 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; + } + } //如果元数据非空且其 notes 非空,则修改元数据类型信息 + } + + public int getSyncAction(Cursor c) { //实现同步操作 + try { + JSONObject noteInfo = null; //新建一个 JSONObject 的对象实体 + if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) { + noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + } //元数据信息不为空并且元数据信息还含有“META_HEAD_NOTE”,说明便签存在 + + if (noteInfo == null) { + Log.w(TAG, "it seems that note meta has been deleted"); + return SYNC_ACTION_UPDATE_REMOTE; + } //云端便签 id 已被删除,不存在,返回更新本地数据的同步行为 + + if (!noteInfo.has(NoteColumns.ID)) { + Log.w(TAG, "remote note id seems to be deleted"); + return SYNC_ACTION_UPDATE_LOCAL; + } //匹配note的id + + // 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; //判断修改后的ID匹配是否成功,成功则返回无同步操作,未成功则应用云端到本地,返回本地同步更新操作 + } + + 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; + } + } else { + // validate gtask id + if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) { + //判断gtask的id与获取的id是否匹配 + Log.e(TAG, "gtask id doesn't match"); //错误,未找到 gtask 的 id + return SYNC_ACTION_ERROR; + } + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { + ////错误,未找到 gtask 的 id + // 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; + } + + 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; + } //设定note成员变量 + + public void setPriorSibling(Task priorSibling) { + this.mPriorSibling = priorSibling; + } //设置优先兄弟 task 的优先级 + + public void setParent(TaskList parent) { + this.mParent = parent; + } //设置父类节点 + + public boolean getCompleted() { + return this.mCompleted; + } //判断是否完成 + + public String getNotes() { + return this.mNotes; + } //获取成员变量 mNotes 的信息 + + public Task getPriorSibling() { + return this.mPriorSibling; + } //获取优先兄弟列表 + + public TaskList getParent() { + return this.mParent; + } //获取父类节点列表 + +} diff --git a/doc/标注/210340054_金佳艺/TaskList.java b/doc/标注/210340054_金佳艺/TaskList.java new file mode 100644 index 0000000..7abba2c --- /dev/null +++ b/doc/标注/210340054_金佳艺/TaskList.java @@ -0,0 +1,431 @@ +/* + * 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. + */ + //TaskList代码标注 + //主要作用:同步任务列表,将Task组织成同步任务列表进行管理 +package net.micode.notes.gtask.data; + +import android.database.Cursor; +import android.util.Log; + +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.gtask.exception.ActionFailureException; +import net.micode.notes.tool.GTaskStringUtils; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + + +public class TaskList extends Node {//创建继承 Node的任务表类 + private static final String TAG = TaskList.class.getSimpleName(); //tag标记 + //调用getSimplename()函数获取名字并赋值给TAG作为标记 + private int mIndex; //当前TaskList的指针 + + private ArrayList mChildren; //类中主要的保存数据的单元,用来实现一个以Task为元素的ArrayList + + + public TaskList() { //构造函数进行初始化 + super(); //调用父类构造方法 + mChildren = new ArrayList(); //声明数组 + mIndex = 1; + } + + /* (non-Javadoc) + * @see net.micode.notes.gtask.data.Node#getCreateAction(int) + * 生成并返回一个包含了一定数据的JSONObject实体 + */ + + 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); + //操作的是列表,而不只是单个task了 + // action_id + js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); + + // index + js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex); + + // entity_delta + // 新建一个 JSONObject 对象,名为实体,将 name,creator id,entity type 三个信息存在一起 + JSONObject entity = new JSONObject(); //创建一个实体类并进行初始化 + entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + //getName是父类的一个函数 + entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); + //初始化id + entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE, + GTaskStringUtils.GTASK_JSON_TYPE_GROUP); + //将实体类型设置为“GROUP” + js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to generate tasklist-create jsonobject"); + } + + return js; + } + + /* (non-Javadoc) + * @see net.micode.notes.gtask.data.Node#getUpdateAction(int) + * 生成并返回一个包含了一定数据的JSONObject实体 + */ + + public JSONObject getUpdateAction(int actionId) { //接受更新action,返回jsonobject + JSONObject js = new 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()); + + // entity_delta + JSONObject entity = new JSONObject(); + entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + 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(); + throw new ActionFailureException("fail to generate tasklist-update jsonobject"); + } + + return js; + } + + public void setContentByRemoteJSON(JSONObject js) { + //通过云端 JSON 数据设置实例化对象 js 的内容 + if (js != null) { + try { + // id + if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { + setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); + } + //判断js对象是否为空,如果为空即没有内容就不需要进行设置了 + + // last_modified + if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { + setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); + } + //调用JSONObject中的getLong函数,得到last_modified的号,并作为参数传给setLastModified函数(父类函数)进行设置 + + // name + if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { + setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); + } //对任务的name进行设置 + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to get tasklist content from jsonobject"); + } + } + } + + public void setContentByLocalJSON(JSONObject js) { //通过本地 JSON 数据设置对象 js 内容 + if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) { + //若 js 创建失败或 js 中不存在 META_HEAD_NOTE信息 + Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); + } //警告,没有可用资源 + + try { + JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + //NullPointerException这个异常出现在处理对象时对象不存在但又没有捕捉到进行处理的时候 + + if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { + //对文件夹,设置文件名 + String name = folder.getString(NoteColumns.SNIPPET); + //获取文件夹片段字符串作为文件夹名称 + setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + name); + //设置名称为MIUI系统文件夹前缀+文件夹名称 + } else if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { + //判断是不是系统文件 + if (folder.getLong(NoteColumns.ID) == Notes.ID_ROOT_FOLDER) + setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT); + //如果是根文件夹,设置名称:MIUI系统文件夹前缀+默认文件夹名称 + else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER) + setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + + GTaskStringUtils.FOLDER_CALL_NOTE); + //如果是通话文件夹,设置名称:MIUI系统文件夹前缀+通话便签文件夹名称 + else + Log.e(TAG, "invalid system folder"); + ;//无效系统文件夹警告 + } else { + Log.e(TAG, "error type"); + //错误的文件夹类型 + } + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + } + + public JSONObject getLocalJSONFromContent() { //从content获取本地json + try { + JSONObject js = new JSONObject(); //创建对象并初始化 + JSONObject folder = new JSONObject(); //创建文件夹对象并初始化 + + String folderName = getName(); + if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX)) + folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(), + folderName.length()); + folder.put(NoteColumns.SNIPPET, folderName); + //如果获取的文件夹名称是以[MIUI_Notes]开头,则文件夹名称应删掉前缀 + if (folderName.equals(GTaskStringUtils.FOLDER_DEFAULT) + || folderName.equals(GTaskStringUtils.FOLDER_CALL_NOTE)) + folder.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + //这里与上一个函数setContentByRemoteJSON(JSONObject js)是一个逆过程,可以参看上一个函数是如何构造出foldername的 + else + folder.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); + + js.put(GTaskStringUtils.META_HEAD_NOTE, folder); + + return js; + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return null; + } + } + + public int getSyncAction(Cursor c) { //获取同步信息 + try { + 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; + } //匹配失败,返回更新本地数据的同步行为 + } 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; + } //如果获取的ID不匹配,返回同步动作失败 + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { + // local modification only + return SYNC_ACTION_UPDATE_REMOTE; + //如果是最近一次修改的 id,则返回云端更新的同步动作 + } else { + // for folder conflicts, just apply local modification + return SYNC_ACTION_UPDATE_REMOTE; + } + } + } catch (Exception e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + + return SYNC_ACTION_ERROR; + } + + + // @return + //功能:获得TaskList的大小,即mChildren的大小 + + public int getChildTaskCount() { + + return mChildren.size(); + } + + //获得TaskList的大小,即mChildren的大小,mChildren 是TaskList 的一个实例 + //@param task + //@return 返回值为是否成功添加任务。 + //功能:在当前任务表末尾添加新的任务。 + + public boolean addChildTask(Task task) { + boolean ret = false; + if (task != null && !mChildren.contains(task)) { //任务非空且任务表中不存在该任务 + ret = mChildren.add(task); + if (ret) { + // need to set prior sibling and parent + task.setPriorSibling(mChildren.isEmpty() ? null : mChildren + .get(mChildren.size() - 1)); + task.setParent(this); + //ArrayList的每一次修改变化都要紧跟相关Task中PriorSibling的修改 + } + } + return ret; + } + + /** + * @param task + * @param index + * @return + * 功能:在当前任务表的指定位置添加新的任务。 + */ + + public boolean addChildTask(Task task, int index) { + if (index < 0 || index > mChildren.size()) { + Log.e(TAG, "add child task: invalid index"); + return false; + } + //在当前任务表的指定位置添加新的任务,index是指针 + + int pos = mChildren.indexOf(task); + if (task != null && pos == -1) { + mChildren.add(index, task); + //获取要添加的任务在列表中的位置,如果不在列表中则返回-1 + + // update the task list + Task preTask = null; //更新任务表 + Task afterTask = null; + if (index != 0) + preTask = mChildren.get(index - 1); + if (index != mChildren.size() - 1) + afterTask = mChildren.get(index + 1); + + task.setPriorSibling(preTask); //使得前后三个任务连在一起 + if (afterTask != null) + afterTask.setPriorSibling(task); + } + + return true; + } + + /** + * @param task + * @return 返回删除是否成功 + * 功能:删除TaskList中的一个Task + */ + + public boolean removeChildTask(Task task) { //删除任务表中的子任务 + boolean ret = false; + int index = mChildren.indexOf(task); //获取该任务在任务表中的索引 + if (index != -1) { //索引有效,任务在表中存在 + ret = mChildren.remove(task); //移除任务 + + if (ret) { + // reset prior sibling and parent + task.setPriorSibling(null); + task.setParent(null); //删除成功,task的上一个任务指针和父指针置空 + + // update the task list + if (index != mChildren.size()) { + mChildren.get(index).setPriorSibling( + index == 0 ? null : mChildren.get(index - 1)); + } //删除成功后,要对任务列表进行更新 + } + } + return ret; + } + + /** + * @param task + * @param index + * @return + * 功能:将当前TaskList中含有的某个Task移到index位置 + */ + + public boolean moveChildTask(Task task, int index) { + + if (index < 0 || index >= mChildren.size()) { + Log.e(TAG, "move child task: invalid index"); + return false; + } + + int pos = mChildren.indexOf(task); + if (pos == -1) { + Log.e(TAG, "move child task: the task should in the list"); + return false; + } + + if (pos == index) + return true; + return (removeChildTask(task) && addChildTask(task, index)); + } + //利用已经实现好的功能完成当下功能 + + /** + * @param gid + * @return返回寻找结果 + * 功能:按gid寻找Task + */ + + public Task findChildTaskByGid(String gid) { + for (int i = 0; i < mChildren.size(); i++) { + Task t = mChildren.get(i); + if (t.getGid().equals(gid)) { + return t; + } + } + return null; + } + + /** + * @param task + * @return + * 功能:返回指定Task的index + */ + public int getChildTaskIndex(Task task) { + return mChildren.indexOf(task); + } + + /** + * @param index + * @return + * 功能:返回指定index的Task + */ + public Task getChildTaskByIndex(int index) { + if (index < 0 || index >= mChildren.size()) { + Log.e(TAG, "getTaskByIndex: invalid index"); //如果指针不在范围内,无效索引 + return null; + } + return mChildren.get(index); + } + + /** + * @param gid + * @return + * 功能:返回指定gid的Task + */ + public Task getChilTaskByGid(String gid) { + for (Task task : mChildren) { //ArrayList的遍历方法 //通过索引获取子任务 + if (task.getGid().equals(gid)) + return task; + } + return null; + } + + public ArrayList getChildTaskList() { + return this.mChildren; + } //获取子任务列表 + + public void setIndex(int index) { + this.mIndex = index; + } //设置任务索引 + + public int getIndex() { + return this.mIndex; + } //获取任务索引 +}