/* * Copyright 2016 Flipkart Internet Pvt. Ltd. * * 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.flipkart.android.proteus; import android.support.annotation.Nullable; import com.flipkart.android.proteus.toolbox.ProteusConstants; import com.flipkart.android.proteus.toolbox.Result; import com.flipkart.android.proteus.toolbox.Utils; import com.google.gson.JsonElement; import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import java.util.Map; import java.util.regex.Pattern; /** * @author Aditya Sharat */ public class DataContext { private final boolean isClone; private JsonObject data; @Nullable private JsonObject reverseScope; @Nullable private JsonObject scope; private int index; public DataContext() { this.data = new JsonObject(); this.scope = new JsonObject(); this.reverseScope = new JsonObject(); this.index = -1; this.isClone = false; } public DataContext(DataContext dataContext) { this.data = dataContext.getData(); this.scope = dataContext.getScope(); this.reverseScope = dataContext.getReverseScope(); this.index = dataContext.getIndex(); this.isClone = true; } public static DataContext updateDataContext(DataContext dataContext, JsonObject data, JsonObject scope, int dataIndex) { JsonObject reverseScope = new JsonObject(); JsonObject newData = new JsonObject(); dataContext.setIndex(dataIndex); if (data == null) { data = new JsonObject(); } for (Map.Entry<String, JsonElement> entry : scope.entrySet()) { String key = entry.getKey(); String value = entry.getValue().getAsString(); Result result = Utils.readJson(value, data, dataContext.getIndex()); JsonElement element = result.isSuccess() ? result.element : new JsonObject(); newData.add(key, element); String unAliasedValue = value.replace(ProteusConstants.INDEX, String.valueOf(dataContext.getIndex())); reverseScope.add(unAliasedValue, new JsonPrimitive(key)); } Utils.addElements(newData, data, false); if (dataContext.getData() == null) { dataContext.setData(new JsonObject()); } else { dataContext.setData(newData); } dataContext.setScope(scope); dataContext.setReverseScope(reverseScope); return dataContext; } public static String getAliasedDataPath(String dataPath, JsonObject reverseScope, boolean isBindingPath) { String[] segments; if (isBindingPath) { segments = dataPath.split(ProteusConstants.DATA_PATH_DELIMITER); } else { segments = dataPath.split(ProteusConstants.DATA_PATH_SIMPLE_DELIMITER); } if (reverseScope == null) { return dataPath; } String alias = Utils.getPropertyAsString(reverseScope, segments[0]); if (alias == null) { return dataPath; } return dataPath.replaceFirst(Pattern.quote(segments[0]), alias); } public JsonObject getData() { return data; } public void setData(JsonObject data) { this.data = data; } @Nullable public JsonObject getScope() { return scope; } public void setScope(@Nullable JsonObject scope) { this.scope = scope; } @Nullable public JsonObject getReverseScope() { return reverseScope; } public void setReverseScope(@Nullable JsonObject reverseScope) { this.reverseScope = reverseScope; } public boolean isClone() { return isClone; } @Nullable public JsonElement get(String dataPath) { String aliasedDataPath = getAliasedDataPath(dataPath, reverseScope, true); Result result = Utils.readJson(aliasedDataPath, data, index); if (result.isSuccess()) { return result.element; } else if (result.RESULT_CODE == Result.RESULT_JSON_NULL_EXCEPTION) { return JsonNull.INSTANCE; } return null; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public DataContext createChildDataContext(JsonObject scope, int dataIndex) { return updateDataContext(new DataContext(), data, scope, dataIndex); } public void updateDataContext(JsonObject data) { updateDataContext(this, data, scope, index); } }