org.wso2.carbon.governance.rest.api.internal.JSONMessageBodyReader.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.governance.rest.api.internal.JSONMessageBodyReader.java

Source

/*
 * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *   WSO2 Inc. licenses this file to you 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 org.wso2.carbon.governance.rest.api.internal;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class JSONMessageBodyReader {

    protected void handleJSON(JsonReader reader, Map<String, Object> map) throws IOException {
        handleObject(reader, map, null, false);
    }

    /**
     * Traverses through a json object and maps the keys and values to a {@link Map}
     *
     * @param reader        {@link JsonReader}
     * @param map           map that the values to be added.
     * @param token         {@link JsonToken}
     * @param isArray       whether the object is inside a json array
     * @throws IOException  If unable to parse the json object
     */
    protected void handleObject(JsonReader reader, Map<String, Object> map, JsonToken token, boolean isArray)
            throws IOException {
        String key = null;
        while (true) {
            if (token == null) {
                token = reader.peek();
            }

            if (JsonToken.BEGIN_OBJECT.equals(token)) {
                reader.beginObject();

            } else if (JsonToken.END_OBJECT.equals(token)) {
                reader.endObject();

            } else if (JsonToken.NAME.equals(token)) {
                key = reader.nextName();

            } else if (JsonToken.STRING.equals(token)) {
                String value = reader.nextString();
                handleValue(key, value, map, isArray);
                key = null;

            } else if (JsonToken.NUMBER.equals(token)) {
                Double value = reader.nextDouble();
                handleValue(key, value, map, isArray);
                key = null;

            } else if (token.equals(JsonToken.BEGIN_ARRAY)) {
                Map<String, Object> values = handleArray(reader);
                if (key != null) {
                    map.put(key, values);
                }

            } else {
                reader.skipValue();
            }

            if (reader.hasNext()) {
                token = reader.peek();
            } else {
                break;
            }
        }
    }

    /**
     * Traverse through a json array and maps the array elements to a {@link Map}
     *
     * @param reader        {@link JsonReader}
     * @return              map with json array values mapped to key value pairs.
     * @throws IOException  If unable to parse the json array.
     */
    private Map<String, Object> handleArray(JsonReader reader) throws IOException {
        Map<String, Object> values = new HashMap<>();
        reader.beginArray();
        JsonToken token = reader.peek();
        while (token != null) {
            if (token.equals(JsonToken.END_ARRAY)) {
                reader.endArray();
                return values;
            } else {
                handleObject(reader, values, token, true);
            }
            token = reader.peek();
        }
        return values;
    }

    /**
     * Inserts json values to the given map. Handles multi valued attributes such as unbounded attributes
     * and assigns them to a {@link Map}.
     *
     * @param key       key to be added.
     * @param value     value to be added.
     * @param map       the map that the value being added.
     * @param isArray   whether the value is included inside a json array.
     */
    private void handleValue(String key, Object value, Map<String, Object> map, boolean isArray) {
        /*
         * Fix for REGISTRY-3613
         * Enabling multiple values with the same key to be added as attributes in order to save
         * unbounded elements such as endpoints.
         */
        if (isArray) {
            List values;
            if (StringUtils.isNotBlank(key)) {
                if (map.containsKey(key) && map.get(key) instanceof List) {
                    values = (List) map.get(key);
                } else {
                    values = new ArrayList<>();
                }
                values.add(value);
                map.put(key, values);
            }
        } else {
            map.put(key, String.valueOf(value));
        }
    }
}