/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.sa.descriptor; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; /** * Reads service definition JSON from an input stream. */ public class ServiceDefinitionReader { private static final JsonParser PARSER = new JsonParser(); private static final Gson GSON = new Gson(); public ServiceDefinition readService(InputStream in) throws IOException { JsonObject descriptor = readDescriptor(in); // Remove the items so they aren't interpreted when converting from JSON JsonElement items = descriptor.remove("items"); // Backwards compatibility JsonElement fields = descriptor.remove("fields"); ServiceDefinition service = GSON.fromJson(descriptor, ServiceDefinition.class); if (items != null && items.isJsonObject()) { for (ItemDefinition item : readItems(items.getAsJsonObject())) { service.addItem(item); } } if (fields != null && fields.isJsonObject()) { for (ItemDefinition item : readItems(fields.getAsJsonObject())) { service.addItem(item); } } return service; } private List<ItemDefinition> readItems(JsonObject parent) { List<ItemDefinition> items = new ArrayList<>(); for (Map.Entry<String, JsonElement> entry : parent.entrySet()) { String name = entry.getKey(); JsonElement child = entry.getValue(); if (child.isJsonObject()) { ItemDefinition item = readItem(child.getAsJsonObject()); item.name = name; items.add(item); } } return items; } private ItemDefinition readItem(JsonObject obj) { String type = getString(obj, "type"); if (ServiceItem.TYPE_GROUP.equals(type)) { return readGroup(obj); } else if (ServiceItem.TYPE_TABLE.equals(type)) { return readTable(obj); } else if (ServiceItem.TYPE_MODAL.equals(type)) { return readModal(obj); } else { return readField(obj); } } private GroupDefinition readGroup(JsonObject obj) { JsonElement items = obj.remove("items"); GroupDefinition group = GSON.fromJson(obj, GroupDefinition.class); if (items != null && items.isJsonObject()) { for (ItemDefinition item : readItems(items.getAsJsonObject())) { group.addItem(item); } } return group; } private TableDefinition readTable(JsonObject obj) { JsonElement items = obj.remove("items"); // Ensure 'fields' doesn't get automatically mapped onto the table fields obj.remove("fields"); TableDefinition table = GSON.fromJson(obj, TableDefinition.class); if (items != null && items.isJsonObject()) { for (ItemDefinition item : readItems(items.getAsJsonObject())) { // Only allow fields in tables if (item instanceof FieldDefinition) { table.addField((FieldDefinition) item); } } } return table; } private ModalDefinition readModal(JsonObject obj) { JsonElement items = obj.remove("items"); ModalDefinition modal = GSON.fromJson(obj, ModalDefinition.class); if (items != null && items.isJsonObject()) { for (ItemDefinition item : readItems(items.getAsJsonObject())) { modal.addItem(item); } } return modal; } private FieldDefinition readField(JsonObject obj) { return GSON.fromJson(obj, FieldDefinition.class); } /** * Reads a descriptor from an InputStream and injects i18n properties where applicable. * * @param in * the input stream. * @return the JSON descriptor. * * @throws IOException * if an I/O error occurs. */ private JsonObject readDescriptor(InputStream in) throws IOException { try { return PARSER.parse(new InputStreamReader(in)).getAsJsonObject(); } finally { IOUtils.closeQuietly(in); } } /** * Gets a JSON property as a string. If the property is a primitive it is converted to a string, otherwise null is * returned. * * @param obj * the JSON object. * @param name * the property name. * @return the property value as a string. */ private static String getString(JsonObject obj, String name) { JsonElement property = obj.get(name); return (property != null) && property.isJsonPrimitive() ? property.getAsString() : null; } }