package com.revolsys.record.io.format.json; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.annotation.PreDestroy; import com.revolsys.datatype.DataType; import com.revolsys.datatype.DataTypes; import com.revolsys.record.schema.FieldDefinition; import com.revolsys.record.schema.RecordDefinition; import com.revolsys.spring.resource.Resource; public class JsonSchemaWriter { private final JsonMapWriter writer; public JsonSchemaWriter(final Resource resource) { final Writer out = resource.newWriter(); this.writer = new JsonMapWriter(out, true); this.writer.setListRoot(true); } @PreDestroy public void close() { this.writer.close(); } @Override protected void finalize() throws Throwable { close(); } private Collection<Object> toJsonList(final Collection<?> collection) { final List<Object> list = new ArrayList<>(); for (final Object object : collection) { final Object jsonValue = toJsonValue(object); list.add(jsonValue); } return list; } public Map<String, Object> toJsonMap(final Map<String, ?> map) { final Map<String, Object> jsonMap = new LinkedHashMap<>(); for (final Entry<String, ?> entry : map.entrySet()) { final String name = entry.getKey(); final Object value = entry.getValue(); final Object jsonValue = toJsonValue(value); if (jsonValue != null) { jsonMap.put(name, jsonValue); } } return jsonMap; } public Object toJsonValue(Object value) { Object jsonValue = null; if (value == null) { jsonValue = null; } else if (value instanceof Number) { jsonValue = value; } else if (value instanceof Boolean) { jsonValue = value; } else if (value instanceof CharSequence) { jsonValue = value; } else if (value instanceof Map) { final Map<String, Object> objectMap = (Map<String, Object>)value; value = toJsonMap(objectMap); } else if (value instanceof Collection) { final Collection<?> collection = (Collection<?>)value; value = toJsonList(collection); } else { jsonValue = DataTypes.toString(value); } return jsonValue; } public void write(final RecordDefinition recordDefinition) { final Map<String, Object> recordDefinitionMap = new LinkedHashMap<>(); recordDefinitionMap.put("name", recordDefinition.getPath()); final List<Map<String, Object>> fields = new ArrayList<>(); recordDefinitionMap.put("fields", fields); for (final FieldDefinition attribute : recordDefinition.getFields()) { final Map<String, Object> field = new LinkedHashMap<>(); final String name = attribute.getName(); field.put("name", name); final DataType dataType = attribute.getDataType(); final String dataTypeName = dataType.getName(); field.put("type", dataTypeName); final int length = attribute.getLength(); if (length > 0) { field.put("length", length); } final int scale = attribute.getScale(); if (scale > 0) { field.put("scale", scale); } final boolean required = attribute.isRequired(); field.put("required", required); final Map<String, ?> attributeProperties = attribute.getProperties(); final Map<String, Object> fieldProperties = toJsonMap(attributeProperties); if (!fieldProperties.isEmpty()) { field.put("properties", fieldProperties); } fields.add(field); } this.writer.write(recordDefinitionMap); } }