|
9 | 9 | import com.fasterxml.jackson.databind.JsonNode;
|
10 | 10 | import com.fasterxml.jackson.databind.node.ArrayNode;
|
11 | 11 | import org.apache.commons.io.input.BOMInputStream;
|
| 12 | +import org.apache.logging.log4j.util.Strings; |
12 | 13 | import org.slf4j.Logger;
|
13 | 14 | import org.slf4j.LoggerFactory;
|
14 | 15 |
|
@@ -150,34 +151,44 @@ private static void validateTable(
|
150 | 151 | // Iterate over each row and validate each field value.
|
151 | 152 | int rowIndex = 0;
|
152 | 153 | int rowsWithWrongNumberOfColumns = 0;
|
| 154 | + int emptyRows = 0; |
153 | 155 | while (csvReader.readRecord()) {
|
154 | 156 | // First, check that row has the correct number of fields.
|
155 | 157 | int recordColumnCount = csvReader.getColumnCount();
|
156 |
| - if (recordColumnCount != fieldsFound.length) { |
157 |
| - rowsWithWrongNumberOfColumns++; |
158 |
| - } |
159 |
| - // Validate each value in row. Note: we iterate over the fields and not values because a row may be missing |
160 |
| - // columns, but we still want to validate that missing value (e.g., if it is missing a required field). |
161 | 158 | String[] rowValues = csvReader.getValues();
|
162 |
| - for (int f = 0; f < fieldsFound.length; f++) { |
163 |
| - // If value exists for index, use that. Otherwise, default to null to avoid out of bounds exception. |
164 |
| - String val = f < recordColumnCount ? rowValues[f] : null; |
165 |
| - validateTableValue(issues, tableId, rowIndex, rowValues, val, fieldsFound, fieldsFound[f], gtfsFeed); |
| 159 | + if (recordColumnCount == 1 && Strings.isBlank(rowValues[0])) { |
| 160 | + // If row is empty (technically, the row has one column with a blank value), |
| 161 | + // report that as such (and skip validating column values). |
| 162 | + emptyRows++; |
| 163 | + } else { |
| 164 | + if (recordColumnCount != fieldsFound.length) { |
| 165 | + rowsWithWrongNumberOfColumns++; |
| 166 | + } |
| 167 | + // Validate each value in row. Note: we iterate over the fields and not values because a row may be missing |
| 168 | + // columns, but we still want to validate that missing value (e.g., if it is missing a required field). |
| 169 | + for (int f = 0; f < fieldsFound.length; f++) { |
| 170 | + // If value exists for index, use that. Otherwise, default to null to avoid out of bounds exception. |
| 171 | + String val = f < recordColumnCount ? rowValues[f] : null; |
| 172 | + validateTableValue(issues, tableId, rowIndex, rowValues, val, fieldsFound, fieldsFound[f], gtfsFeed); |
| 173 | + } |
166 | 174 | }
|
167 | 175 | rowIndex++;
|
168 | 176 | }
|
169 | 177 | csvReader.close();
|
170 | 178 |
|
171 |
| - // Add issue for wrong number of columns after processing all rows. |
| 179 | + // Add issues for wrong number of columns and for empty rows after processing all rows. |
172 | 180 | // Note: We considered adding an issue for each row, but opted for the single error approach because there's no
|
173 | 181 | // concept of a row-level issue in the UI right now. So we would potentially need to add that to the UI
|
174 | 182 | // somewhere. Also, there's the trouble of reporting the issue at the row level, but not really giving the user
|
175 |
| - // a great way to resolve the issue in the GTFS+ editor. Essentially, all of the rows with the wrong number of |
| 183 | + // a great way to resolve the issue in the GTFS+ editor. Essentially, all rows with the wrong number of |
176 | 184 | // columns can be resolved simply by clicking the "Save and Revalidate" button -- so the resolution is more at
|
177 | 185 | // the table level than the row level (like, for example, a bad value for a field would be).
|
178 | 186 | if (rowsWithWrongNumberOfColumns > 0) {
|
179 | 187 | issues.add(new ValidationIssue(tableId, null, -1, rowsWithWrongNumberOfColumns + " row(s) do not contain the same number of fields as there are headers. (File may need to be edited manually.)"));
|
180 | 188 | }
|
| 189 | + if (emptyRows > 0) { |
| 190 | + issues.add(new ValidationIssue(tableId, null, -1, emptyRows + " row(s) are empty. (File may need to be edited manually.)")); |
| 191 | + } |
181 | 192 | }
|
182 | 193 |
|
183 | 194 | /** Determine if a GTFS+ spec field is required. */
|
|
0 commit comments