diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/CommonSourceReader.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/CommonSourceReader.java index 4a7d1c05..b7430017 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/CommonSourceReader.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/CommonSourceReader.java @@ -10,10 +10,7 @@ import org.openstreetmap.josm.tools.Utils; import jakarta.json.Json; -import jakarta.json.JsonObject; -import jakarta.json.JsonReader; -import jakarta.json.JsonStructure; -import jakarta.json.JsonValue; +import jakarta.json.stream.JsonParser; import jakarta.json.stream.JsonParsingException; /** @@ -44,12 +41,12 @@ public Optional parse() throws IOException { this.cachedFile = new CachedFile(this.source); } this.cachedFile.setFastFail(this.fastFail); - try (JsonReader reader = Json.createReader(cachedFile.setMaxAge(CachedFile.DAYS) + try (JsonParser reader = Json.createParser(cachedFile.setMaxAge(CachedFile.DAYS) .setCachingStrategy(CachedFile.CachingStrategy.IfModifiedSince).getContentReader())) { - JsonStructure struct = reader.read(); - if (JsonValue.ValueType.OBJECT == struct.getValueType()) { - final var jsonObject = struct.asJsonObject(); - return Optional.ofNullable(this.parseJson(jsonObject)); + while (reader.hasNext()) { + if (reader.hasNext() && reader.next() == JsonParser.Event.START_OBJECT) { + return Optional.ofNullable(this.parseJson(reader)); + } } } catch (JsonParsingException jsonParsingException) { Logging.error(jsonParsingException); @@ -60,10 +57,10 @@ public Optional parse() throws IOException { /** * Parses MapWithAI entry sources * - * @param jsonObject The json of the data sources + * @param parser The json of the data sources. This will be in the {@link JsonParser.Event#START_OBJECT} state. * @return The parsed entries */ - public abstract T parseJson(JsonObject jsonObject); + public abstract T parseJson(JsonParser parser); /** * Sets whether opening HTTP connections should fail fast, i.e., whether a diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ConflationSourceReader.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ConflationSourceReader.java index ab654c27..2da38b30 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ConflationSourceReader.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ConflationSourceReader.java @@ -10,9 +10,9 @@ import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAICategory; import org.openstreetmap.josm.tools.Pair; -import jakarta.json.JsonObject; import jakarta.json.JsonString; import jakarta.json.JsonValue; +import jakarta.json.stream.JsonParser; /** * Read conflation entries from JSON @@ -44,12 +44,12 @@ public ConflationSourceReader(String source) { /** * Parses MapWithAI entry sources * - * @param jsonObject The json of the data sources + * @param parser The json of the data sources * @return The parsed entries */ @Override - public Map> parseJson(JsonObject jsonObject) { - return jsonObject.entrySet().stream().flatMap(i -> parse(i).stream()) + public Map> parseJson(JsonParser parser) { + return parser.getObjectStream().flatMap(i -> parse(i).stream()) .collect(Collectors.groupingBy(p -> p.a, Collectors.mapping(p -> p.b, Collectors.toList()))); } diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ESRISourceReader.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ESRISourceReader.java index 787e3593..04d087f1 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ESRISourceReader.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ESRISourceReader.java @@ -164,7 +164,7 @@ private ForkJoinTask parse(JsonObject feature) { newInfo.setName(feature.getString("title", feature.getString("name"))); final var extent = feature.getJsonArray("extent").getValuesAs(JsonArray.class).stream() .flatMap(array -> array.getValuesAs(JsonNumber.class).stream()).map(JsonNumber::doubleValue) - .map(Object::toString).toArray(String[]::new); + .map(d -> Double.toString(d)).toArray(String[]::new); final var imageryBounds = new ImageryBounds(String.join(",", extent[1], extent[0], extent[3], extent[2]), ","); newInfo.setBounds(imageryBounds); newInfo.setSourceType(MapWithAIType.ESRI_FEATURE_SERVER); diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/MapWithAISourceReader.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/MapWithAISourceReader.java index a54cc213..51c8b696 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/MapWithAISourceReader.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/MapWithAISourceReader.java @@ -17,9 +17,9 @@ import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIType; import org.openstreetmap.josm.tools.Territories; -import jakarta.json.JsonObject; import jakarta.json.JsonString; import jakarta.json.JsonValue; +import jakarta.json.stream.JsonParser; /** * Reader to parse the list of available MapWithAI servers from an JSON @@ -54,12 +54,12 @@ public MapWithAISourceReader(String source) { /** * Parses MapWithAI entry sources * - * @param jsonObject The json of the data sources + * @param parser The json of the data sources * @return The parsed entries */ @Override - public List parseJson(JsonObject jsonObject) { - return jsonObject.entrySet().stream().map(MapWithAISourceReader::parse).collect(Collectors.toList()); + public List parseJson(JsonParser parser) { + return parser.getObjectStream().map(MapWithAISourceReader::parse).collect(Collectors.toList()); } private static MapWithAIInfo parse(Map.Entry entry) { diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/OvertureSourceReader.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/OvertureSourceReader.java index 8e741875..6c51b50d 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/OvertureSourceReader.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/OvertureSourceReader.java @@ -9,6 +9,8 @@ import java.util.Collections; import java.util.EnumSet; import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.imagery.ImageryInfo; @@ -23,6 +25,7 @@ import jakarta.json.JsonObject; import jakarta.json.JsonString; import jakarta.json.JsonValue; +import jakarta.json.stream.JsonParser; /** * Read data from overture sources @@ -36,35 +39,38 @@ public OvertureSourceReader(MapWithAIInfo source) { } @Override - public List parseJson(JsonObject jsonObject) { + public List parseJson(JsonParser jsonParser) { + final var jsonObject = jsonParser.getObject(); if (jsonObject.containsKey("releases")) { - final var info = new ArrayList(6 * 4); - final var releases = jsonObject.get("releases"); - final var baseUri = URI.create(this.source.getUrl()).resolve("./"); // safe since we created an URI from the source to get to this point - if (releases instanceof JsonArray rArray) { - for (JsonValue value : rArray) { - if (value instanceof JsonObject release && release.containsKey("release_id") - && release.containsKey("files")) { - final var id = release.get("release_id"); - final var files = release.get("files"); - if (id instanceof JsonString sId && files instanceof JsonArray fArray) { - final String releaseId = sId.getString(); - for (JsonValue file : fArray) { - final var newInfo = parseFile(baseUri, releaseId, file); - if (newInfo != null) { - info.add(newInfo); - } - } - } - } - } - } - info.trimToSize(); - return info; + return parseRoot(jsonObject); } return Collections.emptyList(); } + private List parseRoot(JsonObject jsonObject) { + final var info = new ArrayList(6 * 4); + final var releases = jsonObject.get("releases"); + final var baseUri = URI.create(this.source.getUrl()).resolve("./"); // safe since we created an URI from the source to get to this point + if (releases instanceof JsonArray rArray) { + rArray.parallelStream().flatMap(value -> parseReleases(baseUri, value)).filter(Objects::nonNull) + .forEachOrdered(info::add); + } + info.trimToSize(); + return info; + } + + private Stream parseReleases(URI baseUri, JsonValue value) { + if (value instanceof JsonObject release && release.containsKey("release_id") && release.containsKey("files")) { + final var id = release.get("release_id"); + final var files = release.get("files"); + if (id instanceof JsonString sId && files instanceof JsonArray fArray) { + final String releaseId = sId.getString(); + return fArray.parallelStream().map(file -> parseFile(baseUri, releaseId, file)); + } + } + return Stream.empty(); + } + /** * Parse the individual file from the files array * @param baseUri The base URI (if the href is relative)