/* * 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; import android.database.Cursor; import android.util.Log; import net.micode.notes.tool.GTaskStringUtils; import org.json.JSONException; import org.json.JSONObject; /** * GTask(谷歌任务)的元数据模型类 * 继承自抽象基类{@link Task},专门处理与GTask关联的元数据(如关联的GTask ID) * 核心功能:存储元数据的JSON信息、解析远程GTask的JSON数据获取关联ID、标记元数据是否值得保存 * 该类部分父类方法被重写为抛出异常,因为元数据不需要本地JSON处理和同步动作判断的逻辑 * * @author MiCode Open Source Community * @date 2010-2011 * @see Task 抽象任务基类 */ public class MetaData extends Task { /** * 日志标签,使用类的简单名称(MetaData),便于Logcat中定位日志来源 */ private final static String TAG = MetaData.class.getSimpleName(); /** * 与当前元数据关联的GTask唯一标识(Gid) * Gid是GTask系统中用于标识任务的唯一ID,用于笔记与GTask的关联同步 */ private String mRelatedGid = null; /** * 设置元数据内容:将关联的GTask ID存入JSON对象,并设置元数据的名称和笔记内容 * 步骤: * 1. 向传入的JSON元数据对象中添加GTask ID的键值对 * 2. 将JSON对象转为字符串,设置为当前任务的笔记内容(notes字段) * 3. 设置当前任务的名称为元数据专用名称({@link GTaskStringUtils#META_NOTE_NAME}) * * @param gid 关联的GTask唯一标识(Gid) * @param metaInfo 存储元数据的JSON对象,用于封装元数据键值对 */ public void setMeta(String gid, JSONObject metaInfo) { try { // 向JSON对象中添加GTask ID的键值对,键为META_HEAD_GTASK_ID metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); } catch (JSONException e) { // 捕获JSON操作异常,输出错误日志 Log.e(TAG, "failed to put related gid"); } // 将JSON对象转为字符串,设置为任务的笔记内容(父类Task的notes属性) setNotes(metaInfo.toString()); // 设置任务名称为元数据专用名称(区分普通任务和元数据任务) setName(GTaskStringUtils.META_NOTE_NAME); } /** * 获取与当前元数据关联的GTask ID * * @return 关联的GTask ID(null表示未设置或解析失败) */ public String getRelatedGid() { return mRelatedGid; } /** * 重写父类方法,判断当前元数据是否值得保存到本地/远程 * 判定条件:任务的笔记内容(元数据JSON字符串)不为null * 该方法用于同步时过滤无意义的元数据,避免空数据存储 * * @return true表示值得保存(笔记内容非空),false表示无需保存 */ @Override public boolean isWorthSaving() { return getNotes() != null; } /** * 重写父类方法,根据远程GTask的JSON数据设置元数据内容 * 步骤: * 1. 调用父类方法初始化基础任务内容 * 2. 若笔记内容(元数据JSON字符串)非空,解析JSON获取关联的GTask ID * 3. 捕获JSON解析异常,输出警告日志并将GTask ID置为null * * @param js 远程GTask返回的JSON对象,包含元数据信息 */ @Override public void setContentByRemoteJSON(JSONObject js) { // 调用父类方法,处理基础的任务内容(如名称、笔记等) super.setContentByRemoteJSON(js); // 若笔记内容(元数据JSON字符串)非空,则解析关联的GTask ID if (getNotes() != null) { try { // 将笔记内容转为JSON对象(去除首尾空格,避免解析错误) JSONObject metaInfo = new JSONObject(getNotes().trim()); // 从JSON对象中获取GTask ID并赋值给成员变量 mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID); } catch (JSONException e) { // 捕获JSON解析异常,输出警告日志,将GTask ID置为null Log.w(TAG, "failed to get related gid"); mRelatedGid = null; } } } /** * 重写父类方法,禁止调用该方法(元数据不需要本地JSON处理) * 该方法被调用时会抛出非法访问错误,提示开发者该方法不适用 * * @throws IllegalAccessError 调用该方法时立即抛出异常 */ @Override public void setContentByLocalJSON(JSONObject js) { // 抛出异常,说明该方法不应被调用(元数据仅处理远程GTask的JSON,不处理本地JSON) throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called"); } /** * 重写父类方法,禁止调用该方法(元数据不需要生成本地JSON) * 该方法被调用时会抛出非法访问错误,提示开发者该方法不适用 * * @throws IllegalAccessError 调用该方法时立即抛出异常 * @return 无返回值(因为会直接抛出异常) */ @Override public JSONObject getLocalJSONFromContent() { throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called"); } /** * 重写父类方法,禁止调用该方法(元数据不需要判断同步动作) * 该方法被调用时会抛出非法访问错误,提示开发者该方法不适用 * * @param c 数据库游标(用于查询本地数据),此处未使用 * @throws IllegalAccessError 调用该方法时立即抛出异常 * @return 无返回值(因为会直接抛出异常) */ @Override public int getSyncAction(Cursor c) { throw new IllegalAccessError("MetaData:getSyncAction should not be called"); } }