Skip to content

Commit 4fcb583

Browse files
committed
fix(GTFS+): add check for missing, but required columns
fix #206
1 parent f367375 commit 4fcb583

File tree

1 file changed

+39
-16
lines changed

1 file changed

+39
-16
lines changed

src/main/java/com/conveyal/datatools/manager/controllers/api/GtfsPlusController.java

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -303,23 +303,32 @@ private static Collection<ValidationIssue> getGtfsPlusValidation(Request req, Re
303303
*/
304304
private static void validateTable(
305305
Collection<ValidationIssue> issues,
306-
JsonNode tableNode,
307-
InputStream inputStream,
306+
JsonNode specTable,
307+
InputStream inputStreamToValidate,
308308
GTFSFeed gtfsFeed
309309
) throws IOException {
310-
String tableId = tableNode.get("id").asText();
311-
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
310+
String tableId = specTable.get("id").asText();
311+
// Read in table data from input stream.
312+
BufferedReader in = new BufferedReader(new InputStreamReader(inputStreamToValidate));
312313
String line = in.readLine();
313-
String[] fields = line.split(",");
314-
List<String> fieldList = Arrays.asList(fields);
315-
JsonNode[] fieldNodes = new JsonNode[fields.length];
316-
JsonNode fieldsNode = tableNode.get("fields");
317-
for(int i = 0; i < fieldsNode.size(); i++) {
318-
JsonNode fieldNode = fieldsNode.get(i);
319-
int index = fieldList.indexOf(fieldNode.get("name").asText());
320-
if(index != -1) fieldNodes[index] = fieldNode;
314+
String[] inputHeaders = line.split(",");
315+
List<String> fieldList = Arrays.asList(inputHeaders);
316+
JsonNode[] fieldsFounds = new JsonNode[inputHeaders.length];
317+
JsonNode specFields = specTable.get("fields");
318+
// Iterate over spec fields and check that there are no missing required fields.
319+
for (int i = 0; i < specFields.size(); i++) {
320+
JsonNode specField = specFields.get(i);
321+
String fieldName = specField.get("name").asText();
322+
int index = fieldList.indexOf(fieldName);
323+
if (index != -1) {
324+
// Add spec field for each field found.
325+
fieldsFounds[index] = specField;
326+
} else if (isRequired(specField)) {
327+
// If spec field not found, check that missing field was not required.
328+
issues.add(new ValidationIssue(tableId, fieldName, -1, "Required column missing."));
329+
}
321330
}
322-
331+
// Iterate over each row and validate each field value.
323332
int rowIndex = 0;
324333
while((line = in.readLine()) != null) {
325334
String[] values = line.split(Consts.COLUMN_SPLIT, -1);
@@ -330,9 +339,22 @@ private static void validateTable(
330339
}
331340
}
332341

333-
private static void validateTableValue(Collection<ValidationIssue> issues, String tableId, int rowIndex, String value, JsonNode fieldNode, GTFSFeed gtfsFeed) {
334-
if(fieldNode == null) return;
335-
String fieldName = fieldNode.get("name").asText();
342+
/** Determine if a GTFS+ spec field is required. */
343+
private static boolean isRequired(JsonNode specField) {
344+
return specField.get("required") != null && specField.get("required").asBoolean();
345+
}
346+
347+
/** Validate a single value for a GTFS+ table. */
348+
private static void validateTableValue(
349+
Collection<ValidationIssue> issues,
350+
String tableId,
351+
int rowIndex,
352+
String value,
353+
JsonNode specField,
354+
GTFSFeed gtfsFeed
355+
) {
356+
if (specField == null) return;
357+
String fieldName = specField.get("name").asText();
336358

337359
if(fieldNode.get("required") != null && fieldNode.get("required").asBoolean()) {
338360
if(value == null || value.length() == 0) {
@@ -398,6 +420,7 @@ private static void validateTableValue(Collection<ValidationIssue> issues, Strin
398420

399421
}
400422

423+
/** A validation issue for a GTFS+ field. Use rowIndex = -1 for a table level issue. */
401424
public static class ValidationIssue implements Serializable {
402425
private static final long serialVersionUID = 1L;
403426
public String tableId;

0 commit comments

Comments
 (0)