diff --git a/spring-boot-tools/spring-boot-configuration-metadata/pom.xml b/spring-boot-tools/spring-boot-configuration-metadata/pom.xml index 6374a429cd40..f54557497916 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/pom.xml +++ b/spring-boot-tools/spring-boot-configuration-metadata/pom.xml @@ -18,10 +18,9 @@ ${basedir}/../.. - - org.json - json + com.googlecode.json-simple + json-simple diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataRepositoryJsonBuilder.java b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataRepositoryJsonBuilder.java index f268a26dccbf..94f6f2905c79 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataRepositoryJsonBuilder.java +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataRepositoryJsonBuilder.java @@ -16,6 +16,8 @@ package org.springframework.boot.configurationmetadata; +import org.json.simple.parser.ParseException; + import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; @@ -23,8 +25,6 @@ import java.util.List; import java.util.Map; -import org.json.JSONException; - /** * Load a {@link ConfigurationMetadataRepository} from the content of arbitrary * resource(s). @@ -98,8 +98,7 @@ public ConfigurationMetadataRepository build() { return result; } - private SimpleConfigurationMetadataRepository add(InputStream in, Charset charset) - throws IOException { + private SimpleConfigurationMetadataRepository add(InputStream in, Charset charset) { try { RawConfigurationMetadata metadata = this.reader.read(in, charset); return create(metadata); @@ -108,7 +107,7 @@ private SimpleConfigurationMetadataRepository add(InputStream in, Charset charse throw new IllegalArgumentException( "Failed to read configuration " + "metadata", ex); } - catch (JSONException ex) { + catch (ParseException ex) { throw new IllegalArgumentException( "Invalid configuration " + "metadata document", ex); } diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/JsonReader.java b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/JsonReader.java index 97b33969f248..bb6183ff250f 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/JsonReader.java +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/JsonReader.java @@ -19,13 +19,18 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.StringWriter; import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Iterator; +import java.util.Collections; import java.util.List; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; -import org.json.JSONArray; -import org.json.JSONObject; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; /** * Read standard json metadata format as {@link ConfigurationMetadataRepository}. @@ -40,7 +45,7 @@ class JsonReader { private final DescriptionExtractor descriptionExtractor = new DescriptionExtractor(); public RawConfigurationMetadata read(InputStream in, Charset charset) - throws IOException { + throws IOException, ParseException { JSONObject json = readJson(in, charset); List groups = parseAllSources(json); List items = parseAllItems(json); @@ -49,102 +54,83 @@ public RawConfigurationMetadata read(InputStream in, Charset charset) } private List parseAllSources(JSONObject root) { - List result = new ArrayList(); - if (!root.has("groups")) { - return result; - } - JSONArray sources = root.getJSONArray("groups"); - for (int i = 0; i < sources.length(); i++) { - JSONObject source = sources.getJSONObject(i); - result.add(parseSource(source)); - } - return result; + return parse(root, this::parseSource, "groups"); } private List parseAllItems(JSONObject root) { - List result = new ArrayList(); - if (!root.has("properties")) { - return result; - } - JSONArray items = root.getJSONArray("properties"); - for (int i = 0; i < items.length(); i++) { - JSONObject item = items.getJSONObject(i); - result.add(parseItem(item)); - } - return result; + return parse(root, this::parseItem, "properties"); } private List parseAllHints(JSONObject root) { - List result = new ArrayList(); - if (!root.has("hints")) { - return result; - } - JSONArray items = root.getJSONArray("hints"); - for (int i = 0; i < items.length(); i++) { - JSONObject item = items.getJSONObject(i); - result.add(parseHint(item)); + return parse(root, this::parseHint, "hints"); + } + + private List parse(JSONObject root, Function parser, String key) { + if (!root.containsKey(key)) { + return Collections.emptyList(); } - return result; + + List items = getMustExist(root, (key)); + return items.stream().map(parser).collect(Collectors.toList()); } private ConfigurationMetadataSource parseSource(JSONObject json) { ConfigurationMetadataSource source = new ConfigurationMetadataSource(); - source.setGroupId(json.getString("name")); - source.setType(json.optString("type", null)); - String description = json.optString("description", null); + source.setGroupId(getMustExist(json, "name")); + source.setType(getOrNull(json, "type")); + String description = getOrNull(json, "description"); source.setDescription(description); source.setShortDescription( this.descriptionExtractor.getShortDescription(description)); - source.setSourceType(json.optString("sourceType", null)); - source.setSourceMethod(json.optString("sourceMethod", null)); + source.setSourceType(getOrNull(json, "sourceType")); + source.setSourceMethod(getOrNull(json, "sourceMethod")); return source; } private ConfigurationMetadataItem parseItem(JSONObject json) { ConfigurationMetadataItem item = new ConfigurationMetadataItem(); - item.setId(json.getString("name")); - item.setType(json.optString("type", null)); - String description = json.optString("description", null); + item.setId(getMustExist(json, "name")); + item.setType(getOrNull(json, "type")); + String description = getOrNull(json, "description"); item.setDescription(description); item.setShortDescription( this.descriptionExtractor.getShortDescription(description)); - item.setDefaultValue(readItemValue(json.opt("defaultValue"))); + item.setDefaultValue(readItemValue(getOrNull(json, "defaultValue"))); item.setDeprecation(parseDeprecation(json)); - item.setSourceType(json.optString("sourceType", null)); - item.setSourceMethod(json.optString("sourceMethod", null)); + item.setSourceType(getOrNull(json, "sourceType")); + item.setSourceMethod(getOrNull(json, "sourceMethod")); return item; } private ConfigurationMetadataHint parseHint(JSONObject json) { ConfigurationMetadataHint hint = new ConfigurationMetadataHint(); - hint.setId(json.getString("name")); - if (json.has("values")) { - JSONArray values = json.getJSONArray("values"); - for (int i = 0; i < values.length(); i++) { - JSONObject value = values.getJSONObject(i); + hint.setId(getMustExist(json, ("name"))); + if (json.containsKey("values")) { + JSONArray values = getMustExist(json, "values"); + for (int i = 0; i < values.size(); i++) { + JSONObject value = (JSONObject) values.get(i); ValueHint valueHint = new ValueHint(); - valueHint.setValue(readItemValue(value.get("value"))); - String description = value.optString("description", null); + valueHint.setValue(readItemValue(getMustExist(value, "value"))); + String description = getOrNull(value, "description"); valueHint.setDescription(description); valueHint.setShortDescription( this.descriptionExtractor.getShortDescription(description)); hint.getValueHints().add(valueHint); } } - if (json.has("providers")) { - JSONArray providers = json.getJSONArray("providers"); - for (int i = 0; i < providers.length(); i++) { - JSONObject provider = providers.getJSONObject(i); + if (json.containsKey("providers")) { + JSONArray providers = getMustExist(json, ("providers")); + for (int i = 0; i < providers.size(); i++) { + JSONObject provider = (JSONObject) providers.get(i); ValueProvider valueProvider = new ValueProvider(); - valueProvider.setName(provider.getString("name")); - if (provider.has("parameters")) { - JSONObject parameters = provider.getJSONObject("parameters"); - Iterator keys = parameters.keys(); - while (keys.hasNext()) { - String key = (String) keys.next(); + valueProvider.setName(getMustExist(provider, "name")); + if (provider.containsKey("parameters")) { + JSONObject parameters = getMustExist(provider, "parameters"); + Set keys = parameters.keySet(); + keys.forEach( key -> { valueProvider.getParameters().put(key, - readItemValue(parameters.get(key))); - } + readItemValue(getMustExist(parameters, key))); + }); } hint.getValueProviders().add(valueProvider); } @@ -153,22 +139,23 @@ private ConfigurationMetadataHint parseHint(JSONObject json) { } private Deprecation parseDeprecation(JSONObject object) { - if (object.has("deprecation")) { - JSONObject deprecationJsonObject = object.getJSONObject("deprecation"); + if (object.containsKey("deprecation")) { + JSONObject deprecationJsonObject = getMustExist(object, "deprecation"); Deprecation deprecation = new Deprecation(); - deprecation.setReason(deprecationJsonObject.optString("reason", null)); + deprecation.setReason(getOrNull(deprecationJsonObject, "reason")); deprecation - .setReplacement(deprecationJsonObject.optString("replacement", null)); + .setReplacement(getOrNull(deprecationJsonObject, "replacement")); return deprecation; } - return (object.optBoolean("deprecated") ? new Deprecation() : null); + final Boolean deprecated = getOrNull(object, "deprecated"); + return (deprecated != null && deprecated) ? new Deprecation() : null; } private Object readItemValue(Object value) { if (value instanceof JSONArray) { JSONArray array = (JSONArray) value; - Object[] content = new Object[array.length()]; - for (int i = 0; i < array.length(); i++) { + Object[] content = new Object[array.size()]; + for (int i = 0; i < array.size(); i++) { content[i] = array.get(i); } return content; @@ -176,20 +163,42 @@ private Object readItemValue(Object value) { return value; } - private JSONObject readJson(InputStream in, Charset charset) throws IOException { + private JSONObject readJson(InputStream in, Charset charset) throws IOException, ParseException { try { - StringBuilder out = new StringBuilder(); + StringWriter out = new StringWriter(); InputStreamReader reader = new InputStreamReader(in, charset); char[] buffer = new char[BUFFER_SIZE]; - int bytesRead = -1; + int bytesRead; while ((bytesRead = reader.read(buffer)) != -1) { - out.append(buffer, 0, bytesRead); + out.append(new String(buffer), 0, bytesRead); } - return new JSONObject(out.toString()); + JSONParser parser = new JSONParser(); + return (JSONObject) parser.parse(out.toString()); } finally { in.close(); } } + @SuppressWarnings("unchecked") + private T get(JSONObject source, String key, boolean mustExist) { + final T value = (T) source.get(key); + if (value != null) { + return value; + } + + if (mustExist) { + throw new IllegalStateException("Key " + key + "not found."); + } + + return null; + } + + private T getOrNull(JSONObject source, String key) { + return get(source, key, false); + } + + private T getMustExist(JSONObject source, String key) { + return get(source, key, true); + } } diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java b/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java index 488eab2bc064..21e0abe2a598 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java @@ -16,11 +16,9 @@ package org.springframework.boot.configurationmetadata; -import java.io.IOException; import java.nio.charset.Charset; import java.util.List; -import org.json.JSONException; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -37,20 +35,20 @@ public class JsonReaderTests extends AbstractConfigurationMetadataTests { private final JsonReader reader = new JsonReader(); @Test - public void emptyMetadata() throws IOException { + public void emptyMetadata() throws Exception { RawConfigurationMetadata rawMetadata = readFor("empty"); assertThat(rawMetadata.getSources()).isEmpty(); assertThat(rawMetadata.getItems()).isEmpty(); } @Test - public void invalidMetadata() throws IOException { - this.thrown.expect(JSONException.class); + public void invalidMetadata() throws Exception { + this.thrown.expect(IllegalStateException.class); readFor("invalid"); } @Test - public void emptyGroupName() throws IOException { + public void emptyGroupName() throws Exception { RawConfigurationMetadata rawMetadata = readFor("empty-groups"); List items = rawMetadata.getItems(); assertThat(items).hasSize(2); @@ -62,7 +60,7 @@ public void emptyGroupName() throws IOException { } @Test - public void simpleMetadata() throws IOException { + public void simpleMetadata() throws Exception { RawConfigurationMetadata rawMetadata = readFor("foo"); List sources = rawMetadata.getSources(); assertThat(sources).hasSize(2); @@ -92,7 +90,7 @@ public void simpleMetadata() throws IOException { assertThat(hint.getId()).isEqualTo("spring.foo.counter"); assertThat(hint.getValueHints()).hasSize(1); ValueHint valueHint = hint.getValueHints().get(0); - assertThat(valueHint.getValue()).isEqualTo(42); + assertThat(valueHint.getValue()).isEqualTo(42L); assertThat(valueHint.getDescription()).isEqualTo( "Because that's the answer to any question, choose it. \nReally."); assertThat(valueHint.getShortDescription()) @@ -106,7 +104,7 @@ public void simpleMetadata() throws IOException { } @Test - public void metadataHints() throws IOException { + public void metadataHints() throws Exception { RawConfigurationMetadata rawMetadata = readFor("bar"); List hints = rawMetadata.getHints(); assertThat(hints).hasSize(1); @@ -133,7 +131,7 @@ public void metadataHints() throws IOException { } @Test - public void rootMetadata() throws IOException { + public void rootMetadata() throws Exception { RawConfigurationMetadata rawMetadata = readFor("root"); List sources = rawMetadata.getSources(); assertThat(sources).isEmpty(); @@ -144,7 +142,7 @@ public void rootMetadata() throws IOException { } @Test - public void deprecatedMetadata() throws IOException { + public void deprecatedMetadata() throws Exception { RawConfigurationMetadata rawMetadata = readFor("deprecated"); List items = rawMetadata.getItems(); assertThat(items).hasSize(3); @@ -171,8 +169,7 @@ public void deprecatedMetadata() throws IOException { assertThat(item3.getDeprecation()).isEqualTo(null); } - RawConfigurationMetadata readFor(String path) throws IOException { + private RawConfigurationMetadata readFor(String path) throws Exception { return this.reader.read(getInputStreamFor(path), DEFAULT_CHARSET); } - } diff --git a/spring-boot-tools/spring-boot-configuration-processor/pom.xml b/spring-boot-tools/spring-boot-configuration-processor/pom.xml index 21d0fca3d3d2..6128b888873b 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/pom.xml +++ b/spring-boot-tools/spring-boot-configuration-processor/pom.xml @@ -1,49 +1,59 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-tools - 2.0.0.BUILD-SNAPSHOT - - spring-boot-configuration-processor - Spring Boot Configuration Processor - Spring Boot Configuration Processor - http://projects.spring.io/spring-boot/ - - Pivotal Software, Inc. - http://www.spring.io - - - ${basedir}/../.. - - - - - org.json - json - - - - org.projectlombok - lombok - test - - - org.springframework - spring-core - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - none - - - - - + + + 4.0.0 + + org.springframework.boot + spring-boot-tools + 2.0.0.BUILD-SNAPSHOT + + spring-boot-configuration-processor + Spring Boot Configuration Processor + Spring Boot Configuration Processor + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + + + + + com.googlecode.json-simple + json-simple + + + org.springframework + spring-core + + + + org.projectlombok + lombok + test + + + com.fasterxml.jackson.core + jackson-core + test + + + com.fasterxml.jackson.core + jackson-databind + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + none + + + + + diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataStore.java b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataStore.java index a78569ddafed..4acf2a64c13f 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataStore.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/MetadataStore.java @@ -27,8 +27,7 @@ import javax.tools.FileObject; import javax.tools.StandardLocation; -import org.json.JSONException; - +import org.json.simple.parser.ParseException; import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; import org.springframework.boot.configurationprocessor.metadata.InvalidConfigurationMetadataException; import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller; @@ -87,7 +86,7 @@ private ConfigurationMetadata readMetadata(InputStream in) throws IOException { catch (IOException ex) { return null; } - catch (JSONException ex) { + catch (ParseException ex) { throw new InvalidConfigurationMetadataException( "Invalid additional meta-data in '" + METADATA_PATH + "': " + ex.getMessage(), diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java index 13bc23e4473e..5b4a7520dd1b 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshaller.java @@ -30,10 +30,10 @@ import java.util.Map; import java.util.Set; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; import org.springframework.boot.configurationprocessor.metadata.ItemMetadata.ItemType; /** @@ -55,14 +55,14 @@ public void write(ConfigurationMetadata metadata, OutputStream outputStream) object.put("groups", toJsonArray(metadata, ItemType.GROUP)); object.put("properties", toJsonArray(metadata, ItemType.PROPERTY)); object.put("hints", toJsonArray(metadata.getHints())); - outputStream.write(object.toString(2).getBytes(UTF_8)); + outputStream.write(object.toString().getBytes(UTF_8)); } private JSONArray toJsonArray(ConfigurationMetadata metadata, ItemType itemType) { JSONArray jsonArray = new JSONArray(); for (ItemMetadata item : metadata.getItems()) { if (item.isOfItemType(itemType)) { - jsonArray.put(toJsonObject(item)); + jsonArray.add(toJsonObject(item)); } } return jsonArray; @@ -71,7 +71,7 @@ private JSONArray toJsonArray(ConfigurationMetadata metadata, ItemType itemType) private JSONArray toJsonArray(Collection hints) { JSONArray jsonArray = new JSONArray(); for (ItemHint hint : hints) { - jsonArray.put(toJsonObject(hint)); + jsonArray.add(toJsonObject(hint)); } return jsonArray; } @@ -117,7 +117,7 @@ private JSONObject toJsonObject(ItemHint hint) { private JSONArray getItemHintValues(ItemHint hint) { JSONArray values = new JSONArray(); for (ItemHint.ValueHint value : hint.getValues()) { - values.put(getItemHintValue(value)); + values.add(getItemHintValue(value)); } return values; } @@ -132,7 +132,7 @@ private JSONObject getItemHintValue(ItemHint.ValueHint value) { private JSONArray getItemHintProviders(ItemHint hint) { JSONArray providers = new JSONArray(); for (ItemHint.ValueProvider provider : hint.getProviders()) { - providers.put(getItemHintProvider(provider)); + providers.add(getItemHintProvider(provider)); } return providers; } @@ -172,7 +172,7 @@ private Object extractItemValue(Object value) { JSONArray array = new JSONArray(); int length = Array.getLength(value); for (int i = 0; i < length; i++) { - array.put(Array.get(value, i)); + array.add(Array.get(value, i)); } defaultValue = array; @@ -180,25 +180,25 @@ private Object extractItemValue(Object value) { return defaultValue; } - public ConfigurationMetadata read(InputStream inputStream) throws IOException { + public ConfigurationMetadata read(InputStream inputStream) throws IOException, ParseException { ConfigurationMetadata metadata = new ConfigurationMetadata(); - JSONObject object = new JSONObject(toString(inputStream)); - JSONArray groups = object.optJSONArray("groups"); + JSONObject object = parseJson(inputStream); + JSONArray groups = getOrNull(object, "groups"); if (groups != null) { - for (int i = 0; i < groups.length(); i++) { + for (int i = 0; i < groups.size(); i++) { metadata.add(toItemMetadata((JSONObject) groups.get(i), ItemType.GROUP)); } } - JSONArray properties = object.optJSONArray("properties"); + JSONArray properties = getOrNull(object, "properties"); if (properties != null) { - for (int i = 0; i < properties.length(); i++) { + for (int i = 0; i < properties.size(); i++) { metadata.add(toItemMetadata((JSONObject) properties.get(i), ItemType.PROPERTY)); } } - JSONArray hints = object.optJSONArray("hints"); + JSONArray hints = getOrNull(object, "hints"); if (hints != null) { - for (int i = 0; i < hints.length(); i++) { + for (int i = 0; i < hints.size(); i++) { metadata.add(toItemHint((JSONObject) hints.get(i))); } } @@ -206,42 +206,43 @@ public ConfigurationMetadata read(InputStream inputStream) throws IOException { } private ItemMetadata toItemMetadata(JSONObject object, ItemType itemType) { - String name = object.getString("name"); - String type = object.optString("type", null); - String description = object.optString("description", null); - String sourceType = object.optString("sourceType", null); - String sourceMethod = object.optString("sourceMethod", null); - Object defaultValue = readItemValue(object.opt("defaultValue")); + String name = getMustExist(object, "name"); + String type = getOrNull(object, "type"); + String description = getOrNull(object, "description"); + String sourceType = getOrNull(object, "sourceType"); + String sourceMethod = getOrNull(object, "sourceMethod"); + Object defaultValue = readItemValue(getOrNull(object, "defaultValue")); ItemDeprecation deprecation = toItemDeprecation(object); return new ItemMetadata(itemType, name, null, type, sourceType, sourceMethod, description, defaultValue, deprecation); } private ItemDeprecation toItemDeprecation(JSONObject object) { - if (object.has("deprecation")) { - JSONObject deprecationJsonObject = object.getJSONObject("deprecation"); + if (object.containsKey("deprecation")) { + JSONObject deprecationJsonObject = getMustExist(object, "deprecation"); ItemDeprecation deprecation = new ItemDeprecation(); - deprecation.setReason(deprecationJsonObject.optString("reason", null)); + deprecation.setReason(getOrNull(deprecationJsonObject, "reason")); deprecation - .setReplacement(deprecationJsonObject.optString("replacement", null)); + .setReplacement(getOrNull(deprecationJsonObject, "replacement")); return deprecation; } - return (object.optBoolean("deprecated") ? new ItemDeprecation() : null); + final Boolean deprecated = getOrNull(object, "deprecated"); + return (deprecated != null && deprecated) ? new ItemDeprecation() : null; } private ItemHint toItemHint(JSONObject object) { - String name = object.getString("name"); + String name = getMustExist(object, "name"); List values = new ArrayList(); - if (object.has("values")) { - JSONArray valuesArray = object.getJSONArray("values"); - for (int i = 0; i < valuesArray.length(); i++) { + if (object.containsKey("values")) { + JSONArray valuesArray = getMustExist(object, "values"); + for (int i = 0; i < valuesArray.size(); i++) { values.add(toValueHint((JSONObject) valuesArray.get(i))); } } List providers = new ArrayList(); - if (object.has("providers")) { - JSONArray providersObject = object.getJSONArray("providers"); - for (int i = 0; i < providersObject.length(); i++) { + if (object.containsKey("providers")) { + JSONArray providersObject = getMustExist(object, "providers"); + for (int i = 0; i < providersObject.size(); i++) { providers.add(toValueProvider((JSONObject) providersObject.get(i))); } } @@ -249,16 +250,16 @@ private ItemHint toItemHint(JSONObject object) { } private ItemHint.ValueHint toValueHint(JSONObject object) { - Object value = readItemValue(object.get("value")); - String description = object.optString("description", null); + Object value = readItemValue(getMustExist(object, "value")); + String description = getOrNull(object, "description"); return new ItemHint.ValueHint(value, description); } private ItemHint.ValueProvider toValueProvider(JSONObject object) { - String name = object.getString("name"); + String name = getMustExist(object, "name"); Map parameters = new HashMap(); - if (object.has("parameters")) { - JSONObject parametersObject = object.getJSONObject("parameters"); + if (object.containsKey("parameters")) { + JSONObject parametersObject = getMustExist(object, "parameters"); for (Object k : parametersObject.keySet()) { String key = (String) k; Object value = readItemValue(parametersObject.get(key)); @@ -271,8 +272,8 @@ private ItemHint.ValueProvider toValueProvider(JSONObject object) { private Object readItemValue(Object value) { if (value instanceof JSONArray) { JSONArray array = (JSONArray) value; - Object[] content = new Object[array.length()]; - for (int i = 0; i < array.length(); i++) { + Object[] content = new Object[array.size()]; + for (int i = 0; i < array.size(); i++) { content[i] = array.get(i); } return content; @@ -280,7 +281,7 @@ private Object readItemValue(Object value) { return value; } - private String toString(InputStream inputStream) throws IOException { + private JSONObject parseJson(InputStream inputStream) throws IOException, ParseException { StringBuilder out = new StringBuilder(); InputStreamReader reader = new InputStreamReader(inputStream, UTF_8); char[] buffer = new char[BUFFER_SIZE]; @@ -288,7 +289,31 @@ private String toString(InputStream inputStream) throws IOException { while ((bytesRead = reader.read(buffer)) != -1) { out.append(buffer, 0, bytesRead); } - return out.toString(); + JSONParser parser = new JSONParser(); + parser.parse(out.toString()); + return (JSONObject) parser.parse(out.toString()); + } + + @SuppressWarnings("unchecked") + private T get(JSONObject source, String key, boolean mustExist) { + final T value = (T) source.get(key); + if (value != null) { + return value; + } + + if (mustExist) { + throw new IllegalStateException("Key " + key + "not found."); + } + + return null; + } + + private T getOrNull(JSONObject source, String key) { + return get(source, key, false); + } + + private T getMustExist(JSONObject source, String key) { + return get(source, key, true); } /** @@ -296,12 +321,13 @@ private String toString(InputStream inputStream) throws IOException { */ @SuppressWarnings("rawtypes") private static class JSONOrderedObject extends JSONObject { + private static final long serialVersionUID = -2562835478249976579L; private Set keys = new LinkedHashSet(); @Override - public JSONObject put(String key, Object value) throws JSONException { - this.keys.add(key); + public Object put(Object key, Object value) { + this.keys.add((String) key); return super.put(key, value); } @@ -309,7 +335,5 @@ public JSONObject put(String key, Object value) throws JSONException { public Set keySet() { return this.keys; } - } - } diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java index c9a3033a6eb8..d295e3685f80 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java @@ -22,8 +22,8 @@ import java.util.Arrays; import java.util.Collections; -import org.json.JSONArray; -import org.json.JSONObject; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -68,8 +68,11 @@ import org.springframework.boot.configurationsample.specific.SimplePojo; import org.springframework.util.FileCopyUtils; +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; import static org.assertj.core.api.Assertions.assertThat; +import com.fasterxml.jackson.databind.ObjectMapper; + /** * Tests for {@link ConfigurationMetadataAnnotationProcessor}. * @@ -87,10 +90,12 @@ public class ConfigurationMetadataAnnotationProcessorTests { public ExpectedException thrown = ExpectedException.none(); private TestCompiler compiler; + private final ObjectMapper mapper = new ObjectMapper(); @Before public void createCompiler() throws IOException { this.compiler = new TestCompiler(this.temporaryFolder); + mapper.setSerializationInclusion(NON_NULL); } @Test @@ -606,11 +611,11 @@ public void mergingOfAdditionalMetadata() throws Exception { property.put("type", "java.lang.String"); property.put("sourceType", AdditionalMetadata.class.getName()); JSONArray properties = new JSONArray(); - properties.put(property); + properties.add(property); JSONObject additionalMetadata = new JSONObject(); additionalMetadata.put("properties", properties); FileWriter writer = new FileWriter(additionalMetadataFile); - additionalMetadata.write(writer); + additionalMetadata.writeJSONString(writer); writer.flush(); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata).has(Metadata.withProperty("simple.comparator")); @@ -692,7 +697,7 @@ private void assertSimpleLombokProperties(ConfigurationMetadata metadata, assertThat(metadata).has(Metadata.withProperty(prefix + ".description")); assertThat(metadata).has(Metadata.withProperty(prefix + ".counter")); assertThat(metadata).has(Metadata.withProperty(prefix + ".number") - .fromSource(source).withDefaultValue(0).withDeprecation(null, null)); + .fromSource(source).withDefaultValue(0L).withDeprecation(null, null)); assertThat(metadata).has(Metadata.withProperty(prefix + ".items")); assertThat(metadata).doesNotHave(Metadata.withProperty(prefix + ".ignored")); } @@ -739,7 +744,7 @@ private void writePropertyDeprecation(ItemMetadata... items) throws IOException } jsonObject.put("deprecation", deprecationJson); } - propertiesArray.put(jsonObject); + propertiesArray.add(jsonObject); } JSONObject additionalMetadata = new JSONObject(); @@ -760,7 +765,7 @@ private void writeMetadata(File metadataFile, JSONObject metadata) throws IOException { FileWriter writer = new FileWriter(metadataFile); try { - metadata.write(writer); + mapper.writeValue(writer, metadata); } finally { writer.close(); diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestConfigurationMetadataAnnotationProcessor.java b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestConfigurationMetadataAnnotationProcessor.java index b0ff80fd51fe..28e8a30e1492 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestConfigurationMetadataAnnotationProcessor.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestConfigurationMetadataAnnotationProcessor.java @@ -24,6 +24,7 @@ import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; +import org.json.simple.parser.ParseException; import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller; @@ -84,7 +85,7 @@ protected ConfigurationMetadata writeMetaData() { } return this.metadata; } - catch (IOException e) { + catch (IOException|ParseException e) { throw new RuntimeException("Failed to read metadata from disk", e); } } diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java index 280f191accc2..853ea74ddbaa 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/metadata/JsonMarshallerTests.java @@ -18,7 +18,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.Collections; @@ -38,7 +37,7 @@ public class JsonMarshallerTests { @Test - public void marshallAndUnmarshal() throws IOException { + public void marshallAndUnmarshal() throws Exception { ConfigurationMetadata metadata = new ConfigurationMetadata(); metadata.add(ItemMetadata.newProperty("a", "b", StringBuffer.class.getName(), InputStream.class.getName(), "sourceMethod", "desc", "x", @@ -72,7 +71,7 @@ public void marshallAndUnmarshal() throws IOException { .fromSource(InputStream.class).withDescription("desc") .withDefaultValue("x").withDeprecation("Deprecation comment", "b.c.d")); assertThat(read).has(Metadata.withProperty("b.c.d")); - assertThat(read).has(Metadata.withProperty("c").withDefaultValue(123)); + assertThat(read).has(Metadata.withProperty("c").withDefaultValue(123L)); assertThat(read).has(Metadata.withProperty("d").withDefaultValue(true)); assertThat(read).has( Metadata.withProperty("e").withDefaultValue(new String[] { "y", "n" })); @@ -81,9 +80,8 @@ public void marshallAndUnmarshal() throws IOException { assertThat(read).has(Metadata.withGroup("d")); assertThat(read).has(Metadata.withHint("a.b")); assertThat(read).has( - Metadata.withHint("c").withValue(0, 123, "hey").withValue(1, 456, null)); + Metadata.withHint("c").withValue(0, 123L, "hey").withValue(1, 456L, null)); assertThat(read).has(Metadata.withHint("d").withProvider("first", "target", "foo") .withProvider("second")); } - }