-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
279 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
core/src/main/java/org/mobilitydata/gtfsvalidator/notice/GeoJsonDuplicatedElementNotice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.mobilitydata.gtfsvalidator.notice; | ||
|
||
import static org.mobilitydata.gtfsvalidator.notice.SeverityLevel.ERROR; | ||
|
||
import org.mobilitydata.gtfsvalidator.annotation.GtfsValidationNotice; | ||
|
||
/** Duplicated elements in locations.geojson file. */ | ||
@GtfsValidationNotice(severity = ERROR) | ||
public class GeoJsonDuplicatedElementNotice extends ValidationNotice { | ||
/** The name of the file where the duplicated element was found. */ | ||
private final String filename; | ||
|
||
/** The duplicated element in the GeoJSON file. */ | ||
private final String duplicatedElement; | ||
|
||
public GeoJsonDuplicatedElementNotice(String filename, String duplicatedElement) { | ||
this.filename = filename; | ||
this.duplicatedElement = duplicatedElement; | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
core/src/main/java/org/mobilitydata/gtfsvalidator/notice/GeoJsonUnknownElementNotice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.mobilitydata.gtfsvalidator.notice; | ||
|
||
import static org.mobilitydata.gtfsvalidator.notice.SeverityLevel.INFO; | ||
|
||
import org.mobilitydata.gtfsvalidator.annotation.GtfsValidationNotice; | ||
|
||
/** Unknown elements in locations.geojson file. */ | ||
@GtfsValidationNotice(severity = INFO) | ||
public class GeoJsonUnknownElementNotice extends ValidationNotice { | ||
/** The name of the file where the unknown element was found. */ | ||
private final String filename; | ||
|
||
/** The unknown element in the GeoJSON file. */ | ||
private final String unknownElement; | ||
|
||
public GeoJsonUnknownElementNotice(String filename, String unknownElement) { | ||
this.filename = filename; | ||
this.unknownElement = unknownElement; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
.../src/main/java/org/mobilitydata/gtfsvalidator/util/geojson/DuplicateJsonKeyException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package org.mobilitydata.gtfsvalidator.util.geojson; | ||
|
||
public class DuplicateJsonKeyException extends RuntimeException { | ||
private String key; | ||
private String message; | ||
|
||
public DuplicateJsonKeyException(String key, String message) { | ||
this.key = key; | ||
this.message = message; | ||
} | ||
|
||
public String getKey() { | ||
return key; | ||
} | ||
|
||
public String getMessage() { | ||
return message; | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
main/src/main/java/org/mobilitydata/gtfsvalidator/util/geojson/MapJsonTypeAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package org.mobilitydata.gtfsvalidator.util.geojson; | ||
|
||
import com.google.gson.*; | ||
import com.google.gson.stream.JsonReader; | ||
import com.google.gson.stream.JsonWriter; | ||
import java.io.IOException; | ||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* A custom JSON type adapter for parsing JSON objects with duplicate keys. The target class is | ||
* {@link Map}{@code <String, Object>}. as JSonElement is captured by the default Gson TypeAdapter. | ||
* | ||
* <p>When a JSON object has two keys with the same name at the same level, this type adapter throws | ||
* a {@link DuplicateJsonKeyException}. | ||
*/ | ||
public class MapJsonTypeAdapter extends TypeAdapter<Map<String, Object>> { | ||
|
||
@Override | ||
public void write(JsonWriter out, Map<String, Object> value) throws IOException { | ||
new Gson().toJson(value, Map.class, out); | ||
} | ||
|
||
@Override | ||
public Map<String, Object> read(JsonReader in) throws IOException { | ||
return parseJsonObject(in); | ||
} | ||
|
||
private Map<String, Object> parseJsonObject(JsonReader in) throws IOException { | ||
Map<String, Object> map = new LinkedHashMap<>(); | ||
|
||
in.beginObject(); | ||
while (in.hasNext()) { | ||
String key = in.nextName(); | ||
|
||
if (map.containsKey(key)) { | ||
throw new DuplicateJsonKeyException(key, "Duplicated Key: " + key); | ||
} | ||
|
||
Object value = parseJsonValue(in); | ||
map.put(key, value); | ||
} | ||
in.endObject(); | ||
|
||
return map; | ||
} | ||
|
||
private Object parseJsonValue(JsonReader in) throws IOException { | ||
switch (in.peek()) { | ||
case BEGIN_OBJECT: | ||
return parseJsonObject(in); | ||
case BEGIN_ARRAY: | ||
return parseJsonArray(in); | ||
case STRING: | ||
return in.nextString(); | ||
case NUMBER: | ||
return in.nextDouble(); | ||
case BOOLEAN: | ||
return in.nextBoolean(); | ||
case NULL: | ||
in.nextNull(); | ||
return null; | ||
default: | ||
throw new JsonParseException("Unexpected JSON token: " + in.peek()); | ||
} | ||
} | ||
|
||
private Object parseJsonArray(JsonReader in) throws IOException { | ||
JsonArray jsonArray = new JsonArray(); | ||
in.beginArray(); | ||
while (in.hasNext()) { | ||
jsonArray.add(new Gson().toJsonTree(parseJsonValue(in))); | ||
} | ||
in.endArray(); | ||
return jsonArray; | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
main/src/main/java/org/mobilitydata/gtfsvalidator/util/geojson/UnknownJsonKeyException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package org.mobilitydata.gtfsvalidator.util.geojson; | ||
|
||
public class UnknownJsonKeyException extends RuntimeException { | ||
private final String message; | ||
private String key; | ||
|
||
public UnknownJsonKeyException(String key, String message) { | ||
this.key = key; | ||
this.message = message; | ||
} | ||
|
||
public String getKey() { | ||
return key; | ||
} | ||
|
||
public String getMessage() { | ||
return message; | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
main/src/test/java/org/mobilitydata/gtfsvalidator/util/geojson/GeoJsonTypeAdapterTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package org.mobilitydata.gtfsvalidator.util.geojson; | ||
|
||
import static org.junit.Assert.assertThrows; | ||
|
||
import com.google.gson.Gson; | ||
import com.google.gson.GsonBuilder; | ||
import com.google.gson.reflect.TypeToken; | ||
import com.google.gson.stream.JsonReader; | ||
import java.io.StringReader; | ||
import java.util.Map; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
public class GeoJsonTypeAdapterTest { | ||
|
||
Gson gson; | ||
|
||
@Before | ||
public void before() { | ||
gson = | ||
(new GsonBuilder()) | ||
.registerTypeAdapter( | ||
new TypeToken<Map<String, Object>>() {}.getType(), new MapJsonTypeAdapter()) | ||
.create(); | ||
} | ||
|
||
/** | ||
* Test that the custom JSON type adapter can handle a throws DuplicateJsonKeyException when: - A | ||
* JSON object has two keys with the same name at the same level. | ||
*/ | ||
@Test | ||
public void testDuplicateKeyExceptionSameLevel() { | ||
final var json = "{ \"type\": 1, \"type\": 2 }"; | ||
JsonReader reader = new JsonReader(new StringReader(json)); | ||
MapJsonTypeAdapter adapter = new MapJsonTypeAdapter(); | ||
assertThrows( | ||
DuplicateJsonKeyException.class, | ||
() -> { | ||
adapter.read(reader); | ||
}); | ||
} | ||
|
||
/** | ||
* Test that the custom JSON type adapter can handle a simple JSON object that don't contain | ||
* duplicate keys. | ||
*/ | ||
@Test | ||
public void testDuplicateKeyExceptionNestedLevel() { | ||
String json = | ||
"{\"type\": \"Alice\", \"features\": { \"properties\": \"Bob\", \"properties\": \"abc\" }}"; | ||
JsonReader reader = new JsonReader(new StringReader(json)); | ||
MapJsonTypeAdapter adapter = new MapJsonTypeAdapter(); | ||
|
||
assertThrows( | ||
DuplicateJsonKeyException.class, | ||
() -> { | ||
adapter.read(reader); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters