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.
123456/java/net/micode/notes/gtask/data/SqlData.java

243 lines
13 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.
* 这段 Java 代码定义了Task类它继承自抽象类Node是用于处理任务相关数据及操作的核心类围绕任务在与 GTask 数据交互(如创建、更新动作对应的 JSON 构建,以及从 JSON 解析数据等)、同步操作判断、数据完整性判断(是否值得保存)以及各类属性设置与获取等方面构建功能逻辑。类中通过对抽象方法的实现,规范了任务数据在不同场景下的序列化与反序列化操作,同时结合自身属性(如完成状态、备注信息、关联的前置任务和父任务列表等),全方位地对任务对象进行管理与操作,在涉及任务数据的同步、展示与持久化存储等业务场景中起着关键作用。
函数分析
Task类构造函数
所属类Task
功能调用父类构造函数进行初始化后对自身特有的属性进行初始化将完成状态设为false备注信息设为null前置任务设为null父任务列表设为null元数据信息设为null为后续根据业务需求设置这些属性值准备初始状态。
getCreateAction方法
所属类Task
功能创建一个新的JSONObject对象按照 GTask 相关的数据格式要求向其中添加如动作类型创建、动作ID、任务在父任务列表中的索引、任务实体相关数据名称、创建者ID、类型、备注等、父任务ID、目标父任务类型、列表ID以及前置任务ID若存在等信息若添加过程出现JSONException则记录错误日志、打印堆栈信息并抛出异常最终返回构建好的用于创建任务的JSONObject用于生成创建任务操作对应的 JSON 数据结构。
getUpdateAction方法
所属类Task
功能同样先创建一个JSONObject对象然后依据 GTask 格式规范向其中添加动作类型更新、动作ID、任务ID以及任务实体更新相关的数据名称、备注、删除状态等若出现JSONException则记录错误日志、打印堆栈信息并抛出异常最后返回该JSONObject用于构建任务更新操作对应的 JSON 数据内容。
setContentByRemoteJSON方法
所属类Task
功能在传入的JSONObject不为null的前提下尝试从其中获取并设置任务的相关属性信息包括ID、最后修改时间、名称、备注、删除状态以及完成状态等若获取过程出现JSONException则记录错误日志、打印堆栈信息并抛出异常用于根据远程传来的 JSON 数据更新任务对象的属性内容。
setContentByLocalJSON方法
所属类Task
功能先对传入的JSONObject进行有效性判断若不符合要求则记录警告日志若符合则尝试从中解析出笔记相关信息进一步判断笔记类型是否合法然后遍历数据数组找到类型为普通笔记的数据项将其内容设置为任务的名称用于依据本地 JSON 数据设置任务的名称等相关属性。
getLocalJSONFromContent方法
所属类Task
功能根据元数据信息mMetaInfo是否为null分情况处理若为null且任务名称也为null则记录警告日志并返回null否则构建一个新的JSONObject按照特定格式填充任务相关数据如笔记内容、类型等并返回若mMetaInfo不为null则从其中获取并更新对应的数据如将任务名称更新到相关数据项中最后返回处理后的JSONObject用于生成基于任务当前内容的本地 JSON 数据表示形式。
setMetaInfo方法
所属类Task
功能在传入的MetaData对象不为null且其备注信息不为null的情况下尝试将备注信息转换为JSONObject并赋值给mMetaInfo属性若转换出现JSONException则记录警告日志并将mMetaInfo设为null用于设置任务的元数据信息方便后续基于元数据进行相关操作与判断。
getSyncAction方法
所属类Task
功能通过一系列复杂的条件判断来确定任务的同步操作类型首先尝试获取元数据中的笔记相关信息基于其是否存在以及笔记ID等信息与游标数据的对比结合本地是否有更新、同步ID与最后修改时间是否匹配、GTask ID是否一致等多方面因素按照不同情况返回对应的同步操作类型常量如无操作、本地更新、远程更新、更新冲突、出现错误等若过程中出现异常则记录错误日志并打印堆栈信息用于判断任务在数据同步过程中的操作类型。
isWorthSaving方法
所属类Task
功能通过判断元数据信息是否为null以及任务名称和备注信息去除空白字符后长度是否大于0等条件返回表示任务是否值得保存的布尔值用于确定任务对象当前的数据状态是否有保存的必要。
setCompleted方法
所属类Task
功能接收一个布尔型参数completed将其赋值给mCompleted属性用于设置任务的完成状态满足业务场景中对任务完成与否的标记需求。
setNotes方法
所属类Task
功能传入一个字符串参数notes将其赋值给mNotes属性用于更新任务的备注信息方便在不同阶段修改任务的相关说明内容。
setPriorSibling方法
所属类Task
功能接受一个Task类型的参数priorSibling将其赋值给mPriorSibling属性用于设置任务的前置任务构建任务之间的先后顺序关联关系。
setParent方法
所属类Task
功能接收一个TaskList类型的参数parent将其赋值给mParent属性用于设置任务所属的父任务列表确立任务在任务层级结构中的归属关系。
getCompleted方法
所属类Task
功能返回mCompleted属性的值也就是任务的完成状态用于获取任务是否已完成的相关信息便于展示、筛选等业务操作。
getNotes方法
所属类Task
功能返回mNotes属性的值即任务的备注信息用于获取任务的相关说明内容在查看、编辑任务详情等场景下会用到。
getPriorSibling方法
所属类Task
功能返回mPriorSibling属性的值也就是任务的前置任务对象方便在处理任务顺序、依赖关系等业务逻辑中获取前置任务相关信息。
getParent方法
所属类Task
功能返回mParent属性的值即任务所属的父任务列表对象用于获取任务在任务层级结构中的上层归属信息有助于进行任务分组、层级展示等操作。
*/
package net.micode.notes.gtask.data;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
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.data.NotesDatabaseHelper.TABLE;
import net.micode.notes.gtask.exception.ActionFailureException;
import org.json.JSONException;
import org.json.JSONObject;
public class SqlData {
private static final String TAG = SqlData.class.getSimpleName();
private static final int INVALID_ID = -99999;
public static final String[] PROJECTION_DATA = new String[] {
DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1,
DataColumns.DATA3
};
public static final int DATA_ID_COLUMN = 0;
public static final int DATA_MIME_TYPE_COLUMN = 1;
public static final int DATA_CONTENT_COLUMN = 2;
public static final int DATA_CONTENT_DATA_1_COLUMN = 3;
public static final int DATA_CONTENT_DATA_3_COLUMN = 4;
private ContentResolver mContentResolver;
private boolean mIsCreate;
private long mDataId;
private String mDataMimeType;
private String mDataContent;
private long mDataContentData1;
private String mDataContentData3;
private ContentValues mDiffDataValues;
public SqlData(Context context) {
mContentResolver = context.getContentResolver();
mIsCreate = true;
mDataId = INVALID_ID;
mDataMimeType = DataConstants.NOTE;
mDataContent = "";
mDataContentData1 = 0;
mDataContentData3 = "";
mDiffDataValues = new ContentValues();
}
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
mIsCreate = false;
loadFromCursor(c);
mDiffDataValues = new ContentValues();
}
private void loadFromCursor(Cursor c) {
mDataId = c.getLong(DATA_ID_COLUMN);
mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
mDataContent = c.getString(DATA_CONTENT_COLUMN);
mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN);
mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
}
public void setContent(JSONObject js) throws JSONException {
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
if (mIsCreate || mDataId != dataId) {
mDiffDataValues.put(DataColumns.ID, dataId);
}
mDataId = dataId;
String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE)
: DataConstants.NOTE;
if (mIsCreate || !mDataMimeType.equals(dataMimeType)) {
mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType);
}
mDataMimeType = dataMimeType;
String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : "";
if (mIsCreate || !mDataContent.equals(dataContent)) {
mDiffDataValues.put(DataColumns.CONTENT, dataContent);
}
mDataContent = dataContent;
long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0;
if (mIsCreate || mDataContentData1 != dataContentData1) {
mDiffDataValues.put(DataColumns.DATA1, dataContentData1);
}
mDataContentData1 = dataContentData1;
String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : "";
if (mIsCreate || !mDataContentData3.equals(dataContentData3)) {
mDiffDataValues.put(DataColumns.DATA3, dataContentData3);
}
mDataContentData3 = dataContentData3;
}
public JSONObject getContent() throws JSONException {
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
return null;
}
JSONObject js = new JSONObject();
js.put(DataColumns.ID, mDataId);
js.put(DataColumns.MIME_TYPE, mDataMimeType);
js.put(DataColumns.CONTENT, mDataContent);
js.put(DataColumns.DATA1, mDataContentData1);
js.put(DataColumns.DATA3, mDataContentData3);
return js;
}
public void commit(long noteId, boolean validateVersion, long version) {
if (mIsCreate) {
if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) {
mDiffDataValues.remove(DataColumns.ID);
}
mDiffDataValues.put(DataColumns.NOTE_ID, noteId);
Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues);
try {
mDataId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
Log.e(TAG, "Get note id error :" + e.toString());
throw new ActionFailureException("create note failed");
}
} else {
if (mDiffDataValues.size() > 0) {
int result = 0;
if (!validateVersion) {
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null);
} else {
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues,
" ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE
+ " WHERE " + NoteColumns.VERSION + "=?)", new String[] {
String.valueOf(noteId), String.valueOf(version)
});
}
if (result == 0) {
Log.w(TAG, "there is no update. maybe user updates note when syncing");
}
}
}
mDiffDataValues.clear();
mIsCreate = false;
}
public long getId() {
return mDataId;
}
}