org.jboss.hal.core.Json.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.hal.core.Json.java

Source

/*
 * Copyright 2015-2016 Red Hat, Inc, and individual contributors.
 *
 * 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
 *
 * https://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.jboss.hal.core;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.google.common.base.Strings;
import elemental2.core.JsArray;
import jsinterop.base.Any;
import jsinterop.base.JsPropertyMap;
import org.jboss.hal.dmr.ModelNode;
import org.jboss.hal.dmr.ModelType;
import org.jboss.hal.dmr.Property;
import org.jboss.hal.meta.Metadata;
import org.jetbrains.annotations.NonNls;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static elemental2.core.Global.JSON;
import static java.util.Collections.emptyList;
import static org.jboss.hal.dmr.ModelDescriptionConstants.ATTRIBUTES;
import static org.jboss.hal.dmr.ModelDescriptionConstants.TYPE;
import static org.jboss.hal.dmr.ModelDescriptionConstants.VALUE_TYPE;
import static org.jboss.hal.dmr.ModelType.BIG_INTEGER;
import static org.jboss.hal.dmr.ModelType.INT;

public final class Json {

    private static final String EMPTY_JSON = "Empty JSON '{}'";
    @NonNls
    private static final Logger logger = LoggerFactory.getLogger(Json.class);

    @SuppressWarnings("unchecked")
    public static List<ModelNode> parseArray(String json, Metadata metadata, Map<String, String> mappping) {
        if (Strings.emptyToNull(json) != null) {
            JsArray<JsPropertyMap<Object>> array = (JsArray<JsPropertyMap<Object>>) JSON.parse(json);
            if (array.length != 0) {
                List<ModelNode> nodes = new ArrayList<>();
                for (int i = 0; i < array.length; i++) {
                    JsPropertyMap<Object> map = array.getAt(i);
                    ModelNode node = iterateMap(map, metadata, mappping);
                    if (node.isDefined()) {
                        nodes.add(node);
                    }
                }
                return nodes;
            } else {
                logger.warn(EMPTY_JSON, json);
                return emptyList();
            }
        } else {
            logger.warn(EMPTY_JSON, json);
            return emptyList();
        }
    }

    @SuppressWarnings("unchecked")
    public static ModelNode parseSingle(String json, Metadata metadata, Map<String, String> mappping) {
        if (Strings.emptyToNull(json) != null) {
            JsPropertyMap<Object> map = (JsPropertyMap<Object>) JSON.parse(json);
            if (map != null) {
                return iterateMap(map, metadata, mappping);
            } else {
                logger.warn(EMPTY_JSON, json);
                return new ModelNode();
            }
        } else {
            logger.warn(EMPTY_JSON, json);
            return new ModelNode();
        }
    }

    private static ModelNode iterateMap(JsPropertyMap<Object> map, Metadata metadata,
            Map<String, String> mappping) {
        ModelNode node = new ModelNode();
        List<Property> attributeDescriptions = metadata.getDescription().getAttributes(ATTRIBUTES);

        map.forEach(jsonName -> {
            String dmrName = mappping.get(jsonName);
            if (dmrName != null) {
                ModelNode attributeDescription = findAttributeDescription(dmrName, attributeDescriptions);
                if (attributeDescription != null) {
                    if (map.has(jsonName)) {
                        Any any = map.getAny(jsonName);
                        ModelNode value = anyValue(jsonName, dmrName, attributeDescription, any);
                        if (value.isDefined()) {
                            node.get(dmrName).set(value);
                        }
                    }
                } else {
                    logger.warn("No attribute description found for JSON key '{}' / DMR attribute '{}'", jsonName,
                            dmrName);
                }
            } else {
                logger.warn("No mapping from JSON to DMR found for JSON key '{}'", jsonName);
            }
        });
        return node;
    }

    private static ModelNode anyValue(String jsonName, String dmrName, ModelNode attributeDescription, Any value) {
        ModelNode node = new ModelNode();
        ModelType type = attributeDescription.get(TYPE).asType();
        switch (type) {
        case BOOLEAN:
            node.set(value.asBoolean());
            break;

        case BIG_INTEGER:
        case INT:
        case LONG:
            long longValue = value.asLong();
            if (type == BIG_INTEGER) {
                node.set(BigInteger.valueOf(longValue));
            } else if (type == INT) {
                node.set((int) longValue);
            } else {
                node.set(longValue);
            }
            break;

        case DOUBLE:
            double doubleValue = value.asDouble();
            node.set(doubleValue);
            break;

        case LIST:
            Any[] array = value.asArray();
            for (Any any : array) {
                node.add(String.valueOf(any));
            }
            break;

        case OBJECT:
            boolean stringValueType = attributeDescription.get(VALUE_TYPE).getType().equals(ModelType.TYPE)
                    && attributeDescription.get(VALUE_TYPE).asType().equals(ModelType.STRING);
            if (stringValueType) {
                JsPropertyMap<Object> map = value.asPropertyMap();
                map.forEach(key -> node.get(key).set(String.valueOf(map.getAny(key))));
            }
            break;

        case STRING:
            node.set(value.asString());
            break;

        // unsupported types
        case BIG_DECIMAL:
        case BYTES:
        case EXPRESSION:
        case PROPERTY:
        case TYPE:
        case UNDEFINED:
            logger.warn("Unsupported type {} when mapping JSON key {} to DMR attribute {}", type, jsonName,
                    dmrName);
            break;
        default:
            break;
        }
        return node;
    }

    private static ModelNode findAttributeDescription(String name, List<Property> attributeDescriptions) {
        for (Property property : attributeDescriptions) {
            if (name.equals(property.getName())) {
                return property.getValue();
            }
        }
        return null;
    }

    private Json() {
    }
}