From 4ede76117cd0717b6a8f818587baa008402fcd06 Mon Sep 17 00:00:00 2001 From: yfyl1005 <2812723117@qq.com> Date: Tue, 18 Apr 2023 11:19:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A0=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/标注/210340061_林亭旭/Task.java | 396 +++++++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 doc/标注/210340061_林亭旭/Task.java diff --git a/doc/标注/210340061_林亭旭/Task.java b/doc/标注/210340061_林亭旭/Task.java new file mode 100644 index 0000000..229001e --- /dev/null +++ b/doc/标注/210340061_林亭旭/Task.java @@ -0,0 +1,396 @@ +/* + * 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; +//包含了一些用于处理GTask(Google Task)相关数据的类。具体来说,这些类实现了将本地笔记同步到Google Task中,以及从Google Task中同步笔记到本地的功能。 + +import android.database.Cursor;//引入Android类cursor(为Android提供接口用于访问数据源中的数据,并支持对数据进行查询、排序、更新等操作。) +import android.text.TextUtils;// 引入Android类TextUtilsAndroid提供的一个工具类,包含了一些字符串处理相关的方法,如检查字符串是否为空、去除字符串两端的空格等 +import android.util.Log;//引入Android类Log是Android提供的一个工具类,用于在开发和调试过程中输出日志信息 + +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;//是一个字符串处理工具类,定义了一些与Google Task有关的字符串处理方法 + +import org.json.JSONArray;//是一个表示JSON数组的类,可以方便地读取和操作JSON数组中的元素。 +import org.json.JSONException;//是一个异常类,表示在解析JSON数据时发生了错误。 +import org.json.JSONObject;//是一个表示JSON对象的类,可以方便地读取和操作JSON对象中的属性和值。 +public class Task extends Node//定义了一个Task类,继承自Node类 +{ + private static final String TAG = Task.class.getSimpleName(); + + private boolean mCompleted;//表示任务是否已完成 + + private String mNotes;//表示任务的注释信息 + + private JSONObject mMetaInfo;//表示任务的元信息,是一个JSONObject对象 + + private Task mPriorSibling;//表示该任务在同级任务中的前一个任务对象 + + private TaskList mParent;//表示该任务所属的任务列表对象 + + public Task() { + super(); + mCompleted = false; + mNotes = null; + mPriorSibling = null; + mParent = null; + mMetaInfo = null; + }//无参构造函数,初始化所有属性值均为null或false + + public JSONObject getCreateAction(int actionId) + //getCreateAction方法接收一个整型参数actionId,将该参数作为返回JSONObject对象的action_id属性值。 + { + JSONObject js = new 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); + + // index,父任务列表中的索引 + js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this)); + + // entity_delta一个JSONObject对象 + 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,//实体类数据task + GTaskStringUtils.GTASK_JSON_TYPE_TASK); + if (getNotes() != null) + //如果任务有注释,则设置notes属性表示任务注释信息。 + { + entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); + } + js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); + + // parent_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 + 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。 + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to generate task-create jsonobject"); + } + //如果在生成JSONObject对象时发生异常,则会抛出一个自定义异常ActionFailureException。 + return js; + } + + public JSONObject getUpdateAction(int actionId) + //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属性值为该任务的gid。 + // 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.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"); + }//如果在生成JSONObject对象时发生异常,则会抛出一个自定义异常ActionFailureException。 + + return js; + } + + public void setContentByRemoteJSON(JSONObject js) + //定义了一个setContentByRemoteJSON方法,该方法从远程JSON对象中获取任务的属性值,并将这些属性值设置到本地任务对象中 + //表示从远程服务器获取的任务信息 + { + if (js != null) //首先检查传入的JSON对象是否为空,如果不是空对象,则依次从JSON对象中获取以下属性值 + { + try { + // id + if (js.has(GTaskStringUtils.GTASK_JSON_ID)) + //id属性值,并调用setGid方法将其赋值给本地任务对象的gid属性 + { + setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); + } + + // last_modified + if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { + setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); + }//last_modified属性值,并调用setLastModified方法将其赋值给本地任务对象的lastModified属性 + + // name + if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { + setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); + }//name属性值,并调用setName方法将其赋值给本地任务对象的name属性 + + // notes + if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) { + setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES)); + }//notes属性值,并调用setNotes方法将其赋值给本地任务对象的notes属性 + + // deleted + if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) { + setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED)); + }//deleted属性值,并调用setDeleted方法将其赋值给本地任务对象的deleted属性 + + // completed + if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) { + setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED)); + }//completed属性值,并调用setCompleted方法将其赋值给本地任务对象的completed属性 + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + throw new ActionFailureException("fail to get task content from jsonobject"); + }//如果在解析JSON对象时发生异常,则会抛出一个自定义异常ActionFailureException + } + } + + public void setContentByLocalJSON(JSONObject js) + //定义了一个setContentByLocalJSON方法,该方法从本地JSON对象中获取任务的属性值,并将这些属性值设置到本地任务对象中 + //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"); + }//该方法首先检查传入的JSON对象是否为空,以及是否包含必要属性。如果不满足这些条件,则打印一条警告日志并退出方法 + + try { + JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); +//从JSON对象中获取META_HEAD_NOTE和META_HEAD_DATA属性的值,并分别赋给变量note和dataArray + if (note.getInt(NoteColumns.TYPE) != Notes.TYPE_NOTE) { + Log.e(TAG, "invalid type"); + return; + } +//该方法检查获取到的note对象的type属性是否为Notes.TYPE_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; + } + }//该方法遍历dataArray数组中的每个元素,找到mime_type属性为DataConstants.NOTE的元素,并将其content属性值赋给本地任务对象的name属性 + + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + }//如果在解析JSON对象时发生异常,则会打印一条错误日志 + } + + public JSONObject getLocalJSONFromContent() + //定义了一个getLocalJSONFromContent方法,该方法从本地任务对象中获取任务的属性值,并将这些属性值构造成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; + } +//根据任务的元信息(即mMetaInfo属性),判断任务是从Web端创建还是同步而来。如果任务的元信息为空,则认为该任务是从Web端创建的。 + + 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;//对于从Web端创建的任务,如果任务名称为空,则会打印一条警告日志并返回null。 + // 否则,该方法构造一个JSONObject对象,其中包含META_HEAD_DATA和META_HEAD_NOTE两个属性 + // 并将任务的名称设置为META_HEAD_DATA属性所表示的JSONArray对象中的data属性值 + } else { + // synced task + JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA); + //对于同步而来的任务,该方法首先获取任务的META_HEAD_DATA和META_HEAD_NOTE属性的值, + 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; + } + }//遍历META_HEAD_DATA属性值所表示的JSONArray对象中的所有元素,找到mime_type属性为DataConstants.NOTE的元素,并将其content属性值设置为本地任务对象的名称 + + note.put(NoteColumns.TYPE, Notes.TYPE_NOTE); + return mMetaInfo; + }//最后,该方法将note对象的type属性设置为Notes.TYPE_NOTE,并返回元信息对应的JSONObject对象 + } catch (JSONException e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + return null; + }//如果在构造JSON对象时发生异常,则会打印一条错误日志,并返回null + } + + public void setMetaInfo(MetaData metaData) //用于设置mMetaInfo属性 + //接收一个MetaData对象参数metaData + { + if (metaData != null && metaData.getNotes() != null) { + try { + mMetaInfo = new JSONObject(metaData.getNotes()); + } + //metaData不为空并且其notes属性不为空字符串,则将notes属性值解析为JSON对象,并将其赋给mMetaInfo属性 + catch (JSONException e) { + Log.w(TAG, e.toString()); + mMetaInfo = null; + }//如果在解析JSON对象时发生异常,则会打印一条警告日志并将mMetaInfo属性赋为null + }//如果metaData对象或者其notes属性为空,则不会对mMetaInfo属性做任何更改 + } + + 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); + }//mMetaInfo属性,中获取与任务相关联的笔记信息 + + if (noteInfo == null) { + Log.w(TAG, "it seems that note meta has been deleted"); + return SYNC_ACTION_UPDATE_REMOTE; + }//// 如果不存在,则会打印一条警告日志并返回SYNC_ACTION_UPDATE_REMOTE操作类型 + + if (!noteInfo.has(NoteColumns.ID)) { + Log.w(TAG, "remote note id seems to be deleted"); + return SYNC_ACTION_UPDATE_LOCAL; + }//检查笔记信息中是否存在NoteColumns.ID属性, + // 如果不存在,则会打印一条警告日志并返回SYNC_ACTION_UPDATE_LOCAL操作类型 + + // 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; + }//获取查询结果集c中的本地笔记的id属性值,并将其与笔记信息中的NoteColumns.ID属性值进行比较。 + // 如果两者不相等,则会打印一条警告日志并返回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 + return SYNC_ACTION_NONE; + } else { + // apply remote to local + return SYNC_ACTION_UPDATE_LOCAL; + }//根据本地笔记对象的LOCAL_MODIFIED_COLUMN属性值是否为0来确定是否存在本地更新。如果该属性值为0,则表示没有本地更新。 + // 如果本地笔记对象的SYNC_ID_COLUMN属性值等于当前任务对象的最后修改时间,则表示两者都没有更新 + // 返回SYNC_ACTION_NONE操作类型;否则,返回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; + } + if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { + // local modification only + return SYNC_ACTION_UPDATE_REMOTE; + } else { + return SYNC_ACTION_UPDATE_CONFLICT; + }//如果本地笔记对象的LOCAL_MODIFIED_COLUMN属性值不为0,则表示存在本地更新。 + // 此时,检查SqlNote.GTASK_ID_COLUMN属性值是否与当前任务对象的Google Task ID相等。 + // 如果不相等,打印一条错误日志并返回SYNC_ACTION_ERROR操作类型。 + // 接着,比较本地笔记对象的SYNC_ID_COLUMN属性值与getLastModified()方法返回值是否相等。 + // 如果相等,则表示只存在本地更新,返回SYNC_ACTION_UPDATE_REMOTE操作类型; + // 否则,返回SYNC_ACTION_UPDATE_CONFLICT操作类型 + } + } catch (Exception e) { + Log.e(TAG, e.toString()); + e.printStackTrace(); + } + + return SYNC_ACTION_ERROR; + }//如果在执行过程中发生异常,则会打印一条错误日志并返回SYNC_ACTION_ERROR操作类型。 + + public boolean isWorthSaving() { + return mMetaInfo != null || (getName() != null && getName().trim().length() > 0) + || (getNotes() != null && getNotes().trim().length() > 0); + }//isWorthSaving()方法用于判断当前任务对象是否值得保存,返回一个布尔值。 + //该方法会判断以下三种情况,只要其中任意一种情况成立,则返回true,表示该任务对象值得保存: + //mMetaInfo属性不为null,即当前任务对象存在元信息。 + //getName()方法返回值不为null且去除空格后长度大于0,表示当前任务对象的名称不为空。 + //getNotes()方法返回值不为null且去除空格后长度大于0,表示当前任务对象的笔记内容不为空。 + //如果上述所有条件都不成立,则返回false,表示当前任务对象不值得保存 + + 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; + } + +}