com.flipkart.android.proteus.toolbox.Utils.java Source code

Java tutorial

Introduction

Here is the source code for com.flipkart.android.proteus.toolbox.Utils.java

Source

/*
 * 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;
    }
}