Skip to content

Commit

Permalink
Add NonIncreasingTimeValidator and MismatchedTransportModeValidator
Browse files Browse the repository at this point in the history
  • Loading branch information
vpaturet committed Dec 20, 2024
1 parent 085f590 commit 56b138f
Show file tree
Hide file tree
Showing 20 changed files with 3,809 additions and 8 deletions.
16 changes: 15 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.entur</groupId>
<artifactId>netex-validator-java</artifactId>
<version>9.0.2-SNAPSHOT</version>
<version>10.0.0-SNAPSHOT</version>

<name>netex-validator-java</name>
<description>Library for validating NeTEx datasets against the Nordic NeTEx Profile.</description>
Expand Down Expand Up @@ -64,6 +64,7 @@
<zt-zip.version>1.17</zt-zip.version>
<junit.version>5.11.3</junit.version>
<mockito-core.version>5.14.2</mockito-core.version>
<hamcrest.version>2.2</hamcrest.version>
<logback-classic.version>1.5.12</logback-classic.version>

<maven-exec-plugin.version>1.6.0</maven-exec-plugin.version>
Expand Down Expand Up @@ -102,6 +103,7 @@
<!-- GPG configuration for jar signing-->
<gpg.executable>gpg</gpg.executable>
<gpg.keyname>${env.GPG_KEY_NAME}</gpg.keyname>

</properties>

<dependencies>
Expand Down Expand Up @@ -154,6 +156,12 @@
<version>${slf4j.version}</version>
</dependency>

<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>3.0.0</version>
</dependency>

<!-- testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand All @@ -179,6 +187,12 @@
<version>${mockito-core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.zeroturnaround</groupId>
<artifactId>zt-zip</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.entur.netex.validation.validator.jaxb;

import jakarta.annotation.Nullable;
import java.util.*;
import java.util.function.Function;
import javax.annotation.Nullable;
import org.entur.netex.index.api.NetexEntitiesIndex;
import org.entur.netex.validation.validator.DataLocation;
import org.entur.netex.validation.validator.ValidationContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.entur.netex.validation.validator.jaxb;

import javax.annotation.Nullable;
import jakarta.annotation.Nullable;
import org.entur.netex.index.api.NetexEntitiesIndex;
import org.entur.netex.validation.validator.model.QuayCoordinates;
import org.entur.netex.validation.validator.model.QuayId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

package org.entur.netex.validation.validator.jaxb;

import javax.annotation.Nullable;
import jakarta.annotation.Nullable;
import org.entur.netex.validation.validator.model.QuayCoordinates;
import org.entur.netex.validation.validator.model.QuayId;
import org.entur.netex.validation.validator.model.StopPlaceId;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package org.entur.netex.validation.validator.jaxb.model.stoptime;

import java.math.BigInteger;
import java.time.LocalTime;
import org.entur.netex.validation.validator.model.ScheduledStopPointId;
import org.rutebanken.netex.model.TimetabledPassingTime;

/**
* Wrapper around {@link TimetabledPassingTime} that provides a simpler interface for passing times
* comparison. Passing times are exposed as seconds since midnight, taking into account the day
* offset.
* <p>
* This class does not take Daylight Saving Time transitions into account, this is an error and
* should be fixed. See https://github.com/opentripplanner/OpenTripPlanner/issues/5109
*/
abstract sealed class AbstractStopTime
implements StopTime
permits FlexibleStopTime, RegularStopTime {

private final ScheduledStopPointId scheduledStopPointId;
private final TimetabledPassingTime timetabledPassingTime;

protected AbstractStopTime(
ScheduledStopPointId scheduledStopPointId,
TimetabledPassingTime timetabledPassingTime
) {
this.scheduledStopPointId = scheduledStopPointId;
this.timetabledPassingTime = timetabledPassingTime;
}

@Override
public ScheduledStopPointId scheduledStopPointId() {
return scheduledStopPointId;
}

protected LocalTime arrivalTime() {
return timetabledPassingTime.getArrivalTime();
}

protected BigInteger arrivalDayOffset() {
return timetabledPassingTime.getArrivalDayOffset();
}

protected LocalTime latestArrivalTime() {
return timetabledPassingTime.getLatestArrivalTime();
}

protected BigInteger latestArrivalDayOffset() {
return timetabledPassingTime.getLatestArrivalDayOffset();
}

protected LocalTime departureTime() {
return timetabledPassingTime.getDepartureTime();
}

protected BigInteger departureDayOffset() {
return timetabledPassingTime.getDepartureDayOffset();
}

protected LocalTime earliestDepartureTime() {
return timetabledPassingTime.getEarliestDepartureTime();
}

protected BigInteger earliestDepartureDayOffset() {
return timetabledPassingTime.getEarliestDepartureDayOffset();
}

protected boolean isRegularStopFollowedByAreaStopValid(
FlexibleStopTime next
) {
return (
normalizedDepartureTimeOrElseArrivalTime() <=
next.normalizedEarliestDepartureTime()
);
}

protected boolean isAreaStopFollowedByRegularStopValid(RegularStopTime next) {
return (
normalizedLatestArrivalTime() <=
next.normalizedArrivalTimeOrElseDepartureTime()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package org.entur.netex.validation.validator.jaxb.model.stoptime;

import org.entur.netex.validation.validator.model.ScheduledStopPointId;
import org.rutebanken.netex.model.TimetabledPassingTime;

/**
* Wrapper around {@link TimetabledPassingTime} that provides a simpler interface
* for passing times comparison.
* Passing times are exposed as seconds since midnight, taking into account the day offset.
*/
final class FlexibleStopTime extends AbstractStopTime {

FlexibleStopTime(
ScheduledStopPointId scheduledStopPointId,
TimetabledPassingTime timetabledPassingTime
) {
super(scheduledStopPointId, timetabledPassingTime);
}

@Override
public boolean isComplete() {
return hasLatestArrivalTime() && hasEarliestDepartureTime();
}

@Override
public boolean isConsistent() {
return (
!isComplete() ||
normalizedLatestArrivalTime() >= normalizedEarliestDepartureTime()
);
}

@Override
public boolean isStopTimesIncreasing(StopTime next) {
if (next instanceof RegularStopTime regularStopTime) {
return isAreaStopFollowedByRegularStopValid(regularStopTime);
}
return isAreaStopFollowedByAreaStopValid((FlexibleStopTime) next);
}

@Override
public int getStopTimeDiff(StopTime given) {
// TODO: This should be fixed. We need to take into account the type of given.
// Is it the same type as this, or not. See how we have done in
// isRegularStopFollowedByRegularStopValid, isAreaStopFollowedByAreaStopValid,
// isRegularStopFollowedByAreaStopValid, isAreaStopFollowedByRegularStopValid

if (given instanceof FlexibleStopTime) {
return isComplete()
? normalizedEarliestDepartureTime() - normalizedLatestArrivalTime()
: 0;
}
return (
given.normalizedEarliestDepartureTime() -
normalizedArrivalTimeOrElseDepartureTime()
);
}

@Override
public int normalizedEarliestDepartureTime() {
return elapsedTimeSinceMidnight(
earliestDepartureTime(),
earliestDepartureDayOffset()
);
}

@Override
public int normalizedLatestArrivalTime() {
return elapsedTimeSinceMidnight(
latestArrivalTime(),
latestArrivalDayOffset()
);
}

@Override
public int normalizedDepartureTimeOrElseArrivalTime() {
throw new UnsupportedOperationException();
}

@Override
public int normalizedArrivalTimeOrElseDepartureTime() {
throw new UnsupportedOperationException();
}

private boolean hasLatestArrivalTime() {
return latestArrivalTime() != null;
}

private boolean hasEarliestDepartureTime() {
return earliestDepartureTime() != null;
}

private boolean isAreaStopFollowedByAreaStopValid(FlexibleStopTime next) {
int earliestDepartureTime = normalizedEarliestDepartureTime();
int nextEarliestDepartureTime = next.normalizedEarliestDepartureTime();
int latestArrivalTime = normalizedLatestArrivalTime();
int nextLatestArrivalTime = next.normalizedLatestArrivalTime();

return (
earliestDepartureTime <= nextEarliestDepartureTime &&
latestArrivalTime <= nextLatestArrivalTime
);
}

@Override
public boolean isArrivalInMinutesResolution() {
return hasLatestArrivalTime()
? latestArrivalTime().getSecond() == 0
: earliestDepartureTime().getSecond() == 0;
}

@Override
public boolean isDepartureInMinutesResolution() {
return hasEarliestDepartureTime()
? earliestDepartureTime().getSecond() == 0
: latestArrivalTime().getSecond() == 0;
}
}
Loading

0 comments on commit 56b138f

Please sign in to comment.