/* * Copyright (C) 2011 The original author or authors. * * 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 com.zapta.apps.maniana.persistence; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.zapta.apps.maniana.annotations.ApplicationScope; import com.zapta.apps.maniana.model.AppModel; import com.zapta.apps.maniana.model.ItemColor; import com.zapta.apps.maniana.model.ItemModel; import com.zapta.apps.maniana.model.PageKind; import com.zapta.apps.maniana.util.IdGenerator; import com.zapta.apps.maniana.util.LogUtil; /** * Performs model deserialization from JSON doc. * * TODO: define consts for the json field names. * * @author Tal Dayan */ @ApplicationScope public class ModelDeserialization implements FieldNames { /** * Deserialize a model from a JSON doc. * * @param resultModel filled in with the deserialize model data. All previous content is lost, * regardless of the outcome. * * @param resultMetadata filled in with the deserialized metadata. All previous content is lost, * regardless of the outcome. * * @throws JSONException */ public static final void deserializeModel(AppModel resultModel, PersistenceMetadata resultMetadata, String jsonString) throws JSONException { resultModel.clear(); resultMetadata.clear(); final JSONObject root = new JSONObject(jsonString); final int format = root.getInt(FIELD_FORMAT); if (format < 2) { LogUtil.info("Loading data file in old format: " + format); // In format version 1 the model fields were at top level and we did not have metadata. populateModelFields(root, resultModel); // NOTE: metadata was already cleared above. } else { // For format >= 2. populateModelFields(root.getJSONObject(FIELD_MODEL), resultModel); resultMetadata.fromJson(root.getJSONObject(FIELD_METADATA)); } } /** * Deserialize the model fields. Note that in format version 1 the model fields were at top json * level and in format >= 2, the model fields are in a 'model' sub field. */ private static final void populateModelFields(JSONObject root, AppModel appModel) throws JSONException { appModel.setLastPushDateStamp(root.optString(FIELD_LAST_PUSH_DATE, "")); populateItemListFromJason(root.getJSONArray(FIELD_TODAY), appModel, PageKind.TODAY); populateItemListFromJason(root.getJSONArray(FIELD_TOMOROW), appModel, PageKind.TOMOROW); } /** Deserialize a page item list */ private static final void populateItemListFromJason(JSONArray jsonItems, AppModel appModel, PageKind pageKind) throws JSONException { for (int i = 0; i < jsonItems.length(); i++) { final ItemModel item = modelItemFromJson(jsonItems.getJSONObject(i)); // Force item in the today page to be unlocked. if (pageKind.isToday() && item.isLocked()) { LogUtil.warning("Cleared lock state while loading a today item"); item.setIsLocked(false); } appModel.appendItem(pageKind, modelItemFromJson(jsonItems.getJSONObject(i))); } } /** Deserialize a single item */ private static final ItemModel modelItemFromJson(JSONObject jsonItem) throws JSONException { final String optId = jsonItem.optString(FIELD_ID, null); final String id = (optId == null) ? IdGenerator.getFreshId() : optId; final long optUpdateTime = jsonItem.optLong(FIELD_UPDATE_TIME); final long updateTime = (optUpdateTime == 0) ? System.currentTimeMillis() : optUpdateTime; final String text = jsonItem.getString(FIELD_TEXT); final boolean isCompleted = jsonItem.optBoolean(FIELD_DONE); final boolean isLocked = jsonItem.optBoolean(FIELD_LOCKED); final long scheduled = jsonItem.optLong(FIELD_SCHEDULED); final String optColorKey = jsonItem.optString(FIELD_COLOR, null); // NOTE(tal): NONE may or may not be in the current user selected task color set. // Default to NONE if not found. final ItemColor color = (optColorKey == null) ? ItemColor.NONE : ItemColor.fromKey( optColorKey, ItemColor.NONE); return new ItemModel(updateTime, id, text, isCompleted, isLocked, scheduled, color); } }