/* * 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.toolbox; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.support.annotation.NonNull; import com.flipkart.android.proteus.parser.ParseHelper; import com.google.gson.Gson; import com.google.gson.JsonArray; 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.StringTokenizer; /** * @author Aditya Sharat */ public class Utils { public static final String LIB_NAME = "proteus"; public static final String VERSION = "4.1.0-SNAPSHOT"; public static final String ATTRIBUTE_BORDER_WIDTH = "width"; public static final String ATTRIBUTE_BORDER_COLOR = "color"; public static final String ATTRIBUTE_BORDER_RADIUS = "radius"; public static final String ATTRIBUTE_BG_COLOR = "bgColor"; public static Result readJson(String path, JsonObject data, int index) { // replace INDEX reference with index value if (ProteusConstants.INDEX.equals(path)) { path = path.replace(ProteusConstants.INDEX, String.valueOf(index)); return Result.success(new JsonPrimitive(path)); } else { StringTokenizer tokenizer = new StringTokenizer(path, ProteusConstants.DATA_PATH_DELIMITERS); JsonElement elementToReturn = data; JsonElement tempElement; JsonArray tempArray; while (tokenizer.hasMoreTokens()) { String segment = tokenizer.nextToken(); if (elementToReturn == null) { return Result.NO_SUCH_DATA_PATH_EXCEPTION; } if (elementToReturn.isJsonNull()) { return Result.JSON_NULL_EXCEPTION; } if ("".equals(segment)) { continue; } if (elementToReturn.isJsonArray()) { tempArray = elementToReturn.getAsJsonArray(); if (ProteusConstants.INDEX.equals(segment)) { if (index < tempArray.size()) { elementToReturn = tempArray.get(index); } else { return Result.NO_SUCH_DATA_PATH_EXCEPTION; } } else if (ProteusConstants.ARRAY_DATA_LENGTH_REFERENCE.equals(segment)) { elementToReturn = new JsonPrimitive(tempArray.size()); } else if (ProteusConstants.ARRAY_DATA_LAST_INDEX_REFERENCE.equals(segment)) { if (tempArray.size() == 0) { return Result.NO_SUCH_DATA_PATH_EXCEPTION; } elementToReturn = tempArray.get(tempArray.size() - 1); } else { try { index = Integer.parseInt(segment); } catch (NumberFormatException e) { return Result.INVALID_DATA_PATH_EXCEPTION; } if (index < tempArray.size()) { elementToReturn = tempArray.get(index); } else { return Result.NO_SUCH_DATA_PATH_EXCEPTION; } } } else if (elementToReturn.isJsonObject()) { tempElement = elementToReturn.getAsJsonObject().get(segment); if (tempElement != null) { elementToReturn = tempElement; } else { return Result.NO_SUCH_DATA_PATH_EXCEPTION; } } else if (elementToReturn.isJsonPrimitive()) { return Result.INVALID_DATA_PATH_EXCEPTION; } else { return Result.NO_SUCH_DATA_PATH_EXCEPTION; } } if (elementToReturn.isJsonNull()) { return Result.JSON_NULL_EXCEPTION; } return Result.success(elementToReturn); } } public static JsonElement merge(JsonElement oldJson, JsonElement newJson, boolean useCopy, Gson gson) { JsonElement newDataElement; JsonArray oldArray; JsonArray newArray; JsonElement oldArrayItem; JsonElement newArrayItem; JsonObject oldObject; if (oldJson == null || oldJson.isJsonNull()) { return useCopy ? gson.fromJson(newJson, JsonElement.class) : newJson; } if (newJson == null || newJson.isJsonNull()) { newJson = JsonNull.INSTANCE; return newJson; } if (newJson.isJsonPrimitive()) { JsonPrimitive value; if (!useCopy) { return newJson; } if (newJson.getAsJsonPrimitive().isBoolean()) { value = new JsonPrimitive(newJson.getAsBoolean()); } else if (newJson.getAsJsonPrimitive().isNumber()) { value = new JsonPrimitive(newJson.getAsNumber()); } else if (newJson.getAsJsonPrimitive().isString()) { value = new JsonPrimitive(newJson.getAsString()); } else { value = newJson.getAsJsonPrimitive(); } return value; } if (newJson.isJsonArray()) { if (!oldJson.isJsonArray()) { return useCopy ? gson.fromJson(newJson, JsonArray.class) : newJson; } else { oldArray = oldJson.getAsJsonArray(); newArray = newJson.getAsJsonArray(); if (oldArray.size() > newArray.size()) { while (oldArray.size() > newArray.size()) { oldArray.remove(oldArray.size() - 1); } } for (int index = 0; index < newArray.size(); index++) { if (index < oldArray.size()) { oldArrayItem = oldArray.get(index); newArrayItem = newArray.get(index); oldArray.set(index, merge(oldArrayItem, newArrayItem, useCopy, gson)); } else { oldArray.add(newArray.get(index)); } } } } else if (newJson.isJsonObject()) { if (!oldJson.isJsonObject()) { return useCopy ? gson.fromJson(newJson, JsonObject.class) : newJson; } else { oldObject = oldJson.getAsJsonObject(); for (Map.Entry<String, JsonElement> entry : newJson.getAsJsonObject().entrySet()) { newDataElement = merge(oldObject.get(entry.getKey()), entry.getValue(), useCopy, gson); oldObject.add(entry.getKey(), newDataElement); } } } else { return useCopy ? gson.fromJson(newJson, JsonElement.class) : newJson; } return oldJson; } public static JsonObject addElements(JsonObject destination, JsonObject source, boolean override) { for (Map.Entry<String, JsonElement> entry : source.entrySet()) { if (!override && destination.get(entry.getKey()) != null) { continue; } destination.add(entry.getKey(), entry.getValue()); } return destination; } public static String getStringFromArray(JsonArray array, String delimiter) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < array.size(); i++) { if (array.get(i).isJsonPrimitive()) { sb.append(array.get(i).getAsString()); } else { sb.append(array.get(i).toString()); } if (i < array.size() - 1) { sb.append(delimiter).append(" "); } } return sb.toString(); } public static JsonObject mergeLayouts(JsonObject destination, JsonObject source) { JsonObject layout = new JsonObject(); for (Map.Entry<String, JsonElement> entry : destination.entrySet()) { layout.add(entry.getKey(), entry.getValue()); } boolean hasType = layout.has(ProteusConstants.TYPE); for (Map.Entry<String, JsonElement> entry : source.entrySet()) { if (ProteusConstants.TYPE.equals(entry.getKey()) && hasType) { continue; } if (ProteusConstants.DATA_CONTEXT.equals(entry.getKey())) { continue; } layout.add(entry.getKey(), entry.getValue()); } return layout; } public static String getPropertyAsString(JsonObject object, String property) { if (object == null || object.isJsonNull()) { return null; } JsonElement element = object.get(property); if (element == null) { return null; } String string; if (!element.isJsonNull() && element.isJsonPrimitive()) { string = element.getAsString(); } else { string = element.toString(); } return string; } @NonNull public static String getLayoutIdentifier(JsonObject layout) { String noLayoutId = "no ID or TAG."; if (layout == null) { return noLayoutId; } String value = Utils.getPropertyAsString(layout, ProteusConstants.ID); if (value != null) { return "ID: " + value + "."; } value = Utils.getPropertyAsString(layout, ProteusConstants.TAG); if (value != null) { return "TAG: " + value + "."; } return noLayoutId; } public static Drawable getBorderDrawable(JsonElement attributeValue, Context context) { if (!attributeValue.isJsonObject() || attributeValue.isJsonNull()) { return null; } float cornerRadius = 0; int borderWidth = 0, borderColor = Color.TRANSPARENT, bgColor = Color.TRANSPARENT; JsonObject data = attributeValue.getAsJsonObject(); String value = Utils.getPropertyAsString(data, ATTRIBUTE_BG_COLOR); if (value != null && !value.equals("-1")) { bgColor = ParseHelper.parseColor(value); } value = Utils.getPropertyAsString(data, ATTRIBUTE_BORDER_COLOR); if (value != null) { borderColor = ParseHelper.parseColor(value); } value = Utils.getPropertyAsString(data, ATTRIBUTE_BORDER_RADIUS); if (value != null) { cornerRadius = ParseHelper.parseDimension(value, context); } value = Utils.getPropertyAsString(data, ATTRIBUTE_BORDER_WIDTH); if (value != null) { borderWidth = (int) ParseHelper.parseDimension(value, context); } GradientDrawable border = new GradientDrawable(); border.setCornerRadius(cornerRadius); border.setShape(GradientDrawable.RECTANGLE); border.setStroke(borderWidth, borderColor); border.setColor(bgColor); return border; } public static String getTagPrefix() { return LIB_NAME + ":"; } public static String getVersion() { return VERSION; } }