001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.plugins.streetside.utils.api;
003
004import javax.json.JsonArray;
005import javax.json.JsonObject;
006import javax.json.JsonValue;
007
008import org.openstreetmap.josm.data.coor.LatLon;
009import org.openstreetmap.josm.plugins.streetside.model.MapObject;
010import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3;
011
012/**
013 * Decodes the JSON returned by {@link APIv3} into Java objects.
014 * Takes a {@link JsonObject} and {@link #decodeMapObject(JsonObject)} tries to convert it to a {@link MapObject}.
015 */
016public final class JsonMapObjectDecoder {
017  private JsonMapObjectDecoder() {
018    // Private constructor to avoid instantiation
019  }
020
021  public static MapObject decodeMapObject(final JsonObject json) {
022    if (json == null || !"Feature".equals(json.getString("type", null))) {
023      return null;
024    }
025
026    final JsonValue properties = json.get("properties");
027    final JsonValue geometry = json.get("geometry");
028    if (properties instanceof JsonObject && geometry instanceof JsonObject) {
029      final String key = ((JsonObject) properties).getString("key", null);
030      final String packg = ((JsonObject) properties).getString("package", null);
031      final String value = ((JsonObject) properties).getString("value", null);
032      final Long firstSeenTime = JsonDecoder.decodeTimestamp(((JsonObject) properties).getString("first_seen_at", null));
033      final Long lastSeenTime = JsonDecoder.decodeTimestamp(((JsonObject) properties).getString("last_seen_at", null));
034      final Long updatedTime = JsonDecoder.decodeTimestamp(((JsonObject) properties).getString("updated_at", null));
035
036      final JsonValue coordVal = "Point".equals(((JsonObject) geometry).getString("type", null))
037        ? ((JsonObject) geometry).get("coordinates")
038        : null;
039      final LatLon coordinate = coordVal instanceof JsonArray ? JsonDecoder.decodeLatLon((JsonArray) coordVal) : null;
040
041      if (
042        key != null &&
043        packg != null &&
044        value != null &&
045        firstSeenTime != null &&
046        lastSeenTime != null &&
047        updatedTime != null &&
048        coordinate != null
049      ) {
050        return new MapObject(
051          coordinate,
052          key,
053          packg,
054          value,
055          firstSeenTime, lastSeenTime, updatedTime
056        );
057      }
058    }
059    return null;
060  }
061}