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.
TEST1231/作业8.txt

493 lines
21 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.

// 导入所需的类和接口
import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
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.NoteColumns;
import net.micode.notes.gtask.exception.ActionFailureException;
import net.micode.notes.tool.GTaskStringUtils;
import net.micode.notes.tool.ResourceParser;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
// 声明SqlNote类
public class SqlNote {
// 定义日志标签
private static final String TAG = SqlNote.class.getSimpleName();
// 定义无效ID常量
private static final int INVALID_ID = -99999;
// 定义从数据库查询Note时需要的列
public static final String[] PROJECTION_NOTE = new String[] {
NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID,
NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE,
NoteColumns.NOTES_COUNT, NoteColumns.PARENT_ID, NoteColumns.SNIPPET, NoteColumns.TYPE,
NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE, NoteColumns.SYNC_ID,
NoteColumns.LOCAL_MODIFIED, NoteColumns.ORIGIN_PARENT_ID, NoteColumns.GTASK_ID,
NoteColumns.VERSION
};
// 定义各列在PROJECTION_NOTE数组中的索引
public static final int ID_COLUMN = 0;
// ... 其他列的索引定义
// 类的成员变量
private Context mContext; // 应用上下文
private ContentResolver mContentResolver; // 内容解析器,用于访问内容提供者
private boolean mIsCreate; // 标记是否是新建
private long mId; // 笔记ID
// ... 其他成员变量定义
// 构造函数
public SqlNote(Context context) {
mContext = context; // 初始化上下文
mContentResolver = context.getContentResolver(); // 初始化内容解析器
mIsCreate = true; // 标记为新建
mId = INVALID_ID; // 初始化ID为无效ID
mAlertDate = 0; // 初始化提醒日期
mBgColorId = ResourceParser.getDefaultBgId(context); // 初始化背景颜色ID
mCreatedDate = System.currentTimeMillis(); // 初始化创建日期为当前时间
mHasAttachment = 0; // 初始化是否有附件标记
mModifiedDate = System.currentTimeMillis(); // 初始化修改日期为当前时间
mParentId = 0; // 初始化父ID
mSnippet = ""; // 初始化摘要
mType = Notes.TYPE_NOTE; // 初始化类型
mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; // 初始化小部件ID为无效ID
mWidgetType = Notes.TYPE_WIDGET_INVALIDE; // 初始化小部件类型
mOriginParent = 0; // 初始化原始父ID
mVersion = 0; // 初始化版本
mDiffNoteValues = new ContentValues(); // 初始化差异值存储
mDataList = new ArrayList<SqlData>(); // 初始化数据列表
}
// 构造函数通过上下文和Cursor对象来初始化SqlNote对象
public SqlNote(Context context, Cursor c) {
mContext = context; // 保存上下文引用
mContentResolver = context.getContentResolver(); // 获取内容解析器实例用于与Content Providers交互
mIsCreate = false; // 标记这个对象不是新创建的(即不是通过插入操作创建的)
loadFromCursor(c); // 从传入的Cursor加载数据
mDataList = new ArrayList<SqlData>(); // 初始化数据存储列表,用于存储笔记的附加数据
if (mType == Notes.TYPE_NOTE) // 如果笔记类型是普通笔记
loadDataContent(); // 加载笔记的详细内容
mDiffNoteValues = new ContentValues(); // 初始化ContentValues对象用于存储笔记的更改可能用于更新操作
}
// 构造函数通过上下文和笔记ID来初始化SqlNote对象
public SqlNote(Context context, long id) {
mContext = context; // 保存上下文引用
mContentResolver = context.getContentResolver(); // 获取内容解析器实例
mIsCreate = false; // 标记这个对象不是新创建的
loadFromCursor(id); // 根据笔记ID加载数据
mDataList = new ArrayList<SqlData>(); // 初始化数据存储列表
if (mType == Notes.TYPE_NOTE) // 如果笔记类型是普通笔记
loadDataContent(); // 加载笔记的详细内容
mDiffNoteValues = new ContentValues(); // 初始化ContentValues对象
}
// 私有方法根据传入的笔记ID加载数据
private void loadFromCursor(long id) {
Cursor c = null; // 声明Cursor对象
try {
// 使用内容解析器查询数据库获取指定ID的笔记数据
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)",
new String[] { String.valueOf(id) }, null);
if (c != null) {
c.moveToNext(); // 移动到Cursor的第一行如果存在
loadFromCursor(c); // 从Cursor加载数据
} else {
Log.w(TAG, "loadFromCursor: cursor = null"); // 如果Cursor为空记录警告日志
}
} finally {
if (c != null)
c.close(); // 关闭Cursor
}
}
// 私有方法从传入的Cursor加载数据到SqlNote对象的属性中
private void loadFromCursor(Cursor c) {
mId = c.getLong(ID_COLUMN); // 加载笔记ID
mAlertDate = c.getLong(ALERTED_DATE_COLUMN); // 加载提醒日期
mBgColorId = c.getInt(BG_COLOR_ID_COLUMN); // 加载背景颜色ID
mCreatedDate = c.getLong(CREATED_DATE_COLUMN); // 加载创建日期
mHasAttachment = c.getInt(HAS_ATTACHMENT_COLUMN); // 加载是否有附件的标记
mModifiedDate = c.getLong(MODIFIED_DATE_COLUMN); // 加载修改日期
mParentId = c.getLong(PARENT_ID_COLUMN); // 加载父笔记ID
mSnippet = c.getString(SNIPPET_COLUMN); // 加载摘要文本
mType = c.getInt(TYPE_COLUMN); // 加载笔记类型
mWidgetId = c.getInt(WIDGET_ID_COLUMN); // 加载小部件ID
mWidgetType = c.getInt(WIDGET_TYPE_COLUMN); // 加载小部件类型
mVersion = c.getLong(VERSION_COLUMN); // 加载版本号
}
// 私有方法,加载笔记的详细内容(如附加的数据项)
private void loadDataContent() {
Cursor c = null; // 声明Cursor对象
mDataList.clear(); // 清空数据列表,准备加载新数据
try {
// 使用内容解析器查询数据库获取指定笔记ID的所有数据项
c = mContentResolver.query(Notes.CONTENT_DATA_URI, SqlData.PROJECTION_DATA,
"(note_id=?)", new String[] { String.valueOf(mId) }, null);
if (c != null) {
if (c.getCount() == 0) {
Log.w(TAG, "it seems that the note has not data"); // 如果没有数据项,记录警告日志
return;
}
while (c.moveToNext()) { // 遍历Cursor为每一个数据项创建一个SqlData对象并添加到列表中
SqlData data = new SqlData(mContext, c);
mDataList.add(data);
}
} else {
Log.w(TAG, "loadDataContent: cursor = null"); // 如果Cursor为空记录警告日志
}
} finally {
if (c != null)
c.close(); // 关闭Cursor
}
}
// 定义一个方法接收一个JSONObject参数返回一个布尔值
public boolean setContent(JSONObject js) {
try {
// 从传入的JSONObject中获取名为GTaskStringUtils.META_HEAD_NOTE的JSONObject
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
// 判断笔记类型,如果是系统类型,则打印日志并跳过后续操作
if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) {
Log.w(TAG, "cannot set system folder");
}
// 如果是文件夹类型
else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) {
// 更新snippet和type属性如果它们是新的或者发生了变化
String snippet = note.has(NoteColumns.SNIPPET) ? note.getString(NoteColumns.SNIPPET) : "";
if (mIsCreate || !mSnippet.equals(snippet)) {
mDiffNoteValues.put(NoteColumns.SNIPPET, snippet);
}
mSnippet = snippet;
int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE) : Notes.TYPE_NOTE;
if (mIsCreate || mType != type) {
mDiffNoteValues.put(NoteColumns.TYPE, type);
}
mType = type;
}
// 如果是普通笔记类型
else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_NOTE) {
// 获取数据数组
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
// 更新ID属性
long id = note.has(NoteColumns.ID) ? note.getLong(NoteColumns.ID) : INVALID_ID;
if (mIsCreate || mId != id) {
mDiffNoteValues.put(NoteColumns.ID, id);
}
mId = id;
// 更新alertDate属性
long alertDate = note.has(NoteColumns.ALERTED_DATE) ? note.getLong(NoteColumns.ALERTED_DATE) : 0;
if (mIsCreate || mAlertDate != alertDate) {
mDiffNoteValues.put(NoteColumns.ALERTED_DATE, alertDate);
}
mAlertDate = alertDate;
// 更新bgColorId属性
int bgColorId = note.has(NoteColumns.BG_COLOR_ID) ? note.getInt(NoteColumns.BG_COLOR_ID) : ResourceParser.getDefaultBgId(mContext);
if (mIsCreate || mBgColorId != bgColorId) {
mDiffNoteValues.put(NoteColumns.BG_COLOR_ID, bgColorId);
}
mBgColorId = bgColorId;
// 更新createDate属性
long createDate = note.has(NoteColumns.CREATED_DATE) ? note.getLong(NoteColumns.CREATED_DATE) : System.currentTimeMillis();
if (mIsCreate || mCreatedDate != createDate) {
mDiffNoteValues.put(NoteColumns.CREATED_DATE, createDate);
}
mCreatedDate = createDate;
// 更新hasAttachment属性
int hasAttachment = note.has(NoteColumns.HAS_ATTACHMENT) ? note.getInt(NoteColumns.HAS_ATTACHMENT) : 0;
if (mIsCreate || mHasAttachment != hasAttachment) {
mDiffNoteValues.put(NoteColumns.HAS_ATTACHMENT, hasAttachment);
}
mHasAttachment = hasAttachment;
// 更新modifiedDate属性
long modifiedDate = note.has(NoteColumns.MODIFIED_DATE) ? note.getLong(NoteColumns.MODIFIED_DATE) : System.currentTimeMillis();
if (mIsCreate || mModifiedDate != modifiedDate) {
mDiffNoteValues.put(NoteColumns.MODIFIED_DATE, modifiedDate);
}
mModifiedDate = modifiedDate;
// 更新parentId属性
long parentId = note.has(NoteColumns.PARENT_ID) ? note.getLong(NoteColumns.PARENT_ID) : 0;
if (mIsCreate || mParentId != parentId) {
mDiffNoteValues.put(NoteColumns.PARENT_ID, parentId);
}
mParentId = parentId;
// 更新snippet属性对于普通笔记再次处理可能是因为前面处理文件夹时也用了这个名字的变量
String snippet = note.has(NoteColumns.SNIPPET) ? note.getString(NoteColumns.SNIPPET) : "";
if (mIsCreate || !mSnippet.equals(snippet)) {
mDiffNoteValues.put(NoteColumns.SNIPPET, snippet);
}
mSnippet = snippet;
// 更新type属性对于普通笔记再次处理
int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE) : Notes.TYPE_NOTE;
if (mIsCreate || mType != type) {
mDiffNoteValues.put(NoteColumns.TYPE, type);
}
mType = type;
// 更新widgetId属性
int widgetId = note.has(NoteColumns.WIDGET_ID) ? note.getInt(NoteColumns.WIDGET_ID) : AppWidgetManager.INVALID_APPWIDGET_ID;
if (mIsCreate || mWidgetId != widgetId) {
mDiffNoteValues.put(NoteColumns.WIDGET_ID, widgetId);
}
mWidgetId = widgetId;
// 更新widgetType属性
int widgetType = note.has(NoteColumns.WIDGET_TYPE) ? note.getInt(NoteColumns.WIDGET_TYPE) : Notes.TYPE_WIDGET_INVALIDE;
if (mIsCreate || mWidgetType != widgetType) {
mDiffNoteValues.put(NoteColumns.WIDGET_TYPE, widgetType);
}
mWidgetType = widgetType;
// 更新originParent属性
long originParent = note.has(NoteColumns.ORIGIN_PARENT_ID) ? note.getLong(NoteColumns.ORIGIN_PARENT_ID) : 0;
if (mIsCreate || mOriginParent != originParent) {
mDiffNoteValues.put(NoteColumns.ORIGIN_PARENT_ID, originParent);
}
mOriginParent = originParent;
// 遍历数据数组为每个数据项创建或更新SqlData对象
for (int i = 0; i < dataArray.length(); i++) {
JSONObject data = dataArray.getJSONObject(i);
SqlData sqlData = null;
// 如果数据项有ID则尝试在已有数据中查找匹配的SqlData对象
if (data.has(DataColumns.ID)) {
long dataId = data.getLong(DataColumns.ID);
for (SqlData temp : mDataList) {
if (dataId == temp.getId()) {
sqlData = temp;
}
}
}
// 如果没有找到匹配的SqlData对象则创建一个新的
if (sqlData == null) {
sqlData = new SqlData(mContext);
mDataList.add(sqlData);
}
// 更新SqlData对象的内容
sqlData.setContent(data);
}
}
} catch (JSONException e) {
// 捕获JSON异常打印错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
// 返回false表示处理失败
return false;
}
// 如果没有异常发生返回true表示处理成功
return true;
}
// 定义一个方法用于获取当前对象的JSON表示
public JSONObject getContent() {
try {
// 创建一个空的JSONObject用于存储将要返回的数据
JSONObject js = new JSONObject();
// 如果标记为已创建但数据库中没有记录则记录日志并返回null
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
return null;
}
// 创建一个新的JSONObject用于存储笔记信息
JSONObject note = new JSONObject();
// 如果当前对象是笔记类型
if (mType == Notes.TYPE_NOTE) {
// 向note对象中添加各种属性
note.put(NoteColumns.ID, mId);
note.put(NoteColumns.ALERTED_DATE, mAlertDate);
note.put(NoteColumns.BG_COLOR_ID, mBgColorId);
note.put(NoteColumns.CREATED_DATE, mCreatedDate);
note.put(NoteColumns.HAS_ATTACHMENT, mHasAttachment);
note.put(NoteColumns.MODIFIED_DATE, mModifiedDate);
note.put(NoteColumns.PARENT_ID, mParentId);
note.put(NoteColumns.SNIPPET, mSnippet);
note.put(NoteColumns.TYPE, mType);
note.put(NoteColumns.WIDGET_ID, mWidgetId);
note.put(NoteColumns.WIDGET_TYPE, mWidgetType);
note.put(NoteColumns.ORIGIN_PARENT_ID, mOriginParent);
// 将note对象添加到js对象中使用特定的键
js.put(GTaskStringUtils.META_HEAD_NOTE, note);
// 创建一个JSONArray用于存储数据列表
JSONArray dataArray = new JSONArray();
// 遍历数据列表将每个数据项的JSON表示添加到dataArray中
for (SqlData sqlData : mDataList) {
JSONObject data = sqlData.getContent();
if (data != null) {
dataArray.put(data);
}
}
// 将dataArray添加到js对象中使用特定的键
js.put(GTaskStringUtils.META_HEAD_DATA, dataArray);
}
// 如果当前对象是文件夹或系统类型
else if (mType == Notes.TYPE_FOLDER || mType == Notes.TYPE_SYSTEM) {
// 向note对象中添加ID、类型和摘要信息
note.put(NoteColumns.ID, mId);
note.put(NoteColumns.TYPE, mType);
note.put(NoteColumns.SNIPPET, mSnippet);
// 将note对象添加到js对象中使用特定的键
js.put(GTaskStringUtils.META_HEAD_NOTE, note);
}
// 返回构建的JSONObject
return js;
} catch (JSONException e) {
// 捕获JSON异常并记录错误日志
Log.e(TAG, e.toString());
e.printStackTrace();
}
// 如果发生异常返回null
return null;
}
// 设置父ID的方法
public void setParentId(long id) {
mParentId = id;
// 将更改记录到差异映射中,以便稍后提交
mDiffNoteValues.put(NoteColumns.PARENT_ID, id);
}
// 设置Gtask ID的方法
public void setGtaskId(String gid) {
// 将Gtask ID记录到差异映射中
mDiffNoteValues.put(NoteColumns.GTASK_ID, gid);
}
// 设置同步ID的方法
public void setSyncId(long syncId) {
// 将同步ID记录到差异映射中
mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId);
}
// 重置本地修改标记的方法
public void resetLocalModified() {
// 将本地修改标记设置为0表示未修改
mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0);
}
// 获取ID的方法
public long getId() {
return mId;
}
// 获取父ID的方法
public long getParentId() {
return mParentId;
}
// 获取摘要信息的方法
public String getSnippet() {
return mSnippet;
}
// 判断当前对象是否为笔记类型的方法
public boolean isNoteType() {
return mType == Notes.TYPE_NOTE;
}
// 提交更改的方法,包括创建和更新操作
public void commit(boolean validateVersion) {
// 如果是创建操作
if (mIsCreate) {
// 如果ID无效但差异映射中包含ID则移除ID
if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) {
mDiffNoteValues.remove(NoteColumns.ID);
}
// 插入新记录到内容提供者并获取新记录的ID
Uri uri = mContentResolver.insert(Notes.CONTENT_NOTE_URI, mDiffNoteValues);
try {
mId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
// 捕获数字格式异常并记录错误日志
Log.e(TAG, "Get note id error :" + e.toString());
throw new ActionFailureException("create note failed");
}
// 如果ID无效则抛出异常
if (mId == 0) {
throw new IllegalStateException("Create thread id failed");
}
// 如果是笔记类型,则提交数据列表的更改
if (mType == Notes.TYPE_NOTE) {
for (SqlData sqlData : mDataList) {
sqlData.commit(mId, false, -1);
}
}
}
// 如果是更新操作
else {
// 检查ID是否有效
if (mId <= 0 && mId != Notes.ID_ROOT_FOLDER && mId != Notes.ID_CALL_RECORD_FOLDER) {
Log.e(TAG, "No such note");
throw new IllegalStateException("Try to update note with invalid id");
}
// 如果有需要更新的属性
if (mDiffNoteValues.size() > 0) {
mVersion ++; // 增加版本号
int result = 0;
// 根据是否验证版本,执行不同的更新操作
if (!validateVersion) {
result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "("
+ NoteColumns.ID + "=?)", new String[] {
String.valueOf(mId)
});
} else {
result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "("
+ NoteColumns.ID + "=?) AND (" + NoteColumns.VERSION + "<=?)",
new String[] {
String.valueOf(mId), String.valueOf(mVersion)
});
}
// 如果没有记录被更新,记录警告日志
if (result == 0) {
Log.w(TAG, "there is no update. maybe user updates note when syncing");
}
}
// 如果是笔记类型,则提交数据列表的更改
if (mType == Notes.TYPE_NOTE) {
for (SqlData sqlData : mDataList) {
sqlData.commit(mId, validateVersion, mVersion);
}
}
}
// 刷新本地信息
loadFromCursor(mId);
// 如果是笔记类型,则加载数据内容
if (mType == Notes.TYPE_NOTE)
loadDataContent();
// 清空差异映射
mDiffNoteValues.clear();
// 标记为已创建(对于更新操作,实际上是重置为未创建状态)
mIsCreate = false;
}