From 0445186aa14a493d0274bbe3a96e4e24768e4309 Mon Sep 17 00:00:00 2001 From: lukaseder Date: Mon, 8 Aug 2016 16:27:25 +0200 Subject: [PATCH] [#5389] Enhance DSLContext.fetchFromJSON() to support new formats --- .../main/java/org/jooq/impl/JSONReader.java | 111 ++++++++++-------- 1 file changed, 63 insertions(+), 48 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONReader.java b/jOOQ/src/main/java/org/jooq/impl/JSONReader.java index bb6447bf03..79c9d30c0f 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONReader.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONReader.java @@ -40,16 +40,17 @@ */ package org.jooq.impl; -import static org.jooq.impl.Tools.EMPTY_STRING; - import java.io.BufferedReader; import java.io.Closeable; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import org.jooq.tools.json.ContainerFactory; import org.jooq.tools.json.JSONParser; @@ -60,86 +61,100 @@ import org.jooq.tools.json.ParseException; * * @author Johannes Bühler */ -@SuppressWarnings({ "rawtypes", "unchecked" }) +@SuppressWarnings({ "unchecked" }) final class JSONReader implements Closeable { private final BufferedReader br; private final JSONParser parser; - private String[] fieldMetaData; + private String[] fieldNames; + private Map fieldIndexes; private List records; - public JSONReader(Reader reader) { + JSONReader(Reader reader) { this.br = new BufferedReader(reader); this.parser = new JSONParser(); } - public List readAll() throws IOException { - if (this.records != null) { - return this.records; - } - try { - LinkedHashMap jsonRoot = getJsonRoot(); - readFields(jsonRoot); - records = readRecords(jsonRoot); - } - catch (ParseException ex) { - throw new RuntimeException(ex); + final List readAll() throws IOException { + if (records == null) { + try { + LinkedHashMap> jsonRoot = getJsonRoot(); + + readFields(jsonRoot); + readRecords(jsonRoot); + } + catch (ParseException ex) { + throw new RuntimeException(ex); + } } + return records; } - public String[] getFields() throws IOException { - if (fieldMetaData == null) { + final String[] getFields() throws IOException { + if (fieldNames == null) readAll(); - } - return fieldMetaData; + + return fieldNames; } @Override - public void close() throws IOException { + public final void close() throws IOException { br.close(); } - private List readRecords(LinkedHashMap jsonRoot) { - LinkedList jsonRecords = (LinkedList) jsonRoot.get("records"); - records = new ArrayList(); - for (Object record : jsonRecords) { - LinkedList values = (LinkedList) record; - List v = new ArrayList(); - for (Object value : values) { - String asString = value == null ? null : String.valueOf(value); - v.add(asString); - } - records.add(v.toArray(EMPTY_STRING)); - } + private final void readRecords(LinkedHashMap> jsonRoot) { + records = new ArrayList(); - return records; + for (Object record : jsonRoot.get("records")) { + String[] v = new String[fieldNames.length]; + int i = 0; + + // [#5372] Serialisation mode ARRAY + if (record instanceof LinkedList) + for (Object value : (LinkedList) record) + v[i++] = value == null ? null : String.valueOf(value); + + // [#5372] Serialisation mode OBJECT + else if (record instanceof LinkedHashMap) + for (Entry entry : ((LinkedHashMap) record).entrySet()) + v[fieldIndexes.get(entry.getKey())] = entry.getValue() == null ? null : String.valueOf(entry.getValue()); + + else + throw new IllegalArgumentException("Ill formed JSON : " + jsonRoot); + + records.add(v); + } } - private LinkedHashMap getJsonRoot() throws IOException, ParseException { + private LinkedHashMap> getJsonRoot() throws IOException, ParseException { Object parse = parser.parse(br, new ContainerFactory() { @Override - public LinkedHashMap createObjectContainer() { - return new LinkedHashMap(); + public LinkedHashMap createObjectContainer() { + return new LinkedHashMap(); } @Override - public List createArrayContainer() { - return new LinkedList(); + public List createArrayContainer() { + return new LinkedList(); } }); - return (LinkedHashMap) parse; + return (LinkedHashMap>) parse; } - private void readFields(LinkedHashMap jsonRoot) { - if (fieldMetaData != null) { - return; - } - LinkedList fieldEntries = (LinkedList) jsonRoot.get("fields"); - fieldMetaData = new String[fieldEntries.size()]; + private final void readFields(LinkedHashMap> jsonRoot) { + LinkedList> fieldEntries = + (LinkedList>) jsonRoot.get("fields"); + + fieldNames = new String[fieldEntries.size()]; + fieldIndexes = new HashMap(); int i = 0; - for (Object key : fieldEntries) { - fieldMetaData[i] = (String) ((LinkedHashMap) key).get("name"); + for (LinkedHashMap key : fieldEntries) { + String name = key.get("name"); + + fieldNames[i] = name; + fieldIndexes.put(name, i); + i++; } }