package com.revolsys.record.io.format.json; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import com.revolsys.collection.map.LinkedHashMapEx; import com.revolsys.collection.map.MapEx; import com.revolsys.io.AbstractIoFactoryWithCoordinateSystem; import com.revolsys.io.FileUtil; import com.revolsys.io.IoConstants; import com.revolsys.io.file.Paths; import com.revolsys.io.map.MapReader; import com.revolsys.io.map.MapReaderFactory; import com.revolsys.io.map.MapWriter; import com.revolsys.io.map.MapWriterFactory; import com.revolsys.record.ArrayRecord; import com.revolsys.record.Record; import com.revolsys.record.io.RecordWriter; import com.revolsys.record.io.RecordWriterFactory; import com.revolsys.record.schema.RecordDefinition; import com.revolsys.spring.resource.FileSystemResource; import com.revolsys.spring.resource.PathResource; import com.revolsys.spring.resource.Resource; import com.revolsys.util.Exceptions; import com.revolsys.util.Property; public class Json extends AbstractIoFactoryWithCoordinateSystem implements MapReaderFactory, MapWriterFactory, RecordWriterFactory { public static final String FILE_EXTENSION = "json"; public static final String MIME_TYPE = "application/json"; public static Map<String, Object> getMap(final Map<String, Object> record, final String fieldName) { final String value = (String)record.get(fieldName); return toObjectMap(value); } public static MapEx toMap(final File directory, final String path) { if (directory == null || path == null) { return new LinkedHashMapEx(); } else { final File file = FileUtil.getFile(directory, path); if (file.exists() && !file.isDirectory()) { final FileSystemResource resource = new FileSystemResource(file); return toMap(resource); } else { return new LinkedHashMapEx(); } } } public static MapEx toMap(final Object source) { final Resource resource = Resource.getResource(source); return toMap(resource); } public static MapEx toMap(final Path directory, final String path) { if (directory == null || path == null) { return new LinkedHashMapEx(); } else { final Path file = directory.resolve(path); if (Paths.exists(file) && !Files.isDirectory(file)) { final PathResource resource = new PathResource(file); return toMap(resource); } else { return new LinkedHashMapEx(); } } } public static MapEx toMap(final Reader reader) { try ( Reader reader2 = reader; final JsonMapIterator iterator = new JsonMapIterator(reader2, true)) { if (iterator.hasNext()) { return iterator.next(); } else { return null; } } catch (final IOException e) { throw new RuntimeException("Unable to read JSON map", e); } } public static final MapEx toMap(final Resource resource) { if (resource != null && (!(resource instanceof FileSystemResource) || resource.exists())) { final Reader reader = resource.newBufferedReader(); return toMap(reader); } return new LinkedHashMapEx(); } public static Map<String, String> toMap(final String string) { final MapEx map = toObjectMap(string); if (map.isEmpty()) { return new LinkedHashMap<>(); } else { final Map<String, String> stringMap = new LinkedHashMap<>(); for (final Entry<String, Object> entry : map.entrySet()) { final String key = entry.getKey(); final Object value = entry.getValue(); if (value == null) { stringMap.put(key, null); } else { stringMap.put(key, value.toString()); } } return stringMap; } } public static final List<MapEx> toMapList(final Object source) { final Resource resource = Resource.getResource(source); if (resource != null && (!(resource instanceof FileSystemResource) || resource.exists())) { try ( final BufferedReader reader = resource.newBufferedReader(); final JsonMapReader jsonReader = new JsonMapReader(reader)) { return jsonReader.toList(); } catch (final IOException e) { Exceptions.throwUncheckedException(e); } } return new ArrayList<>(); } public static List<MapEx> toMapList(final String string) { final StringReader in = new StringReader(string); try ( final JsonMapReader reader = new JsonMapReader(in)) { return reader.toList(); } } public static MapEx toObjectMap(final String string) { if (Property.hasValue(string)) { final StringReader reader = new StringReader(string); try ( final MapReader mapReader = new JsonMapReader(reader, true)) { for (final MapEx map : mapReader) { return map; } } } return new LinkedHashMapEx(); } public static final Record toRecord(final RecordDefinition recordDefinition, final String string) { final StringReader in = new StringReader(string); final JsonRecordIterator iterator = new JsonRecordIterator(recordDefinition, in, true); try { if (iterator.hasNext()) { return iterator.next(); } else { return null; } } finally { iterator.close(); } } public static List<Record> toRecordList(final RecordDefinition recordDefinition, final String string) { final StringReader in = new StringReader(string); final JsonRecordIterator iterator = new JsonRecordIterator(recordDefinition, in); try { final List<Record> objects = new ArrayList<>(); while (iterator.hasNext()) { final Record object = iterator.next(); objects.add(object); } return objects; } finally { iterator.close(); } } public static String toString(final List<? extends Map<String, Object>> list) { final StringWriter writer = new StringWriter(); final JsonMapWriter mapWriter = new JsonMapWriter(writer, false); for (final Map<String, Object> map : list) { mapWriter.write(map); } mapWriter.close(); return writer.toString(); } public static String toString(final Map<String, ? extends Object> values) { final StringWriter writer = new StringWriter(); try ( final JsonWriter jsonWriter = new JsonWriter(writer, false)) { jsonWriter.write(values); } return writer.toString(); } public static String toString(final Map<String, ? extends Object> values, final boolean indent) { final StringWriter writer = new StringWriter(); try ( final JsonWriter jsonWriter = new JsonWriter(writer, indent)) { jsonWriter.write(values); } return writer.toString(); } public static String toString(final Object value) { final StringWriter stringWriter = new StringWriter(); try ( JsonWriter jsonWriter = new JsonWriter(stringWriter)) { jsonWriter.value(value); } return stringWriter.toString(); } public static final String toString(final Record object) { final RecordDefinition recordDefinition = object.getRecordDefinition(); final StringWriter writer = new StringWriter(); final JsonRecordWriter recordWriter = new JsonRecordWriter(recordDefinition, writer); recordWriter.setProperty(IoConstants.SINGLE_OBJECT_PROPERTY, Boolean.TRUE); recordWriter.write(object); recordWriter.close(); return writer.toString(); } public static String toString(final RecordDefinition recordDefinition, final List<? extends Map<String, Object>> list) { final StringWriter writer = new StringWriter(); final JsonRecordWriter recordWriter = new JsonRecordWriter(recordDefinition, writer); for (final Map<String, Object> map : list) { final Record object = new ArrayRecord(recordDefinition); object.setValues(map); recordWriter.write(object); } recordWriter.close(); return writer.toString(); } public static String toString(final RecordDefinition recordDefinition, final Map<String, ? extends Object> parameters) { final Record object = new ArrayRecord(recordDefinition); object.setValues(parameters); return toString(object); } public static void writeMap(final Map<String, ? extends Object> object, final Object target) { writeMap(object, target, true); } public static void writeMap(final Map<String, ? extends Object> object, final Object target, final boolean indent) { final Resource resource = Resource.getResource(target); try ( final Writer writer = resource.newWriter()) { writeMap(writer, object, indent); } catch (final IOException e) { } } public static void writeMap(final Writer writer, final Map<String, ? extends Object> object) { writeMap(writer, object, true); } public static void writeMap(final Writer writer, final Map<String, ? extends Object> object, final boolean indent) { try ( final JsonMapWriter out = new JsonMapWriter(writer, indent)) { out.setSingleObject(true); out.write(object); } catch (final RuntimeException | Error e) { throw e; } } public Json() { super("JSON"); addMediaTypeAndFileExtension(MIME_TYPE, FILE_EXTENSION); } @Override public boolean isReadFromZipFileSupported() { return true; } @Override public MapReader newMapReader(final Resource resource) { return new JsonMapReader(resource.getInputStream()); } @Override public MapWriter newMapWriter(final OutputStream out, final Charset charset) { return newMapWriter(out); } @Override public MapWriter newMapWriter(final Writer out) { return new JsonMapWriter(out); } @Override public RecordWriter newRecordWriter(final String baseName, final RecordDefinition recordDefinition, final OutputStream outputStream, final Charset charset) { final OutputStreamWriter writer = FileUtil.newUtf8Writer(outputStream); return new JsonRecordWriter(recordDefinition, writer); } }