Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MTC Field length validation #276

Merged
merged 19 commits into from
Apr 13, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b85a922
refactor(Feed): allow additional validators
landonreed Apr 1, 2020
8b72831
test(MTC): Set up test files for MTC field length validation.
binh-dam-ibigroup Apr 1, 2020
eeb6b32
feat(MTCValidator): Implement MTC validator and complete test.
binh-dam-ibigroup Apr 2, 2020
3f42515
docs: Refine comments and error messages.
binh-dam-ibigroup Apr 2, 2020
4058c9b
refactor(FieldLengthError): Remove unused class.
binh-dam-ibigroup Apr 2, 2020
d423983
refactor: Replace calling reflection on FeedValidator constructors wi…
binh-dam-ibigroup Apr 2, 2020
9b94a0e
refactor(Feed): Replace callback interface to create MTCValidator wit…
binh-dam-ibigroup Apr 2, 2020
13696e5
refactor(validate): remove list from custom validator interface
landonreed Apr 2, 2020
df84840
refactor(validator): rename validator creator
landonreed Apr 3, 2020
d449b12
refactor(validator): refactor Feed class and add javadoc
landonreed Apr 3, 2020
b6aea3b
refactor(validator): fix npe
landonreed Apr 3, 2020
19db9c2
Merge branch 'field-length-validator' into field-length-validator-ltr-2
landonreed Apr 3, 2020
fd249da
refactor: fix build/imports
landonreed Apr 3, 2020
28b1dda
refactor(GTFSTest): Use FeedValidatorCreator... syntax to remove test…
binh-dam-ibigroup Apr 3, 2020
707a119
refactor(MTCValidator): Rename validation method + add overload, adju…
binh-dam-ibigroup Apr 6, 2020
7e97461
fix(tests): Fix tests
binh-dam-ibigroup Apr 6, 2020
be1fc6d
refactor(MTCValidator): Rename validateFieldLength; Add null check!
binh-dam-ibigroup Apr 6, 2020
ffd601a
Merge branch 'field-length-validator' of https://github.com/conveyal/…
binh-dam-ibigroup Apr 6, 2020
12ff728
refactor(NewGTFSErrorType): Reorganize error types per PR comment.
binh-dam-ibigroup Apr 7, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public enum NewGTFSErrorType {
URL_FORMAT(Priority.MEDIUM, "URL format should be <scheme>://<authority><path>?<query>#<fragment>"),
LANGUAGE_FORMAT(Priority.LOW, "Language should be specified with a valid BCP47 tag."),
ILLEGAL_FIELD_VALUE(Priority.MEDIUM, "Fields may not contain tabs, carriage returns or new lines."),
// The error type below is an MTC-specific requirement.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's organize these into sections instead of having an individual comment for potentially each error type.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you have anything in mind for reorganizing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say one section for errors that apply during all types of validation and another section for MTC-specific errors.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIELD_VALUE_TOO_LONG(Priority.MEDIUM, "Field value has too many characters."),
binh-dam-ibigroup marked this conversation as resolved.
Show resolved Hide resolved
INTEGER_FORMAT(Priority.MEDIUM, "Incorrect integer format."),
FARE_TRANSFER_MISMATCH(Priority.MEDIUM, "A fare that does not permit transfers has a non-zero transfer duration."),
Expand Down
41 changes: 24 additions & 17 deletions src/main/java/com/conveyal/gtfs/validator/MTCValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@
import com.conveyal.gtfs.loader.Feed;
import com.conveyal.gtfs.model.*;

import java.net.URL;

import static com.conveyal.gtfs.error.NewGTFSErrorType.FIELD_VALUE_TOO_LONG;

/**
* MTCValidator checks in a GTFS feed that the length of certain field values
* do not exceed the 511 MTC guidelines. (TODO: add guidelines URL.)
* To refer to specific limits, search the guidelines for the word 'character'.
* MTCValidator runs a set of custom validation checks for GTFS feeds managed by MTC in Data Tools.
* The checks consist of validating field lengths at this time per the 511 MTC guidelines at
* https://github.com/ibi-group/datatools-ui/files/4438625/511.Transit_Data.Guidelines_V2.0_3-27-2020.pdf.
* For specific field lengths, search the guidelines for the word 'character'.
*
* Note that other validations, e.g. on GTFS+ files, are discussed in
* https://github.com/ibi-group/datatools-ui/issues/544.
*/
public class MTCValidator extends FeedValidator {

Expand All @@ -20,37 +26,38 @@ public MTCValidator(Feed feed, SQLErrorStorage errorStorage) {
@Override
public void validate() {
for (Agency agency : feed.agencies) {
fieldLengthShouldNotExceed(agency, agency.agency_id, 50);
fieldLengthShouldNotExceed(agency, agency.agency_name, 50);
fieldLengthShouldNotExceed(agency, agency.agency_url, 500);
validateFieldLength(agency, agency.agency_id, 50);
validateFieldLength(agency, agency.agency_name, 50);
validateFieldLength(agency, agency.agency_url, 500);
}

for (Stop stop : feed.stops) {
fieldLengthShouldNotExceed(stop, stop.stop_name, 100);
validateFieldLength(stop, stop.stop_name, 100);
}

for (Trip trip : feed.trips) {
fieldLengthShouldNotExceed(trip, trip.trip_headsign, 120);
fieldLengthShouldNotExceed(trip, trip.trip_short_name, 50);
validateFieldLength(trip, trip.trip_headsign, 120);
validateFieldLength(trip, trip.trip_short_name, 50);
}

// TODO: Handle calendar_attributes.txt?
}

/**
* Checks that the length of a string (or Object.toString()) does not exceed a length.
* Checks that the length of a string does not exceed a certain length.
* Reports an error if the length is exceeded.
* @param entity The containing GTFS entity (for error reporting purposes).
* @param objValue The value to check.
* @param value The String value to check.
* @param maxLength The length to check, should be positive or zero.
* @return true if the length of objValue.toString() is maxLength or less or if objValue is null; false otherwise.
* @return true if value.length() is maxLength or less, or if value is null; false otherwise.
*/
public boolean fieldLengthShouldNotExceed(Entity entity, Object objValue, int maxLength) {
String value = objValue != null ? objValue.toString() : "";
if (value.length() > maxLength) {
public boolean validateFieldLength(Entity entity, String value, int maxLength) {
if (value != null && value.length() > maxLength) {
if (errorStorage != null) registerError(entity, FIELD_VALUE_TOO_LONG, "[over " + maxLength + " characters] " + value);
return false;
}
return true;
}

public boolean validateFieldLength(Entity entity, URL url, int maxLength) {
return validateFieldLength(entity, url != null ? url.toString() : "", maxLength);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public class MTCValidatorTest {
@Test
public void fieldlLengthShouldNotExceed() {
MTCValidator validator = new MTCValidator(null, null);
assertThat(validator.fieldLengthShouldNotExceed(null, "abcdefghijklmnopqrstwxyz1234567890", 20), is(false));
assertThat(validator.fieldLengthShouldNotExceed(null, "abcdef", 20), is(true));
assertThat(validator.validateFieldLength(null, "abcdefghijklmnopqrstwxyz1234567890", 20), is(false));
assertThat(validator.validateFieldLength(null, "abcdef", 20), is(true));
}

@Test
Expand All @@ -22,7 +22,7 @@ public void fieldlLengthShouldNotExceed_usingObject() throws MalformedURLExcepti

// You can also pass objects, in that case it will use toString().
URL url = new URL("http://www.gtfs.org");
assertThat(validator.fieldLengthShouldNotExceed(null, url, 10), is(false));
assertThat(validator.fieldLengthShouldNotExceed(null, url, 30), is(true));
assertThat(validator.validateFieldLength(null, url, 10), is(false));
assertThat(validator.validateFieldLength(null, url, 30), is(true));
}
}