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

refactor: Replace CurrentDateTime with DateForValidation and use LocalDate #1636

Merged
merged 5 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -16,34 +16,34 @@

package org.mobilitydata.gtfsvalidator.input;

import java.time.ZonedDateTime;
import java.time.LocalDate;

/** Represents the current date and time */
public class CurrentDateTime {
/** The date to be used for validation rules. */
public class DateForValidation {

private final ZonedDateTime now;
private final LocalDate date;

public CurrentDateTime(ZonedDateTime now) {
this.now = now;
public DateForValidation(LocalDate date) {
this.date = date;
}

public ZonedDateTime getNow() {
return now;
public LocalDate getDate() {
return date;
}

@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other instanceof CurrentDateTime) {
return this.now.equals(((CurrentDateTime) other).now);
if (other instanceof DateForValidation) {
return this.date.equals(((DateForValidation) other).date);
}
return false;
}

@Override
public int hashCode() {
return now.hashCode();
return date.hashCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public abstract class GtfsInput implements Closeable {
public static final String invalidInputMessage =
"At least 1 GTFS file is in a subfolder. All GTFS files must reside at the root level directly.";

public static final String USER_AGENT_PREFIX = "MobilityData GTFS-Validator";

/**
* Creates a specific GtfsInput to read data from the given path.
*
Expand Down Expand Up @@ -92,18 +94,6 @@ public static boolean hasSubfolderWithGtfsFile(Path path) throws IOException {
return containsGtfsFileInSubfolder(zipInputStream);
}

/**
* Check if an input zip file from an URL contains a subfolder with GTFS files
*
* @param url
* @return
* @throws IOException
*/
public static boolean hasSubfolderWithGtfsFile(URL url) throws IOException {
ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(url.openStream()));
return containsGtfsFileInSubfolder(zipInputStream);
}

/**
* Common method used by two overloaded hasSubfolderWithGtfsFile methods
*
Expand Down Expand Up @@ -143,20 +133,21 @@ private static boolean containsGtfsFileInSubfolder(ZipInputStream zipInputStream
* @param sourceUrl the fully qualified URL to download of the resource to download
* @param targetPath the path to store the downloaded GTFS archive
* @param noticeContainer
* @param validatorVersion
* @return the {@code GtfsInput} created after download of the GTFS archive
* @throws IOException if GTFS archive cannot be stored at the specified location
* @throws URISyntaxException if URL is malformed
*/
public static GtfsInput createFromUrl(
URL sourceUrl, Path targetPath, NoticeContainer noticeContainer)
URL sourceUrl, Path targetPath, NoticeContainer noticeContainer, String validatorVersion)
throws IOException, URISyntaxException {
// getParent() may return null if there is no parent, so call toAbsolutePath() first.
Path targetDirectory = targetPath.toAbsolutePath().getParent();
if (!Files.isDirectory(targetDirectory)) {
Files.createDirectories(targetDirectory);
}
try (OutputStream outputStream = Files.newOutputStream(targetPath)) {
loadFromUrl(sourceUrl, outputStream);
loadFromUrl(sourceUrl, outputStream, validatorVersion);
}
return createFromPath(targetPath, noticeContainer);
}
Expand All @@ -171,14 +162,15 @@ public static GtfsInput createFromUrl(
* @throws IOException if no file could not be found at the specified location
* @throws URISyntaxException if URL is malformed
*/
public static GtfsInput createFromUrlInMemory(URL sourceUrl, NoticeContainer noticeContainer)
public static GtfsInput createFromUrlInMemory(
URL sourceUrl, NoticeContainer noticeContainer, String validatorVersion)
throws IOException, URISyntaxException {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
loadFromUrl(sourceUrl, outputStream);
loadFromUrl(sourceUrl, outputStream, validatorVersion);
File zipFile = new File(sourceUrl.toString());
String fileName = zipFile.getName().replace(".zip", "");
if (hasSubfolderWithGtfsFile(sourceUrl)) {

if (containsGtfsFileInSubfolder(
new ZipInputStream(new ByteArrayInputStream(outputStream.toByteArray())))) {
noticeContainer.addValidationNotice(
new InvalidInputFilesInSubfolderNotice(invalidInputMessage));
}
Expand All @@ -192,19 +184,35 @@ public static GtfsInput createFromUrlInMemory(URL sourceUrl, NoticeContainer not
*
* @param sourceUrl the fully qualified URL
* @param outputStream the output stream
* @param validatorVersion
* @throws IOException if no file could not be found at the specified location
* @throws URISyntaxException if URL is malformed
*/
private static void loadFromUrl(URL sourceUrl, OutputStream outputStream)
private static void loadFromUrl(URL sourceUrl, OutputStream outputStream, String validatorVersion)
throws IOException, URISyntaxException {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet httpGet = new HttpGet(sourceUrl.toURI());
httpGet.setHeader("User-Agent", getUserAgent(validatorVersion));
try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
httpResponse.getEntity().writeTo(outputStream);
}
}
}

/**
* @param validatorVersion version of the validator
* @return the user agent string in the format: "MobilityData GTFS-Validator/{validatorVersion}
* (Java {java version})"
*/
private static String getUserAgent(String validatorVersion) {
return USER_AGENT_PREFIX
+ "/"
+ (validatorVersion != null ? validatorVersion : "")
+ " (Java "
+ System.getProperty("java.version")
+ ")";
}

/**
* Lists all files inside the GTFS dataset, even if they are not CSV and do not have .txt
* extension.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.mobilitydata.gtfsvalidator.input.CountryCode;
import org.mobilitydata.gtfsvalidator.input.CurrentDateTime;
import org.mobilitydata.gtfsvalidator.input.DateForValidation;
import org.mobilitydata.gtfsvalidator.notice.NoticeContainer;
import org.mobilitydata.gtfsvalidator.notice.ValidationNotice;
import org.mobilitydata.gtfsvalidator.table.AnyTableLoader;
Expand All @@ -41,7 +40,7 @@
public class LoadingHelper {

private CountryCode countryCode = CountryCode.forStringOrUnknown("ca");
private ZonedDateTime currentTime = ZonedDateTime.of(2021, 1, 1, 14, 30, 0, 0, ZoneOffset.UTC);
private LocalDate dateForValidation = LocalDate.of(2021, 1, 1);

private NoticeContainer noticeContainer = new NoticeContainer();

Expand All @@ -68,7 +67,7 @@ public <X extends GtfsEntity, Y extends GtfsTableContainer<X>> Y load(
ValidationContext context =
ValidationContext.builder()
.setCountryCode(countryCode)
.setCurrentDateTime(new CurrentDateTime(currentTime))
.setDateForValidation(new DateForValidation(dateForValidation))
.build();
ValidatorProvider provider = new DefaultValidatorProvider(context, validatorLoader);
return (Y) AnyTableLoader.load(tableDescriptor, provider, in, noticeContainer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import com.google.common.collect.ImmutableMap;
import org.mobilitydata.gtfsvalidator.input.CountryCode;
import org.mobilitydata.gtfsvalidator.input.CurrentDateTime;
import org.mobilitydata.gtfsvalidator.input.DateForValidation;

/**
* A read-only context passed to particular validator objects. It gives information relevant for
Expand Down Expand Up @@ -57,8 +57,8 @@ public CountryCode countryCode() {
*
* @return The time when validation started as @code{ZonedDateTime}
*/
public CurrentDateTime currentDateTime() {
return get(CurrentDateTime.class);
public DateForValidation dateForValidation() {
return get(DateForValidation.class);
}

/** Returns a member of the context with requested class. */
Expand All @@ -82,8 +82,8 @@ public Builder setCountryCode(CountryCode countryCode) {
}

/** Sets the current time. */
public Builder setCurrentDateTime(CurrentDateTime currentDateTime) {
return set(CurrentDateTime.class, currentDateTime);
public Builder setDateForValidation(DateForValidation dateForValidation) {
return set(DateForValidation.class, dateForValidation);
}

/** Sets a member of the context with requested class. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.ZonedDateTime;
import java.time.LocalDate;
import java.util.List;
import org.mobilitydata.gtfsvalidator.input.CountryCode;
import org.mobilitydata.gtfsvalidator.input.CurrentDateTime;
import org.mobilitydata.gtfsvalidator.input.DateForValidation;
import org.mobilitydata.gtfsvalidator.notice.NoticeContainer;
import org.mobilitydata.gtfsvalidator.notice.ValidationNotice;
import org.mobilitydata.gtfsvalidator.validator.ValidationContext;
Expand All @@ -32,7 +32,7 @@ public static InputStream toInputStream(String s) {
public static ValidationContext contextForTest() {
return ValidationContext.builder()
.setCountryCode(CountryCode.forStringOrUnknown("ca"))
.setCurrentDateTime(new CurrentDateTime(ZonedDateTime.now()))
.setDateForValidation(new DateForValidation(LocalDate.now()))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,23 @@

import static com.google.common.truth.Truth.assertThat;

import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.LocalDate;
import org.junit.Test;

public class CurrentDateTimeTest {
private static final ZonedDateTime TEST_NOW =
ZonedDateTime.of(2021, 1, 1, 14, 30, 0, 0, ZoneOffset.UTC);
private static final ZonedDateTime OTHER_DATE_TIME =
ZonedDateTime.of(2021, 4, 1, 14, 30, 0, 0, ZoneOffset.UTC);
public class DateForValidationTest {
private static final LocalDate TEST_NOW = LocalDate.of(2021, 1, 1);
private static final LocalDate OTHER_DATE_TIME = LocalDate.of(2021, 4, 1);

@Test
public void getNow() {
CurrentDateTime currentDateTime = new CurrentDateTime(TEST_NOW);
assertThat(currentDateTime.getNow()).isEqualTo(TEST_NOW);
public void getDate() {
DateForValidation dateForValidation = new DateForValidation(TEST_NOW);
assertThat(dateForValidation.getDate()).isEqualTo(TEST_NOW);
}

@Test
public void testEquals() {
assertThat(new CurrentDateTime(TEST_NOW).equals(new CurrentDateTime(TEST_NOW))).isTrue();
assertThat(new CurrentDateTime(TEST_NOW).equals(new CurrentDateTime(OTHER_DATE_TIME)))
assertThat(new DateForValidation(TEST_NOW).equals(new DateForValidation(TEST_NOW))).isTrue();
assertThat(new DateForValidation(TEST_NOW).equals(new DateForValidation(OTHER_DATE_TIME)))
.isFalse();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,14 @@ public void zipInput() throws IOException {
}
}

@Test
public void urlInputHasNoSubfolderWithGtfsFile() throws IOException {
URL url = new URL(VALID_URL);
assertFalse(GtfsInput.hasSubfolderWithGtfsFile(url));
}

@Test
public void createFromUrl_valid_success() throws IOException, URISyntaxException {
try (GtfsInput underTest =
GtfsInput.createFromUrl(
new URL(VALID_URL), tmpDir.getRoot().toPath().resolve("storage"), noticeContainer)) {
new URL(VALID_URL),
tmpDir.getRoot().toPath().resolve("storage"),
noticeContainer,
"1.0.1")) {
assertThat(underTest instanceof GtfsZipFileInput);
}
}
Expand All @@ -100,13 +97,14 @@ public void createFromUrl_invalid_throwsException() {
GtfsInput.createFromUrl(
new URL(INVALID_URL),
tmpDir.getRoot().toPath().resolve("storage"),
noticeContainer));
noticeContainer,
"1.0.1"));
}

@Test
public void createFromUrlInMemory_valid_success() throws IOException, URISyntaxException {
try (GtfsInput underTest =
GtfsInput.createFromUrlInMemory(new URL(VALID_URL), noticeContainer)) {
GtfsInput.createFromUrlInMemory(new URL(VALID_URL), noticeContainer, "1.0.1")) {
assertThat(underTest instanceof GtfsZipFileInput);
}
}
Expand All @@ -115,6 +113,6 @@ public void createFromUrlInMemory_valid_success() throws IOException, URISyntaxE
public void createFromUrlInMemory_invalid_throwsException() {
assertThrows(
IOException.class,
() -> GtfsInput.createFromUrlInMemory(new URL(INVALID_URL), noticeContainer));
() -> GtfsInput.createFromUrlInMemory(new URL(INVALID_URL), noticeContainer, "1.0.1"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@

import javax.inject.Inject;
import org.mobilitydata.gtfsvalidator.input.CountryCode;
import org.mobilitydata.gtfsvalidator.input.CurrentDateTime;
import org.mobilitydata.gtfsvalidator.input.DateForValidation;
import org.mobilitydata.gtfsvalidator.notice.NoticeContainer;
import org.mobilitydata.gtfsvalidator.validator.SingleEntityValidator;

public class GtfsTestEntityValidator extends SingleEntityValidator<GtfsTestEntity> {
private final CountryCode countryCode;
private final CurrentDateTime currentDateTime;
private final DateForValidation dateForValidation;

@Inject
public GtfsTestEntityValidator(CountryCode countryCode, CurrentDateTime currentDateTime) {
public GtfsTestEntityValidator(CountryCode countryCode, DateForValidation dateForValidation) {
this.countryCode = countryCode;
this.currentDateTime = currentDateTime;
this.dateForValidation = dateForValidation;
}

@Override
Expand All @@ -39,7 +39,7 @@ public CountryCode getCountryCode() {
return countryCode;
}

public CurrentDateTime getCurrentDateTime() {
return currentDateTime;
public DateForValidation getDateForValidation() {
return dateForValidation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@

import javax.inject.Inject;
import org.mobilitydata.gtfsvalidator.input.CountryCode;
import org.mobilitydata.gtfsvalidator.input.CurrentDateTime;
import org.mobilitydata.gtfsvalidator.input.DateForValidation;
import org.mobilitydata.gtfsvalidator.notice.NoticeContainer;
import org.mobilitydata.gtfsvalidator.validator.FileValidator;

public class GtfsTestSingleFileValidator extends FileValidator {

private final GtfsTestTableContainer table;
private final CountryCode countryCode;
private final CurrentDateTime currentDateTime;
private final DateForValidation dateForValidation;

@Inject
public GtfsTestSingleFileValidator(
GtfsTestTableContainer table, CountryCode countryCode, CurrentDateTime currentDateTime) {
GtfsTestTableContainer table, CountryCode countryCode, DateForValidation dateForValidation) {
this.table = table;
this.countryCode = countryCode;
this.currentDateTime = currentDateTime;
this.dateForValidation = dateForValidation;
}

@Override
Expand All @@ -47,7 +47,7 @@ public CountryCode getCountryCode() {
return countryCode;
}

public CurrentDateTime getCurrentDateTime() {
return currentDateTime;
public DateForValidation getDateForValidation() {
return dateForValidation;
}
}
Loading
Loading